diff options
Diffstat (limited to 'sound/soc/omap/ams-delta.c')
-rw-r--r-- | sound/soc/omap/ams-delta.c | 98 |
1 files changed, 55 insertions, 43 deletions
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index b0f618e44840..9d88efa06e3c 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c | |||
@@ -99,7 +99,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, | |||
99 | int pin, changed = 0; | 99 | int pin, changed = 0; |
100 | 100 | ||
101 | /* Refuse any mode changes if we are not able to control the codec. */ | 101 | /* Refuse any mode changes if we are not able to control the codec. */ |
102 | if (!codec->control_data) | 102 | if (!codec->hw_write) |
103 | return -EUNATCH; | 103 | return -EUNATCH; |
104 | 104 | ||
105 | if (ucontrol->value.enumerated.item[0] >= control->max) | 105 | if (ucontrol->value.enumerated.item[0] >= control->max) |
@@ -268,10 +268,32 @@ static void cx81801_timeout(unsigned long data) | |||
268 | ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0); | 268 | ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0); |
269 | } | 269 | } |
270 | 270 | ||
271 | /* | ||
272 | * Used for passing a codec structure pointer | ||
273 | * from the board initialization code to the tty line discipline. | ||
274 | */ | ||
275 | static struct snd_soc_codec *cx20442_codec; | ||
276 | |||
271 | /* Line discipline .open() */ | 277 | /* Line discipline .open() */ |
272 | static int cx81801_open(struct tty_struct *tty) | 278 | static int cx81801_open(struct tty_struct *tty) |
273 | { | 279 | { |
274 | return v253_ops.open(tty); | 280 | int ret; |
281 | |||
282 | if (!cx20442_codec) | ||
283 | return -ENODEV; | ||
284 | |||
285 | /* | ||
286 | * Pass the codec structure pointer for use by other ldisc callbacks, | ||
287 | * both the card and the codec specific parts. | ||
288 | */ | ||
289 | tty->disc_data = cx20442_codec; | ||
290 | |||
291 | ret = v253_ops.open(tty); | ||
292 | |||
293 | if (ret < 0) | ||
294 | tty->disc_data = NULL; | ||
295 | |||
296 | return ret; | ||
275 | } | 297 | } |
276 | 298 | ||
277 | /* Line discipline .close() */ | 299 | /* Line discipline .close() */ |
@@ -281,11 +303,14 @@ static void cx81801_close(struct tty_struct *tty) | |||
281 | 303 | ||
282 | del_timer_sync(&cx81801_timer); | 304 | del_timer_sync(&cx81801_timer); |
283 | 305 | ||
284 | v253_ops.close(tty); | ||
285 | |||
286 | /* Prevent the hook switch from further changing the DAPM pins */ | 306 | /* Prevent the hook switch from further changing the DAPM pins */ |
287 | INIT_LIST_HEAD(&ams_delta_hook_switch.pins); | 307 | INIT_LIST_HEAD(&ams_delta_hook_switch.pins); |
288 | 308 | ||
309 | if (!codec) | ||
310 | return; | ||
311 | |||
312 | v253_ops.close(tty); | ||
313 | |||
289 | /* Revert back to default audio input/output constellation */ | 314 | /* Revert back to default audio input/output constellation */ |
290 | snd_soc_dapm_disable_pin(codec, "Mouthpiece"); | 315 | snd_soc_dapm_disable_pin(codec, "Mouthpiece"); |
291 | snd_soc_dapm_enable_pin(codec, "Earpiece"); | 316 | snd_soc_dapm_enable_pin(codec, "Earpiece"); |
@@ -310,7 +335,10 @@ static void cx81801_receive(struct tty_struct *tty, | |||
310 | const unsigned char *c; | 335 | const unsigned char *c; |
311 | int apply, ret; | 336 | int apply, ret; |
312 | 337 | ||
313 | if (!codec->control_data) { | 338 | if (!codec) |
339 | return; | ||
340 | |||
341 | if (!codec->hw_write) { | ||
314 | /* First modem response, complete setup procedure */ | 342 | /* First modem response, complete setup procedure */ |
315 | 343 | ||
316 | /* Initialize timer used for config pulse generation */ | 344 | /* Initialize timer used for config pulse generation */ |
@@ -323,7 +351,7 @@ static void cx81801_receive(struct tty_struct *tty, | |||
323 | ARRAY_SIZE(ams_delta_hook_switch_pins), | 351 | ARRAY_SIZE(ams_delta_hook_switch_pins), |
324 | ams_delta_hook_switch_pins); | 352 | ams_delta_hook_switch_pins); |
325 | if (ret) | 353 | if (ret) |
326 | dev_warn(codec->socdev->card->dev, | 354 | dev_warn(codec->dev, |
327 | "Failed to link hook switch to DAPM pins, " | 355 | "Failed to link hook switch to DAPM pins, " |
328 | "will continue with hook switch unlinked.\n"); | 356 | "will continue with hook switch unlinked.\n"); |
329 | 357 | ||
@@ -383,7 +411,7 @@ static int ams_delta_hw_params(struct snd_pcm_substream *substream, | |||
383 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 411 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
384 | 412 | ||
385 | /* Set cpu DAI configuration */ | 413 | /* Set cpu DAI configuration */ |
386 | return snd_soc_dai_set_fmt(rtd->dai->cpu_dai, | 414 | return snd_soc_dai_set_fmt(rtd->cpu_dai, |
387 | SND_SOC_DAIFMT_DSP_A | | 415 | SND_SOC_DAIFMT_DSP_A | |
388 | SND_SOC_DAIFMT_NB_NF | | 416 | SND_SOC_DAIFMT_NB_NF | |
389 | SND_SOC_DAIFMT_CBM_CFM); | 417 | SND_SOC_DAIFMT_CBM_CFM); |
@@ -398,7 +426,7 @@ static struct snd_soc_ops ams_delta_ops = { | |||
398 | static int ams_delta_set_bias_level(struct snd_soc_card *card, | 426 | static int ams_delta_set_bias_level(struct snd_soc_card *card, |
399 | enum snd_soc_bias_level level) | 427 | enum snd_soc_bias_level level) |
400 | { | 428 | { |
401 | struct snd_soc_codec *codec = card->codec; | 429 | struct snd_soc_codec *codec = card->rtd->codec; |
402 | 430 | ||
403 | switch (level) { | 431 | switch (level) { |
404 | case SND_SOC_BIAS_ON: | 432 | case SND_SOC_BIAS_ON: |
@@ -461,18 +489,22 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream) | |||
461 | * Card initialization | 489 | * Card initialization |
462 | */ | 490 | */ |
463 | 491 | ||
464 | static int ams_delta_cx20442_init(struct snd_soc_codec *codec) | 492 | static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) |
465 | { | 493 | { |
466 | struct snd_soc_dai *codec_dai = codec->dai; | 494 | struct snd_soc_codec *codec = rtd->codec; |
467 | struct snd_soc_card *card = codec->socdev->card; | 495 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
496 | struct snd_soc_card *card = rtd->card; | ||
468 | int ret; | 497 | int ret; |
469 | /* Codec is ready, now add/activate board specific controls */ | 498 | /* Codec is ready, now add/activate board specific controls */ |
470 | 499 | ||
500 | /* Store a pointer to the codec structure for tty ldisc use */ | ||
501 | cx20442_codec = codec; | ||
502 | |||
471 | /* Set up digital mute if not provided by the codec */ | 503 | /* Set up digital mute if not provided by the codec */ |
472 | if (!codec_dai->ops) { | 504 | if (!codec_dai->driver->ops) { |
473 | codec_dai->ops = &ams_delta_dai_ops; | 505 | codec_dai->driver->ops = &ams_delta_dai_ops; |
474 | } else if (!codec_dai->ops->digital_mute) { | 506 | } else if (!codec_dai->driver->ops->digital_mute) { |
475 | codec_dai->ops->digital_mute = ams_delta_digital_mute; | 507 | codec_dai->driver->ops->digital_mute = ams_delta_digital_mute; |
476 | } else { | 508 | } else { |
477 | ams_delta_ops.startup = ams_delta_startup; | 509 | ams_delta_ops.startup = ams_delta_startup; |
478 | ams_delta_ops.shutdown = ams_delta_shutdown; | 510 | ams_delta_ops.shutdown = ams_delta_shutdown; |
@@ -483,7 +515,7 @@ static int ams_delta_cx20442_init(struct snd_soc_codec *codec) | |||
483 | 515 | ||
484 | /* Add hook switch - can be used to control the codec from userspace | 516 | /* Add hook switch - can be used to control the codec from userspace |
485 | * even if line discipline fails */ | 517 | * even if line discipline fails */ |
486 | ret = snd_soc_jack_new(card, "hook_switch", | 518 | ret = snd_soc_jack_new(rtd->codec, "hook_switch", |
487 | SND_JACK_HEADSET, &ams_delta_hook_switch); | 519 | SND_JACK_HEADSET, &ams_delta_hook_switch); |
488 | if (ret) | 520 | if (ret) |
489 | dev_warn(card->dev, | 521 | dev_warn(card->dev, |
@@ -551,27 +583,22 @@ static int ams_delta_cx20442_init(struct snd_soc_codec *codec) | |||
551 | static struct snd_soc_dai_link ams_delta_dai_link = { | 583 | static struct snd_soc_dai_link ams_delta_dai_link = { |
552 | .name = "CX20442", | 584 | .name = "CX20442", |
553 | .stream_name = "CX20442", | 585 | .stream_name = "CX20442", |
554 | .cpu_dai = &omap_mcbsp_dai[0], | 586 | .cpu_dai_name ="omap-mcbsp-dai.0", |
555 | .codec_dai = &cx20442_dai, | 587 | .codec_dai_name = "cx20442-hifi", |
556 | .init = ams_delta_cx20442_init, | 588 | .init = ams_delta_cx20442_init, |
589 | .platform_name = "omap-pcm-audio", | ||
590 | .codec_name = "cx20442-codec", | ||
557 | .ops = &ams_delta_ops, | 591 | .ops = &ams_delta_ops, |
558 | }; | 592 | }; |
559 | 593 | ||
560 | /* Audio card driver */ | 594 | /* Audio card driver */ |
561 | static struct snd_soc_card ams_delta_audio_card = { | 595 | static struct snd_soc_card ams_delta_audio_card = { |
562 | .name = "AMS_DELTA", | 596 | .name = "AMS_DELTA", |
563 | .platform = &omap_soc_platform, | ||
564 | .dai_link = &ams_delta_dai_link, | 597 | .dai_link = &ams_delta_dai_link, |
565 | .num_links = 1, | 598 | .num_links = 1, |
566 | .set_bias_level = ams_delta_set_bias_level, | 599 | .set_bias_level = ams_delta_set_bias_level, |
567 | }; | 600 | }; |
568 | 601 | ||
569 | /* Audio subsystem */ | ||
570 | static struct snd_soc_device ams_delta_snd_soc_device = { | ||
571 | .card = &ams_delta_audio_card, | ||
572 | .codec_dev = &cx20442_codec_dev, | ||
573 | }; | ||
574 | |||
575 | /* Module init/exit */ | 602 | /* Module init/exit */ |
576 | static struct platform_device *ams_delta_audio_platform_device; | 603 | static struct platform_device *ams_delta_audio_platform_device; |
577 | static struct platform_device *cx20442_platform_device; | 604 | static struct platform_device *cx20442_platform_device; |
@@ -589,9 +616,7 @@ static int __init ams_delta_module_init(void) | |||
589 | return -ENOMEM; | 616 | return -ENOMEM; |
590 | 617 | ||
591 | platform_set_drvdata(ams_delta_audio_platform_device, | 618 | platform_set_drvdata(ams_delta_audio_platform_device, |
592 | &ams_delta_snd_soc_device); | 619 | &ams_delta_audio_card); |
593 | ams_delta_snd_soc_device.dev = &ams_delta_audio_platform_device->dev; | ||
594 | *(unsigned int *)ams_delta_dai_link.cpu_dai->private_data = OMAP_MCBSP1; | ||
595 | 620 | ||
596 | ret = platform_device_add(ams_delta_audio_platform_device); | 621 | ret = platform_device_add(ams_delta_audio_platform_device); |
597 | if (ret) | 622 | if (ret) |
@@ -601,8 +626,8 @@ static int __init ams_delta_module_init(void) | |||
601 | * Codec platform device could be registered from elsewhere (board?), | 626 | * Codec platform device could be registered from elsewhere (board?), |
602 | * but I do it here as it makes sense only if used with the card. | 627 | * but I do it here as it makes sense only if used with the card. |
603 | */ | 628 | */ |
604 | cx20442_platform_device = platform_device_register_simple("cx20442", | 629 | cx20442_platform_device = |
605 | -1, NULL, 0); | 630 | platform_device_register_simple("cx20442-codec", -1, NULL, 0); |
606 | return 0; | 631 | return 0; |
607 | err: | 632 | err: |
608 | platform_device_put(ams_delta_audio_platform_device); | 633 | platform_device_put(ams_delta_audio_platform_device); |
@@ -612,19 +637,6 @@ module_init(ams_delta_module_init); | |||
612 | 637 | ||
613 | static void __exit ams_delta_module_exit(void) | 638 | static void __exit ams_delta_module_exit(void) |
614 | { | 639 | { |
615 | struct snd_soc_codec *codec; | ||
616 | struct tty_struct *tty; | ||
617 | |||
618 | if (ams_delta_audio_card.codec) { | ||
619 | codec = ams_delta_audio_card.codec; | ||
620 | |||
621 | if (codec->control_data) { | ||
622 | tty = codec->control_data; | ||
623 | |||
624 | tty_hangup(tty); | ||
625 | } | ||
626 | } | ||
627 | |||
628 | if (tty_unregister_ldisc(N_V253) != 0) | 640 | if (tty_unregister_ldisc(N_V253) != 0) |
629 | dev_warn(&ams_delta_audio_platform_device->dev, | 641 | dev_warn(&ams_delta_audio_platform_device->dev, |
630 | "failed to unregister V253 line discipline\n"); | 642 | "failed to unregister V253 line discipline\n"); |