aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorZhiwu Song <Zhiwu.Song@csr.com>2012-02-08 10:28:35 -0500
committerWolfram Sang <w.sang@pengutronix.de>2012-03-07 13:05:04 -0500
commit979b907fa55be8cdbbf455b9204b7e4602f303e6 (patch)
tree245d0ae5235936322701331e815438c77774e274 /drivers
parentbf6c2de11c43955ffb4394e6dfc86363298c0a05 (diff)
i2c: add CSR SiRFprimaII on-chip I2C controllers driver
SiRFprimaII is the latest generation application processor from CSR’s multi-function SoC product family. The SoC support codes are in arch/arm/mach-prima2 from Linux mainline 3.0. There are two I2C controllers on primaII, features include: * Two I2C controller modules are on chip * RISC I/O bus read write register * Up to 16 bytes data buffer for issuing commands and writing data at the same time * Up to 16 commands, and receiving read data 16 bytes at a time * Error INT report (ACK check) * No-ACK bus protocols (SCCB bus protocols) Signed-off-by: Zhiwu Song <Zhiwu.Song@csr.com> Signed-off-by: Xiangzhen Ye <Xiangzhen.Ye@csr.com> Signed-off-by: Yuping Luo <Yuping.Luo@csr.com> Signed-off-by: Barry Song <Baohua.Song@csr.com> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/i2c/busses/Kconfig10
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-sirf.c459
3 files changed, 470 insertions, 0 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index e99bfa86ba71..71c1b0a7535c 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -645,6 +645,16 @@ config I2C_SIMTEC
645 This driver can also be built as a module. If so, the module 645 This driver can also be built as a module. If so, the module
646 will be called i2c-simtec. 646 will be called i2c-simtec.
647 647
648config I2C_SIRF
649 tristate "CSR SiRFprimaII I2C interface"
650 depends on ARCH_PRIMA2
651 help
652 If you say yes to this option, support will be included for the
653 CSR SiRFprimaII I2C interface.
654
655 This driver can also be built as a module. If so, the module
656 will be called i2c-sirf.
657
648config I2C_STU300 658config I2C_STU300
649 tristate "ST Microelectronics DDC I2C interface" 659 tristate "ST Microelectronics DDC I2C interface"
650 depends on MACH_U300 660 depends on MACH_U300
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 8f9e7b6677e1..569567b0d027 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -64,6 +64,7 @@ obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
64obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o 64obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
65obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o 65obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
66obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o 66obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
67obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o
67obj-$(CONFIG_I2C_STU300) += i2c-stu300.o 68obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
68obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o 69obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o
69obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o 70obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
diff --git a/drivers/i2c/busses/i2c-sirf.c b/drivers/i2c/busses/i2c-sirf.c
new file mode 100644
index 000000000000..5574a47792fb
--- /dev/null
+++ b/drivers/i2c/busses/i2c-sirf.c
@@ -0,0 +1,459 @@
1/*
2 * I2C bus driver for CSR SiRFprimaII
3 *
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
5 *
6 * Licensed under GPLv2 or later.
7 */
8
9#include <linux/interrupt.h>
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/slab.h>
13#include <linux/platform_device.h>
14#include <linux/i2c.h>
15#include <linux/clk.h>
16#include <linux/err.h>
17#include <linux/io.h>
18
19#define SIRFSOC_I2C_CLK_CTRL 0x00
20#define SIRFSOC_I2C_STATUS 0x0C
21#define SIRFSOC_I2C_CTRL 0x10
22#define SIRFSOC_I2C_IO_CTRL 0x14
23#define SIRFSOC_I2C_SDA_DELAY 0x18
24#define SIRFSOC_I2C_CMD_START 0x1C
25#define SIRFSOC_I2C_CMD_BUF 0x30
26#define SIRFSOC_I2C_DATA_BUF 0x80
27
28#define SIRFSOC_I2C_CMD_BUF_MAX 16
29#define SIRFSOC_I2C_DATA_BUF_MAX 16
30
31#define SIRFSOC_I2C_CMD(x) (SIRFSOC_I2C_CMD_BUF + (x)*0x04)
32#define SIRFSOC_I2C_DATA_MASK(x) (0xFF<<(((x)&3)*8))
33#define SIRFSOC_I2C_DATA_SHIFT(x) (((x)&3)*8)
34
35#define SIRFSOC_I2C_DIV_MASK (0xFFFF)
36
37/* I2C status flags */
38#define SIRFSOC_I2C_STAT_BUSY BIT(0)
39#define SIRFSOC_I2C_STAT_TIP BIT(1)
40#define SIRFSOC_I2C_STAT_NACK BIT(2)
41#define SIRFSOC_I2C_STAT_TR_INT BIT(4)
42#define SIRFSOC_I2C_STAT_STOP BIT(6)
43#define SIRFSOC_I2C_STAT_CMD_DONE BIT(8)
44#define SIRFSOC_I2C_STAT_ERR BIT(9)
45#define SIRFSOC_I2C_CMD_INDEX (0x1F<<16)
46
47/* I2C control flags */
48#define SIRFSOC_I2C_RESET BIT(0)
49#define SIRFSOC_I2C_CORE_EN BIT(1)
50#define SIRFSOC_I2C_MASTER_MODE BIT(2)
51#define SIRFSOC_I2C_CMD_DONE_EN BIT(11)
52#define SIRFSOC_I2C_ERR_INT_EN BIT(12)
53
54#define SIRFSOC_I2C_SDA_DELAY_MASK (0xFF)
55#define SIRFSOC_I2C_SCLF_FILTER (3<<8)
56
57#define SIRFSOC_I2C_START_CMD BIT(0)
58
59#define SIRFSOC_I2C_CMD_RP(x) ((x)&0x7)
60#define SIRFSOC_I2C_NACK BIT(3)
61#define SIRFSOC_I2C_WRITE BIT(4)
62#define SIRFSOC_I2C_READ BIT(5)
63#define SIRFSOC_I2C_STOP BIT(6)
64#define SIRFSOC_I2C_START BIT(7)
65
66#define SIRFSOC_I2C_DEFAULT_SPEED 100000
67
68struct sirfsoc_i2c {
69 void __iomem *base;
70 struct clk *clk;
71 u32 cmd_ptr; /* Current position in CMD buffer */
72 u8 *buf; /* Buffer passed by user */
73 u32 msg_len; /* Message length */
74 u32 finished_len; /* number of bytes read/written */
75 u32 read_cmd_len; /* number of read cmd sent */
76 int msg_read; /* 1 indicates a read message */
77 int err_status; /* 1 indicates an error on bus */
78
79 u32 sda_delay; /* For suspend/resume */
80 u32 clk_div;
81 int last; /* Last message in transfer, STOP cmd can be sent */
82
83 struct completion done; /* indicates completion of message transfer */
84 struct i2c_adapter adapter;
85};
86
87static void i2c_sirfsoc_read_data(struct sirfsoc_i2c *siic)
88{
89 u32 data = 0;
90 int i;
91
92 for (i = 0; i < siic->read_cmd_len; i++) {
93 if (!(i & 0x3))
94 data = readl(siic->base + SIRFSOC_I2C_DATA_BUF + i);
95 siic->buf[siic->finished_len++] =
96 (u8)((data & SIRFSOC_I2C_DATA_MASK(i)) >>
97 SIRFSOC_I2C_DATA_SHIFT(i));
98 }
99}
100
101static void i2c_sirfsoc_queue_cmd(struct sirfsoc_i2c *siic)
102{
103 u32 regval;
104 int i = 0;
105
106 if (siic->msg_read) {
107 while (((siic->finished_len + i) < siic->msg_len)
108 && (siic->cmd_ptr < SIRFSOC_I2C_CMD_BUF_MAX)) {
109 regval = SIRFSOC_I2C_READ | SIRFSOC_I2C_CMD_RP(0);
110 if (((siic->finished_len + i) ==
111 (siic->msg_len - 1)) && siic->last)
112 regval |= SIRFSOC_I2C_STOP | SIRFSOC_I2C_NACK;
113 writel(regval,
114 siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
115 i++;
116 }
117
118 siic->read_cmd_len = i;
119 } else {
120 while ((siic->cmd_ptr < SIRFSOC_I2C_CMD_BUF_MAX - 1)
121 && (siic->finished_len < siic->msg_len)) {
122 regval = SIRFSOC_I2C_WRITE | SIRFSOC_I2C_CMD_RP(0);
123 if ((siic->finished_len == (siic->msg_len - 1))
124 && siic->last)
125 regval |= SIRFSOC_I2C_STOP;
126 writel(regval,
127 siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
128 writel(siic->buf[siic->finished_len++],
129 siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
130 }
131 }
132 siic->cmd_ptr = 0;
133
134 /* Trigger the transfer */
135 writel(SIRFSOC_I2C_START_CMD, siic->base + SIRFSOC_I2C_CMD_START);
136}
137
138static irqreturn_t i2c_sirfsoc_irq(int irq, void *dev_id)
139{
140 struct sirfsoc_i2c *siic = (struct sirfsoc_i2c *)dev_id;
141 u32 i2c_stat = readl(siic->base + SIRFSOC_I2C_STATUS);
142
143 if (i2c_stat & SIRFSOC_I2C_STAT_ERR) {
144 /* Error conditions */
145 siic->err_status = 1;
146 writel(SIRFSOC_I2C_STAT_ERR, siic->base + SIRFSOC_I2C_STATUS);
147
148 if (i2c_stat & SIRFSOC_I2C_STAT_NACK)
149 dev_err(&siic->adapter.dev, "ACK not received\n");
150 else
151 dev_err(&siic->adapter.dev, "I2C error\n");
152
153 complete(&siic->done);
154 } else if (i2c_stat & SIRFSOC_I2C_STAT_CMD_DONE) {
155 /* CMD buffer execution complete */
156 if (siic->msg_read)
157 i2c_sirfsoc_read_data(siic);
158 if (siic->finished_len == siic->msg_len)
159 complete(&siic->done);
160 else /* Fill a new CMD buffer for left data */
161 i2c_sirfsoc_queue_cmd(siic);
162
163 writel(SIRFSOC_I2C_STAT_CMD_DONE, siic->base + SIRFSOC_I2C_STATUS);
164 }
165
166 return IRQ_HANDLED;
167}
168
169static void i2c_sirfsoc_set_address(struct sirfsoc_i2c *siic,
170 struct i2c_msg *msg)
171{
172 unsigned char addr;
173 u32 regval = SIRFSOC_I2C_START | SIRFSOC_I2C_CMD_RP(0) | SIRFSOC_I2C_WRITE;
174
175 /* no data and last message -> add STOP */
176 if (siic->last && (msg->len == 0))
177 regval |= SIRFSOC_I2C_STOP;
178
179 writel(regval, siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
180
181 addr = msg->addr << 1; /* Generate address */
182 if (msg->flags & I2C_M_RD)
183 addr |= 1;
184
185 writel(addr, siic->base + SIRFSOC_I2C_CMD(siic->cmd_ptr++));
186}
187
188static int i2c_sirfsoc_xfer_msg(struct sirfsoc_i2c *siic, struct i2c_msg *msg)
189{
190 u32 regval = readl(siic->base + SIRFSOC_I2C_CTRL);
191 /* timeout waiting for the xfer to finish or fail */
192 int timeout = msecs_to_jiffies((msg->len + 1) * 50);
193 int ret = 0;
194
195 i2c_sirfsoc_set_address(siic, msg);
196
197 writel(regval | SIRFSOC_I2C_CMD_DONE_EN | SIRFSOC_I2C_ERR_INT_EN,
198 siic->base + SIRFSOC_I2C_CTRL);
199 i2c_sirfsoc_queue_cmd(siic);
200
201 if (wait_for_completion_timeout(&siic->done, timeout) == 0) {
202 siic->err_status = 1;
203 dev_err(&siic->adapter.dev, "Transfer timeout\n");
204 }
205
206 writel(regval & ~(SIRFSOC_I2C_CMD_DONE_EN | SIRFSOC_I2C_ERR_INT_EN),
207 siic->base + SIRFSOC_I2C_CTRL);
208 writel(0, siic->base + SIRFSOC_I2C_CMD_START);
209
210 if (siic->err_status) {
211 writel(readl(siic->base + SIRFSOC_I2C_CTRL) | SIRFSOC_I2C_RESET,
212 siic->base + SIRFSOC_I2C_CTRL);
213 while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
214 cpu_relax();
215
216 ret = -EIO;
217 }
218
219 return ret;
220}
221
222static u32 i2c_sirfsoc_func(struct i2c_adapter *adap)
223{
224 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
225}
226
227static int i2c_sirfsoc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
228 int num)
229{
230 struct sirfsoc_i2c *siic = adap->algo_data;
231 int i, ret;
232
233 clk_enable(siic->clk);
234
235 for (i = 0; i < num; i++) {
236 siic->buf = msgs[i].buf;
237 siic->msg_len = msgs[i].len;
238 siic->msg_read = !!(msgs[i].flags & I2C_M_RD);
239 siic->err_status = 0;
240 siic->cmd_ptr = 0;
241 siic->finished_len = 0;
242 siic->last = (i == (num - 1));
243
244 ret = i2c_sirfsoc_xfer_msg(siic, &msgs[i]);
245 if (ret) {
246 clk_disable(siic->clk);
247 return ret;
248 }
249 }
250
251 clk_disable(siic->clk);
252 return num;
253}
254
255/* I2C algorithms associated with this master controller driver */
256static const struct i2c_algorithm i2c_sirfsoc_algo = {
257 .master_xfer = i2c_sirfsoc_xfer,
258 .functionality = i2c_sirfsoc_func,
259};
260
261static int __devinit i2c_sirfsoc_probe(struct platform_device *pdev)
262{
263 struct sirfsoc_i2c *siic;
264 struct i2c_adapter *adap;
265 struct resource *mem_res;
266 struct clk *clk;
267 int bitrate;
268 int ctrl_speed;
269 int irq;
270
271 int err;
272 u32 regval;
273
274 clk = clk_get(&pdev->dev, NULL);
275 if (IS_ERR(clk)) {
276 err = PTR_ERR(clk);
277 dev_err(&pdev->dev, "Clock get failed\n");
278 goto err_get_clk;
279 }
280
281 err = clk_prepare(clk);
282 if (err) {
283 dev_err(&pdev->dev, "Clock prepare failed\n");
284 goto err_clk_prep;
285 }
286
287 err = clk_enable(clk);
288 if (err) {
289 dev_err(&pdev->dev, "Clock enable failed\n");
290 goto err_clk_en;
291 }
292
293 ctrl_speed = clk_get_rate(clk);
294
295 siic = devm_kzalloc(&pdev->dev, sizeof(*siic), GFP_KERNEL);
296 if (!siic) {
297 dev_err(&pdev->dev, "Can't allocate driver data\n");
298 err = -ENOMEM;
299 goto out;
300 }
301 adap = &siic->adapter;
302 adap->class = I2C_CLASS_HWMON;
303
304 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
305 if (mem_res == NULL) {
306 dev_err(&pdev->dev, "Unable to get MEM resource\n");
307 err = -EINVAL;
308 goto out;
309 }
310
311 siic->base = devm_request_and_ioremap(&pdev->dev, mem_res);
312 if (siic->base == NULL) {
313 dev_err(&pdev->dev, "IO remap failed!\n");
314 err = -ENOMEM;
315 goto out;
316 }
317
318 irq = platform_get_irq(pdev, 0);
319 if (irq < 0) {
320 err = irq;
321 goto out;
322 }
323 err = devm_request_irq(&pdev->dev, irq, i2c_sirfsoc_irq, 0,
324 dev_name(&pdev->dev), siic);
325 if (err)
326 goto out;
327
328 adap->algo = &i2c_sirfsoc_algo;
329 adap->algo_data = siic;
330
331 adap->dev.parent = &pdev->dev;
332 adap->nr = pdev->id;
333
334 strlcpy(adap->name, "sirfsoc-i2c", sizeof(adap->name));
335
336 platform_set_drvdata(pdev, adap);
337 init_completion(&siic->done);
338
339 /* Controller Initalisation */
340
341 writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL);
342 while (readl(siic->base + SIRFSOC_I2C_CTRL) & SIRFSOC_I2C_RESET)
343 cpu_relax();
344 writel(SIRFSOC_I2C_CORE_EN | SIRFSOC_I2C_MASTER_MODE,
345 siic->base + SIRFSOC_I2C_CTRL);
346
347 siic->clk = clk;
348
349 err = of_property_read_u32(pdev->dev.of_node,
350 "clock-frequency", &bitrate);
351 if (err < 0)
352 bitrate = SIRFSOC_I2C_DEFAULT_SPEED;
353
354 if (bitrate < 100000)
355 regval =
356 (2 * ctrl_speed) / (2 * bitrate * 11);
357 else
358 regval = ctrl_speed / (bitrate * 5);
359
360 writel(regval, siic->base + SIRFSOC_I2C_CLK_CTRL);
361 if (regval > 0xFF)
362 writel(0xFF, siic->base + SIRFSOC_I2C_SDA_DELAY);
363 else
364 writel(regval, siic->base + SIRFSOC_I2C_SDA_DELAY);
365
366 err = i2c_add_numbered_adapter(adap);
367 if (err < 0) {
368 dev_err(&pdev->dev, "Can't add new i2c adapter\n");
369 goto out;
370 }
371
372 clk_disable(clk);
373
374 dev_info(&pdev->dev, " I2C adapter ready to operate\n");
375
376 return 0;
377
378out:
379 clk_disable(clk);
380err_clk_en:
381 clk_unprepare(clk);
382err_clk_prep:
383 clk_put(clk);
384err_get_clk:
385 return err;
386}
387
388static int __devexit i2c_sirfsoc_remove(struct platform_device *pdev)
389{
390 struct i2c_adapter *adapter = platform_get_drvdata(pdev);
391 struct sirfsoc_i2c *siic = adapter->algo_data;
392
393 writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL);
394 i2c_del_adapter(adapter);
395 clk_unprepare(siic->clk);
396 clk_put(siic->clk);
397 return 0;
398}
399
400#ifdef CONFIG_PM
401static int i2c_sirfsoc_suspend(struct device *dev)
402{
403 struct platform_device *pdev = to_platform_device(dev);
404 struct i2c_adapter *adapter = platform_get_drvdata(pdev);
405 struct sirfsoc_i2c *siic = adapter->algo_data;
406
407 clk_enable(siic->clk);
408 siic->sda_delay = readl(siic->base + SIRFSOC_I2C_SDA_DELAY);
409 siic->clk_div = readl(siic->base + SIRFSOC_I2C_CLK_CTRL);
410 clk_disable(siic->clk);
411 return 0;
412}
413
414static int i2c_sirfsoc_resume(struct device *dev)
415{
416 struct platform_device *pdev = to_platform_device(dev);
417 struct i2c_adapter *adapter = platform_get_drvdata(pdev);
418 struct sirfsoc_i2c *siic = adapter->algo_data;
419
420 clk_enable(siic->clk);
421 writel(SIRFSOC_I2C_RESET, siic->base + SIRFSOC_I2C_CTRL);
422 writel(SIRFSOC_I2C_CORE_EN | SIRFSOC_I2C_MASTER_MODE,
423 siic->base + SIRFSOC_I2C_CTRL);
424 writel(siic->clk_div, siic->base + SIRFSOC_I2C_CLK_CTRL);
425 writel(siic->sda_delay, siic->base + SIRFSOC_I2C_SDA_DELAY);
426 clk_disable(siic->clk);
427 return 0;
428}
429
430static const struct dev_pm_ops i2c_sirfsoc_pm_ops = {
431 .suspend = i2c_sirfsoc_suspend,
432 .resume = i2c_sirfsoc_resume,
433};
434#endif
435
436static const struct of_device_id sirfsoc_i2c_of_match[] __devinitconst = {
437 { .compatible = "sirf,prima2-i2c", },
438 {},
439};
440MODULE_DEVICE_TABLE(of, sirfsoc_i2c_of_match);
441
442static struct platform_driver i2c_sirfsoc_driver = {
443 .driver = {
444 .name = "sirfsoc_i2c",
445 .owner = THIS_MODULE,
446#ifdef CONFIG_PM
447 .pm = &i2c_sirfsoc_pm_ops,
448#endif
449 .of_match_table = sirfsoc_i2c_of_match,
450 },
451 .probe = i2c_sirfsoc_probe,
452 .remove = __devexit_p(i2c_sirfsoc_remove),
453};
454module_platform_driver(i2c_sirfsoc_driver);
455
456MODULE_DESCRIPTION("SiRF SoC I2C master controller driver");
457MODULE_AUTHOR("Zhiwu Song <Zhiwu.Song@csr.com>, "
458 "Xiangzhen Ye <Xiangzhen.Ye@csr.com>");
459MODULE_LICENSE("GPL v2");