108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg/* 208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * This driver implements I2C master functionality using the LSI API2C 308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * controller. 408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * 508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * NOTE: The controller has a limitation in that it can only do transfers of 608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * maximum 255 bytes at a time. If a larger transfer is attempted, error code 708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * (-EINVAL) is returned. 808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * 908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * This software is licensed under the terms of the GNU General Public 1008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * License version 2, as published by the Free Software Foundation, and 1108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * may be copied, distributed, and modified under those terms. 1208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg */ 1308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/clk.h> 1408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/clkdev.h> 1508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/err.h> 1608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/i2c.h> 1708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/init.h> 1808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/interrupt.h> 1908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/module.h> 2008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/io.h> 2108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/kernel.h> 2208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#include <linux/platform_device.h> 2308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 2408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define SCL_WAIT_TIMEOUT_NS 25000000 2508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define I2C_XFER_TIMEOUT (msecs_to_jiffies(250)) 2608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define I2C_STOP_TIMEOUT (msecs_to_jiffies(100)) 2708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define FIFO_SIZE 8 2808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 2908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define GLOBAL_CONTROL 0x00 3008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define GLOBAL_MST_EN BIT(0) 3108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define GLOBAL_SLV_EN BIT(1) 3208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define GLOBAL_IBML_EN BIT(2) 3308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define INTERRUPT_STATUS 0x04 3408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define INTERRUPT_ENABLE 0x08 3508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define INT_SLV BIT(1) 3608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define INT_MST BIT(0) 3708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define WAIT_TIMER_CONTROL 0x0c 3808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define WT_EN BIT(15) 3908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define WT_VALUE(_x) ((_x) & 0x7fff) 4008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define IBML_TIMEOUT 0x10 4108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define IBML_LOW_MEXT 0x14 4208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define IBML_LOW_SEXT 0x18 4308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define TIMER_CLOCK_DIV 0x1c 4408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define I2C_BUS_MONITOR 0x20 4508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define SOFT_RESET 0x24 4608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_COMMAND 0x28 4708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define CMD_BUSY (1<<3) 4808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define CMD_MANUAL (0x00 | CMD_BUSY) 4908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define CMD_AUTO (0x01 | CMD_BUSY) 5008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_RX_XFER 0x2c 5108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_TX_XFER 0x30 5208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_ADDR_1 0x34 5308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_ADDR_2 0x38 5408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_DATA 0x3c 5508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_TX_FIFO 0x40 5608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_RX_FIFO 0x44 5708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_INT_ENABLE 0x48 5808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_INT_STATUS 0x4c 5908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_RFL (1 << 13) /* RX FIFO serivce */ 6008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_TFL (1 << 12) /* TX FIFO service */ 6108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_SNS (1 << 11) /* Manual mode done */ 6208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_SS (1 << 10) /* Automatic mode done */ 6308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_SCC (1 << 9) /* Stop complete */ 6408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_IP (1 << 8) /* Invalid parameter */ 6508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_TSS (1 << 7) /* Timeout */ 6608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_AL (1 << 6) /* Arbitration lost */ 6708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_ND (1 << 5) /* NAK on data phase */ 6808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_NA (1 << 4) /* NAK on address phase */ 6908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_NAK (MST_STATUS_NA | \ 7008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg MST_STATUS_ND) 7108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_STATUS_ERR (MST_STATUS_NAK | \ 7208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg MST_STATUS_AL | \ 7308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg MST_STATUS_IP | \ 7408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg MST_STATUS_TSS) 7508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_TX_BYTES_XFRD 0x50 7608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define MST_RX_BYTES_XFRD 0x54 7708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define SCL_HIGH_PERIOD 0x80 7808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define SCL_LOW_PERIOD 0x84 7908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define SPIKE_FLTR_LEN 0x88 8008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define SDA_SETUP_TIME 0x8c 8108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg#define SDA_HOLD_TIME 0x90 8208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 8308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg/** 8408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * axxia_i2c_dev - I2C device context 8508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @base: pointer to register struct 8608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @msg: pointer to current message 8708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @msg_xfrd: number of bytes transferred in msg 8808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @msg_err: error code for completed message 8908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @msg_complete: xfer completion object 9008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @dev: device reference 9108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @adapter: core i2c abstraction 9208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @i2c_clk: clock reference for i2c input clock 9308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @bus_clk_rate: current i2c bus clock rate 9408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg */ 9508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstruct axxia_i2c_dev { 9608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg void __iomem *base; 9708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct i2c_msg *msg; 9808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg size_t msg_xfrd; 9908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int msg_err; 10008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct completion msg_complete; 10108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct device *dev; 10208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct i2c_adapter adapter; 10308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct clk *i2c_clk; 10408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 bus_clk_rate; 10508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg}; 10608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 10708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic void i2c_int_disable(struct axxia_i2c_dev *idev, u32 mask) 10808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 10908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 int_en; 11008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 11108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int_en = readl(idev->base + MST_INT_ENABLE); 11208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(int_en & ~mask, idev->base + MST_INT_ENABLE); 11308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 11408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 11508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic void i2c_int_enable(struct axxia_i2c_dev *idev, u32 mask) 11608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 11708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 int_en; 11808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 11908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int_en = readl(idev->base + MST_INT_ENABLE); 12008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(int_en | mask, idev->base + MST_INT_ENABLE); 12108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 12208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 12308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg/** 12408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * ns_to_clk - Convert time (ns) to clock cycles for the given clock frequency. 12508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg */ 12608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic u32 ns_to_clk(u64 ns, u32 clk_mhz) 12708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 12808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return div_u64(ns * clk_mhz, 1000); 12908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 13008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 13108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int axxia_i2c_init(struct axxia_i2c_dev *idev) 13208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 13308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 divisor = clk_get_rate(idev->i2c_clk) / idev->bus_clk_rate; 13408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 clk_mhz = clk_get_rate(idev->i2c_clk) / 1000000; 13508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 t_setup; 13608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 t_high, t_low; 13708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 tmo_clk; 13808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 prescale; 13908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg unsigned long timeout; 14008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 14108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_dbg(idev->dev, "rate=%uHz per_clk=%uMHz -> ratio=1:%u\n", 14208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->bus_clk_rate, clk_mhz, divisor); 14308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 14408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Reset controller */ 14508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(0x01, idev->base + SOFT_RESET); 14608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg timeout = jiffies + msecs_to_jiffies(100); 14708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg while (readl(idev->base + SOFT_RESET) & 1) { 14808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (time_after(jiffies, timeout)) { 14908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_warn(idev->dev, "Soft reset failed\n"); 15008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg break; 15108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 15208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 15308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 15408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Enable Master Mode */ 15508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(0x1, idev->base + GLOBAL_CONTROL); 15608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 15708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (idev->bus_clk_rate <= 100000) { 15808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Standard mode SCL 50/50, tSU:DAT = 250 ns */ 15908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg t_high = divisor * 1 / 2; 16008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg t_low = divisor * 1 / 2; 16108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg t_setup = ns_to_clk(250, clk_mhz); 16208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } else { 16308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Fast mode SCL 33/66, tSU:DAT = 100 ns */ 16408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg t_high = divisor * 1 / 3; 16508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg t_low = divisor * 2 / 3; 16608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg t_setup = ns_to_clk(100, clk_mhz); 16708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 16808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 16908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* SCL High Time */ 17008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(t_high, idev->base + SCL_HIGH_PERIOD); 17108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* SCL Low Time */ 17208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(t_low, idev->base + SCL_LOW_PERIOD); 17308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* SDA Setup Time */ 17408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(t_setup, idev->base + SDA_SETUP_TIME); 17508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* SDA Hold Time, 300ns */ 17608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(ns_to_clk(300, clk_mhz), idev->base + SDA_HOLD_TIME); 17708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Filter <50ns spikes */ 17808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(ns_to_clk(50, clk_mhz), idev->base + SPIKE_FLTR_LEN); 17908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 18008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Configure Time-Out Registers */ 18108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg tmo_clk = ns_to_clk(SCL_WAIT_TIMEOUT_NS, clk_mhz); 18208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 18308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Find prescaler value that makes tmo_clk fit in 15-bits counter. */ 18408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg for (prescale = 0; prescale < 15; ++prescale) { 18508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (tmo_clk <= 0x7fff) 18608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg break; 18708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg tmo_clk >>= 1; 18808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 18908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (tmo_clk > 0x7fff) 19008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg tmo_clk = 0x7fff; 19108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 19208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Prescale divider (log2) */ 19308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(prescale, idev->base + TIMER_CLOCK_DIV); 19408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Timeout in divided clocks */ 19508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(WT_EN | WT_VALUE(tmo_clk), idev->base + WAIT_TIMER_CONTROL); 19608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 19708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Mask all master interrupt bits */ 19808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_disable(idev, ~0); 19908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 20008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Interrupt enable */ 20108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(0x01, idev->base + INTERRUPT_ENABLE); 20208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 20308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return 0; 20408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 20508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 20608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int i2c_m_rd(const struct i2c_msg *msg) 20708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 20808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return (msg->flags & I2C_M_RD) != 0; 20908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 21008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 21108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int i2c_m_ten(const struct i2c_msg *msg) 21208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 21308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return (msg->flags & I2C_M_TEN) != 0; 21408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 21508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 21608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int i2c_m_recv_len(const struct i2c_msg *msg) 21708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 21808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return (msg->flags & I2C_M_RECV_LEN) != 0; 21908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 22008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 22108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg/** 22208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * axxia_i2c_empty_rx_fifo - Fetch data from RX FIFO and update SMBus block 22308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * transfer length if this is the first byte of such a transfer. 22408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg */ 22508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int axxia_i2c_empty_rx_fifo(struct axxia_i2c_dev *idev) 22608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 22708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct i2c_msg *msg = idev->msg; 22808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg size_t rx_fifo_avail = readl(idev->base + MST_RX_FIFO); 22908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int bytes_to_transfer = min(rx_fifo_avail, msg->len - idev->msg_xfrd); 23008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 23108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg while (bytes_to_transfer-- > 0) { 23208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int c = readl(idev->base + MST_DATA); 23308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 23408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (idev->msg_xfrd == 0 && i2c_m_recv_len(msg)) { 23508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* 23608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * Check length byte for SMBus block read 23708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg */ 23808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (c <= 0 || c > I2C_SMBUS_BLOCK_MAX) { 23908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->msg_err = -EPROTO; 24008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_disable(idev, ~0); 24108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg complete(&idev->msg_complete); 24208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg break; 24308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 24408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg msg->len = 1 + c; 24508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(msg->len, idev->base + MST_RX_XFER); 24608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 24708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg msg->buf[idev->msg_xfrd++] = c; 24808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 24908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 25008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return 0; 25108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 25208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 25308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg/** 25408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * axxia_i2c_fill_tx_fifo - Fill TX FIFO from current message buffer. 25508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * @return: Number of bytes left to transfer. 25608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg */ 25708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int axxia_i2c_fill_tx_fifo(struct axxia_i2c_dev *idev) 25808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 25908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct i2c_msg *msg = idev->msg; 26008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg size_t tx_fifo_avail = FIFO_SIZE - readl(idev->base + MST_TX_FIFO); 26108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int bytes_to_transfer = min(tx_fifo_avail, msg->len - idev->msg_xfrd); 26208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int ret = msg->len - idev->msg_xfrd - bytes_to_transfer; 26308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 26408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg while (bytes_to_transfer-- > 0) 26508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(msg->buf[idev->msg_xfrd++], idev->base + MST_DATA); 26608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 26708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return ret; 26808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 26908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 27008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic irqreturn_t axxia_i2c_isr(int irq, void *_dev) 27108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 27208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct axxia_i2c_dev *idev = _dev; 27308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 status; 27408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 27508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (!(readl(idev->base + INTERRUPT_STATUS) & INT_MST)) 27608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return IRQ_NONE; 27708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 27808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Read interrupt status bits */ 27908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg status = readl(idev->base + MST_INT_STATUS); 28008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 28108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (!idev->msg) { 28208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_warn(idev->dev, "unexpected interrupt\n"); 28308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg goto out; 28408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 28508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 28608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* RX FIFO needs service? */ 28708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (i2c_m_rd(idev->msg) && (status & MST_STATUS_RFL)) 28808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg axxia_i2c_empty_rx_fifo(idev); 28908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 29008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* TX FIFO needs service? */ 29108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (!i2c_m_rd(idev->msg) && (status & MST_STATUS_TFL)) { 29208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (axxia_i2c_fill_tx_fifo(idev) == 0) 29308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_disable(idev, MST_STATUS_TFL); 29408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 29508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 29608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (status & MST_STATUS_SCC) { 29708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Stop completed */ 29808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_disable(idev, ~0); 29908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg complete(&idev->msg_complete); 30008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } else if (status & MST_STATUS_SNS) { 30108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Transfer done */ 30208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_disable(idev, ~0); 30308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (i2c_m_rd(idev->msg) && idev->msg_xfrd < idev->msg->len) 30408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg axxia_i2c_empty_rx_fifo(idev); 30508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg complete(&idev->msg_complete); 30608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } else if (unlikely(status & MST_STATUS_ERR)) { 30708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Transfer error */ 30808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_disable(idev, ~0); 30908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (status & MST_STATUS_AL) 31008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->msg_err = -EAGAIN; 31108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg else if (status & MST_STATUS_NAK) 31208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->msg_err = -ENXIO; 31308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg else 31408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->msg_err = -EIO; 31508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_dbg(idev->dev, "error %#x, addr=%#x rx=%u/%u tx=%u/%u\n", 31608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg status, 31708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->msg->addr, 31808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg readl(idev->base + MST_RX_BYTES_XFRD), 31908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg readl(idev->base + MST_RX_XFER), 32008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg readl(idev->base + MST_TX_BYTES_XFRD), 32108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg readl(idev->base + MST_TX_XFER)); 32208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg complete(&idev->msg_complete); 32308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 32408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 32508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergout: 32608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Clear interrupt */ 32708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(INT_MST, idev->base + INTERRUPT_STATUS); 32808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 32908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return IRQ_HANDLED; 33008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 33108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 33208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int axxia_i2c_xfer_msg(struct axxia_i2c_dev *idev, struct i2c_msg *msg) 33308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 33408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 int_mask = MST_STATUS_ERR | MST_STATUS_SNS; 33508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 rx_xfer, tx_xfer; 33608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 addr_1, addr_2; 33708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int ret; 33808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 33908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (msg->len > 255) { 34008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_warn(idev->dev, "unsupported length %u\n", msg->len); 34108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return -EINVAL; 34208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 34308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 34408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->msg = msg; 34508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->msg_xfrd = 0; 34608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->msg_err = 0; 34708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg reinit_completion(&idev->msg_complete); 34808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 34908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (i2c_m_ten(msg)) { 35008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* 10-bit address 35108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * addr_1: 5'b11110 | addr[9:8] | (R/nW) 35208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * addr_2: addr[7:0] 35308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg */ 35408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg addr_1 = 0xF0 | ((msg->addr >> 7) & 0x06); 35508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg addr_2 = msg->addr & 0xFF; 35608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } else { 35708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* 7-bit address 35808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * addr_1: addr[6:0] | (R/nW) 35908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg * addr_2: dont care 36008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg */ 36108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg addr_1 = (msg->addr << 1) & 0xFF; 36208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg addr_2 = 0; 36308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 36408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 36508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (i2c_m_rd(msg)) { 36608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* I2C read transfer */ 36708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg rx_xfer = i2c_m_recv_len(msg) ? I2C_SMBUS_BLOCK_MAX : msg->len; 36808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg tx_xfer = 0; 36908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg addr_1 |= 1; /* Set the R/nW bit of the address */ 37008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } else { 37108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* I2C write transfer */ 37208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg rx_xfer = 0; 37308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg tx_xfer = msg->len; 37408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 37508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 37608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(rx_xfer, idev->base + MST_RX_XFER); 37708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(tx_xfer, idev->base + MST_TX_XFER); 37808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(addr_1, idev->base + MST_ADDR_1); 37908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(addr_2, idev->base + MST_ADDR_2); 38008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 38108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (i2c_m_rd(msg)) 38208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int_mask |= MST_STATUS_RFL; 38308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg else if (axxia_i2c_fill_tx_fifo(idev) != 0) 38408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int_mask |= MST_STATUS_TFL; 38508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 38608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Start manual mode */ 38708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(CMD_MANUAL, idev->base + MST_COMMAND); 38808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 38908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_enable(idev, int_mask); 39008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 39108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg ret = wait_for_completion_timeout(&idev->msg_complete, 39208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg I2C_XFER_TIMEOUT); 39308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 39408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_disable(idev, int_mask); 39508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 39608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (readl(idev->base + MST_COMMAND) & CMD_BUSY) 39708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_warn(idev->dev, "busy after xfer\n"); 39808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 39908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (ret == 0) 40008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->msg_err = -ETIMEDOUT; 40108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 40208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (unlikely(idev->msg_err) && idev->msg_err != -ENXIO) 40308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg axxia_i2c_init(idev); 40408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 40508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return idev->msg_err; 40608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 40708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 40808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int axxia_i2c_stop(struct axxia_i2c_dev *idev) 40908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 41008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 int_mask = MST_STATUS_ERR | MST_STATUS_SCC; 41108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int ret; 41208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 41308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg reinit_completion(&idev->msg_complete); 41408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 41508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg /* Issue stop */ 41608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg writel(0xb, idev->base + MST_COMMAND); 41708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_enable(idev, int_mask); 41808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg ret = wait_for_completion_timeout(&idev->msg_complete, 41908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg I2C_STOP_TIMEOUT); 42008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_int_disable(idev, int_mask); 42108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (ret == 0) 42208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return -ETIMEDOUT; 42308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 42408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (readl(idev->base + MST_COMMAND) & CMD_BUSY) 42508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_warn(idev->dev, "busy after stop\n"); 42608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 42708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return 0; 42808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 42908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 43008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int 43108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergaxxia_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) 43208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 43308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct axxia_i2c_dev *idev = i2c_get_adapdata(adap); 43408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int i; 43508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int ret = 0; 43608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 43708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg for (i = 0; ret == 0 && i < num; ++i) 43808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg ret = axxia_i2c_xfer_msg(idev, &msgs[i]); 43908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 44008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg axxia_i2c_stop(idev); 44108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 44208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return ret ? : i; 44308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 44408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 44508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic u32 axxia_i2c_func(struct i2c_adapter *adap) 44608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 44708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg u32 caps = (I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR | 44808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg I2C_FUNC_SMBUS_EMUL | I2C_FUNC_SMBUS_BLOCK_DATA); 44908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return caps; 45008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 45108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 45208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic const struct i2c_algorithm axxia_i2c_algo = { 45308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg .master_xfer = axxia_i2c_xfer, 45408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg .functionality = axxia_i2c_func, 45508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg}; 45608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 45708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int axxia_i2c_probe(struct platform_device *pdev) 45808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 45908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct device_node *np = pdev->dev.of_node; 46008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct axxia_i2c_dev *idev = NULL; 46108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct resource *res; 46208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg void __iomem *base; 46308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int irq; 46408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg int ret = 0; 46508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 46608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev = devm_kzalloc(&pdev->dev, sizeof(*idev), GFP_KERNEL); 46708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (!idev) 46808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return -ENOMEM; 46908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 47008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 47108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg base = devm_ioremap_resource(&pdev->dev, res); 47208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (IS_ERR(base)) 47308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return PTR_ERR(base); 47408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 47508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg irq = platform_get_irq(pdev, 0); 47608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (irq < 0) { 47708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_err(&pdev->dev, "missing interrupt resource\n"); 47808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return irq; 47908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 48008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 48108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->i2c_clk = devm_clk_get(&pdev->dev, "i2c"); 48208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (IS_ERR(idev->i2c_clk)) { 48308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_err(&pdev->dev, "missing clock\n"); 48408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return PTR_ERR(idev->i2c_clk); 48508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 48608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 48708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->base = base; 48808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->dev = &pdev->dev; 48908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg init_completion(&idev->msg_complete); 49008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 49108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg of_property_read_u32(np, "clock-frequency", &idev->bus_clk_rate); 49208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (idev->bus_clk_rate == 0) 49308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->bus_clk_rate = 100000; /* default clock rate */ 49408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 49508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg ret = axxia_i2c_init(idev); 49608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (ret) { 49708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_err(&pdev->dev, "failed to initialize\n"); 49808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return ret; 49908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 50008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 50108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg ret = devm_request_irq(&pdev->dev, irq, axxia_i2c_isr, 0, 50208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg pdev->name, idev); 50308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (ret) { 50408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_err(&pdev->dev, "failed to claim IRQ%d\n", irq); 50508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return ret; 50608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 50708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 50808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg clk_prepare_enable(idev->i2c_clk); 50908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 51008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_set_adapdata(&idev->adapter, idev); 51108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg strlcpy(idev->adapter.name, pdev->name, sizeof(idev->adapter.name)); 51208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->adapter.owner = THIS_MODULE; 51308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->adapter.algo = &axxia_i2c_algo; 51408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->adapter.dev.parent = &pdev->dev; 51508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg idev->adapter.dev.of_node = pdev->dev.of_node; 51608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 51708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg platform_set_drvdata(pdev, idev); 51808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 51908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg ret = i2c_add_adapter(&idev->adapter); 52008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg if (ret) { 52108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg dev_err(&pdev->dev, "failed to add adapter\n"); 52208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return ret; 52308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg } 52408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 52508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return 0; 52608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 52708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 52808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic int axxia_i2c_remove(struct platform_device *pdev) 52908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg{ 53008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg struct axxia_i2c_dev *idev = platform_get_drvdata(pdev); 53108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 53208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg clk_disable_unprepare(idev->i2c_clk); 53308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg i2c_del_adapter(&idev->adapter); 53408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 53508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg return 0; 53608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg} 53708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 53808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg/* Match table for of_platform binding */ 53908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic const struct of_device_id axxia_i2c_of_match[] = { 54008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg { .compatible = "lsi,api2c", }, 54108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg {}, 54208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg}; 54308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 54408678b850cd0c49cc49c7fed0c93f720f85368e8Anders BergMODULE_DEVICE_TABLE(of, axxia_i2c_of_match); 54508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 54608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergstatic struct platform_driver axxia_i2c_driver = { 54708678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg .probe = axxia_i2c_probe, 54808678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg .remove = axxia_i2c_remove, 54908678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg .driver = { 55008678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg .name = "axxia-i2c", 55108678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg .of_match_table = axxia_i2c_of_match, 55208678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg }, 55308678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg}; 55408678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 55508678b850cd0c49cc49c7fed0c93f720f85368e8Anders Bergmodule_platform_driver(axxia_i2c_driver); 55608678b850cd0c49cc49c7fed0c93f720f85368e8Anders Berg 55708678b850cd0c49cc49c7fed0c93f720f85368e8Anders BergMODULE_DESCRIPTION("Axxia I2C Bus driver"); 55808678b850cd0c49cc49c7fed0c93f720f85368e8Anders BergMODULE_AUTHOR("Anders Berg <anders.berg@lsi.com>"); 55908678b850cd0c49cc49c7fed0c93f720f85368e8Anders BergMODULE_LICENSE("GPL v2"); 560