diff options
author | Paul Walmsley <paul@pwsan.com> | 2008-11-21 16:39:55 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2008-11-21 16:39:55 -0500 |
commit | 9c76b878eb3f837ff98b37aa254e6cc7942e946b (patch) | |
tree | be127e8a3d0cb5bd5fd6e4f937f350093c50412a /drivers/i2c/busses/i2c-omap.c | |
parent | 3831f154418e058616129942e8175dc4c7e4a1d8 (diff) |
i2c-omap: convert 'rev1' flag to generic 'rev' u8
i2c-omap discriminates only between "revision 1" or "greater than
revision 1." A following patch introduces code that must also
discriminate between rev2.x, rev3.6, and rev3.12 controllers. Support
this by storing the full revision data from the I2C_REV register, rather
than just a single bit.
The revision definitions may need to be extended for other ES levels
that aren't currently available here. rev3.6 is what's present on the
2430SDP here (unknown ES revision); rev3.12 is used on the 3430ES2
here.
Signed-off-by: Paul Walmsley <paul@pwsan.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'drivers/i2c/busses/i2c-omap.c')
-rw-r--r-- | drivers/i2c/busses/i2c-omap.c | 25 |
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 40a1e4bc92f1..3ac510d9c9ba 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c | |||
@@ -38,6 +38,13 @@ | |||
38 | #include <linux/clk.h> | 38 | #include <linux/clk.h> |
39 | #include <linux/io.h> | 39 | #include <linux/io.h> |
40 | 40 | ||
41 | /* I2C controller revisions */ | ||
42 | #define OMAP_I2C_REV_2 0x20 | ||
43 | |||
44 | /* I2C controller revisions present on specific hardware */ | ||
45 | #define OMAP_I2C_REV_ON_2430 0x36 | ||
46 | #define OMAP_I2C_REV_ON_3430 0x3C | ||
47 | |||
41 | /* timeout waiting for the controller to respond */ | 48 | /* timeout waiting for the controller to respond */ |
42 | #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) | 49 | #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) |
43 | 50 | ||
@@ -139,7 +146,7 @@ struct omap_i2c_dev { | |||
139 | * fifo_size==0 implies no fifo | 146 | * fifo_size==0 implies no fifo |
140 | * if set, should be trsh+1 | 147 | * if set, should be trsh+1 |
141 | */ | 148 | */ |
142 | unsigned rev1:1; | 149 | u8 rev; |
143 | unsigned b_hw:1; /* bad h/w fixes */ | 150 | unsigned b_hw:1; /* bad h/w fixes */ |
144 | unsigned idle:1; | 151 | unsigned idle:1; |
145 | u16 iestate; /* Saved interrupt register */ | 152 | u16 iestate; /* Saved interrupt register */ |
@@ -209,7 +216,7 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) | |||
209 | 216 | ||
210 | dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); | 217 | dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); |
211 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); | 218 | omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0); |
212 | if (dev->rev1) { | 219 | if (dev->rev < OMAP_I2C_REV_2) { |
213 | iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */ | 220 | iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG); /* Read clears */ |
214 | } else { | 221 | } else { |
215 | omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate); | 222 | omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate); |
@@ -231,7 +238,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) | |||
231 | unsigned long timeout; | 238 | unsigned long timeout; |
232 | unsigned long internal_clk = 0; | 239 | unsigned long internal_clk = 0; |
233 | 240 | ||
234 | if (!dev->rev1) { | 241 | if (dev->rev >= OMAP_I2C_REV_2) { |
235 | omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, OMAP_I2C_SYSC_SRST); | 242 | omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, OMAP_I2C_SYSC_SRST); |
236 | /* For some reason we need to set the EN bit before the | 243 | /* For some reason we need to set the EN bit before the |
237 | * reset done bit gets set. */ | 244 | * reset done bit gets set. */ |
@@ -710,6 +717,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
710 | struct omap_i2c_dev *dev; | 717 | struct omap_i2c_dev *dev; |
711 | struct i2c_adapter *adap; | 718 | struct i2c_adapter *adap; |
712 | struct resource *mem, *irq, *ioarea; | 719 | struct resource *mem, *irq, *ioarea; |
720 | void *isr; | ||
713 | int r; | 721 | int r; |
714 | u32 speed = 0; | 722 | u32 speed = 0; |
715 | 723 | ||
@@ -760,8 +768,7 @@ omap_i2c_probe(struct platform_device *pdev) | |||
760 | 768 | ||
761 | omap_i2c_unidle(dev); | 769 | omap_i2c_unidle(dev); |
762 | 770 | ||
763 | if (cpu_is_omap15xx()) | 771 | dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; |
764 | dev->rev1 = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) < 0x20; | ||
765 | 772 | ||
766 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { | 773 | if (cpu_is_omap2430() || cpu_is_omap34xx()) { |
767 | u16 s; | 774 | u16 s; |
@@ -782,16 +789,16 @@ omap_i2c_probe(struct platform_device *pdev) | |||
782 | /* reset ASAP, clearing any IRQs */ | 789 | /* reset ASAP, clearing any IRQs */ |
783 | omap_i2c_init(dev); | 790 | omap_i2c_init(dev); |
784 | 791 | ||
785 | r = request_irq(dev->irq, dev->rev1 ? omap_i2c_rev1_isr : omap_i2c_isr, | 792 | isr = (dev->rev < OMAP_I2C_REV_2) ? omap_i2c_rev1_isr : omap_i2c_isr; |
786 | 0, pdev->name, dev); | 793 | r = request_irq(dev->irq, isr, 0, pdev->name, dev); |
787 | 794 | ||
788 | if (r) { | 795 | if (r) { |
789 | dev_err(dev->dev, "failure requesting irq %i\n", dev->irq); | 796 | dev_err(dev->dev, "failure requesting irq %i\n", dev->irq); |
790 | goto err_unuse_clocks; | 797 | goto err_unuse_clocks; |
791 | } | 798 | } |
792 | r = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; | 799 | |
793 | dev_info(dev->dev, "bus %d rev%d.%d at %d kHz\n", | 800 | dev_info(dev->dev, "bus %d rev%d.%d at %d kHz\n", |
794 | pdev->id, r >> 4, r & 0xf, dev->speed); | 801 | pdev->id, dev->rev >> 4, dev->rev & 0xf, dev->speed); |
795 | 802 | ||
796 | omap_i2c_idle(dev); | 803 | omap_i2c_idle(dev); |
797 | 804 | ||