public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
@ 2010-10-08 16:52 Mark Brown
  2010-10-08 18:57 ` Stefan Schmidt
  2010-10-19  9:38 ` Samuel Ortiz
  0 siblings, 2 replies; 14+ messages in thread
From: Mark Brown @ 2010-10-08 16:52 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, patches, Mark Brown

In preparation for the addition of SPI support for the WM831x move the I2C
specific code into a separate file with a separate Kconfig option so the
I2C support can be excluded from the build.

Also update the 1133-EV1 PMIC module support for SMDK6410 to use the new
symbol.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 arch/arm/mach-s3c64xx/Kconfig   |    1 +
 drivers/mfd/Kconfig             |   14 +++--
 drivers/mfd/Makefile            |    1 +
 drivers/mfd/wm831x-core.c       |  138 +-------------------------------------
 include/linux/mfd/wm831x/core.h |   12 ++++
 5 files changed, 27 insertions(+), 139 deletions(-)

diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 1e4d78a..546db5c 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -185,6 +185,7 @@ config SMDK6410_WM1192_EV1
 	select REGULATOR_WM831X
 	select S3C24XX_GPIO_EXTRA64
 	select MFD_WM831X
+	select MFD_WM831X_I2C
 	help
 	  The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
 	  daughtercard for the Samsung SMDK6410 reference platform.
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 6c6b9f0..608a277 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -315,14 +315,18 @@ config MFD_WM8400
 	  the functionality of the device.
 
 config MFD_WM831X
-	bool "Support Wolfson Microelectronics WM831x/2x PMICs"
+	bool
+	depends on GENERIC_HARDIRQS
+
+config MFD_WM831X_I2C
+	bool "Support Wolfson Microelectronics WM831x/2x PMICs with I2C"
 	select MFD_CORE
 	depends on I2C=y && GENERIC_HARDIRQS
 	help
-	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs.
-	  This driver provides common support for accessing the device,
-	  additional drivers must be enabled in order to use the
-	  functionality of the device.
+	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs
+	  when controlled using I2C.  This driver provides common support
+	  for accessing the device, additional drivers must be enabled in
+	  order to use the functionality of the device.
 
 config MFD_WM8350
 	bool
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 70b2699..c9ef41b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_MFD_TC6393XB)	+= tc6393xb.o tmio_core.o
 obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
 wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
 obj-$(CONFIG_MFD_WM831X)	+= wm831x.o
+obj-$(CONFIG_MFD_WM831X_I2C)	+= wm831x-i2c.o
 wm8350-objs			:= wm8350-core.o wm8350-regmap.o wm8350-gpio.o
 wm8350-objs			+= wm8350-irq.o
 obj-$(CONFIG_MFD_WM8350)	+= wm8350.o
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index ad36579..7d2563f 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -14,7 +14,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/i2c.h>
 #include <linux/bcd.h>
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
@@ -90,15 +89,6 @@ int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
 };
 EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
 
-enum wm831x_parent {
-	WM8310 = 0x8310,
-	WM8311 = 0x8311,
-	WM8312 = 0x8312,
-	WM8320 = 0x8320,
-	WM8321 = 0x8321,
-	WM8325 = 0x8325,
-};
-
 static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
 {
 	if (!wm831x->locked)
@@ -1447,7 +1437,7 @@ static struct mfd_cell backlight_devs[] = {
 /*
  * Instantiate the generic non-control parts of the device.
  */
-static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
+int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 {
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
 	int rev;
@@ -1673,7 +1663,7 @@ err:
 	return ret;
 }
 
-static void wm831x_device_exit(struct wm831x *wm831x)
+void wm831x_device_exit(struct wm831x *wm831x)
 {
 	wm831x_otp_exit(wm831x);
 	mfd_remove_devices(wm831x->dev);
@@ -1683,7 +1673,7 @@ static void wm831x_device_exit(struct wm831x *wm831x)
 	kfree(wm831x);
 }
 
-static int wm831x_device_suspend(struct wm831x *wm831x)
+int wm831x_device_suspend(struct wm831x *wm831x)
 {
 	int reg, mask;
 
@@ -1719,126 +1709,6 @@ static int wm831x_device_suspend(struct wm831x *wm831x)
 	return 0;
 }
 
-static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
-				  int bytes, void *dest)
-{
-	struct i2c_client *i2c = wm831x->control_data;
-	int ret;
-	u16 r = cpu_to_be16(reg);
-
-	ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
-	if (ret < 0)
-		return ret;
-	if (ret != 2)
-		return -EIO;
-
-	ret = i2c_master_recv(i2c, dest, bytes);
-	if (ret < 0)
-		return ret;
-	if (ret != bytes)
-		return -EIO;
-	return 0;
-}
-
-/* Currently we allocate the write buffer on the stack; this is OK for
- * small writes - if we need to do large writes this will need to be
- * revised.
- */
-static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
-				   int bytes, void *src)
-{
-	struct i2c_client *i2c = wm831x->control_data;
-	unsigned char msg[bytes + 2];
-	int ret;
-
-	reg = cpu_to_be16(reg);
-	memcpy(&msg[0], &reg, 2);
-	memcpy(&msg[2], src, bytes);
-
-	ret = i2c_master_send(i2c, msg, bytes + 2);
-	if (ret < 0)
-		return ret;
-	if (ret < bytes + 2)
-		return -EIO;
-
-	return 0;
-}
-
-static int wm831x_i2c_probe(struct i2c_client *i2c,
-			    const struct i2c_device_id *id)
-{
-	struct wm831x *wm831x;
-
-	wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
-	if (wm831x == NULL)
-		return -ENOMEM;
-
-	i2c_set_clientdata(i2c, wm831x);
-	wm831x->dev = &i2c->dev;
-	wm831x->control_data = i2c;
-	wm831x->read_dev = wm831x_i2c_read_device;
-	wm831x->write_dev = wm831x_i2c_write_device;
-
-	return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
-}
-
-static int wm831x_i2c_remove(struct i2c_client *i2c)
-{
-	struct wm831x *wm831x = i2c_get_clientdata(i2c);
-
-	wm831x_device_exit(wm831x);
-
-	return 0;
-}
-
-static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
-{
-	struct wm831x *wm831x = i2c_get_clientdata(i2c);
-
-	return wm831x_device_suspend(wm831x);
-}
-
-static const struct i2c_device_id wm831x_i2c_id[] = {
-	{ "wm8310", WM8310 },
-	{ "wm8311", WM8311 },
-	{ "wm8312", WM8312 },
-	{ "wm8320", WM8320 },
-	{ "wm8321", WM8321 },
-	{ "wm8325", WM8325 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
-
-
-static struct i2c_driver wm831x_i2c_driver = {
-	.driver = {
-		   .name = "wm831x",
-		   .owner = THIS_MODULE,
-	},
-	.probe = wm831x_i2c_probe,
-	.remove = wm831x_i2c_remove,
-	.suspend = wm831x_i2c_suspend,
-	.id_table = wm831x_i2c_id,
-};
-
-static int __init wm831x_i2c_init(void)
-{
-	int ret;
-
-	ret = i2c_add_driver(&wm831x_i2c_driver);
-	if (ret != 0)
-		pr_err("Failed to register wm831x I2C driver: %d\n", ret);
-
-	return ret;
-}
-subsys_initcall(wm831x_i2c_init);
-
-static void __exit wm831x_i2c_exit(void)
-{
-	i2c_del_driver(&wm831x_i2c_driver);
-}
-module_exit(wm831x_i2c_exit);
-
-MODULE_DESCRIPTION("I2C support for the WM831X AudioPlus PMIC");
+MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mark Brown");
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index eb5bd4e..a1239c4 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -238,6 +238,15 @@ struct regulator_dev;
 
 #define WM831X_NUM_IRQ_REGS 5
 
+enum wm831x_parent {
+	WM8310 = 0x8310,
+	WM8311 = 0x8311,
+	WM8312 = 0x8312,
+	WM8320 = 0x8320,
+	WM8321 = 0x8321,
+	WM8325 = 0x8325,
+};
+
 struct wm831x {
 	struct mutex io_lock;
 
@@ -285,6 +294,9 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
 int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
 		     int count, u16 *buf);
 
+int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq);
+void wm831x_device_exit(struct wm831x *wm831x);
+int wm831x_device_suspend(struct wm831x *wm831x);
 int wm831x_irq_init(struct wm831x *wm831x, int irq);
 void wm831x_irq_exit(struct wm831x *wm831x);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
  2010-10-08 16:52 Mark Brown
@ 2010-10-08 18:57 ` Stefan Schmidt
  2010-10-08 18:58   ` Mark Brown
  2010-10-19  9:38 ` Samuel Ortiz
  1 sibling, 1 reply; 14+ messages in thread
From: Stefan Schmidt @ 2010-10-08 18:57 UTC (permalink / raw)
  To: Mark Brown; +Cc: Samuel Ortiz, linux-kernel, patches

Hello.

On Fri, 2010-10-08 at 09:52, Mark Brown wrote:
> In preparation for the addition of SPI support for the WM831x move the I2C
> specific code into a separate file with a separate Kconfig option so the
> I2C support can be excluded from the build.

The factored out file is missing here. Makefile has a reference for wm831x-i2c,
but you seemed to have forgotten to git add it.

> Also update the 1133-EV1 PMIC module support for SMDK6410 to use the new
> symbol.
> 
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
>  arch/arm/mach-s3c64xx/Kconfig   |    1 +
>  drivers/mfd/Kconfig             |   14 +++--
>  drivers/mfd/Makefile            |    1 +
>  drivers/mfd/wm831x-core.c       |  138 +-------------------------------------
>  include/linux/mfd/wm831x/core.h |   12 ++++
>  5 files changed, 27 insertions(+), 139 deletions(-)

regards
Stefan Schmidt

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
  2010-10-08 18:57 ` Stefan Schmidt
@ 2010-10-08 18:58   ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2010-10-08 18:58 UTC (permalink / raw)
  To: Stefan Schmidt; +Cc: Samuel Ortiz, linux-kernel, patches

On Fri, Oct 08, 2010 at 08:57:08PM +0200, Stefan Schmidt wrote:
> Hello.
> 
> On Fri, 2010-10-08 at 09:52, Mark Brown wrote:
> > In preparation for the addition of SPI support for the WM831x move the I2C
> > specific code into a separate file with a separate Kconfig option so the
> > I2C support can be excluded from the build.

> The factored out file is missing here. Makefile has a reference for wm831x-i2c,
> but you seemed to have forgotten to git add it.

Gah, will resend shortly.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
@ 2010-10-08 21:23 Mark Brown
  2010-10-08 21:23 ` [PATCH 2/2] mfd: Add WM831x SPI support Mark Brown
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Mark Brown @ 2010-10-08 21:23 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, patches, Mark Brown

In preparation for the addition of SPI support for the WM831x move the I2C
specific code into a separate file with a separate Kconfig option so the
I2C support can be excluded from the build.

Also update the 1133-EV1 PMIC module support for SMDK6410 to use the new
symbol.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---

Resending as my finger macro sent these to the ALSA list.

 arch/arm/mach-s3c64xx/Kconfig   |    1 +
 drivers/mfd/Kconfig             |   14 +++--
 drivers/mfd/Makefile            |    1 +
 drivers/mfd/wm831x-core.c       |  138 +------------------------------------
 drivers/mfd/wm831x-i2c.c        |  143 +++++++++++++++++++++++++++++++++++++++
 include/linux/mfd/wm831x/core.h |   12 +++
 6 files changed, 170 insertions(+), 139 deletions(-)
 create mode 100644 drivers/mfd/wm831x-i2c.c

diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index 1e4d78a..546db5c 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -185,6 +185,7 @@ config SMDK6410_WM1192_EV1
 	select REGULATOR_WM831X
 	select S3C24XX_GPIO_EXTRA64
 	select MFD_WM831X
+	select MFD_WM831X_I2C
 	help
 	  The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
 	  daughtercard for the Samsung SMDK6410 reference platform.
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 6c6b9f0..608a277 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -315,14 +315,18 @@ config MFD_WM8400
 	  the functionality of the device.
 
 config MFD_WM831X
-	bool "Support Wolfson Microelectronics WM831x/2x PMICs"
+	bool
+	depends on GENERIC_HARDIRQS
+
+config MFD_WM831X_I2C
+	bool "Support Wolfson Microelectronics WM831x/2x PMICs with I2C"
 	select MFD_CORE
 	depends on I2C=y && GENERIC_HARDIRQS
 	help
-	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs.
-	  This driver provides common support for accessing the device,
-	  additional drivers must be enabled in order to use the
-	  functionality of the device.
+	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs
+	  when controlled using I2C.  This driver provides common support
+	  for accessing the device, additional drivers must be enabled in
+	  order to use the functionality of the device.
 
 config MFD_WM8350
 	bool
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 70b2699..c9ef41b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -24,6 +24,7 @@ obj-$(CONFIG_MFD_TC6393XB)	+= tc6393xb.o tmio_core.o
 obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
 wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
 obj-$(CONFIG_MFD_WM831X)	+= wm831x.o
+obj-$(CONFIG_MFD_WM831X_I2C)	+= wm831x-i2c.o
 wm8350-objs			:= wm8350-core.o wm8350-regmap.o wm8350-gpio.o
 wm8350-objs			+= wm8350-irq.o
 obj-$(CONFIG_MFD_WM8350)	+= wm8350.o
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index ad36579..7d2563f 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -14,7 +14,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/i2c.h>
 #include <linux/bcd.h>
 #include <linux/delay.h>
 #include <linux/mfd/core.h>
@@ -90,15 +89,6 @@ int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
 };
 EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
 
-enum wm831x_parent {
-	WM8310 = 0x8310,
-	WM8311 = 0x8311,
-	WM8312 = 0x8312,
-	WM8320 = 0x8320,
-	WM8321 = 0x8321,
-	WM8325 = 0x8325,
-};
-
 static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
 {
 	if (!wm831x->locked)
@@ -1447,7 +1437,7 @@ static struct mfd_cell backlight_devs[] = {
 /*
  * Instantiate the generic non-control parts of the device.
  */
-static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
+int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
 {
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
 	int rev;
@@ -1673,7 +1663,7 @@ err:
 	return ret;
 }
 
-static void wm831x_device_exit(struct wm831x *wm831x)
+void wm831x_device_exit(struct wm831x *wm831x)
 {
 	wm831x_otp_exit(wm831x);
 	mfd_remove_devices(wm831x->dev);
@@ -1683,7 +1673,7 @@ static void wm831x_device_exit(struct wm831x *wm831x)
 	kfree(wm831x);
 }
 
-static int wm831x_device_suspend(struct wm831x *wm831x)
+int wm831x_device_suspend(struct wm831x *wm831x)
 {
 	int reg, mask;
 
@@ -1719,126 +1709,6 @@ static int wm831x_device_suspend(struct wm831x *wm831x)
 	return 0;
 }
 
-static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
-				  int bytes, void *dest)
-{
-	struct i2c_client *i2c = wm831x->control_data;
-	int ret;
-	u16 r = cpu_to_be16(reg);
-
-	ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
-	if (ret < 0)
-		return ret;
-	if (ret != 2)
-		return -EIO;
-
-	ret = i2c_master_recv(i2c, dest, bytes);
-	if (ret < 0)
-		return ret;
-	if (ret != bytes)
-		return -EIO;
-	return 0;
-}
-
-/* Currently we allocate the write buffer on the stack; this is OK for
- * small writes - if we need to do large writes this will need to be
- * revised.
- */
-static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
-				   int bytes, void *src)
-{
-	struct i2c_client *i2c = wm831x->control_data;
-	unsigned char msg[bytes + 2];
-	int ret;
-
-	reg = cpu_to_be16(reg);
-	memcpy(&msg[0], &reg, 2);
-	memcpy(&msg[2], src, bytes);
-
-	ret = i2c_master_send(i2c, msg, bytes + 2);
-	if (ret < 0)
-		return ret;
-	if (ret < bytes + 2)
-		return -EIO;
-
-	return 0;
-}
-
-static int wm831x_i2c_probe(struct i2c_client *i2c,
-			    const struct i2c_device_id *id)
-{
-	struct wm831x *wm831x;
-
-	wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
-	if (wm831x == NULL)
-		return -ENOMEM;
-
-	i2c_set_clientdata(i2c, wm831x);
-	wm831x->dev = &i2c->dev;
-	wm831x->control_data = i2c;
-	wm831x->read_dev = wm831x_i2c_read_device;
-	wm831x->write_dev = wm831x_i2c_write_device;
-
-	return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
-}
-
-static int wm831x_i2c_remove(struct i2c_client *i2c)
-{
-	struct wm831x *wm831x = i2c_get_clientdata(i2c);
-
-	wm831x_device_exit(wm831x);
-
-	return 0;
-}
-
-static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
-{
-	struct wm831x *wm831x = i2c_get_clientdata(i2c);
-
-	return wm831x_device_suspend(wm831x);
-}
-
-static const struct i2c_device_id wm831x_i2c_id[] = {
-	{ "wm8310", WM8310 },
-	{ "wm8311", WM8311 },
-	{ "wm8312", WM8312 },
-	{ "wm8320", WM8320 },
-	{ "wm8321", WM8321 },
-	{ "wm8325", WM8325 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
-
-
-static struct i2c_driver wm831x_i2c_driver = {
-	.driver = {
-		   .name = "wm831x",
-		   .owner = THIS_MODULE,
-	},
-	.probe = wm831x_i2c_probe,
-	.remove = wm831x_i2c_remove,
-	.suspend = wm831x_i2c_suspend,
-	.id_table = wm831x_i2c_id,
-};
-
-static int __init wm831x_i2c_init(void)
-{
-	int ret;
-
-	ret = i2c_add_driver(&wm831x_i2c_driver);
-	if (ret != 0)
-		pr_err("Failed to register wm831x I2C driver: %d\n", ret);
-
-	return ret;
-}
-subsys_initcall(wm831x_i2c_init);
-
-static void __exit wm831x_i2c_exit(void)
-{
-	i2c_del_driver(&wm831x_i2c_driver);
-}
-module_exit(wm831x_i2c_exit);
-
-MODULE_DESCRIPTION("I2C support for the WM831X AudioPlus PMIC");
+MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mark Brown");
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
new file mode 100644
index 0000000..156b198
--- /dev/null
+++ b/drivers/mfd/wm831x-i2c.c
@@ -0,0 +1,143 @@
+/*
+ * wm831x-i2c.c  --  I2C access for Wolfson WM831x PMICs
+ *
+ * Copyright 2009,2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/mfd/core.h>
+#include <linux/slab.h>
+
+#include <linux/mfd/wm831x/core.h>
+#include <linux/mfd/wm831x/pdata.h>
+
+static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
+				  int bytes, void *dest)
+{
+	struct i2c_client *i2c = wm831x->control_data;
+	int ret;
+	u16 r = cpu_to_be16(reg);
+
+	ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
+	if (ret < 0)
+		return ret;
+	if (ret != 2)
+		return -EIO;
+
+	ret = i2c_master_recv(i2c, dest, bytes);
+	if (ret < 0)
+		return ret;
+	if (ret != bytes)
+		return -EIO;
+	return 0;
+}
+
+/* Currently we allocate the write buffer on the stack; this is OK for
+ * small writes - if we need to do large writes this will need to be
+ * revised.
+ */
+static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
+				   int bytes, void *src)
+{
+	struct i2c_client *i2c = wm831x->control_data;
+	unsigned char msg[bytes + 2];
+	int ret;
+
+	reg = cpu_to_be16(reg);
+	memcpy(&msg[0], &reg, 2);
+	memcpy(&msg[2], src, bytes);
+
+	ret = i2c_master_send(i2c, msg, bytes + 2);
+	if (ret < 0)
+		return ret;
+	if (ret < bytes + 2)
+		return -EIO;
+
+	return 0;
+}
+
+static int wm831x_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct wm831x *wm831x;
+
+	wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
+	if (wm831x == NULL)
+		return -ENOMEM;
+
+	i2c_set_clientdata(i2c, wm831x);
+	wm831x->dev = &i2c->dev;
+	wm831x->control_data = i2c;
+	wm831x->read_dev = wm831x_i2c_read_device;
+	wm831x->write_dev = wm831x_i2c_write_device;
+
+	return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
+}
+
+static int wm831x_i2c_remove(struct i2c_client *i2c)
+{
+	struct wm831x *wm831x = i2c_get_clientdata(i2c);
+
+	wm831x_device_exit(wm831x);
+
+	return 0;
+}
+
+static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
+{
+	struct wm831x *wm831x = i2c_get_clientdata(i2c);
+
+	return wm831x_device_suspend(wm831x);
+}
+
+static const struct i2c_device_id wm831x_i2c_id[] = {
+	{ "wm8310", WM8310 },
+	{ "wm8311", WM8311 },
+	{ "wm8312", WM8312 },
+	{ "wm8320", WM8320 },
+	{ "wm8321", WM8321 },
+	{ "wm8325", WM8325 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
+
+
+static struct i2c_driver wm831x_i2c_driver = {
+	.driver = {
+		   .name = "wm831x",
+		   .owner = THIS_MODULE,
+	},
+	.probe = wm831x_i2c_probe,
+	.remove = wm831x_i2c_remove,
+	.suspend = wm831x_i2c_suspend,
+	.id_table = wm831x_i2c_id,
+};
+
+static int __init wm831x_i2c_init(void)
+{
+	int ret;
+
+	ret = i2c_add_driver(&wm831x_i2c_driver);
+	if (ret != 0)
+		pr_err("Failed to register wm831x I2C driver: %d\n", ret);
+
+	return ret;
+}
+subsys_initcall(wm831x_i2c_init);
+
+static void __exit wm831x_i2c_exit(void)
+{
+	i2c_del_driver(&wm831x_i2c_driver);
+}
+module_exit(wm831x_i2c_exit);
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
index eb5bd4e..a1239c4 100644
--- a/include/linux/mfd/wm831x/core.h
+++ b/include/linux/mfd/wm831x/core.h
@@ -238,6 +238,15 @@ struct regulator_dev;
 
 #define WM831X_NUM_IRQ_REGS 5
 
+enum wm831x_parent {
+	WM8310 = 0x8310,
+	WM8311 = 0x8311,
+	WM8312 = 0x8312,
+	WM8320 = 0x8320,
+	WM8321 = 0x8321,
+	WM8325 = 0x8325,
+};
+
 struct wm831x {
 	struct mutex io_lock;
 
@@ -285,6 +294,9 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
 int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
 		     int count, u16 *buf);
 
+int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq);
+void wm831x_device_exit(struct wm831x *wm831x);
+int wm831x_device_suspend(struct wm831x *wm831x);
 int wm831x_irq_init(struct wm831x *wm831x, int irq);
 void wm831x_irq_exit(struct wm831x *wm831x);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 2/2] mfd: Add WM831x SPI support
  2010-10-08 21:23 [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver Mark Brown
@ 2010-10-08 21:23 ` Mark Brown
  2010-10-19  9:44   ` Samuel Ortiz
  2010-10-19  9:43 ` [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver Samuel Ortiz
  2010-10-19 11:15 ` Samuel Ortiz
  2 siblings, 1 reply; 14+ messages in thread
From: Mark Brown @ 2010-10-08 21:23 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, patches, Mark Brown

Implement support for controlling WM831x and WM832x devices using SPI.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---

Resending as my finger macro sent these to the ALSA list.

 drivers/mfd/Kconfig      |   10 ++
 drivers/mfd/Makefile     |    1 +
 drivers/mfd/wm831x-spi.c |  232 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 243 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/wm831x-spi.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 608a277..40aa2e8 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -328,6 +328,16 @@ config MFD_WM831X_I2C
 	  for accessing the device, additional drivers must be enabled in
 	  order to use the functionality of the device.
 
+config MFD_WM831X_SPI
+	bool "Support Wolfson Microelectronics WM831x/2x PMICs with SPI"
+	select MFD_CORE
+	depends on SPI_MASTER && GENERIC_HARDIRQS
+	help
+	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs
+	  when controlled using SPI.  This driver provides common support
+	  for accessing the device, additional drivers must be enabled in
+	  order to use the functionality of the device.
+
 config MFD_WM8350
 	bool
 	depends on GENERIC_HARDIRQS
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c9ef41b..f54b365 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
 wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
 obj-$(CONFIG_MFD_WM831X)	+= wm831x.o
 obj-$(CONFIG_MFD_WM831X_I2C)	+= wm831x-i2c.o
+obj-$(CONFIG_MFD_WM831X_SPI)	+= wm831x-spi.o
 wm8350-objs			:= wm8350-core.o wm8350-regmap.o wm8350-gpio.o
 wm8350-objs			+= wm8350-irq.o
 obj-$(CONFIG_MFD_WM8350)	+= wm8350.o
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
new file mode 100644
index 0000000..073d4c6
--- /dev/null
+++ b/drivers/mfd/wm831x-spi.c
@@ -0,0 +1,232 @@
+/*
+ * wm831x-spi.c  --  SPI access for Wolfson WM831x PMICs
+ *
+ * Copyright 2009,2010 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+
+#include <linux/mfd/wm831x/core.h>
+
+static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg,
+				  int bytes, void *dest)
+{
+	u16 tx_val;
+	u16 *d = dest;
+	int r, ret;
+
+	/* Go register at a time */
+	for (r = reg; r < reg + (bytes / 2); r++) {
+		tx_val = r | 0x8000;
+
+		ret = spi_write_then_read(wm831x->control_data,
+					  (u8 *)&tx_val, 2, (u8 *)d, 2);
+		if (ret != 0)
+			return ret;
+
+		*d = be16_to_cpu(*d);
+
+		d++;
+	}
+
+	return 0;
+}
+
+static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
+				   int bytes, void *src)
+{
+	struct spi_device *spi = wm831x->control_data;
+	u16 *s = src;
+	u16 data[2];
+	int ret;
+
+	/* Go register at a time */
+	for (r = reg; r < reg + (bytes / 2); r++) {
+		data[0] = r;
+		data[1] = *s++;
+
+		ret = spi_write(spi, (char *)&data, sizeof(data));
+		if (ret != 0)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int __devinit wm831x_spi_probe(struct spi_device *spi)
+{
+	struct wm831x *wm831x;
+	enum wm831x_parent type;
+
+	/* Currently SPI support for ID tables is unmerged, we're faking it */
+	if (strcmp(spi->modalias, "wm8310") == 0)
+		type = WM8310;
+	else if (strcmp(spi->modalias, "wm8311") == 0)
+		type = WM8311;
+	else if (strcmp(spi->modalias, "wm8312") == 0)
+		type = WM8312;
+	else if (strcmp(spi->modalias, "wm8320") == 0)
+		type = WM8320;
+	else if (strcmp(spi->modalias, "wm8321") == 0)
+		type = WM8321;
+	else if (strcmp(spi->modalias, "wm8325") == 0)
+		type = WM8325;
+	else {
+		dev_err(&spi->dev, "Unknown device type\n");
+		return -EINVAL;
+	}
+
+	wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
+	if (wm831x == NULL)
+		return -ENOMEM;
+
+	spi->bits_per_word = 16;
+	spi->mode = SPI_MODE_0;
+
+	dev_set_drvdata(&spi->dev, wm831x);
+	wm831x->dev = &spi->dev;
+	wm831x->control_data = spi;
+	wm831x->read_dev = wm831x_spi_read_device;
+	wm831x->write_dev = wm831x_spi_write_device;
+
+	return wm831x_device_init(wm831x, type, spi->irq);
+}
+
+static int __devexit wm831x_spi_remove(struct spi_device *spi)
+{
+	struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
+
+	wm831x_device_exit(wm831x);
+
+	return 0;
+}
+
+static int wm831x_spi_suspend(struct spi_device *spi, pm_message_t m)
+{
+	struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
+
+	return wm831x_device_suspend(wm831x);
+}
+
+static struct spi_driver wm8310_spi_driver = {
+	.driver = {
+		.name	= "wm8310",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm831x_spi_probe,
+	.remove		= __devexit_p(wm831x_spi_remove),
+	.suspend	= wm831x_spi_suspend,
+};
+
+static struct spi_driver wm8311_spi_driver = {
+	.driver = {
+		.name	= "wm8311",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm831x_spi_probe,
+	.remove		= __devexit_p(wm831x_spi_remove),
+	.suspend	= wm831x_spi_suspend,
+};
+
+static struct spi_driver wm8312_spi_driver = {
+	.driver = {
+		.name	= "wm8312",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm831x_spi_probe,
+	.remove		= __devexit_p(wm831x_spi_remove),
+	.suspend	= wm831x_spi_suspend,
+};
+
+static struct spi_driver wm8320_spi_driver = {
+	.driver = {
+		.name	= "wm8320",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm831x_spi_probe,
+	.remove		= __devexit_p(wm831x_spi_remove),
+	.suspend	= wm831x_spi_suspend,
+};
+
+static struct spi_driver wm8321_spi_driver = {
+	.driver = {
+		.name	= "wm8321",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm831x_spi_probe,
+	.remove		= __devexit_p(wm831x_spi_remove),
+	.suspend	= wm831x_spi_suspend,
+};
+
+static struct spi_driver wm8325_spi_driver = {
+	.driver = {
+		.name	= "wm8325",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= wm831x_spi_probe,
+	.remove		= __devexit_p(wm831x_spi_remove),
+	.suspend	= wm831x_spi_suspend,
+};
+
+static int __init wm831x_spi_init(void)
+{
+	int ret;
+
+	ret = spi_register_driver(&wm8310_spi_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM8310 SPI driver: %d\n", ret);
+
+	ret = spi_register_driver(&wm8311_spi_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM8311 SPI driver: %d\n", ret);
+
+	ret = spi_register_driver(&wm8312_spi_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM8312 SPI driver: %d\n", ret);
+
+	ret = spi_register_driver(&wm8320_spi_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM8320 SPI driver: %d\n", ret);
+
+	ret = spi_register_driver(&wm8321_spi_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM8321 SPI driver: %d\n", ret);
+
+	ret = spi_register_driver(&wm8325_spi_driver);
+	if (ret != 0)
+		pr_err("Failed to register WM8325 SPI driver: %d\n", ret);
+
+	return 0;
+}
+subsys_initcall(wm831x_spi_init);
+
+static void __exit wm831x_spi_exit(void)
+{
+	spi_unregister_driver(&wm8325_spi_driver);
+	spi_unregister_driver(&wm8321_spi_driver);
+	spi_unregister_driver(&wm8320_spi_driver);
+	spi_unregister_driver(&wm8312_spi_driver);
+	spi_unregister_driver(&wm8311_spi_driver);
+	spi_unregister_driver(&wm8310_spi_driver);
+}
+module_exit(wm831x_spi_exit);
+
+MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Mark Brown");
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
  2010-10-08 16:52 Mark Brown
  2010-10-08 18:57 ` Stefan Schmidt
@ 2010-10-19  9:38 ` Samuel Ortiz
  1 sibling, 0 replies; 14+ messages in thread
From: Samuel Ortiz @ 2010-10-19  9:38 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, patches

Hi Mark,

On Fri, Oct 08, 2010 at 09:52:58AM -0700, Mark Brown wrote:
> In preparation for the addition of SPI support for the WM831x move the I2C
> specific code into a separate file with a separate Kconfig option so the
> I2C support can be excluded from the build.
> 
> Also update the 1133-EV1 PMIC module support for SMDK6410 to use the new
> symbol.
Patch applied, many thanks.

Cheers,
Samuel.
-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
  2010-10-08 21:23 [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver Mark Brown
  2010-10-08 21:23 ` [PATCH 2/2] mfd: Add WM831x SPI support Mark Brown
@ 2010-10-19  9:43 ` Samuel Ortiz
  2010-10-19 11:15 ` Samuel Ortiz
  2 siblings, 0 replies; 14+ messages in thread
From: Samuel Ortiz @ 2010-10-19  9:43 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, patches

On Fri, Oct 08, 2010 at 02:23:22PM -0700, Mark Brown wrote:
> In preparation for the addition of SPI support for the WM831x move the I2C
> specific code into a separate file with a separate Kconfig option so the
> I2C support can be excluded from the build.
> 
> Also update the 1133-EV1 PMIC module support for SMDK6410 to use the new
> symbol.
Sorry, that's the one I applied.

Cheers,
Samuel.

 
> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
> 
> Resending as my finger macro sent these to the ALSA list.
> 
>  arch/arm/mach-s3c64xx/Kconfig   |    1 +
>  drivers/mfd/Kconfig             |   14 +++--
>  drivers/mfd/Makefile            |    1 +
>  drivers/mfd/wm831x-core.c       |  138 +------------------------------------
>  drivers/mfd/wm831x-i2c.c        |  143 +++++++++++++++++++++++++++++++++++++++
>  include/linux/mfd/wm831x/core.h |   12 +++
>  6 files changed, 170 insertions(+), 139 deletions(-)
>  create mode 100644 drivers/mfd/wm831x-i2c.c
> 
> diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
> index 1e4d78a..546db5c 100644
> --- a/arch/arm/mach-s3c64xx/Kconfig
> +++ b/arch/arm/mach-s3c64xx/Kconfig
> @@ -185,6 +185,7 @@ config SMDK6410_WM1192_EV1
>  	select REGULATOR_WM831X
>  	select S3C24XX_GPIO_EXTRA64
>  	select MFD_WM831X
> +	select MFD_WM831X_I2C
>  	help
>  	  The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
>  	  daughtercard for the Samsung SMDK6410 reference platform.
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 6c6b9f0..608a277 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -315,14 +315,18 @@ config MFD_WM8400
>  	  the functionality of the device.
>  
>  config MFD_WM831X
> -	bool "Support Wolfson Microelectronics WM831x/2x PMICs"
> +	bool
> +	depends on GENERIC_HARDIRQS
> +
> +config MFD_WM831X_I2C
> +	bool "Support Wolfson Microelectronics WM831x/2x PMICs with I2C"
>  	select MFD_CORE
>  	depends on I2C=y && GENERIC_HARDIRQS
>  	help
> -	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs.
> -	  This driver provides common support for accessing the device,
> -	  additional drivers must be enabled in order to use the
> -	  functionality of the device.
> +	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs
> +	  when controlled using I2C.  This driver provides common support
> +	  for accessing the device, additional drivers must be enabled in
> +	  order to use the functionality of the device.
>  
>  config MFD_WM8350
>  	bool
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 70b2699..c9ef41b 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -24,6 +24,7 @@ obj-$(CONFIG_MFD_TC6393XB)	+= tc6393xb.o tmio_core.o
>  obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
>  wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
>  obj-$(CONFIG_MFD_WM831X)	+= wm831x.o
> +obj-$(CONFIG_MFD_WM831X_I2C)	+= wm831x-i2c.o
>  wm8350-objs			:= wm8350-core.o wm8350-regmap.o wm8350-gpio.o
>  wm8350-objs			+= wm8350-irq.o
>  obj-$(CONFIG_MFD_WM8350)	+= wm8350.o
> diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
> index ad36579..7d2563f 100644
> --- a/drivers/mfd/wm831x-core.c
> +++ b/drivers/mfd/wm831x-core.c
> @@ -14,7 +14,6 @@
>  
>  #include <linux/kernel.h>
>  #include <linux/module.h>
> -#include <linux/i2c.h>
>  #include <linux/bcd.h>
>  #include <linux/delay.h>
>  #include <linux/mfd/core.h>
> @@ -90,15 +89,6 @@ int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
>  };
>  EXPORT_SYMBOL_GPL(wm831x_isinkv_values);
>  
> -enum wm831x_parent {
> -	WM8310 = 0x8310,
> -	WM8311 = 0x8311,
> -	WM8312 = 0x8312,
> -	WM8320 = 0x8320,
> -	WM8321 = 0x8321,
> -	WM8325 = 0x8325,
> -};
> -
>  static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
>  {
>  	if (!wm831x->locked)
> @@ -1447,7 +1437,7 @@ static struct mfd_cell backlight_devs[] = {
>  /*
>   * Instantiate the generic non-control parts of the device.
>   */
> -static int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
> +int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq)
>  {
>  	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
>  	int rev;
> @@ -1673,7 +1663,7 @@ err:
>  	return ret;
>  }
>  
> -static void wm831x_device_exit(struct wm831x *wm831x)
> +void wm831x_device_exit(struct wm831x *wm831x)
>  {
>  	wm831x_otp_exit(wm831x);
>  	mfd_remove_devices(wm831x->dev);
> @@ -1683,7 +1673,7 @@ static void wm831x_device_exit(struct wm831x *wm831x)
>  	kfree(wm831x);
>  }
>  
> -static int wm831x_device_suspend(struct wm831x *wm831x)
> +int wm831x_device_suspend(struct wm831x *wm831x)
>  {
>  	int reg, mask;
>  
> @@ -1719,126 +1709,6 @@ static int wm831x_device_suspend(struct wm831x *wm831x)
>  	return 0;
>  }
>  
> -static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
> -				  int bytes, void *dest)
> -{
> -	struct i2c_client *i2c = wm831x->control_data;
> -	int ret;
> -	u16 r = cpu_to_be16(reg);
> -
> -	ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
> -	if (ret < 0)
> -		return ret;
> -	if (ret != 2)
> -		return -EIO;
> -
> -	ret = i2c_master_recv(i2c, dest, bytes);
> -	if (ret < 0)
> -		return ret;
> -	if (ret != bytes)
> -		return -EIO;
> -	return 0;
> -}
> -
> -/* Currently we allocate the write buffer on the stack; this is OK for
> - * small writes - if we need to do large writes this will need to be
> - * revised.
> - */
> -static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
> -				   int bytes, void *src)
> -{
> -	struct i2c_client *i2c = wm831x->control_data;
> -	unsigned char msg[bytes + 2];
> -	int ret;
> -
> -	reg = cpu_to_be16(reg);
> -	memcpy(&msg[0], &reg, 2);
> -	memcpy(&msg[2], src, bytes);
> -
> -	ret = i2c_master_send(i2c, msg, bytes + 2);
> -	if (ret < 0)
> -		return ret;
> -	if (ret < bytes + 2)
> -		return -EIO;
> -
> -	return 0;
> -}
> -
> -static int wm831x_i2c_probe(struct i2c_client *i2c,
> -			    const struct i2c_device_id *id)
> -{
> -	struct wm831x *wm831x;
> -
> -	wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
> -	if (wm831x == NULL)
> -		return -ENOMEM;
> -
> -	i2c_set_clientdata(i2c, wm831x);
> -	wm831x->dev = &i2c->dev;
> -	wm831x->control_data = i2c;
> -	wm831x->read_dev = wm831x_i2c_read_device;
> -	wm831x->write_dev = wm831x_i2c_write_device;
> -
> -	return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
> -}
> -
> -static int wm831x_i2c_remove(struct i2c_client *i2c)
> -{
> -	struct wm831x *wm831x = i2c_get_clientdata(i2c);
> -
> -	wm831x_device_exit(wm831x);
> -
> -	return 0;
> -}
> -
> -static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
> -{
> -	struct wm831x *wm831x = i2c_get_clientdata(i2c);
> -
> -	return wm831x_device_suspend(wm831x);
> -}
> -
> -static const struct i2c_device_id wm831x_i2c_id[] = {
> -	{ "wm8310", WM8310 },
> -	{ "wm8311", WM8311 },
> -	{ "wm8312", WM8312 },
> -	{ "wm8320", WM8320 },
> -	{ "wm8321", WM8321 },
> -	{ "wm8325", WM8325 },
> -	{ }
> -};
> -MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
> -
> -
> -static struct i2c_driver wm831x_i2c_driver = {
> -	.driver = {
> -		   .name = "wm831x",
> -		   .owner = THIS_MODULE,
> -	},
> -	.probe = wm831x_i2c_probe,
> -	.remove = wm831x_i2c_remove,
> -	.suspend = wm831x_i2c_suspend,
> -	.id_table = wm831x_i2c_id,
> -};
> -
> -static int __init wm831x_i2c_init(void)
> -{
> -	int ret;
> -
> -	ret = i2c_add_driver(&wm831x_i2c_driver);
> -	if (ret != 0)
> -		pr_err("Failed to register wm831x I2C driver: %d\n", ret);
> -
> -	return ret;
> -}
> -subsys_initcall(wm831x_i2c_init);
> -
> -static void __exit wm831x_i2c_exit(void)
> -{
> -	i2c_del_driver(&wm831x_i2c_driver);
> -}
> -module_exit(wm831x_i2c_exit);
> -
> -MODULE_DESCRIPTION("I2C support for the WM831X AudioPlus PMIC");
> +MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC");
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Mark Brown");
> diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
> new file mode 100644
> index 0000000..156b198
> --- /dev/null
> +++ b/drivers/mfd/wm831x-i2c.c
> @@ -0,0 +1,143 @@
> +/*
> + * wm831x-i2c.c  --  I2C access for Wolfson WM831x PMICs
> + *
> + * Copyright 2009,2010 Wolfson Microelectronics PLC.
> + *
> + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
> + *
> + *  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 <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/i2c.h>
> +#include <linux/delay.h>
> +#include <linux/mfd/core.h>
> +#include <linux/slab.h>
> +
> +#include <linux/mfd/wm831x/core.h>
> +#include <linux/mfd/wm831x/pdata.h>
> +
> +static int wm831x_i2c_read_device(struct wm831x *wm831x, unsigned short reg,
> +				  int bytes, void *dest)
> +{
> +	struct i2c_client *i2c = wm831x->control_data;
> +	int ret;
> +	u16 r = cpu_to_be16(reg);
> +
> +	ret = i2c_master_send(i2c, (unsigned char *)&r, 2);
> +	if (ret < 0)
> +		return ret;
> +	if (ret != 2)
> +		return -EIO;
> +
> +	ret = i2c_master_recv(i2c, dest, bytes);
> +	if (ret < 0)
> +		return ret;
> +	if (ret != bytes)
> +		return -EIO;
> +	return 0;
> +}
> +
> +/* Currently we allocate the write buffer on the stack; this is OK for
> + * small writes - if we need to do large writes this will need to be
> + * revised.
> + */
> +static int wm831x_i2c_write_device(struct wm831x *wm831x, unsigned short reg,
> +				   int bytes, void *src)
> +{
> +	struct i2c_client *i2c = wm831x->control_data;
> +	unsigned char msg[bytes + 2];
> +	int ret;
> +
> +	reg = cpu_to_be16(reg);
> +	memcpy(&msg[0], &reg, 2);
> +	memcpy(&msg[2], src, bytes);
> +
> +	ret = i2c_master_send(i2c, msg, bytes + 2);
> +	if (ret < 0)
> +		return ret;
> +	if (ret < bytes + 2)
> +		return -EIO;
> +
> +	return 0;
> +}
> +
> +static int wm831x_i2c_probe(struct i2c_client *i2c,
> +			    const struct i2c_device_id *id)
> +{
> +	struct wm831x *wm831x;
> +
> +	wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
> +	if (wm831x == NULL)
> +		return -ENOMEM;
> +
> +	i2c_set_clientdata(i2c, wm831x);
> +	wm831x->dev = &i2c->dev;
> +	wm831x->control_data = i2c;
> +	wm831x->read_dev = wm831x_i2c_read_device;
> +	wm831x->write_dev = wm831x_i2c_write_device;
> +
> +	return wm831x_device_init(wm831x, id->driver_data, i2c->irq);
> +}
> +
> +static int wm831x_i2c_remove(struct i2c_client *i2c)
> +{
> +	struct wm831x *wm831x = i2c_get_clientdata(i2c);
> +
> +	wm831x_device_exit(wm831x);
> +
> +	return 0;
> +}
> +
> +static int wm831x_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
> +{
> +	struct wm831x *wm831x = i2c_get_clientdata(i2c);
> +
> +	return wm831x_device_suspend(wm831x);
> +}
> +
> +static const struct i2c_device_id wm831x_i2c_id[] = {
> +	{ "wm8310", WM8310 },
> +	{ "wm8311", WM8311 },
> +	{ "wm8312", WM8312 },
> +	{ "wm8320", WM8320 },
> +	{ "wm8321", WM8321 },
> +	{ "wm8325", WM8325 },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id);
> +
> +
> +static struct i2c_driver wm831x_i2c_driver = {
> +	.driver = {
> +		   .name = "wm831x",
> +		   .owner = THIS_MODULE,
> +	},
> +	.probe = wm831x_i2c_probe,
> +	.remove = wm831x_i2c_remove,
> +	.suspend = wm831x_i2c_suspend,
> +	.id_table = wm831x_i2c_id,
> +};
> +
> +static int __init wm831x_i2c_init(void)
> +{
> +	int ret;
> +
> +	ret = i2c_add_driver(&wm831x_i2c_driver);
> +	if (ret != 0)
> +		pr_err("Failed to register wm831x I2C driver: %d\n", ret);
> +
> +	return ret;
> +}
> +subsys_initcall(wm831x_i2c_init);
> +
> +static void __exit wm831x_i2c_exit(void)
> +{
> +	i2c_del_driver(&wm831x_i2c_driver);
> +}
> +module_exit(wm831x_i2c_exit);
> diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h
> index eb5bd4e..a1239c4 100644
> --- a/include/linux/mfd/wm831x/core.h
> +++ b/include/linux/mfd/wm831x/core.h
> @@ -238,6 +238,15 @@ struct regulator_dev;
>  
>  #define WM831X_NUM_IRQ_REGS 5
>  
> +enum wm831x_parent {
> +	WM8310 = 0x8310,
> +	WM8311 = 0x8311,
> +	WM8312 = 0x8312,
> +	WM8320 = 0x8320,
> +	WM8321 = 0x8321,
> +	WM8325 = 0x8325,
> +};
> +
>  struct wm831x {
>  	struct mutex io_lock;
>  
> @@ -285,6 +294,9 @@ int wm831x_set_bits(struct wm831x *wm831x, unsigned short reg,
>  int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg,
>  		     int count, u16 *buf);
>  
> +int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq);
> +void wm831x_device_exit(struct wm831x *wm831x);
> +int wm831x_device_suspend(struct wm831x *wm831x);
>  int wm831x_irq_init(struct wm831x *wm831x, int irq);
>  void wm831x_irq_exit(struct wm831x *wm831x);
>  
> -- 
> 1.7.1
> 

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] mfd: Add WM831x SPI support
  2010-10-08 21:23 ` [PATCH 2/2] mfd: Add WM831x SPI support Mark Brown
@ 2010-10-19  9:44   ` Samuel Ortiz
  2010-10-19  9:53     ` Mark Brown
  0 siblings, 1 reply; 14+ messages in thread
From: Samuel Ortiz @ 2010-10-19  9:44 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, patches

Hi Mark,

On Fri, Oct 08, 2010 at 02:23:23PM -0700, Mark Brown wrote:
> Implement support for controlling WM831x and WM832x devices using SPI.
Patch applied, many thanks.

Cheers,
Samuel.


> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
> 
> Resending as my finger macro sent these to the ALSA list.
> 
>  drivers/mfd/Kconfig      |   10 ++
>  drivers/mfd/Makefile     |    1 +
>  drivers/mfd/wm831x-spi.c |  232 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 243 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/mfd/wm831x-spi.c
> 
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 608a277..40aa2e8 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -328,6 +328,16 @@ config MFD_WM831X_I2C
>  	  for accessing the device, additional drivers must be enabled in
>  	  order to use the functionality of the device.
>  
> +config MFD_WM831X_SPI
> +	bool "Support Wolfson Microelectronics WM831x/2x PMICs with SPI"
> +	select MFD_CORE
> +	depends on SPI_MASTER && GENERIC_HARDIRQS
> +	help
> +	  Support for the Wolfson Microelecronics WM831x and WM832x PMICs
> +	  when controlled using SPI.  This driver provides common support
> +	  for accessing the device, additional drivers must be enabled in
> +	  order to use the functionality of the device.
> +
>  config MFD_WM8350
>  	bool
>  	depends on GENERIC_HARDIRQS
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index c9ef41b..f54b365 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -25,6 +25,7 @@ obj-$(CONFIG_MFD_WM8400)	+= wm8400-core.o
>  wm831x-objs			:= wm831x-core.o wm831x-irq.o wm831x-otp.o
>  obj-$(CONFIG_MFD_WM831X)	+= wm831x.o
>  obj-$(CONFIG_MFD_WM831X_I2C)	+= wm831x-i2c.o
> +obj-$(CONFIG_MFD_WM831X_SPI)	+= wm831x-spi.o
>  wm8350-objs			:= wm8350-core.o wm8350-regmap.o wm8350-gpio.o
>  wm8350-objs			+= wm8350-irq.o
>  obj-$(CONFIG_MFD_WM8350)	+= wm8350.o
> diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
> new file mode 100644
> index 0000000..073d4c6
> --- /dev/null
> +++ b/drivers/mfd/wm831x-spi.c
> @@ -0,0 +1,232 @@
> +/*
> + * wm831x-spi.c  --  SPI access for Wolfson WM831x PMICs
> + *
> + * Copyright 2009,2010 Wolfson Microelectronics PLC.
> + *
> + * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
> + *
> + *  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 <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/spi/spi.h>
> +
> +#include <linux/mfd/wm831x/core.h>
> +
> +static int wm831x_spi_read_device(struct wm831x *wm831x, unsigned short reg,
> +				  int bytes, void *dest)
> +{
> +	u16 tx_val;
> +	u16 *d = dest;
> +	int r, ret;
> +
> +	/* Go register at a time */
> +	for (r = reg; r < reg + (bytes / 2); r++) {
> +		tx_val = r | 0x8000;
> +
> +		ret = spi_write_then_read(wm831x->control_data,
> +					  (u8 *)&tx_val, 2, (u8 *)d, 2);
> +		if (ret != 0)
> +			return ret;
> +
> +		*d = be16_to_cpu(*d);
> +
> +		d++;
> +	}
> +
> +	return 0;
> +}
> +
> +static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
> +				   int bytes, void *src)
> +{
> +	struct spi_device *spi = wm831x->control_data;
> +	u16 *s = src;
> +	u16 data[2];
> +	int ret;
> +
> +	/* Go register at a time */
> +	for (r = reg; r < reg + (bytes / 2); r++) {
> +		data[0] = r;
> +		data[1] = *s++;
> +
> +		ret = spi_write(spi, (char *)&data, sizeof(data));
> +		if (ret != 0)
> +			return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static int __devinit wm831x_spi_probe(struct spi_device *spi)
> +{
> +	struct wm831x *wm831x;
> +	enum wm831x_parent type;
> +
> +	/* Currently SPI support for ID tables is unmerged, we're faking it */
> +	if (strcmp(spi->modalias, "wm8310") == 0)
> +		type = WM8310;
> +	else if (strcmp(spi->modalias, "wm8311") == 0)
> +		type = WM8311;
> +	else if (strcmp(spi->modalias, "wm8312") == 0)
> +		type = WM8312;
> +	else if (strcmp(spi->modalias, "wm8320") == 0)
> +		type = WM8320;
> +	else if (strcmp(spi->modalias, "wm8321") == 0)
> +		type = WM8321;
> +	else if (strcmp(spi->modalias, "wm8325") == 0)
> +		type = WM8325;
> +	else {
> +		dev_err(&spi->dev, "Unknown device type\n");
> +		return -EINVAL;
> +	}
> +
> +	wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
> +	if (wm831x == NULL)
> +		return -ENOMEM;
> +
> +	spi->bits_per_word = 16;
> +	spi->mode = SPI_MODE_0;
> +
> +	dev_set_drvdata(&spi->dev, wm831x);
> +	wm831x->dev = &spi->dev;
> +	wm831x->control_data = spi;
> +	wm831x->read_dev = wm831x_spi_read_device;
> +	wm831x->write_dev = wm831x_spi_write_device;
> +
> +	return wm831x_device_init(wm831x, type, spi->irq);
> +}
> +
> +static int __devexit wm831x_spi_remove(struct spi_device *spi)
> +{
> +	struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
> +
> +	wm831x_device_exit(wm831x);
> +
> +	return 0;
> +}
> +
> +static int wm831x_spi_suspend(struct spi_device *spi, pm_message_t m)
> +{
> +	struct wm831x *wm831x = dev_get_drvdata(&spi->dev);
> +
> +	return wm831x_device_suspend(wm831x);
> +}
> +
> +static struct spi_driver wm8310_spi_driver = {
> +	.driver = {
> +		.name	= "wm8310",
> +		.bus	= &spi_bus_type,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= wm831x_spi_probe,
> +	.remove		= __devexit_p(wm831x_spi_remove),
> +	.suspend	= wm831x_spi_suspend,
> +};
> +
> +static struct spi_driver wm8311_spi_driver = {
> +	.driver = {
> +		.name	= "wm8311",
> +		.bus	= &spi_bus_type,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= wm831x_spi_probe,
> +	.remove		= __devexit_p(wm831x_spi_remove),
> +	.suspend	= wm831x_spi_suspend,
> +};
> +
> +static struct spi_driver wm8312_spi_driver = {
> +	.driver = {
> +		.name	= "wm8312",
> +		.bus	= &spi_bus_type,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= wm831x_spi_probe,
> +	.remove		= __devexit_p(wm831x_spi_remove),
> +	.suspend	= wm831x_spi_suspend,
> +};
> +
> +static struct spi_driver wm8320_spi_driver = {
> +	.driver = {
> +		.name	= "wm8320",
> +		.bus	= &spi_bus_type,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= wm831x_spi_probe,
> +	.remove		= __devexit_p(wm831x_spi_remove),
> +	.suspend	= wm831x_spi_suspend,
> +};
> +
> +static struct spi_driver wm8321_spi_driver = {
> +	.driver = {
> +		.name	= "wm8321",
> +		.bus	= &spi_bus_type,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= wm831x_spi_probe,
> +	.remove		= __devexit_p(wm831x_spi_remove),
> +	.suspend	= wm831x_spi_suspend,
> +};
> +
> +static struct spi_driver wm8325_spi_driver = {
> +	.driver = {
> +		.name	= "wm8325",
> +		.bus	= &spi_bus_type,
> +		.owner	= THIS_MODULE,
> +	},
> +	.probe		= wm831x_spi_probe,
> +	.remove		= __devexit_p(wm831x_spi_remove),
> +	.suspend	= wm831x_spi_suspend,
> +};
> +
> +static int __init wm831x_spi_init(void)
> +{
> +	int ret;
> +
> +	ret = spi_register_driver(&wm8310_spi_driver);
> +	if (ret != 0)
> +		pr_err("Failed to register WM8310 SPI driver: %d\n", ret);
> +
> +	ret = spi_register_driver(&wm8311_spi_driver);
> +	if (ret != 0)
> +		pr_err("Failed to register WM8311 SPI driver: %d\n", ret);
> +
> +	ret = spi_register_driver(&wm8312_spi_driver);
> +	if (ret != 0)
> +		pr_err("Failed to register WM8312 SPI driver: %d\n", ret);
> +
> +	ret = spi_register_driver(&wm8320_spi_driver);
> +	if (ret != 0)
> +		pr_err("Failed to register WM8320 SPI driver: %d\n", ret);
> +
> +	ret = spi_register_driver(&wm8321_spi_driver);
> +	if (ret != 0)
> +		pr_err("Failed to register WM8321 SPI driver: %d\n", ret);
> +
> +	ret = spi_register_driver(&wm8325_spi_driver);
> +	if (ret != 0)
> +		pr_err("Failed to register WM8325 SPI driver: %d\n", ret);
> +
> +	return 0;
> +}
> +subsys_initcall(wm831x_spi_init);
> +
> +static void __exit wm831x_spi_exit(void)
> +{
> +	spi_unregister_driver(&wm8325_spi_driver);
> +	spi_unregister_driver(&wm8321_spi_driver);
> +	spi_unregister_driver(&wm8320_spi_driver);
> +	spi_unregister_driver(&wm8312_spi_driver);
> +	spi_unregister_driver(&wm8311_spi_driver);
> +	spi_unregister_driver(&wm8310_spi_driver);
> +}
> +module_exit(wm831x_spi_exit);
> +
> +MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs");
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Mark Brown");
> -- 
> 1.7.1
> 

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] mfd: Add WM831x SPI support
  2010-10-19  9:44   ` Samuel Ortiz
@ 2010-10-19  9:53     ` Mark Brown
  2010-10-19 10:52       ` Samuel Ortiz
  0 siblings, 1 reply; 14+ messages in thread
From: Mark Brown @ 2010-10-19  9:53 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, patches

On Tue, Oct 19, 2010 at 11:44:23AM +0200, Samuel Ortiz wrote:

> > +static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
> > +				   int bytes, void *src)
> > +{
> > +	struct spi_device *spi = wm831x->control_data;
> > +	u16 *s = src;
> > +	u16 data[2];
> > +	int ret;
> > +
> > +	/* Go register at a time */
> > +	for (r = reg; r < reg + (bytes / 2); r++) {
> > +		data[0] = r;

Oh, gah.  We need an extra int r here, I've obviously stuffed up the
move from the BSP I was working on.  Sorry about that:

>From b7fc0d8ff8c96fabf531d685bda7c3d5b8c51f35 Mon Sep 17 00:00:00 2001
From: Mark Brown <broonie@opensource.wolfsonmicro.com>
Date: Tue, 19 Oct 2010 02:53:08 -0700
Subject: [PATCH] mfd: Fix missing variable in WM831x SPI

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
---
 drivers/mfd/wm831x-spi.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 073d4c6..2789b15 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -48,7 +48,7 @@ static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
 	struct spi_device *spi = wm831x->control_data;
 	u16 *s = src;
 	u16 data[2];
-	int ret;
+	int ret, r;
 
 	/* Go register at a time */
 	for (r = reg; r < reg + (bytes / 2); r++) {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 2/2] mfd: Add WM831x SPI support
  2010-10-19  9:53     ` Mark Brown
@ 2010-10-19 10:52       ` Samuel Ortiz
  0 siblings, 0 replies; 14+ messages in thread
From: Samuel Ortiz @ 2010-10-19 10:52 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, patches

Hi Mark,

On Tue, Oct 19, 2010 at 02:53:54AM -0700, Mark Brown wrote:
> On Tue, Oct 19, 2010 at 11:44:23AM +0200, Samuel Ortiz wrote:
> 
> > > +static int wm831x_spi_write_device(struct wm831x *wm831x, unsigned short reg,
> > > +				   int bytes, void *src)
> > > +{
> > > +	struct spi_device *spi = wm831x->control_data;
> > > +	u16 *s = src;
> > > +	u16 data[2];
> > > +	int ret;
> > > +
> > > +	/* Go register at a time */
> > > +	for (r = reg; r < reg + (bytes / 2); r++) {
> > > +		data[0] = r;
> 
> Oh, gah.  We need an extra int r here, I've obviously stuffed up the
> move from the BSP I was working on.  Sorry about that:
No problem, I didn't see it as I haven't build my tree yet.
I squashed this fix into the initial patch.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
  2010-10-08 21:23 [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver Mark Brown
  2010-10-08 21:23 ` [PATCH 2/2] mfd: Add WM831x SPI support Mark Brown
  2010-10-19  9:43 ` [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver Samuel Ortiz
@ 2010-10-19 11:15 ` Samuel Ortiz
  2010-10-19 15:14   ` Mark Brown
  2 siblings, 1 reply; 14+ messages in thread
From: Samuel Ortiz @ 2010-10-19 11:15 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, patches

Hi Mark,

On Fri, Oct 08, 2010 at 02:23:22PM -0700, Mark Brown wrote:
> diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
> index 1e4d78a..546db5c 100644
> --- a/arch/arm/mach-s3c64xx/Kconfig
> +++ b/arch/arm/mach-s3c64xx/Kconfig
> @@ -185,6 +185,7 @@ config SMDK6410_WM1192_EV1
>  	select REGULATOR_WM831X
>  	select S3C24XX_GPIO_EXTRA64
>  	select MFD_WM831X
> +	select MFD_WM831X_I2C
>  	help
>  	  The Wolfson Microelectronics 1192-EV1 is a WM831x based PMIC
>  	  daughtercard for the Samsung SMDK6410 reference platform.
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index 6c6b9f0..608a277 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -315,14 +315,18 @@ config MFD_WM8400
>  	  the functionality of the device.
>  
>  config MFD_WM831X
> -	bool "Support Wolfson Microelectronics WM831x/2x PMICs"
> +	bool
> +	depends on GENERIC_HARDIRQS
> +
> +config MFD_WM831X_I2C
> +	bool "Support Wolfson Microelectronics WM831x/2x PMICs with I2C"
>  	select MFD_CORE
I think we should select MFD_WM831X here as well otherwise there's nothing
preventing us from building the I2C or the SPI part without the core one. And
that leads to a build breakage.

Cheers,
Samuel.

-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
  2010-10-19 11:15 ` Samuel Ortiz
@ 2010-10-19 15:14   ` Mark Brown
  2010-10-19 15:27     ` Samuel Ortiz
  0 siblings, 1 reply; 14+ messages in thread
From: Mark Brown @ 2010-10-19 15:14 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, patches

On Tue, Oct 19, 2010 at 01:15:54PM +0200, Samuel Ortiz wrote:

> I think we should select MFD_WM831X here as well otherwise there's nothing
> preventing us from building the I2C or the SPI part without the core one. And
> that leads to a build breakage.

I agree, I'll try to send a followup out unless you update the patch
before I get to it.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
  2010-10-19 15:14   ` Mark Brown
@ 2010-10-19 15:27     ` Samuel Ortiz
  2010-10-19 17:51       ` Mark Brown
  0 siblings, 1 reply; 14+ messages in thread
From: Samuel Ortiz @ 2010-10-19 15:27 UTC (permalink / raw)
  To: Mark Brown; +Cc: linux-kernel, patches

On Tue, Oct 19, 2010 at 08:14:16AM -0700, Mark Brown wrote:
> On Tue, Oct 19, 2010 at 01:15:54PM +0200, Samuel Ortiz wrote:
> 
> > I think we should select MFD_WM831X here as well otherwise there's nothing
> > preventing us from building the I2C or the SPI part without the core one. And
> > that leads to a build breakage.
> 
> I agree, I'll try to send a followup out unless you update the patch
> before I get to it.
I'll update the patch.

Cheers,
Samuel.


-- 
Intel Open Source Technology Centre
http://oss.intel.com/

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver
  2010-10-19 15:27     ` Samuel Ortiz
@ 2010-10-19 17:51       ` Mark Brown
  0 siblings, 0 replies; 14+ messages in thread
From: Mark Brown @ 2010-10-19 17:51 UTC (permalink / raw)
  To: Samuel Ortiz; +Cc: linux-kernel, patches

On Tue, Oct 19, 2010 at 05:27:57PM +0200, Samuel Ortiz wrote:

> I'll update the patch.

Thanks!

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2010-10-19 17:51 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-08 21:23 [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver Mark Brown
2010-10-08 21:23 ` [PATCH 2/2] mfd: Add WM831x SPI support Mark Brown
2010-10-19  9:44   ` Samuel Ortiz
2010-10-19  9:53     ` Mark Brown
2010-10-19 10:52       ` Samuel Ortiz
2010-10-19  9:43 ` [PATCH 1/2] mfd: Factor out WM831x I2C I/O from the core driver Samuel Ortiz
2010-10-19 11:15 ` Samuel Ortiz
2010-10-19 15:14   ` Mark Brown
2010-10-19 15:27     ` Samuel Ortiz
2010-10-19 17:51       ` Mark Brown
  -- strict thread matches above, loose matches on Subject: below --
2010-10-08 16:52 Mark Brown
2010-10-08 18:57 ` Stefan Schmidt
2010-10-08 18:58   ` Mark Brown
2010-10-19  9:38 ` Samuel Ortiz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox