aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorGanesan Ramalingam <ganesanr@broadcom.com>2012-07-13 09:44:25 -0400
committerWolfram Sang <w.sang@pengutronix.de>2012-07-14 07:30:25 -0400
commit7326e38ffe894d0cd2904704b7d8c53d4a55d752 (patch)
tree7261b5bad76ce15dbad07f78a5b5e4b210f6d634 /drivers/i2c
parentd739a464f3b83cc879a2ba6aec33634c44068531 (diff)
i2c: i2c-ocores: support for 16bit and 32bit IO
Some architectures supports only 16-bit or 32-bit read/write access to their IO space. Add a 'reg-io-width' platform and OF parameter which specifies the IO width to support these platforms. reg-io-width can be specified as 1, 2 or 4, and has a default value of 1 if it is unspecified. Signed-off-by: Ganesan Ramalingam <ganesanr@broadcom.com> Signed-off-by: Jayachandran C <jayachandranc@netlogicmicro.com> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/i2c-ocores.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 9e0709d5fb36..bffd5501ac2d 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -30,6 +30,7 @@
30struct ocores_i2c { 30struct ocores_i2c {
31 void __iomem *base; 31 void __iomem *base;
32 u32 reg_shift; 32 u32 reg_shift;
33 u32 reg_io_width;
33 wait_queue_head_t wait; 34 wait_queue_head_t wait;
34 struct i2c_adapter adap; 35 struct i2c_adapter adap;
35 struct i2c_msg *msg; 36 struct i2c_msg *msg;
@@ -72,12 +73,22 @@ struct ocores_i2c {
72 73
73static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) 74static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
74{ 75{
75 iowrite8(value, i2c->base + (reg << i2c->reg_shift)); 76 if (i2c->reg_io_width == 4)
77 iowrite32(value, i2c->base + (reg << i2c->reg_shift));
78 else if (i2c->reg_io_width == 2)
79 iowrite16(value, i2c->base + (reg << i2c->reg_shift));
80 else
81 iowrite8(value, i2c->base + (reg << i2c->reg_shift));
76} 82}
77 83
78static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) 84static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg)
79{ 85{
80 return ioread8(i2c->base + (reg << i2c->reg_shift)); 86 if (i2c->reg_io_width == 4)
87 return ioread32(i2c->base + (reg << i2c->reg_shift));
88 else if (i2c->reg_io_width == 2)
89 return ioread16(i2c->base + (reg << i2c->reg_shift));
90 else
91 return ioread8(i2c->base + (reg << i2c->reg_shift));
81} 92}
82 93
83static void ocores_process(struct ocores_i2c *i2c) 94static void ocores_process(struct ocores_i2c *i2c)
@@ -244,6 +255,8 @@ static int ocores_i2c_of_probe(struct platform_device *pdev,
244 } 255 }
245 i2c->clock_khz = val / 1000; 256 i2c->clock_khz = val / 1000;
246 257
258 of_property_read_u32(pdev->dev.of_node, "reg-io-width",
259 &i2c->reg_io_width);
247 return 0; 260 return 0;
248} 261}
249#else 262#else
@@ -286,6 +299,7 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
286 pdata = pdev->dev.platform_data; 299 pdata = pdev->dev.platform_data;
287 if (pdata) { 300 if (pdata) {
288 i2c->reg_shift = pdata->reg_shift; 301 i2c->reg_shift = pdata->reg_shift;
302 i2c->reg_io_width = pdata->reg_io_width;
289 i2c->clock_khz = pdata->clock_khz; 303 i2c->clock_khz = pdata->clock_khz;
290 } else { 304 } else {
291 ret = ocores_i2c_of_probe(pdev, i2c); 305 ret = ocores_i2c_of_probe(pdev, i2c);
@@ -293,6 +307,9 @@ static int __devinit ocores_i2c_probe(struct platform_device *pdev)
293 return ret; 307 return ret;
294 } 308 }
295 309
310 if (i2c->reg_io_width == 0)
311 i2c->reg_io_width = 1; /* Set to default value */
312
296 ocores_init(i2c); 313 ocores_init(i2c);
297 314
298 init_waitqueue_head(&i2c->wait); 315 init_waitqueue_head(&i2c->wait);