[PATCH] i2c: core: make it possible to match a pure device tree driver

2013-05-12 Thread Linus Walleij
This tries to address an issue found when writing an MFD driver
for the Nomadik STw481x PMICs: as the platform is using device
tree exclusively I want to specify the driver matching like
this:

static const struct of_device_id stw481x_match[] = {
{ .compatible = "st,stw4810", },
{ .compatible = "st,stw4811", },
{},
};

static struct i2c_driver stw481x_driver = {
.driver = {
.name   = "stw481x",
.of_match_table = stw481x_match,
},
.probe  = stw481x_probe,
.remove = stw481x_remove,
};

However that turns out not to be possible: the I2C probe code
is written so that the probe() call is always passed a match
from i2c_match_id() using non-devicetree matches.

This is probably why most devices using device tree for I2C
clients currently will pass no .of_match_table *at all* but
instead just use .id_table from struct i2c_driver to match
the device. As you realize that means that the whole idea with
compatible strings is discarded, and that is why we find strange
device tree I2C device compatible strings like "product" instead
of "vendor,product" as you could expect.

Let's figure out how to fix this before the mess spreads. This
patch will allow probeing devices with only an of_match_table
as per above, and will pass NULL as the second argument to the
probe() function. If the driver wants to deduce secondary info
from the struct of_device_id .data field, it has to call
of_match_device() on its own match table in the probe function
device tree probe path.

If drivers define both an .of_match_table *AND* a i2c_driver
.id_table, the .of_match_table will take precedence, just
as is done in the i2c_device_match() function in i2c-core.c.

I2C devices probed from device tree should subsequently be
fixed to handle the case where of_match_table() is
used (I think none of them do that today), and platforms should
fix their device trees to use compatible strings for I2C devices
instead of setting the name to Linux device driver names as is
done in multiple cases today.

Cc: Rob Herring 
Cc: Grant Likely 
Signed-off-by: Linus Walleij 
---
I would need some device tree core people to confirm that I am
on the right track with this. I was s confused when I found
that .of_match_table could not be used with I2C devices...
---
 drivers/i2c/i2c-core.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 6b63cc7..30b5bb2 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -240,7 +240,7 @@ static int i2c_device_probe(struct device *dev)
return 0;
 
driver = to_i2c_driver(dev->driver);
-   if (!driver->probe || !driver->id_table)
+   if (!driver->probe || (!driver->id_table && 
!dev->driver->of_match_table))
return -ENODEV;
client->driver = driver;
if (!device_can_wakeup(&client->dev))
@@ -248,7 +248,12 @@ static int i2c_device_probe(struct device *dev)
client->flags & I2C_CLIENT_WAKE);
dev_dbg(dev, "probe\n");
 
-   status = driver->probe(client, i2c_match_id(driver->id_table, client));
+   if (dev->driver->of_match_table)
+   /* Device tree matching */
+   status = driver->probe(client, NULL);
+   else
+   /* Fall back to matching the id_table */
+   status = driver->probe(client, i2c_match_id(driver->id_table, 
client));
if (status) {
client->driver = NULL;
i2c_set_clientdata(client, NULL);
-- 
1.8.1.4

--
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


[PATCH] i2c: vt8500: Add support for I2C bus on Wondermedia SoCs

2013-05-12 Thread Tony Prisk
This patch adds support for the I2C bus controllers found on Wondermedia
8xxx-series SoCs. Only master-mode is supported.

Signed-off-by: Tony Prisk 
---
 .../devicetree/bindings/i2c/i2c-vt8500.txt |   24 +
 MAINTAINERS|1 +
 drivers/i2c/busses/Kconfig |   10 +
 drivers/i2c/busses/Makefile|1 +
 drivers/i2c/busses/i2c-wmt.c   |  488 
 5 files changed, 524 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/i2c/i2c-vt8500.txt
 create mode 100644 drivers/i2c/busses/i2c-wmt.c

diff --git a/Documentation/devicetree/bindings/i2c/i2c-vt8500.txt 
b/Documentation/devicetree/bindings/i2c/i2c-vt8500.txt
new file mode 100644
index 000..94a425e
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-vt8500.txt
@@ -0,0 +1,24 @@
+* Wondermedia I2C Controller
+
+Required properties :
+
+ - compatible : should be "wm,wm8505-i2c"
+ - reg : Offset and length of the register set for the device
+ - interrupts :  where IRQ is the interrupt number
+ - clocks : phandle to the I2C clock source
+
+Optional properties :
+
+ - clock-frequency : desired I2C bus clock frequency in Hz.
+   Valid values are 10 and 40.
+   Default to 10 if not specified, or invalid value.
+
+Example :
+
+   i2c_0: i2c@d828 {
+   compatible = "wm,wm8505-i2c";
+   reg = <0xd828 0x1000>;
+   interrupts = <19>;
+   clocks = <&clki2c0>;
+   clock-frequency = <40>;
+   };
diff --git a/MAINTAINERS b/MAINTAINERS
index 3d7782b..44ea994 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1285,6 +1285,7 @@ S:Maintained
 F: arch/arm/mach-vt8500/
 F: drivers/clocksource/vt8500_timer.c
 F: drivers/gpio/gpio-vt8500.c
+F: drivers/i2c/busses/i2c-wmt.c
 F: drivers/mmc/host/wmt-sdmmc.c
 F: drivers/pwm/pwm-vt8500.c
 F: drivers/rtc/rtc-vt8500.c
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 631736e..89e7ec2 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -724,6 +724,16 @@ config I2C_VERSATILE
  This driver can also be built as a module.  If so, the module
  will be called i2c-versatile.
 
+config I2C_WMT
+   tristate "Wondermedia WM8xxx SoC I2C bus support"
+   depends on ARCH_VT8500
+   help
+ Say yes if you want to support the I2C bus on Wondermedia 8xxx-series
+ SoCs.
+
+ This driver can also be built as a module. If so, the module will be
+ called i2c-wmt.
+
 config I2C_OCTEON
tristate "Cavium OCTEON I2C bus support"
depends on CPU_CAVIUM_OCTEON
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 8f4fc23..3ba94a9 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_I2C_SIRF)+= i2c-sirf.o
 obj-$(CONFIG_I2C_STU300)   += i2c-stu300.o
 obj-$(CONFIG_I2C_TEGRA)+= i2c-tegra.o
 obj-$(CONFIG_I2C_VERSATILE)+= i2c-versatile.o
+obj-$(CONFIG_I2C_WMT)  += i2c-wmt.o
 obj-$(CONFIG_I2C_OCTEON)   += i2c-octeon.o
 obj-$(CONFIG_I2C_XILINX)   += i2c-xiic.o
 obj-$(CONFIG_I2C_XLR)  += i2c-xlr.o
diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c
new file mode 100644
index 000..5cebb29
--- /dev/null
+++ b/drivers/i2c/busses/i2c-wmt.c
@@ -0,0 +1,488 @@
+/*
+ *  Wondermedia I2C Master Mode Driver
+ *
+ *  Copyright (C) 2012 Tony Prisk 
+ *
+ *  Derived from GPLv2+ licensed source:
+ *  - Copyright (C) 2008 WonderMedia Technologies, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2, or
+ *  (at your option) any later version. as published by the Free Software
+ *  Foundation
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define REG_CR 0x00
+#define REG_TCR0x02
+#define REG_CSR0x04
+#define REG_ISR0x06
+#define REG_IMR0x08
+#define REG_CDR0x0A
+#define REG_TR 0x0C
+#define REG_MCR0x0E
+#define REG_SLAVE_CR   0x10
+#define REG_SLAVE_SR   0x12
+#define REG_SLAVE_ISR  0x14
+#define REG_SLAVE_IMR  0x16
+#define REG_SLAVE_DR   0x18
+#define REG_SLAVE_TR   0x1A
+
+/* REG_CR Bit fields */
+#define CR_TX_NEXT_ACK 0x
+#define CR_ENABLE  0x0001
+#define CR_TX_NEXT_NO_ACK  0x0002
+#define CR_TX_END  0x0004
+#define CR_CPU_RDY 0x0008
+#define SLAV_MODE_SEL  0x8000
+
+/* REG_TCR Bit fields */
+#define TCR_STANDARD_MODE  0x
+#define TCR_MASTER_WRITE   0x
+#define TCR_HS_MODE0x2000
+#define TCR_MASTER_READ0x4000
+#define