phonesdk: update wm8994 device
author邱建斌 <qjb@rock-chips.com>
Thu, 1 Dec 2011 02:49:43 +0000 (10:49 +0800)
committer邱建斌 <qjb@rock-chips.com>
Thu, 1 Dec 2011 02:49:43 +0000 (10:49 +0800)
arch/arm/mach-rk29/board-rk29-phonesdk.c
drivers/headset_observe/rk_headset.c
drivers/mfd/wm8994-core.c [changed mode: 0644->0755]
drivers/regulator/wm8994-regulator.c [changed mode: 0644->0755]
include/linux/mfd/wm8994/core.h
include/linux/mfd/wm8994/gpio.h
sound/soc/codecs/wm8994.c
sound/soc/rk29/rk29_wm8994.c

index 7ff1514f212f69eeb9406432a13755d62cee8ed9..825489336d913ec1df328ea7a663e0cc50880a1c 100755 (executable)
@@ -52,6 +52,9 @@
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/gpio.h>
 
+#include <linux/regulator/fixed.h>
+#include <linux/mfd/wm8994/pdata.h>
+
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 #include <linux/i2c-gpio.h>
@@ -1696,12 +1699,126 @@ struct platform_device rk29_device_gps = {
        };
 #endif
 
+
+/*****************************************************************************************
+ * wm8994  codec
+ * author: qjb@rock-chips.com
+ *****************************************************************************************/
+#if defined(CONFIG_MFD_WM8994)
+static struct regulator_consumer_supply wm8994_fixed_voltage0_supplies[] = {
+       REGULATOR_SUPPLY("DBVDD", "5-001a"),
+       REGULATOR_SUPPLY("AVDD2", "5-001a"),
+       REGULATOR_SUPPLY("CPVDD", "5-001a"),
+};
+
+static struct regulator_consumer_supply wm8994_fixed_voltage1_supplies[] = {
+       REGULATOR_SUPPLY("SPKVDD1", "5-001a"),
+       REGULATOR_SUPPLY("SPKVDD2", "5-001a"),
+};
+
+static struct regulator_init_data wm8994_fixed_voltage0_init_data = {
+       .constraints = {
+               .always_on = 1,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(wm8994_fixed_voltage0_supplies),
+       .consumer_supplies      = wm8994_fixed_voltage0_supplies,
+};
+
+static struct regulator_init_data wm8994_fixed_voltage1_init_data = {
+       .constraints = {
+               .always_on = 1,
+       },
+       .num_consumer_supplies  = ARRAY_SIZE(wm8994_fixed_voltage1_supplies),
+       .consumer_supplies      = wm8994_fixed_voltage1_supplies,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage0_config = {
+       .supply_name    = "VCC_1.8V_PDA",
+       .microvolts     = 1800000,
+       .gpio           = -EINVAL,
+       .init_data      = &wm8994_fixed_voltage0_init_data,
+};
+
+static struct fixed_voltage_config wm8994_fixed_voltage1_config = {
+       .supply_name    = "V_BAT",
+       .microvolts     = 3700000,
+       .gpio           = -EINVAL,
+       .init_data      = &wm8994_fixed_voltage1_init_data,
+};
+
+static struct platform_device wm8994_fixed_voltage0 = {
+       .name           = "reg-fixed-voltage",
+       .id             = 0,
+       .dev            = {
+               .platform_data  = &wm8994_fixed_voltage0_config,
+       },
+};
+
+static struct platform_device wm8994_fixed_voltage1 = {
+       .name           = "reg-fixed-voltage",
+       .id             = 1,
+       .dev            = {
+               .platform_data  = &wm8994_fixed_voltage1_config,
+       },
+};
+
+static struct regulator_consumer_supply wm8994_avdd1_supply =
+       REGULATOR_SUPPLY("AVDD1", "5-001a");
+
+static struct regulator_consumer_supply wm8994_dcvdd_supply =
+       REGULATOR_SUPPLY("DCVDD", "5-001a");
+
+
+
+static struct regulator_init_data wm8994_ldo1_data = {
+       .constraints    = {
+               .name           = "AVDD1_3.0V",
+               .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &wm8994_avdd1_supply,
+};
+
+static struct regulator_init_data wm8994_ldo2_data = {
+       .constraints    = {
+               .name           = "DCVDD_1.0V",
+       },
+       .num_consumer_supplies  = 1,
+       .consumer_supplies      = &wm8994_dcvdd_supply,
+};
+
+static struct wm8994_pdata wm8994_platform_data = {
+#if defined (CONFIG_GPIO_WM8994)       
+       .gpio_base = WM8994_GPIO_EXPANDER_BASE,
+       //Fill value to initialize the GPIO     
+       .gpio_defaults ={},
+#endif         
+       /* configure gpio1 function: 0x0001(Logic level input/output) */
+//     .gpio_defaults[0] = 0x0001,
+       /* configure gpio3/4/5/7 function for AIF2 voice */
+//     .gpio_defaults[2] = 0x8100,
+//     .gpio_defaults[3] = 0x8100,
+//     .gpio_defaults[4] = 0x8100,
+//     .gpio_defaults[6] = 0x0100,
+       /* configure gpio8/9/10/11 function for AIF3 BT */
+//     .gpio_defaults[7] = 0x8100,
+//     .gpio_defaults[8] = 0x0100,
+//     .gpio_defaults[9] = 0x0100,
+//     .gpio_defaults[10] = 0x0100,
+       .ldo[0] = { RK29_PIN5_PA1, NULL, &wm8994_ldo1_data },   /* XM0FRNB_2 */
+       .ldo[1] = { 0, NULL, &wm8994_ldo2_data },
+
+       .micdet_irq = 0,
+       .irq_base = 0,
+};
+#endif 
+
 #ifdef CONFIG_RK_HEADSET_DET
 #define HEADSET_GPIO RK29_PIN4_PD2
 struct rk_headset_pdata rk_headset_info = {
        .Headset_gpio           = RK29_PIN4_PD2,
        .headset_in_type= HEADSET_IN_HIGH,
-       .Hook_gpio = RK29_PIN4_PD1,//Detection Headset--Must be set
+//     .Hook_gpio = RK29_PIN4_PD1,//Detection Headset--Must be set
        .hook_key_code = KEY_MEDIA,
 };
 
@@ -1906,6 +2023,9 @@ static struct i2c_board_info __initdata board_i2c0_devices[] = {
                .type                   = "wm8994",
                .addr           = 0x1a,
                .flags                  = 0,
+       #if defined(CONFIG_MFD_WM8994)                  
+               .platform_data  = &wm8994_platform_data,        
+       #endif  
        },
 #endif
 #if defined (CONFIG_BATTERY_STC3100)
@@ -2963,6 +3083,11 @@ static struct platform_device *devices[] __initdata = {
        &rk29_device_i2c3,
 #endif
 
+#ifdef CONFIG_MFD_WM8994
+       &wm8994_fixed_voltage0,
+       &wm8994_fixed_voltage1,
+#endif 
+
 #ifdef CONFIG_SND_RK29_SOC_I2S_2CH
         &rk29_device_iis_2ch,
 #endif
@@ -3463,7 +3588,8 @@ static void __init machine_rk29_board_init(void)
     
        gpio_request(POWER_ON_PIN,"poweronpin");
        gpio_set_value(POWER_ON_PIN, GPIO_HIGH);
-       gpio_direction_output(POWER_ON_PIN, GPIO_HIGH);
+       gpio_direction_output(POWER_ON_PIN, GPIO_HIGH);                 
+       
        pm_power_off = rk29_pm_power_off;
        //arm_pm_restart = rk29_pm_power_restart;
 
index e5b6f6d178ac56f1cef184d9590ad93894e9fe63..ab47661ca19590affecfac8fd50b1815d285f47b 100755 (executable)
@@ -194,7 +194,7 @@ static void headsetobserve_work(struct work_struct *work)
                //      enable_irq(headset_info->irq[HOOK]);
                        headset_info->cur_headset_status = BIT_HEADSET;
                        headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);//
-                       if (pdata->Headset_gpio != NULL) {
+                       if (pdata->Hook_gpio != NULL) {
                                del_timer(&headset_info->headset_timer);//Start the timer, wait for switch to the headphone channel
                                headset_info->headset_timer.expires = jiffies + 500;
                                add_timer(&headset_info->headset_timer);
@@ -219,11 +219,11 @@ static void headsetobserve_work(struct work_struct *work)
                //      DBG("---HEADSET_IN_LOW headset in LOW ---\n");
                        headset_info->cur_headset_status = BIT_HEADSET;
                        headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);//
-                       if (pdata->Headset_gpio != NULL) {                      
+                       if (pdata->Hook_gpio != NULL) {                 
                                del_timer(&headset_info->headset_timer);//Start the timer, wait for switch to the headphone channel
                                headset_info->headset_timer.expires = jiffies + 500;
                                add_timer(&headset_info->headset_timer);
-                       }       
+                       }
                }
                else if(level > 0)
                {//out--High level
old mode 100644 (file)
new mode 100755 (executable)
index 7617bcd..89c20f0
 #include <linux/mfd/wm8994/core.h>
 #include <linux/mfd/wm8994/pdata.h>
 #include <linux/mfd/wm8994/registers.h>
-#include <mach/gpio.h>
-
-#define WM_PW_EN RK29_PIN5_PA1
 
+#if 0
+#define DBG(x...) printk(KERN_DEBUG x)
+#else
+#define DBG(x...) do { } while (0)
+#endif
 static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
                       int bytes, void *dest)
 {
@@ -46,6 +48,7 @@ static int wm8994_read(struct wm8994 *wm8994, unsigned short reg,
                dev_vdbg(wm8994->dev, "Read %04x from R%d(0x%x)\n",
                         be16_to_cpu(buf[i]), reg + i, reg + i);
        }
+
        return 0;
 }
 
@@ -65,7 +68,7 @@ int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
        ret = wm8994_read(wm8994, reg, 2, &val);
 
        mutex_unlock(&wm8994->io_lock);
-
+       DBG("%s:0x%04x = 0x%04x\n",__FUNCTION__,reg,be16_to_cpu(val));
        if (ret < 0)
                return ret;
        else
@@ -109,6 +112,7 @@ static int wm8994_write(struct wm8994 *wm8994, unsigned short reg,
                dev_vdbg(wm8994->dev, "Write %04x to R%d(0x%x)\n",
                         be16_to_cpu(buf[i]), reg + i, reg + i);
        }
+
        return wm8994->write_dev(wm8994, reg, bytes, src);
 }
 
@@ -125,7 +129,7 @@ int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
        int ret;
 
        val = cpu_to_be16(val);
-
+       DBG("%s:0x%04x = 0x%04x\n",__FUNCTION__,reg,val);
        mutex_lock(&wm8994->io_lock);
 
        ret = wm8994_write(wm8994, reg, 2, &val);
@@ -245,13 +249,13 @@ static struct mfd_cell wm8994_devs[] = {
  * management.
  */
 static const char *wm8994_main_supplies[] = {
-       "DBVDD",
-       "DCVDD",
-       "AVDD1",
-       "AVDD2",
-       "CPVDD",
-       "SPKVDD1",
-       "SPKVDD2",
+//     "DBVDD",
+//     "DCVDD",
+//     "AVDD1",
+//     "AVDD2",
+//     "CPVDD",
+//     "SPKVDD1",
+//     "SPKVDD2",
 };
 
 static const char *wm8958_main_supplies[] = {
@@ -267,17 +271,18 @@ static const char *wm8958_main_supplies[] = {
 };
 
 #ifdef CONFIG_PM
-int wm8994_suspend(struct wm8994 *wm8994)
+static int wm8994_suspend(struct device *dev)
 {
+       struct wm8994 *wm8994 = dev_get_drvdata(dev);
        int ret;
 
        /* Don't actually go through with the suspend if the CODEC is
         * still active (eg, for audio passthrough from CP. */
        ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1);
        if (ret < 0) {
-               dev_err(wm8994->dev, "Failed to read power status: %d\n", ret);
+               dev_err(dev, "Failed to read power status: %d\n", ret);
        } else if (ret & WM8994_VMID_SEL_MASK) {
-               dev_dbg(wm8994->dev, "CODEC still active, ignoring suspend\n");
+               dev_dbg(dev, "CODEC still active, ignoring suspend\n");
                return 0;
        }
 
@@ -288,13 +293,13 @@ int wm8994_suspend(struct wm8994 *wm8994)
        ret = wm8994_read(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
                          &wm8994->gpio_regs);
        if (ret < 0)
-               dev_err(wm8994->dev, "Failed to save GPIO registers: %d\n", ret);
+               dev_err(dev, "Failed to save GPIO registers: %d\n", ret);
 
        /* For similar reasons we also stash the regulator states */
        ret = wm8994_read(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
                          &wm8994->ldo_regs);
        if (ret < 0)
-               dev_err(wm8994->dev, "Failed to save LDO registers: %d\n", ret);
+               dev_err(dev, "Failed to save LDO registers: %d\n", ret);
 
        /* Explicitly put the device into reset in case regulators
         * don't get disabled in order to ensure consistent restart.
@@ -303,51 +308,46 @@ int wm8994_suspend(struct wm8994 *wm8994)
 
        wm8994->suspended = true;
 
-/*     ret = regulator_bulk_disable(wm8994->num_supplies,
+       ret = regulator_bulk_disable(wm8994->num_supplies,
                                     wm8994->supplies);
        if (ret != 0) {
                dev_err(dev, "Failed to disable supplies: %d\n", ret);
                return ret;
        }
-*/
-
-       gpio_set_value(WM_PW_EN, GPIO_LOW);
 
        return 0;
 }
 
-int wm8994_resume(struct wm8994 *wm8994)
+static int wm8994_resume(struct device *dev)
 {
+       struct wm8994 *wm8994 = dev_get_drvdata(dev);
        int ret;
 
        /* We may have lied to the PM core about suspending */
        if (!wm8994->suspended)
                return 0;
 
-       gpio_set_value(WM_PW_EN, GPIO_HIGH);
-       msleep(50);
-
-/*     ret = regulator_bulk_enable(wm8994->num_supplies,
+       ret = regulator_bulk_enable(wm8994->num_supplies,
                                    wm8994->supplies);
        if (ret != 0) {
                dev_err(dev, "Failed to enable supplies: %d\n", ret);
                return ret;
        }
-*/
+
        ret = wm8994_write(wm8994, WM8994_INTERRUPT_STATUS_1_MASK,
                           WM8994_NUM_IRQ_REGS * 2, &wm8994->irq_masks_cur);
        if (ret < 0)
-               dev_err(wm8994->dev, "Failed to restore interrupt masks: %d\n", ret);
+               dev_err(dev, "Failed to restore interrupt masks: %d\n", ret);
 
        ret = wm8994_write(wm8994, WM8994_LDO_1, WM8994_NUM_LDO_REGS * 2,
                           &wm8994->ldo_regs);
        if (ret < 0)
-               dev_err(wm8994->dev, "Failed to restore LDO registers: %d\n", ret);
+               dev_err(dev, "Failed to restore LDO registers: %d\n", ret);
 
        ret = wm8994_write(wm8994, WM8994_GPIO_1, WM8994_NUM_GPIO_REGS * 2,
                           &wm8994->gpio_regs);
        if (ret < 0)
-               dev_err(wm8994->dev, "Failed to restore GPIO registers: %d\n", ret);
+               dev_err(dev, "Failed to restore GPIO registers: %d\n", ret);
 
        wm8994->suspended = false;
 
@@ -399,7 +399,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
                goto err;
        }
 
-/*     switch (wm8994->type) {
+       switch (wm8994->type) {
        case WM8994:
                wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies);
                break;
@@ -446,7 +446,7 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
                dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
                goto err_get;
        }
-*/
+
        ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET);
        if (ret < 0) {
                dev_err(wm8994->dev, "Failed to read ID register\n");
@@ -542,12 +542,12 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq)
 err_irq:
        wm8994_irq_exit(wm8994);
 err_enable:
-//     regulator_bulk_disable(wm8994->num_supplies,
-//                            wm8994->supplies);
+       regulator_bulk_disable(wm8994->num_supplies,
+                              wm8994->supplies);
 err_get:
-//     regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
+       regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
 err_supplies:
-//     kfree(wm8994->supplies);
+       kfree(wm8994->supplies);
 err:
        mfd_remove_devices(wm8994->dev);
        kfree(wm8994);
@@ -559,10 +559,10 @@ static void wm8994_device_exit(struct wm8994 *wm8994)
        pm_runtime_disable(wm8994->dev);
        mfd_remove_devices(wm8994->dev);
        wm8994_irq_exit(wm8994);
-//     regulator_bulk_disable(wm8994->num_supplies,
-//                            wm8994->supplies);
-//     regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
-//     kfree(wm8994->supplies);
+       regulator_bulk_disable(wm8994->num_supplies,
+                              wm8994->supplies);
+       regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
+       kfree(wm8994->supplies);
        kfree(wm8994);
 }
 
@@ -590,43 +590,38 @@ static int wm8994_i2c_read_device(struct wm8994 *wm8994, unsigned short reg,
 static int wm8994_i2c_write_device(struct wm8994 *wm8994, unsigned short reg,
                                   int bytes, const void *src)
 {
+
        struct i2c_client *i2c = wm8994->control_data;
-       struct i2c_msg xfer[2];
+       struct i2c_msg xfer;    
+       unsigned char msg[bytes + 2];
        int ret;
 
        reg = cpu_to_be16(reg);
-
-       xfer[0].addr = i2c->addr;
-       xfer[0].flags = 0;
-       xfer[0].len = 2;
-       xfer[0].buf = (char *)&reg;
-       xfer[0].scl_rate = 100 * 1000;
-
-       xfer[1].addr = i2c->addr;
-       xfer[1].flags = I2C_M_NOSTART;
-       xfer[1].len = bytes;
-       xfer[1].buf = (char *)src;
-       xfer[1].scl_rate = 100 * 1000;
-
-       ret = i2c_transfer(i2c->adapter, xfer, 2);
+       memcpy(&msg[0], &reg, 2);
+       memcpy(&msg[2], src, bytes);
+       
+       xfer.addr = i2c->addr;
+       xfer.flags = i2c->flags;
+       xfer.len = bytes + 2;
+       xfer.buf = (char *)msg;
+       xfer.scl_rate = 100 * 1000;
+       xfer.udelay = i2c->udelay;
+       xfer.read_type = 0;
+       
+       ret = i2c_transfer(i2c->adapter, &xfer, 1);
        if (ret < 0)
                return ret;
-       if (ret != 2)
+       if (ret != 1)
                return -EIO;
 
        return 0;
 }
 
-int wm8994_probe(struct i2c_client *i2c,
-                   const struct i2c_device_id *id)
+static int wm8994_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
 {
        struct wm8994 *wm8994;
-
-       gpio_request(WM_PW_EN, NULL);
-       gpio_direction_output(WM_PW_EN, GPIO_HIGH);
-
-       msleep(50);
-
+       
        wm8994 = kzalloc(sizeof(struct wm8994), GFP_KERNEL);
        if (wm8994 == NULL)
                return -ENOMEM;
@@ -642,7 +637,7 @@ int wm8994_probe(struct i2c_client *i2c,
        return wm8994_device_init(wm8994, i2c->irq);
 }
 
-int wm8994_remove(struct i2c_client *i2c)
+static int wm8994_i2c_remove(struct i2c_client *i2c)
 {
        struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
 
@@ -650,6 +645,46 @@ int wm8994_remove(struct i2c_client *i2c)
 
        return 0;
 }
+
+static const struct i2c_device_id wm8994_i2c_id[] = {
+       { "wm8994", WM8994 },
+       { "wm8958", WM8958 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
+
+static UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume,
+                           NULL);
+
+static struct i2c_driver wm8994_i2c_driver = {
+       .driver = {
+               .name = "wm8994",
+               .owner = THIS_MODULE,
+               .pm = &wm8994_pm_ops,
+       },
+       .probe = wm8994_i2c_probe,
+       .remove = wm8994_i2c_remove,
+       .id_table = wm8994_i2c_id,
+};
+
+static int __init wm8994_i2c_init(void)
+{
+       int ret;
+
+       ret = i2c_add_driver(&wm8994_i2c_driver);
+       if (ret != 0)
+               pr_err("Failed to register wm8994 I2C driver: %d\n", ret);
+
+       return ret;
+}
+module_init(wm8994_i2c_init);
+
+static void __exit wm8994_i2c_exit(void)
+{
+       i2c_del_driver(&wm8994_i2c_driver);
+}
+module_exit(wm8994_i2c_exit);
+
 MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
old mode 100644 (file)
new mode 100755 (executable)
index 383080b..e7b65bb
@@ -120,7 +120,7 @@ static struct regulator_ops wm8994_ldo1_ops = {
        .enable = wm8994_ldo_enable,
        .disable = wm8994_ldo_disable,
        .is_enabled = wm8994_ldo_is_enabled,
-//     .enable_time = wm8994_ldo_enable_time,
+       .enable_time = wm8994_ldo_enable_time,
 
        .list_voltage = wm8994_ldo1_list_voltage,
        .get_voltage_sel = wm8994_ldo1_get_voltage_sel,
@@ -189,7 +189,7 @@ static struct regulator_ops wm8994_ldo2_ops = {
        .enable = wm8994_ldo_enable,
        .disable = wm8994_ldo_disable,
        .is_enabled = wm8994_ldo_is_enabled,
-//     .enable_time = wm8994_ldo_enable_time,
+       .enable_time = wm8994_ldo_enable_time,
 
        .list_voltage = wm8994_ldo2_list_voltage,
        .get_voltage_sel = wm8994_ldo2_get_voltage_sel,
@@ -238,6 +238,7 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
 
        if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) {
                ldo->enable = pdata->ldo[id].enable;
+               ldo->is_enabled = true;
 
                ret = gpio_request(ldo->enable, "WM8994 LDO enable");
                if (ret < 0) {
index 3e2c91f91657a8eb32297c7db4be123f8542ea95..f0b69cdae41cc94f24c995d9812301d9eb711451 100644 (file)
@@ -16,7 +16,6 @@
 #define __MFD_WM8994_CORE_H__
 
 #include <linux/interrupt.h>
-#include <linux/i2c.h>
 
 enum wm8994_type {
        WM8994 = 0,
@@ -114,10 +113,4 @@ static inline void wm8994_free_irq(struct wm8994 *wm8994, int irq, void *data)
 int wm8994_irq_init(struct wm8994 *wm8994);
 void wm8994_irq_exit(struct wm8994 *wm8994);
 
-int wm8994_suspend(struct wm8994 *wm8994);
-int wm8994_resume(struct wm8994 *wm8994);
-
-int wm8994_probe(struct i2c_client *i2c, const struct i2c_device_id *id);
-int wm8994_remove(struct i2c_client *i2c);
-
 #endif
index b4d4c22991e8b81eb81674987633b128fb362fb3..0c79b5ff4b5a3bb94de5e58ab2f65509685280be 100644 (file)
 #define WM8994_GP_FN_WSEQ_STATUS    16
 #define WM8994_GP_FN_FIFO_ERROR     17
 #define WM8994_GP_FN_OPCLK          18
+#define WM8994_GP_FN_THW           19
+#define WM8994_GP_FN_DCS_DONE      20
+#define WM8994_GP_FN_FLL1_OUT       21
+#define WM8994_GP_FN_FLL2_OUT       22
 
 #define WM8994_GPN_DIR                          0x8000  /* GPN_DIR */
 #define WM8994_GPN_DIR_MASK                     0x8000  /* GPN_DIR */
index 52f46b3cc58c9a0d92da6b4ddd00966ebf657e27..f7bc8d07ae401af9f96701b17e2f950efbc350fa 100755 (executable)
@@ -10,7 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#define DEBUG
+
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/init.h>
@@ -29,6 +29,7 @@
 #include <sound/initval.h>
 #include <sound/tlv.h>
 #include <trace/events/asoc.h>
+#include <mach/gpio.h>
 
 #include <linux/mfd/wm8994/core.h>
 #include <linux/mfd/wm8994/registers.h>
 #include "wm8994.h"
 #include "wm_hubs.h"
 
+#define WM8994_PROC
+#ifdef WM8994_PROC
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/vmalloc.h>
+char debug_write_read = 0;
+#endif
+
+#if 1
+#define DBG(x...) printk(KERN_INFO x)
+#else
+#define DBG(x...) do { } while (0)
+#endif
+
 #define WM8994_NUM_DRC 3
 #define WM8994_NUM_EQ  3
 
-struct wm8994 *wm8994_control;
+static struct snd_soc_codec *wm8994_codec;
 
 static int wm8994_drc_base[] = {
        WM8994_AIF1_DRC1_1,
@@ -121,12 +136,17 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
        int ret;
 
        BUG_ON(reg > WM8994_MAX_REGISTER);
-
+#ifdef WM8994_PROC             
+       if(debug_write_read != 0)               
+               printk("%s:0x%04x = 0x%04x\n",__FUNCTION__,reg,value);
+#endif
        if (!wm8994_volatile(codec, reg)) {
                ret = snd_soc_cache_write(codec, reg, value);
                if (ret != 0)
                        dev_err(codec->dev, "Cache write to %x failed: %d\n",
                                reg, ret);
+       //      else
+       //              DBG("snd_soc_cache_write:0x%04x = 0x%04x\n",reg,value);
        }
 
        return wm8994_reg_write(codec->control_data, reg, value);
@@ -139,18 +159,25 @@ static unsigned int wm8994_read(struct snd_soc_codec *codec,
        int ret;
 
        BUG_ON(reg > WM8994_MAX_REGISTER);
-
+               
        if (!wm8994_volatile(codec, reg) && wm8994_readable(codec, reg) &&
            reg < codec->driver->reg_cache_size) {
                ret = snd_soc_cache_read(codec, reg, &val);
                if (ret >= 0)
+               {               
+               //      DBG("snd_soc_cache_read:0x%04x = 0x%04x\n",reg,val);
                        return val;
+               }       
                else
                        dev_err(codec->dev, "Cache read from %x failed: %d\n",
                                reg, ret);
        }
-
-       return wm8994_reg_read(codec->control_data, reg);
+       val = wm8994_reg_read(codec->control_data, reg);
+#ifdef WM8994_PROC                     
+       if(debug_write_read != 0)                       
+               printk("%s:0x%04x = 0x%04x",__FUNCTION__,reg,val);      
+#endif
+       return val;
 }
 
 static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
@@ -2331,32 +2358,6 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
        return snd_soc_update_bits(codec, reg, mask, val);
 }
 
-struct snd_soc_codec *wm8994_regshow_codec;
-
-static ssize_t wm8994_index_reg_show(struct device *dev,
-       struct device_attribute *attr, char *buf)
-{
-       #define IDX_REG_FMT "reg 0x%04x value 0x%04x\n"
-       unsigned int val;
-       int cnt = 0, i;
-
-       cnt += sprintf(buf, "WM8994 index register\n");
-       for (i = 0; i < WM8994_CACHE_SIZE; i++) {
-               if (!wm8994_readable(wm8994_regshow_codec, i) || wm8994_volatile(wm8994_regshow_codec, i))
-                       continue;
-               val = wm8994_reg_read(wm8994_control, i);
-               if (!val)
-                       continue;
-               cnt += sprintf(buf + cnt, IDX_REG_FMT, i, val);
-       }
-
-       if (cnt >= PAGE_SIZE)
-               cnt = PAGE_SIZE - 1;
-
-       return cnt;
-}
-static DEVICE_ATTR(index_reg, 0444, wm8994_index_reg_show, NULL);
-
 #define WM8994_RATES SNDRV_PCM_RATE_8000_96000
 
 #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
@@ -2446,7 +2447,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
 };
 
 #ifdef CONFIG_PM
-static int wm8994_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
+static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
        struct wm8994 *control = codec->control_data;
@@ -2473,20 +2474,16 @@ static int wm8994_codec_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
        wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
-       wm8994_suspend(control);
-
        return 0;
 }
 
-static int wm8994_codec_resume(struct snd_soc_codec *codec)
+static int wm8994_resume(struct snd_soc_codec *codec)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
        struct wm8994 *control = codec->control_data;
        int i, ret;
        unsigned int val, mask;
 
-       wm8994_resume(control);
-
        if (wm8994->revision < 4) {
                /* force a HW read */
                val = wm8994_reg_read(codec->control_data,
@@ -2882,31 +2879,33 @@ out:
        return IRQ_HANDLED;
 }
 
+#ifdef WM8994_PROC     
+static int wm8994_proc_init(void);
+#endif
+
 static int wm8994_codec_probe(struct snd_soc_codec *codec)
 {
        struct wm8994 *control;
        struct wm8994_priv *wm8994;
        struct snd_soc_dapm_context *dapm = &codec->dapm;
        int ret, i;
+       
+#ifdef WM8994_PROC     
+       wm8994_proc_init();
+#endif
 
-       if (wm8994_control == NULL) {
-               pr_err("wm8994_codec_probe:wm8994_control is NULL!");
-               return -EIO;
-       }
-
-       codec->control_data = wm8994_control;//dev_get_drvdata(codec->dev->parent);
+       codec->control_data = dev_get_drvdata(codec->dev->parent);
        control = codec->control_data;
 
-       wm8994_regshow_codec = codec;
-
        wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
        if (wm8994 == NULL)
                return -ENOMEM;
        snd_soc_codec_set_drvdata(codec, wm8994);
 
-       wm8994->pdata = wm8994_control->dev->platform_data;//dev_get_platdata(codec->dev->parent);
+       wm8994->pdata = dev_get_platdata(codec->dev->parent);
        wm8994->codec = codec;
-
+       wm8994_codec = codec;
+       
        if (wm8994->pdata && wm8994->pdata->micdet_irq)
                wm8994->micdet_irq = wm8994->pdata->micdet_irq;
        else if (wm8994->pdata && wm8994->pdata->irq_base)
@@ -3149,7 +3148,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
        }
                
 
-       wm_hubs_add_analogue_routes(codec, 0, 0);
+       wm_hubs_add_analogue_routes(codec, 1, 0);
        snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
 
        switch (control->type) {
@@ -3184,13 +3183,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
                break;
        }
 
-       ret = device_create_file(codec->dev, &dev_attr_index_reg);
-       if (ret != 0) {
-               dev_err(codec->dev,
-                       "Failed to create index_reg sysfs files: %d\n", ret);
-               return ret;
-       }
-
        return 0;
 
 err_irq:
@@ -3246,8 +3238,8 @@ static int  wm8994_codec_remove(struct snd_soc_codec *codec)
 static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
        .probe =        wm8994_codec_probe,
        .remove =       wm8994_codec_remove,
-       .suspend =      wm8994_codec_suspend,
-       .resume =       wm8994_codec_resume,
+       .suspend =      wm8994_suspend,
+       .resume =       wm8994_resume,
        .read =         wm8994_read,
        .write =        wm8994_write,
        .readable_register = wm8994_readable,
@@ -3260,71 +3252,164 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
        .compress_type = SND_SOC_RBTREE_COMPRESSION,
 };
 
-static int wm8994_i2c_probe(struct i2c_client *i2c,
-                           const struct i2c_device_id *id)
+static int __devinit wm8994_probe(struct platform_device *pdev)
 {
-       int ret;
-
-       ret = wm8994_probe(i2c, id);
-       if (ret < 0) {
-               pr_err("wm8994_i2c_probe error!");
-               return ret;
-       }
-
-       wm8994_control = i2c_get_clientdata(i2c);
-
-       return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8994,
-               wm8994_dai, ARRAY_SIZE(wm8994_dai));
+       return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm8994,
+                       wm8994_dai, ARRAY_SIZE(wm8994_dai));
 }
 
-static int wm8994_i2c_remove(struct i2c_client *i2c)
+static int __devexit wm8994_remove(struct platform_device *pdev)
 {
-       wm8994_remove(i2c);
-       snd_soc_unregister_codec(&i2c->dev);
-
+       snd_soc_unregister_codec(&pdev->dev);
        return 0;
 }
 
-static const struct i2c_device_id wm8994_i2c_id[] = {
-       { "wm8994", WM8994 },
-//     { "wm8958", WM8958 },
-       { }
-};
-MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
-
-//static UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume,
-//                         NULL);
-
-static struct i2c_driver wm8994_i2c_driver = {
+static struct platform_driver wm8994_codec_driver = {
        .driver = {
-               .name = "WM8994",
-               .owner = THIS_MODULE,
-               //.pm = &wm8994_pm_ops,
-       },
-       .probe = wm8994_i2c_probe,
-       .remove = wm8994_i2c_remove,
-       .id_table = wm8994_i2c_id,
+                  .name = "wm8994-codec",
+                  .owner = THIS_MODULE,
+                  },
+       .probe = wm8994_probe,
+       .remove = __devexit_p(wm8994_remove),
 };
 
-static int __init wm8994_i2c_init(void)
+static __init int wm8994_init(void)
 {
-       int ret;
-
-       ret = i2c_add_driver(&wm8994_i2c_driver);
-       if (ret != 0)
-               pr_err("Failed to register wm8994 I2C driver: %d\n", ret);
-
-       return ret;
+       return platform_driver_register(&wm8994_codec_driver);
 }
-module_init(wm8994_i2c_init);
+module_init(wm8994_init);
 
-static void __exit wm8994_i2c_exit(void)
+static __exit void wm8994_exit(void)
 {
-       i2c_del_driver(&wm8994_i2c_driver);
+       platform_driver_unregister(&wm8994_codec_driver);
 }
-module_exit(wm8994_i2c_exit);
+module_exit(wm8994_exit);
+
 
 MODULE_DESCRIPTION("ASoC WM8994 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:wm8994-codec");
+
+//=====================================================================
+//Proc
+#ifdef WM8994_PROC
+static ssize_t wm8994_proc_write(struct file *file, const char __user *buffer,
+                          unsigned long len, void *data)
+{
+       char *cookie_pot; 
+       char *p;
+       int reg;
+       int value;
+       
+       cookie_pot = (char *)vmalloc( len );
+       if (!cookie_pot) 
+       {
+               return -ENOMEM;
+       } 
+       else 
+       {
+               if (copy_from_user( cookie_pot, buffer, len )) 
+                       return -EFAULT;
+       }
+
+       switch(cookie_pot[0])
+       {
+       case 'd':
+       case 'D':
+               debug_write_read ++;
+               debug_write_read %= 2;
+               if(debug_write_read != 0)
+                       printk("Debug read and write reg on\n");
+               else    
+                       printk("Debug read and write reg off\n");       
+               break;  
+       case 'r':
+       case 'R':
+               printk("Read reg debug\n");             
+               if(cookie_pot[1] ==':')
+               {
+                       debug_write_read = 1;
+                       strsep(&cookie_pot,":");
+                       while((p=strsep(&cookie_pot,",")))
+                       {
+                               reg = simple_strtol(p,NULL,16);
+                               value = wm8994_reg_read(wm8994_codec->control_data,reg);
+                               printk("wm8994_read:0x%04x = 0x%04x",reg,value);
+                       }
+                       debug_write_read = 0;
+                       printk("\n");
+               }
+               else
+               {
+                       printk("Error Read reg debug.\n");
+                       printk("For example: echo 'r:22,23,24,25'>wm8994_ts\n");
+               }
+               break;
+       case 'w':
+       case 'W':
+               printk("Write reg debug\n");            
+               if(cookie_pot[1] ==':')
+               {
+                       debug_write_read = 1;
+                       strsep(&cookie_pot,":");
+                       while((p=strsep(&cookie_pot,"=")))
+                       {
+                               reg = simple_strtol(p,NULL,16);
+                               p=strsep(&cookie_pot,",");
+                               value = simple_strtol(p,NULL,16);
+                               wm8994_reg_write(wm8994_codec->control_data,reg,value);
+                               printk("wm8994_write:0x%04x = 0x%04x",reg,value);
+                       }
+                       debug_write_read = 0;
+                       printk("\n");
+               }
+               else
+               {
+                       printk("Error Write reg debug.\n");
+                       printk("For example: w:22=0,23=0,24=0,25=0\n");
+               }
+               break;
+       case 'p'://enable pa
+               gpio_request(RK29_PIN6_PD3, NULL);                              
+               gpio_direction_output(RK29_PIN6_PD3,GPIO_HIGH);                         
+               gpio_free(RK29_PIN6_PD3);
+               break;
+       default:
+               printk("Help for wm8994_ts .\n-->The Cmd list: \n");
+               printk("-->'d&&D' Open or Off the debug\n");
+               printk("-->'r&&R' Read reg debug,Example: echo 'r:22,23,24,25'>wm8994_ts\n");
+               printk("-->'w&&W' Write reg debug,Example: echo 'w:22=0,23=0,24=0,25=0'>wm8994_ts\n");
+               break;
+       }
+
+       return len;
+}
+static const struct file_operations wm8994_proc_fops = {
+       .owner          = THIS_MODULE,
+       //.open         = snd_mem_proc_open,
+       //.read         = seq_read,
+//#ifdef CONFIG_PCI
+       .write          = wm8994_proc_write,
+//#endif
+       //.llseek       = seq_lseek,
+       //.release      = single_release,
+};
+
+static int wm8994_proc_init(void)
+{
+       struct proc_dir_entry *wm8994_proc_entry;
+       wm8994_proc_entry = create_proc_entry("driver/wm8994_ts", 0777, NULL);
+       if(wm8994_proc_entry != NULL)
+       {
+               wm8994_proc_entry->write_proc = wm8994_proc_write;
+               return -1;
+       }
+       else
+       {
+               printk("create proc error !\n");
+       }
+       return 0;
+}
+
+#endif
index 95bb3ecaff97e7fe349ad9af4660d63a522ac5d1..1bd6e5b1e0e53d3f340e58179ba70808a01cf831 100755 (executable)
@@ -46,16 +46,6 @@ static int rk29_aif1_hw_params(struct snd_pcm_substream *substream,
 
        DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
 
-       if ((params->flags == HW_PARAMS_FLAG_EQVOL_ON)||(params->flags == HW_PARAMS_FLAG_EQVOL_OFF))
-       {
-               DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
-
-               if (codec_dai->driver->ops->hw_params)
-                       ret = codec_dai->driver->ops->hw_params(substream, params, codec_dai); //by Vincent
-
-               return 0;
-       }
-
        /* set codec DAI configuration */
 #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) 
        DBG("Set codec_dai slave\n");
@@ -72,14 +62,14 @@ static int rk29_aif1_hw_params(struct snd_pcm_substream *substream,
 
        /* set cpu DAI configuration */
 #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) 
-       DBG("Set cpu_dai slave\n");
+       DBG("Set cpu_dai master\n");
        ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
                SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
 #endif 
 #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER)  
        ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
                SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 
-       DBG("Set cpu_dai master\n"); 
+       DBG("Set cpu_dai slave\n"); 
 #endif         
        if (ret < 0)
                return ret;
@@ -100,22 +90,23 @@ static int rk29_aif1_hw_params(struct snd_pcm_substream *substream,
                default:
                        DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
                        return -EINVAL;
-                       break;
        }
 
-       DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
-
+       DBG("Enter:%s, %d, rate=%d,pll_out = %d\n",__FUNCTION__,__LINE__,params_rate(params),pll_out);
+#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)  
+       ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
+       if(ret < 0)
+       {
+               DBG("rk29_hw_params_wm8994:failed to set the cpu sysclk for codec side\n"); 
+               return ret;
+       }
        ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, pll_out, 0);
        if (ret < 0) {
                DBG("rk29_hw_params_wm8994:failed to set the sysclk for codec side\n"); 
                return ret;
        }
-
-       snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
-
-#if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE)
-       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1);
-       snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3);
+#else if
+       
 #endif
 
        return 0;
@@ -278,7 +269,7 @@ static struct snd_soc_dai_link rk29_dai[] = {
        {
                .name = "WM8994 I2S1",
                .stream_name = "WM8994 PCM",
-               .codec_name = "WM8994.0-001a",
+               .codec_name = "wm8994-codec",
                .platform_name = "rockchip-audio",
                .cpu_dai_name = "rk29_i2s.0",
                .codec_dai_name = "wm8994-aif1",
@@ -287,7 +278,7 @@ static struct snd_soc_dai_link rk29_dai[] = {
        {
                .name = "WM8994 I2S2",
                .stream_name = "WM8994 PCM",
-               .codec_name = "WM8994.0-001a",
+               .codec_name = "wm8994-codec",
                .platform_name = "rockchip-audio",
                .cpu_dai_name = "rk29_i2s.0",
                .codec_dai_name = "wm8994-aif2",
@@ -296,7 +287,7 @@ static struct snd_soc_dai_link rk29_dai[] = {
        {
                .name = "WM8994 I2S3",
                .stream_name = "WM8994 PCM",
-               .codec_name = "WM8994.0-001a",
+               .codec_name = "wm8994-codec",
                .platform_name = "rockchip-audio",
                .cpu_dai_name = "rk29_i2s.0",
                .codec_dai_name = "wm8994-aif3",
@@ -307,7 +298,7 @@ static struct snd_soc_dai_link rk29_dai[] = {
 static struct snd_soc_card snd_soc_card_rk29 = {
        .name = "RK29_WM8994",
        .dai_link = rk29_dai,
-       .num_links = 3,
+       .num_links = ARRAY_SIZE(rk29_dai),
 };
 
 static struct platform_device *rk29_snd_device;