diff options
author | Ganesan Ramalingam <ganesanr@broadcom.com> | 2012-07-13 09:44:25 -0400 |
---|---|---|
committer | Wolfram Sang <w.sang@pengutronix.de> | 2012-07-14 07:30:25 -0400 |
commit | 7326e38ffe894d0cd2904704b7d8c53d4a55d752 (patch) | |
tree | 7261b5bad76ce15dbad07f78a5b5e4b210f6d634 /drivers/i2c | |
parent | d739a464f3b83cc879a2ba6aec33634c44068531 (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.c | 21 |
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 @@ | |||
30 | struct ocores_i2c { | 30 | struct 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 | ||
73 | static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value) | 74 | static 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 | ||
78 | static inline u8 oc_getreg(struct ocores_i2c *i2c, int reg) | 84 | static 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 | ||
83 | static void ocores_process(struct ocores_i2c *i2c) | 94 | static 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); |