Re: [PATCH 2/2] i2c: add driver for Sigma Designs SMP8642 I2C master

2015-11-01 Thread Måns Rullgård
Wolfram Sang  writes:

> On Sat, Oct 31, 2015 at 05:35:57PM +, Mans Rullgard wrote:
>> This adds a driver for the Sigma Designs SMP8642 built-in I2C master
>> controller.  The hardware is very similar to the I2C controller in the
>> Ralink RT3050 chip with the addition of interrupt generation and an
>> inverted busy/idle status bit.  There are typically two controllers with
>> a shared IRQ.
>> 
>> Signed-off-by: Mans Rullgard 
>
> Thanks for the driver. Same answer as here, though:
>
> http://www.spinics.net/lists/linux-i2c/msg17001.html
>
>> +#define TANGOX_I2C_CONFIG   0x00
>> +#define TANGOX_I2C_CLKDIV   0x04
>> +#define TANGOX_I2C_DEVADDR  0x08
>> +#define TANGOX_I2C_ADDR 0x0c
>> +#define TANGOX_I2C_DATAOUT  0x10
>> +#define TANGOX_I2C_DATAIN   0x14
>> +#define TANGOX_I2C_STATUS   0x18
>> +#define TANGOX_I2C_STARTXFER0x1c
>> +#define TANGOX_I2C_BYTECNT  0x20
>> +#define TANGOX_I2C_INT_EN   0x24
>> +#define TANGOX_I2C_INT_STAT 0x28
>
> The register set looks like the one from i2c-xlr.c, only that they are
> 32 bit apart instead of 8. Can you check if you can reuse that driver?

It does look very similar indeed.  I thought I'd checked for an existing
driver, but apparently I missed that one.  I'll modify the xlr driver to
handle this hardware as well instead.

-- 
Måns Rullgård
m...@mansr.com
--
To unsubscribe from this list: send the line "unsubscribe linux-i2c" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/2] i2c: add driver for Sigma Designs SMP8642 I2C master

2015-11-01 Thread Wolfram Sang
On Sat, Oct 31, 2015 at 05:35:57PM +, Mans Rullgard wrote:
> This adds a driver for the Sigma Designs SMP8642 built-in I2C master
> controller.  The hardware is very similar to the I2C controller in the
> Ralink RT3050 chip with the addition of interrupt generation and an
> inverted busy/idle status bit.  There are typically two controllers with
> a shared IRQ.
> 
> Signed-off-by: Mans Rullgard 

Thanks for the driver. Same answer as here, though:

http://www.spinics.net/lists/linux-i2c/msg17001.html

> +#define TANGOX_I2C_CONFIG0x00
> +#define TANGOX_I2C_CLKDIV0x04
> +#define TANGOX_I2C_DEVADDR   0x08
> +#define TANGOX_I2C_ADDR  0x0c
> +#define TANGOX_I2C_DATAOUT   0x10
> +#define TANGOX_I2C_DATAIN0x14
> +#define TANGOX_I2C_STATUS0x18
> +#define TANGOX_I2C_STARTXFER 0x1c
> +#define TANGOX_I2C_BYTECNT   0x20
> +#define TANGOX_I2C_INT_EN0x24
> +#define TANGOX_I2C_INT_STAT  0x28

The register set looks like the one from i2c-xlr.c, only that they are
32 bit apart instead of 8. Can you check if you can reuse that driver?

Thanks,

   Wolfram



signature.asc
Description: Digital signature


Re: [PATCH 2/2] i2c: add driver for Sigma Designs SMP8642 I2C master

2015-11-01 Thread Wolfram Sang

> > The register set looks like the one from i2c-xlr.c, only that they are
> > 32 bit apart instead of 8. Can you check if you can reuse that driver?
> 
> It does look very similar indeed.  I thought I'd checked for an existing
> driver, but apparently I missed that one.  I'll modify the xlr driver to
> handle this hardware as well instead.

Thanks, much appreciated!



signature.asc
Description: Digital signature


[PATCH 2/2] i2c: add driver for Sigma Designs SMP8642 I2C master

2015-10-31 Thread Mans Rullgard
This adds a driver for the Sigma Designs SMP8642 built-in I2C master
controller.  The hardware is very similar to the I2C controller in the
Ralink RT3050 chip with the addition of interrupt generation and an
inverted busy/idle status bit.  There are typically two controllers with
a shared IRQ.

Signed-off-by: Mans Rullgard 
---
 drivers/i2c/busses/Kconfig  |   8 +
 drivers/i2c/busses/Makefile |   1 +
 drivers/i2c/busses/i2c-tangox.c | 330 
 3 files changed, 339 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-tangox.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 08b8617..f764e3a 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -974,6 +974,14 @@ config I2C_RCAR
  This driver can also be built as a module.  If so, the module
  will be called i2c-rcar.
 
+config I2C_TANGOX
+   tristate "SMP86xx I2C master support"
+   depends on ARCH_TANGOX
+   help
+ This driver supports the Sigma Designs SMP86xx built-in I2c master.
+
+ If built as a module, it will be called i2c-tangox.
+
 comment "External I2C/SMBus adapter drivers"
 
 config I2C_DIOLAN_U2C
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 6df3b30..d7a9f94 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -94,6 +94,7 @@ obj-$(CONFIG_I2C_XILINX)  += i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)  += i2c-xlr.o
 obj-$(CONFIG_I2C_XLP9XX)   += i2c-xlp9xx.o
 obj-$(CONFIG_I2C_RCAR) += i2c-rcar.o
+obj-$(CONFIG_I2C_TANGOX)   += i2c-tangox.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_DIOLAN_U2C)   += i2c-diolan-u2c.o
diff --git a/drivers/i2c/busses/i2c-tangox.c b/drivers/i2c/busses/i2c-tangox.c
new file mode 100644
index 000..586b3cb
--- /dev/null
+++ b/drivers/i2c/busses/i2c-tangox.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2015 Mans Rullgard 
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define TANGOX_I2C_CONFIG  0x00
+#define TANGOX_I2C_CLKDIV  0x04
+#define TANGOX_I2C_DEVADDR 0x08
+#define TANGOX_I2C_ADDR0x0c
+#define TANGOX_I2C_DATAOUT 0x10
+#define TANGOX_I2C_DATAIN  0x14
+#define TANGOX_I2C_STATUS  0x18
+#define TANGOX_I2C_STARTXFER   0x1c
+#define TANGOX_I2C_BYTECNT 0x20
+#define TANGOX_I2C_INT_EN  0x24
+#define TANGOX_I2C_INT_STAT0x28
+
+#define TANGOX_I2C_CFG_EN  (1 << 8)
+#define TANGOX_I2C_CFG_ADDRLEN(x)  ((x) << 5)
+#define TANGOX_I2C_CFG_DEVADLEN(x) ((x) << 2)
+#define TANGOX_I2C_CFG_ADDRDIS (1 << 1)
+#define TANGOX_I2C_CFG_DEVADDIS(1 << 0)
+
+#define TANGOX_I2C_STATUS_IDLE (1 << 0)
+#define TANGOX_I2C_STATUS_SDOEMPTY (1 << 1)
+#define TANGOX_I2C_STATUS_DATARDY  (1 << 2)
+#define TANGOX_I2C_STATUS_ACKERR   (1 << 3)
+#define TANGOX_I2C_STATUS_STARTERR (1 << 4)
+
+#define TANGOX_I2C_XFER_WR 0
+#define TANGOX_I2C_XFER_RD 1
+#define TANGOX_I2C_XFER_NODATA 2
+
+#define TANGOX_I2C_CFG_WR  0x1f8
+#define TANGOX_I2C_CFG_RD  0x1fa
+
+#define TANGOX_I2C_TIMEOUT(len)msecs_to_jiffies(10 * len)
+
+struct tangox_i2c {
+   struct i2c_adapter adap;
+   void __iomem *base;
+   struct i2c_msg *msg;
+   int pos;
+   wait_queue_head_t wait;
+   struct clk *clk;
+};
+
+static int tangox_i2c_idle(struct tangox_i2c *ti2c)
+{
+   return readl(ti2c->base + TANGOX_I2C_STATUS) & TANGOX_I2C_STATUS_IDLE;
+}
+
+static int tangox_i2c_wait(struct tangox_i2c *ti2c, unsigned long timeout)
+{
+   int status;
+   int t;
+
+   t = wait_event_timeout(ti2c->wait, tangox_i2c_idle(ti2c), timeout);
+   if (!t)
+   return -ETIMEDOUT;
+
+   status = readl(ti2c->base + TANGOX_I2C_STATUS);
+
+   return status & TANGOX_I2C_STATUS_ACKERR ? -EIO : 0;
+}
+
+static void tangox_i2c_tx_irq(struct tangox_i2c *ti2c, u32 status)
+{
+   struct i2c_msg *msg = ti2c->msg;
+
+   if (status & TANGOX_I2C_STATUS_SDOEMPTY)
+   writel(msg->buf[ti2c->pos++], ti2c->base + TANGOX_I2C_DATAOUT);
+}
+
+static void tangox_i2c_rx_irq(struct tangox_i2c *ti2c, u32 status)
+{
+   struct i2c_msg *msg = ti2c->msg;
+
+   if (status & TANGOX_I2C_STATUS_DATARDY)
+   msg->buf[ti2c->pos++] = readl(ti2c->base + TANGOX_I2C_DATAIN);
+}
+
+static irqreturn_t tangox_i2c_irq(int irq, void *dev_id)
+{
+   struct tangox_i2c *ti2c = dev_id;
+