]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - sound/soc/omap/ams-delta.c
Merge branch 'master' into tk71
[mv-sheeva.git] / sound / soc / omap / ams-delta.c
index b0f618e4484068e6c62e7b9515b6af5d6dfa021e..3167be689621ace695b79f4ffa11ea6878a8f933 100644 (file)
@@ -26,7 +26,7 @@
 #include <linux/spinlock.h>
 #include <linux/tty.h>
 
-#include <sound/soc-dapm.h>
+#include <sound/soc.h>
 #include <sound/jack.h>
 
 #include <asm/mach-types.h>
@@ -94,12 +94,13 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
                                        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
        struct soc_enum *control = (struct soc_enum *)kcontrol->private_value;
        unsigned short pins;
        int pin, changed = 0;
 
        /* Refuse any mode changes if we are not able to control the codec. */
-       if (!codec->control_data)
+       if (!codec->hw_write)
                return -EUNATCH;
 
        if (ucontrol->value.enumerated.item[0] >= control->max)
@@ -112,48 +113,48 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
 
        /* Setup pins after corresponding bits if changed */
        pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE));
-       if (pin != snd_soc_dapm_get_pin_status(codec, "Mouthpiece")) {
+       if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) {
                changed = 1;
                if (pin)
-                       snd_soc_dapm_enable_pin(codec, "Mouthpiece");
+                       snd_soc_dapm_enable_pin(dapm, "Mouthpiece");
                else
-                       snd_soc_dapm_disable_pin(codec, "Mouthpiece");
+                       snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
        }
        pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
-       if (pin != snd_soc_dapm_get_pin_status(codec, "Earpiece")) {
+       if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) {
                changed = 1;
                if (pin)
-                       snd_soc_dapm_enable_pin(codec, "Earpiece");
+                       snd_soc_dapm_enable_pin(dapm, "Earpiece");
                else
-                       snd_soc_dapm_disable_pin(codec, "Earpiece");
+                       snd_soc_dapm_disable_pin(dapm, "Earpiece");
        }
        pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
-       if (pin != snd_soc_dapm_get_pin_status(codec, "Microphone")) {
+       if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) {
                changed = 1;
                if (pin)
-                       snd_soc_dapm_enable_pin(codec, "Microphone");
+                       snd_soc_dapm_enable_pin(dapm, "Microphone");
                else
-                       snd_soc_dapm_disable_pin(codec, "Microphone");
+                       snd_soc_dapm_disable_pin(dapm, "Microphone");
        }
        pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
-       if (pin != snd_soc_dapm_get_pin_status(codec, "Speaker")) {
+       if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) {
                changed = 1;
                if (pin)
-                       snd_soc_dapm_enable_pin(codec, "Speaker");
+                       snd_soc_dapm_enable_pin(dapm, "Speaker");
                else
-                       snd_soc_dapm_disable_pin(codec, "Speaker");
+                       snd_soc_dapm_disable_pin(dapm, "Speaker");
        }
        pin = !!(pins & (1 << AMS_DELTA_AGC));
        if (pin != ams_delta_audio_agc) {
                ams_delta_audio_agc = pin;
                changed = 1;
                if (pin)
-                       snd_soc_dapm_enable_pin(codec, "AGCIN");
+                       snd_soc_dapm_enable_pin(dapm, "AGCIN");
                else
-                       snd_soc_dapm_disable_pin(codec, "AGCIN");
+                       snd_soc_dapm_disable_pin(dapm, "AGCIN");
        }
        if (changed)
-               snd_soc_dapm_sync(codec);
+               snd_soc_dapm_sync(dapm);
 
        mutex_unlock(&codec->mutex);
 
@@ -164,19 +165,20 @@ static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol,
                                        struct snd_ctl_elem_value *ucontrol)
 {
        struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
        unsigned short pins, mode;
 
-       pins = ((snd_soc_dapm_get_pin_status(codec, "Mouthpiece") <<
+       pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") <<
                                                        AMS_DELTA_MOUTHPIECE) |
-                       (snd_soc_dapm_get_pin_status(codec, "Earpiece") <<
+                       (snd_soc_dapm_get_pin_status(dapm, "Earpiece") <<
                                                        AMS_DELTA_EARPIECE));
        if (pins)
-               pins |= (snd_soc_dapm_get_pin_status(codec, "Microphone") <<
+               pins |= (snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
                                                        AMS_DELTA_MICROPHONE);
        else
-               pins = ((snd_soc_dapm_get_pin_status(codec, "Microphone") <<
+               pins = ((snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
                                                        AMS_DELTA_MICROPHONE) |
-                       (snd_soc_dapm_get_pin_status(codec, "Speaker") <<
+                       (snd_soc_dapm_get_pin_status(dapm, "Speaker") <<
                                                        AMS_DELTA_SPEAKER) |
                        (ams_delta_audio_agc << AMS_DELTA_AGC));
 
@@ -268,31 +270,57 @@ static void cx81801_timeout(unsigned long data)
                ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0);
 }
 
+/*
+ * Used for passing a codec structure pointer
+ * from the board initialization code to the tty line discipline.
+ */
+static struct snd_soc_codec *cx20442_codec;
+
 /* Line discipline .open() */
 static int cx81801_open(struct tty_struct *tty)
 {
-       return v253_ops.open(tty);
+       int ret;
+
+       if (!cx20442_codec)
+               return -ENODEV;
+
+       /*
+        * Pass the codec structure pointer for use by other ldisc callbacks,
+        * both the card and the codec specific parts.
+        */
+       tty->disc_data = cx20442_codec;
+
+       ret = v253_ops.open(tty);
+
+       if (ret < 0)
+               tty->disc_data = NULL;
+
+       return ret;
 }
 
 /* Line discipline .close() */
 static void cx81801_close(struct tty_struct *tty)
 {
        struct snd_soc_codec *codec = tty->disc_data;
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
 
        del_timer_sync(&cx81801_timer);
 
-       v253_ops.close(tty);
-
        /* Prevent the hook switch from further changing the DAPM pins */
        INIT_LIST_HEAD(&ams_delta_hook_switch.pins);
 
+       if (!codec)
+               return;
+
+       v253_ops.close(tty);
+
        /* Revert back to default audio input/output constellation */
-       snd_soc_dapm_disable_pin(codec, "Mouthpiece");
-       snd_soc_dapm_enable_pin(codec, "Earpiece");
-       snd_soc_dapm_enable_pin(codec, "Microphone");
-       snd_soc_dapm_disable_pin(codec, "Speaker");
-       snd_soc_dapm_disable_pin(codec, "AGCIN");
-       snd_soc_dapm_sync(codec);
+       snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
+       snd_soc_dapm_enable_pin(dapm, "Earpiece");
+       snd_soc_dapm_enable_pin(dapm, "Microphone");
+       snd_soc_dapm_disable_pin(dapm, "Speaker");
+       snd_soc_dapm_disable_pin(dapm, "AGCIN");
+       snd_soc_dapm_sync(dapm);
 }
 
 /* Line discipline .hangup() */
@@ -310,7 +338,10 @@ static void cx81801_receive(struct tty_struct *tty,
        const unsigned char *c;
        int apply, ret;
 
-       if (!codec->control_data) {
+       if (!codec)
+               return;
+
+       if (!codec->hw_write) {
                /* First modem response, complete setup procedure */
 
                /* Initialize timer used for config pulse generation */
@@ -323,7 +354,7 @@ static void cx81801_receive(struct tty_struct *tty,
                                        ARRAY_SIZE(ams_delta_hook_switch_pins),
                                        ams_delta_hook_switch_pins);
                if (ret)
-                       dev_warn(codec->socdev->card->dev,
+                       dev_warn(codec->dev,
                                "Failed to link hook switch to DAPM pins, "
                                "will continue with hook switch unlinked.\n");
 
@@ -383,7 +414,7 @@ static int ams_delta_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 
        /* Set cpu DAI configuration */
-       return snd_soc_dai_set_fmt(rtd->dai->cpu_dai,
+       return snd_soc_dai_set_fmt(rtd->cpu_dai,
                                   SND_SOC_DAIFMT_DSP_A |
                                   SND_SOC_DAIFMT_NB_NF |
                                   SND_SOC_DAIFMT_CBM_CFM);
@@ -398,22 +429,22 @@ static struct snd_soc_ops ams_delta_ops = {
 static int ams_delta_set_bias_level(struct snd_soc_card *card,
                                        enum snd_soc_bias_level level)
 {
-       struct snd_soc_codec *codec = card->codec;
+       struct snd_soc_codec *codec = card->rtd->codec;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
        case SND_SOC_BIAS_PREPARE:
        case SND_SOC_BIAS_STANDBY:
-               if (codec->bias_level == SND_SOC_BIAS_OFF)
+               if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
                        ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
                                                AMS_DELTA_LATCH2_MODEM_NRESET);
                break;
        case SND_SOC_BIAS_OFF:
-               if (codec->bias_level != SND_SOC_BIAS_OFF)
+               if (codec->dapm.bias_level != SND_SOC_BIAS_OFF)
                        ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
                                                0);
        }
-       codec->bias_level = level;
+       codec->dapm.bias_level = level;
 
        return 0;
 }
@@ -461,18 +492,21 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream)
  * Card initialization
  */
 
-static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
+static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_dai *codec_dai = codec->dai;
-       struct snd_soc_card *card = codec->socdev->card;
+       struct snd_soc_codec *codec = rtd->codec;
+       struct snd_soc_dapm_context *dapm = &codec->dapm;
+       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_card *card = rtd->card;
        int ret;
        /* Codec is ready, now add/activate board specific controls */
 
+       /* Store a pointer to the codec structure for tty ldisc use */
+       cx20442_codec = codec;
+
        /* Set up digital mute if not provided by the codec */
-       if (!codec_dai->ops) {
-               codec_dai->ops = &ams_delta_dai_ops;
-       } else if (!codec_dai->ops->digital_mute) {
-               codec_dai->ops->digital_mute = ams_delta_digital_mute;
+       if (!codec_dai->driver->ops) {
+               codec_dai->driver->ops = &ams_delta_dai_ops;
        } else {
                ams_delta_ops.startup = ams_delta_startup;
                ams_delta_ops.shutdown = ams_delta_shutdown;
@@ -483,7 +517,7 @@ static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
 
        /* Add hook switch - can be used to control the codec from userspace
         * even if line discipline fails */
-       ret = snd_soc_jack_new(card, "hook_switch",
+       ret = snd_soc_jack_new(rtd->codec, "hook_switch",
                                SND_JACK_HEADSET, &ams_delta_hook_switch);
        if (ret)
                dev_warn(card->dev,
@@ -509,7 +543,7 @@ static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
        }
 
        /* Add board specific DAPM widgets and routes */
-       ret = snd_soc_dapm_new_controls(codec, ams_delta_dapm_widgets,
+       ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets,
                                        ARRAY_SIZE(ams_delta_dapm_widgets));
        if (ret) {
                dev_warn(card->dev,
@@ -518,7 +552,7 @@ static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
                return 0;
        }
 
-       ret = snd_soc_dapm_add_routes(codec, ams_delta_audio_map,
+       ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map,
                                        ARRAY_SIZE(ams_delta_audio_map));
        if (ret) {
                dev_warn(card->dev,
@@ -528,13 +562,13 @@ static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
        }
 
        /* Set up initial pin constellation */
-       snd_soc_dapm_disable_pin(codec, "Mouthpiece");
-       snd_soc_dapm_enable_pin(codec, "Earpiece");
-       snd_soc_dapm_enable_pin(codec, "Microphone");
-       snd_soc_dapm_disable_pin(codec, "Speaker");
-       snd_soc_dapm_disable_pin(codec, "AGCIN");
-       snd_soc_dapm_disable_pin(codec, "AGCOUT");
-       snd_soc_dapm_sync(codec);
+       snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
+       snd_soc_dapm_enable_pin(dapm, "Earpiece");
+       snd_soc_dapm_enable_pin(dapm, "Microphone");
+       snd_soc_dapm_disable_pin(dapm, "Speaker");
+       snd_soc_dapm_disable_pin(dapm, "AGCIN");
+       snd_soc_dapm_disable_pin(dapm, "AGCOUT");
+       snd_soc_dapm_sync(dapm);
 
        /* Add virtual switch */
        ret = snd_soc_add_controls(codec, ams_delta_audio_controls,
@@ -551,27 +585,22 @@ static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
 static struct snd_soc_dai_link ams_delta_dai_link = {
        .name = "CX20442",
        .stream_name = "CX20442",
-       .cpu_dai = &omap_mcbsp_dai[0],
-       .codec_dai = &cx20442_dai,
+       .cpu_dai_name ="omap-mcbsp-dai.0",
+       .codec_dai_name = "cx20442-voice",
        .init = ams_delta_cx20442_init,
+       .platform_name = "omap-pcm-audio",
+       .codec_name = "cx20442-codec",
        .ops = &ams_delta_ops,
 };
 
 /* Audio card driver */
 static struct snd_soc_card ams_delta_audio_card = {
        .name = "AMS_DELTA",
-       .platform = &omap_soc_platform,
        .dai_link = &ams_delta_dai_link,
        .num_links = 1,
        .set_bias_level = ams_delta_set_bias_level,
 };
 
-/* Audio subsystem */
-static struct snd_soc_device ams_delta_snd_soc_device = {
-       .card = &ams_delta_audio_card,
-       .codec_dev = &cx20442_codec_dev,
-};
-
 /* Module init/exit */
 static struct platform_device *ams_delta_audio_platform_device;
 static struct platform_device *cx20442_platform_device;
@@ -589,9 +618,7 @@ static int __init ams_delta_module_init(void)
                return -ENOMEM;
 
        platform_set_drvdata(ams_delta_audio_platform_device,
-                               &ams_delta_snd_soc_device);
-       ams_delta_snd_soc_device.dev = &ams_delta_audio_platform_device->dev;
-       *(unsigned int *)ams_delta_dai_link.cpu_dai->private_data = OMAP_MCBSP1;
+                               &ams_delta_audio_card);
 
        ret = platform_device_add(ams_delta_audio_platform_device);
        if (ret)
@@ -601,8 +628,8 @@ static int __init ams_delta_module_init(void)
         * Codec platform device could be registered from elsewhere (board?),
         * but I do it here as it makes sense only if used with the card.
         */
-       cx20442_platform_device = platform_device_register_simple("cx20442",
-                                                               -1, NULL, 0);
+       cx20442_platform_device =
+               platform_device_register_simple("cx20442-codec", -1, NULL, 0);
        return 0;
 err:
        platform_device_put(ams_delta_audio_platform_device);
@@ -612,19 +639,6 @@ module_init(ams_delta_module_init);
 
 static void __exit ams_delta_module_exit(void)
 {
-       struct snd_soc_codec *codec;
-       struct tty_struct *tty;
-
-       if (ams_delta_audio_card.codec) {
-               codec = ams_delta_audio_card.codec;
-
-               if (codec->control_data) {
-                       tty = codec->control_data;
-
-                       tty_hangup(tty);
-               }
-       }
-
        if (tty_unregister_ldisc(N_V253) != 0)
                dev_warn(&ams_delta_audio_platform_device->dev,
                        "failed to unregister V253 line discipline\n");