ASoC: machine driver for Toshiba e750
[safe/jmp/linux-2.6] / sound / soc / pxa / corgi.c
index edeea63..1ba25a5 100644 (file)
@@ -4,7 +4,7 @@
  * Copyright 2005 Wolfson Microelectronics PLC.
  * Copyright 2005 Openedhand Ltd.
  *
- * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
  *          Richard Purdie <richard@openedhand.com>
  *
  *  This program is free software; you can redistribute  it and/or modify it
 #include <linux/timer.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
 
 #include <asm/mach-types.h>
-#include <asm/hardware/scoop.h>
-#include <asm/arch/pxa-regs.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/corgi.h>
-#include <asm/arch/audio.h>
+#include <mach/pxa-regs.h>
+#include <mach/hardware.h>
+#include <mach/corgi.h>
+#include <mach/audio.h>
 
 #include "../codecs/wm8731.h"
 #include "pxa2xx-pcm.h"
@@ -50,47 +50,51 @@ static int corgi_spk_func;
 
 static void corgi_ext_control(struct snd_soc_codec *codec)
 {
-       int spk = 0, mic = 0, line = 0, hp = 0, hs = 0;
-
        /* set up jack connection */
        switch (corgi_jack_func) {
        case CORGI_HP:
-               hp = 1;
                /* set = unmute headphone */
-               set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-               set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+               gpio_set_value(CORGI_GPIO_MUTE_L, 1);
+               gpio_set_value(CORGI_GPIO_MUTE_R, 1);
+               snd_soc_dapm_disable_pin(codec, "Mic Jack");
+               snd_soc_dapm_disable_pin(codec, "Line Jack");
+               snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+               snd_soc_dapm_disable_pin(codec, "Headset Jack");
                break;
        case CORGI_MIC:
-               mic = 1;
                /* reset = mute headphone */
-               reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-               reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+               gpio_set_value(CORGI_GPIO_MUTE_L, 0);
+               gpio_set_value(CORGI_GPIO_MUTE_R, 0);
+               snd_soc_dapm_enable_pin(codec, "Mic Jack");
+               snd_soc_dapm_disable_pin(codec, "Line Jack");
+               snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+               snd_soc_dapm_disable_pin(codec, "Headset Jack");
                break;
        case CORGI_LINE:
-               line = 1;
-               reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-               reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+               gpio_set_value(CORGI_GPIO_MUTE_L, 0);
+               gpio_set_value(CORGI_GPIO_MUTE_R, 0);
+               snd_soc_dapm_disable_pin(codec, "Mic Jack");
+               snd_soc_dapm_enable_pin(codec, "Line Jack");
+               snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+               snd_soc_dapm_disable_pin(codec, "Headset Jack");
                break;
        case CORGI_HEADSET:
-               hs = 1;
-               mic = 1;
-               reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-               set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
+               gpio_set_value(CORGI_GPIO_MUTE_L, 0);
+               gpio_set_value(CORGI_GPIO_MUTE_R, 1);
+               snd_soc_dapm_enable_pin(codec, "Mic Jack");
+               snd_soc_dapm_disable_pin(codec, "Line Jack");
+               snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+               snd_soc_dapm_enable_pin(codec, "Headset Jack");
                break;
        }
 
        if (corgi_spk_func == CORGI_SPK_ON)
-               spk = 1;
-
-       /* set the enpoints to their new connetion states */
-       snd_soc_dapm_set_endpoint(codec, "Ext Spk", spk);
-       snd_soc_dapm_set_endpoint(codec, "Mic Jack", mic);
-       snd_soc_dapm_set_endpoint(codec, "Line Jack", line);
-       snd_soc_dapm_set_endpoint(codec, "Headphone Jack", hp);
-       snd_soc_dapm_set_endpoint(codec, "Headset Jack", hs);
+               snd_soc_dapm_enable_pin(codec, "Ext Spk");
+       else
+               snd_soc_dapm_disable_pin(codec, "Ext Spk");
 
        /* signal a DAPM event */
-       snd_soc_dapm_sync_endpoints(codec);
+       snd_soc_dapm_sync(codec);
 }
 
 static int corgi_startup(struct snd_pcm_substream *substream)
@@ -104,23 +108,19 @@ static int corgi_startup(struct snd_pcm_substream *substream)
 }
 
 /* we need to unmute the HP at shutdown as the mute burns power on corgi */
-static int corgi_shutdown(struct snd_pcm_substream *substream)
+static void corgi_shutdown(struct snd_pcm_substream *substream)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->socdev->codec;
-
        /* set = unmute headphone */
-       set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L);
-       set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R);
-       return 0;
+       gpio_set_value(CORGI_GPIO_MUTE_L, 1);
+       gpio_set_value(CORGI_GPIO_MUTE_R, 1);
 }
 
 static int corgi_hw_params(struct snd_pcm_substream *substream,
        struct snd_pcm_hw_params *params)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai;
-       struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
        unsigned int clk = 0;
        int ret = 0;
 
@@ -139,25 +139,25 @@ static int corgi_hw_params(struct snd_pcm_substream *substream,
        }
 
        /* set codec DAI configuration */
-       ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
                SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
        if (ret < 0)
                return ret;
 
        /* set cpu DAI configuration */
-       ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
                SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
        if (ret < 0)
                return ret;
 
        /* set the codec system clock for DAC and ADC */
-       ret = codec_dai->dai_ops.set_sysclk(codec_dai, WM8731_SYSCLK, clk,
+       ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK, clk,
                SND_SOC_CLOCK_IN);
        if (ret < 0)
                return ret;
 
        /* set the I2S system clock as input (unused) */
-       ret = cpu_dai->dai_ops.set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
+       ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0,
                SND_SOC_CLOCK_IN);
        if (ret < 0)
                return ret;
@@ -214,22 +214,14 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol,
 static int corgi_amp_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *k, int event)
 {
-       if (SND_SOC_DAPM_EVENT_ON(event))
-               set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
-       else
-               reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
-
+       gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
        return 0;
 }
 
 static int corgi_mic_event(struct snd_soc_dapm_widget *w,
        struct snd_kcontrol *k, int event)
 {
-       if (SND_SOC_DAPM_EVENT_ON(event))
-               set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
-       else
-               reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
-
+       gpio_set_value(CORGI_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
        return 0;
 }
 
@@ -285,8 +277,8 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
 {
        int i, err;
 
-       snd_soc_dapm_set_endpoint(codec, "LLINEIN", 0);
-       snd_soc_dapm_set_endpoint(codec, "RLINEIN", 0);
+       snd_soc_dapm_nc_pin(codec, "LLINEIN");
+       snd_soc_dapm_nc_pin(codec, "RLINEIN");
 
        /* Add corgi specific controls */
        for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) {
@@ -303,7 +295,7 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
        /* Set up corgi specific audio path audio_map */
        snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
 
-       snd_soc_dapm_sync_endpoints(codec);
+       snd_soc_dapm_sync(codec);
        return 0;
 }
 
@@ -318,21 +310,22 @@ static struct snd_soc_dai_link corgi_dai = {
 };
 
 /* corgi audio machine driver */
-static struct snd_soc_machine snd_soc_machine_corgi = {
+static struct snd_soc_card snd_soc_corgi = {
        .name = "Corgi",
+       .platform = &pxa2xx_soc_platform,
        .dai_link = &corgi_dai,
        .num_links = 1,
 };
 
 /* corgi audio private data */
 static struct wm8731_setup_data corgi_wm8731_setup = {
+       .i2c_bus = 0,
        .i2c_address = 0x1b,
 };
 
 /* corgi audio subsystem */
 static struct snd_soc_device corgi_snd_devdata = {
-       .machine = &snd_soc_machine_corgi,
-       .platform = &pxa2xx_soc_platform,
+       .card = &snd_soc_corgi,
        .codec_dev = &soc_codec_dev_wm8731,
        .codec_data = &corgi_wm8731_setup,
 };