From: Matt Hsu <matt_hsu@openmoko.org>
Date: Wed, 11 Feb 2009 23:11:32 +0800

Add support of dummy_wm8753 driver on gta03.

Signed-off-by: Matt Hsu <matt_hsu@openmoko.org>
---
 arch/arm/mach-s3c6410/mach-om-gta03.c |    5 +-
 drivers/i2c/chips/Kconfig             |    8 ++
 drivers/i2c/chips/Makefile            |    1 +
 drivers/i2c/chips/dummy_wm8753.c      |  171 +++++++++++++++++++++++++++++++++
 4 files changed, 184 insertions(+), 1 deletions(-)
 create mode 100644 drivers/i2c/chips/dummy_wm8753.c

diff --git a/arch/arm/mach-s3c6410/mach-om-gta03.c b/arch/arm/mach-s3c6410/mach-om-gta03.c
index 413a823..4cfcd65 100644
--- a/arch/arm/mach-s3c6410/mach-om-gta03.c
+++ b/arch/arm/mach-s3c6410/mach-om-gta03.c
@@ -489,6 +489,7 @@ struct pcf50633_platform_data om_gta03_pcf_pdata = {
 				.max_uV = 3300000,
 				.valid_modes_mask = REGULATOR_MODE_NORMAL,
 				.apply_uV = 1,
+				.always_on = 1,
 			},
 			.num_consumer_supplies = 0,
 		},
@@ -570,7 +571,9 @@ static struct i2c_board_info om_gta03_i2c_devs[] __initdata = {
 		.irq = GTA03_IRQ_LED,
 		.platform_data = &om_gta03_lp5521_pdata,
 	},
-
+	{
+		I2C_BOARD_INFO("dummy_wm8753", 0x1a),
+	},
 };
 
 struct platform_device gta03_device_spi_lcm;
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index cc025b2..d2e9554 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -159,4 +159,12 @@ config PCA9632
 	  This driver can also be built as a module.  If so, the module
 	  will be called pca9632.
 
+config DUMMY_WM8753
+	tristate "dummy wm8753 driver"
+	depends on I2C
+	help
+	  If you say yes here you get support for the fake WM8753 audio codec driver.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called dummy_8753.
 endmenu
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index a575282..4fbc4b9 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_PCF8575)		+= pcf8575.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
 obj-$(CONFIG_SENSORS_TSL2550)	+= tsl2550.o
 obj-$(CONFIG_PCA9632)		+= pca9632.o
+obj-$(CONFIG_DUMMY_WM8753)	+= dummy_wm8753.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
 EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/chips/dummy_wm8753.c b/drivers/i2c/chips/dummy_wm8753.c
new file mode 100644
index 0000000..4baaf82
--- /dev/null
+++ b/drivers/i2c/chips/dummy_wm8753.c
@@ -0,0 +1,171 @@
+/*
+ * Dummy wm8753 driver.
+ *
+ * Copyright(c) 2008 Openmoko Inc.
+ *
+ * Author: Matt Hsu <matt_hsu@openmoko.org>
+ *
+ * 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/device.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+
+#define WM8753_RESET 	0x1f
+#define CODEC_NAME 	"WM8753"
+
+struct dummy_wm8753_data{
+	struct i2c_client *client;
+};
+
+static struct i2c_driver dummy_wm8753_driver;
+
+static u16 wm8753_reg[] = {
+	0x0008, 0x0000, 0x000a, 0x000a,
+	0x0033, 0x0000, 0x0007, 0x00ff,
+	0x00ff, 0x000f, 0x000f, 0x007b,
+	0x0000, 0x0032, 0x0000, 0x00c3,
+	0x00c3, 0x00c0, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0000, 0x0000, 0x0000, 0x0055,
+	0x0005, 0x0050, 0x0055, 0x0050,
+	0x0055, 0x0050, 0x0055, 0x0079,
+	0x0079, 0x0079, 0x0079, 0x0079,
+	0x0000, 0x0000, 0x0000, 0x0000,
+	0x0097, 0x0097, 0x0000, 0x0004,
+	0x0000, 0x0083, 0x0024, 0x01ba,
+	0x0000, 0x0083, 0x0024, 0x01ba,
+	0x0000, 0x0000
+};
+
+static int wm8753_write(struct dummy_wm8753_data *wm8753, 
+				unsigned int reg, unsigned int value)
+{
+	u8 data[2];
+
+	/* data is
+	 *   D15..D9 WM8753 register offset
+	 *   D8...D0 register data
+	 */
+	data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+	data[1] = value & 0x00ff;
+
+	wm8753_reg[reg] = value;
+	if (i2c_master_send(wm8753->client, data, 2) == 2)
+		return 0;
+	else
+		return -EIO;
+}
+
+static ssize_t codec_reg_write(struct device *dev, 
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct dummy_wm8753_data *wm8753 = i2c_get_clientdata(client);
+	char *start = buf;
+	unsigned long value, reg;
+
+	reg = simple_strtoul(start, &start, 16);
+
+	while (*start == ' ')
+		start++;
+
+	strict_strtoul(start, 16, &value);
+	wm8753_reg[reg] = value;
+
+	return count;
+}
+
+static ssize_t codec_reg_read(struct device *dev, struct device_attribute *attr,
+			   const char *buf)
+{
+	unsigned int i;
+	int count = 0;
+
+	count += sprintf(buf, "%s registers\n", CODEC_NAME);
+
+	for (i = 0; i < 0x3e; i++) {
+		count += sprintf(buf + count, "%2x:", i);
+		count += sprintf(buf + count, "%4x \n", wm8753_reg[i]);
+	}
+
+	return count;
+}
+
+static DEVICE_ATTR(codec_reg, S_IRUGO | S_IWUSR, codec_reg_read, codec_reg_write);
+
+static int
+dummy_wm8753_probe(struct i2c_client *client, const struct i2c_device_id *ids)
+{
+	struct dummy_wm8753_data *wm8753;
+	int ret;
+
+	wm8753 = kzalloc(sizeof(struct dummy_wm8753_data), GFP_KERNEL);
+	if (!wm8753)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, wm8753);
+	wm8753->client = client;
+
+	ret = sysfs_create_file(&client->dev.kobj, &dev_attr_codec_reg.attr);
+
+	dev_dbg(&wm8753->client->dev, "entering \n");
+
+	if (ret) {
+		dev_err(&client->dev, "Failed to create sysfs\n");
+		goto exit_kfree;
+	}
+
+	/* reset codec */
+	wm8753_write(wm8753, WM8753_RESET, 0);
+
+	return 0;
+
+exit_kfree:
+	kfree(wm8753);
+	return ret;
+}
+
+static int dummy_wm8753_remove(struct i2c_client *client)
+{
+	struct dummy_wm8753_data *wm8753 = i2c_get_clientdata(client);
+	kfree(wm8753);
+	return 0;
+}
+
+static struct i2c_device_id dummy_wm8753_id_table[] = {
+	{"dummy_wm8753", 0x1a},
+};
+
+static struct i2c_driver dummy_wm8753_driver = {
+	.driver = {
+		.name	 = "dummy_wm8753",
+	},
+	.id_table	= dummy_wm8753_id_table,
+	.probe 		= dummy_wm8753_probe,
+	.remove 	= dummy_wm8753_remove,
+};
+
+
+static int __init dummy_wm8753_init(void)
+{
+	return i2c_add_driver(&dummy_wm8753_driver);
+}
+
+static void dummy_wm8753_exit(void)
+{
+	i2c_del_driver(&dummy_wm8753_driver);
+}
+module_init(dummy_wm8753_init);
+module_exit(dummy_wm8753_exit);
+
+MODULE_AUTHOR("Matt Hsu <matt_hsu@openmoko.org>");
+MODULE_LICENSE("GPLv2");
-- 
1.5.6.5

