diff options
Diffstat (limited to 'sound/soc/codecs/wm9712.c')
-rw-r--r-- | sound/soc/codecs/wm9712.c | 57 |
1 files changed, 25 insertions, 32 deletions
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index af83d629078a..765cf1e7369e 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -154,21 +154,6 @@ SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), | |||
154 | SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), | 154 | SOC_SINGLE("Mic 20dB Boost Switch", AC97_MIC, 7, 1, 0), |
155 | }; | 155 | }; |
156 | 156 | ||
157 | /* add non dapm controls */ | ||
158 | static int wm9712_add_controls(struct snd_soc_codec *codec) | ||
159 | { | ||
160 | int err, i; | ||
161 | |||
162 | for (i = 0; i < ARRAY_SIZE(wm9712_snd_ac97_controls); i++) { | ||
163 | err = snd_ctl_add(codec->card, | ||
164 | snd_soc_cnew(&wm9712_snd_ac97_controls[i], | ||
165 | codec, NULL)); | ||
166 | if (err < 0) | ||
167 | return err; | ||
168 | } | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | /* We have to create a fake left and right HP mixers because | 157 | /* We have to create a fake left and right HP mixers because |
173 | * the codec only has a single control that is shared by both channels. | 158 | * the codec only has a single control that is shared by both channels. |
174 | * This makes it impossible to determine the audio path. | 159 | * This makes it impossible to determine the audio path. |
@@ -467,7 +452,7 @@ static unsigned int ac97_read(struct snd_soc_codec *codec, | |||
467 | else { | 452 | else { |
468 | reg = reg >> 1; | 453 | reg = reg >> 1; |
469 | 454 | ||
470 | if (reg > (ARRAY_SIZE(wm9712_reg))) | 455 | if (reg >= (ARRAY_SIZE(wm9712_reg))) |
471 | return -EIO; | 456 | return -EIO; |
472 | 457 | ||
473 | return cache[reg]; | 458 | return cache[reg]; |
@@ -481,7 +466,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, | |||
481 | 466 | ||
482 | soc_ac97_ops.write(codec->ac97, reg, val); | 467 | soc_ac97_ops.write(codec->ac97, reg, val); |
483 | reg = reg >> 1; | 468 | reg = reg >> 1; |
484 | if (reg <= (ARRAY_SIZE(wm9712_reg))) | 469 | if (reg < (ARRAY_SIZE(wm9712_reg))) |
485 | cache[reg] = val; | 470 | cache[reg] = val; |
486 | 471 | ||
487 | return 0; | 472 | return 0; |
@@ -493,7 +478,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream, | |||
493 | struct snd_pcm_runtime *runtime = substream->runtime; | 478 | struct snd_pcm_runtime *runtime = substream->runtime; |
494 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 479 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
495 | struct snd_soc_device *socdev = rtd->socdev; | 480 | struct snd_soc_device *socdev = rtd->socdev; |
496 | struct snd_soc_codec *codec = socdev->codec; | 481 | struct snd_soc_codec *codec = socdev->card->codec; |
497 | int reg; | 482 | int reg; |
498 | u16 vra; | 483 | u16 vra; |
499 | 484 | ||
@@ -514,7 +499,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream, | |||
514 | struct snd_pcm_runtime *runtime = substream->runtime; | 499 | struct snd_pcm_runtime *runtime = substream->runtime; |
515 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 500 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
516 | struct snd_soc_device *socdev = rtd->socdev; | 501 | struct snd_soc_device *socdev = rtd->socdev; |
517 | struct snd_soc_codec *codec = socdev->codec; | 502 | struct snd_soc_codec *codec = socdev->card->codec; |
518 | u16 vra, xsle; | 503 | u16 vra, xsle; |
519 | 504 | ||
520 | vra = ac97_read(codec, AC97_EXTENDED_STATUS); | 505 | vra = ac97_read(codec, AC97_EXTENDED_STATUS); |
@@ -532,6 +517,14 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream, | |||
532 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ | 517 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 |\ |
533 | SNDRV_PCM_RATE_48000) | 518 | SNDRV_PCM_RATE_48000) |
534 | 519 | ||
520 | static struct snd_soc_dai_ops wm9712_dai_ops_hifi = { | ||
521 | .prepare = ac97_prepare, | ||
522 | }; | ||
523 | |||
524 | static struct snd_soc_dai_ops wm9712_dai_ops_aux = { | ||
525 | .prepare = ac97_aux_prepare, | ||
526 | }; | ||
527 | |||
535 | struct snd_soc_dai wm9712_dai[] = { | 528 | struct snd_soc_dai wm9712_dai[] = { |
536 | { | 529 | { |
537 | .name = "AC97 HiFi", | 530 | .name = "AC97 HiFi", |
@@ -548,8 +541,7 @@ struct snd_soc_dai wm9712_dai[] = { | |||
548 | .channels_max = 2, | 541 | .channels_max = 2, |
549 | .rates = WM9712_AC97_RATES, | 542 | .rates = WM9712_AC97_RATES, |
550 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 543 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
551 | .ops = { | 544 | .ops = &wm9712_dai_ops_hifi, |
552 | .prepare = ac97_prepare,}, | ||
553 | }, | 545 | }, |
554 | { | 546 | { |
555 | .name = "AC97 Aux", | 547 | .name = "AC97 Aux", |
@@ -559,8 +551,7 @@ struct snd_soc_dai wm9712_dai[] = { | |||
559 | .channels_max = 1, | 551 | .channels_max = 1, |
560 | .rates = WM9712_AC97_RATES, | 552 | .rates = WM9712_AC97_RATES, |
561 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | 553 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, |
562 | .ops = { | 554 | .ops = &wm9712_dai_ops_aux, |
563 | .prepare = ac97_aux_prepare,}, | ||
564 | } | 555 | } |
565 | }; | 556 | }; |
566 | EXPORT_SYMBOL_GPL(wm9712_dai); | 557 | EXPORT_SYMBOL_GPL(wm9712_dai); |
@@ -607,7 +598,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev, | |||
607 | pm_message_t state) | 598 | pm_message_t state) |
608 | { | 599 | { |
609 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 600 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
610 | struct snd_soc_codec *codec = socdev->codec; | 601 | struct snd_soc_codec *codec = socdev->card->codec; |
611 | 602 | ||
612 | wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); | 603 | wm9712_set_bias_level(codec, SND_SOC_BIAS_OFF); |
613 | return 0; | 604 | return 0; |
@@ -616,7 +607,7 @@ static int wm9712_soc_suspend(struct platform_device *pdev, | |||
616 | static int wm9712_soc_resume(struct platform_device *pdev) | 607 | static int wm9712_soc_resume(struct platform_device *pdev) |
617 | { | 608 | { |
618 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 609 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
619 | struct snd_soc_codec *codec = socdev->codec; | 610 | struct snd_soc_codec *codec = socdev->card->codec; |
620 | int i, ret; | 611 | int i, ret; |
621 | u16 *cache = codec->reg_cache; | 612 | u16 *cache = codec->reg_cache; |
622 | 613 | ||
@@ -652,10 +643,11 @@ static int wm9712_soc_probe(struct platform_device *pdev) | |||
652 | 643 | ||
653 | printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); | 644 | printk(KERN_INFO "WM9711/WM9712 SoC Audio Codec %s\n", WM9712_VERSION); |
654 | 645 | ||
655 | socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | 646 | socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), |
656 | if (socdev->codec == NULL) | 647 | GFP_KERNEL); |
648 | if (socdev->card->codec == NULL) | ||
657 | return -ENOMEM; | 649 | return -ENOMEM; |
658 | codec = socdev->codec; | 650 | codec = socdev->card->codec; |
659 | mutex_init(&codec->mutex); | 651 | mutex_init(&codec->mutex); |
660 | 652 | ||
661 | codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL); | 653 | codec->reg_cache = kmemdup(wm9712_reg, sizeof(wm9712_reg), GFP_KERNEL); |
@@ -698,7 +690,8 @@ static int wm9712_soc_probe(struct platform_device *pdev) | |||
698 | ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); | 690 | ac97_write(codec, AC97_VIDEO, ac97_read(codec, AC97_VIDEO) | 0x3000); |
699 | 691 | ||
700 | wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 692 | wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
701 | wm9712_add_controls(codec); | 693 | snd_soc_add_controls(codec, wm9712_snd_ac97_controls, |
694 | ARRAY_SIZE(wm9712_snd_ac97_controls)); | ||
702 | wm9712_add_widgets(codec); | 695 | wm9712_add_widgets(codec); |
703 | ret = snd_soc_init_card(socdev); | 696 | ret = snd_soc_init_card(socdev); |
704 | if (ret < 0) { | 697 | if (ret < 0) { |
@@ -718,15 +711,15 @@ codec_err: | |||
718 | kfree(codec->reg_cache); | 711 | kfree(codec->reg_cache); |
719 | 712 | ||
720 | cache_err: | 713 | cache_err: |
721 | kfree(socdev->codec); | 714 | kfree(socdev->card->codec); |
722 | socdev->codec = NULL; | 715 | socdev->card->codec = NULL; |
723 | return ret; | 716 | return ret; |
724 | } | 717 | } |
725 | 718 | ||
726 | static int wm9712_soc_remove(struct platform_device *pdev) | 719 | static int wm9712_soc_remove(struct platform_device *pdev) |
727 | { | 720 | { |
728 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 721 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
729 | struct snd_soc_codec *codec = socdev->codec; | 722 | struct snd_soc_codec *codec = socdev->card->codec; |
730 | 723 | ||
731 | if (codec == NULL) | 724 | if (codec == NULL) |
732 | return 0; | 725 | return 0; |