diff options
author | Jarkko Nikula <jhnikula@gmail.com> | 2010-06-21 07:14:59 -0400 |
---|---|---|
committer | Liam Girdwood <lrg@slimlogic.co.uk> | 2010-06-23 06:29:08 -0400 |
commit | 4eb5470326ca09c0eeae4502f52375d657a585c2 (patch) | |
tree | d12a4630e0bc34da6ac368c2cc973f1897d3acc5 /sound/soc/omap/rx51.c | |
parent | 3d5a4516238ff1da81f5c38a7ddd87127487c8ca (diff) |
ASoC: RX-51: Add Jack Function kcontrol
Nokia RX-51/N900 has multifunction 4-pole audio-video jack that can be used
as headphone, headset or audio-video connector. This patch implements the
control 'Jack Function' which is used to select the desired function.
At the moment only TV-out without audio is supported.
Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/omap/rx51.c')
-rw-r--r-- | sound/soc/omap/rx51.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 47d831ef2dbb..1a2de34eecf5 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
@@ -37,14 +37,21 @@ | |||
37 | #include "omap-pcm.h" | 37 | #include "omap-pcm.h" |
38 | #include "../codecs/tlv320aic3x.h" | 38 | #include "../codecs/tlv320aic3x.h" |
39 | 39 | ||
40 | #define RX51_TVOUT_SEL_GPIO 40 | ||
40 | /* | 41 | /* |
41 | * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This | 42 | * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This |
42 | * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c | 43 | * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c |
43 | */ | 44 | */ |
44 | #define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7) | 45 | #define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7) |
45 | 46 | ||
47 | enum { | ||
48 | RX51_JACK_DISABLED, | ||
49 | RX51_JACK_TVOUT, /* tv-out */ | ||
50 | }; | ||
51 | |||
46 | static int rx51_spk_func; | 52 | static int rx51_spk_func; |
47 | static int rx51_dmic_func; | 53 | static int rx51_dmic_func; |
54 | static int rx51_jack_func; | ||
48 | 55 | ||
49 | static void rx51_ext_control(struct snd_soc_codec *codec) | 56 | static void rx51_ext_control(struct snd_soc_codec *codec) |
50 | { | 57 | { |
@@ -57,6 +64,9 @@ static void rx51_ext_control(struct snd_soc_codec *codec) | |||
57 | else | 64 | else |
58 | snd_soc_dapm_disable_pin(codec, "DMic"); | 65 | snd_soc_dapm_disable_pin(codec, "DMic"); |
59 | 66 | ||
67 | gpio_set_value(RX51_TVOUT_SEL_GPIO, | ||
68 | rx51_jack_func == RX51_JACK_TVOUT); | ||
69 | |||
60 | snd_soc_dapm_sync(codec); | 70 | snd_soc_dapm_sync(codec); |
61 | } | 71 | } |
62 | 72 | ||
@@ -162,6 +172,28 @@ static int rx51_set_input(struct snd_kcontrol *kcontrol, | |||
162 | return 1; | 172 | return 1; |
163 | } | 173 | } |
164 | 174 | ||
175 | static int rx51_get_jack(struct snd_kcontrol *kcontrol, | ||
176 | struct snd_ctl_elem_value *ucontrol) | ||
177 | { | ||
178 | ucontrol->value.integer.value[0] = rx51_jack_func; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int rx51_set_jack(struct snd_kcontrol *kcontrol, | ||
184 | struct snd_ctl_elem_value *ucontrol) | ||
185 | { | ||
186 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
187 | |||
188 | if (rx51_jack_func == ucontrol->value.integer.value[0]) | ||
189 | return 0; | ||
190 | |||
191 | rx51_jack_func = ucontrol->value.integer.value[0]; | ||
192 | rx51_ext_control(codec); | ||
193 | |||
194 | return 1; | ||
195 | } | ||
196 | |||
165 | static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { | 197 | static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { |
166 | SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event), | 198 | SND_SOC_DAPM_SPK("Ext Spk", rx51_spk_event), |
167 | SND_SOC_DAPM_MIC("DMic", NULL), | 199 | SND_SOC_DAPM_MIC("DMic", NULL), |
@@ -177,10 +209,12 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
177 | 209 | ||
178 | static const char *spk_function[] = {"Off", "On"}; | 210 | static const char *spk_function[] = {"Off", "On"}; |
179 | static const char *input_function[] = {"ADC", "Digital Mic"}; | 211 | static const char *input_function[] = {"ADC", "Digital Mic"}; |
212 | static const char *jack_function[] = {"Off", "TV-OUT"}; | ||
180 | 213 | ||
181 | static const struct soc_enum rx51_enum[] = { | 214 | static const struct soc_enum rx51_enum[] = { |
182 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), | 215 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), |
183 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function), | 216 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function), |
217 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function), | ||
184 | }; | 218 | }; |
185 | 219 | ||
186 | static const struct snd_kcontrol_new aic34_rx51_controls[] = { | 220 | static const struct snd_kcontrol_new aic34_rx51_controls[] = { |
@@ -188,6 +222,8 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = { | |||
188 | rx51_get_spk, rx51_set_spk), | 222 | rx51_get_spk, rx51_set_spk), |
189 | SOC_ENUM_EXT("Input Select", rx51_enum[1], | 223 | SOC_ENUM_EXT("Input Select", rx51_enum[1], |
190 | rx51_get_input, rx51_set_input), | 224 | rx51_get_input, rx51_set_input), |
225 | SOC_ENUM_EXT("Jack Function", rx51_enum[2], | ||
226 | rx51_get_jack, rx51_set_jack), | ||
191 | }; | 227 | }; |
192 | 228 | ||
193 | static int rx51_aic34_init(struct snd_soc_codec *codec) | 229 | static int rx51_aic34_init(struct snd_soc_codec *codec) |
@@ -259,6 +295,11 @@ static int __init rx51_soc_init(void) | |||
259 | if (!machine_is_nokia_rx51()) | 295 | if (!machine_is_nokia_rx51()) |
260 | return -ENODEV; | 296 | return -ENODEV; |
261 | 297 | ||
298 | err = gpio_request(RX51_TVOUT_SEL_GPIO, "tvout_sel"); | ||
299 | if (err) | ||
300 | goto err_gpio_tvout_sel; | ||
301 | gpio_direction_output(RX51_TVOUT_SEL_GPIO, 0); | ||
302 | |||
262 | rx51_snd_device = platform_device_alloc("soc-audio", -1); | 303 | rx51_snd_device = platform_device_alloc("soc-audio", -1); |
263 | if (!rx51_snd_device) { | 304 | if (!rx51_snd_device) { |
264 | err = -ENOMEM; | 305 | err = -ENOMEM; |
@@ -277,6 +318,8 @@ static int __init rx51_soc_init(void) | |||
277 | err2: | 318 | err2: |
278 | platform_device_put(rx51_snd_device); | 319 | platform_device_put(rx51_snd_device); |
279 | err1: | 320 | err1: |
321 | gpio_free(RX51_TVOUT_SEL_GPIO); | ||
322 | err_gpio_tvout_sel: | ||
280 | 323 | ||
281 | return err; | 324 | return err; |
282 | } | 325 | } |
@@ -284,6 +327,7 @@ err1: | |||
284 | static void __exit rx51_soc_exit(void) | 327 | static void __exit rx51_soc_exit(void) |
285 | { | 328 | { |
286 | platform_device_unregister(rx51_snd_device); | 329 | platform_device_unregister(rx51_snd_device); |
330 | gpio_free(RX51_TVOUT_SEL_GPIO); | ||
287 | } | 331 | } |
288 | 332 | ||
289 | module_init(rx51_soc_init); | 333 | module_init(rx51_soc_init); |