| OLD | NEW |
| 1 /* | 1 /* |
| 2 * tosa.c -- SoC audio for Tosa | 2 * tosa.c -- SoC audio for Tosa |
| 3 * | 3 * |
| 4 * Copyright 2005 Wolfson Microelectronics PLC. | 4 * Copyright 2005 Wolfson Microelectronics PLC. |
| 5 * Copyright 2005 Openedhand Ltd. | 5 * Copyright 2005 Openedhand Ltd. |
| 6 * | 6 * |
| 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk> | 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk> |
| 8 * Richard Purdie <richard@openedhand.com> | 8 * Richard Purdie <richard@openedhand.com> |
| 9 * | 9 * |
| 10 * This program is free software; you can redistribute it and/or modify it | 10 * This program is free software; you can redistribute it and/or modify it |
| 11 * under the terms of the GNU General Public License as published by the | 11 * under the terms of the GNU General Public License as published by the |
| 12 * Free Software Foundation; either version 2 of the License, or (at your | 12 * Free Software Foundation; either version 2 of the License, or (at your |
| 13 * option) any later version. | 13 * option) any later version. |
| 14 * | 14 * |
| 15 * GPIO's | 15 * GPIO's |
| 16 * 1 - Jack Insertion | 16 * 1 - Jack Insertion |
| 17 * 5 - Hookswitch (headset answer/hang up switch) | 17 * 5 - Hookswitch (headset answer/hang up switch) |
| 18 * | 18 * |
| 19 */ | 19 */ |
| 20 | 20 |
| 21 #include <linux/module.h> | 21 #include <linux/module.h> |
| 22 #include <linux/moduleparam.h> | 22 #include <linux/moduleparam.h> |
| 23 #include <linux/device.h> | 23 #include <linux/device.h> |
| 24 #include <linux/gpio.h> | 24 #include <linux/gpio.h> |
| 25 | 25 |
| 26 #include <sound/core.h> | 26 #include <sound/core.h> |
| 27 #include <sound/pcm.h> | 27 #include <sound/pcm.h> |
| 28 #include <sound/soc.h> | 28 #include <sound/soc.h> |
| 29 #include <sound/soc-dapm.h> | |
| 30 | 29 |
| 31 #include <asm/mach-types.h> | 30 #include <asm/mach-types.h> |
| 32 #include <mach/tosa.h> | 31 #include <mach/tosa.h> |
| 33 #include <mach/audio.h> | 32 #include <mach/audio.h> |
| 34 | 33 |
| 35 #include "../codecs/wm9712.h" | 34 #include "../codecs/wm9712.h" |
| 36 #include "pxa2xx-ac97.h" | 35 #include "pxa2xx-ac97.h" |
| 37 | 36 |
| 38 static struct snd_soc_card tosa; | 37 static struct snd_soc_card tosa; |
| 39 | 38 |
| 40 #define TOSA_HP 0 | 39 #define TOSA_HP 0 |
| 41 #define TOSA_MIC_INT 1 | 40 #define TOSA_MIC_INT 1 |
| 42 #define TOSA_HEADSET 2 | 41 #define TOSA_HEADSET 2 |
| 43 #define TOSA_HP_OFF 3 | 42 #define TOSA_HP_OFF 3 |
| 44 #define TOSA_SPK_ON 0 | 43 #define TOSA_SPK_ON 0 |
| 45 #define TOSA_SPK_OFF 1 | 44 #define TOSA_SPK_OFF 1 |
| 46 | 45 |
| 47 static int tosa_jack_func; | 46 static int tosa_jack_func; |
| 48 static int tosa_spk_func; | 47 static int tosa_spk_func; |
| 49 | 48 |
| 50 static void tosa_ext_control(struct snd_soc_codec *codec) | 49 static void tosa_ext_control(struct snd_soc_codec *codec) |
| 51 { | 50 { |
| 51 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 52 |
| 52 /* set up jack connection */ | 53 /* set up jack connection */ |
| 53 switch (tosa_jack_func) { | 54 switch (tosa_jack_func) { |
| 54 case TOSA_HP: | 55 case TOSA_HP: |
| 55 » » snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); | 56 » » snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); |
| 56 » » snd_soc_dapm_enable_pin(codec, "Headphone Jack"); | 57 » » snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); |
| 57 » » snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 58 » » snd_soc_dapm_disable_pin(dapm, "Headset Jack"); |
| 58 break; | 59 break; |
| 59 case TOSA_MIC_INT: | 60 case TOSA_MIC_INT: |
| 60 » » snd_soc_dapm_enable_pin(codec, "Mic (Internal)"); | 61 » » snd_soc_dapm_enable_pin(dapm, "Mic (Internal)"); |
| 61 » » snd_soc_dapm_disable_pin(codec, "Headphone Jack"); | 62 » » snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); |
| 62 » » snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 63 » » snd_soc_dapm_disable_pin(dapm, "Headset Jack"); |
| 63 break; | 64 break; |
| 64 case TOSA_HEADSET: | 65 case TOSA_HEADSET: |
| 65 » » snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); | 66 » » snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); |
| 66 » » snd_soc_dapm_disable_pin(codec, "Headphone Jack"); | 67 » » snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); |
| 67 » » snd_soc_dapm_enable_pin(codec, "Headset Jack"); | 68 » » snd_soc_dapm_enable_pin(dapm, "Headset Jack"); |
| 68 break; | 69 break; |
| 69 } | 70 } |
| 70 | 71 |
| 71 if (tosa_spk_func == TOSA_SPK_ON) | 72 if (tosa_spk_func == TOSA_SPK_ON) |
| 72 » » snd_soc_dapm_enable_pin(codec, "Speaker"); | 73 » » snd_soc_dapm_enable_pin(dapm, "Speaker"); |
| 73 else | 74 else |
| 74 » » snd_soc_dapm_disable_pin(codec, "Speaker"); | 75 » » snd_soc_dapm_disable_pin(dapm, "Speaker"); |
| 75 | 76 |
| 76 » snd_soc_dapm_sync(codec); | 77 » snd_soc_dapm_sync(dapm); |
| 77 } | 78 } |
| 78 | 79 |
| 79 static int tosa_startup(struct snd_pcm_substream *substream) | 80 static int tosa_startup(struct snd_pcm_substream *substream) |
| 80 { | 81 { |
| 81 struct snd_soc_pcm_runtime *rtd = substream->private_data; | 82 struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 82 struct snd_soc_codec *codec = rtd->codec; | 83 struct snd_soc_codec *codec = rtd->codec; |
| 83 | 84 |
| 84 mutex_lock(&codec->mutex); | 85 mutex_lock(&codec->mutex); |
| 85 | 86 |
| 86 /* check the jack status at stream startup */ | 87 /* check the jack status at stream startup */ |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 static const struct snd_kcontrol_new tosa_controls[] = { | 185 static const struct snd_kcontrol_new tosa_controls[] = { |
| 185 SOC_ENUM_EXT("Jack Function", tosa_enum[0], tosa_get_jack, | 186 SOC_ENUM_EXT("Jack Function", tosa_enum[0], tosa_get_jack, |
| 186 tosa_set_jack), | 187 tosa_set_jack), |
| 187 SOC_ENUM_EXT("Speaker Function", tosa_enum[1], tosa_get_spk, | 188 SOC_ENUM_EXT("Speaker Function", tosa_enum[1], tosa_get_spk, |
| 188 tosa_set_spk), | 189 tosa_set_spk), |
| 189 }; | 190 }; |
| 190 | 191 |
| 191 static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd) | 192 static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd) |
| 192 { | 193 { |
| 193 struct snd_soc_codec *codec = rtd->codec; | 194 struct snd_soc_codec *codec = rtd->codec; |
| 195 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 194 int err; | 196 int err; |
| 195 | 197 |
| 196 » snd_soc_dapm_nc_pin(codec, "OUT3"); | 198 » snd_soc_dapm_nc_pin(dapm, "OUT3"); |
| 197 » snd_soc_dapm_nc_pin(codec, "MONOOUT"); | 199 » snd_soc_dapm_nc_pin(dapm, "MONOOUT"); |
| 198 | 200 |
| 199 /* add tosa specific controls */ | 201 /* add tosa specific controls */ |
| 200 err = snd_soc_add_controls(codec, tosa_controls, | 202 err = snd_soc_add_controls(codec, tosa_controls, |
| 201 ARRAY_SIZE(tosa_controls)); | 203 ARRAY_SIZE(tosa_controls)); |
| 202 if (err < 0) | 204 if (err < 0) |
| 203 return err; | 205 return err; |
| 204 | 206 |
| 205 /* add tosa specific widgets */ | 207 /* add tosa specific widgets */ |
| 206 » snd_soc_dapm_new_controls(codec, tosa_dapm_widgets, | 208 » snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets, |
| 207 ARRAY_SIZE(tosa_dapm_widgets)); | 209 ARRAY_SIZE(tosa_dapm_widgets)); |
| 208 | 210 |
| 209 /* set up tosa specific audio path audio_map */ | 211 /* set up tosa specific audio path audio_map */ |
| 210 » snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | 212 » snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 211 | 213 |
| 212 » snd_soc_dapm_sync(codec); | 214 » snd_soc_dapm_sync(dapm); |
| 213 return 0; | 215 return 0; |
| 214 } | 216 } |
| 215 | 217 |
| 216 static struct snd_soc_dai_link tosa_dai[] = { | 218 static struct snd_soc_dai_link tosa_dai[] = { |
| 217 { | 219 { |
| 218 .name = "AC97", | 220 .name = "AC97", |
| 219 .stream_name = "AC97 HiFi", | 221 .stream_name = "AC97 HiFi", |
| 220 .cpu_dai_name = "pxa-ac97.0", | 222 .cpu_dai_name = "pxa-ac97.0", |
| 221 .codec_dai_name = "wm9712-hifi", | 223 .codec_dai_name = "wm9712-hifi", |
| 222 .platform_name = "pxa-pcm-audio", | 224 .platform_name = "pxa-pcm-audio", |
| 223 .codec_name = "wm9712-codec", | 225 .codec_name = "wm9712-codec", |
| 224 .init = tosa_ac97_init, | 226 .init = tosa_ac97_init, |
| 225 .ops = &tosa_ops, | 227 .ops = &tosa_ops, |
| 226 }, | 228 }, |
| 227 { | 229 { |
| 228 .name = "AC97 Aux", | 230 .name = "AC97 Aux", |
| 229 .stream_name = "AC97 Aux", | 231 .stream_name = "AC97 Aux", |
| 230 .cpu_dai_name = "pxa-ac97.1", | 232 .cpu_dai_name = "pxa-ac97.1", |
| 231 .codec_dai_name = "wm9712-aux", | 233 .codec_dai_name = "wm9712-aux", |
| 232 .platform_name = "pxa-pcm-audio", | 234 .platform_name = "pxa-pcm-audio", |
| 233 .codec_name = "wm9712-codec", | 235 .codec_name = "wm9712-codec", |
| 234 .ops = &tosa_ops, | 236 .ops = &tosa_ops, |
| 235 }, | 237 }, |
| 236 }; | 238 }; |
| 237 | 239 |
| 238 static int tosa_probe(struct platform_device *dev) | 240 static int tosa_probe(struct snd_soc_card *card) |
| 239 { | 241 { |
| 240 int ret; | 242 int ret; |
| 241 | 243 |
| 242 ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack"); | 244 ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack"); |
| 243 if (ret) | 245 if (ret) |
| 244 return ret; | 246 return ret; |
| 245 ret = gpio_direction_output(TOSA_GPIO_L_MUTE, 0); | 247 ret = gpio_direction_output(TOSA_GPIO_L_MUTE, 0); |
| 246 if (ret) | 248 if (ret) |
| 247 gpio_free(TOSA_GPIO_L_MUTE); | 249 gpio_free(TOSA_GPIO_L_MUTE); |
| 248 | 250 |
| 249 return ret; | 251 return ret; |
| 250 } | 252 } |
| 251 | 253 |
| 252 static int tosa_remove(struct platform_device *dev) | 254 static int tosa_remove(struct snd_soc_card *card) |
| 253 { | 255 { |
| 254 gpio_free(TOSA_GPIO_L_MUTE); | 256 gpio_free(TOSA_GPIO_L_MUTE); |
| 255 return 0; | 257 return 0; |
| 256 } | 258 } |
| 257 | 259 |
| 258 static struct snd_soc_card tosa = { | 260 static struct snd_soc_card tosa = { |
| 259 .name = "Tosa", | 261 .name = "Tosa", |
| 260 .dai_link = tosa_dai, | 262 .dai_link = tosa_dai, |
| 261 .num_links = ARRAY_SIZE(tosa_dai), | 263 .num_links = ARRAY_SIZE(tosa_dai), |
| 262 .probe = tosa_probe, | 264 .probe = tosa_probe, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 platform_device_unregister(tosa_snd_device); | 297 platform_device_unregister(tosa_snd_device); |
| 296 } | 298 } |
| 297 | 299 |
| 298 module_init(tosa_init); | 300 module_init(tosa_init); |
| 299 module_exit(tosa_exit); | 301 module_exit(tosa_exit); |
| 300 | 302 |
| 301 /* Module information */ | 303 /* Module information */ |
| 302 MODULE_AUTHOR("Richard Purdie"); | 304 MODULE_AUTHOR("Richard Purdie"); |
| 303 MODULE_DESCRIPTION("ALSA SoC Tosa"); | 305 MODULE_DESCRIPTION("ALSA SoC Tosa"); |
| 304 MODULE_LICENSE("GPL"); | 306 MODULE_LICENSE("GPL"); |
| OLD | NEW |