diff options
Diffstat (limited to 'sound/soc/tegra/tegra_wm8903.c')
-rw-r--r-- | sound/soc/tegra/tegra_wm8903.c | 179 |
1 files changed, 70 insertions, 109 deletions
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index bbd79bf56303..4ac73730d79a 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <sound/pcm.h> | 39 | #include <sound/pcm.h> |
40 | #include <sound/pcm_params.h> | 40 | #include <sound/pcm_params.h> |
41 | #include <sound/soc.h> | 41 | #include <sound/soc.h> |
42 | #include <sound/tegra_wm8903.h> | ||
43 | 42 | ||
44 | #include "../codecs/wm8903.h" | 43 | #include "../codecs/wm8903.h" |
45 | 44 | ||
@@ -48,7 +47,11 @@ | |||
48 | #define DRV_NAME "tegra-snd-wm8903" | 47 | #define DRV_NAME "tegra-snd-wm8903" |
49 | 48 | ||
50 | struct tegra_wm8903 { | 49 | struct tegra_wm8903 { |
51 | struct tegra_wm8903_platform_data pdata; | 50 | int gpio_spkr_en; |
51 | int gpio_hp_det; | ||
52 | int gpio_hp_mute; | ||
53 | int gpio_int_mic_en; | ||
54 | int gpio_ext_mic_en; | ||
52 | struct tegra_asoc_utils_data util_data; | 55 | struct tegra_asoc_utils_data util_data; |
53 | }; | 56 | }; |
54 | 57 | ||
@@ -129,12 +132,11 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w, | |||
129 | struct snd_soc_dapm_context *dapm = w->dapm; | 132 | struct snd_soc_dapm_context *dapm = w->dapm; |
130 | struct snd_soc_card *card = dapm->card; | 133 | struct snd_soc_card *card = dapm->card; |
131 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 134 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
132 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | ||
133 | 135 | ||
134 | if (!gpio_is_valid(pdata->gpio_spkr_en)) | 136 | if (!gpio_is_valid(machine->gpio_spkr_en)) |
135 | return 0; | 137 | return 0; |
136 | 138 | ||
137 | gpio_set_value_cansleep(pdata->gpio_spkr_en, | 139 | gpio_set_value_cansleep(machine->gpio_spkr_en, |
138 | SND_SOC_DAPM_EVENT_ON(event)); | 140 | SND_SOC_DAPM_EVENT_ON(event)); |
139 | 141 | ||
140 | return 0; | 142 | return 0; |
@@ -146,12 +148,11 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w, | |||
146 | struct snd_soc_dapm_context *dapm = w->dapm; | 148 | struct snd_soc_dapm_context *dapm = w->dapm; |
147 | struct snd_soc_card *card = dapm->card; | 149 | struct snd_soc_card *card = dapm->card; |
148 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 150 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
149 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | ||
150 | 151 | ||
151 | if (!gpio_is_valid(pdata->gpio_hp_mute)) | 152 | if (!gpio_is_valid(machine->gpio_hp_mute)) |
152 | return 0; | 153 | return 0; |
153 | 154 | ||
154 | gpio_set_value_cansleep(pdata->gpio_hp_mute, | 155 | gpio_set_value_cansleep(machine->gpio_hp_mute, |
155 | !SND_SOC_DAPM_EVENT_ON(event)); | 156 | !SND_SOC_DAPM_EVENT_ON(event)); |
156 | 157 | ||
157 | return 0; | 158 | return 0; |
@@ -163,17 +164,6 @@ static const struct snd_soc_dapm_widget tegra_wm8903_dapm_widgets[] = { | |||
163 | SND_SOC_DAPM_MIC("Mic Jack", NULL), | 164 | SND_SOC_DAPM_MIC("Mic Jack", NULL), |
164 | }; | 165 | }; |
165 | 166 | ||
166 | static const struct snd_soc_dapm_route harmony_audio_map[] = { | ||
167 | {"Headphone Jack", NULL, "HPOUTR"}, | ||
168 | {"Headphone Jack", NULL, "HPOUTL"}, | ||
169 | {"Int Spk", NULL, "ROP"}, | ||
170 | {"Int Spk", NULL, "RON"}, | ||
171 | {"Int Spk", NULL, "LOP"}, | ||
172 | {"Int Spk", NULL, "LON"}, | ||
173 | {"Mic Jack", NULL, "MICBIAS"}, | ||
174 | {"IN1L", NULL, "Mic Jack"}, | ||
175 | }; | ||
176 | |||
177 | static const struct snd_kcontrol_new tegra_wm8903_controls[] = { | 167 | static const struct snd_kcontrol_new tegra_wm8903_controls[] = { |
178 | SOC_DAPM_PIN_SWITCH("Int Spk"), | 168 | SOC_DAPM_PIN_SWITCH("Int Spk"), |
179 | }; | 169 | }; |
@@ -185,10 +175,9 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) | |||
185 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 175 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
186 | struct snd_soc_card *card = codec->card; | 176 | struct snd_soc_card *card = codec->card; |
187 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); | 177 | struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); |
188 | struct tegra_wm8903_platform_data *pdata = &machine->pdata; | ||
189 | 178 | ||
190 | if (gpio_is_valid(pdata->gpio_hp_det)) { | 179 | if (gpio_is_valid(machine->gpio_hp_det)) { |
191 | tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; | 180 | tegra_wm8903_hp_jack_gpio.gpio = machine->gpio_hp_det; |
192 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, | 181 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, |
193 | &tegra_wm8903_hp_jack); | 182 | &tegra_wm8903_hp_jack); |
194 | snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, | 183 | snd_soc_jack_add_pins(&tegra_wm8903_hp_jack, |
@@ -226,9 +215,6 @@ static int tegra_wm8903_remove(struct snd_soc_card *card) | |||
226 | static struct snd_soc_dai_link tegra_wm8903_dai = { | 215 | static struct snd_soc_dai_link tegra_wm8903_dai = { |
227 | .name = "WM8903", | 216 | .name = "WM8903", |
228 | .stream_name = "WM8903 PCM", | 217 | .stream_name = "WM8903 PCM", |
229 | .codec_name = "wm8903.0-001a", | ||
230 | .platform_name = "tegra20-i2s.0", | ||
231 | .cpu_dai_name = "tegra20-i2s.0", | ||
232 | .codec_dai_name = "wm8903-hifi", | 218 | .codec_dai_name = "wm8903-hifi", |
233 | .init = tegra_wm8903_init, | 219 | .init = tegra_wm8903_init, |
234 | .ops = &tegra_wm8903_ops, | 220 | .ops = &tegra_wm8903_ops, |
@@ -257,96 +243,25 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
257 | struct device_node *np = pdev->dev.of_node; | 243 | struct device_node *np = pdev->dev.of_node; |
258 | struct snd_soc_card *card = &snd_soc_tegra_wm8903; | 244 | struct snd_soc_card *card = &snd_soc_tegra_wm8903; |
259 | struct tegra_wm8903 *machine; | 245 | struct tegra_wm8903 *machine; |
260 | struct tegra_wm8903_platform_data *pdata; | ||
261 | int ret; | 246 | int ret; |
262 | 247 | ||
263 | if (!pdev->dev.platform_data && !pdev->dev.of_node) { | ||
264 | dev_err(&pdev->dev, "No platform data supplied\n"); | ||
265 | return -EINVAL; | ||
266 | } | ||
267 | |||
268 | machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903), | 248 | machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8903), |
269 | GFP_KERNEL); | 249 | GFP_KERNEL); |
270 | if (!machine) { | 250 | if (!machine) { |
271 | dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n"); | 251 | dev_err(&pdev->dev, "Can't allocate tegra_wm8903 struct\n"); |
272 | ret = -ENOMEM; | 252 | return -ENOMEM; |
273 | goto err; | ||
274 | } | 253 | } |
275 | pdata = &machine->pdata; | ||
276 | 254 | ||
277 | card->dev = &pdev->dev; | 255 | card->dev = &pdev->dev; |
278 | platform_set_drvdata(pdev, card); | 256 | platform_set_drvdata(pdev, card); |
279 | snd_soc_card_set_drvdata(card, machine); | 257 | snd_soc_card_set_drvdata(card, machine); |
280 | 258 | ||
281 | if (pdev->dev.platform_data) { | 259 | machine->gpio_spkr_en = of_get_named_gpio(np, "nvidia,spkr-en-gpios", |
282 | memcpy(pdata, card->dev->platform_data, sizeof(*pdata)); | 260 | 0); |
283 | } else if (np) { | 261 | if (machine->gpio_spkr_en == -EPROBE_DEFER) |
284 | pdata->gpio_spkr_en = of_get_named_gpio(np, | 262 | return -EPROBE_DEFER; |
285 | "nvidia,spkr-en-gpios", 0); | 263 | if (gpio_is_valid(machine->gpio_spkr_en)) { |
286 | if (pdata->gpio_spkr_en == -EPROBE_DEFER) | 264 | ret = devm_gpio_request_one(&pdev->dev, machine->gpio_spkr_en, |
287 | return -EPROBE_DEFER; | ||
288 | |||
289 | pdata->gpio_hp_mute = of_get_named_gpio(np, | ||
290 | "nvidia,hp-mute-gpios", 0); | ||
291 | if (pdata->gpio_hp_mute == -EPROBE_DEFER) | ||
292 | return -EPROBE_DEFER; | ||
293 | |||
294 | pdata->gpio_hp_det = of_get_named_gpio(np, | ||
295 | "nvidia,hp-det-gpios", 0); | ||
296 | if (pdata->gpio_hp_det == -EPROBE_DEFER) | ||
297 | return -EPROBE_DEFER; | ||
298 | |||
299 | pdata->gpio_int_mic_en = of_get_named_gpio(np, | ||
300 | "nvidia,int-mic-en-gpios", 0); | ||
301 | if (pdata->gpio_int_mic_en == -EPROBE_DEFER) | ||
302 | return -EPROBE_DEFER; | ||
303 | |||
304 | pdata->gpio_ext_mic_en = of_get_named_gpio(np, | ||
305 | "nvidia,ext-mic-en-gpios", 0); | ||
306 | if (pdata->gpio_ext_mic_en == -EPROBE_DEFER) | ||
307 | return -EPROBE_DEFER; | ||
308 | } | ||
309 | |||
310 | if (np) { | ||
311 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | ||
312 | if (ret) | ||
313 | goto err; | ||
314 | |||
315 | ret = snd_soc_of_parse_audio_routing(card, | ||
316 | "nvidia,audio-routing"); | ||
317 | if (ret) | ||
318 | goto err; | ||
319 | |||
320 | tegra_wm8903_dai.codec_name = NULL; | ||
321 | tegra_wm8903_dai.codec_of_node = of_parse_phandle(np, | ||
322 | "nvidia,audio-codec", 0); | ||
323 | if (!tegra_wm8903_dai.codec_of_node) { | ||
324 | dev_err(&pdev->dev, | ||
325 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
326 | ret = -EINVAL; | ||
327 | goto err; | ||
328 | } | ||
329 | |||
330 | tegra_wm8903_dai.cpu_dai_name = NULL; | ||
331 | tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np, | ||
332 | "nvidia,i2s-controller", 0); | ||
333 | if (!tegra_wm8903_dai.cpu_of_node) { | ||
334 | dev_err(&pdev->dev, | ||
335 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | ||
336 | ret = -EINVAL; | ||
337 | goto err; | ||
338 | } | ||
339 | |||
340 | tegra_wm8903_dai.platform_name = NULL; | ||
341 | tegra_wm8903_dai.platform_of_node = | ||
342 | tegra_wm8903_dai.cpu_of_node; | ||
343 | } else { | ||
344 | card->dapm_routes = harmony_audio_map; | ||
345 | card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); | ||
346 | } | ||
347 | |||
348 | if (gpio_is_valid(pdata->gpio_spkr_en)) { | ||
349 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en, | ||
350 | GPIOF_OUT_INIT_LOW, "spkr_en"); | 265 | GPIOF_OUT_INIT_LOW, "spkr_en"); |
351 | if (ret) { | 266 | if (ret) { |
352 | dev_err(card->dev, "cannot get spkr_en gpio\n"); | 267 | dev_err(card->dev, "cannot get spkr_en gpio\n"); |
@@ -354,8 +269,12 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
354 | } | 269 | } |
355 | } | 270 | } |
356 | 271 | ||
357 | if (gpio_is_valid(pdata->gpio_hp_mute)) { | 272 | machine->gpio_hp_mute = of_get_named_gpio(np, "nvidia,hp-mute-gpios", |
358 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute, | 273 | 0); |
274 | if (machine->gpio_hp_mute == -EPROBE_DEFER) | ||
275 | return -EPROBE_DEFER; | ||
276 | if (gpio_is_valid(machine->gpio_hp_mute)) { | ||
277 | ret = devm_gpio_request_one(&pdev->dev, machine->gpio_hp_mute, | ||
359 | GPIOF_OUT_INIT_HIGH, "hp_mute"); | 278 | GPIOF_OUT_INIT_HIGH, "hp_mute"); |
360 | if (ret) { | 279 | if (ret) { |
361 | dev_err(card->dev, "cannot get hp_mute gpio\n"); | 280 | dev_err(card->dev, "cannot get hp_mute gpio\n"); |
@@ -363,9 +282,18 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
363 | } | 282 | } |
364 | } | 283 | } |
365 | 284 | ||
366 | if (gpio_is_valid(pdata->gpio_int_mic_en)) { | 285 | machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); |
286 | if (machine->gpio_hp_det == -EPROBE_DEFER) | ||
287 | return -EPROBE_DEFER; | ||
288 | |||
289 | machine->gpio_int_mic_en = of_get_named_gpio(np, | ||
290 | "nvidia,int-mic-en-gpios", 0); | ||
291 | if (machine->gpio_int_mic_en == -EPROBE_DEFER) | ||
292 | return -EPROBE_DEFER; | ||
293 | if (gpio_is_valid(machine->gpio_int_mic_en)) { | ||
367 | /* Disable int mic; enable signal is active-high */ | 294 | /* Disable int mic; enable signal is active-high */ |
368 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en, | 295 | ret = devm_gpio_request_one(&pdev->dev, |
296 | machine->gpio_int_mic_en, | ||
369 | GPIOF_OUT_INIT_LOW, "int_mic_en"); | 297 | GPIOF_OUT_INIT_LOW, "int_mic_en"); |
370 | if (ret) { | 298 | if (ret) { |
371 | dev_err(card->dev, "cannot get int_mic_en gpio\n"); | 299 | dev_err(card->dev, "cannot get int_mic_en gpio\n"); |
@@ -373,9 +301,14 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
373 | } | 301 | } |
374 | } | 302 | } |
375 | 303 | ||
376 | if (gpio_is_valid(pdata->gpio_ext_mic_en)) { | 304 | machine->gpio_ext_mic_en = of_get_named_gpio(np, |
305 | "nvidia,ext-mic-en-gpios", 0); | ||
306 | if (machine->gpio_ext_mic_en == -EPROBE_DEFER) | ||
307 | return -EPROBE_DEFER; | ||
308 | if (gpio_is_valid(machine->gpio_ext_mic_en)) { | ||
377 | /* Enable ext mic; enable signal is active-low */ | 309 | /* Enable ext mic; enable signal is active-low */ |
378 | ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en, | 310 | ret = devm_gpio_request_one(&pdev->dev, |
311 | machine->gpio_ext_mic_en, | ||
379 | GPIOF_OUT_INIT_LOW, "ext_mic_en"); | 312 | GPIOF_OUT_INIT_LOW, "ext_mic_en"); |
380 | if (ret) { | 313 | if (ret) { |
381 | dev_err(card->dev, "cannot get ext_mic_en gpio\n"); | 314 | dev_err(card->dev, "cannot get ext_mic_en gpio\n"); |
@@ -383,6 +316,34 @@ static int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
383 | } | 316 | } |
384 | } | 317 | } |
385 | 318 | ||
319 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | ||
320 | if (ret) | ||
321 | goto err; | ||
322 | |||
323 | ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing"); | ||
324 | if (ret) | ||
325 | goto err; | ||
326 | |||
327 | tegra_wm8903_dai.codec_of_node = of_parse_phandle(np, | ||
328 | "nvidia,audio-codec", 0); | ||
329 | if (!tegra_wm8903_dai.codec_of_node) { | ||
330 | dev_err(&pdev->dev, | ||
331 | "Property 'nvidia,audio-codec' missing or invalid\n"); | ||
332 | ret = -EINVAL; | ||
333 | goto err; | ||
334 | } | ||
335 | |||
336 | tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np, | ||
337 | "nvidia,i2s-controller", 0); | ||
338 | if (!tegra_wm8903_dai.cpu_of_node) { | ||
339 | dev_err(&pdev->dev, | ||
340 | "Property 'nvidia,i2s-controller' missing or invalid\n"); | ||
341 | ret = -EINVAL; | ||
342 | goto err; | ||
343 | } | ||
344 | |||
345 | tegra_wm8903_dai.platform_of_node = tegra_wm8903_dai.cpu_of_node; | ||
346 | |||
386 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); | 347 | ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); |
387 | if (ret) | 348 | if (ret) |
388 | goto err; | 349 | goto err; |