diff options
Diffstat (limited to 'sound/soc/codecs/uda134x.c')
-rw-r--r-- | sound/soc/codecs/uda134x.c | 154 |
1 files changed, 59 insertions, 95 deletions
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index f3b4c1d6a82d..7540a509a6f5 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c | |||
@@ -161,8 +161,7 @@ static int uda134x_startup(struct snd_pcm_substream *substream, | |||
161 | struct snd_soc_dai *dai) | 161 | struct snd_soc_dai *dai) |
162 | { | 162 | { |
163 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 163 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
164 | struct snd_soc_device *socdev = rtd->socdev; | 164 | struct snd_soc_codec *codec =rtd->codec; |
165 | struct snd_soc_codec *codec = socdev->card->codec; | ||
166 | struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); | 165 | struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); |
167 | struct snd_pcm_runtime *master_runtime; | 166 | struct snd_pcm_runtime *master_runtime; |
168 | 167 | ||
@@ -194,8 +193,7 @@ static void uda134x_shutdown(struct snd_pcm_substream *substream, | |||
194 | struct snd_soc_dai *dai) | 193 | struct snd_soc_dai *dai) |
195 | { | 194 | { |
196 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 195 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
197 | struct snd_soc_device *socdev = rtd->socdev; | 196 | struct snd_soc_codec *codec = rtd->codec; |
198 | struct snd_soc_codec *codec = socdev->card->codec; | ||
199 | struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); | 197 | struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); |
200 | 198 | ||
201 | if (uda134x->master_substream == substream) | 199 | if (uda134x->master_substream == substream) |
@@ -209,8 +207,7 @@ static int uda134x_hw_params(struct snd_pcm_substream *substream, | |||
209 | struct snd_soc_dai *dai) | 207 | struct snd_soc_dai *dai) |
210 | { | 208 | { |
211 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 209 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
212 | struct snd_soc_device *socdev = rtd->socdev; | 210 | struct snd_soc_codec *codec = rtd->codec; |
213 | struct snd_soc_codec *codec = socdev->card->codec; | ||
214 | struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); | 211 | struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); |
215 | u8 hw_params; | 212 | u8 hw_params; |
216 | 213 | ||
@@ -364,7 +361,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec, | |||
364 | pd->power(1); | 361 | pd->power(1); |
365 | /* Sync reg_cache with the hardware */ | 362 | /* Sync reg_cache with the hardware */ |
366 | for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++) | 363 | for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++) |
367 | codec->write(codec, i, *cache++); | 364 | codec->driver->write(codec, i, *cache++); |
368 | } | 365 | } |
369 | break; | 366 | break; |
370 | case SND_SOC_BIAS_STANDBY: | 367 | case SND_SOC_BIAS_STANDBY: |
@@ -465,8 +462,8 @@ static struct snd_soc_dai_ops uda134x_dai_ops = { | |||
465 | .set_fmt = uda134x_set_dai_fmt, | 462 | .set_fmt = uda134x_set_dai_fmt, |
466 | }; | 463 | }; |
467 | 464 | ||
468 | struct snd_soc_dai uda134x_dai = { | 465 | static struct snd_soc_dai_driver uda134x_dai = { |
469 | .name = "UDA134X", | 466 | .name = "uda134x-hifi", |
470 | /* playback capabilities */ | 467 | /* playback capabilities */ |
471 | .playback = { | 468 | .playback = { |
472 | .stream_name = "Playback", | 469 | .stream_name = "Playback", |
@@ -486,27 +483,21 @@ struct snd_soc_dai uda134x_dai = { | |||
486 | /* pcm operations */ | 483 | /* pcm operations */ |
487 | .ops = &uda134x_dai_ops, | 484 | .ops = &uda134x_dai_ops, |
488 | }; | 485 | }; |
489 | EXPORT_SYMBOL(uda134x_dai); | ||
490 | 486 | ||
491 | 487 | static int uda134x_soc_probe(struct snd_soc_codec *codec) | |
492 | static int uda134x_soc_probe(struct platform_device *pdev) | ||
493 | { | 488 | { |
494 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
495 | struct snd_soc_codec *codec; | ||
496 | struct uda134x_priv *uda134x; | 489 | struct uda134x_priv *uda134x; |
497 | void *codec_setup_data = socdev->codec_data; | 490 | struct uda134x_platform_data *pd = dev_get_drvdata(codec->card->dev); |
498 | int ret = -ENOMEM; | 491 | int ret; |
499 | struct uda134x_platform_data *pd; | ||
500 | 492 | ||
501 | printk(KERN_INFO "UDA134X SoC Audio Codec\n"); | 493 | printk(KERN_INFO "UDA134X SoC Audio Codec\n"); |
502 | 494 | ||
503 | if (!codec_setup_data) { | 495 | if (!pd) { |
504 | printk(KERN_ERR "UDA134X SoC codec: " | 496 | printk(KERN_ERR "UDA134X SoC codec: " |
505 | "missing L3 bitbang function\n"); | 497 | "missing L3 bitbang function\n"); |
506 | return -ENODEV; | 498 | return -ENODEV; |
507 | } | 499 | } |
508 | 500 | ||
509 | pd = codec_setup_data; | ||
510 | switch (pd->model) { | 501 | switch (pd->model) { |
511 | case UDA134X_UDA1340: | 502 | case UDA134X_UDA1340: |
512 | case UDA134X_UDA1341: | 503 | case UDA134X_UDA1341: |
@@ -520,58 +511,22 @@ static int uda134x_soc_probe(struct platform_device *pdev) | |||
520 | return -EINVAL; | 511 | return -EINVAL; |
521 | } | 512 | } |
522 | 513 | ||
523 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | ||
524 | if (socdev->card->codec == NULL) | ||
525 | return ret; | ||
526 | |||
527 | codec = socdev->card->codec; | ||
528 | |||
529 | uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); | 514 | uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL); |
530 | if (uda134x == NULL) | 515 | if (uda134x == NULL) |
531 | goto priv_err; | 516 | return -ENOMEM; |
532 | snd_soc_codec_set_drvdata(codec, uda134x); | 517 | snd_soc_codec_set_drvdata(codec, uda134x); |
533 | 518 | ||
534 | codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg), | 519 | codec->control_data = pd; |
535 | GFP_KERNEL); | ||
536 | if (codec->reg_cache == NULL) | ||
537 | goto reg_err; | ||
538 | |||
539 | mutex_init(&codec->mutex); | ||
540 | |||
541 | codec->reg_cache_size = sizeof(uda134x_reg); | ||
542 | codec->reg_cache_step = 1; | ||
543 | |||
544 | codec->name = "UDA134X"; | ||
545 | codec->owner = THIS_MODULE; | ||
546 | codec->dai = &uda134x_dai; | ||
547 | codec->num_dai = 1; | ||
548 | codec->read = uda134x_read_reg_cache; | ||
549 | codec->write = uda134x_write; | ||
550 | |||
551 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
552 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
553 | |||
554 | codec->control_data = codec_setup_data; | ||
555 | 520 | ||
556 | if (pd->power) | 521 | if (pd->power) |
557 | pd->power(1); | 522 | pd->power(1); |
558 | 523 | ||
559 | uda134x_reset(codec); | 524 | uda134x_reset(codec); |
560 | 525 | ||
561 | if (pd->is_powered_on_standby) { | 526 | if (pd->is_powered_on_standby) |
562 | codec->set_bias_level = NULL; | ||
563 | uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); | 527 | uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); |
564 | } else { | 528 | else |
565 | codec->set_bias_level = uda134x_set_bias_level; | ||
566 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 529 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
567 | } | ||
568 | |||
569 | /* register pcms */ | ||
570 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
571 | if (ret < 0) { | ||
572 | printk(KERN_ERR "UDA134X: failed to register pcms\n"); | ||
573 | goto pcm_err; | ||
574 | } | ||
575 | 530 | ||
576 | switch (pd->model) { | 531 | switch (pd->model) { |
577 | case UDA134X_UDA1340: | 532 | case UDA134X_UDA1340: |
@@ -590,61 +545,42 @@ static int uda134x_soc_probe(struct platform_device *pdev) | |||
590 | default: | 545 | default: |
591 | printk(KERN_ERR "%s unknown codec type: %d", | 546 | printk(KERN_ERR "%s unknown codec type: %d", |
592 | __func__, pd->model); | 547 | __func__, pd->model); |
593 | return -EINVAL; | 548 | kfree(uda134x); |
549 | return -EINVAL; | ||
594 | } | 550 | } |
595 | 551 | ||
596 | if (ret < 0) { | 552 | if (ret < 0) { |
597 | printk(KERN_ERR "UDA134X: failed to register controls\n"); | 553 | printk(KERN_ERR "UDA134X: failed to register controls\n"); |
598 | goto pcm_err; | 554 | kfree(uda134x); |
555 | return ret; | ||
599 | } | 556 | } |
600 | 557 | ||
601 | return 0; | 558 | return 0; |
602 | |||
603 | pcm_err: | ||
604 | kfree(codec->reg_cache); | ||
605 | reg_err: | ||
606 | kfree(snd_soc_codec_get_drvdata(codec)); | ||
607 | priv_err: | ||
608 | kfree(codec); | ||
609 | return ret; | ||
610 | } | 559 | } |
611 | 560 | ||
612 | /* power down chip */ | 561 | /* power down chip */ |
613 | static int uda134x_soc_remove(struct platform_device *pdev) | 562 | static int uda134x_soc_remove(struct snd_soc_codec *codec) |
614 | { | 563 | { |
615 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 564 | struct uda134x_priv *uda134x = snd_soc_codec_get_drvdata(codec); |
616 | struct snd_soc_codec *codec = socdev->card->codec; | ||
617 | 565 | ||
618 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 566 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
619 | uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); | 567 | uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); |
620 | 568 | ||
621 | snd_soc_free_pcms(socdev); | 569 | kfree(uda134x); |
622 | snd_soc_dapm_free(socdev); | ||
623 | |||
624 | kfree(snd_soc_codec_get_drvdata(codec)); | ||
625 | kfree(codec->reg_cache); | ||
626 | kfree(codec); | ||
627 | |||
628 | return 0; | 570 | return 0; |
629 | } | 571 | } |
630 | 572 | ||
631 | #if defined(CONFIG_PM) | 573 | #if defined(CONFIG_PM) |
632 | static int uda134x_soc_suspend(struct platform_device *pdev, | 574 | static int uda134x_soc_suspend(struct snd_soc_codec *codec, |
633 | pm_message_t state) | 575 | pm_message_t state) |
634 | { | 576 | { |
635 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
636 | struct snd_soc_codec *codec = socdev->card->codec; | ||
637 | |||
638 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 577 | uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
639 | uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); | 578 | uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF); |
640 | return 0; | 579 | return 0; |
641 | } | 580 | } |
642 | 581 | ||
643 | static int uda134x_soc_resume(struct platform_device *pdev) | 582 | static int uda134x_soc_resume(struct snd_soc_codec *codec) |
644 | { | 583 | { |
645 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
646 | struct snd_soc_codec *codec = socdev->card->codec; | ||
647 | |||
648 | uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE); | 584 | uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE); |
649 | uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); | 585 | uda134x_set_bias_level(codec, SND_SOC_BIAS_ON); |
650 | return 0; | 586 | return 0; |
@@ -654,25 +590,53 @@ static int uda134x_soc_resume(struct platform_device *pdev) | |||
654 | #define uda134x_soc_resume NULL | 590 | #define uda134x_soc_resume NULL |
655 | #endif /* CONFIG_PM */ | 591 | #endif /* CONFIG_PM */ |
656 | 592 | ||
657 | struct snd_soc_codec_device soc_codec_dev_uda134x = { | 593 | static struct snd_soc_codec_driver soc_codec_dev_uda134x = { |
658 | .probe = uda134x_soc_probe, | 594 | .probe = uda134x_soc_probe, |
659 | .remove = uda134x_soc_remove, | 595 | .remove = uda134x_soc_remove, |
660 | .suspend = uda134x_soc_suspend, | 596 | .suspend = uda134x_soc_suspend, |
661 | .resume = uda134x_soc_resume, | 597 | .resume = uda134x_soc_resume, |
598 | .reg_cache_size = sizeof(uda134x_reg), | ||
599 | .reg_word_size = sizeof(u8), | ||
600 | .reg_cache_step = 1, | ||
601 | .read = uda134x_read_reg_cache, | ||
602 | .write = uda134x_write, | ||
603 | #ifdef POWER_OFF_ON_STANDBY | ||
604 | .set_bias_level = uda134x_set_bias_level, | ||
605 | #endif | ||
606 | }; | ||
607 | |||
608 | static int __devinit uda134x_codec_probe(struct platform_device *pdev) | ||
609 | { | ||
610 | return snd_soc_register_codec(&pdev->dev, | ||
611 | &soc_codec_dev_uda134x, &uda134x_dai, 1); | ||
612 | } | ||
613 | |||
614 | static int __devexit uda134x_codec_remove(struct platform_device *pdev) | ||
615 | { | ||
616 | snd_soc_unregister_codec(&pdev->dev); | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static struct platform_driver uda134x_codec_driver = { | ||
621 | .driver = { | ||
622 | .name = "uda134x-codec", | ||
623 | .owner = THIS_MODULE, | ||
624 | }, | ||
625 | .probe = uda134x_codec_probe, | ||
626 | .remove = __devexit_p(uda134x_codec_remove), | ||
662 | }; | 627 | }; |
663 | EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x); | ||
664 | 628 | ||
665 | static int __init uda134x_init(void) | 629 | static int __init uda134x_codec_init(void) |
666 | { | 630 | { |
667 | return snd_soc_register_dai(&uda134x_dai); | 631 | return platform_driver_register(&uda134x_codec_driver); |
668 | } | 632 | } |
669 | module_init(uda134x_init); | 633 | module_init(uda134x_codec_init); |
670 | 634 | ||
671 | static void __exit uda134x_exit(void) | 635 | static void __exit uda134x_codec_exit(void) |
672 | { | 636 | { |
673 | snd_soc_unregister_dai(&uda134x_dai); | 637 | platform_driver_unregister(&uda134x_codec_driver); |
674 | } | 638 | } |
675 | module_exit(uda134x_exit); | 639 | module_exit(uda134x_codec_exit); |
676 | 640 | ||
677 | MODULE_DESCRIPTION("UDA134X ALSA soc codec driver"); | 641 | MODULE_DESCRIPTION("UDA134X ALSA soc codec driver"); |
678 | MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); | 642 | MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); |