1 // SPDX-License-Identifier: GPL-2.0-only
3 * CE4100 PCI-I2C glue code for PXA's driver
4 * Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
6 * The CE4100's I2C device is more or less the same one as found on PXA.
7 * It does not support target mode, the register slightly moved. This PCI
8 * device provides three bars, every contains a single I2C controller.
10 #include <linux/init.h>
11 #include <linux/pci.h>
12 #include <linux/platform_device.h>
13 #include <linux/platform_data/i2c-pxa.h>
15 #include <linux/of_address.h>
17 #define CE4100_PCI_I2C_DEVS 3
19 struct ce4100_devices
{
20 struct platform_device
*pdev
[CE4100_PCI_I2C_DEVS
];
23 static struct platform_device
*add_i2c_device(struct pci_dev
*dev
, int bar
)
25 struct platform_device
*pdev
;
26 struct i2c_pxa_platform_data pdata
;
27 struct resource res
[2];
28 struct device_node
*child
;
32 memset(&pdata
, 0, sizeof(struct i2c_pxa_platform_data
));
33 memset(&res
, 0, sizeof(res
));
35 res
[0].flags
= IORESOURCE_MEM
;
36 res
[0].start
= pci_resource_start(dev
, bar
);
37 res
[0].end
= pci_resource_end(dev
, bar
);
39 res
[1].flags
= IORESOURCE_IRQ
;
40 res
[1].start
= dev
->irq
;
41 res
[1].end
= dev
->irq
;
43 for_each_child_of_node(dev
->dev
.of_node
, child
) {
48 ret
= of_address_to_resource(child
, 0, &r
);
51 if (r
.start
!= res
[0].start
)
53 if (r
.end
!= res
[0].end
)
55 if (r
.flags
!= res
[0].flags
)
58 prop
= of_get_property(child
, "fast-mode", NULL
);
66 dev_err(&dev
->dev
, "failed to match a DT node for bar %d.\n",
72 pdev
= platform_device_alloc("ce4100-i2c", devnum
);
78 pdev
->dev
.parent
= &dev
->dev
;
79 pdev
->dev
.of_node
= child
;
81 ret
= platform_device_add_resources(pdev
, res
, ARRAY_SIZE(res
));
85 ret
= platform_device_add_data(pdev
, &pdata
, sizeof(pdata
));
89 ret
= platform_device_add(pdev
);
95 platform_device_put(pdev
);
100 static int ce4100_i2c_probe(struct pci_dev
*dev
,
101 const struct pci_device_id
*ent
)
105 struct ce4100_devices
*sds
;
107 ret
= pcim_enable_device(dev
);
111 if (!dev
->dev
.of_node
) {
112 dev_err(&dev
->dev
, "Missing device tree node.\n");
115 sds
= kzalloc(sizeof(*sds
), GFP_KERNEL
);
119 for (i
= 0; i
< ARRAY_SIZE(sds
->pdev
); i
++) {
120 sds
->pdev
[i
] = add_i2c_device(dev
, i
);
121 if (IS_ERR(sds
->pdev
[i
])) {
122 ret
= PTR_ERR(sds
->pdev
[i
]);
124 platform_device_unregister(sds
->pdev
[i
]);
128 pci_set_drvdata(dev
, sds
);
136 static const struct pci_device_id ce4100_i2c_devices
[] = {
137 { PCI_DEVICE(PCI_VENDOR_ID_INTEL
, 0x2e68)},
141 static struct pci_driver ce4100_i2c_driver
= {
143 .suppress_bind_attrs
= true,
145 .name
= "ce4100_i2c",
146 .id_table
= ce4100_i2c_devices
,
147 .probe
= ce4100_i2c_probe
,
149 builtin_pci_driver(ce4100_i2c_driver
);