@@ -28,6 +28,7 @@
struct ocores_i2c {
void __iomem *base;
+ int iobase;
u32 reg_shift;
u32 reg_io_width;
wait_queue_head_t wait;
@@ -127,6 +128,16 @@ static inline u8 oc_getreg_32be(struct ocores_i2c *i2c, int reg)
return ioread32be(i2c->base + (reg << i2c->reg_shift));
}
+static void oc_setreg_io_8(struct ocores_i2c *i2c, int reg, u8 value)
+{
+ outb(value, i2c->iobase + reg);
+}
+
+static inline u8 oc_getreg_io_8(struct ocores_i2c *i2c, int reg)
+{
+ return inb(i2c->iobase + reg);
+}
+
static inline void oc_setreg(struct ocores_i2c *i2c, int reg, u8 value)
{
i2c->setreg(i2c, reg, value);
@@ -423,9 +434,24 @@ static int ocores_i2c_probe(struct platform_device *pdev)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- i2c->base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(i2c->base))
- return PTR_ERR(i2c->base);
+ if (res) {
+ i2c->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(i2c->base))
+ return PTR_ERR(i2c->base);
+ } else {
+ res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+ if (!res)
+ return -EINVAL;
+ i2c->iobase = res->start;
+ if (!devm_request_region(&pdev->dev, res->start,
+ resource_size(res),
+ pdev->name)) {
+ dev_err(&pdev->dev, "Can't get I/O resource.\n");
+ return -EBUSY;
+ }
+ i2c->setreg = oc_setreg_io_8;
+ i2c->getreg = oc_getreg_io_8;
+ }
pdata = dev_get_platdata(&pdev->dev);
if (pdata) {
Some implementations of the OCORES i2c bus master use IO mapped registers. Add support for getting the IO registers from the platform data, and register accessor functions. Signed-off-by: Andrew Lunn <andrew@lunn.ch> --- drivers/i2c/busses/i2c-ocores.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-)