On Wed, 2016-12-07 at 17:55 +0000, Luis Oliveira wrote: > - The functions related to I2C master mode of operation were moved > to a single file: i2c-designware-master.c > - Common functions were moved into i2c-designware-common.c > - Common definitions were moved into i2c-designware-core.h (were in > core.c) > Yeah, there are some places that might be cleaned up but it came from the original and could be done in the future. Acked-by: Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> > Signed-off-by: Luis Oliveira <lolivei@xxxxxxxxxxxx> > --- > Changes V3->V4: (Andy Shevchenko) > - The name of the i2c-designware-src.c was changed to i2c-designware- > common.c > as suggested by Andy. > > drivers/i2c/busses/Makefile | 1 + > drivers/i2c/busses/i2c-designware-common.c | 252 > +++++++++++++++ > drivers/i2c/busses/i2c-designware-core.h | 131 ++++++++ > ...c-designware-core.c => i2c-designware-master.c} | 347 +----------- > --------- > 4 files changed, 390 insertions(+), 341 deletions(-) > create mode 100644 drivers/i2c/busses/i2c-designware-common.c > rename drivers/i2c/busses/{i2c-designware-core.c => i2c-designware- > master.c} (66%) > > diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile > index 1c1bac87a9db..4f8f6a2b9346 100644 > --- a/drivers/i2c/busses/Makefile > +++ b/drivers/i2c/busses/Makefile > @@ -40,6 +40,7 @@ obj-$(CONFIG_I2C_CBUS_GPIO) += i2c-cbus- > gpio.o > obj-$(CONFIG_I2C_CPM) += i2c-cpm.o > obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o > obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o > +i2c-designware-core-objs := i2c-designware-common.o i2c-designware- > master.o > obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware- > platform.o > i2c-designware-platform-objs := i2c-designware-platdrv.o > i2c-designware-platform-$(CONFIG_I2C_DESIGNWARE_BAYTRAIL) += i2c- > designware-baytrail.o > diff --git a/drivers/i2c/busses/i2c-designware-common.c > b/drivers/i2c/busses/i2c-designware-common.c > new file mode 100644 > index 000000000000..6afd2ff5d73f > --- /dev/null > +++ b/drivers/i2c/busses/i2c-designware-common.c > @@ -0,0 +1,252 @@ > +/* > + * Synopsys DesignWare I2C adapter driver (master only). > + * > + * Based on the TI DAVINCI I2C adapter driver. > + * > + * Copyright (C) 2006 Texas Instruments. > + * Copyright (C) 2007 MontaVista Software Inc. > + * Copyright (C) 2009 Provigent Ltd. > + * > + * ------------------------------------------------------------------ > ---------- > + * > + * This program is free software; you can redistribute it and/or > modify > + * it under the terms of the GNU General Public License as published > by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * ------------------------------------------------------------------ > ---------- > + * > + */ > +#include <linux/export.h> > +#include <linux/errno.h> > +#include <linux/err.h> > +#include <linux/i2c.h> > +#include <linux/interrupt.h> > +#include <linux/io.h> > +#include <linux/pm_runtime.h> > +#include <linux/delay.h> > +#include <linux/module.h> > +#include "i2c-designware-core.h" > + > +static char *abort_sources[] = { > + [ABRT_7B_ADDR_NOACK] = > + "slave address not acknowledged (7bit mode)", > + [ABRT_10ADDR1_NOACK] = > + "first address byte not acknowledged (10bit mode)", > + [ABRT_10ADDR2_NOACK] = > + "second address byte not acknowledged (10bit mode)", > + [ABRT_TXDATA_NOACK] = > + "data not acknowledged", > + [ABRT_GCALL_NOACK] = > + "no acknowledgement for a general call", > + [ABRT_GCALL_READ] = > + "read after general call", > + [ABRT_SBYTE_ACKDET] = > + "start byte acknowledged", > + [ABRT_SBYTE_NORSTRT] = > + "trying to send start byte when restart is disabled", > + [ABRT_10B_RD_NORSTRT] = > + "trying to read when restart is disabled (10bit > mode)", > + [ABRT_MASTER_DIS] = > + "trying to use disabled adapter", > + [ARB_LOST] = > + "lost arbitration", > +}; > + > +u32 dw_readl(struct dw_i2c_dev *dev, int offset) > +{ > + u32 value; > + > + if (dev->accessor_flags & ACCESS_16BIT) > + value = readw_relaxed(dev->base + offset) | > + (readw_relaxed(dev->base + offset + 2) << > 16); > + else > + value = readl_relaxed(dev->base + offset); > + > + if (dev->accessor_flags & ACCESS_SWAP) > + return swab32(value); > + else > + return value; > +} > + > +void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset) > +{ > + if (dev->accessor_flags & ACCESS_SWAP) > + b = swab32(b); > + > + if (dev->accessor_flags & ACCESS_16BIT) { > + writew_relaxed((u16)b, dev->base + offset); > + writew_relaxed((u16)(b >> 16), dev->base + offset + > 2); > + } else { > + writel_relaxed(b, dev->base + offset); > + } > +} > + > +u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int > offset) > +{ > + /* > + * DesignWare I2C core doesn't seem to have solid strategy to > meet > + * the tHD;STA timing spec. Configuring _HCNT based on tHIGH > spec > + * will result in violation of the tHD;STA spec. > + */ > + if (cond) > + /* > + * Conditional expression: > + * > + * IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH > + * > + * This is based on the DW manuals, and represents an > ideal > + * configuration. The resulting I2C bus speed will > be > + * faster than any of the others. > + * > + * If your hardware is free from tHD;STA issue, try > this one. > + */ > + return (ic_clk * tSYMBOL + 500000) / 1000000 - 8 + > offset; > + else > + /* > + * Conditional expression: > + * > + * IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf) > + * > + * This is just experimental rule; the tHD;STA period > turned > + * out to be proportinal to (_HCNT + 3). With this > setting, > + * we could meet both tHIGH and tHD;STA timing specs. > + * > + * If unsure, you'd better to take this alternative. > + * > + * The reason why we need to take into account "tf" > here, > + * is the same as described in i2c_dw_scl_lcnt(). > + */ > + return (ic_clk * (tSYMBOL + tf) + 500000) / 1000000 > + - 3 + offset; > +} > + > +u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) > +{ > + /* > + * Conditional expression: > + * > + * IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf) > + * > + * DW I2C core starts counting the SCL CNTs for the LOW > period > + * of the SCL clock (tLOW) as soon as it pulls the SCL line. > + * In order to meet the tLOW timing spec, we need to take > into > + * account the fall time of SCL signal (tf). Default tf > value > + * should be 0.3 us, for safety. > + */ > + return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + > offset; > +} > + > +void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) > +{ > + dw_writel(dev, enable, DW_IC_ENABLE); > +} > + > +void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable) > +{ > + int timeout = 100; > + > + do { > + __i2c_dw_enable(dev, enable); > + if ((dw_readl(dev, DW_IC_ENABLE_STATUS) & 1) == > enable) > + return; > + > + /* > + * Wait 10 times the signaling period of the highest > I2C > + * transfer supported by the driver (for 400KHz this > is > + * 25us) as described in the DesignWare I2C databook. > + */ > + usleep_range(25, 250); > + } while (timeout--); > + > + dev_warn(dev->dev, "timeout in %sabling adapter\n", > + enable ? "en" : "dis"); > +} > + > +unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev) > +{ > + /* > + * Clock is not necessary if we got LCNT/HCNT values directly > from > + * the platform code. > + */ > + if (WARN_ON_ONCE(!dev->get_clk_rate_khz)) > + return 0; > + return dev->get_clk_rate_khz(dev); > +} > + > +int i2c_dw_acquire_lock(struct dw_i2c_dev *dev) > +{ > + int ret; > + > + if (!dev->acquire_lock) > + return 0; > + > + ret = dev->acquire_lock(dev); > + if (!ret) > + return 0; > + > + dev_err(dev->dev, "couldn't acquire bus ownership\n"); > + > + return ret; > +} > + > +void i2c_dw_release_lock(struct dw_i2c_dev *dev) > +{ > + if (dev->release_lock) > + dev->release_lock(dev); > +} > + > +/* > + * Waiting for bus not busy > + */ > +int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) > +{ > + int timeout = TIMEOUT; > + > + while (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) { > + if (timeout <= 0) { > + dev_warn(dev->dev, "timeout waiting for bus > ready\n"); > + return -ETIMEDOUT; > + } > + timeout--; > + usleep_range(1000, 1100); > + } > + > + return 0; > +} > + > +int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev) > +{ > + unsigned long abort_source = dev->abort_source; > + int i; > + > + if (abort_source & DW_IC_TX_ABRT_NOACK) { > + for_each_set_bit(i, &abort_source, > ARRAY_SIZE(abort_sources)) > + dev_dbg(dev->dev, > + "%s: %s\n", __func__, > abort_sources[i]); > + return -EREMOTEIO; > + } > + > + for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) > + dev_err(dev->dev, "%s: %s\n", __func__, > abort_sources[i]); > + > + if (abort_source & DW_IC_TX_ARB_LOST) > + return -EAGAIN; > + else if (abort_source & DW_IC_TX_ABRT_GCALL_READ) > + return -EINVAL; /* wrong msgs[] data */ > + else > + return -EIO; > +} > + > +u32 i2c_dw_func(struct i2c_adapter *adap) > +{ > + struct dw_i2c_dev *dev = i2c_get_adapdata(adap); > + return dev->functionality; > +} > + > +MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core"); > +MODULE_LICENSE("GPL"); > diff --git a/drivers/i2c/busses/i2c-designware-core.h > b/drivers/i2c/busses/i2c-designware-core.h > index 26250b425e2f..8bba7a37c3ce 100644 > --- a/drivers/i2c/busses/i2c-designware-core.h > +++ b/drivers/i2c/busses/i2c-designware-core.h > @@ -40,6 +40,124 @@ > #define DW_IC_CON_RESTART_EN 0x20 > #define DW_IC_CON_SLAVE_DISABLE 0x40 > > +/* > + * Registers offset > + */ > +#define DW_IC_CON 0x0 > +#define DW_IC_TAR 0x4 > +#define DW_IC_DATA_CMD 0x10 > +#define DW_IC_SS_SCL_HCNT 0x14 > +#define DW_IC_SS_SCL_LCNT 0x18 > +#define DW_IC_FS_SCL_HCNT 0x1c > +#define DW_IC_FS_SCL_LCNT 0x20 > +#define DW_IC_HS_SCL_HCNT 0x24 > +#define DW_IC_HS_SCL_LCNT 0x28 > +#define DW_IC_INTR_STAT 0x2c > +#define DW_IC_INTR_MASK 0x30 > +#define DW_IC_RAW_INTR_STAT 0x34 > +#define DW_IC_RX_TL 0x38 > +#define DW_IC_TX_TL 0x3c > +#define DW_IC_CLR_INTR 0x40 > +#define DW_IC_CLR_RX_UNDER 0x44 > +#define DW_IC_CLR_RX_OVER 0x48 > +#define DW_IC_CLR_TX_OVER 0x4c > +#define DW_IC_CLR_RD_REQ 0x50 > +#define DW_IC_CLR_TX_ABRT 0x54 > +#define DW_IC_CLR_RX_DONE 0x58 > +#define DW_IC_CLR_ACTIVITY 0x5c > +#define DW_IC_CLR_STOP_DET 0x60 > +#define DW_IC_CLR_START_DET 0x64 > +#define DW_IC_CLR_GEN_CALL 0x68 > +#define DW_IC_ENABLE 0x6c > +#define DW_IC_STATUS 0x70 > +#define DW_IC_TXFLR 0x74 > +#define DW_IC_RXFLR 0x78 > +#define DW_IC_SDA_HOLD 0x7c > +#define DW_IC_TX_ABRT_SOURCE 0x80 > +#define DW_IC_ENABLE_STATUS 0x9c > +#define DW_IC_COMP_PARAM_1 0xf4 > +#define DW_IC_COMP_VERSION 0xf8 > +#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A > +#define DW_IC_COMP_TYPE 0xfc > +#define DW_IC_COMP_TYPE_VALUE 0x44570140 > + > +#define DW_IC_INTR_RX_UNDER 0x001 > +#define DW_IC_INTR_RX_OVER 0x002 > +#define DW_IC_INTR_RX_FULL 0x004 > +#define DW_IC_INTR_TX_OVER 0x008 > +#define DW_IC_INTR_TX_EMPTY 0x010 > +#define DW_IC_INTR_RD_REQ 0x020 > +#define DW_IC_INTR_TX_ABRT 0x040 > +#define DW_IC_INTR_RX_DONE 0x080 > +#define DW_IC_INTR_ACTIVITY 0x100 > +#define DW_IC_INTR_STOP_DET 0x200 > +#define DW_IC_INTR_START_DET 0x400 > +#define DW_IC_INTR_GEN_CALL 0x800 > + > +#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | > \ > + DW_IC_INTR_TX_ABRT | \ > + DW_IC_INTR_STOP_DET) > +#define DW_IC_INTR_MASTER_MASK (DW_IC_INTR_DEFAULT_MAS > K | \ > + DW_IC_INTR_TX_EMPTY) > +#define DW_IC_STATUS_ACTIVITY 0x1 > +#define DW_IC_STATUS_TFE BIT(2) > +#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) > + > +#define DW_IC_SDA_HOLD_RX_SHIFT 16 > +#define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, > DW_IC_SDA_HOLD_RX_SHIFT) > + > +#define DW_IC_ERR_TX_ABRT 0x1 > + > +#define DW_IC_TAR_10BITADDR_MASTER BIT(12) > + > +#define DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH (BIT(2) | BIT(3)) > +#define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK GENMASK(3, 2) > + > +/* > + * status codes > + */ > +#define STATUS_IDLE 0x0 > +#define STATUS_WRITE_IN_PROGRESS 0x1 > +#define STATUS_READ_IN_PROGRESS 0x2 > + > +#define TIMEOUT 20 /* ms */ > + > +/* > + * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register > + * > + * only expected abort codes are listed here > + * refer to the datasheet for the full list > + */ > +#define ABRT_7B_ADDR_NOACK 0 > +#define ABRT_10ADDR1_NOACK 1 > +#define ABRT_10ADDR2_NOACK 2 > +#define ABRT_TXDATA_NOACK 3 > +#define ABRT_GCALL_NOACK 4 > +#define ABRT_GCALL_READ 5 > +#define ABRT_SBYTE_ACKDET 7 > +#define ABRT_SBYTE_NORSTRT 9 > +#define ABRT_10B_RD_NORSTRT 10 > +#define ABRT_MASTER_DIS 11 > +#define ARB_LOST 12 > + > +#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << > ABRT_7B_ADDR_NOACK) > +#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << > ABRT_10ADDR1_NOACK) > +#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << > ABRT_10ADDR2_NOACK) > +#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK) > +#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK) > +#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ) > +#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET) > +#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << > ABRT_SBYTE_NORSTRT) > +#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << > ABRT_10B_RD_NORSTRT) > +#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS) > +#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST) > + > +#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOA > CK | \ > + DW_IC_TX_ABRT_10ADDR1_NOACK > | \ > + DW_IC_TX_ABRT_10ADDR2_NOACK > | \ > + DW_IC_TX_ABRT_TXDATA_NOACK | > \ > + DW_IC_TX_ABRT_GCALL_NOACK) > + > > /** > * struct dw_i2c_dev - private i2c-designware data > @@ -132,6 +250,19 @@ struct dw_i2c_dev { > #define ACCESS_16BIT 0x00000002 > #define ACCESS_INTR_MASK 0x00000004 > > +u32 dw_readl(struct dw_i2c_dev *dev, int offset); > +void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset); > +u32 i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int > offset); > +u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset); > +void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable); > +void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool enable); > +unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev); > +int i2c_dw_acquire_lock(struct dw_i2c_dev *dev); > +void i2c_dw_release_lock(struct dw_i2c_dev *dev); > +int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev); > +int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev); > +u32 i2c_dw_func(struct i2c_adapter *adap); > + > extern int i2c_dw_init(struct dw_i2c_dev *dev); > extern void i2c_dw_disable(struct dw_i2c_dev *dev); > extern void i2c_dw_disable_int(struct dw_i2c_dev *dev); > diff --git a/drivers/i2c/busses/i2c-designware-core.c > b/drivers/i2c/busses/i2c-designware-master.c > similarity index 66% > rename from drivers/i2c/busses/i2c-designware-core.c > rename to drivers/i2c/busses/i2c-designware-master.c > index a51addfde565..9943addac3d7 100644 > --- a/drivers/i2c/busses/i2c-designware-core.c > +++ b/drivers/i2c/busses/i2c-designware-master.c > @@ -32,305 +32,18 @@ > #include <linux/module.h> > #include "i2c-designware-core.h" > > -/* > - * Registers offset > - */ > -#define DW_IC_CON 0x0 > -#define DW_IC_TAR 0x4 > -#define DW_IC_DATA_CMD 0x10 > -#define DW_IC_SS_SCL_HCNT 0x14 > -#define DW_IC_SS_SCL_LCNT 0x18 > -#define DW_IC_FS_SCL_HCNT 0x1c > -#define DW_IC_FS_SCL_LCNT 0x20 > -#define DW_IC_HS_SCL_HCNT 0x24 > -#define DW_IC_HS_SCL_LCNT 0x28 > -#define DW_IC_INTR_STAT 0x2c > -#define DW_IC_INTR_MASK 0x30 > -#define DW_IC_RAW_INTR_STAT 0x34 > -#define DW_IC_RX_TL 0x38 > -#define DW_IC_TX_TL 0x3c > -#define DW_IC_CLR_INTR 0x40 > -#define DW_IC_CLR_RX_UNDER 0x44 > -#define DW_IC_CLR_RX_OVER 0x48 > -#define DW_IC_CLR_TX_OVER 0x4c > -#define DW_IC_CLR_RD_REQ 0x50 > -#define DW_IC_CLR_TX_ABRT 0x54 > -#define DW_IC_CLR_RX_DONE 0x58 > -#define DW_IC_CLR_ACTIVITY 0x5c > -#define DW_IC_CLR_STOP_DET 0x60 > -#define DW_IC_CLR_START_DET 0x64 > -#define DW_IC_CLR_GEN_CALL 0x68 > -#define DW_IC_ENABLE 0x6c > -#define DW_IC_STATUS 0x70 > -#define DW_IC_TXFLR 0x74 > -#define DW_IC_RXFLR 0x78 > -#define DW_IC_SDA_HOLD 0x7c > -#define DW_IC_TX_ABRT_SOURCE 0x80 > -#define DW_IC_ENABLE_STATUS 0x9c > -#define DW_IC_COMP_PARAM_1 0xf4 > -#define DW_IC_COMP_VERSION 0xf8 > -#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A > -#define DW_IC_COMP_TYPE 0xfc > -#define DW_IC_COMP_TYPE_VALUE 0x44570140 > - > -#define DW_IC_INTR_RX_UNDER 0x001 > -#define DW_IC_INTR_RX_OVER 0x002 > -#define DW_IC_INTR_RX_FULL 0x004 > -#define DW_IC_INTR_TX_OVER 0x008 > -#define DW_IC_INTR_TX_EMPTY 0x010 > -#define DW_IC_INTR_RD_REQ 0x020 > -#define DW_IC_INTR_TX_ABRT 0x040 > -#define DW_IC_INTR_RX_DONE 0x080 > -#define DW_IC_INTR_ACTIVITY 0x100 > -#define DW_IC_INTR_STOP_DET 0x200 > -#define DW_IC_INTR_START_DET 0x400 > -#define DW_IC_INTR_GEN_CALL 0x800 > - > -#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | > \ > - DW_IC_INTR_TX_ABRT | \ > - DW_IC_INTR_STOP_DET) > - > -#define DW_IC_INTR_MASTER_MASK (DW_IC_INTR_DEFAULT_MAS > K | \ > - DW_IC_INTR_TX_EMPTY) > - > -#define DW_IC_STATUS_ACTIVITY 0x1 > - > -#define DW_IC_SDA_HOLD_RX_SHIFT 16 > -#define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, > DW_IC_SDA_HOLD_RX_SHIFT) > - > -#define DW_IC_ERR_TX_ABRT 0x1 > - > -#define DW_IC_TAR_10BITADDR_MASTER BIT(12) > - > -#define DW_IC_COMP_PARAM_1_SPEED_MODE_HIGH (BIT(2) | BIT(3)) > -#define DW_IC_COMP_PARAM_1_SPEED_MODE_MASK GENMASK(3, 2) > - > -/* > - * status codes > - */ > -#define STATUS_IDLE 0x0 > -#define STATUS_WRITE_IN_PROGRESS 0x1 > -#define STATUS_READ_IN_PROGRESS 0x2 > - > -#define TIMEOUT 20 /* ms */ > - > -/* > - * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register > - * > - * only expected abort codes are listed here > - * refer to the datasheet for the full list > - */ > -#define ABRT_7B_ADDR_NOACK 0 > -#define ABRT_10ADDR1_NOACK 1 > -#define ABRT_10ADDR2_NOACK 2 > -#define ABRT_TXDATA_NOACK 3 > -#define ABRT_GCALL_NOACK 4 > -#define ABRT_GCALL_READ 5 > -#define ABRT_SBYTE_ACKDET 7 > -#define ABRT_SBYTE_NORSTRT 9 > -#define ABRT_10B_RD_NORSTRT 10 > -#define ABRT_MASTER_DIS 11 > -#define ARB_LOST 12 > - > -#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << > ABRT_7B_ADDR_NOACK) > -#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << > ABRT_10ADDR1_NOACK) > -#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << > ABRT_10ADDR2_NOACK) > -#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK) > -#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK) > -#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ) > -#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET) > -#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << > ABRT_SBYTE_NORSTRT) > -#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << > ABRT_10B_RD_NORSTRT) > -#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS) > -#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST) > - > -#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOA > CK | \ > - DW_IC_TX_ABRT_10ADDR1_NOACK > | \ > - DW_IC_TX_ABRT_10ADDR2_NOACK > | \ > - DW_IC_TX_ABRT_TXDATA_NOACK | > \ > - DW_IC_TX_ABRT_GCALL_NOACK) > - > -static char *abort_sources[] = { > - [ABRT_7B_ADDR_NOACK] = > - "slave address not acknowledged (7bit mode)", > - [ABRT_10ADDR1_NOACK] = > - "first address byte not acknowledged (10bit mode)", > - [ABRT_10ADDR2_NOACK] = > - "second address byte not acknowledged (10bit mode)", > - [ABRT_TXDATA_NOACK] = > - "data not acknowledged", > - [ABRT_GCALL_NOACK] = > - "no acknowledgement for a general call", > - [ABRT_GCALL_READ] = > - "read after general call", > - [ABRT_SBYTE_ACKDET] = > - "start byte acknowledged", > - [ABRT_SBYTE_NORSTRT] = > - "trying to send start byte when restart is disabled", > - [ABRT_10B_RD_NORSTRT] = > - "trying to read when restart is disabled (10bit > mode)", > - [ABRT_MASTER_DIS] = > - "trying to use disabled adapter", > - [ARB_LOST] = > - "lost arbitration", > -}; > - > -static u32 dw_readl(struct dw_i2c_dev *dev, int offset) > -{ > - u32 value; > - > - if (dev->accessor_flags & ACCESS_16BIT) > - value = readw_relaxed(dev->base + offset) | > - (readw_relaxed(dev->base + offset + 2) << > 16); > - else > - value = readl_relaxed(dev->base + offset); > - > - if (dev->accessor_flags & ACCESS_SWAP) > - return swab32(value); > - else > - return value; > -} > - > -static void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset) > -{ > - if (dev->accessor_flags & ACCESS_SWAP) > - b = swab32(b); > - > - if (dev->accessor_flags & ACCESS_16BIT) { > - writew_relaxed((u16)b, dev->base + offset); > - writew_relaxed((u16)(b >> 16), dev->base + offset + > 2); > - } else { > - writel_relaxed(b, dev->base + offset); > - } > -} > - > static void i2c_dw_configure_fifo_master(struct dw_i2c_dev *dev) > { > /* Configure Tx/Rx FIFO threshold levels */ > dw_writel(dev, dev->tx_fifo_depth / 2, DW_IC_TX_TL); > dw_writel(dev, 0, DW_IC_RX_TL); > > - /* configure the i2c master */ > + /* configure the I2C master */ > dw_writel(dev, dev->master_cfg, DW_IC_CON); > } > > -static u32 > -i2c_dw_scl_hcnt(u32 ic_clk, u32 tSYMBOL, u32 tf, int cond, int > offset) > -{ > - /* > - * DesignWare I2C core doesn't seem to have solid strategy to > meet > - * the tHD;STA timing spec. Configuring _HCNT based on tHIGH > spec > - * will result in violation of the tHD;STA spec. > - */ > - if (cond) > - /* > - * Conditional expression: > - * > - * IC_[FS]S_SCL_HCNT + (1+4+3) >= IC_CLK * tHIGH > - * > - * This is based on the DW manuals, and represents an > ideal > - * configuration. The resulting I2C bus speed will > be > - * faster than any of the others. > - * > - * If your hardware is free from tHD;STA issue, try > this one. > - */ > - return (ic_clk * tSYMBOL + 500000) / 1000000 - 8 + > offset; > - else > - /* > - * Conditional expression: > - * > - * IC_[FS]S_SCL_HCNT + 3 >= IC_CLK * (tHD;STA + tf) > - * > - * This is just experimental rule; the tHD;STA period > turned > - * out to be proportinal to (_HCNT + 3). With this > setting, > - * we could meet both tHIGH and tHD;STA timing specs. > - * > - * If unsure, you'd better to take this alternative. > - * > - * The reason why we need to take into account "tf" > here, > - * is the same as described in i2c_dw_scl_lcnt(). > - */ > - return (ic_clk * (tSYMBOL + tf) + 500000) / 1000000 > - - 3 + offset; > -} > - > -static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset) > -{ > - /* > - * Conditional expression: > - * > - * IC_[FS]S_SCL_LCNT + 1 >= IC_CLK * (tLOW + tf) > - * > - * DW I2C core starts counting the SCL CNTs for the LOW > period > - * of the SCL clock (tLOW) as soon as it pulls the SCL line. > - * In order to meet the tLOW timing spec, we need to take > into > - * account the fall time of SCL signal (tf). Default tf > value > - * should be 0.3 us, for safety. > - */ > - return ((ic_clk * (tLOW + tf) + 500000) / 1000000) - 1 + > offset; > -} > - > -static void __i2c_dw_enable(struct dw_i2c_dev *dev, bool enable) > -{ > - dw_writel(dev, enable, DW_IC_ENABLE); > -} > - > -static void __i2c_dw_enable_and_wait(struct dw_i2c_dev *dev, bool > enable) > -{ > - int timeout = 100; > - > - do { > - __i2c_dw_enable(dev, enable); > - if ((dw_readl(dev, DW_IC_ENABLE_STATUS) & 1) == > enable) > - return; > - > - /* > - * Wait 10 times the signaling period of the highest > I2C > - * transfer supported by the driver (for 400KHz this > is > - * 25us) as described in the DesignWare I2C databook. > - */ > - usleep_range(25, 250); > - } while (timeout--); > - > - dev_warn(dev->dev, "timeout in %sabling adapter\n", > - enable ? "en" : "dis"); > -} > - > -static unsigned long i2c_dw_clk_rate(struct dw_i2c_dev *dev) > -{ > - /* > - * Clock is not necessary if we got LCNT/HCNT values directly > from > - * the platform code. > - */ > - if (WARN_ON_ONCE(!dev->get_clk_rate_khz)) > - return 0; > - return dev->get_clk_rate_khz(dev); > -} > - > -static int i2c_dw_acquire_lock(struct dw_i2c_dev *dev) > -{ > - int ret; > - > - if (!dev->acquire_lock) > - return 0; > - > - ret = dev->acquire_lock(dev); > - if (!ret) > - return 0; > - > - dev_err(dev->dev, "couldn't acquire bus ownership\n"); > - > - return ret; > -} > - > -static void i2c_dw_release_lock(struct dw_i2c_dev *dev) > -{ > - if (dev->release_lock) > - dev->release_lock(dev); > -} > - > /** > - * i2c_dw_init() - initialize the designware i2c hardware > + * i2c_dw_init() - initialize the designware i2c master hardware > * @dev: device private data > * > * This functions configures and enables the I2C. > @@ -462,25 +175,6 @@ int i2c_dw_init(struct dw_i2c_dev *dev) > } > EXPORT_SYMBOL_GPL(i2c_dw_init); > > -/* > - * Waiting for bus not busy > - */ > -static int i2c_dw_wait_bus_not_busy(struct dw_i2c_dev *dev) > -{ > - int timeout = TIMEOUT; > - > - while (dw_readl(dev, DW_IC_STATUS) & DW_IC_STATUS_ACTIVITY) { > - if (timeout <= 0) { > - dev_warn(dev->dev, "timeout waiting for bus > ready\n"); > - return -ETIMEDOUT; > - } > - timeout--; > - usleep_range(1000, 1100); > - } > - > - return 0; > -} > - > static void i2c_dw_xfer_init(struct dw_i2c_dev *dev) > { > struct i2c_msg *msgs = dev->msgs; > @@ -715,29 +409,6 @@ i2c_dw_read(struct dw_i2c_dev *dev) > } > } > > -static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev) > -{ > - unsigned long abort_source = dev->abort_source; > - int i; > - > - if (abort_source & DW_IC_TX_ABRT_NOACK) { > - for_each_set_bit(i, &abort_source, > ARRAY_SIZE(abort_sources)) > - dev_dbg(dev->dev, > - "%s: %s\n", __func__, > abort_sources[i]); > - return -EREMOTEIO; > - } > - > - for_each_set_bit(i, &abort_source, ARRAY_SIZE(abort_sources)) > - dev_err(dev->dev, "%s: %s\n", __func__, > abort_sources[i]); > - > - if (abort_source & DW_IC_TX_ARB_LOST) > - return -EAGAIN; > - else if (abort_source & DW_IC_TX_ABRT_GCALL_READ) > - return -EINVAL; /* wrong msgs[] data */ > - else > - return -EIO; > -} > - > /* > * Prepare controller for a transaction and call i2c_dw_xfer_msg > */ > @@ -825,12 +496,6 @@ i2c_dw_xfer(struct i2c_adapter *adap, struct > i2c_msg msgs[], int num) > return ret; > } > > -static u32 i2c_dw_func(struct i2c_adapter *adap) > -{ > - struct dw_i2c_dev *dev = i2c_get_adapdata(adap); > - return dev->functionality; > -} > - > static struct i2c_algorithm i2c_dw_algo = { > .master_xfer = i2c_dw_xfer, > .functionality = i2c_dw_func, > @@ -892,10 +557,10 @@ static u32 i2c_dw_read_clear_intrbits(struct > dw_i2c_dev *dev) > } > > /* > - * Interrupt service routine. This gets called whenever an I2C > interrupt > + * Interrupt service routine. This gets called whenever an I2C master > interrupt > * occurs. > */ > -int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev) > +static int i2c_dw_irq_handler_master(struct dw_i2c_dev *dev) > { > u32 stat; > > @@ -940,7 +605,7 @@ int i2c_dw_irq_handler_master(struct dw_i2c_dev > *dev) > static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) > { > struct dw_i2c_dev *dev = dev_id; > - u32 stat, enabled, mode; > + u32 stat, enabled; > > enabled = dw_readl(dev, DW_IC_ENABLE); > stat = dw_readl(dev, DW_IC_RAW_INTR_STAT); > @@ -1041,5 +706,5 @@ int i2c_dw_probe(struct dw_i2c_dev *dev) > } > EXPORT_SYMBOL_GPL(i2c_dw_probe); > > -MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter core"); > +MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter master"); > MODULE_LICENSE("GPL"); -- Andy Shevchenko <andriy.shevchenko@xxxxxxxxxxxxxxx> Intel Finland Oy -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html