aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorWolfram Sang <wsa@sang-engineering.com>2013-12-20 13:08:50 -0500
committerWolfram Sang <wsa@the-dreams.de>2014-01-02 09:56:52 -0500
commit310c18a414504e42dbeb96263bc81ca865c7c3e5 (patch)
tree632df5415bc4f96e8b75a7496ecbb9ee14f7054c /drivers/i2c
parent802eee95bde72fd0cd0f3a5b2098375a487d1eda (diff)
i2c: riic: add driver
Tested with a r7s72100 genmai board acessing an eeprom. Signed-off-by: Wolfram Sang <wsa@sang-engineering.com> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/Kconfig10
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-riic.c427
3 files changed, 438 insertions, 0 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 3b26129f6055..8e8332d5ac73 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -648,6 +648,16 @@ config I2C_PXA_SLAVE
648 is necessary for systems where the PXA may be a target on the 648 is necessary for systems where the PXA may be a target on the
649 I2C bus. 649 I2C bus.
650 650
651config I2C_RIIC
652 tristate "Renesas RIIC adapter"
653 depends on ARCH_SHMOBILE || COMPILE_TEST
654 help
655 If you say yes to this option, support will be included for the
656 Renesas RIIC I2C interface.
657
658 This driver can also be built as a module. If so, the module
659 will be called i2c-riic.
660
651config HAVE_S3C2410_I2C 661config HAVE_S3C2410_I2C
652 bool 662 bool
653 help 663 help
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index c73eb0ea788e..dca041b1b99d 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
63obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o 63obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
64obj-$(CONFIG_I2C_PXA) += i2c-pxa.o 64obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
65obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o 65obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
66obj-$(CONFIG_I2C_RIIC) += i2c-riic.o
66obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o 67obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
67obj-$(CONFIG_I2C_S6000) += i2c-s6000.o 68obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
68obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o 69obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
diff --git a/drivers/i2c/busses/i2c-riic.c b/drivers/i2c/busses/i2c-riic.c
new file mode 100644
index 000000000000..9e1f8bacfb39
--- /dev/null
+++ b/drivers/i2c/busses/i2c-riic.c
@@ -0,0 +1,427 @@
1/*
2 * Renesas RIIC driver
3 *
4 * Copyright (C) 2013 Wolfram Sang <wsa@sang-engineering.com>
5 * Copyright (C) 2013 Renesas Solutions Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 */
11
12/*
13 * This i2c core has a lot of interrupts, namely 8. We use their chaining as
14 * some kind of state machine.
15 *
16 * 1) The main xfer routine kicks off a transmission by putting the start bit
17 * (or repeated start) on the bus and enabling the transmit interrupt (TIE)
18 * since we need to send the slave address + RW bit in every case.
19 *
20 * 2) TIE sends slave address + RW bit and selects how to continue.
21 *
22 * 3a) Write case: We keep utilizing TIE as long as we have data to send. If we
23 * are done, we switch over to the transmission done interrupt (TEIE) and mark
24 * the message as completed (includes sending STOP) there.
25 *
26 * 3b) Read case: We switch over to receive interrupt (RIE). One dummy read is
27 * needed to start clocking, then we keep receiving until we are done. Note
28 * that we use the RDRFS mode all the time, i.e. we ACK/NACK every byte by
29 * writing to the ACKBT bit. I tried using the RDRFS mode only at the end of a
30 * message to create the final NACK as sketched in the datasheet. This caused
31 * some subtle races (when byte n was processed and byte n+1 was already
32 * waiting), though, and I started with the safe approach.
33 *
34 * 4) If we got a NACK somewhere, we flag the error and stop the transmission
35 * via NAKIE.
36 *
37 * Also check the comments in the interrupt routines for some gory details.
38 */
39
40#include <linux/clk.h>
41#include <linux/completion.h>
42#include <linux/err.h>
43#include <linux/i2c.h>
44#include <linux/interrupt.h>
45#include <linux/io.h>
46#include <linux/module.h>
47#include <linux/of.h>
48#include <linux/platform_device.h>
49
50#define RIIC_ICCR1 0x00
51#define RIIC_ICCR2 0x04
52#define RIIC_ICMR1 0x08
53#define RIIC_ICMR3 0x10
54#define RIIC_ICSER 0x18
55#define RIIC_ICIER 0x1c
56#define RIIC_ICSR2 0x24
57#define RIIC_ICBRL 0x34
58#define RIIC_ICBRH 0x38
59#define RIIC_ICDRT 0x3c
60#define RIIC_ICDRR 0x40
61
62#define ICCR1_ICE 0x80
63#define ICCR1_IICRST 0x40
64#define ICCR1_SOWP 0x10
65
66#define ICCR2_BBSY 0x80
67#define ICCR2_SP 0x08
68#define ICCR2_RS 0x04
69#define ICCR2_ST 0x02
70
71#define ICMR1_CKS_MASK 0x70
72#define ICMR1_BCWP 0x08
73#define ICMR1_CKS(_x) ((((_x) << 4) & ICMR1_CKS_MASK) | ICMR1_BCWP)
74
75#define ICMR3_RDRFS 0x20
76#define ICMR3_ACKWP 0x10
77#define ICMR3_ACKBT 0x08
78
79#define ICIER_TIE 0x80
80#define ICIER_TEIE 0x40
81#define ICIER_RIE 0x20
82#define ICIER_NAKIE 0x10
83
84#define ICSR2_NACKF 0x10
85
86/* ICBRx (@ PCLK 33MHz) */
87#define ICBR_RESERVED 0xe0 /* Should be 1 on writes */
88#define ICBRL_SP100K (19 | ICBR_RESERVED)
89#define ICBRH_SP100K (16 | ICBR_RESERVED)
90#define ICBRL_SP400K (21 | ICBR_RESERVED)
91#define ICBRH_SP400K (9 | ICBR_RESERVED)
92
93#define RIIC_INIT_MSG -1
94
95struct riic_dev {
96 void __iomem *base;
97 u8 *buf;
98 struct i2c_msg *msg;
99 int bytes_left;
100 int err;
101 int is_last;
102 struct completion msg_done;
103 struct i2c_adapter adapter;
104 struct clk *clk;
105};
106
107struct riic_irq_desc {
108 int res_num;
109 irq_handler_t isr;
110 char *name;
111};
112
113static inline void riic_clear_set_bit(struct riic_dev *riic, u8 clear, u8 set, u8 reg)
114{
115 writeb((readb(riic->base + reg) & ~clear) | set, riic->base + reg);
116}
117
118static int riic_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
119{
120 struct riic_dev *riic = i2c_get_adapdata(adap);
121 unsigned long time_left;
122 int i, ret;
123 u8 start_bit;
124
125 ret = clk_prepare_enable(riic->clk);
126 if (ret)
127 return ret;
128
129 if (readb(riic->base + RIIC_ICCR2) & ICCR2_BBSY) {
130 riic->err = -EBUSY;
131 goto out;
132 }
133
134 reinit_completion(&riic->msg_done);
135 riic->err = 0;
136
137 writeb(0, riic->base + RIIC_ICSR2);
138
139 for (i = 0, start_bit = ICCR2_ST; i < num; i++) {
140 riic->bytes_left = RIIC_INIT_MSG;
141 riic->buf = msgs[i].buf;
142 riic->msg = &msgs[i];
143 riic->is_last = (i == num - 1);
144
145 writeb(ICIER_NAKIE | ICIER_TIE, riic->base + RIIC_ICIER);
146
147 writeb(start_bit, riic->base + RIIC_ICCR2);
148
149 time_left = wait_for_completion_timeout(&riic->msg_done, riic->adapter.timeout);
150 if (time_left == 0)
151 riic->err = -ETIMEDOUT;
152
153 if (riic->err)
154 break;
155
156 start_bit = ICCR2_RS;
157 }
158
159 out:
160 clk_disable_unprepare(riic->clk);
161
162 return riic->err ?: num;
163}
164
165static irqreturn_t riic_tdre_isr(int irq, void *data)
166{
167 struct riic_dev *riic = data;
168 u8 val;
169
170 if (!riic->bytes_left)
171 return IRQ_NONE;
172
173 if (riic->bytes_left == RIIC_INIT_MSG) {
174 val = !!(riic->msg->flags & I2C_M_RD);
175 if (val)
176 /* On read, switch over to receive interrupt */
177 riic_clear_set_bit(riic, ICIER_TIE, ICIER_RIE, RIIC_ICIER);
178 else
179 /* On write, initialize length */
180 riic->bytes_left = riic->msg->len;
181
182 val |= (riic->msg->addr << 1);
183 } else {
184 val = *riic->buf;
185 riic->buf++;
186 riic->bytes_left--;
187 }
188
189 /*
190 * Switch to transmission ended interrupt when done. Do check here
191 * after bytes_left was initialized to support SMBUS_QUICK (new msg has
192 * 0 length then)
193 */
194 if (riic->bytes_left == 0)
195 riic_clear_set_bit(riic, ICIER_TIE, ICIER_TEIE, RIIC_ICIER);
196
197 /*
198 * This acks the TIE interrupt. We get another TIE immediately if our
199 * value could be moved to the shadow shift register right away. So
200 * this must be after updates to ICIER (where we want to disable TIE)!
201 */
202 writeb(val, riic->base + RIIC_ICDRT);
203
204 return IRQ_HANDLED;
205}
206
207static irqreturn_t riic_tend_isr(int irq, void *data)
208{
209 struct riic_dev *riic = data;
210
211 if (readb(riic->base + RIIC_ICSR2) & ICSR2_NACKF) {
212 /* We got a NACKIE */
213 readb(riic->base + RIIC_ICDRR); /* dummy read */
214 riic->err = -ENXIO;
215 } else if (riic->bytes_left) {
216 return IRQ_NONE;
217 }
218
219 if (riic->is_last || riic->err)
220 writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
221
222 writeb(0, riic->base + RIIC_ICIER);
223 complete(&riic->msg_done);
224
225 return IRQ_HANDLED;
226}
227
228static irqreturn_t riic_rdrf_isr(int irq, void *data)
229{
230 struct riic_dev *riic = data;
231
232 if (!riic->bytes_left)
233 return IRQ_NONE;
234
235 if (riic->bytes_left == RIIC_INIT_MSG) {
236 riic->bytes_left = riic->msg->len;
237 readb(riic->base + RIIC_ICDRR); /* dummy read */
238 return IRQ_HANDLED;
239 }
240
241 if (riic->bytes_left == 1) {
242 /* STOP must come before we set ACKBT! */
243 if (riic->is_last)
244 writeb(ICCR2_SP, riic->base + RIIC_ICCR2);
245
246 riic_clear_set_bit(riic, 0, ICMR3_ACKBT, RIIC_ICMR3);
247
248 writeb(0, riic->base + RIIC_ICIER);
249 complete(&riic->msg_done);
250 } else {
251 riic_clear_set_bit(riic, ICMR3_ACKBT, 0, RIIC_ICMR3);
252 }
253
254 /* Reading acks the RIE interrupt */
255 *riic->buf = readb(riic->base + RIIC_ICDRR);
256 riic->buf++;
257 riic->bytes_left--;
258
259 return IRQ_HANDLED;
260}
261
262static u32 riic_func(struct i2c_adapter *adap)
263{
264 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
265}
266
267static const struct i2c_algorithm riic_algo = {
268 .master_xfer = riic_xfer,
269 .functionality = riic_func,
270};
271
272static int riic_init_hw(struct riic_dev *riic, u32 spd)
273{
274 int ret;
275 unsigned long rate;
276
277 ret = clk_prepare_enable(riic->clk);
278 if (ret)
279 return ret;
280
281 /*
282 * TODO: Implement formula to calculate the timing values depending on
283 * variable parent clock rate and arbitrary bus speed
284 */
285 rate = clk_get_rate(riic->clk);
286 if (rate != 33325000) {
287 dev_err(&riic->adapter.dev,
288 "invalid parent clk (%lu). Must be 33325000Hz\n", rate);
289 clk_disable_unprepare(riic->clk);
290 return -EINVAL;
291 }
292
293 /* Changing the order of accessing IICRST and ICE may break things! */
294 writeb(ICCR1_IICRST | ICCR1_SOWP, riic->base + RIIC_ICCR1);
295 riic_clear_set_bit(riic, 0, ICCR1_ICE, RIIC_ICCR1);
296
297 switch (spd) {
298 case 100000:
299 writeb(ICMR1_CKS(3), riic->base + RIIC_ICMR1);
300 writeb(ICBRH_SP100K, riic->base + RIIC_ICBRH);
301 writeb(ICBRL_SP100K, riic->base + RIIC_ICBRL);
302 break;
303 case 400000:
304 writeb(ICMR1_CKS(1), riic->base + RIIC_ICMR1);
305 writeb(ICBRH_SP400K, riic->base + RIIC_ICBRH);
306 writeb(ICBRL_SP400K, riic->base + RIIC_ICBRL);
307 break;
308 default:
309 dev_err(&riic->adapter.dev,
310 "unsupported bus speed (%dHz). Use 100000 or 400000\n", spd);
311 clk_disable_unprepare(riic->clk);
312 return -EINVAL;
313 }
314
315 writeb(0, riic->base + RIIC_ICSER);
316 writeb(ICMR3_ACKWP | ICMR3_RDRFS, riic->base + RIIC_ICMR3);
317
318 riic_clear_set_bit(riic, ICCR1_IICRST, 0, RIIC_ICCR1);
319
320 clk_disable_unprepare(riic->clk);
321
322 return 0;
323}
324
325static struct riic_irq_desc riic_irqs[] = {
326 { .res_num = 0, .isr = riic_tend_isr, .name = "riic-tend" },
327 { .res_num = 1, .isr = riic_rdrf_isr, .name = "riic-rdrf" },
328 { .res_num = 2, .isr = riic_tdre_isr, .name = "riic-tdre" },
329 { .res_num = 5, .isr = riic_tend_isr, .name = "riic-nack" },
330};
331
332static int riic_i2c_probe(struct platform_device *pdev)
333{
334 struct device_node *np = pdev->dev.of_node;
335 struct riic_dev *riic;
336 struct i2c_adapter *adap;
337 struct resource *res;
338 u32 bus_rate = 0;
339 int i, ret;
340
341 riic = devm_kzalloc(&pdev->dev, sizeof(*riic), GFP_KERNEL);
342 if (!riic)
343 return -ENOMEM;
344
345 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
346 riic->base = devm_ioremap_resource(&pdev->dev, res);
347 if (IS_ERR(riic->base))
348 return PTR_ERR(riic->base);
349
350 riic->clk = devm_clk_get(&pdev->dev, NULL);
351 if (IS_ERR(riic->clk)) {
352 dev_err(&pdev->dev, "missing controller clock");
353 return PTR_ERR(riic->clk);
354 }
355
356 for (i = 0; i < ARRAY_SIZE(riic_irqs); i++) {
357 res = platform_get_resource(pdev, IORESOURCE_IRQ, riic_irqs[i].res_num);
358 if (!res)
359 return -ENODEV;
360
361 ret = devm_request_irq(&pdev->dev, res->start, riic_irqs[i].isr,
362 0, riic_irqs[i].name, riic);
363 if (ret) {
364 dev_err(&pdev->dev, "failed to request irq %s\n", riic_irqs[i].name);
365 return ret;
366 }
367 }
368
369 adap = &riic->adapter;
370 i2c_set_adapdata(adap, riic);
371 strlcpy(adap->name, "Renesas RIIC adapter", sizeof(adap->name));
372 adap->owner = THIS_MODULE;
373 adap->algo = &riic_algo;
374 adap->dev.parent = &pdev->dev;
375 adap->dev.of_node = pdev->dev.of_node;
376
377 init_completion(&riic->msg_done);
378
379 of_property_read_u32(np, "clock-frequency", &bus_rate);
380 ret = riic_init_hw(riic, bus_rate);
381 if (ret)
382 return ret;
383
384
385 ret = i2c_add_adapter(adap);
386 if (ret) {
387 dev_err(&pdev->dev, "failed to add adapter\n");
388 return ret;
389 }
390
391 platform_set_drvdata(pdev, riic);
392
393 dev_info(&pdev->dev, "registered with %dHz bus speed\n", bus_rate);
394 return 0;
395}
396
397static int riic_i2c_remove(struct platform_device *pdev)
398{
399 struct riic_dev *riic = platform_get_drvdata(pdev);
400
401 writeb(0, riic->base + RIIC_ICIER);
402 i2c_del_adapter(&riic->adapter);
403
404 return 0;
405}
406
407static struct of_device_id riic_i2c_dt_ids[] = {
408 { .compatible = "renesas,riic-rz" },
409 { /* Sentinel */ },
410};
411
412static struct platform_driver riic_i2c_driver = {
413 .probe = riic_i2c_probe,
414 .remove = riic_i2c_remove,
415 .driver = {
416 .name = "i2c-riic",
417 .owner = THIS_MODULE,
418 .of_match_table = riic_i2c_dt_ids,
419 },
420};
421
422module_platform_driver(riic_i2c_driver);
423
424MODULE_DESCRIPTION("Renesas RIIC adapter");
425MODULE_AUTHOR("Wolfram Sang <wsa@sang-engineering.com>");
426MODULE_LICENSE("GPL v2");
427MODULE_DEVICE_TABLE(of, riic_i2c_dt_ids);