aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorDirk Brandewie <dirk.brandewie@gmail.com>2011-10-29 05:57:23 -0400
committerBen Dooks <ben-linux@fluff.org>2011-10-29 06:03:39 -0400
commit2373f6b9744d5373b886f3ce1a985193cca0a356 (patch)
tree1d3e76da9c3c0bdac1be935742210ebd5e77719d /drivers/i2c
parent4a423a8c8107b983007199c76c8327cd1747f092 (diff)
i2c-designware: split of i2c-designware.c into core and bus specific parts
This patch splits i2c-designware.c into three pieces: i2c-designware-core.c, contains the code that interacts directly with the core. i2c-designware-platdrv.c, contains the code specific to the platform driver using the core. i2c-designware-core.h contains the definitions and declareations shared by i2c-designware-core.c and i2c-designware-platdrv.c. This patch is the first in a set to allow multiple instances of the designware I2C core in the system. Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com> Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'drivers/i2c')
-rw-r--r--drivers/i2c/busses/Kconfig6
-rw-r--r--drivers/i2c/busses/Makefile3
-rw-r--r--drivers/i2c/busses/i2c-designware-core.c (renamed from drivers/i2c/busses/i2c-designware.c)353
-rw-r--r--drivers/i2c/busses/i2c-designware-core.h194
-rw-r--r--drivers/i2c/busses/i2c-designware-platdrv.c199
5 files changed, 412 insertions, 343 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 646068e5100..e6f6e88021e 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -350,15 +350,15 @@ config I2C_DAVINCI
350 devices such as DaVinci NIC. 350 devices such as DaVinci NIC.
351 For details please see http://www.ti.com/davinci 351 For details please see http://www.ti.com/davinci
352 352
353config I2C_DESIGNWARE 353config I2C_DESIGNWARE_PLATFORM
354 tristate "Synopsys DesignWare" 354 tristate "Synopsys DesignWare Platfrom"
355 depends on HAVE_CLK 355 depends on HAVE_CLK
356 help 356 help
357 If you say yes to this option, support will be included for the 357 If you say yes to this option, support will be included for the
358 Synopsys DesignWare I2C adapter. Only master mode is supported. 358 Synopsys DesignWare I2C adapter. Only master mode is supported.
359 359
360 This driver can also be built as a module. If so, the module 360 This driver can also be built as a module. If so, the module
361 will be called i2c-designware. 361 will be called i2c-designware-platform.
362 362
363config I2C_GPIO 363config I2C_GPIO
364 tristate "GPIO-based bitbanging I2C" 364 tristate "GPIO-based bitbanging I2C"
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index e6cf294d372..d7fe55fb077 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -33,7 +33,8 @@ obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o
33obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o 33obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o
34obj-$(CONFIG_I2C_CPM) += i2c-cpm.o 34obj-$(CONFIG_I2C_CPM) += i2c-cpm.o
35obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o 35obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o
36obj-$(CONFIG_I2C_DESIGNWARE) += i2c-designware.o 36obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o
37i2c-designware-platform-objs := i2c-designware-platdrv.o i2c-designware-core.o
37obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o 38obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
38obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o 39obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o
39obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o 40obj-$(CONFIG_I2C_IBM_IIC) += i2c-ibm_iic.o
diff --git a/drivers/i2c/busses/i2c-designware.c b/drivers/i2c/busses/i2c-designware-core.c
index a7abbcd3d80..38d5a6b22a8 100644
--- a/drivers/i2c/busses/i2c-designware.c
+++ b/drivers/i2c/busses/i2c-designware-core.c
@@ -25,127 +25,14 @@
25 * ---------------------------------------------------------------------------- 25 * ----------------------------------------------------------------------------
26 * 26 *
27 */ 27 */
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/delay.h>
31#include <linux/i2c.h>
32#include <linux/clk.h> 28#include <linux/clk.h>
33#include <linux/errno.h> 29#include <linux/errno.h>
34#include <linux/sched.h>
35#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/i2c.h>
36#include <linux/interrupt.h> 32#include <linux/interrupt.h>
37#include <linux/platform_device.h>
38#include <linux/io.h> 33#include <linux/io.h>
39#include <linux/slab.h> 34#include <linux/delay.h>
40#include <linux/swab.h> 35#include "i2c-designware-core.h"
41
42/*
43 * Registers offset
44 */
45#define DW_IC_CON 0x0
46#define DW_IC_TAR 0x4
47#define DW_IC_DATA_CMD 0x10
48#define DW_IC_SS_SCL_HCNT 0x14
49#define DW_IC_SS_SCL_LCNT 0x18
50#define DW_IC_FS_SCL_HCNT 0x1c
51#define DW_IC_FS_SCL_LCNT 0x20
52#define DW_IC_INTR_STAT 0x2c
53#define DW_IC_INTR_MASK 0x30
54#define DW_IC_RAW_INTR_STAT 0x34
55#define DW_IC_RX_TL 0x38
56#define DW_IC_TX_TL 0x3c
57#define DW_IC_CLR_INTR 0x40
58#define DW_IC_CLR_RX_UNDER 0x44
59#define DW_IC_CLR_RX_OVER 0x48
60#define DW_IC_CLR_TX_OVER 0x4c
61#define DW_IC_CLR_RD_REQ 0x50
62#define DW_IC_CLR_TX_ABRT 0x54
63#define DW_IC_CLR_RX_DONE 0x58
64#define DW_IC_CLR_ACTIVITY 0x5c
65#define DW_IC_CLR_STOP_DET 0x60
66#define DW_IC_CLR_START_DET 0x64
67#define DW_IC_CLR_GEN_CALL 0x68
68#define DW_IC_ENABLE 0x6c
69#define DW_IC_STATUS 0x70
70#define DW_IC_TXFLR 0x74
71#define DW_IC_RXFLR 0x78
72#define DW_IC_COMP_PARAM_1 0xf4
73#define DW_IC_COMP_TYPE 0xfc
74#define DW_IC_TX_ABRT_SOURCE 0x80
75
76#define DW_IC_CON_MASTER 0x1
77#define DW_IC_CON_SPEED_STD 0x2
78#define DW_IC_CON_SPEED_FAST 0x4
79#define DW_IC_CON_10BITADDR_MASTER 0x10
80#define DW_IC_CON_RESTART_EN 0x20
81#define DW_IC_CON_SLAVE_DISABLE 0x40
82
83#define DW_IC_INTR_RX_UNDER 0x001
84#define DW_IC_INTR_RX_OVER 0x002
85#define DW_IC_INTR_RX_FULL 0x004
86#define DW_IC_INTR_TX_OVER 0x008
87#define DW_IC_INTR_TX_EMPTY 0x010
88#define DW_IC_INTR_RD_REQ 0x020
89#define DW_IC_INTR_TX_ABRT 0x040
90#define DW_IC_INTR_RX_DONE 0x080
91#define DW_IC_INTR_ACTIVITY 0x100
92#define DW_IC_INTR_STOP_DET 0x200
93#define DW_IC_INTR_START_DET 0x400
94#define DW_IC_INTR_GEN_CALL 0x800
95
96#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
97 DW_IC_INTR_TX_EMPTY | \
98 DW_IC_INTR_TX_ABRT | \
99 DW_IC_INTR_STOP_DET)
100
101#define DW_IC_STATUS_ACTIVITY 0x1
102
103#define DW_IC_ERR_TX_ABRT 0x1
104
105/*
106 * status codes
107 */
108#define STATUS_IDLE 0x0
109#define STATUS_WRITE_IN_PROGRESS 0x1
110#define STATUS_READ_IN_PROGRESS 0x2
111
112#define TIMEOUT 20 /* ms */
113
114/*
115 * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register
116 *
117 * only expected abort codes are listed here
118 * refer to the datasheet for the full list
119 */
120#define ABRT_7B_ADDR_NOACK 0
121#define ABRT_10ADDR1_NOACK 1
122#define ABRT_10ADDR2_NOACK 2
123#define ABRT_TXDATA_NOACK 3
124#define ABRT_GCALL_NOACK 4
125#define ABRT_GCALL_READ 5
126#define ABRT_SBYTE_ACKDET 7
127#define ABRT_SBYTE_NORSTRT 9
128#define ABRT_10B_RD_NORSTRT 10
129#define ABRT_MASTER_DIS 11
130#define ARB_LOST 12
131
132#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK)
133#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK)
134#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK)
135#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK)
136#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK)
137#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ)
138#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET)
139#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT)
140#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT)
141#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS)
142#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST)
143
144#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \
145 DW_IC_TX_ABRT_10ADDR1_NOACK | \
146 DW_IC_TX_ABRT_10ADDR2_NOACK | \
147 DW_IC_TX_ABRT_TXDATA_NOACK | \
148 DW_IC_TX_ABRT_GCALL_NOACK)
149 36
150static char *abort_sources[] = { 37static char *abort_sources[] = {
151 [ABRT_7B_ADDR_NOACK] = 38 [ABRT_7B_ADDR_NOACK] =
@@ -172,59 +59,7 @@ static char *abort_sources[] = {
172 "lost arbitration", 59 "lost arbitration",
173}; 60};
174 61
175/** 62u32 dw_readl(struct dw_i2c_dev *dev, int offset)
176 * struct dw_i2c_dev - private i2c-designware data
177 * @dev: driver model device node
178 * @base: IO registers pointer
179 * @cmd_complete: tx completion indicator
180 * @lock: protect this struct and IO registers
181 * @clk: input reference clock
182 * @cmd_err: run time hadware error code
183 * @msgs: points to an array of messages currently being transferred
184 * @msgs_num: the number of elements in msgs
185 * @msg_write_idx: the element index of the current tx message in the msgs
186 * array
187 * @tx_buf_len: the length of the current tx buffer
188 * @tx_buf: the current tx buffer
189 * @msg_read_idx: the element index of the current rx message in the msgs
190 * array
191 * @rx_buf_len: the length of the current rx buffer
192 * @rx_buf: the current rx buffer
193 * @msg_err: error status of the current transfer
194 * @status: i2c master status, one of STATUS_*
195 * @abort_source: copy of the TX_ABRT_SOURCE register
196 * @irq: interrupt number for the i2c master
197 * @swab: true if the instantiated IP is of different endianess
198 * @adapter: i2c subsystem adapter node
199 * @tx_fifo_depth: depth of the hardware tx fifo
200 * @rx_fifo_depth: depth of the hardware rx fifo
201 */
202struct dw_i2c_dev {
203 struct device *dev;
204 void __iomem *base;
205 struct completion cmd_complete;
206 struct mutex lock;
207 struct clk *clk;
208 int cmd_err;
209 struct i2c_msg *msgs;
210 int msgs_num;
211 int msg_write_idx;
212 u32 tx_buf_len;
213 u8 *tx_buf;
214 int msg_read_idx;
215 u32 rx_buf_len;
216 u8 *rx_buf;
217 int msg_err;
218 unsigned int status;
219 u32 abort_source;
220 int irq;
221 int swab;
222 struct i2c_adapter adapter;
223 unsigned int tx_fifo_depth;
224 unsigned int rx_fifo_depth;
225};
226
227static u32 dw_readl(struct dw_i2c_dev *dev, int offset)
228{ 63{
229 u32 value = readl(dev->base + offset); 64 u32 value = readl(dev->base + offset);
230 65
@@ -234,7 +69,7 @@ static u32 dw_readl(struct dw_i2c_dev *dev, int offset)
234 return value; 69 return value;
235} 70}
236 71
237static void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset) 72void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset)
238{ 73{
239 if (dev->swab) 74 if (dev->swab)
240 b = swab32(b); 75 b = swab32(b);
@@ -305,7 +140,7 @@ static u32 i2c_dw_scl_lcnt(u32 ic_clk, u32 tLOW, u32 tf, int offset)
305 * This function is called during I2C init function, and in case of timeout at 140 * This function is called during I2C init function, and in case of timeout at
306 * run time. 141 * run time.
307 */ 142 */
308static int i2c_dw_init(struct dw_i2c_dev *dev) 143int i2c_dw_init(struct dw_i2c_dev *dev)
309{ 144{
310 u32 input_clock_khz = clk_get_rate(dev->clk) / 1000; 145 u32 input_clock_khz = clk_get_rate(dev->clk) / 1000;
311 u32 ic_con, hcnt, lcnt; 146 u32 ic_con, hcnt, lcnt;
@@ -419,7 +254,7 @@ static void i2c_dw_xfer_init(struct dw_i2c_dev *dev)
419 * messages into the tx buffer. Even if the size of i2c_msg data is 254 * messages into the tx buffer. Even if the size of i2c_msg data is
420 * longer than the size of the tx buffer, it handles everything. 255 * longer than the size of the tx buffer, it handles everything.
421 */ 256 */
422static void 257void
423i2c_dw_xfer_msg(struct dw_i2c_dev *dev) 258i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
424{ 259{
425 struct i2c_msg *msgs = dev->msgs; 260 struct i2c_msg *msgs = dev->msgs;
@@ -490,7 +325,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev)
490 if (dev->msg_err) 325 if (dev->msg_err)
491 intr_mask = 0; 326 intr_mask = 0;
492 327
493 dw_writel(dev, intr_mask, DW_IC_INTR_MASK); 328 dw_writel(dev, intr_mask, DW_IC_INTR_MASK);
494} 329}
495 330
496static void 331static void
@@ -555,7 +390,7 @@ static int i2c_dw_handle_tx_abort(struct dw_i2c_dev *dev)
555/* 390/*
556 * Prepare controller for a transaction and call i2c_dw_xfer_msg 391 * Prepare controller for a transaction and call i2c_dw_xfer_msg
557 */ 392 */
558static int 393int
559i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) 394i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
560{ 395{
561 struct dw_i2c_dev *dev = i2c_get_adapdata(adap); 396 struct dw_i2c_dev *dev = i2c_get_adapdata(adap);
@@ -618,7 +453,7 @@ done:
618 return ret; 453 return ret;
619} 454}
620 455
621static u32 i2c_dw_func(struct i2c_adapter *adap) 456u32 i2c_dw_func(struct i2c_adapter *adap)
622{ 457{
623 return I2C_FUNC_I2C | 458 return I2C_FUNC_I2C |
624 I2C_FUNC_10BIT_ADDR | 459 I2C_FUNC_10BIT_ADDR |
@@ -638,9 +473,9 @@ static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
638 * in the IC_RAW_INTR_STAT register. 473 * in the IC_RAW_INTR_STAT register.
639 * 474 *
640 * That is, 475 * That is,
641 * stat = readl(IC_INTR_STAT); 476 * stat = dw_readl(IC_INTR_STAT);
642 * equals to, 477 * equals to,
643 * stat = readl(IC_RAW_INTR_STAT) & readl(IC_INTR_MASK); 478 * stat = dw_readl(IC_RAW_INTR_STAT) & dw_readl(IC_INTR_MASK);
644 * 479 *
645 * The raw version might be useful for debugging purposes. 480 * The raw version might be useful for debugging purposes.
646 */ 481 */
@@ -649,7 +484,7 @@ static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
649 /* 484 /*
650 * Do not use the IC_CLR_INTR register to clear interrupts, or 485 * Do not use the IC_CLR_INTR register to clear interrupts, or
651 * you'll miss some interrupts, triggered during the period from 486 * you'll miss some interrupts, triggered during the period from
652 * readl(IC_INTR_STAT) to readl(IC_CLR_INTR). 487 * dw_readl(IC_INTR_STAT) to dw_readl(IC_CLR_INTR).
653 * 488 *
654 * Instead, use the separately-prepared IC_CLR_* registers. 489 * Instead, use the separately-prepared IC_CLR_* registers.
655 */ 490 */
@@ -687,7 +522,7 @@ static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev)
687 * Interrupt service routine. This gets called whenever an I2C interrupt 522 * Interrupt service routine. This gets called whenever an I2C interrupt
688 * occurs. 523 * occurs.
689 */ 524 */
690static irqreturn_t i2c_dw_isr(int this_irq, void *dev_id) 525irqreturn_t i2c_dw_isr(int this_irq, void *dev_id)
691{ 526{
692 struct dw_i2c_dev *dev = dev_id; 527 struct dw_i2c_dev *dev = dev_id;
693 u32 stat; 528 u32 stat;
@@ -725,163 +560,3 @@ tx_aborted:
725 560
726 return IRQ_HANDLED; 561 return IRQ_HANDLED;
727} 562}
728
729static struct i2c_algorithm i2c_dw_algo = {
730 .master_xfer = i2c_dw_xfer,
731 .functionality = i2c_dw_func,
732};
733
734static int __devinit dw_i2c_probe(struct platform_device *pdev)
735{
736 struct dw_i2c_dev *dev;
737 struct i2c_adapter *adap;
738 struct resource *mem, *ioarea;
739 int irq, r;
740 u32 reg;
741
742 /* NOTE: driver uses the static register mapping */
743 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
744 if (!mem) {
745 dev_err(&pdev->dev, "no mem resource?\n");
746 return -EINVAL;
747 }
748
749 irq = platform_get_irq(pdev, 0);
750 if (irq < 0) {
751 dev_err(&pdev->dev, "no irq resource?\n");
752 return irq; /* -ENXIO */
753 }
754
755 ioarea = request_mem_region(mem->start, resource_size(mem),
756 pdev->name);
757 if (!ioarea) {
758 dev_err(&pdev->dev, "I2C region already claimed\n");
759 return -EBUSY;
760 }
761
762 dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL);
763 if (!dev) {
764 r = -ENOMEM;
765 goto err_release_region;
766 }
767
768 init_completion(&dev->cmd_complete);
769 mutex_init(&dev->lock);
770 dev->dev = get_device(&pdev->dev);
771 dev->irq = irq;
772 platform_set_drvdata(pdev, dev);
773
774 dev->clk = clk_get(&pdev->dev, NULL);
775 if (IS_ERR(dev->clk)) {
776 r = -ENODEV;
777 goto err_free_mem;
778 }
779 clk_enable(dev->clk);
780
781 dev->base = ioremap(mem->start, resource_size(mem));
782 if (dev->base == NULL) {
783 dev_err(&pdev->dev, "failure mapping io resources\n");
784 r = -EBUSY;
785 goto err_unuse_clocks;
786 }
787
788 r = i2c_dw_init(dev);
789 if (r)
790 goto err_unuse_clocks;
791
792 reg = dw_readl(dev, DW_IC_COMP_PARAM_1);
793 dev->tx_fifo_depth = ((reg >> 16) & 0xff) + 1;
794 dev->rx_fifo_depth = ((reg >> 8) & 0xff) + 1;
795
796
797 dw_writel(dev, 0, DW_IC_INTR_MASK); /* disable IRQ */
798 r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev);
799 if (r) {
800 dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
801 goto err_iounmap;
802 }
803
804 adap = &dev->adapter;
805 i2c_set_adapdata(adap, dev);
806 adap->owner = THIS_MODULE;
807 adap->class = I2C_CLASS_HWMON;
808 strlcpy(adap->name, "Synopsys DesignWare I2C adapter",
809 sizeof(adap->name));
810 adap->algo = &i2c_dw_algo;
811 adap->dev.parent = &pdev->dev;
812
813 adap->nr = pdev->id;
814 r = i2c_add_numbered_adapter(adap);
815 if (r) {
816 dev_err(&pdev->dev, "failure adding adapter\n");
817 goto err_free_irq;
818 }
819
820 return 0;
821
822err_free_irq:
823 free_irq(dev->irq, dev);
824err_iounmap:
825 iounmap(dev->base);
826err_unuse_clocks:
827 clk_disable(dev->clk);
828 clk_put(dev->clk);
829 dev->clk = NULL;
830err_free_mem:
831 platform_set_drvdata(pdev, NULL);
832 put_device(&pdev->dev);
833 kfree(dev);
834err_release_region:
835 release_mem_region(mem->start, resource_size(mem));
836
837 return r;
838}
839
840static int __devexit dw_i2c_remove(struct platform_device *pdev)
841{
842 struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
843 struct resource *mem;
844
845 platform_set_drvdata(pdev, NULL);
846 i2c_del_adapter(&dev->adapter);
847 put_device(&pdev->dev);
848
849 clk_disable(dev->clk);
850 clk_put(dev->clk);
851 dev->clk = NULL;
852
853 dw_writel(dev, 0, DW_IC_ENABLE);
854 free_irq(dev->irq, dev);
855 kfree(dev);
856
857 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
858 release_mem_region(mem->start, resource_size(mem));
859 return 0;
860}
861
862/* work with hotplug and coldplug */
863MODULE_ALIAS("platform:i2c_designware");
864
865static struct platform_driver dw_i2c_driver = {
866 .remove = __devexit_p(dw_i2c_remove),
867 .driver = {
868 .name = "i2c_designware",
869 .owner = THIS_MODULE,
870 },
871};
872
873static int __init dw_i2c_init_driver(void)
874{
875 return platform_driver_probe(&dw_i2c_driver, dw_i2c_probe);
876}
877module_init(dw_i2c_init_driver);
878
879static void __exit dw_i2c_exit_driver(void)
880{
881 platform_driver_unregister(&dw_i2c_driver);
882}
883module_exit(dw_i2c_exit_driver);
884
885MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
886MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter");
887MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h
new file mode 100644
index 00000000000..4e37031c6b6
--- /dev/null
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -0,0 +1,194 @@
1/*
2 * Synopsys DesignWare I2C adapter driver (master only).
3 *
4 * Based on the TI DAVINCI I2C adapter driver.
5 *
6 * Copyright (C) 2006 Texas Instruments.
7 * Copyright (C) 2007 MontaVista Software Inc.
8 * Copyright (C) 2009 Provigent Ltd.
9 *
10 * ----------------------------------------------------------------------------
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * ----------------------------------------------------------------------------
26 *
27 */
28
29/*
30 * Registers offset
31 */
32#define DW_IC_CON 0x0
33#define DW_IC_TAR 0x4
34#define DW_IC_DATA_CMD 0x10
35#define DW_IC_SS_SCL_HCNT 0x14
36#define DW_IC_SS_SCL_LCNT 0x18
37#define DW_IC_FS_SCL_HCNT 0x1c
38#define DW_IC_FS_SCL_LCNT 0x20
39#define DW_IC_INTR_STAT 0x2c
40#define DW_IC_INTR_MASK 0x30
41#define DW_IC_RAW_INTR_STAT 0x34
42#define DW_IC_RX_TL 0x38
43#define DW_IC_TX_TL 0x3c
44#define DW_IC_CLR_INTR 0x40
45#define DW_IC_CLR_RX_UNDER 0x44
46#define DW_IC_CLR_RX_OVER 0x48
47#define DW_IC_CLR_TX_OVER 0x4c
48#define DW_IC_CLR_RD_REQ 0x50
49#define DW_IC_CLR_TX_ABRT 0x54
50#define DW_IC_CLR_RX_DONE 0x58
51#define DW_IC_CLR_ACTIVITY 0x5c
52#define DW_IC_CLR_STOP_DET 0x60
53#define DW_IC_CLR_START_DET 0x64
54#define DW_IC_CLR_GEN_CALL 0x68
55#define DW_IC_ENABLE 0x6c
56#define DW_IC_STATUS 0x70
57#define DW_IC_TXFLR 0x74
58#define DW_IC_RXFLR 0x78
59#define DW_IC_TX_ABRT_SOURCE 0x80
60#define DW_IC_COMP_PARAM_1 0xf4
61#define DW_IC_COMP_TYPE 0xfc
62#define DW_IC_COMP_TYPE_VALUE 0x44570140
63
64#define DW_IC_CON_MASTER 0x1
65#define DW_IC_CON_SPEED_STD 0x2
66#define DW_IC_CON_SPEED_FAST 0x4
67#define DW_IC_CON_10BITADDR_MASTER 0x10
68#define DW_IC_CON_RESTART_EN 0x20
69#define DW_IC_CON_SLAVE_DISABLE 0x40
70
71#define DW_IC_INTR_RX_UNDER 0x001
72#define DW_IC_INTR_RX_OVER 0x002
73#define DW_IC_INTR_RX_FULL 0x004
74#define DW_IC_INTR_TX_OVER 0x008
75#define DW_IC_INTR_TX_EMPTY 0x010
76#define DW_IC_INTR_RD_REQ 0x020
77#define DW_IC_INTR_TX_ABRT 0x040
78#define DW_IC_INTR_RX_DONE 0x080
79#define DW_IC_INTR_ACTIVITY 0x100
80#define DW_IC_INTR_STOP_DET 0x200
81#define DW_IC_INTR_START_DET 0x400
82#define DW_IC_INTR_GEN_CALL 0x800
83
84#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
85 DW_IC_INTR_TX_EMPTY | \
86 DW_IC_INTR_TX_ABRT | \
87 DW_IC_INTR_STOP_DET)
88
89#define DW_IC_STATUS_ACTIVITY 0x1
90
91#define DW_IC_ERR_TX_ABRT 0x1
92
93/*
94 * status codes
95 */
96#define STATUS_IDLE 0x0
97#define STATUS_WRITE_IN_PROGRESS 0x1
98#define STATUS_READ_IN_PROGRESS 0x2
99
100#define TIMEOUT 20 /* ms */
101
102/*
103 * hardware abort codes from the DW_IC_TX_ABRT_SOURCE register
104 *
105 * only expected abort codes are listed here
106 * refer to the datasheet for the full list
107 */
108#define ABRT_7B_ADDR_NOACK 0
109#define ABRT_10ADDR1_NOACK 1
110#define ABRT_10ADDR2_NOACK 2
111#define ABRT_TXDATA_NOACK 3
112#define ABRT_GCALL_NOACK 4
113#define ABRT_GCALL_READ 5
114#define ABRT_SBYTE_ACKDET 7
115#define ABRT_SBYTE_NORSTRT 9
116#define ABRT_10B_RD_NORSTRT 10
117#define ABRT_MASTER_DIS 11
118#define ARB_LOST 12
119
120#define DW_IC_TX_ABRT_7B_ADDR_NOACK (1UL << ABRT_7B_ADDR_NOACK)
121#define DW_IC_TX_ABRT_10ADDR1_NOACK (1UL << ABRT_10ADDR1_NOACK)
122#define DW_IC_TX_ABRT_10ADDR2_NOACK (1UL << ABRT_10ADDR2_NOACK)
123#define DW_IC_TX_ABRT_TXDATA_NOACK (1UL << ABRT_TXDATA_NOACK)
124#define DW_IC_TX_ABRT_GCALL_NOACK (1UL << ABRT_GCALL_NOACK)
125#define DW_IC_TX_ABRT_GCALL_READ (1UL << ABRT_GCALL_READ)
126#define DW_IC_TX_ABRT_SBYTE_ACKDET (1UL << ABRT_SBYTE_ACKDET)
127#define DW_IC_TX_ABRT_SBYTE_NORSTRT (1UL << ABRT_SBYTE_NORSTRT)
128#define DW_IC_TX_ABRT_10B_RD_NORSTRT (1UL << ABRT_10B_RD_NORSTRT)
129#define DW_IC_TX_ABRT_MASTER_DIS (1UL << ABRT_MASTER_DIS)
130#define DW_IC_TX_ARB_LOST (1UL << ARB_LOST)
131
132#define DW_IC_TX_ABRT_NOACK (DW_IC_TX_ABRT_7B_ADDR_NOACK | \
133 DW_IC_TX_ABRT_10ADDR1_NOACK | \
134 DW_IC_TX_ABRT_10ADDR2_NOACK | \
135 DW_IC_TX_ABRT_TXDATA_NOACK | \
136 DW_IC_TX_ABRT_GCALL_NOACK)
137/**
138 * struct dw_i2c_dev - private i2c-designware data
139 * @dev: driver model device node
140 * @base: IO registers pointer
141 * @cmd_complete: tx completion indicator
142 * @lock: protect this struct and IO registers
143 * @clk: input reference clock
144 * @cmd_err: run time hadware error code
145 * @msgs: points to an array of messages currently being transfered
146 * @msgs_num: the number of elements in msgs
147 * @msg_write_idx: the element index of the current tx message in the msgs
148 * array
149 * @tx_buf_len: the length of the current tx buffer
150 * @tx_buf: the current tx buffer
151 * @msg_read_idx: the element index of the current rx message in the msgs
152 * array
153 * @rx_buf_len: the length of the current rx buffer
154 * @rx_buf: the current rx buffer
155 * @msg_err: error status of the current transfer
156 * @status: i2c master status, one of STATUS_*
157 * @abort_source: copy of the TX_ABRT_SOURCE register
158 * @irq: interrupt number for the i2c master
159 * @adapter: i2c subsystem adapter node
160 * @tx_fifo_depth: depth of the hardware tx fifo
161 * @rx_fifo_depth: depth of the hardware rx fifo
162 */
163struct dw_i2c_dev {
164 struct device *dev;
165 void __iomem *base;
166 struct completion cmd_complete;
167 struct mutex lock;
168 struct clk *clk;
169 int cmd_err;
170 struct i2c_msg *msgs;
171 int msgs_num;
172 int msg_write_idx;
173 u32 tx_buf_len;
174 u8 *tx_buf;
175 int msg_read_idx;
176 u32 rx_buf_len;
177 u8 *rx_buf;
178 int msg_err;
179 unsigned int status;
180 u32 abort_source;
181 int irq;
182 int swab;
183 struct i2c_adapter adapter;
184 unsigned int tx_fifo_depth;
185 unsigned int rx_fifo_depth;
186};
187
188extern u32 dw_readl(struct dw_i2c_dev *dev, int offset);
189extern void dw_writel(struct dw_i2c_dev *dev, u32 b, int offset);
190extern int i2c_dw_init(struct dw_i2c_dev *dev);
191extern int i2c_dw_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
192 int num);
193extern u32 i2c_dw_func(struct i2c_adapter *adap);
194extern irqreturn_t i2c_dw_isr(int this_irq, void *dev_id);
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
new file mode 100644
index 00000000000..9d10ae8c695
--- /dev/null
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -0,0 +1,199 @@
1/*
2 * Synopsys DesignWare I2C adapter driver (master only).
3 *
4 * Based on the TI DAVINCI I2C adapter driver.
5 *
6 * Copyright (C) 2006 Texas Instruments.
7 * Copyright (C) 2007 MontaVista Software Inc.
8 * Copyright (C) 2009 Provigent Ltd.
9 *
10 * ----------------------------------------------------------------------------
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 * ----------------------------------------------------------------------------
26 *
27 */
28#include <linux/kernel.h>
29#include <linux/module.h>
30#include <linux/delay.h>
31#include <linux/i2c.h>
32#include <linux/clk.h>
33#include <linux/errno.h>
34#include <linux/sched.h>
35#include <linux/err.h>
36#include <linux/interrupt.h>
37#include <linux/platform_device.h>
38#include <linux/io.h>
39#include <linux/slab.h>
40#include "i2c-designware-core.h"
41
42static struct i2c_algorithm i2c_dw_algo = {
43 .master_xfer = i2c_dw_xfer,
44 .functionality = i2c_dw_func,
45};
46
47static int __devinit dw_i2c_probe(struct platform_device *pdev)
48{
49 struct dw_i2c_dev *dev;
50 struct i2c_adapter *adap;
51 struct resource *mem, *ioarea;
52 int irq, r;
53
54 /* NOTE: driver uses the static register mapping */
55 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
56 if (!mem) {
57 dev_err(&pdev->dev, "no mem resource?\n");
58 return -EINVAL;
59 }
60
61 irq = platform_get_irq(pdev, 0);
62 if (irq < 0) {
63 dev_err(&pdev->dev, "no irq resource?\n");
64 return irq; /* -ENXIO */
65 }
66
67 ioarea = request_mem_region(mem->start, resource_size(mem),
68 pdev->name);
69 if (!ioarea) {
70 dev_err(&pdev->dev, "I2C region already claimed\n");
71 return -EBUSY;
72 }
73
74 dev = kzalloc(sizeof(struct dw_i2c_dev), GFP_KERNEL);
75 if (!dev) {
76 r = -ENOMEM;
77 goto err_release_region;
78 }
79
80 init_completion(&dev->cmd_complete);
81 mutex_init(&dev->lock);
82 dev->dev = get_device(&pdev->dev);
83 dev->irq = irq;
84 platform_set_drvdata(pdev, dev);
85
86 dev->clk = clk_get(&pdev->dev, NULL);
87 if (IS_ERR(dev->clk)) {
88 r = -ENODEV;
89 goto err_free_mem;
90 }
91 clk_enable(dev->clk);
92
93 dev->base = ioremap(mem->start, resource_size(mem));
94 if (dev->base == NULL) {
95 dev_err(&pdev->dev, "failure mapping io resources\n");
96 r = -EBUSY;
97 goto err_unuse_clocks;
98 }
99 {
100 u32 param1 = dw_readl(dev, DW_IC_COMP_PARAM_1);
101
102 dev->tx_fifo_depth = ((param1 >> 16) & 0xff) + 1;
103 dev->rx_fifo_depth = ((param1 >> 8) & 0xff) + 1;
104 }
105 r = i2c_dw_init(dev);
106 if (r)
107 goto err_iounmap;
108
109 dw_writel(dev, 0, DW_IC_INTR_MASK); /* disable IRQ */
110 r = request_irq(dev->irq, i2c_dw_isr, IRQF_DISABLED, pdev->name, dev);
111 if (r) {
112 dev_err(&pdev->dev, "failure requesting irq %i\n", dev->irq);
113 goto err_iounmap;
114 }
115
116 adap = &dev->adapter;
117 i2c_set_adapdata(adap, dev);
118 adap->owner = THIS_MODULE;
119 adap->class = I2C_CLASS_HWMON;
120 strlcpy(adap->name, "Synopsys DesignWare I2C adapter",
121 sizeof(adap->name));
122 adap->algo = &i2c_dw_algo;
123 adap->dev.parent = &pdev->dev;
124
125 adap->nr = pdev->id;
126 r = i2c_add_numbered_adapter(adap);
127 if (r) {
128 dev_err(&pdev->dev, "failure adding adapter\n");
129 goto err_free_irq;
130 }
131
132 return 0;
133
134err_free_irq:
135 free_irq(dev->irq, dev);
136err_iounmap:
137 iounmap(dev->base);
138err_unuse_clocks:
139 clk_disable(dev->clk);
140 clk_put(dev->clk);
141 dev->clk = NULL;
142err_free_mem:
143 platform_set_drvdata(pdev, NULL);
144 put_device(&pdev->dev);
145 kfree(dev);
146err_release_region:
147 release_mem_region(mem->start, resource_size(mem));
148
149 return r;
150}
151
152static int __devexit dw_i2c_remove(struct platform_device *pdev)
153{
154 struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
155 struct resource *mem;
156
157 platform_set_drvdata(pdev, NULL);
158 i2c_del_adapter(&dev->adapter);
159 put_device(&pdev->dev);
160
161 clk_disable(dev->clk);
162 clk_put(dev->clk);
163 dev->clk = NULL;
164
165 dw_writel(dev, 0, DW_IC_ENABLE);
166 free_irq(dev->irq, dev);
167 kfree(dev);
168
169 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
170 release_mem_region(mem->start, resource_size(mem));
171 return 0;
172}
173
174/* work with hotplug and coldplug */
175MODULE_ALIAS("platform:i2c_designware");
176
177static struct platform_driver dw_i2c_driver = {
178 .remove = __devexit_p(dw_i2c_remove),
179 .driver = {
180 .name = "i2c_designware",
181 .owner = THIS_MODULE,
182 },
183};
184
185static int __init dw_i2c_init_driver(void)
186{
187 return platform_driver_probe(&dw_i2c_driver, dw_i2c_probe);
188}
189module_init(dw_i2c_init_driver);
190
191static void __exit dw_i2c_exit_driver(void)
192{
193 platform_driver_unregister(&dw_i2c_driver);
194}
195module_exit(dw_i2c_exit_driver);
196
197MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
198MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter");
199MODULE_LICENSE("GPL");