i2c: ocores: Add support for IO mapper registers.
authorAndrew Lunn <andrew@lunn.ch>
Thu, 14 Feb 2019 03:24:49 +0000 (04:24 +0100)
committerWolfram Sang <wsa@the-dreams.de>
Thu, 14 Feb 2019 16:58:07 +0000 (17:58 +0100)
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>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
drivers/i2c/busses/i2c-ocores.c

index b32d67c90d67e624608c7639afee60a6d0383928..0d90a82a2c032150da22ab418f04d6521669e078 100644 (file)
@@ -34,6 +34,7 @@
  */
 struct ocores_i2c {
        void __iomem *base;
+       int iobase;
        u32 reg_shift;
        u32 reg_io_width;
        unsigned long flags;
@@ -135,6 +136,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);
@@ -593,9 +604,24 @@ static int ocores_i2c_probe(struct platform_device *pdev)
        spin_lock_init(&i2c->process_lock);
 
        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) {