Merge remote-tracking branches 'asoc/topic/inntel', 'asoc/topic/input', 'asoc/topic...
[sfrench/cifs-2.6.git] / sound / soc / codecs / wm5102.c
index 93876c6d48ee9a850516771339fad3be22ce980b..e7ab37d0dd325c0614e18ce6b2c671acee1c2915 100644 (file)
@@ -607,6 +607,9 @@ static int wm5102_sysclk_ev(struct snd_soc_dapm_widget *w,
                break;
        case SND_SOC_DAPM_PRE_PMD:
                break;
+       case SND_SOC_DAPM_PRE_PMU:
+       case SND_SOC_DAPM_POST_PMD:
+               return arizona_clk_ev(w, kcontrol, event);
        default:
                return 0;
        }
@@ -1077,9 +1080,11 @@ static const struct snd_kcontrol_new wm5102_aec_loopback_mux =
 static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
 SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
                    0, wm5102_sysclk_ev,
-                   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+                   SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD |
+                   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
-                   ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
+                   ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, arizona_clk_ev,
+                   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 SND_SOC_DAPM_SUPPLY("OPCLK", ARIZONA_OUTPUT_SYSTEM_CLOCK,
                    ARIZONA_OPCLK_ENA_SHIFT, 0, NULL, 0),
 SND_SOC_DAPM_SUPPLY("ASYNCOPCLK", ARIZONA_OUTPUT_ASYNC_CLOCK,
@@ -1903,7 +1908,7 @@ static struct snd_soc_dai_driver wm5102_dai[] = {
 static int wm5102_open(struct snd_compr_stream *stream)
 {
        struct snd_soc_pcm_runtime *rtd = stream->private_data;
-       struct wm5102_priv *priv = snd_soc_codec_get_drvdata(rtd->codec);
+       struct wm5102_priv *priv = snd_soc_platform_get_drvdata(rtd->platform);
 
        return wm_adsp_compr_open(&priv->core.adsp[0], stream);
 }
@@ -1926,18 +1931,10 @@ static irqreturn_t wm5102_adsp2_irq(int irq, void *data)
 static int wm5102_codec_probe(struct snd_soc_codec *codec)
 {
        struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+       struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
        struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
-       struct arizona *arizona = priv->core.arizona;
        int ret;
 
-       ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
-                                 "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
-                                 priv);
-       if (ret != 0) {
-               dev_err(codec->dev, "Failed to request DSP IRQ: %d\n", ret);
-               return ret;
-       }
-
        ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec);
        if (ret)
                return ret;
@@ -1949,8 +1946,9 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
 
        arizona_init_spk(codec);
        arizona_init_gpio(codec);
+       arizona_init_notifiers(codec);
 
-       snd_soc_dapm_disable_pin(dapm, "HAPTICS");
+       snd_soc_component_disable_pin(component, "HAPTICS");
 
        priv->core.arizona->dapm = dapm;
 
@@ -1965,16 +1963,11 @@ err_adsp2_codec_probe:
 static int wm5102_codec_remove(struct snd_soc_codec *codec)
 {
        struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
-       struct arizona *arizona = priv->core.arizona;
 
        wm_adsp2_codec_remove(&priv->core.adsp[0], codec);
 
        priv->core.arizona->dapm = NULL;
 
-       arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv);
-
-       arizona_free_spk(codec);
-
        return 0;
 }
 
@@ -2092,25 +2085,47 @@ static int wm5102_probe(struct platform_device *pdev)
        pm_runtime_enable(&pdev->dev);
        pm_runtime_idle(&pdev->dev);
 
+       ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1,
+                                 "ADSP2 Compressed IRQ", wm5102_adsp2_irq,
+                                 wm5102);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "Failed to request DSP IRQ: %d\n", ret);
+               return ret;
+       }
+
+       ret = arizona_init_spk_irqs(arizona);
+       if (ret < 0)
+               goto err_dsp_irq;
+
        ret = snd_soc_register_platform(&pdev->dev, &wm5102_compr_platform);
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to register platform: %d\n", ret);
-               return ret;
+               goto err_spk_irqs;
        }
 
        ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,
                                      wm5102_dai, ARRAY_SIZE(wm5102_dai));
        if (ret < 0) {
                dev_err(&pdev->dev, "Failed to register codec: %d\n", ret);
-               snd_soc_unregister_platform(&pdev->dev);
+               goto err_platform;
        }
 
+       return ret;
+
+err_platform:
+       snd_soc_unregister_platform(&pdev->dev);
+err_spk_irqs:
+       arizona_free_spk_irqs(arizona);
+err_dsp_irq:
+       arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5102);
+
        return ret;
 }
 
 static int wm5102_remove(struct platform_device *pdev)
 {
        struct wm5102_priv *wm5102 = platform_get_drvdata(pdev);
+       struct arizona *arizona = wm5102->core.arizona;
 
        snd_soc_unregister_platform(&pdev->dev);
        snd_soc_unregister_codec(&pdev->dev);
@@ -2118,6 +2133,10 @@ static int wm5102_remove(struct platform_device *pdev)
 
        wm_adsp2_remove(&wm5102->core.adsp[0]);
 
+       arizona_free_spk_irqs(arizona);
+
+       arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, wm5102);
+
        return 0;
 }