aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-10-14 11:30:03 -0400
committerJean Delvare <khali@mahadeva.delvare>2008-10-14 11:30:03 -0400
commit4ad48e6ab18c86255f534a2cdcba5a4ead57a15f (patch)
treeef6604e3090a77ea845349299658c300025af430 /drivers
parentce5640330b10c6cecfbda50569b9f53c081d10c6 (diff)
i2c: Renesas Highlander FPGA SMBus support
This adds support for the SMBus adapter found in the various FPGAs on the Renesas Highlander platforms. Particularly the R0P7780LC0011RL and R0P7785LC0011RL FPGAs. Functionality is fairly restricted, in that only byte and block data transfers are supported. Normal/fast mode and IRQ/polling are also supported. Primarily used for various RTCs and thermal sensors. Signed-off-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/Kconfig12
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-highlander.c498
3 files changed, 511 insertions, 0 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 6ee997b2817c..e54b9fe46804 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -330,6 +330,18 @@ config I2C_GPIO
330 This is a very simple bitbanging I2C driver utilizing the 330 This is a very simple bitbanging I2C driver utilizing the
331 arch-neutral GPIO API to control the SCL and SDA lines. 331 arch-neutral GPIO API to control the SCL and SDA lines.
332 332
333config I2C_HIGHLANDER
334 tristate "Highlander FPGA SMBus interface"
335 depends on SH_HIGHLANDER
336 help
337 If you say yes to this option, support will be included for
338 the SMBus interface located in the FPGA on various Highlander
339 boards, particularly the R0P7780LC0011RL and R0P7785LC0011RL
340 FPGAs. This is wholly unrelated to the SoC I2C.
341
342 This driver can also be built as a module. If so, the module
343 will be called i2c-highlander.
344
333config I2C_IBM_IIC 345config I2C_IBM_IIC
334 tristate "IBM PPC 4xx on-chip I2C interface" 346 tristate "IBM PPC 4xx on-chip I2C interface"
335 depends on 4xx 347 depends on 4xx
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 97dbfa2107fe..0c2c4b26cdf1 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -31,6 +31,7 @@ obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
31obj-$(CONFIG_I2C_CPM) += i2c-cpm.o 31obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
32obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o 32obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
33obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o 33obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
34obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
34obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o 35obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
35obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o 36obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
36obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o 37obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c
new file mode 100644
index 000000000000..f4d22ae9d294
--- /dev/null
+++ b/drivers/i2c/busses/i2c-highlander.c
@@ -0,0 +1,498 @@
1/*
2 * Renesas Solutions Highlander FPGA I2C/SMBus support.
3 *
4 * Supported devices: R0P7780LC0011RL, R0P7785LC0011RL
5 *
6 * Copyright (C) 2008 Paul Mundt
7 * Copyright (C) 2008 Renesas Solutions Corp.
8 * Copyright (C) 2008 Atom Create Engineering Co., Ltd.
9 *
10 * This file is subject to the terms and conditions of the GNU General
11 * Public License version 2. See the file "COPYING" in the main directory
12 * of this archive for more details.
13 */
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/interrupt.h>
17#include <linux/i2c.h>
18#include <linux/platform_device.h>
19#include <linux/completion.h>
20#include <linux/io.h>
21#include <linux/delay.h>
22
23#define SMCR 0x00
24#define SMCR_START (1 << 0)
25#define SMCR_IRIC (1 << 1)
26#define SMCR_BBSY (1 << 2)
27#define SMCR_ACKE (1 << 3)
28#define SMCR_RST (1 << 4)
29#define SMCR_IEIC (1 << 6)
30
31#define SMSMADR 0x02
32
33#define SMMR 0x04
34#define SMMR_MODE0 (1 << 0)
35#define SMMR_MODE1 (1 << 1)
36#define SMMR_CAP (1 << 3)
37#define SMMR_TMMD (1 << 4)
38#define SMMR_SP (1 << 7)
39
40#define SMSADR 0x06
41#define SMTRDR 0x46
42
43struct highlander_i2c_dev {
44 struct device *dev;
45 void __iomem *base;
46 struct i2c_adapter adapter;
47 struct completion cmd_complete;
48 unsigned long last_read_time;
49 int irq;
50 u8 *buf;
51 size_t buf_len;
52};
53
54static int iic_force_poll, iic_force_normal;
55static int iic_timeout = 1000, iic_read_delay;
56
57static inline void highlander_i2c_irq_enable(struct highlander_i2c_dev *dev)
58{
59 iowrite16(ioread16(dev->base + SMCR) | SMCR_IEIC, dev->base + SMCR);
60}
61
62static inline void highlander_i2c_irq_disable(struct highlander_i2c_dev *dev)
63{
64 iowrite16(ioread16(dev->base + SMCR) & ~SMCR_IEIC, dev->base + SMCR);
65}
66
67static inline void highlander_i2c_start(struct highlander_i2c_dev *dev)
68{
69 iowrite16(ioread16(dev->base + SMCR) | SMCR_START, dev->base + SMCR);
70}
71
72static inline void highlander_i2c_done(struct highlander_i2c_dev *dev)
73{
74 iowrite16(ioread16(dev->base + SMCR) | SMCR_IRIC, dev->base + SMCR);
75}
76
77static void highlander_i2c_setup(struct highlander_i2c_dev *dev)
78{
79 u16 smmr;
80
81 smmr = ioread16(dev->base + SMMR);
82 smmr |= SMMR_TMMD;
83
84 if (iic_force_normal)
85 smmr &= ~SMMR_SP;
86 else
87 smmr |= SMMR_SP;
88
89 iowrite16(smmr, dev->base + SMMR);
90}
91
92static void smbus_write_data(u8 *src, u16 *dst, int len)
93{
94 for (; len > 1; len -= 2) {
95 *dst++ = be16_to_cpup((u16 *)src);
96 src += 2;
97 }
98
99 if (len)
100 *dst = *src << 8;
101}
102
103static void smbus_read_data(u16 *src, u8 *dst, int len)
104{
105 for (; len > 1; len -= 2) {
106 *(u16 *)dst = cpu_to_be16p(src++);
107 dst += 2;
108 }
109
110 if (len)
111 *dst = *src >> 8;
112}
113
114static void highlander_i2c_command(struct highlander_i2c_dev *dev,
115 u8 command, int len)
116{
117 unsigned int i;
118 u16 cmd = (command << 8) | command;
119
120 for (i = 0; i < len; i += 2) {
121 if (len - i == 1)
122 cmd = command << 8;
123 iowrite16(cmd, dev->base + SMSADR + i);
124 dev_dbg(dev->dev, "command data[%x] 0x%04x\n", i/2, cmd);
125 }
126}
127
128static int highlander_i2c_wait_for_bbsy(struct highlander_i2c_dev *dev)
129{
130 unsigned long timeout;
131
132 timeout = jiffies + msecs_to_jiffies(iic_timeout);
133 while (ioread16(dev->base + SMCR) & SMCR_BBSY) {
134 if (time_after(jiffies, timeout)) {
135 dev_warn(dev->dev, "timeout waiting for bus ready\n");
136 return -ETIMEDOUT;
137 }
138
139 msleep(1);
140 }
141
142 return 0;
143}
144
145static int highlander_i2c_reset(struct highlander_i2c_dev *dev)
146{
147 iowrite16(ioread16(dev->base + SMCR) | SMCR_RST, dev->base + SMCR);
148 return highlander_i2c_wait_for_bbsy(dev);
149}
150
151static int highlander_i2c_wait_for_ack(struct highlander_i2c_dev *dev)
152{
153 u16 tmp = ioread16(dev->base + SMCR);
154
155 if ((tmp & (SMCR_IRIC | SMCR_ACKE)) == SMCR_ACKE) {
156 dev_warn(dev->dev, "ack abnormality\n");
157 return highlander_i2c_reset(dev);
158 }
159
160 return 0;
161}
162
163static irqreturn_t highlander_i2c_irq(int irq, void *dev_id)
164{
165 struct highlander_i2c_dev *dev = dev_id;
166
167 highlander_i2c_done(dev);
168 complete(&dev->cmd_complete);
169
170 return IRQ_HANDLED;
171}
172
173static void highlander_i2c_poll(struct highlander_i2c_dev *dev)
174{
175 unsigned long timeout;
176 u16 smcr;
177
178 timeout = jiffies + msecs_to_jiffies(iic_timeout);
179 for (;;) {
180 smcr = ioread16(dev->base + SMCR);
181
182 /*
183 * Don't bother checking ACKE here, this and the reset
184 * are handled in highlander_i2c_wait_xfer_done() when
185 * waiting for the ACK.
186 */
187
188 if (smcr & SMCR_IRIC)
189 return;
190 if (time_after(jiffies, timeout))
191 break;
192
193 cpu_relax();
194 cond_resched();
195 }
196
197 dev_err(dev->dev, "polling timed out\n");
198}
199
200static inline int highlander_i2c_wait_xfer_done(struct highlander_i2c_dev *dev)
201{
202 if (dev->irq)
203 wait_for_completion_timeout(&dev->cmd_complete,
204 msecs_to_jiffies(iic_timeout));
205 else
206 /* busy looping, the IRQ of champions */
207 highlander_i2c_poll(dev);
208
209 return highlander_i2c_wait_for_ack(dev);
210}
211
212static int highlander_i2c_read(struct highlander_i2c_dev *dev)
213{
214 int i, cnt;
215 u16 data[16];
216
217 if (highlander_i2c_wait_for_bbsy(dev))
218 return -EAGAIN;
219
220 highlander_i2c_start(dev);
221
222 if (highlander_i2c_wait_xfer_done(dev)) {
223 dev_err(dev->dev, "Arbitration loss\n");
224 return -EAGAIN;
225 }
226
227 /*
228 * The R0P7780LC0011RL FPGA needs a significant delay between
229 * data read cycles, otherwise the transciever gets confused and
230 * garbage is returned when the read is subsequently aborted.
231 *
232 * It is not sufficient to wait for BBSY.
233 *
234 * While this generally only applies to the older SH7780-based
235 * Highlanders, the same issue can be observed on SH7785 ones,
236 * albeit less frequently. SH7780-based Highlanders may need
237 * this to be as high as 1000 ms.
238 */
239 if (iic_read_delay && time_before(jiffies, dev->last_read_time +
240 msecs_to_jiffies(iic_read_delay)))
241 msleep(jiffies_to_msecs((dev->last_read_time +
242 msecs_to_jiffies(iic_read_delay)) - jiffies));
243
244 cnt = (dev->buf_len + 1) >> 1;
245 for (i = 0; i < cnt; i++) {
246 data[i] = ioread16(dev->base + SMTRDR + (i * sizeof(u16)));
247 dev_dbg(dev->dev, "read data[%x] 0x%04x\n", i, data[i]);
248 }
249
250 smbus_read_data(data, dev->buf, dev->buf_len);
251
252 dev->last_read_time = jiffies;
253
254 return 0;
255}
256
257static int highlander_i2c_write(struct highlander_i2c_dev *dev)
258{
259 int i, cnt;
260 u16 data[16];
261
262 smbus_write_data(dev->buf, data, dev->buf_len);
263
264 cnt = (dev->buf_len + 1) >> 1;
265 for (i = 0; i < cnt; i++) {
266 iowrite16(data[i], dev->base + SMTRDR + (i * sizeof(u16)));
267 dev_dbg(dev->dev, "write data[%x] 0x%04x\n", i, data[i]);
268 }
269
270 if (highlander_i2c_wait_for_bbsy(dev))
271 return -EAGAIN;
272
273 highlander_i2c_start(dev);
274
275 return highlander_i2c_wait_xfer_done(dev);
276}
277
278static int highlander_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr,
279 unsigned short flags, char read_write,
280 u8 command, int size,
281 union i2c_smbus_data *data)
282{
283 struct highlander_i2c_dev *dev = i2c_get_adapdata(adap);
284 int read = read_write & I2C_SMBUS_READ;
285 u16 tmp;
286
287 init_completion(&dev->cmd_complete);
288
289 dev_dbg(dev->dev, "addr %04x, command %02x, read_write %d, size %d\n",
290 addr, command, read_write, size);
291
292 /*
293 * Set up the buffer and transfer size
294 */
295 switch (size) {
296 case I2C_SMBUS_BYTE_DATA:
297 dev->buf = &data->byte;
298 dev->buf_len = 1;
299 break;
300 case I2C_SMBUS_I2C_BLOCK_DATA:
301 dev->buf = &data->block[1];
302 dev->buf_len = data->block[0];
303 break;
304 default:
305 dev_err(dev->dev, "unsupported command %d\n", size);
306 return -EINVAL;
307 }
308
309 /*
310 * Encode the mode setting
311 */
312 tmp = ioread16(dev->base + SMMR);
313 tmp &= ~(SMMR_MODE0 | SMMR_MODE1);
314
315 switch (dev->buf_len) {
316 case 1:
317 /* default */
318 break;
319 case 8:
320 tmp |= SMMR_MODE0;
321 break;
322 case 16:
323 tmp |= SMMR_MODE1;
324 break;
325 case 32:
326 tmp |= (SMMR_MODE0 | SMMR_MODE1);
327 break;
328 default:
329 dev_err(dev->dev, "unsupported xfer size %d\n", dev->buf_len);
330 return -EINVAL;
331 }
332
333 iowrite16(tmp, dev->base + SMMR);
334
335 /* Ensure we're in a sane state */
336 highlander_i2c_done(dev);
337
338 /* Set slave address */
339 iowrite16((addr << 1) | read, dev->base + SMSMADR);
340
341 highlander_i2c_command(dev, command, dev->buf_len);
342
343 if (read)
344 return highlander_i2c_read(dev);
345 else
346 return highlander_i2c_write(dev);
347}
348
349static u32 highlander_i2c_func(struct i2c_adapter *adapter)
350{
351 return I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK;
352}
353
354static const struct i2c_algorithm highlander_i2c_algo = {
355 .smbus_xfer = highlander_i2c_smbus_xfer,
356 .functionality = highlander_i2c_func,
357};
358
359static int __devinit highlander_i2c_probe(struct platform_device *pdev)
360{
361 struct highlander_i2c_dev *dev;
362 struct i2c_adapter *adap;
363 struct resource *res;
364 int ret;
365
366 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
367 if (unlikely(!res)) {
368 dev_err(&pdev->dev, "no mem resource\n");
369 return -ENODEV;
370 }
371
372 dev = kzalloc(sizeof(struct highlander_i2c_dev), GFP_KERNEL);
373 if (unlikely(!dev))
374 return -ENOMEM;
375
376 dev->base = ioremap_nocache(res->start, res->end - res->start + 1);
377 if (unlikely(!dev->base)) {
378 ret = -ENXIO;
379 goto err;
380 }
381
382 dev->dev = &pdev->dev;
383 platform_set_drvdata(pdev, dev);
384
385 dev->irq = platform_get_irq(pdev, 0);
386 if (iic_force_poll)
387 dev->irq = 0;
388
389 if (dev->irq) {
390 ret = request_irq(dev->irq, highlander_i2c_irq, IRQF_DISABLED,
391 pdev->name, dev);
392 if (unlikely(ret))
393 goto err_unmap;
394
395 highlander_i2c_irq_enable(dev);
396 } else {
397 dev_notice(&pdev->dev, "no IRQ, using polling mode\n");
398 highlander_i2c_irq_disable(dev);
399 }
400
401 dev->last_read_time = jiffies; /* initial read jiffies */
402
403 highlander_i2c_setup(dev);
404
405 adap = &dev->adapter;
406 i2c_set_adapdata(adap, dev);
407 adap->owner = THIS_MODULE;
408 adap->class = I2C_CLASS_HWMON;
409 strlcpy(adap->name, "HL FPGA I2C adapter", sizeof(adap->name));
410 adap->algo = &highlander_i2c_algo;
411 adap->dev.parent = &pdev->dev;
412 adap->nr = pdev->id;
413
414 /*
415 * Reset the adapter
416 */
417 ret = highlander_i2c_reset(dev);
418 if (unlikely(ret)) {
419 dev_err(&pdev->dev, "controller didn't come up\n");
420 goto err_free_irq;
421 }
422
423 ret = i2c_add_numbered_adapter(adap);
424 if (unlikely(ret)) {
425 dev_err(&pdev->dev, "failure adding adapter\n");
426 goto err_free_irq;
427 }
428
429 return 0;
430
431err_free_irq:
432 if (dev->irq)
433 free_irq(dev->irq, dev);
434err_unmap:
435 iounmap(dev->base);
436err:
437 kfree(dev);
438
439 platform_set_drvdata(pdev, NULL);
440
441 return ret;
442}
443
444static int __devexit highlander_i2c_remove(struct platform_device *pdev)
445{
446 struct highlander_i2c_dev *dev = platform_get_drvdata(pdev);
447
448 i2c_del_adapter(&dev->adapter);
449
450 if (dev->irq)
451 free_irq(dev->irq, dev);
452
453 iounmap(dev->base);
454 kfree(dev);
455
456 platform_set_drvdata(pdev, NULL);
457
458 return 0;
459}
460
461static struct platform_driver highlander_i2c_driver = {
462 .driver = {
463 .name = "i2c-highlander",
464 .owner = THIS_MODULE,
465 },
466
467 .probe = highlander_i2c_probe,
468 .remove = __devexit_p(highlander_i2c_remove),
469};
470
471static int __init highlander_i2c_init(void)
472{
473 return platform_driver_register(&highlander_i2c_driver);
474}
475
476static void __exit highlander_i2c_exit(void)
477{
478 platform_driver_unregister(&highlander_i2c_driver);
479}
480
481module_init(highlander_i2c_init);
482module_exit(highlander_i2c_exit);
483
484MODULE_AUTHOR("Paul Mundt");
485MODULE_DESCRIPTION("Renesas Highlander FPGA I2C/SMBus adapter");
486MODULE_LICENSE("GPL v2");
487
488module_param(iic_force_poll, bool, 0);
489module_param(iic_force_normal, bool, 0);
490module_param(iic_timeout, int, 0);
491module_param(iic_read_delay, int, 0);
492
493MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
494MODULE_PARM_DESC(iic_force_normal,
495 "Force normal mode (100 kHz), default is fast mode (400 kHz)");
496MODULE_PARM_DESC(iic_timeout, "Set timeout value in msecs (default 1000 ms)");
497MODULE_PARM_DESC(iic_read_delay,
498 "Delay between data read cycles (default 0 ms)");