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.
7 #include <linux/platform_device.h>
8 #include <linux/i2c/pxa-i2c.h>
10 #include <linux/of_device.h>
11 #include <linux/of_address.h>
13 #define CE4100_PCI_I2C_DEVS 3
15 struct ce4100_devices
{
16 struct platform_device
*pdev
[CE4100_PCI_I2C_DEVS
];
19 static struct platform_device
*add_i2c_device(struct pci_dev
*dev
, int bar
)
21 struct platform_device
*pdev
;
22 struct i2c_pxa_platform_data pdata
;
23 struct resource res
[2];
24 struct device_node
*child
;
28 memset(&pdata
, 0, sizeof(struct i2c_pxa_platform_data
));
29 memset(&res
, 0, sizeof(res
));
31 res
[0].flags
= IORESOURCE_MEM
;
32 res
[0].start
= pci_resource_start(dev
, bar
);
33 res
[0].end
= pci_resource_end(dev
, bar
);
35 res
[1].flags
= IORESOURCE_IRQ
;
36 res
[1].start
= dev
->irq
;
37 res
[1].end
= dev
->irq
;
39 for_each_child_of_node(dev
->dev
.of_node
, child
) {
44 ret
= of_address_to_resource(child
, 0, &r
);
47 if (r
.start
!= res
[0].start
)
49 if (r
.end
!= res
[0].end
)
51 if (r
.flags
!= res
[0].flags
)
54 prop
= of_get_property(child
, "fast-mode", NULL
);
62 dev_err(&dev
->dev
, "failed to match a DT node for bar %d.\n",
68 pdev
= platform_device_alloc("ce4100-i2c", devnum
);
74 pdev
->dev
.parent
= &dev
->dev
;
75 pdev
->dev
.of_node
= child
;
77 ret
= platform_device_add_resources(pdev
, res
, ARRAY_SIZE(res
));
81 ret
= platform_device_add_data(pdev
, &pdata
, sizeof(pdata
));
85 ret
= platform_device_add(pdev
);
91 platform_device_put(pdev
);
96 static int __devinit
ce4100_i2c_probe(struct pci_dev
*dev
,
97 const struct pci_device_id
*ent
)
101 struct ce4100_devices
*sds
;
103 ret
= pci_enable_device_mem(dev
);
107 if (!dev
->dev
.of_node
) {
108 dev_err(&dev
->dev
, "Missing device tree node.\n");
111 sds
= kzalloc(sizeof(*sds
), GFP_KERNEL
);
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
])) {
119 platform_device_unregister(sds
->pdev
[i
]);
123 pci_set_drvdata(dev
, sds
);
127 pci_set_drvdata(dev
, NULL
);
130 pci_disable_device(dev
);
134 static void __devexit
ce4100_i2c_remove(struct pci_dev
*dev
)
136 struct ce4100_devices
*sds
;
139 sds
= pci_get_drvdata(dev
);
140 pci_set_drvdata(dev
, NULL
);
142 for (i
= 0; i
< ARRAY_SIZE(sds
->pdev
); i
++)
143 platform_device_unregister(sds
->pdev
[i
]);
145 pci_disable_device(dev
);
149 static struct pci_device_id ce4100_i2c_devices
[] __devinitdata
= {
150 { PCI_DEVICE(PCI_VENDOR_ID_INTEL
, 0x2e68)},
153 MODULE_DEVICE_TABLE(pci
, ce4100_i2c_devices
);
155 static 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
),
162 static int __init
ce4100_i2c_init(void)
164 return pci_register_driver(&ce4100_i2c_driver
);
166 module_init(ce4100_i2c_init
);
168 static void __exit
ce4100_i2c_exit(void)
170 pci_unregister_driver(&ce4100_i2c_driver
);
172 module_exit(ce4100_i2c_exit
);
174 MODULE_DESCRIPTION("CE4100 PCI-I2C glue code for PXA's driver");
175 MODULE_LICENSE("GPL v2");
176 MODULE_AUTHOR("Sebastian Andrzej Siewior <bigeasy@linutronix.de>");