aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/omap/n810.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/omap/n810.c')
-rw-r--r--sound/soc/omap/n810.c106
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
43static struct clk *sys_clkout2; 43static struct clk *sys_clkout2;
44static struct clk *sys_clkout2_src; 44static struct clk *sys_clkout2_src;
@@ -46,13 +46,26 @@ static struct clk *func96m_clk;
46 46
47static int n810_spk_func; 47static int n810_spk_func;
48static int n810_jack_func; 48static int n810_jack_func;
49static int n810_dmic_func;
49 50
50static void n810_ext_control(struct snd_soc_codec *codec) 51static 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
58static int n810_startup(struct snd_pcm_substream *substream) 71static 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
166static 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
174static 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
153static int n810_spk_event(struct snd_soc_dapm_widget *w, 188static 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,
175static const struct snd_soc_dapm_widget aic33_dapm_widgets[] = { 210static 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
180static const char *audio_map[][3] = { 216static 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
188static const char *spk_function[] = {"Off", "On"}; 227static const char *spk_function[] = {"Off", "On"};
189static const char *jack_function[] = {"Off", "Headphone"}; 228static const char *jack_function[] = {"Off", "Headphone"};
229static const char *input_function[] = {"ADC", "Digital Mic"};
190static const struct soc_enum n810_enum[] = { 230static 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
195static const struct snd_kcontrol_new aic33_n810_controls[] = { 236static 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
202static int n810_aic33_init(struct snd_soc_codec *codec) 245static 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 */
251static struct aic3x_setup_data n810_aic33_setup = { 292static 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;
316err2: 359err2:
@@ -325,6 +368,9 @@ err1:
325 368
326static void __exit n810_soc_exit(void) 369static 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