diff options
author | Andrew Lunn <andrew@lunn.ch> | 2019-02-14 04:24:49 +0100 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2019-02-14 17:58:07 +0100 |
commit | 809445d4b7fa7101d9434182bebbd8c84d7e4b65 (patch) | |
tree | acc4cdf10a4c704a79881fcee7ed7a0e6935dd6a /drivers/i2c/busses | |
parent | fac9c29fc7d5b57724b88f54d27e11b20404a2ec (diff) |
i2c: ocores: Add support for IO mapper registers.
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>
Diffstat (limited to 'drivers/i2c/busses')
-rw-r--r-- | drivers/i2c/busses/i2c-ocores.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index b32d67c90d67..0d90a82a2c03 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c @@ -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) { |