aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2011-03-02 05:26:53 -0500
committerBen Dooks <ben-linux@fluff.org>2011-03-21 05:18:54 -0400
commit7e94dd154e934aa2137c427c3b1c8e9a6e465fcd (patch)
tree77a8705ed9f3b5b0e94381f4ccb5458fd10721f8 /drivers/i2c
parentb459396ee9398bdf61e3118ca730394f58e90c9c (diff)
i2c-pxa2xx: Add PCI support for PXA I2C controller
The Sodaville I2C controller is almost the same as found on PXA2xx. The difference: - the register are at a different offset - no slave support The PCI probe code adds three platform devices which are probed then by the platform code. The X86 part also adds dummy clock defines because we don't have HW clock support. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> 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/Kconfig7
-rw-r--r--drivers/i2c/busses/Makefile1
-rw-r--r--drivers/i2c/busses/i2c-pxa-pci.c176
-rw-r--r--drivers/i2c/busses/i2c-pxa.c27
4 files changed, 206 insertions, 5 deletions
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 230601e8853f..b6e53c277276 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -546,15 +546,18 @@ config I2C_PUV3
546 546
547config I2C_PXA 547config I2C_PXA
548 tristate "Intel PXA2XX I2C adapter" 548 tristate "Intel PXA2XX I2C adapter"
549 depends on ARCH_PXA || ARCH_MMP 549 depends on ARCH_PXA || ARCH_MMP || (X86_32 && PCI && OF)
550 help 550 help
551 If you have devices in the PXA I2C bus, say yes to this option. 551 If you have devices in the PXA I2C bus, say yes to this option.
552 This driver can also be built as a module. If so, the module 552 This driver can also be built as a module. If so, the module
553 will be called i2c-pxa. 553 will be called i2c-pxa.
554 554
555config I2C_PXA_PCI
556 def_bool I2C_PXA && X86_32 && PCI && OF
557
555config I2C_PXA_SLAVE 558config I2C_PXA_SLAVE
556 bool "Intel PXA2XX I2C Slave comms support" 559 bool "Intel PXA2XX I2C Slave comms support"
557 depends on I2C_PXA 560 depends on I2C_PXA && !X86_32
558 help 561 help
559 Support I2C slave mode communications on the PXA I2C bus. This 562 Support I2C slave mode communications on the PXA I2C bus. This
560 is necessary for systems where the PXA may be a target on the 563 is necessary for systems where the PXA may be a target on the
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 3878c959d4fa..1dd554e51440 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_I2C_PMCMSP) += i2c-pmcmsp.o
54obj-$(CONFIG_I2C_PNX) += i2c-pnx.o 54obj-$(CONFIG_I2C_PNX) += i2c-pnx.o
55obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o 55obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
56obj-$(CONFIG_I2C_PXA) += i2c-pxa.o 56obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
57obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
57obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o 58obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
58obj-$(CONFIG_I2C_S6000) += i2c-s6000.o 59obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
59obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o 60obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c
new file mode 100644
index 000000000000..6659d269b841
--- /dev/null
+++ b/drivers/i2c/busses/i2c-pxa-pci.c
@@ -0,0 +1,176 @@
1/*
2 * The CE4100's I2C device is more or less the same one as found on PXA.
3 * It does not support slave mode, the register slightly moved. This PCI
4 * device provides three bars, every contains a single I2C controller.
5 */
6#include <linux/pci.h>
7#include <linux/platform_device.h>
8#include <linux/i2c/pxa-i2c.h>
9#include <linux/of.h>
10#include <linux/of_device.h>
11#include <linux/of_address.h>
12
13#define CE4100_PCI_I2C_DEVS 3
14
15struct ce4100_devices {
16 struct platform_device *pdev[CE4100_PCI_I2C_DEVS];
17};
18
19static struct platform_device *add_i2c_device(struct pci_dev *dev, int bar)
20{
21 struct platform_device *pdev;
22 struct i2c_pxa_platform_data pdata;
23 struct resource res[2];
24 struct device_node *child;
25 static int devnum;
26 int ret;
27
28 memset(&pdata, 0, sizeof(struct i2c_pxa_platform_data));
29 memset(&res, 0, sizeof(res));
30
31 res[0].flags = IORESOURCE_MEM;
32 res[0].start = pci_resource_start(dev, bar);
33 res[0].end = pci_resource_end(dev, bar);
34
35 res[1].flags = IORESOURCE_IRQ;
36 res[1].start = dev->irq;
37 res[1].end = dev->irq;
38
39 for_each_child_of_node(dev->dev.of_node, child) {
40 const void *prop;
41 struct resource r;
42 int ret;
43
44 ret = of_address_to_resource(child, 0, &r);
45 if (ret < 0)
46 continue;
47 if (r.start != res[0].start)
48 continue;
49 if (r.end != res[0].end)
50 continue;
51 if (r.flags != res[0].flags)
52 continue;
53
54 prop = of_get_property(child, "fast-mode", NULL);
55 if (prop)
56 pdata.fast_mode = 1;
57
58 break;
59 }
60
61 if (!child) {
62 dev_err(&dev->dev, "failed to match a DT node for bar %d.\n",
63 bar);
64 ret = -EINVAL;
65 goto out;
66 }
67
68 pdev = platform_device_alloc("ce4100-i2c", devnum);
69 if (!pdev) {
70 of_node_put(child);
71 ret = -ENOMEM;
72 goto out;
73 }
74 pdev->dev.parent = &dev->dev;
75 pdev->dev.of_node = child;
76
77 ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
78 if (ret)
79 goto err;
80
81 ret = platform_device_add_data(pdev, &pdata, sizeof(pdata));
82 if (ret)
83 goto err;
84
85 ret = platform_device_add(pdev);
86 if (ret)
87 goto err;
88 devnum++;
89 return pdev;
90err:
91 platform_device_put(pdev);
92out:
93 return ERR_PTR(ret);
94}
95
96static int __devinit ce4100_i2c_probe(struct pci_dev *dev,
97 const struct pci_device_id *ent)
98{
99 int ret;
100 int i;
101 struct ce4100_devices *sds;
102
103 ret = pci_enable_device_mem(dev);
104 if (ret)
105 return ret;
106
107 if (!dev->dev.of_node) {
108 dev_err(&dev->dev, "Missing device tree node.\n");
109 return -EINVAL;
110 }
111 sds = kzalloc(sizeof(*sds), GFP_KERNEL);
112 if (!sds)
113 goto err_mem;
114
115 for (i = 0; i < ARRAY_SIZE(sds->pdev); i++) {
116 sds->pdev[i] = add_i2c_device(dev, i);
117 if (IS_ERR(sds->pdev[i])) {
118 while (--i >= 0)
119 platform_device_unregister(sds->pdev[i]);
120 goto err_dev_add;
121 }
122 }
123 pci_set_drvdata(dev, sds);
124 return 0;
125
126err_dev_add:
127 pci_set_drvdata(dev, NULL);
128 kfree(sds);
129err_mem:
130 pci_disable_device(dev);
131 return ret;
132}
133
134static void __devexit ce4100_i2c_remove(struct pci_dev *dev)
135{
136 struct ce4100_devices *sds;
137 unsigned int i;
138
139 sds = pci_get_drvdata(dev);
140 pci_set_drvdata(dev, NULL);
141
142 for (i = 0; i < ARRAY_SIZE(sds->pdev); i++)
143 platform_device_unregister(sds->pdev[i]);
144
145 pci_disable_device(dev);
146 kfree(sds);
147}
148
149static struct pci_device_id ce4100_i2c_devices[] __devinitdata = {
150 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)},
151 { },
152};
153MODULE_DEVICE_TABLE(pci, ce4100_i2c_devices);
154
155static struct pci_driver ce4100_i2c_driver = {
156 .name = "ce4100_i2c",
157 .id_table = ce4100_i2c_devices,
158 .probe = ce4100_i2c_probe,
159 .remove = __devexit_p(ce4100_i2c_remove),
160};
161
162static int __init ce4100_i2c_init(void)
163{
164 return pci_register_driver(&ce4100_i2c_driver);
165}
166module_init(ce4100_i2c_init);
167
168static void __exit ce4100_i2c_exit(void)
169{
170 pci_unregister_driver(&ce4100_i2c_driver);
171}
172module_exit(ce4100_i2c_exit);
173
174MODULE_DESCRIPTION("CE4100 PCI-I2C glue code for PXA's driver");
175MODULE_LICENSE("GPL v2");
176MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index fc2a90ed14cc..ab59b7e492ed 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -38,6 +38,13 @@
38 38
39#include <asm/irq.h> 39#include <asm/irq.h>
40 40
41#ifndef CONFIG_HAVE_CLK
42#define clk_get(dev, id) NULL
43#define clk_put(clk) do { } while (0)
44#define clk_disable(clk) do { } while (0)
45#define clk_enable(clk) do { } while (0)
46#endif
47
41struct pxa_reg_layout { 48struct pxa_reg_layout {
42 u32 ibmr; 49 u32 ibmr;
43 u32 idbr; 50 u32 idbr;
@@ -49,6 +56,7 @@ struct pxa_reg_layout {
49enum pxa_i2c_types { 56enum pxa_i2c_types {
50 REGS_PXA2XX, 57 REGS_PXA2XX,
51 REGS_PXA3XX, 58 REGS_PXA3XX,
59 REGS_CE4100,
52}; 60};
53 61
54/* 62/*
@@ -69,11 +77,19 @@ static struct pxa_reg_layout pxa_reg_layout[] = {
69 .isr = 0x18, 77 .isr = 0x18,
70 .isar = 0x20, 78 .isar = 0x20,
71 }, 79 },
80 [REGS_CE4100] = {
81 .ibmr = 0x14,
82 .idbr = 0x0c,
83 .icr = 0x00,
84 .isr = 0x04,
85 /* no isar register */
86 },
72}; 87};
73 88
74static const struct platform_device_id i2c_pxa_id_table[] = { 89static const struct platform_device_id i2c_pxa_id_table[] = {
75 { "pxa2xx-i2c", REGS_PXA2XX }, 90 { "pxa2xx-i2c", REGS_PXA2XX },
76 { "pxa3xx-pwri2c", REGS_PXA3XX }, 91 { "pxa3xx-pwri2c", REGS_PXA3XX },
92 { "ce4100-i2c", REGS_CE4100 },
77 { }, 93 { },
78}; 94};
79MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table); 95MODULE_DEVICE_TABLE(platform, i2c_pxa_id_table);
@@ -442,7 +458,8 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
442 writel(I2C_ISR_INIT, _ISR(i2c)); 458 writel(I2C_ISR_INIT, _ISR(i2c));
443 writel(readl(_ICR(i2c)) & ~ICR_UR, _ICR(i2c)); 459 writel(readl(_ICR(i2c)) & ~ICR_UR, _ICR(i2c));
444 460
445 writel(i2c->slave_addr, _ISAR(i2c)); 461 if (i2c->reg_isar)
462 writel(i2c->slave_addr, _ISAR(i2c));
446 463
447 /* set control register values */ 464 /* set control register values */
448 writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c)); 465 writel(I2C_ICR_INIT | (i2c->fast_mode ? ICR_FM : 0), _ICR(i2c));
@@ -1074,7 +1091,8 @@ static int i2c_pxa_probe(struct platform_device *dev)
1074 i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr; 1091 i2c->reg_idbr = i2c->reg_base + pxa_reg_layout[i2c_type].idbr;
1075 i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr; 1092 i2c->reg_icr = i2c->reg_base + pxa_reg_layout[i2c_type].icr;
1076 i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr; 1093 i2c->reg_isr = i2c->reg_base + pxa_reg_layout[i2c_type].isr;
1077 i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar; 1094 if (i2c_type != REGS_CE4100)
1095 i2c->reg_isar = i2c->reg_base + pxa_reg_layout[i2c_type].isar;
1078 1096
1079 i2c->iobase = res->start; 1097 i2c->iobase = res->start;
1080 i2c->iosize = resource_size(res); 1098 i2c->iosize = resource_size(res);
@@ -1113,7 +1131,10 @@ static int i2c_pxa_probe(struct platform_device *dev)
1113 i2c->adap.algo_data = i2c; 1131 i2c->adap.algo_data = i2c;
1114 i2c->adap.dev.parent = &dev->dev; 1132 i2c->adap.dev.parent = &dev->dev;
1115 1133
1116 ret = i2c_add_numbered_adapter(&i2c->adap); 1134 if (i2c_type == REGS_CE4100)
1135 ret = i2c_add_adapter(&i2c->adap);
1136 else
1137 ret = i2c_add_numbered_adapter(&i2c->adap);
1117 if (ret < 0) { 1138 if (ret < 0) {
1118 printk(KERN_INFO "I2C: Failed to add bus\n"); 1139 printk(KERN_INFO "I2C: Failed to add bus\n");
1119 goto eadapt; 1140 goto eadapt;