diff options
author | Laura Lawrence <Laura.Lawrence@freescale.com> | 2008-01-22 15:30:16 -0600 |
---|---|---|
committer | Daniel Schaeffer <daniel.schaeffer@timesys.com> | 2008-08-25 15:20:36 -0400 |
commit | d61adf321a13a299a644748a3148d8c350df20ca (patch) | |
tree | cde7b33d63eb0f2123c740d69232e37ff5a0140a /drivers | |
parent | 8e90502ae2a59747f9d044206577803c9a1dac90 (diff) |
ENGR00060848 Add imx37 audio playback support
imx37 driver based on ASoC + Wolfson WM8350 AudioPlus support
http://opensource.wolfsonmicro.com/node/8
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pmic/Makefile | 5 | ||||
-rw-r--r-- | drivers/pmic/pmic-wm8350-i2c.c | 167 |
2 files changed, 170 insertions, 2 deletions
diff --git a/drivers/pmic/Makefile b/drivers/pmic/Makefile index 9b556e115b45..cab9157a938a 100644 --- a/drivers/pmic/Makefile +++ b/drivers/pmic/Makefile @@ -3,11 +3,12 @@ # ifeq ($(CONFIG_PMIC_DEBUG),y) - EXTRA_CFLAGS += -DDEBUG + EXTRA_CFLAGS += -DDEBUG endif obj-$(CONFIG_PMIC) += pmic.o obj-$(CONFIG_PMIC_WM8350) += \ - pmic-wm8350.o pmic-wm8350-bus.o + pmic-wm8350.o pmic-wm8350-bus.o pmic-wm8350-i2c.o + diff --git a/drivers/pmic/pmic-wm8350-i2c.c b/drivers/pmic/pmic-wm8350-i2c.c new file mode 100644 index 000000000000..9851c159a38f --- /dev/null +++ b/drivers/pmic/pmic-wm8350-i2c.c @@ -0,0 +1,167 @@ +#include <linux/module.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <linux/pm.h> +#include <linux/bitops.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/err.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/leds.h> +#include <linux/fb.h> +#include <linux/pmic.h> +#include <linux/pmic/wm8350.h> + +#define WM8350_I2C_ADDR (0x34 >> 1) + +extern void wm8350_free(struct wm8350 *wm8350); +extern int wm8350_init(struct wm8350* wm8350); + + +static int wm8350_i2c_detach(struct i2c_client *client); + +void wm8350_irq_work(struct work_struct *work) +{ + wm8350_irq_worker(work); +} + +irqreturn_t wm8350_irq_handler(int irq, void *data) +{ + struct wm8350 *wm8350 = (struct wm8350*)data; + schedule_work(&wm8350->work); + return IRQ_HANDLED; +} + +/* + * WM8350 2 wire address + */ +static unsigned short normal_i2c[] = { WM8350_I2C_ADDR, I2C_CLIENT_END }; + +/* Magic definition of all other variables and things */ +I2C_CLIENT_INSMOD; + +static int wm8350_pmic_i2c_detect(struct i2c_adapter *adap, int addr, int kind) +{ + struct wm8350* wm8350; + struct i2c_client *i2c; + int ret = 0; + + if (addr != WM8350_I2C_ADDR) + return -ENODEV; + + i2c = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); + if (i2c == NULL) + return -ENOMEM; + + wm8350 = kzalloc(sizeof(struct wm8350), GFP_KERNEL); + if (wm8350 == NULL) { + kfree(i2c); + return -ENOMEM; + } + + i2c->addr = addr; + i2c->adapter = adap; + + mutex_init(&wm8350->work_mutex); + i2c_set_clientdata(i2c, wm8350); + wm8350->i2c_client = i2c; + wm8350_set_io(wm8350, WM8350_IO_I2C, NULL, NULL); + + ret = i2c_attach_client(i2c); + if (ret < 0) { + printk(KERN_ERR "wm8350: failed to attach device at addr 0x%x\n", addr); + goto err; + } + + ret = wm8350_create_cache(wm8350); + if (ret < 0) { + printk(KERN_ERR "wm8350: failed to create register cache\n"); + goto err; + } + + if (wm8350_reg_read(wm8350, 0) == 0x0) + printk("wm8350: found Rev C device\n"); + else if (wm8350_reg_read(wm8350, 0) == 0x6143) + printk("wm8350: found Rev E device\n"); + else { + printk(KERN_ERR "wm8350: device is not a WM8350\n"); + ret = -ENODEV; + goto err; + } + + ret = wm8350_init(wm8350); + if (ret == 0) + return ret; + +err: + wm8350_i2c_detach(i2c); + return ret; +} + +static int wm8350_i2c_attach(struct i2c_adapter *adap) +{ + return i2c_probe(adap, &addr_data, wm8350_pmic_i2c_detect); +} + +static int wm8350_i2c_detach(struct i2c_client *client) +{ + struct wm8350 *wm8350 = i2c_get_clientdata(client); + + wm8350_free(wm8350); + i2c_detach_client(client); + kfree(client); + if (wm8350->reg_cache) + kfree(wm8350->reg_cache); + kfree(wm8350); + + return 0; +} + +#ifdef CONFIG_PM +static int wm8350_i2c_suspend(struct i2c_client *client, pm_message_t state) +{ + int ret = 0; + return ret; +} + +static int wm8350_i2c_resume(struct i2c_client *client) +{ + int ret = 0; + return ret; +} + +#else +#define wm8350_i2c_suspend NULL +#define wm8350_i2c_resume NULL +#endif + +static struct i2c_driver wm8350_i2c_driver = { + .driver = { + .name = "WM8350", + }, + .attach_adapter = wm8350_i2c_attach, + .detach_client = wm8350_i2c_detach, + .suspend = wm8350_i2c_suspend, + .resume = wm8350_i2c_resume, + .command = NULL, +}; + + +static int __init wm8350_pmic_init(void) +{ + return i2c_add_driver(&wm8350_i2c_driver); +} + +static void __exit wm8350_pmic_exit(void) +{ + i2c_del_driver(&wm8350_i2c_driver); +} + +module_init(wm8350_pmic_init); +module_exit(wm8350_pmic_exit); + +MODULE_AUTHOR("Liam Girdwood"); +MODULE_DESCRIPTION("PMIC WM8350 Driver"); +MODULE_LICENSE("GPL"); + |