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.
6 #include <linux/module.h>
8 #include <linux/platform_device.h>
9 #include <linux/i2c/pxa-i2c.h>
11 #include <linux/of_device.h>
12 #include <linux/of_address.h>
14 #define CE4100_PCI_I2C_DEVS 3
16 struct ce4100_devices
{
17 struct platform_device
*pdev
[CE4100_PCI_I2C_DEVS
];
20 static struct platform_device
*add_i2c_device(struct pci_dev
*dev
, int bar
)
22 struct platform_device
*pdev
;
23 struct i2c_pxa_platform_data pdata
;
24 struct resource res
[2];
25 struct device_node
*child
;
29 memset(&pdata
, 0, sizeof(struct i2c_pxa_platform_data
));
30 memset(&res
, 0, sizeof(res
));
32 res
[0].flags
= IORESOURCE_MEM
;
33 res
[0].start
= pci_resource_start(dev
, bar
);
34 res
[0].end
= pci_resource_end(dev
, bar
);
36 res
[1].flags
= IORESOURCE_IRQ
;
37 res
[1].start
= dev
->irq
;
38 res
[1].end
= dev
->irq
;
40 for_each_child_of_node(dev
->dev
.of_node
, child
) {
45 ret
= of_address_to_resource(child
, 0, &r
);
48 if (r
.start
!= res
[0].start
)
50 if (r
.end
!= res
[0].end
)
52 if (r
.flags
!= res
[0].flags
)
55 prop
= of_get_property(child
, "fast-mode", NULL
);
63 dev_err(&dev
->dev
, "failed to match a DT node for bar %d.\n",
69 pdev
= platform_device_alloc("ce4100-i2c", devnum
);
75 pdev
->dev
.parent
= &dev
->dev
;
76 pdev
->dev
.of_node
= child
;
78 ret
= platform_device_add_resources(pdev
, res
, ARRAY_SIZE(res
));
82 ret
= platform_device_add_data(pdev
, &pdata
, sizeof(pdata
));
86 ret
= platform_device_add(pdev
);
92 platform_device_put(pdev
);
97 static int ce4100_i2c_probe(struct pci_dev
*dev
,
98 const struct pci_device_id
*ent
)
102 struct ce4100_devices
*sds
;
104 ret
= pci_enable_device_mem(dev
);
108 if (!dev
->dev
.of_node
) {
109 dev_err(&dev
->dev
, "Missing device tree node.\n");
112 sds
= kzalloc(sizeof(*sds
), GFP_KERNEL
);
118 for (i
= 0; i
< ARRAY_SIZE(sds
->pdev
); i
++) {
119 sds
->pdev
[i
] = add_i2c_device(dev
, i
);
120 if (IS_ERR(sds
->pdev
[i
])) {
121 ret
= PTR_ERR(sds
->pdev
[i
]);
123 platform_device_unregister(sds
->pdev
[i
]);
127 pci_set_drvdata(dev
, sds
);
133 pci_disable_device(dev
);
137 static void ce4100_i2c_remove(struct pci_dev
*dev
)
139 struct ce4100_devices
*sds
;
142 sds
= pci_get_drvdata(dev
);
144 for (i
= 0; i
< ARRAY_SIZE(sds
->pdev
); i
++)
145 platform_device_unregister(sds
->pdev
[i
]);
147 pci_disable_device(dev
);
151 static const struct pci_device_id ce4100_i2c_devices
[] = {
152 { PCI_DEVICE(PCI_VENDOR_ID_INTEL
, 0x2e68)},
155 MODULE_DEVICE_TABLE(pci
, ce4100_i2c_devices
);
157 static struct pci_driver ce4100_i2c_driver
= {
158 .name
= "ce4100_i2c",
159 .id_table
= ce4100_i2c_devices
,
160 .probe
= ce4100_i2c_probe
,
161 .remove
= ce4100_i2c_remove
,
164 module_pci_driver(ce4100_i2c_driver
);
166 MODULE_DESCRIPTION("CE4100 PCI-I2C glue code for PXA's driver");
167 MODULE_LICENSE("GPL v2");
168 MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");