> -----Original Message----- > From: Ben Dooks [mailto:ben-linux@xxxxxxxxx] > Sent: Monday, March 08, 2010 3:48 AM > To: Shilimkar, Santosh > Cc: ben-linux@xxxxxxxxx; linux-omap@xxxxxxxxxxxxxxx; linux-i2c@xxxxxxxxxxxxxxx; Syed, Rafiuddin; Cory > Maccarrone > Subject: Re: [PATCH] omap: i2c: Add i2c support on omap4 platform > > On Fri, Feb 19, 2010 at 10:03:00PM +0530, Santosh Shilimkar wrote: > > This patch is rebased version of earlier post to add I2C > > driver support to OMAP4 platform. On OMAP4, all > > I2C register address offsets are changed from OMAP1/2/3 I2C. > > In order to not have #ifdef's at various places in code, > > as well as to support multi-OMAP build, an array is created > > to hold the register addresses with it's offset. > > > > This patch was submitted, reviewed and acked on mailing list > > already. For more details refer below link > > http://www.mail-archive.com/linux-i2c@xxxxxxxxxxxxxxx/msg02281.html > > > > This updated verion has a depedancy on "Add support for 16-bit registers" > > posted on linux-omap. Below is the patch-works link for the same > > > > http://patchwork.kernel.org/patch/72295/ > > currently even with this patch applied it doesn't apply cleanly. May be it needs refresh after recent merges? Are you ok if I refresh this patch against latest mainline on top of below patch and repost http://patchwork.kernel.org/patch/72295/ > > > Signed-off-by: Syed Rafiuddin <rafiuddin.syed@xxxxxx> > > Signed-off-by: Santosh Shilimkar <santosh.shilimkar@xxxxxx> > > Acked-by: Kevin Hilman <khilman@xxxxxxxxxxxxxxxxxxx> > > Reviewed-by: Paul Walmsley <paul@xxxxxxxxx> > > Reviewed-by: Tony Lindgren <tony@xxxxxxxxxxx> > > Cc: Ben Dooks <ben-linux@xxxxxxxxx> > > Cc: Cory Maccarrone <darkstar6262@xxxxxxxxx> > > --- > > drivers/i2c/busses/i2c-omap.c | 146 ++++++++++++++++++++++++++++++++--------- > > 1 files changed, 114 insertions(+), 32 deletions(-) > > > > diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c > > index 9c3ce4d..7c15496 100644 > > --- a/drivers/i2c/busses/i2c-omap.c > > +++ b/drivers/i2c/busses/i2c-omap.c > > @@ -44,29 +44,37 @@ > > /* I2C controller revisions present on specific hardware */ > > #define OMAP_I2C_REV_ON_2430 0x36 > > #define OMAP_I2C_REV_ON_3430 0x3C > > +#define OMAP_I2C_REV_ON_4430 0x40 > > > > /* timeout waiting for the controller to respond */ > > #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) > > > > -#define OMAP_I2C_REV_REG 0x00 > > -#define OMAP_I2C_IE_REG 0x01 > > -#define OMAP_I2C_STAT_REG 0x02 > > -#define OMAP_I2C_IV_REG 0x03 > > /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */ > > -#define OMAP_I2C_WE_REG 0x03 > > -#define OMAP_I2C_SYSS_REG 0x04 > > -#define OMAP_I2C_BUF_REG 0x05 > > -#define OMAP_I2C_CNT_REG 0x06 > > -#define OMAP_I2C_DATA_REG 0x07 > > -#define OMAP_I2C_SYSC_REG 0x08 > > -#define OMAP_I2C_CON_REG 0x09 > > -#define OMAP_I2C_OA_REG 0x0a > > -#define OMAP_I2C_SA_REG 0x0b > > -#define OMAP_I2C_PSC_REG 0x0c > > -#define OMAP_I2C_SCLL_REG 0x0d > > -#define OMAP_I2C_SCLH_REG 0x0e > > -#define OMAP_I2C_SYSTEST_REG 0x0f > > -#define OMAP_I2C_BUFSTAT_REG 0x10 > > +enum { > > + OMAP_I2C_REV_REG = 0, > > + OMAP_I2C_IE_REG, > > + OMAP_I2C_STAT_REG, > > + OMAP_I2C_IV_REG, > > + OMAP_I2C_WE_REG, > > + OMAP_I2C_SYSS_REG, > > + OMAP_I2C_BUF_REG, > > + OMAP_I2C_CNT_REG, > > + OMAP_I2C_DATA_REG, > > + OMAP_I2C_SYSC_REG, > > + OMAP_I2C_CON_REG, > > + OMAP_I2C_OA_REG, > > + OMAP_I2C_SA_REG, > > + OMAP_I2C_PSC_REG, > > + OMAP_I2C_SCLL_REG, > > + OMAP_I2C_SCLH_REG, > > + OMAP_I2C_SYSTEST_REG, > > + OMAP_I2C_BUFSTAT_REG, > > + OMAP_I2C_REVNB_LO, > > + OMAP_I2C_REVNB_HI, > > + OMAP_I2C_IRQSTATUS_RAW, > > + OMAP_I2C_IRQENABLE_SET, > > + OMAP_I2C_IRQENABLE_CLR, > > +}; > > > > /* I2C Interrupt Enable Register (OMAP_I2C_IE): */ > > #define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */ > > @@ -169,6 +177,7 @@ struct omap_i2c_dev { > > u32 speed; /* Speed of bus in Khz */ > > u16 cmd_err; > > u8 *buf; > > + u8 *regs; > > size_t buf_len; > > struct i2c_adapter adapter; > > u8 fifo_size; /* use as flag and value > > @@ -187,15 +196,64 @@ struct omap_i2c_dev { > > u16 westate; > > }; > > > > +const static u8 reg_map[] = { > > + [OMAP_I2C_REV_REG] = 0x00, > > + [OMAP_I2C_IE_REG] = 0x01, > > + [OMAP_I2C_STAT_REG] = 0x02, > > + [OMAP_I2C_IV_REG] = 0x03, > > + [OMAP_I2C_WE_REG] = 0x03, > > + [OMAP_I2C_SYSS_REG] = 0x04, > > + [OMAP_I2C_BUF_REG] = 0x05, > > + [OMAP_I2C_CNT_REG] = 0x06, > > + [OMAP_I2C_DATA_REG] = 0x07, > > + [OMAP_I2C_SYSC_REG] = 0x08, > > + [OMAP_I2C_CON_REG] = 0x09, > > + [OMAP_I2C_OA_REG] = 0x0a, > > + [OMAP_I2C_SA_REG] = 0x0b, > > + [OMAP_I2C_PSC_REG] = 0x0c, > > + [OMAP_I2C_SCLL_REG] = 0x0d, > > + [OMAP_I2C_SCLH_REG] = 0x0e, > > + [OMAP_I2C_SYSTEST_REG] = 0x0f, > > + [OMAP_I2C_BUFSTAT_REG] = 0x10, > > +}; > > + > > +const static u8 omap4_reg_map[] = { > > + [OMAP_I2C_REV_REG] = 0x04, > > + [OMAP_I2C_IE_REG] = 0x2c, > > + [OMAP_I2C_STAT_REG] = 0x28, > > + [OMAP_I2C_IV_REG] = 0x34, > > + [OMAP_I2C_WE_REG] = 0x34, > > + [OMAP_I2C_SYSS_REG] = 0x90, > > + [OMAP_I2C_BUF_REG] = 0x94, > > + [OMAP_I2C_CNT_REG] = 0x98, > > + [OMAP_I2C_DATA_REG] = 0x9c, > > + [OMAP_I2C_SYSC_REG] = 0x20, > > + [OMAP_I2C_CON_REG] = 0xa4, > > + [OMAP_I2C_OA_REG] = 0xa8, > > + [OMAP_I2C_SA_REG] = 0xac, > > + [OMAP_I2C_PSC_REG] = 0xb0, > > + [OMAP_I2C_SCLL_REG] = 0xb4, > > + [OMAP_I2C_SCLH_REG] = 0xb8, > > + [OMAP_I2C_SYSTEST_REG] = 0xbC, > > + [OMAP_I2C_BUFSTAT_REG] = 0xc0, > > + [OMAP_I2C_REVNB_LO] = 0x00, > > + [OMAP_I2C_REVNB_HI] = 0x04, > > + [OMAP_I2C_IRQSTATUS_RAW] = 0x24, > > + [OMAP_I2C_IRQENABLE_SET] = 0x2c, > > + [OMAP_I2C_IRQENABLE_CLR] = 0x30, > > +}; > > + > > static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev, > > int reg, u16 val) > > { > > - __raw_writew(val, i2c_dev->base + (reg << i2c_dev->reg_shift)); > > + __raw_writew(val, i2c_dev->base + > > + (i2c_dev->regs[reg] << i2c_dev->reg_shift)); > > } > > > > static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) > > { > > - return __raw_readw(i2c_dev->base + (reg << i2c_dev->reg_shift)); > > + return __raw_readw(i2c_dev->base + > > + (i2c_dev->regs[reg] << i2c_dev->reg_shift)); > > } > > > > static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev) > > @@ -264,7 +322,11 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) > > WARN_ON(dev->idle); > > > > dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); > > - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); > > + if (dev->rev >= OMAP_I2C_REV_ON_4430) > > + omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1); > > + else > > + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); > > + > > if (dev->rev < OMAP_I2C_REV_2) { > > iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */ > > } else { > > @@ -329,7 +391,9 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > * REVISIT: Some wkup sources might not be needed. > > */ > > dev->westate = OMAP_I2C_WE_ALL; > > - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev->westate); > > + if (dev->rev < OMAP_I2C_REV_ON_4430) > > + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, > > + dev->westate); > > } > > } > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > @@ -356,7 +420,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > psc = fclk_rate / 12000000; > > } > > > > - if (cpu_is_omap2430() || cpu_is_omap34xx()) { > > + if (!(cpu_class_is_omap1() || cpu_is_omap2420())) { > > > > /* > > * HSI2C controller internal clk rate should be 19.2 Mhz for > > @@ -746,9 +810,12 @@ complete: > > if (dev->buf_len) { > > *dev->buf++ = w; > > dev->buf_len--; > > - /* Data reg from 2430 is 8 bit wide */ > > - if (!cpu_is_omap2430() && > > - !cpu_is_omap34xx()) { > > + /* > > + * Data reg in 2430, omap3 and > > + * omap4 is 8 bit wide > > + */ > > + if (cpu_class_is_omap1() || > > + cpu_is_omap2420()) { > > if (dev->buf_len) { > > *dev->buf++ = w >> 8; > > dev->buf_len--; > > @@ -786,9 +853,12 @@ complete: > > if (dev->buf_len) { > > w = *dev->buf++; > > dev->buf_len--; > > - /* Data reg from 2430 is 8 bit wide */ > > - if (!cpu_is_omap2430() && > > - !cpu_is_omap34xx()) { > > + /* > > + * Data reg in 2430, omap3 and > > + * omap4 is 8 bit wide > > + */ > > + if (cpu_class_is_omap1() || > > + cpu_is_omap2420()) { > > if (dev->buf_len) { > > w |= *dev->buf++ << 8; > > dev->buf_len--; > > @@ -897,6 +967,8 @@ omap_i2c_probe(struct platform_device *pdev) > > > > if (cpu_is_omap7xx()) > > dev->reg_shift = 1; > > + else if (cpu_is_omap44xx()) > > + dev->reg_shift = 0; > > else > > dev->reg_shift = 2; > > > > @@ -911,11 +983,16 @@ omap_i2c_probe(struct platform_device *pdev) > > if ((r = omap_i2c_get_clocks(dev)) != 0) > > goto err_iounmap; > > > > + if (cpu_is_omap44xx()) > > + dev->regs = (u8 *) omap4_reg_map; > > + else > > + dev->regs = (u8 *) reg_map; > > + > > omap_i2c_unidle(dev); > > > > dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > > > > - if (cpu_is_omap2430() || cpu_is_omap34xx()) { > > + if (!(cpu_class_is_omap1() || cpu_is_omap2420())) { > > u16 s; > > > > /* Set up the fifo size - Get total size */ > > @@ -927,8 +1004,13 @@ omap_i2c_probe(struct platform_device *pdev) > > * size. This is to ensure that we can handle the status on int > > * call back latencies. > > */ > > - dev->fifo_size = (dev->fifo_size / 2); > > - dev->b_hw = 1; /* Enable hardware fixes */ > > + if (dev->rev >= OMAP_I2C_REV_ON_4430) { > > + dev->fifo_size = 0; > > + dev->b_hw = 0; /* Disable hardware fixes */ > > + } else { > > + dev->fifo_size = (dev->fifo_size / 2); > > + dev->b_hw = 1; /* Enable hardware fixes */ > > + } > > } > > > > /* reset ASAP, clearing any IRQs */ > > -- > > 1.6.0.4 > > > > -- > > 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 > > -- > Ben (ben@xxxxxxxxx, http://www.fluff.org/) > > 'a smiley only costs 4 bytes' -- 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