diff options
Diffstat (limited to 'sound/soc/omap/n810.c')
-rw-r--r-- | sound/soc/omap/n810.c | 106 |
1 files changed, 76 insertions, 30 deletions
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 6533563a6011..02cec96859b8 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c | |||
@@ -30,15 +30,15 @@ | |||
30 | 30 | ||
31 | #include <asm/mach-types.h> | 31 | #include <asm/mach-types.h> |
32 | #include <asm/arch/hardware.h> | 32 | #include <asm/arch/hardware.h> |
33 | #include <asm/arch/gpio.h> | 33 | #include <linux/gpio.h> |
34 | #include <asm/arch/mcbsp.h> | 34 | #include <asm/arch/mcbsp.h> |
35 | 35 | ||
36 | #include "omap-mcbsp.h" | 36 | #include "omap-mcbsp.h" |
37 | #include "omap-pcm.h" | 37 | #include "omap-pcm.h" |
38 | #include "../codecs/tlv320aic3x.h" | 38 | #include "../codecs/tlv320aic3x.h" |
39 | 39 | ||
40 | #define RX44_HEADSET_AMP_GPIO 10 | 40 | #define N810_HEADSET_AMP_GPIO 10 |
41 | #define RX44_SPEAKER_AMP_GPIO 101 | 41 | #define N810_SPEAKER_AMP_GPIO 101 |
42 | 42 | ||
43 | static struct clk *sys_clkout2; | 43 | static struct clk *sys_clkout2; |
44 | static struct clk *sys_clkout2_src; | 44 | static struct clk *sys_clkout2_src; |
@@ -46,13 +46,26 @@ static struct clk *func96m_clk; | |||
46 | 46 | ||
47 | static int n810_spk_func; | 47 | static int n810_spk_func; |
48 | static int n810_jack_func; | 48 | static int n810_jack_func; |
49 | static int n810_dmic_func; | ||
49 | 50 | ||
50 | static void n810_ext_control(struct snd_soc_codec *codec) | 51 | static void n810_ext_control(struct snd_soc_codec *codec) |
51 | { | 52 | { |
52 | snd_soc_dapm_set_endpoint(codec, "Ext Spk", n810_spk_func); | 53 | if (n810_spk_func) |
53 | snd_soc_dapm_set_endpoint(codec, "Headphone Jack", n810_jack_func); | 54 | snd_soc_dapm_enable_pin(codec, "Ext Spk"); |
55 | else | ||
56 | snd_soc_dapm_disable_pin(codec, "Ext Spk"); | ||
57 | |||
58 | if (n810_jack_func) | ||
59 | snd_soc_dapm_enable_pin(codec, "Headphone Jack"); | ||
60 | else | ||
61 | snd_soc_dapm_disable_pin(codec, "Headphone Jack"); | ||
54 | 62 | ||
55 | snd_soc_dapm_sync_endpoints(codec); | 63 | if (n810_dmic_func) |
64 | snd_soc_dapm_enable_pin(codec, "DMic"); | ||
65 | else | ||
66 | snd_soc_dapm_disable_pin(codec, "DMic"); | ||
67 | |||
68 | snd_soc_dapm_sync(codec); | ||
56 | } | 69 | } |
57 | 70 | ||
58 | static int n810_startup(struct snd_pcm_substream *substream) | 71 | static int n810_startup(struct snd_pcm_substream *substream) |
@@ -73,12 +86,12 @@ static int n810_hw_params(struct snd_pcm_substream *substream, | |||
73 | struct snd_pcm_hw_params *params) | 86 | struct snd_pcm_hw_params *params) |
74 | { | 87 | { |
75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 88 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
76 | struct snd_soc_codec_dai *codec_dai = rtd->dai->codec_dai; | 89 | struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; |
77 | struct snd_soc_cpu_dai *cpu_dai = rtd->dai->cpu_dai; | 90 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; |
78 | int err; | 91 | int err; |
79 | 92 | ||
80 | /* Set codec DAI configuration */ | 93 | /* Set codec DAI configuration */ |
81 | err = codec_dai->dai_ops.set_fmt(codec_dai, | 94 | err = snd_soc_dai_set_fmt(codec_dai, |
82 | SND_SOC_DAIFMT_I2S | | 95 | SND_SOC_DAIFMT_I2S | |
83 | SND_SOC_DAIFMT_NB_NF | | 96 | SND_SOC_DAIFMT_NB_NF | |
84 | SND_SOC_DAIFMT_CBM_CFM); | 97 | SND_SOC_DAIFMT_CBM_CFM); |
@@ -86,7 +99,7 @@ static int n810_hw_params(struct snd_pcm_substream *substream, | |||
86 | return err; | 99 | return err; |
87 | 100 | ||
88 | /* Set cpu DAI configuration */ | 101 | /* Set cpu DAI configuration */ |
89 | err = cpu_dai->dai_ops.set_fmt(cpu_dai, | 102 | err = snd_soc_dai_set_fmt(cpu_dai, |
90 | SND_SOC_DAIFMT_I2S | | 103 | SND_SOC_DAIFMT_I2S | |
91 | SND_SOC_DAIFMT_NB_NF | | 104 | SND_SOC_DAIFMT_NB_NF | |
92 | SND_SOC_DAIFMT_CBM_CFM); | 105 | SND_SOC_DAIFMT_CBM_CFM); |
@@ -94,7 +107,7 @@ static int n810_hw_params(struct snd_pcm_substream *substream, | |||
94 | return err; | 107 | return err; |
95 | 108 | ||
96 | /* Set the codec system clock for DAC and ADC */ | 109 | /* Set the codec system clock for DAC and ADC */ |
97 | err = codec_dai->dai_ops.set_sysclk(codec_dai, 0, 12000000, | 110 | err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000, |
98 | SND_SOC_CLOCK_IN); | 111 | SND_SOC_CLOCK_IN); |
99 | 112 | ||
100 | return err; | 113 | return err; |
@@ -150,13 +163,35 @@ static int n810_set_jack(struct snd_kcontrol *kcontrol, | |||
150 | return 1; | 163 | return 1; |
151 | } | 164 | } |
152 | 165 | ||
166 | static int n810_get_input(struct snd_kcontrol *kcontrol, | ||
167 | struct snd_ctl_elem_value *ucontrol) | ||
168 | { | ||
169 | ucontrol->value.integer.value[0] = n810_dmic_func; | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | static int n810_set_input(struct snd_kcontrol *kcontrol, | ||
175 | struct snd_ctl_elem_value *ucontrol) | ||
176 | { | ||
177 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
178 | |||
179 | if (n810_dmic_func == ucontrol->value.integer.value[0]) | ||
180 | return 0; | ||
181 | |||
182 | n810_dmic_func = ucontrol->value.integer.value[0]; | ||
183 | n810_ext_control(codec); | ||
184 | |||
185 | return 1; | ||
186 | } | ||
187 | |||
153 | static int n810_spk_event(struct snd_soc_dapm_widget *w, | 188 | static int n810_spk_event(struct snd_soc_dapm_widget *w, |
154 | struct snd_kcontrol *k, int event) | 189 | struct snd_kcontrol *k, int event) |
155 | { | 190 | { |
156 | if (SND_SOC_DAPM_EVENT_ON(event)) | 191 | if (SND_SOC_DAPM_EVENT_ON(event)) |
157 | omap_set_gpio_dataout(RX44_SPEAKER_AMP_GPIO, 1); | 192 | gpio_set_value(N810_SPEAKER_AMP_GPIO, 1); |
158 | else | 193 | else |
159 | omap_set_gpio_dataout(RX44_SPEAKER_AMP_GPIO, 0); | 194 | gpio_set_value(N810_SPEAKER_AMP_GPIO, 0); |
160 | 195 | ||
161 | return 0; | 196 | return 0; |
162 | } | 197 | } |
@@ -165,9 +200,9 @@ static int n810_jack_event(struct snd_soc_dapm_widget *w, | |||
165 | struct snd_kcontrol *k, int event) | 200 | struct snd_kcontrol *k, int event) |
166 | { | 201 | { |
167 | if (SND_SOC_DAPM_EVENT_ON(event)) | 202 | if (SND_SOC_DAPM_EVENT_ON(event)) |
168 | omap_set_gpio_dataout(RX44_HEADSET_AMP_GPIO, 1); | 203 | gpio_set_value(N810_HEADSET_AMP_GPIO, 1); |
169 | else | 204 | else |
170 | omap_set_gpio_dataout(RX44_HEADSET_AMP_GPIO, 0); | 205 | gpio_set_value(N810_HEADSET_AMP_GPIO, 0); |
171 | 206 | ||
172 | return 0; | 207 | return 0; |
173 | } | 208 | } |
@@ -175,21 +210,27 @@ static int n810_jack_event(struct snd_soc_dapm_widget *w, | |||
175 | static const struct snd_soc_dapm_widget aic33_dapm_widgets[] = { | 210 | static const struct snd_soc_dapm_widget aic33_dapm_widgets[] = { |
176 | SND_SOC_DAPM_SPK("Ext Spk", n810_spk_event), | 211 | SND_SOC_DAPM_SPK("Ext Spk", n810_spk_event), |
177 | SND_SOC_DAPM_HP("Headphone Jack", n810_jack_event), | 212 | SND_SOC_DAPM_HP("Headphone Jack", n810_jack_event), |
213 | SND_SOC_DAPM_MIC("DMic", NULL), | ||
178 | }; | 214 | }; |
179 | 215 | ||
180 | static const char *audio_map[][3] = { | 216 | static const struct snd_soc_dapm_route audio_map[] = { |
181 | {"Headphone Jack", NULL, "HPLOUT"}, | 217 | {"Headphone Jack", NULL, "HPLOUT"}, |
182 | {"Headphone Jack", NULL, "HPROUT"}, | 218 | {"Headphone Jack", NULL, "HPROUT"}, |
183 | 219 | ||
184 | {"Ext Spk", NULL, "LLOUT"}, | 220 | {"Ext Spk", NULL, "LLOUT"}, |
185 | {"Ext Spk", NULL, "RLOUT"}, | 221 | {"Ext Spk", NULL, "RLOUT"}, |
222 | |||
223 | {"DMic Rate 64", NULL, "Mic Bias 2V"}, | ||
224 | {"Mic Bias 2V", NULL, "DMic"}, | ||
186 | }; | 225 | }; |
187 | 226 | ||
188 | static const char *spk_function[] = {"Off", "On"}; | 227 | static const char *spk_function[] = {"Off", "On"}; |
189 | static const char *jack_function[] = {"Off", "Headphone"}; | 228 | static const char *jack_function[] = {"Off", "Headphone"}; |
229 | static const char *input_function[] = {"ADC", "Digital Mic"}; | ||
190 | static const struct soc_enum n810_enum[] = { | 230 | static const struct soc_enum n810_enum[] = { |
191 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), | 231 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), |
192 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function), | 232 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(jack_function), jack_function), |
233 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(input_function), input_function), | ||
193 | }; | 234 | }; |
194 | 235 | ||
195 | static const struct snd_kcontrol_new aic33_n810_controls[] = { | 236 | static const struct snd_kcontrol_new aic33_n810_controls[] = { |
@@ -197,6 +238,8 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = { | |||
197 | n810_get_spk, n810_set_spk), | 238 | n810_get_spk, n810_set_spk), |
198 | SOC_ENUM_EXT("Jack Function", n810_enum[1], | 239 | SOC_ENUM_EXT("Jack Function", n810_enum[1], |
199 | n810_get_jack, n810_set_jack), | 240 | n810_get_jack, n810_set_jack), |
241 | SOC_ENUM_EXT("Input Select", n810_enum[2], | ||
242 | n810_get_input, n810_set_input), | ||
200 | }; | 243 | }; |
201 | 244 | ||
202 | static int n810_aic33_init(struct snd_soc_codec *codec) | 245 | static int n810_aic33_init(struct snd_soc_codec *codec) |
@@ -204,9 +247,9 @@ static int n810_aic33_init(struct snd_soc_codec *codec) | |||
204 | int i, err; | 247 | int i, err; |
205 | 248 | ||
206 | /* Not connected */ | 249 | /* Not connected */ |
207 | snd_soc_dapm_set_endpoint(codec, "MONO_LOUT", 0); | 250 | snd_soc_dapm_disable_pin(codec, "MONO_LOUT"); |
208 | snd_soc_dapm_set_endpoint(codec, "HPLCOM", 0); | 251 | snd_soc_dapm_disable_pin(codec, "HPLCOM"); |
209 | snd_soc_dapm_set_endpoint(codec, "HPRCOM", 0); | 252 | snd_soc_dapm_disable_pin(codec, "HPRCOM"); |
210 | 253 | ||
211 | /* Add N810 specific controls */ | 254 | /* Add N810 specific controls */ |
212 | for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) { | 255 | for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) { |
@@ -217,15 +260,13 @@ static int n810_aic33_init(struct snd_soc_codec *codec) | |||
217 | } | 260 | } |
218 | 261 | ||
219 | /* Add N810 specific widgets */ | 262 | /* Add N810 specific widgets */ |
220 | for (i = 0; i < ARRAY_SIZE(aic33_dapm_widgets); i++) | 263 | snd_soc_dapm_new_controls(codec, aic33_dapm_widgets, |
221 | snd_soc_dapm_new_control(codec, &aic33_dapm_widgets[i]); | 264 | ARRAY_SIZE(aic33_dapm_widgets)); |
222 | 265 | ||
223 | /* Set up N810 specific audio path audio_map */ | 266 | /* Set up N810 specific audio path audio_map */ |
224 | for (i = 0; i < ARRAY_SIZE(audio_map); i++) | 267 | snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); |
225 | snd_soc_dapm_connect_input(codec, audio_map[i][0], | ||
226 | audio_map[i][1], audio_map[i][2]); | ||
227 | 268 | ||
228 | snd_soc_dapm_sync_endpoints(codec); | 269 | snd_soc_dapm_sync(codec); |
229 | 270 | ||
230 | return 0; | 271 | return 0; |
231 | } | 272 | } |
@@ -250,6 +291,8 @@ static struct snd_soc_machine snd_soc_machine_n810 = { | |||
250 | /* Audio private data */ | 291 | /* Audio private data */ |
251 | static struct aic3x_setup_data n810_aic33_setup = { | 292 | static struct aic3x_setup_data n810_aic33_setup = { |
252 | .i2c_address = 0x18, | 293 | .i2c_address = 0x18, |
294 | .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED, | ||
295 | .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT, | ||
253 | }; | 296 | }; |
254 | 297 | ||
255 | /* Audio subsystem */ | 298 | /* Audio subsystem */ |
@@ -267,7 +310,7 @@ static int __init n810_soc_init(void) | |||
267 | int err; | 310 | int err; |
268 | struct device *dev; | 311 | struct device *dev; |
269 | 312 | ||
270 | if (!machine_is_nokia_n810()) | 313 | if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax())) |
271 | return -ENODEV; | 314 | return -ENODEV; |
272 | 315 | ||
273 | n810_snd_device = platform_device_alloc("soc-audio", -1); | 316 | n810_snd_device = platform_device_alloc("soc-audio", -1); |
@@ -305,12 +348,12 @@ static int __init n810_soc_init(void) | |||
305 | clk_set_parent(sys_clkout2_src, func96m_clk); | 348 | clk_set_parent(sys_clkout2_src, func96m_clk); |
306 | clk_set_rate(sys_clkout2, 12000000); | 349 | clk_set_rate(sys_clkout2, 12000000); |
307 | 350 | ||
308 | if (omap_request_gpio(RX44_HEADSET_AMP_GPIO) < 0) | 351 | if (gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) |
309 | BUG(); | 352 | BUG(); |
310 | if (omap_request_gpio(RX44_SPEAKER_AMP_GPIO) < 0) | 353 | if (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0) |
311 | BUG(); | 354 | BUG(); |
312 | omap_set_gpio_direction(RX44_HEADSET_AMP_GPIO, 0); | 355 | gpio_direction_output(N810_HEADSET_AMP_GPIO, 0); |
313 | omap_set_gpio_direction(RX44_SPEAKER_AMP_GPIO, 0); | 356 | gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0); |
314 | 357 | ||
315 | return 0; | 358 | return 0; |
316 | err2: | 359 | err2: |
@@ -325,6 +368,9 @@ err1: | |||
325 | 368 | ||
326 | static void __exit n810_soc_exit(void) | 369 | static void __exit n810_soc_exit(void) |
327 | { | 370 | { |
371 | gpio_free(N810_SPEAKER_AMP_GPIO); | ||
372 | gpio_free(N810_HEADSET_AMP_GPIO); | ||
373 | |||
328 | platform_device_unregister(n810_snd_device); | 374 | platform_device_unregister(n810_snd_device); |
329 | } | 375 | } |
330 | 376 | ||