0045-Add-Chris-Boot-s-i2c-driver.patch 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. From dc4e4461802c9dff395a49212e8420a9f586e247 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 045/381] Add Chris Boot's i2c driver
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. i2c-bcm2708: fixed baudrate
  9. Fixed issue where the wrong CDIV value was set for baudrates below 3815 Hz (for 250MHz bus clock).
  10. In that case the computed CDIV value was more than 0xffff. However the CDIV register width is only 16 bits.
  11. This resulted in incorrect setting of CDIV and higher baudrate than intended.
  12. Example: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0x1704 -> 42430Hz
  13. After correction: 3500Hz -> CDIV=0x11704 -> CDIV(16bit)=0xffff -> 3815Hz
  14. The correct baudrate is shown in the log after the cdiv > 0xffff correction.
  15. Perform I2C combined transactions when possible
  16. Perform I2C combined transactions whenever possible, within the
  17. restrictions of the Broadcomm Serial Controller.
  18. Disable DONE interrupt during TA poll
  19. Prevent interrupt from being triggered if poll is missed and transfer
  20. starts and finishes.
  21. i2c: Make combined transactions optional and disabled by default
  22. i2c: bcm2708: add device tree support
  23. Add DT support to driver and add to .dtsi file.
  24. Setup pins in .dts file.
  25. i2c is disabled by default.
  26. Signed-off-by: Noralf Tronnes <notro@tronnes.org>
  27. bcm2708: don't register i2c controllers when using DT
  28. The devices for the i2c controllers are in the Device Tree.
  29. Only register devices when not using DT.
  30. Signed-off-by: Noralf Tronnes <notro@tronnes.org>
  31. I2C: Only register the I2C device for the current board revision
  32. i2c_bcm2708: Fix clock reference counting
  33. Fix grabbing lock from atomic context in i2c driver
  34. 2 main changes:
  35. - check for timeouts in the bcm2708_bsc_setup function as indicated by this comment:
  36. /* poll for transfer start bit (should only take 1-20 polls) */
  37. This implies that the setup function can now fail so account for this everywhere it's called
  38. - 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.
  39. i2c-bcm2708: When using DT, leave the GPIO setup to pinctrl
  40. i2c-bcm2708: Increase timeouts to allow larger transfers
  41. Use the timeout value provided by the I2C_TIMEOUT ioctl when waiting
  42. for completion. The default timeout is 1 second.
  43. See: https://github.com/raspberrypi/linux/issues/260
  44. i2c-bcm2708/BCM270X_DT: Add support for I2C2
  45. The third I2C bus (I2C2) is normally reserved for HDMI use. Careless
  46. use of this bus can break an attached display - use with caution.
  47. It is recommended to disable accesses by VideoCore by setting
  48. hdmi_ignore_edid=1 or hdmi_edid_file=1 in config.txt.
  49. The interface is disabled by default - enable using the
  50. i2c2_iknowwhatimdoing DT parameter.
  51. bcm2708-spi: Don't use static pin configuration with DT
  52. Also remove superfluous error checking - the SPI framework ensures the
  53. validity of the chip_select value.
  54. i2c-bcm2708: Remove non-DT support
  55. Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
  56. ---
  57. drivers/i2c/busses/Kconfig | 21 +-
  58. drivers/i2c/busses/Makefile | 2 +
  59. drivers/i2c/busses/i2c-bcm2708.c | 493 +++++++++++++++++++++++++++++++++++++++
  60. 3 files changed, 515 insertions(+), 1 deletion(-)
  61. create mode 100644 drivers/i2c/busses/i2c-bcm2708.c
  62. --- a/drivers/i2c/busses/Kconfig
  63. +++ b/drivers/i2c/busses/Kconfig
  64. @@ -8,6 +8,25 @@ menu "I2C Hardware Bus support"
  65. comment "PC SMBus host controller drivers"
  66. depends on PCI
  67. +config I2C_BCM2708
  68. + tristate "BCM2708 BSC"
  69. + depends on MACH_BCM2708 || MACH_BCM2709 || ARCH_BCM2835
  70. + help
  71. + Enabling this option will add BSC (Broadcom Serial Controller)
  72. + support for the BCM2708. BSC is a Broadcom proprietary bus compatible
  73. + with I2C/TWI/SMBus.
  74. +
  75. +config I2C_BCM2708_BAUDRATE
  76. + prompt "BCM2708 I2C baudrate"
  77. + depends on I2C_BCM2708
  78. + int
  79. + default 100000
  80. + help
  81. + Set the I2C baudrate. This will alter the default value. A
  82. + different baudrate can be set by using a module parameter as well. If
  83. + no parameter is provided when loading, this is the value that will be
  84. + used.
  85. +
  86. config I2C_ALI1535
  87. tristate "ALI 1535"
  88. depends on PCI
  89. @@ -365,7 +384,7 @@ config I2C_AXXIA
  90. config I2C_BCM2835
  91. tristate "Broadcom BCM2835 I2C controller"
  92. - depends on ARCH_BCM2835
  93. + depends on ARCH_BCM2835 || ARCH_BCM2708 || ARCH_BCM2709
  94. help
  95. If you say yes to this option, support will be included for the
  96. BCM2835 I2C controller.
  97. --- a/drivers/i2c/busses/Makefile
  98. +++ b/drivers/i2c/busses/Makefile
  99. @@ -2,6 +2,8 @@
  100. # Makefile for the i2c bus drivers.
  101. #
  102. +obj-$(CONFIG_I2C_BCM2708) += i2c-bcm2708.o
  103. +
  104. # ACPI drivers
  105. obj-$(CONFIG_I2C_SCMI) += i2c-scmi.o
  106. --- /dev/null
  107. +++ b/drivers/i2c/busses/i2c-bcm2708.c
  108. @@ -0,0 +1,493 @@
  109. +/*
  110. + * Driver for Broadcom BCM2708 BSC Controllers
  111. + *
  112. + * Copyright (C) 2012 Chris Boot & Frank Buss
  113. + *
  114. + * This driver is inspired by:
  115. + * i2c-ocores.c, by Peter Korsgaard <jacmet@sunsite.dk>
  116. + *
  117. + * This program is free software; you can redistribute it and/or modify
  118. + * it under the terms of the GNU General Public License as published by
  119. + * the Free Software Foundation; either version 2 of the License, or
  120. + * (at your option) any later version.
  121. + *
  122. + * This program is distributed in the hope that it will be useful,
  123. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  124. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  125. + * GNU General Public License for more details.
  126. + *
  127. + * You should have received a copy of the GNU General Public License
  128. + * along with this program; if not, write to the Free Software
  129. + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  130. + */
  131. +
  132. +#include <linux/kernel.h>
  133. +#include <linux/module.h>
  134. +#include <linux/spinlock.h>
  135. +#include <linux/clk.h>
  136. +#include <linux/err.h>
  137. +#include <linux/of.h>
  138. +#include <linux/platform_device.h>
  139. +#include <linux/io.h>
  140. +#include <linux/slab.h>
  141. +#include <linux/i2c.h>
  142. +#include <linux/interrupt.h>
  143. +#include <linux/sched.h>
  144. +#include <linux/wait.h>
  145. +
  146. +/* BSC register offsets */
  147. +#define BSC_C 0x00
  148. +#define BSC_S 0x04
  149. +#define BSC_DLEN 0x08
  150. +#define BSC_A 0x0c
  151. +#define BSC_FIFO 0x10
  152. +#define BSC_DIV 0x14
  153. +#define BSC_DEL 0x18
  154. +#define BSC_CLKT 0x1c
  155. +
  156. +/* Bitfields in BSC_C */
  157. +#define BSC_C_I2CEN 0x00008000
  158. +#define BSC_C_INTR 0x00000400
  159. +#define BSC_C_INTT 0x00000200
  160. +#define BSC_C_INTD 0x00000100
  161. +#define BSC_C_ST 0x00000080
  162. +#define BSC_C_CLEAR_1 0x00000020
  163. +#define BSC_C_CLEAR_2 0x00000010
  164. +#define BSC_C_READ 0x00000001
  165. +
  166. +/* Bitfields in BSC_S */
  167. +#define BSC_S_CLKT 0x00000200
  168. +#define BSC_S_ERR 0x00000100
  169. +#define BSC_S_RXF 0x00000080
  170. +#define BSC_S_TXE 0x00000040
  171. +#define BSC_S_RXD 0x00000020
  172. +#define BSC_S_TXD 0x00000010
  173. +#define BSC_S_RXR 0x00000008
  174. +#define BSC_S_TXW 0x00000004
  175. +#define BSC_S_DONE 0x00000002
  176. +#define BSC_S_TA 0x00000001
  177. +
  178. +#define I2C_WAIT_LOOP_COUNT 200
  179. +
  180. +#define DRV_NAME "bcm2708_i2c"
  181. +
  182. +static unsigned int baudrate = CONFIG_I2C_BCM2708_BAUDRATE;
  183. +module_param(baudrate, uint, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
  184. +MODULE_PARM_DESC(baudrate, "The I2C baudrate");
  185. +
  186. +static bool combined = false;
  187. +module_param(combined, bool, 0644);
  188. +MODULE_PARM_DESC(combined, "Use combined transactions");
  189. +
  190. +struct bcm2708_i2c {
  191. + struct i2c_adapter adapter;
  192. +
  193. + spinlock_t lock;
  194. + void __iomem *base;
  195. + int irq;
  196. + struct clk *clk;
  197. + u32 cdiv;
  198. +
  199. + struct completion done;
  200. +
  201. + struct i2c_msg *msg;
  202. + int pos;
  203. + int nmsgs;
  204. + bool error;
  205. +};
  206. +
  207. +static inline u32 bcm2708_rd(struct bcm2708_i2c *bi, unsigned reg)
  208. +{
  209. + return readl(bi->base + reg);
  210. +}
  211. +
  212. +static inline void bcm2708_wr(struct bcm2708_i2c *bi, unsigned reg, u32 val)
  213. +{
  214. + writel(val, bi->base + reg);
  215. +}
  216. +
  217. +static inline void bcm2708_bsc_reset(struct bcm2708_i2c *bi)
  218. +{
  219. + bcm2708_wr(bi, BSC_C, 0);
  220. + bcm2708_wr(bi, BSC_S, BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE);
  221. +}
  222. +
  223. +static inline void bcm2708_bsc_fifo_drain(struct bcm2708_i2c *bi)
  224. +{
  225. + while ((bcm2708_rd(bi, BSC_S) & BSC_S_RXD) && (bi->pos < bi->msg->len))
  226. + bi->msg->buf[bi->pos++] = bcm2708_rd(bi, BSC_FIFO);
  227. +}
  228. +
  229. +static inline void bcm2708_bsc_fifo_fill(struct bcm2708_i2c *bi)
  230. +{
  231. + while ((bcm2708_rd(bi, BSC_S) & BSC_S_TXD) && (bi->pos < bi->msg->len))
  232. + bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
  233. +}
  234. +
  235. +static inline int bcm2708_bsc_setup(struct bcm2708_i2c *bi)
  236. +{
  237. + u32 cdiv, s;
  238. + u32 c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_ST | BSC_C_CLEAR_1;
  239. + int wait_loops = I2C_WAIT_LOOP_COUNT;
  240. +
  241. + /* Can't call clk_get_rate as it locks a mutex and here we are spinlocked.
  242. + * Use the value that we cached in the probe.
  243. + */
  244. + cdiv = bi->cdiv;
  245. +
  246. + if (bi->msg->flags & I2C_M_RD)
  247. + c |= BSC_C_INTR | BSC_C_READ;
  248. + else
  249. + c |= BSC_C_INTT;
  250. +
  251. + bcm2708_wr(bi, BSC_DIV, cdiv);
  252. + bcm2708_wr(bi, BSC_A, bi->msg->addr);
  253. + bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
  254. + if (combined)
  255. + {
  256. + /* Do the next two messages meet combined transaction criteria?
  257. + - Current message is a write, next message is a read
  258. + - Both messages to same slave address
  259. + - Write message can fit inside FIFO (16 bytes or less) */
  260. + if ( (bi->nmsgs > 1) &&
  261. + !(bi->msg[0].flags & I2C_M_RD) && (bi->msg[1].flags & I2C_M_RD) &&
  262. + (bi->msg[0].addr == bi->msg[1].addr) && (bi->msg[0].len <= 16)) {
  263. + /* Fill FIFO with entire write message (16 byte FIFO) */
  264. + while (bi->pos < bi->msg->len) {
  265. + bcm2708_wr(bi, BSC_FIFO, bi->msg->buf[bi->pos++]);
  266. + }
  267. + /* Start write transfer (no interrupts, don't clear FIFO) */
  268. + bcm2708_wr(bi, BSC_C, BSC_C_I2CEN | BSC_C_ST);
  269. +
  270. + /* poll for transfer start bit (should only take 1-20 polls) */
  271. + do {
  272. + s = bcm2708_rd(bi, BSC_S);
  273. + } while (!(s & (BSC_S_TA | BSC_S_ERR | BSC_S_CLKT | BSC_S_DONE)) && --wait_loops >= 0);
  274. +
  275. + /* did we time out or some error occured? */
  276. + if (wait_loops < 0 || (s & (BSC_S_ERR | BSC_S_CLKT))) {
  277. + return -1;
  278. + }
  279. +
  280. + /* Send next read message before the write transfer finishes. */
  281. + bi->nmsgs--;
  282. + bi->msg++;
  283. + bi->pos = 0;
  284. + bcm2708_wr(bi, BSC_DLEN, bi->msg->len);
  285. + c = BSC_C_I2CEN | BSC_C_INTD | BSC_C_INTR | BSC_C_ST | BSC_C_READ;
  286. + }
  287. + }
  288. + bcm2708_wr(bi, BSC_C, c);
  289. +
  290. + return 0;
  291. +}
  292. +
  293. +static irqreturn_t bcm2708_i2c_interrupt(int irq, void *dev_id)
  294. +{
  295. + struct bcm2708_i2c *bi = dev_id;
  296. + bool handled = true;
  297. + u32 s;
  298. + int ret;
  299. +
  300. + spin_lock(&bi->lock);
  301. +
  302. + /* we may see camera interrupts on the "other" I2C channel
  303. + Just return if we've not sent anything */
  304. + if (!bi->nmsgs || !bi->msg) {
  305. + goto early_exit;
  306. + }
  307. +
  308. + s = bcm2708_rd(bi, BSC_S);
  309. +
  310. + if (s & (BSC_S_CLKT | BSC_S_ERR)) {
  311. + bcm2708_bsc_reset(bi);
  312. + bi->error = true;
  313. +
  314. + bi->msg = 0; /* to inform the that all work is done */
  315. + bi->nmsgs = 0;
  316. + /* wake up our bh */
  317. + complete(&bi->done);
  318. + } else if (s & BSC_S_DONE) {
  319. + bi->nmsgs--;
  320. +
  321. + if (bi->msg->flags & I2C_M_RD) {
  322. + bcm2708_bsc_fifo_drain(bi);
  323. + }
  324. +
  325. + bcm2708_bsc_reset(bi);
  326. +
  327. + if (bi->nmsgs) {
  328. + /* advance to next message */
  329. + bi->msg++;
  330. + bi->pos = 0;
  331. + ret = bcm2708_bsc_setup(bi);
  332. + if (ret < 0) {
  333. + bcm2708_bsc_reset(bi);
  334. + bi->error = true;
  335. + bi->msg = 0; /* to inform the that all work is done */
  336. + bi->nmsgs = 0;
  337. + /* wake up our bh */
  338. + complete(&bi->done);
  339. + goto early_exit;
  340. + }
  341. + } else {
  342. + bi->msg = 0; /* to inform the that all work is done */
  343. + bi->nmsgs = 0;
  344. + /* wake up our bh */
  345. + complete(&bi->done);
  346. + }
  347. + } else if (s & BSC_S_TXW) {
  348. + bcm2708_bsc_fifo_fill(bi);
  349. + } else if (s & BSC_S_RXR) {
  350. + bcm2708_bsc_fifo_drain(bi);
  351. + } else {
  352. + handled = false;
  353. + }
  354. +
  355. +early_exit:
  356. + spin_unlock(&bi->lock);
  357. +
  358. + return handled ? IRQ_HANDLED : IRQ_NONE;
  359. +}
  360. +
  361. +static int bcm2708_i2c_master_xfer(struct i2c_adapter *adap,
  362. + struct i2c_msg *msgs, int num)
  363. +{
  364. + struct bcm2708_i2c *bi = adap->algo_data;
  365. + unsigned long flags;
  366. + int ret;
  367. +
  368. + spin_lock_irqsave(&bi->lock, flags);
  369. +
  370. + reinit_completion(&bi->done);
  371. + bi->msg = msgs;
  372. + bi->pos = 0;
  373. + bi->nmsgs = num;
  374. + bi->error = false;
  375. +
  376. + ret = bcm2708_bsc_setup(bi);
  377. +
  378. + spin_unlock_irqrestore(&bi->lock, flags);
  379. +
  380. + /* check the result of the setup */
  381. + if (ret < 0)
  382. + {
  383. + dev_err(&adap->dev, "transfer setup timed out\n");
  384. + goto error_timeout;
  385. + }
  386. +
  387. + ret = wait_for_completion_timeout(&bi->done, adap->timeout);
  388. + if (ret == 0) {
  389. + dev_err(&adap->dev, "transfer timed out\n");
  390. + goto error_timeout;
  391. + }
  392. +
  393. + ret = bi->error ? -EIO : num;
  394. + return ret;
  395. +
  396. +error_timeout:
  397. + spin_lock_irqsave(&bi->lock, flags);
  398. + bcm2708_bsc_reset(bi);
  399. + bi->msg = 0; /* to inform the interrupt handler that there's nothing else to be done */
  400. + bi->nmsgs = 0;
  401. + spin_unlock_irqrestore(&bi->lock, flags);
  402. + return -ETIMEDOUT;
  403. +}
  404. +
  405. +static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap)
  406. +{
  407. + return I2C_FUNC_I2C | /*I2C_FUNC_10BIT_ADDR |*/ I2C_FUNC_SMBUS_EMUL;
  408. +}
  409. +
  410. +static struct i2c_algorithm bcm2708_i2c_algorithm = {
  411. + .master_xfer = bcm2708_i2c_master_xfer,
  412. + .functionality = bcm2708_i2c_functionality,
  413. +};
  414. +
  415. +static int bcm2708_i2c_probe(struct platform_device *pdev)
  416. +{
  417. + struct resource *regs;
  418. + int irq, err = -ENOMEM;
  419. + struct clk *clk;
  420. + struct bcm2708_i2c *bi;
  421. + struct i2c_adapter *adap;
  422. + unsigned long bus_hz;
  423. + u32 cdiv;
  424. +
  425. + if (pdev->dev.of_node) {
  426. + u32 bus_clk_rate;
  427. + pdev->id = of_alias_get_id(pdev->dev.of_node, "i2c");
  428. + if (pdev->id < 0) {
  429. + dev_err(&pdev->dev, "alias is missing\n");
  430. + return -EINVAL;
  431. + }
  432. + if (!of_property_read_u32(pdev->dev.of_node,
  433. + "clock-frequency", &bus_clk_rate))
  434. + baudrate = bus_clk_rate;
  435. + else
  436. + dev_warn(&pdev->dev,
  437. + "Could not read clock-frequency property\n");
  438. + }
  439. +
  440. + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  441. + if (!regs) {
  442. + dev_err(&pdev->dev, "could not get IO memory\n");
  443. + return -ENXIO;
  444. + }
  445. +
  446. + irq = platform_get_irq(pdev, 0);
  447. + if (irq < 0) {
  448. + dev_err(&pdev->dev, "could not get IRQ\n");
  449. + return irq;
  450. + }
  451. +
  452. + clk = clk_get(&pdev->dev, NULL);
  453. + if (IS_ERR(clk)) {
  454. + dev_err(&pdev->dev, "could not find clk: %ld\n", PTR_ERR(clk));
  455. + return PTR_ERR(clk);
  456. + }
  457. +
  458. + err = clk_prepare_enable(clk);
  459. + if (err) {
  460. + dev_err(&pdev->dev, "could not enable clk: %d\n", err);
  461. + goto out_clk_put;
  462. + }
  463. +
  464. + bi = kzalloc(sizeof(*bi), GFP_KERNEL);
  465. + if (!bi)
  466. + goto out_clk_disable;
  467. +
  468. + platform_set_drvdata(pdev, bi);
  469. +
  470. + adap = &bi->adapter;
  471. + adap->class = I2C_CLASS_HWMON | I2C_CLASS_DDC;
  472. + adap->algo = &bcm2708_i2c_algorithm;
  473. + adap->algo_data = bi;
  474. + adap->dev.parent = &pdev->dev;
  475. + adap->nr = pdev->id;
  476. + strlcpy(adap->name, dev_name(&pdev->dev), sizeof(adap->name));
  477. + adap->dev.of_node = pdev->dev.of_node;
  478. +
  479. + switch (pdev->id) {
  480. + case 0:
  481. + adap->class = I2C_CLASS_HWMON;
  482. + break;
  483. + case 1:
  484. + adap->class = I2C_CLASS_DDC;
  485. + break;
  486. + case 2:
  487. + adap->class = I2C_CLASS_DDC;
  488. + break;
  489. + default:
  490. + dev_err(&pdev->dev, "can only bind to BSC 0, 1 or 2\n");
  491. + err = -ENXIO;
  492. + goto out_free_bi;
  493. + }
  494. +
  495. + spin_lock_init(&bi->lock);
  496. + init_completion(&bi->done);
  497. +
  498. + bi->base = ioremap(regs->start, resource_size(regs));
  499. + if (!bi->base) {
  500. + dev_err(&pdev->dev, "could not remap memory\n");
  501. + goto out_free_bi;
  502. + }
  503. +
  504. + bi->irq = irq;
  505. + bi->clk = clk;
  506. +
  507. + err = request_irq(irq, bcm2708_i2c_interrupt, IRQF_SHARED,
  508. + dev_name(&pdev->dev), bi);
  509. + if (err) {
  510. + dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
  511. + goto out_iounmap;
  512. + }
  513. +
  514. + bcm2708_bsc_reset(bi);
  515. +
  516. + err = i2c_add_numbered_adapter(adap);
  517. + if (err < 0) {
  518. + dev_err(&pdev->dev, "could not add I2C adapter: %d\n", err);
  519. + goto out_free_irq;
  520. + }
  521. +
  522. + bus_hz = clk_get_rate(bi->clk);
  523. + cdiv = bus_hz / baudrate;
  524. + if (cdiv > 0xffff) {
  525. + cdiv = 0xffff;
  526. + baudrate = bus_hz / cdiv;
  527. + }
  528. + bi->cdiv = cdiv;
  529. +
  530. + dev_info(&pdev->dev, "BSC%d Controller at 0x%08lx (irq %d) (baudrate %d)\n",
  531. + pdev->id, (unsigned long)regs->start, irq, baudrate);
  532. +
  533. + return 0;
  534. +
  535. +out_free_irq:
  536. + free_irq(bi->irq, bi);
  537. +out_iounmap:
  538. + iounmap(bi->base);
  539. +out_free_bi:
  540. + kfree(bi);
  541. +out_clk_disable:
  542. + clk_disable_unprepare(clk);
  543. +out_clk_put:
  544. + clk_put(clk);
  545. + return err;
  546. +}
  547. +
  548. +static int bcm2708_i2c_remove(struct platform_device *pdev)
  549. +{
  550. + struct bcm2708_i2c *bi = platform_get_drvdata(pdev);
  551. +
  552. + platform_set_drvdata(pdev, NULL);
  553. +
  554. + i2c_del_adapter(&bi->adapter);
  555. + free_irq(bi->irq, bi);
  556. + iounmap(bi->base);
  557. + clk_disable_unprepare(bi->clk);
  558. + clk_put(bi->clk);
  559. + kfree(bi);
  560. +
  561. + return 0;
  562. +}
  563. +
  564. +static const struct of_device_id bcm2708_i2c_of_match[] = {
  565. + { .compatible = "brcm,bcm2708-i2c" },
  566. + {},
  567. +};
  568. +MODULE_DEVICE_TABLE(of, bcm2708_i2c_of_match);
  569. +
  570. +static struct platform_driver bcm2708_i2c_driver = {
  571. + .driver = {
  572. + .name = DRV_NAME,
  573. + .owner = THIS_MODULE,
  574. + .of_match_table = bcm2708_i2c_of_match,
  575. + },
  576. + .probe = bcm2708_i2c_probe,
  577. + .remove = bcm2708_i2c_remove,
  578. +};
  579. +
  580. +// module_platform_driver(bcm2708_i2c_driver);
  581. +
  582. +
  583. +static int __init bcm2708_i2c_init(void)
  584. +{
  585. + return platform_driver_register(&bcm2708_i2c_driver);
  586. +}
  587. +
  588. +static void __exit bcm2708_i2c_exit(void)
  589. +{
  590. + platform_driver_unregister(&bcm2708_i2c_driver);
  591. +}
  592. +
  593. +module_init(bcm2708_i2c_init);
  594. +module_exit(bcm2708_i2c_exit);
  595. +
  596. +
  597. +
  598. +MODULE_DESCRIPTION("BSC controller driver for Broadcom BCM2708");
  599. +MODULE_AUTHOR("Chris Boot <bootc@bootc.net>");
  600. +MODULE_LICENSE("GPL v2");
  601. +MODULE_ALIAS("platform:" DRV_NAME);