a22: wm8994 add pa control
author邱建斌 <qjb@rock-chips.com>
Mon, 5 Dec 2011 08:23:50 +0000 (16:23 +0800)
committer邱建斌 <qjb@rock-chips.com>
Mon, 5 Dec 2011 08:23:50 +0000 (16:23 +0800)
arch/arm/mach-rk29/board-rk29-a22.c
include/linux/mfd/wm8994/pdata.h
sound/soc/codecs/wm8994.c
sound/soc/rk29/rk29_wm8994.c

index 2601ee64f91dd864a23469c8c9b84855bc7264bb..cd29b7d386240c0f76df40568e2ef9eccac9d4b5 100755 (executable)
@@ -1738,7 +1738,7 @@ static struct wm8994_pdata wm8994_platform_data = {
 //     .BB_input_diff = 0,
 //     .BB_class = NO_PCM_BB,
 
-//     .PA_control_pin = RK29_PIN6_PD3,
+       .PA_control_pin = RK29_PIN6_PD3,
 };
 #endif 
 #ifdef CONFIG_RK_HEADSET_DET
index 97cf4f27d6470120a389bb8a2e1217871b8e3411..8f6c61490d79a3b7843c78736831c88f0162bcd5 100755 (executable)
@@ -123,7 +123,10 @@ struct wm8994_pdata {
        int gpio_defaults[WM8994_NUM_GPIO];
 
        struct wm8994_ldo_pdata ldo[WM8994_NUM_LDO];
-
+       //wm8994 LDO1_ENA and LDO2_ENA
+       char    PowerEN_iomux_name[50];
+       int             PowerEN_iomux_mode;     
+       
        int irq_base;  /** Base IRQ number for WM8994, required for IRQs */
 
         int num_drc_cfgs;
@@ -167,6 +170,10 @@ struct wm8994_pdata {
 
        /* WM8958 microphone bias configuration */
        int micbias[2];
+
+       //If an external amplifier speakers wm8994              enable>0 disable=0
+       unsigned int PA_control_pin;
+       
 };
 
 #endif
index f7bc8d07ae401af9f96701b17e2f950efbc350fa..53a3dcf6f63c70fb77300db44ee0530546c7e85d 100755 (executable)
@@ -830,6 +830,34 @@ static int late_disable_ev(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
+static int wm8994_PA_event(struct snd_soc_dapm_widget *w,
+                         struct snd_kcontrol *control, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
+       struct wm8994_pdata *pdata = wm8994->pdata;
+       DBG("Enter %s::%s---%d\n",__FILE__,__FUNCTION__,__LINE__);
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               DBG("PA enable\n");
+               gpio_set_value(pdata->PA_control_pin,GPIO_HIGH);        
+               break;
+
+       case SND_SOC_DAPM_PRE_PMD:
+               DBG("PA disable\n");
+               gpio_set_value(pdata->PA_control_pin,GPIO_LOW);
+       //      msleep(50);
+               break;
+
+       default:
+               BUG();
+               break;
+       }
+
+       return 0;
+}
+
 static int aif1clk_ev(struct snd_soc_dapm_widget *w,
                      struct snd_kcontrol *kcontrol, int event)
 {
@@ -1563,6 +1591,24 @@ static const struct snd_soc_dapm_route wm8958_intercon[] = {
        { "AIF3ADC Mux", "Mono PCM", "Mono PCM Out Mux" },
 };
 
+static const struct snd_soc_dapm_route wm8998_PA_intercon[] = {
+
+       { "PA Driver", NULL,"SPKL Driver"},
+       { "PA Driver", NULL,"SPKR Driver"},     
+       
+       { "SPKOUTLP", NULL, "PA Driver" },
+       { "SPKOUTLN", NULL, "PA Driver" },
+       { "SPKOUTRP", NULL, "PA Driver" },
+       { "SPKOUTRN", NULL, "PA Driver" },      
+};
+
+static const struct snd_soc_dapm_widget wm8998_PA_dapm_widgets[] = {
+SND_SOC_DAPM_PGA_E("PA Driver", SND_SOC_NOPM, 0, 0,  NULL, 0, wm8994_PA_event,
+                  SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+};
+
+
 /* The size in bits of the FLL divide multiplied by 10
  * to allow rounding later */
 #define FIXED_FLL_SIZE ((1 << 16) * 10)
@@ -2670,7 +2716,7 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
        else
                snd_soc_add_controls(wm8994->codec, wm8994_eq_controls,
                                     ARRAY_SIZE(wm8994_eq_controls));
-
+       
        for (i = 0; i < ARRAY_SIZE(pdata->micbias); i++) {
                if (pdata->micbias[i]) {
                        snd_soc_write(codec, WM8958_MICBIAS1 + i,
@@ -2887,6 +2933,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
 {
        struct wm8994 *control;
        struct wm8994_priv *wm8994;
+       struct wm8994_pdata *pdata;
        struct snd_soc_dapm_context *dapm = &codec->dapm;
        int ret, i;
        
@@ -2903,6 +2950,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
        snd_soc_codec_set_drvdata(codec, wm8994);
 
        wm8994->pdata = dev_get_platdata(codec->dev->parent);
+       pdata = wm8994->pdata;
        wm8994->codec = codec;
        wm8994_codec = codec;
        
@@ -3097,7 +3145,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
        wm8994_update_class_w(codec);
 
        wm8994_handle_pdata(wm8994);
-
+       
        wm_hubs_add_analogue_controls(codec);
        snd_soc_add_controls(codec, wm8994_snd_controls,
                             ARRAY_SIZE(wm8994_snd_controls));
@@ -3182,7 +3230,20 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
                wm8958_dsp2_init(codec);
                break;
        }
-
+       
+       if(pdata ->PA_control_pin)
+       {
+               dev_info(codec->dev,"Add the PA control route\n");
+               snd_soc_dapm_new_controls(dapm, wm8998_PA_dapm_widgets,
+                                 ARRAY_SIZE(wm8998_PA_dapm_widgets));  
+               snd_soc_dapm_add_routes(dapm, wm8998_PA_intercon, 
+                               ARRAY_SIZE(wm8998_PA_intercon));
+               gpio_request(pdata->PA_control_pin, "wm8994_PA_ctrl");                          
+               gpio_direction_output(pdata->PA_control_pin,GPIO_LOW);
+       }
+       else
+               dev_warn(codec->dev, "have not pa control\n");
+       
        return 0;
 
 err_irq:
@@ -3200,7 +3261,8 @@ static int  wm8994_codec_remove(struct snd_soc_codec *codec)
 {
        struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
        struct wm8994 *control = codec->control_data;
-
+       struct wm8994_pdata *pdata = wm8994->pdata;
+       
        wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
        pm_runtime_disable(codec->dev);
@@ -3228,6 +3290,8 @@ static int  wm8994_codec_remove(struct snd_soc_codec *codec)
                release_firmware(wm8994->mbc_vss);
        if (wm8994->enh_eq)
                release_firmware(wm8994->enh_eq);
+       if (gpio_is_valid(pdata->PA_control_pin))
+               gpio_free(pdata->PA_control_pin);
        kfree(wm8994->retune_mobile_texts);
        kfree(wm8994->drc_texts);
        kfree(wm8994);
index 1bd6e5b1e0e53d3f340e58179ba70808a01cf831..821ee7d19069e832112a0c73f6db16e777326cf7 100755 (executable)
@@ -26,7 +26,7 @@
 #include "rk29_i2s.h"
 #include <linux/clk.h>
 
-#if 1
+#if 0
 #define        DBG(x...)       printk(KERN_INFO x)
 #else
 #define        DBG(x...)