aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/i2c
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2019-02-14 04:24:49 +0100
committerWolfram Sang <wsa@the-dreams.de>2019-02-14 17:58:07 +0100
commit809445d4b7fa7101d9434182bebbd8c84d7e4b65 (patch)
treeacc4cdf10a4c704a79881fcee7ed7a0e6935dd6a /drivers/i2c
parenti2c: ocores: checkpatch fixes (diff)
downloadlinux-dev-809445d4b7fa7101d9434182bebbd8c84d7e4b65.tar.xz
linux-dev-809445d4b7fa7101d9434182bebbd8c84d7e4b65.zip
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')
-rw-r--r--drivers/i2c/busses/i2c-ocores.c32
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) {