CHROMIUM: ALSA: ASoC: exynos hdmi - disable audio in DVI mode
[cascardo/linux.git] / sound / soc / samsung / hdmi_audio.c
index 366f12b..7eef7c8 100644 (file)
@@ -331,10 +331,8 @@ static int hdmi_audio_hw_params(struct device *dev,
        snd_printdd("sample_rate [%d]\n", ctx->params.sample_rate);
 
        /* checking here to cache audioparms for hpd plug handling */
-       if (!atomic_read(&ctx->plugged)) {
-               dev_err(dev, "hdmi not plugged\n");
+       if (!atomic_read(&ctx->plugged))
                return -EINVAL;
-       }
 
        hdmi_audio_control(ctx, false);
        hdmi_conf_init(ctx);
@@ -364,10 +362,8 @@ static int hdmi_audio_trigger(struct device *dev,
        plugin = dev_get_drvdata(dev);
        ctx = container_of(plugin, struct hdmi_audio_context, plugin);
 
-       if (!atomic_read(&ctx->plugged)) {
-               dev_err(dev, "hdmi not plugged\n");
+       if (!atomic_read(&ctx->plugged))
                return -EINVAL;
-       }
 
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
@@ -442,6 +438,21 @@ static void hdmi_audio_hotplug_func(struct work_struct *work)
                        __LINE__, __func__, atomic_read(&ctx->plugged));
 
        plugged = atomic_read(&ctx->plugged);
+
+       if (hdmi_reg_read(ctx, HDMI_MODE_SEL) & HDMI_DVI_MODE_EN) {
+               /* If HDMI operates in DVI mode,
+                * for audio purposes it is the same as nothing plugged.
+                * Unfortunately, hotplug interrupt is received multiple times,
+                * and HDMI_DVI_MODE_EN is set only in the last one.
+                * So, we have already reported that HDMI audio was plugged.
+                * So, update ctx, report now that it was unplugged and return.
+                */
+               atomic_set(&ctx->plugged, 0);
+               if (plugged && ctx->plugin.jack_cb)
+                       ctx->plugin.jack_cb(false);
+               return;
+       }
+
        if (plugged) {
                hdmi_audio_control(ctx, false);
                hdmi_conf_init(ctx);
@@ -475,7 +486,6 @@ static __devinit int hdmi_audio_probe(struct platform_device *pdev)
        int ret = 0;
        struct hdmi_audio_context *ctx;
        struct resource *res;
-       enum of_gpio_flags flags;
        struct device_node *parent_node;
 
        snd_printdd(&pdev->dev, "[%d] %s\n", __LINE__, __func__);
@@ -538,8 +548,7 @@ static __devinit int hdmi_audio_probe(struct platform_device *pdev)
                goto err_workq;
        }
 
-       ctx->hpd_gpio = of_get_named_gpio_flags(parent_node,
-                               "hpd-gpio", 0, &flags);
+       ctx->hpd_gpio = (int)pdev->dev.platform_data;
 
        if (!gpio_is_valid(ctx->hpd_gpio)) {
                dev_err(&pdev->dev, "failed to get hpd gpio.");