Re: [PATCH] omap: i2c: Add i2c support on omap4 platform

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.
 
> 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-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux