| OLD | NEW |
| 1 /* | 1 /* |
| 2 * corgi.c -- SoC audio for Corgi | 2 * corgi.c -- SoC audio for Corgi |
| 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 | 15 |
| 16 #include <linux/module.h> | 16 #include <linux/module.h> |
| 17 #include <linux/moduleparam.h> | 17 #include <linux/moduleparam.h> |
| 18 #include <linux/timer.h> | 18 #include <linux/timer.h> |
| 19 #include <linux/i2c.h> | 19 #include <linux/i2c.h> |
| 20 #include <linux/interrupt.h> | 20 #include <linux/interrupt.h> |
| 21 #include <linux/platform_device.h> | 21 #include <linux/platform_device.h> |
| 22 #include <linux/gpio.h> | 22 #include <linux/gpio.h> |
| 23 #include <sound/core.h> | 23 #include <sound/core.h> |
| 24 #include <sound/pcm.h> | 24 #include <sound/pcm.h> |
| 25 #include <sound/soc.h> | 25 #include <sound/soc.h> |
| 26 #include <sound/soc-dapm.h> | |
| 27 | 26 |
| 28 #include <asm/mach-types.h> | 27 #include <asm/mach-types.h> |
| 29 #include <mach/corgi.h> | 28 #include <mach/corgi.h> |
| 30 #include <mach/audio.h> | 29 #include <mach/audio.h> |
| 31 | 30 |
| 32 #include "../codecs/wm8731.h" | 31 #include "../codecs/wm8731.h" |
| 33 #include "pxa2xx-i2s.h" | 32 #include "pxa2xx-i2s.h" |
| 34 | 33 |
| 35 #define CORGI_HP 0 | 34 #define CORGI_HP 0 |
| 36 #define CORGI_MIC 1 | 35 #define CORGI_MIC 1 |
| 37 #define CORGI_LINE 2 | 36 #define CORGI_LINE 2 |
| 38 #define CORGI_HEADSET 3 | 37 #define CORGI_HEADSET 3 |
| 39 #define CORGI_HP_OFF 4 | 38 #define CORGI_HP_OFF 4 |
| 40 #define CORGI_SPK_ON 0 | 39 #define CORGI_SPK_ON 0 |
| 41 #define CORGI_SPK_OFF 1 | 40 #define CORGI_SPK_OFF 1 |
| 42 | 41 |
| 43 /* audio clock in Hz - rounded from 12.235MHz */ | 42 /* audio clock in Hz - rounded from 12.235MHz */ |
| 44 #define CORGI_AUDIO_CLOCK 12288000 | 43 #define CORGI_AUDIO_CLOCK 12288000 |
| 45 | 44 |
| 46 static int corgi_jack_func; | 45 static int corgi_jack_func; |
| 47 static int corgi_spk_func; | 46 static int corgi_spk_func; |
| 48 | 47 |
| 49 static void corgi_ext_control(struct snd_soc_codec *codec) | 48 static void corgi_ext_control(struct snd_soc_codec *codec) |
| 50 { | 49 { |
| 50 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 51 |
| 51 /* set up jack connection */ | 52 /* set up jack connection */ |
| 52 switch (corgi_jack_func) { | 53 switch (corgi_jack_func) { |
| 53 case CORGI_HP: | 54 case CORGI_HP: |
| 54 /* set = unmute headphone */ | 55 /* set = unmute headphone */ |
| 55 gpio_set_value(CORGI_GPIO_MUTE_L, 1); | 56 gpio_set_value(CORGI_GPIO_MUTE_L, 1); |
| 56 gpio_set_value(CORGI_GPIO_MUTE_R, 1); | 57 gpio_set_value(CORGI_GPIO_MUTE_R, 1); |
| 57 » » snd_soc_dapm_disable_pin(codec, "Mic Jack"); | 58 » » snd_soc_dapm_disable_pin(dapm, "Mic Jack"); |
| 58 » » snd_soc_dapm_disable_pin(codec, "Line Jack"); | 59 » » snd_soc_dapm_disable_pin(dapm, "Line Jack"); |
| 59 » » snd_soc_dapm_enable_pin(codec, "Headphone Jack"); | 60 » » snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); |
| 60 » » snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 61 » » snd_soc_dapm_disable_pin(dapm, "Headset Jack"); |
| 61 break; | 62 break; |
| 62 case CORGI_MIC: | 63 case CORGI_MIC: |
| 63 /* reset = mute headphone */ | 64 /* reset = mute headphone */ |
| 64 gpio_set_value(CORGI_GPIO_MUTE_L, 0); | 65 gpio_set_value(CORGI_GPIO_MUTE_L, 0); |
| 65 gpio_set_value(CORGI_GPIO_MUTE_R, 0); | 66 gpio_set_value(CORGI_GPIO_MUTE_R, 0); |
| 66 » » snd_soc_dapm_enable_pin(codec, "Mic Jack"); | 67 » » snd_soc_dapm_enable_pin(dapm, "Mic Jack"); |
| 67 » » snd_soc_dapm_disable_pin(codec, "Line Jack"); | 68 » » snd_soc_dapm_disable_pin(dapm, "Line Jack"); |
| 68 » » snd_soc_dapm_disable_pin(codec, "Headphone Jack"); | 69 » » snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); |
| 69 » » snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 70 » » snd_soc_dapm_disable_pin(dapm, "Headset Jack"); |
| 70 break; | 71 break; |
| 71 case CORGI_LINE: | 72 case CORGI_LINE: |
| 72 gpio_set_value(CORGI_GPIO_MUTE_L, 0); | 73 gpio_set_value(CORGI_GPIO_MUTE_L, 0); |
| 73 gpio_set_value(CORGI_GPIO_MUTE_R, 0); | 74 gpio_set_value(CORGI_GPIO_MUTE_R, 0); |
| 74 » » snd_soc_dapm_disable_pin(codec, "Mic Jack"); | 75 » » snd_soc_dapm_disable_pin(dapm, "Mic Jack"); |
| 75 » » snd_soc_dapm_enable_pin(codec, "Line Jack"); | 76 » » snd_soc_dapm_enable_pin(dapm, "Line Jack"); |
| 76 » » snd_soc_dapm_disable_pin(codec, "Headphone Jack"); | 77 » » snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); |
| 77 » » snd_soc_dapm_disable_pin(codec, "Headset Jack"); | 78 » » snd_soc_dapm_disable_pin(dapm, "Headset Jack"); |
| 78 break; | 79 break; |
| 79 case CORGI_HEADSET: | 80 case CORGI_HEADSET: |
| 80 gpio_set_value(CORGI_GPIO_MUTE_L, 0); | 81 gpio_set_value(CORGI_GPIO_MUTE_L, 0); |
| 81 gpio_set_value(CORGI_GPIO_MUTE_R, 1); | 82 gpio_set_value(CORGI_GPIO_MUTE_R, 1); |
| 82 » » snd_soc_dapm_enable_pin(codec, "Mic Jack"); | 83 » » snd_soc_dapm_enable_pin(dapm, "Mic Jack"); |
| 83 » » snd_soc_dapm_disable_pin(codec, "Line Jack"); | 84 » » snd_soc_dapm_disable_pin(dapm, "Line Jack"); |
| 84 » » snd_soc_dapm_disable_pin(codec, "Headphone Jack"); | 85 » » snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); |
| 85 » » snd_soc_dapm_enable_pin(codec, "Headset Jack"); | 86 » » snd_soc_dapm_enable_pin(dapm, "Headset Jack"); |
| 86 break; | 87 break; |
| 87 } | 88 } |
| 88 | 89 |
| 89 if (corgi_spk_func == CORGI_SPK_ON) | 90 if (corgi_spk_func == CORGI_SPK_ON) |
| 90 » » snd_soc_dapm_enable_pin(codec, "Ext Spk"); | 91 » » snd_soc_dapm_enable_pin(dapm, "Ext Spk"); |
| 91 else | 92 else |
| 92 » » snd_soc_dapm_disable_pin(codec, "Ext Spk"); | 93 » » snd_soc_dapm_disable_pin(dapm, "Ext Spk"); |
| 93 | 94 |
| 94 /* signal a DAPM event */ | 95 /* signal a DAPM event */ |
| 95 » snd_soc_dapm_sync(codec); | 96 » snd_soc_dapm_sync(dapm); |
| 96 } | 97 } |
| 97 | 98 |
| 98 static int corgi_startup(struct snd_pcm_substream *substream) | 99 static int corgi_startup(struct snd_pcm_substream *substream) |
| 99 { | 100 { |
| 100 struct snd_soc_pcm_runtime *rtd = substream->private_data; | 101 struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 101 struct snd_soc_codec *codec = rtd->codec; | 102 struct snd_soc_codec *codec = rtd->codec; |
| 102 | 103 |
| 103 mutex_lock(&codec->mutex); | 104 mutex_lock(&codec->mutex); |
| 104 | 105 |
| 105 /* check the jack status at stream startup */ | 106 /* check the jack status at stream startup */ |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 SOC_ENUM_EXT("Speaker Function", corgi_enum[1], corgi_get_spk, | 273 SOC_ENUM_EXT("Speaker Function", corgi_enum[1], corgi_get_spk, |
| 273 corgi_set_spk), | 274 corgi_set_spk), |
| 274 }; | 275 }; |
| 275 | 276 |
| 276 /* | 277 /* |
| 277 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device | 278 * Logic for a wm8731 as connected on a Sharp SL-C7x0 Device |
| 278 */ | 279 */ |
| 279 static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) | 280 static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) |
| 280 { | 281 { |
| 281 struct snd_soc_codec *codec = rtd->codec; | 282 struct snd_soc_codec *codec = rtd->codec; |
| 283 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 282 int err; | 284 int err; |
| 283 | 285 |
| 284 » snd_soc_dapm_nc_pin(codec, "LLINEIN"); | 286 » snd_soc_dapm_nc_pin(dapm, "LLINEIN"); |
| 285 » snd_soc_dapm_nc_pin(codec, "RLINEIN"); | 287 » snd_soc_dapm_nc_pin(dapm, "RLINEIN"); |
| 286 | 288 |
| 287 /* Add corgi specific controls */ | 289 /* Add corgi specific controls */ |
| 288 err = snd_soc_add_controls(codec, wm8731_corgi_controls, | 290 err = snd_soc_add_controls(codec, wm8731_corgi_controls, |
| 289 ARRAY_SIZE(wm8731_corgi_controls)); | 291 ARRAY_SIZE(wm8731_corgi_controls)); |
| 290 if (err < 0) | 292 if (err < 0) |
| 291 return err; | 293 return err; |
| 292 | 294 |
| 293 /* Add corgi specific widgets */ | 295 /* Add corgi specific widgets */ |
| 294 » snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, | 296 » snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, |
| 295 ARRAY_SIZE(wm8731_dapm_widgets)); | 297 ARRAY_SIZE(wm8731_dapm_widgets)); |
| 296 | 298 |
| 297 /* Set up corgi specific audio path audio_map */ | 299 /* Set up corgi specific audio path audio_map */ |
| 298 » snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | 300 » snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 299 | 301 |
| 300 » snd_soc_dapm_sync(codec); | 302 » snd_soc_dapm_sync(dapm); |
| 301 return 0; | 303 return 0; |
| 302 } | 304 } |
| 303 | 305 |
| 304 /* corgi digital audio interface glue - connects codec <--> CPU */ | 306 /* corgi digital audio interface glue - connects codec <--> CPU */ |
| 305 static struct snd_soc_dai_link corgi_dai = { | 307 static struct snd_soc_dai_link corgi_dai = { |
| 306 .name = "WM8731", | 308 .name = "WM8731", |
| 307 .stream_name = "WM8731", | 309 .stream_name = "WM8731", |
| 308 » .cpu_dai_name = "pxa-is2-dai", | 310 » .cpu_dai_name = "pxa2xx-i2s", |
| 309 .codec_dai_name = "wm8731-hifi", | 311 .codec_dai_name = "wm8731-hifi", |
| 310 .platform_name = "pxa-pcm-audio", | 312 .platform_name = "pxa-pcm-audio", |
| 311 » .codec_name = "wm8731-codec-0.001a", | 313 » .codec_name = "wm8731-codec-0.001b", |
| 312 .init = corgi_wm8731_init, | 314 .init = corgi_wm8731_init, |
| 313 .ops = &corgi_ops, | 315 .ops = &corgi_ops, |
| 314 }; | 316 }; |
| 315 | 317 |
| 316 /* corgi audio machine driver */ | 318 /* corgi audio machine driver */ |
| 317 static struct snd_soc_card snd_soc_corgi = { | 319 static struct snd_soc_card snd_soc_corgi = { |
| 318 .name = "Corgi", | 320 .name = "Corgi", |
| 319 .dai_link = &corgi_dai, | 321 .dai_link = &corgi_dai, |
| 320 .num_links = 1, | 322 .num_links = 1, |
| 321 }; | 323 }; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 348 platform_device_unregister(corgi_snd_device); | 350 platform_device_unregister(corgi_snd_device); |
| 349 } | 351 } |
| 350 | 352 |
| 351 module_init(corgi_init); | 353 module_init(corgi_init); |
| 352 module_exit(corgi_exit); | 354 module_exit(corgi_exit); |
| 353 | 355 |
| 354 /* Module information */ | 356 /* Module information */ |
| 355 MODULE_AUTHOR("Richard Purdie"); | 357 MODULE_AUTHOR("Richard Purdie"); |
| 356 MODULE_DESCRIPTION("ALSA SoC Corgi"); | 358 MODULE_DESCRIPTION("ALSA SoC Corgi"); |
| 357 MODULE_LICENSE("GPL"); | 359 MODULE_LICENSE("GPL"); |
| OLD | NEW |