brcm2708: add linux 4.1 support
[openwrt.git] / target / linux / brcm2708 / patches-4.1 / 0020-Add-Chris-Boot-s-i2c-driver.patch
1 From 31dade83cc4f448f81d7d460c59d02b9ebc3b05b Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Wed, 17 Jun 2015 15:44:08 +0100
4 Subject: [PATCH 020/121] Add Chris Boot's i2c driver
5
6 i2c-bcm2708: fixed baudrate
7
8 Fixed issue where the wrong CDIV value was set for baudrates below 3815 Hz (for 250MHz bus clock).
9 In that case the computed CDIV value was more than 0xffff. However the CDIV register width is only 16 bits.
10 This resulted in incorrect setting of CDIV and higher baudrate than intended.
11 Example: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0x1704 -> 42430Hz
12 After correction: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0xffff -> 3815Hz
13 The correct baudrate is shown in the log after the cdiv > 0xffff correction.
14
15 Perform I2C combined transactions when possible
16
17 Perform I2C combined transactions whenever possible, within the
18 restrictions of the Broadcomm Serial Controller.
19
20 Disable DONE interrupt during TA poll
21
22 Prevent interrupt from being triggered if poll is missed and transfer
23 starts and finishes.
24
25 i2c: Make combined transactions optional and disabled by default
26
27 i2c: bcm2708: add device tree support
28
29 Add DT support to driver and add to .dtsi file.
30 Setup pins in .dts file.
31 i2c is disabled by default.
32
33 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
34
35 bcm2708: don't register i2c controllers when using DT
36
37 The devices for the i2c controllers are in the Device Tree.
38 Only register devices when not using DT.
39
40 Signed-off-by: Noralf Tronnes <notro@tronnes.org>
41
42 I2C: Only register the I2C device for the current board revision
43
44 i2c_bcm2708: Fix clock reference counting
45
46 Fix grabbing lock from atomic context in i2c driver
47
48 2 main changes:
49 - check for timeouts in the bcm2708_bsc_setup function as indicated by this comment:
50       /* poll for transfer start bit (should only take 1-20 polls) */
51   This implies that the setup function can now fail so account for this everywhere it's called
52 - Removed the clk_get_rate call from inside the setup function as it locks a mutex and that's not ok since we call it from under a spin lock.
53
54 i2c-bcm2708: When using DT, leave the GPIO setup to pinctrl
55 ---
56  arch/arm/mach-bcm2708/bcm2708.c  |  51 ++++
57  arch/arm/mach-bcm2709/bcm2709.c  |  51 ++++
58  drivers/i2c/busses/Kconfig       |  21 +-
59  drivers/i2c/busses/Makefile      |   2 +
60  drivers/i2c/busses/i2c-bcm2708.c | 522 +++++++++++++++++++++++++++++++++++++++
61  5 files changed, 646 insertions(+), 1 deletion(-)
62  create mode 100644 drivers/i2c/busses/i2c-bcm2708.c
63
64 --- a/arch/arm/mach-bcm2708/bcm2708.c
65 +++ b/arch/arm/mach-bcm2708/bcm2708.c
66 @@ -83,6 +83,7 @@ static unsigned uart_clock = UART0_CLOCK
67  static unsigned disk_led_gpio = 16;
68  static unsigned disk_led_active_low = 1;
69  static unsigned reboot_part = 0;
70 +static bool vc_i2c_override = false;
71  
72  static unsigned use_dt = 0;
73  
74 @@ -550,6 +551,45 @@ static struct spi_board_info bcm2708_spi
75  };
76  #endif
77  
78 +static struct resource bcm2708_bsc0_resources[] = {
79 +       {
80 +               .start = BSC0_BASE,
81 +               .end = BSC0_BASE + SZ_256 - 1,
82 +               .flags = IORESOURCE_MEM,
83 +       }, {
84 +               .start = INTERRUPT_I2C,
85 +               .end = INTERRUPT_I2C,
86 +               .flags = IORESOURCE_IRQ,
87 +       }
88 +};
89 +
90 +static struct platform_device bcm2708_bsc0_device = {
91 +       .name = "bcm2708_i2c",
92 +       .id = 0,
93 +       .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources),
94 +       .resource = bcm2708_bsc0_resources,
95 +};
96 +
97 +
98 +static struct resource bcm2708_bsc1_resources[] = {
99 +       {
100 +               .start = BSC1_BASE,
101 +               .end = BSC1_BASE + SZ_256 - 1,
102 +               .flags = IORESOURCE_MEM,
103 +       }, {
104 +               .start = INTERRUPT_I2C,
105 +               .end = INTERRUPT_I2C,
106 +               .flags = IORESOURCE_IRQ,
107 +       }
108 +};
109 +
110 +static struct platform_device bcm2708_bsc1_device = {
111 +       .name = "bcm2708_i2c",
112 +       .id = 1,
113 +       .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources),
114 +       .resource = bcm2708_bsc1_resources,
115 +};
116 +
117  static struct platform_device bcm2835_thermal_device = {
118         .name = "bcm2835_thermal",
119  };
120 @@ -702,6 +742,15 @@ void __init bcm2708_init(void)
121  
122         bcm_register_device_dt(&bcm2708_spi_device);
123  
124 +       if (vc_i2c_override) {
125 +               bcm_register_device_dt(&bcm2708_bsc0_device);
126 +               bcm_register_device_dt(&bcm2708_bsc1_device);
127 +       } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) {
128 +               bcm_register_device_dt(&bcm2708_bsc0_device);
129 +       } else {
130 +               bcm_register_device_dt(&bcm2708_bsc1_device);
131 +       }
132 +
133         bcm_register_device_dt(&bcm2835_thermal_device);
134  
135         if (!use_dt) {
136 @@ -893,3 +942,5 @@ module_param(uart_clock, uint, 0644);
137  module_param(disk_led_gpio, uint, 0644);
138  module_param(disk_led_active_low, uint, 0644);
139  module_param(reboot_part, uint, 0644);
140 +module_param(vc_i2c_override, bool, 0644);
141 +MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral.");
142 --- a/arch/arm/mach-bcm2709/bcm2709.c
143 +++ b/arch/arm/mach-bcm2709/bcm2709.c
144 @@ -85,6 +85,7 @@ static unsigned uart_clock = UART0_CLOCK
145  static unsigned disk_led_gpio = 16;
146  static unsigned disk_led_active_low = 1;
147  static unsigned reboot_part = 0;
148 +static bool vc_i2c_override = false;
149  
150  static unsigned use_dt = 0;
151  
152 @@ -570,6 +571,45 @@ static struct spi_board_info bcm2708_spi
153  };
154  #endif
155  
156 +static struct resource bcm2708_bsc0_resources[] = {
157 +       {
158 +               .start = BSC0_BASE,
159 +               .end = BSC0_BASE + SZ_256 - 1,
160 +               .flags = IORESOURCE_MEM,
161 +       }, {
162 +               .start = INTERRUPT_I2C,
163 +               .end = INTERRUPT_I2C,
164 +               .flags = IORESOURCE_IRQ,
165 +       }
166 +};
167 +
168 +static struct platform_device bcm2708_bsc0_device = {
169 +       .name = "bcm2708_i2c",
170 +       .id = 0,
171 +       .num_resources = ARRAY_SIZE(bcm2708_bsc0_resources),
172 +       .resource = bcm2708_bsc0_resources,
173 +};
174 +
175 +
176 +static struct resource bcm2708_bsc1_resources[] = {
177 +       {
178 +               .start = BSC1_BASE,
179 +               .end = BSC1_BASE + SZ_256 - 1,
180 +               .flags = IORESOURCE_MEM,
181 +       }, {
182 +               .start = INTERRUPT_I2C,
183 +               .end = INTERRUPT_I2C,
184 +               .flags = IORESOURCE_IRQ,
185 +       }
186 +};
187 +
188 +static struct platform_device bcm2708_bsc1_device = {
189 +       .name = "bcm2708_i2c",
190 +       .id = 1,
191 +       .num_resources = ARRAY_SIZE(bcm2708_bsc1_resources),
192 +       .resource = bcm2708_bsc1_resources,
193 +};
194 +
195  static struct platform_device bcm2835_thermal_device = {
196         .name = "bcm2835_thermal",
197  };
198 @@ -722,6 +762,15 @@ void __init bcm2709_init(void)
199  
200         bcm_register_device_dt(&bcm2708_spi_device);
201  
202 +       if (vc_i2c_override) {
203 +               bcm_register_device_dt(&bcm2708_bsc0_device);
204 +               bcm_register_device_dt(&bcm2708_bsc1_device);
205 +       } else if ((boardrev & 0xffffff) == 0x2 || (boardrev & 0xffffff) == 0x3) {
206 +               bcm_register_device_dt(&bcm2708_bsc0_device);
207 +       } else {
208 +               bcm_register_device_dt(&bcm2708_bsc1_device);
209 +       }
210 +
211         bcm_register_device_dt(&bcm2835_thermal_device);
212  
213         if (!use_dt) {
214 @@ -1061,3 +1110,5 @@ module_param(uart_clock, uint, 0644);
215  module_param(disk_led_gpio, uint, 0644);
216  module_param(disk_led_active_low, uint, 0644);
217  module_param(reboot_part, uint, 0644);
218 +module_param(vc_i2c_override, bool, 0644);
219 +MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral.");
220 --- a/drivers/i2c/busses/Kconfig
221 +++ b/drivers/i2c/busses/Kconfig
222 @@ -8,6 +8,25 @@ menu "I2C Hardware Bus support"
223  comment "PC SMBus host controller drivers"
224         depends on PCI
225  
226 +config I2C_BCM2708
227 +       tristate "BCM2708 BSC"
228 +       depends on MACH_BCM2708 || MACH_BCM2709
229 +       help
230 +         Enabling this option will add BSC (Broadcom Serial Controller)
231 +         support for the BCM2708. BSC is a Broadcom proprietary bus compatible
232 +         with I2C/TWI/SMBus.
233 +
234 +config I2C_BCM2708_BAUDRATE
235 +       prompt "BCM2708 I2C baudrate"
236 +       depends on I2C_BCM2708
237 +       int
238 +       default 100000
239 +       help
240 +         Set the I2C baudrate. This will alter the default value. A
241 +         different baudrate can be set by using a module parameter as well. If
242 +         no parameter is provided when loading, this is the value that will be
243 +         used.
244 +
245  config I2C_ALI1535
246         tristate "ALI 1535"
247         depends on PCI
248 @@ -362,7 +381,7 @@ config I2C_AXXIA
249  
250  config I2C_BCM2835
251         tristate "Broadcom BCM2835 I2C controller"
252 -       depends on ARCH_BCM2835
253 +       depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709
254         help
255           If you say yes to this option, support will be included for the
256           BCM2835 I2C controller.
257 --- a/drivers/i2c/busses/Makefile
258 +++ b/drivers/i2c/busses/Makefile
259 @@ -2,6 +2,8 @@
260  # Makefile for the i2c bus drivers.
261  #
262  
263 +obj-$(CONFIG_I2C_BCM2708)      += i2c-bcm2708.o
264 +
265  # ACPI drivers
266  obj-$(CONFIG_I2C_SCMI)         += i2c-scmi.o
267  
268 --- /dev/null
269 +++ b/drivers/i2c/busses/i2c-bcm2708.c
270 @@ -0,0 +1,522 @@
271 +/*
272 + * Driver for Broadcom BCM2708 BSC Controllers
273 + *
274 + * Copyright (C) 2012 Chris Boot & Frank Buss
275 + *
276 + * This driver is inspired by:
277 + * i2c-ocores.c, by Peter Korsgaard <jacmet@sunsite.dk>
278 + *
279 + * This program is free software; you can redistribute it and/or modify
280 + * it under the terms of the GNU General Public License as published by
281 + * the Free Software Foundation; either version 2 of the License, or
282 + * (at your option) any later version.
283 + *
284 + * This program is distributed in the hope that it will be useful,
285 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
286 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
287 + * GNU General Public License for more details.
288 + *
289 + * You should have received a copy of the GNU General Public License
290 + * along with this program; if not, write to the Free Software
291 + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
292 + */
293 +
294 +#include <linux/kernel.h>
295 +#include <linux/module.h>
296 +#include <linux/spinlock.h>
297 +#include <linux/clk.h>
298 +#include <linux/err.h>
299 +#include <linux/of.h>
300 +#include <linux/platform_device.h>
301 +#include <linux/io.h>
302 +#include <linux/slab.h>
303 +#include <linux/i2c.h>
304 +#include <linux/interrupt.h>
305 +#include <linux/sched.h>
306 +#include <linux/wait.h>
307 +
308 +/* BSC register offsets */
309 +#define BSC_C                  0x00
310 +#define BSC_S                  0x04
311 +#define BSC_DLEN               0x08
312 +#define BSC_A                  0x0c
313 +#define BSC_FIFO               0x10
314 +#define BSC_DIV                        0x14
315 +#define BSC_DEL                        0x18
316 +#define BSC_CLKT               0x1c
317 +
318 +/* Bitfields in BSC_C */
319 +#define BSC_C_I2CEN            0x00008000
320 +#define BSC_C_INTR             0x00000400
321 +#define BSC_C_INTT             0x00000200
322 +#define BSC_C_INTD             0x00000100
323 +#define BSC_C_ST               0x00000080
324 +#define BSC_C_CLEAR_1          0x00000020
325 +#define BSC_C_CLEAR_2          0x00000010
326 +#define BSC_C_READ             0x00000001
327 +
328 +/* Bitfields in BSC_S */
329 +#define BSC_S_CLKT             0x00000200
330 +#define BSC_S_ERR              0x00000100
331 +#define BSC_S_RXF              0x00000080
332 +#define BSC_S_TXE              0x00000040
333 +#define BSC_S_RXD              0x00000020
334 +#define BSC_S_TXD              0x00000010
335 +#define BSC_S_RXR              0x00000008
336 +#define BSC_S_TXW              0x00000004
337 +#define BSC_S_DONE             0x00000002
338 +#define BSC_S_TA               0x00000001
339 +
340 +#define I2C_TIMEOUT_MS 150
341 +#define I2C_WAIT_LOOP_COUNT 40
342 +
343 +#define DRV_NAME       "bcm2708_i2c"
344 +
345 +static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE;
346 +module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
347 +MODULE_PARM_DESC(baudrate, "The I2C baudrate");
348 +
349 +static bool combined = false;
350 +module_param(combined, bool, 0644);
351 +MODULE_PARM_DESC(combined, "Use combined transactions");
352 +
353 +struct bcm2708_i2c {
354 +       struct i2c_adapter adapter;
355 +
356 +       spinlock_t lock;
357 +       void __iomem *base;
358 +       int irq;
359 +       struct clk *clk;
360 +       u32 cdiv;
361 +
362 +       struct completion done;
363 +
364 +       struct i2c_msg *msg;
365 +       int pos;
366 +       int nmsgs;
367 +       bool error;
368 +};
369 +
370 +/*
371 + * This function sets the ALT mode on the I2C pins so that we can use them with
372 + * the BSC hardware.
373 + *
374 + * FIXME: This is a hack. Use pinmux / pinctrl.
375 + */
376 +static void bcm2708_i2c_init_pinmode(int id)
377 +{
378 +#define INP_GPIO(g) *(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))
379 +#define SET_GPIO_ALT(g,a) *(gpio+(((g)/10))) |= (((a)<=3?(a)+4:(a)==4?3:2)<<(((g)%10)*3))
380 +
381 +       int pin;
382 +       u32 *gpio = ioremap(GPIO_BASE, SZ_16K);
383 +
384 +       BUG_ON(id != 0 && id != 1);
385 +       /* BSC0 is on GPIO 0 & 1, BSC1 is on GPIO 2 & 3 */
386 +       for (pin = id*2+0; pin <= id*2+1; pin++) {
387 +               printk("bcm2708_i2c_init_pinmode(%d,%d)\n", id, pin);
388 +               INP_GPIO(pin);          /* set mode to GPIO input first */
389 +               SET_GPIO_ALT(pin, 0);   /* set mode to ALT 0 */
390 +       }
391 +
392 +       iounmap(gpio);
393 +
394 +#undef INP_GPIO
395 +#undef SET_GPIO_ALT
396 +}
397 +
398 +static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg)
399 +{
400 +       return readl(bi->base + reg);
401 +}
402 +
403 +static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val)
404 +{
405 +       writel(val, bi->base + reg);
406 +}
407 +
408 +static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi)
409 +{
410 +       bcm2708_wr(bi, BSC_C, 0);
411 +       bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE);
412 +}
413 +
414 +static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi)
415 +{
416 +       while ((bcm2708_rd(bi, BSC_S) & BSC_S_RXD) && (bi->pos < bi->msg->len))
417 +               bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO);
418 +}
419 +
420 +static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi)
421 +{
422 +       while ((bcm2708_rd(bi, BSC_S) & BSC_S_TXD) && (bi->pos < bi->msg->len))
423 +               bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
424 +}
425 +
426 +static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi)
427 +{
428 +       u32 cdiv, s;
429 +       u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1;
430 +       int wait_loops = I2C_WAIT_LOOP_COUNT;
431 +
432 +       /* Can't call clk_get_rate as it locks a mutex and here we are spinlocked.
433 +        * Use the value that we cached in the probe.
434 +        */
435 +       cdiv = bi->cdiv;
436 +
437 +       if (bi->msg->flags & I2C_M_RD)
438 +               c |= BSC_C_INTR | BSC_C_READ;
439 +       else
440 +               c |= BSC_C_INTT;
441 +
442 +       bcm2708_wr(bi, BSC_DIV, cdiv);
443 +       bcm2708_wr(bi, BSC_A, bi->msg->addr);
444 +       bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
445 +       if (combined)
446 +       {
447 +               /* Do the next two messages meet combined transaction criteria?
448 +                  - Current message is a write, next message is a read
449 +                  - Both messages to same slave address
450 +                  - Write message can fit inside FIFO (16 bytes or less) */
451 +               if ( (bi->nmsgs > 1) &&
452 +                       !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) &&
453 +                        (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) {
454 +                       /* Fill FIFO with entire write message (16 byte FIFO) */
455 +                       while (bi->pos < bi->msg->len) {
456 +                               bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
457 +                       }
458 +                       /* Start write transfer (no interrupts, don't clear FIFO) */
459 +                       bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST);
460 +
461 +                       /* poll for transfer start bit (should only take 1-20 polls) */
462 +                       do {
463 +                               s = bcm2708_rd(bi, BSC_S);
464 +                       } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0);
465 +
466 +                       /* did we time out or some error occured? */
467 +                       if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) {
468 +                               return -1;
469 +                       }
470 +
471 +                       /* Send next read message before the write transfer finishes. */
472 +                       bi->nmsgs--;
473 +                       bi->msg++;
474 +                       bi->pos = 0;
475 +                       bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
476 +                       c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ;
477 +               }
478 +       }
479 +       bcm2708_wr(bi, BSC_C, c);
480 +
481 +       return 0;
482 +}
483 +
484 +static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id)
485 +{
486 +       struct bcm2708_i2c *bi = dev_id;
487 +       bool handled = true;
488 +       u32 s;
489 +       int ret;
490 +
491 +       spin_lock(&bi->lock);
492 +
493 +       /* we may see camera interrupts on the "other" I2C channel
494 +                  Just return if we've not sent anything */
495 +       if (!bi->nmsgs || !bi->msg) {
496 +               goto early_exit;
497 +       }
498 +
499 +       s = bcm2708_rd(bi, BSC_S);
500 +
501 +       if (s & (BSC_S_CLKT | BSC_S_ERR)) {
502 +               bcm2708_bsc_reset(bi);
503 +               bi->error = true;
504 +
505 +               bi->msg = 0; /* to inform the that all work is done */
506 +               bi->nmsgs = 0;
507 +               /* wake up our bh */
508 +               complete(&bi->done);
509 +       } else if (s & BSC_S_DONE) {
510 +               bi->nmsgs--;
511 +
512 +               if (bi->msg->flags & I2C_M_RD) {
513 +                       bcm2708_bsc_fifo_drain(bi);
514 +               }
515 +
516 +               bcm2708_bsc_reset(bi);
517 +
518 +               if (bi->nmsgs) {
519 +                       /* advance to next message */
520 +                       bi->msg++;
521 +                       bi->pos = 0;
522 +                       ret = bcm2708_bsc_setup(bi);
523 +                       if (ret < 0) {
524 +                               bcm2708_bsc_reset(bi);
525 +                               bi->error = true;
526 +                               bi->msg = 0; /* to inform the that all work is done */
527 +                               bi->nmsgs = 0;
528 +                               /* wake up our bh */
529 +                               complete(&bi->done);
530 +                               goto early_exit;
531 +                       }
532 +               } else {
533 +                       bi->msg = 0; /* to inform the that all work is done */
534 +                       bi->nmsgs = 0;
535 +                       /* wake up our bh */
536 +                       complete(&bi->done);
537 +               }
538 +       } else if (s & BSC_S_TXW) {
539 +               bcm2708_bsc_fifo_fill(bi);
540 +       } else if (s & BSC_S_RXR) {
541 +               bcm2708_bsc_fifo_drain(bi);
542 +       } else {
543 +               handled = false;
544 +       }
545 +
546 +early_exit:
547 +       spin_unlock(&bi->lock);
548 +
549 +       return handled ? IRQ_HANDLED : IRQ_NONE;
550 +}
551 +
552 +static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap,
553 +       struct i2c_msg *msgs, int num)
554 +{
555 +       struct bcm2708_i2c *bi = adap->algo_data;
556 +       unsigned long flags;
557 +       int ret;
558 +
559 +       spin_lock_irqsave(&bi->lock, flags);
560 +
561 +       reinit_completion(&bi->done);
562 +       bi->msg = msgs;
563 +       bi->pos = 0;
564 +       bi->nmsgs = num;
565 +       bi->error = false;
566 +
567 +       ret = bcm2708_bsc_setup(bi);
568 +
569 +       spin_unlock_irqrestore(&bi->lock, flags);
570 +
571 +       /* check the result of the setup */
572 +       if (ret < 0)
573 +       {
574 +               dev_err(&adap->dev, "transfer setup timed out\n");
575 +               goto error_timeout;
576 +       }
577 +
578 +       ret = wait_for_completion_timeout(&bi->done, msecs_to_jiffies(I2C_TIMEOUT_MS));
579 +       if (ret == 0) {
580 +               dev_err(&adap->dev, "transfer timed out\n");
581 +               goto error_timeout;
582 +       }
583 +
584 +       ret = bi->error ? -EIO : num;
585 +       return ret;
586 +
587 +error_timeout:
588 +       spin_lock_irqsave(&bi->lock, flags);
589 +       bcm2708_bsc_reset(bi);
590 +       bi->msg = 0; /* to inform the interrupt handler that there's nothing else to be done */
591 +       bi->nmsgs = 0;
592 +       spin_unlock_irqrestore(&bi->lock, flags);
593 +       return -ETIMEDOUT;
594 +}
595 +
596 +static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap)
597 +{
598 +       return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL;
599 +}
600 +
601 +static struct i2c_algorithm bcm2708_i2c_algorithm = {
602 +       .master_xfer = bcm2708_i2c_master_xfer,
603 +       .functionality = bcm2708_i2c_functionality,
604 +};
605 +
606 +static int bcm2708_i2c_probe(struct platform_device *pdev)
607 +{
608 +       struct resource *regs;
609 +       int irq, err = -ENOMEM;
610 +       struct clk *clk;
611 +       struct bcm2708_i2c *bi;
612 +       struct i2c_adapter *adap;
613 +       unsigned long bus_hz;
614 +       u32 cdiv;
615 +
616 +       if (pdev->dev.of_node) {
617 +               u32 bus_clk_rate;
618 +               pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c");
619 +               if (pdev->id < 0) {
620 +                       dev_err(&pdev->dev, "alias is missing\n");
621 +                       return -EINVAL;
622 +               }
623 +               if (!of_property_read_u32(pdev->dev.of_node,
624 +                                       "clock-frequency", &bus_clk_rate))
625 +                       baudrate = bus_clk_rate;
626 +               else
627 +                       dev_warn(&pdev->dev,
628 +                               "Could not read clock-frequency property\n");
629 +       }
630 +
631 +       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
632 +       if (!regs) {
633 +               dev_err(&pdev->dev, "could not get IO memory\n");
634 +               return -ENXIO;
635 +       }
636 +
637 +       irq = platform_get_irq(pdev, 0);
638 +       if (irq < 0) {
639 +               dev_err(&pdev->dev, "could not get IRQ\n");
640 +               return irq;
641 +       }
642 +
643 +       clk = clk_get(&pdev->dev, NULL);
644 +       if (IS_ERR(clk)) {
645 +               dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk));
646 +               return PTR_ERR(clk);
647 +       }
648 +
649 +       err = clk_prepare_enable(clk);
650 +       if (err) {
651 +               dev_err(&pdev->dev, "could not enable clk: %d\n", err);
652 +               goto out_clk_put;
653 +       }
654 +
655 +       if (!pdev->dev.of_node)
656 +               bcm2708_i2c_init_pinmode(pdev->id);
657 +
658 +       bi = kzalloc(sizeof(*bi), GFP_KERNEL);
659 +       if (!bi)
660 +               goto out_clk_disable;
661 +
662 +       platform_set_drvdata(pdev, bi);
663 +
664 +       adap = &bi->adapter;
665 +       adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC;
666 +       adap->algo = &bcm2708_i2c_algorithm;
667 +       adap->algo_data = bi;
668 +       adap->dev.parent = &pdev->dev;
669 +       adap->nr = pdev->id;
670 +       strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
671 +       adap->dev.of_node = pdev->dev.of_node;
672 +
673 +       switch (pdev->id) {
674 +       case 0:
675 +               adap->class = I2C_CLASS_HWMON;
676 +               break;
677 +       case 1:
678 +               adap->class = I2C_CLASS_DDC;
679 +               break;
680 +       default:
681 +               dev_err(&pdev->dev, "can only bind to BSC 0 or 1\n");
682 +               err = -ENXIO;
683 +               goto out_free_bi;
684 +       }
685 +
686 +       spin_lock_init(&bi->lock);
687 +       init_completion(&bi->done);
688 +
689 +       bi->base = ioremap(regs->start, resource_size(regs));
690 +       if (!bi->base) {
691 +               dev_err(&pdev->dev, "could not remap memory\n");
692 +               goto out_free_bi;
693 +       }
694 +
695 +       bi->irq = irq;
696 +       bi->clk = clk;
697 +
698 +       err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED,
699 +                       dev_name(&pdev->dev), bi);
700 +       if (err) {
701 +               dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
702 +               goto out_iounmap;
703 +       }
704 +
705 +       bcm2708_bsc_reset(bi);
706 +
707 +       err = i2c_add_numbered_adapter(adap);
708 +       if (err < 0) {
709 +               dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err);
710 +               goto out_free_irq;
711 +       }
712 +
713 +       bus_hz = clk_get_rate(bi->clk);
714 +       cdiv = bus_hz / baudrate;
715 +       if (cdiv > 0xffff) {
716 +               cdiv = 0xffff;
717 +               baudrate = bus_hz / cdiv;
718 +       }
719 +       bi->cdiv = cdiv;
720 +
721 +       dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n",
722 +               pdev->id, (unsigned long)regs->start, irq, baudrate);
723 +
724 +       return 0;
725 +
726 +out_free_irq:
727 +       free_irq(bi->irq, bi);
728 +out_iounmap:
729 +       iounmap(bi->base);
730 +out_free_bi:
731 +       kfree(bi);
732 +out_clk_disable:
733 +       clk_disable_unprepare(clk);
734 +out_clk_put:
735 +       clk_put(clk);
736 +       return err;
737 +}
738 +
739 +static int bcm2708_i2c_remove(struct platform_device *pdev)
740 +{
741 +       struct bcm2708_i2c *bi = platform_get_drvdata(pdev);
742 +
743 +       platform_set_drvdata(pdev, NULL);
744 +
745 +       i2c_del_adapter(&bi->adapter);
746 +       free_irq(bi->irq, bi);
747 +       iounmap(bi->base);
748 +       clk_disable_unprepare(bi->clk);
749 +       clk_put(bi->clk);
750 +       kfree(bi);
751 +
752 +       return 0;
753 +}
754 +
755 +static const struct of_device_id bcm2708_i2c_of_match[] = {
756 +        { .compatible = "brcm,bcm2708-i2c" },
757 +        {},
758 +};
759 +MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match);
760 +
761 +static struct platform_driver bcm2708_i2c_driver = {
762 +       .driver         = {
763 +               .name   = DRV_NAME,
764 +               .owner  = THIS_MODULE,
765 +               .of_match_table = bcm2708_i2c_of_match,
766 +       },
767 +       .probe          = bcm2708_i2c_probe,
768 +       .remove         = bcm2708_i2c_remove,
769 +};
770 +
771 +// module_platform_driver(bcm2708_i2c_driver);
772 +
773 +
774 +static int __init bcm2708_i2c_init(void)
775 +{
776 +       return platform_driver_register(&bcm2708_i2c_driver);
777 +}
778 +
779 +static void __exit bcm2708_i2c_exit(void)
780 +{
781 +       platform_driver_unregister(&bcm2708_i2c_driver);
782 +}
783 +
784 +module_init(bcm2708_i2c_init);
785 +module_exit(bcm2708_i2c_exit);
786 +
787 +
788 +
789 +MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708");
790 +MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
791 +MODULE_LICENSE("GPL v2");
792 +MODULE_ALIAS("platform:" DRV_NAME);