2 * Driver for Broadcom BCM2708 BSC Controllers
4 * Copyright (C) 2012 Chris Boot & Frank Buss
6 * This driver is inspired by:
7 * i2c-ocores.c, by Peter Korsgaard <jacmet@sunsite.dk>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/spinlock.h>
27 #include <linux/clk.h>
28 #include <linux/err.h>
30 #include <linux/platform_device.h>
32 #include <linux/slab.h>
33 #include <linux/i2c.h>
34 #include <linux/interrupt.h>
35 #include <linux/sched.h>
36 #include <linux/wait.h>
38 /* BSC register offsets */
48 /* Bitfields in BSC_C */
49 #define BSC_C_I2CEN 0x00008000
50 #define BSC_C_INTR 0x00000400
51 #define BSC_C_INTT 0x00000200
52 #define BSC_C_INTD 0x00000100
53 #define BSC_C_ST 0x00000080
54 #define BSC_C_CLEAR_1 0x00000020
55 #define BSC_C_CLEAR_2 0x00000010
56 #define BSC_C_READ 0x00000001
58 /* Bitfields in BSC_S */
59 #define BSC_S_CLKT 0x00000200
60 #define BSC_S_ERR 0x00000100
61 #define BSC_S_RXF 0x00000080
62 #define BSC_S_TXE 0x00000040
63 #define BSC_S_RXD 0x00000020
64 #define BSC_S_TXD 0x00000010
65 #define BSC_S_RXR 0x00000008
66 #define BSC_S_TXW 0x00000004
67 #define BSC_S_DONE 0x00000002
68 #define BSC_S_TA 0x00000001
70 #define I2C_WAIT_LOOP_COUNT 200
72 #define DRV_NAME "bcm2708_i2c"
74 static unsigned int baudrate;
75 module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
76 MODULE_PARM_DESC(baudrate, "The I2C baudrate");
78 static bool combined = false;
79 module_param(combined, bool, 0644);
80 MODULE_PARM_DESC(combined, "Use combined transactions");
83 struct i2c_adapter adapter;
92 struct completion done;
100 static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg)
102 return readl(bi->base + reg);
105 static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val)
107 writel(val, bi->base + reg);
110 static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi)
112 bcm2708_wr(bi, BSC_C, 0);
113 bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE);
116 static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi)
118 while ((bi->pos < bi->msg->len) && (bcm2708_rd(bi, BSC_S) & BSC_S_RXD))
119 bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO);
122 static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi)
124 while ((bi->pos < bi->msg->len) && (bcm2708_rd(bi, BSC_S) & BSC_S_TXD))
125 bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
128 static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi)
130 u32 cdiv, s, clk_tout;
131 u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1;
132 int wait_loops = I2C_WAIT_LOOP_COUNT;
134 /* Can't call clk_get_rate as it locks a mutex and here we are spinlocked.
135 * Use the value that we cached in the probe.
138 clk_tout = bi->clk_tout;
140 if (bi->msg->flags & I2C_M_RD)
141 c |= BSC_C_INTR | BSC_C_READ;
145 bcm2708_wr(bi, BSC_CLKT, clk_tout);
146 bcm2708_wr(bi, BSC_DIV, cdiv);
147 bcm2708_wr(bi, BSC_A, bi->msg->addr);
148 bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
151 /* Do the next two messages meet combined transaction criteria?
152 - Current message is a write, next message is a read
153 - Both messages to same slave address
154 - Write message can fit inside FIFO (16 bytes or less) */
155 if ( (bi->nmsgs > 1) &&
156 !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) &&
157 (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) {
160 bcm2708_wr(bi, BSC_C, BSC_C_CLEAR_1);
162 /* Fill FIFO with entire write message (16 byte FIFO) */
163 while (bi->pos < bi->msg->len) {
164 bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
166 /* Start write transfer (no interrupts, don't clear FIFO) */
167 bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST);
169 /* poll for transfer start bit (should only take 1-20 polls) */
171 s = bcm2708_rd(bi, BSC_S);
172 } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0);
174 /* did we time out or some error occured? */
175 if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) {
179 /* Send next read message before the write transfer finishes. */
183 bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
184 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ;
187 bcm2708_wr(bi, BSC_C, c);
192 static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id)
194 struct bcm2708_i2c *bi = dev_id;
199 spin_lock(&bi->lock);
201 /* we may see camera interrupts on the "other" I2C channel
202 Just return if we've not sent anything */
203 if (!bi->nmsgs || !bi->msg) {
207 s = bcm2708_rd(bi, BSC_S);
209 if (s & (BSC_S_CLKT | BSC_S_ERR)) {
210 bcm2708_bsc_reset(bi);
213 bi->msg = 0; /* to inform the that all work is done */
217 } else if (s & BSC_S_DONE) {
220 if (bi->msg->flags & I2C_M_RD) {
221 bcm2708_bsc_fifo_drain(bi);
224 bcm2708_bsc_reset(bi);
227 /* advance to next message */
230 ret = bcm2708_bsc_setup(bi);
232 bcm2708_bsc_reset(bi);
234 bi->msg = 0; /* to inform the that all work is done */
241 bi->msg = 0; /* to inform the that all work is done */
246 } else if (s & BSC_S_TXW) {
247 bcm2708_bsc_fifo_fill(bi);
248 } else if (s & BSC_S_RXR) {
249 bcm2708_bsc_fifo_drain(bi);
255 spin_unlock(&bi->lock);
257 return handled ? IRQ_HANDLED : IRQ_NONE;
260 static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap,
261 struct i2c_msg *msgs, int num)
263 struct bcm2708_i2c *bi = adap->algo_data;
267 spin_lock_irqsave(&bi->lock, flags);
269 reinit_completion(&bi->done);
275 ret = bcm2708_bsc_setup(bi);
277 spin_unlock_irqrestore(&bi->lock, flags);
279 /* check the result of the setup */
282 dev_err(&adap->dev, "transfer setup timed out\n");
286 ret = wait_for_completion_timeout(&bi->done, adap->timeout);
288 dev_err(&adap->dev, "transfer timed out\n");
292 ret = bi->error ? -EIO : num;
296 spin_lock_irqsave(&bi->lock, flags);
297 bcm2708_bsc_reset(bi);
298 bi->msg = 0; /* to inform the interrupt handler that there's nothing else to be done */
300 spin_unlock_irqrestore(&bi->lock, flags);
304 static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap)
306 return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL;
309 static struct i2c_algorithm bcm2708_i2c_algorithm = {
310 .master_xfer = bcm2708_i2c_master_xfer,
311 .functionality = bcm2708_i2c_functionality,
314 static int bcm2708_i2c_probe(struct platform_device *pdev)
316 struct resource *regs;
317 int irq, err = -ENOMEM;
319 struct bcm2708_i2c *bi;
320 struct i2c_adapter *adap;
321 unsigned long bus_hz;
325 baud = CONFIG_I2C_BCM2708_BAUDRATE;
327 if (pdev->dev.of_node) {
329 pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c");
331 dev_err(&pdev->dev, "alias is missing\n");
334 if (!of_property_read_u32(pdev->dev.of_node,
335 "clock-frequency", &bus_clk_rate))
339 "Could not read clock-frequency property\n");
345 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
347 dev_err(&pdev->dev, "could not get IO memory\n");
351 irq = platform_get_irq(pdev, 0);
353 dev_err(&pdev->dev, "could not get IRQ\n");
357 clk = clk_get(&pdev->dev, NULL);
359 dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk));
363 err = clk_prepare_enable(clk);
365 dev_err(&pdev->dev, "could not enable clk: %d\n", err);
369 bi = kzalloc(sizeof(*bi), GFP_KERNEL);
371 goto out_clk_disable;
373 platform_set_drvdata(pdev, bi);
376 adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC;
377 adap->algo = &bcm2708_i2c_algorithm;
378 adap->algo_data = bi;
379 adap->dev.parent = &pdev->dev;
381 strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
382 adap->dev.of_node = pdev->dev.of_node;
386 adap->class = I2C_CLASS_HWMON;
389 adap->class = I2C_CLASS_DDC;
392 adap->class = I2C_CLASS_DDC;
395 dev_err(&pdev->dev, "can only bind to BSC 0, 1 or 2\n");
400 spin_lock_init(&bi->lock);
401 init_completion(&bi->done);
403 bi->base = ioremap(regs->start, resource_size(regs));
405 dev_err(&pdev->dev, "could not remap memory\n");
412 err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED,
413 dev_name(&pdev->dev), bi);
415 dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
419 bcm2708_bsc_reset(bi);
421 err = i2c_add_numbered_adapter(adap);
423 dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err);
427 bus_hz = clk_get_rate(bi->clk);
428 cdiv = bus_hz / baud;
431 baud = bus_hz / cdiv;
434 clk_tout = 35/1000*baud; //35ms timeout as per SMBus specs.
435 if (clk_tout > 0xffff)
439 bi->clk_tout = clk_tout;
441 dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n",
442 pdev->id, (unsigned long)regs->start, irq, baud);
447 free_irq(bi->irq, bi);
453 clk_disable_unprepare(clk);
459 static int bcm2708_i2c_remove(struct platform_device *pdev)
461 struct bcm2708_i2c *bi = platform_get_drvdata(pdev);
463 platform_set_drvdata(pdev, NULL);
465 i2c_del_adapter(&bi->adapter);
466 free_irq(bi->irq, bi);
468 clk_disable_unprepare(bi->clk);
475 static const struct of_device_id bcm2708_i2c_of_match[] = {
476 { .compatible = "brcm,bcm2708-i2c" },
479 MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match);
481 static struct platform_driver bcm2708_i2c_driver = {
484 .owner = THIS_MODULE,
485 .of_match_table = bcm2708_i2c_of_match,
487 .probe = bcm2708_i2c_probe,
488 .remove = bcm2708_i2c_remove,
491 // module_platform_driver(bcm2708_i2c_driver);
494 static int __init bcm2708_i2c_init(void)
496 return platform_driver_register(&bcm2708_i2c_driver);
499 static void __exit bcm2708_i2c_exit(void)
501 platform_driver_unregister(&bcm2708_i2c_driver);
504 module_init(bcm2708_i2c_init);
505 module_exit(bcm2708_i2c_exit);
509 MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708");
510 MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
511 MODULE_LICENSE("GPL v2");
512 MODULE_ALIAS("platform:" DRV_NAME);