diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /sound/soc/codecs/uda1380.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'sound/soc/codecs/uda1380.c')
-rw-r--r-- | sound/soc/codecs/uda1380.c | 342 |
1 files changed, 155 insertions, 187 deletions
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 2f925a27dcde..c5ca8cfea60f 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -27,20 +27,17 @@ | |||
27 | #include <sound/control.h> | 27 | #include <sound/control.h> |
28 | #include <sound/initval.h> | 28 | #include <sound/initval.h> |
29 | #include <sound/soc.h> | 29 | #include <sound/soc.h> |
30 | #include <sound/soc-dapm.h> | ||
31 | #include <sound/tlv.h> | 30 | #include <sound/tlv.h> |
32 | #include <sound/uda1380.h> | 31 | #include <sound/uda1380.h> |
33 | 32 | ||
34 | #include "uda1380.h" | 33 | #include "uda1380.h" |
35 | 34 | ||
36 | static struct snd_soc_codec *uda1380_codec; | ||
37 | |||
38 | /* codec private data */ | 35 | /* codec private data */ |
39 | struct uda1380_priv { | 36 | struct uda1380_priv { |
40 | struct snd_soc_codec codec; | 37 | struct snd_soc_codec *codec; |
41 | u16 reg_cache[UDA1380_CACHEREGNUM]; | ||
42 | unsigned int dac_clk; | 38 | unsigned int dac_clk; |
43 | struct work_struct work; | 39 | struct work_struct work; |
40 | void *control_data; | ||
44 | }; | 41 | }; |
45 | 42 | ||
46 | /* | 43 | /* |
@@ -131,10 +128,51 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, | |||
131 | return -EIO; | 128 | return -EIO; |
132 | } | 129 | } |
133 | 130 | ||
134 | #define uda1380_reset(c) uda1380_write(c, UDA1380_RESET, 0) | 131 | static void uda1380_sync_cache(struct snd_soc_codec *codec) |
132 | { | ||
133 | int reg; | ||
134 | u8 data[3]; | ||
135 | u16 *cache = codec->reg_cache; | ||
136 | |||
137 | /* Sync reg_cache with the hardware */ | ||
138 | for (reg = 0; reg < UDA1380_MVOL; reg++) { | ||
139 | data[0] = reg; | ||
140 | data[1] = (cache[reg] & 0xff00) >> 8; | ||
141 | data[2] = cache[reg] & 0x00ff; | ||
142 | if (codec->hw_write(codec->control_data, data, 3) != 3) | ||
143 | dev_err(codec->dev, "%s: write to reg 0x%x failed\n", | ||
144 | __func__, reg); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | static int uda1380_reset(struct snd_soc_codec *codec) | ||
149 | { | ||
150 | struct uda1380_platform_data *pdata = codec->dev->platform_data; | ||
151 | |||
152 | if (gpio_is_valid(pdata->gpio_reset)) { | ||
153 | gpio_set_value(pdata->gpio_reset, 1); | ||
154 | mdelay(1); | ||
155 | gpio_set_value(pdata->gpio_reset, 0); | ||
156 | } else { | ||
157 | u8 data[3]; | ||
158 | |||
159 | data[0] = UDA1380_RESET; | ||
160 | data[1] = 0; | ||
161 | data[2] = 0; | ||
162 | |||
163 | if (codec->hw_write(codec->control_data, data, 3) != 3) { | ||
164 | dev_err(codec->dev, "%s: failed\n", __func__); | ||
165 | return -EIO; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | return 0; | ||
170 | } | ||
135 | 171 | ||
136 | static void uda1380_flush_work(struct work_struct *work) | 172 | static void uda1380_flush_work(struct work_struct *work) |
137 | { | 173 | { |
174 | struct uda1380_priv *uda1380 = container_of(work, struct uda1380_priv, work); | ||
175 | struct snd_soc_codec *uda1380_codec = uda1380->codec; | ||
138 | int bit, reg; | 176 | int bit, reg; |
139 | 177 | ||
140 | for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { | 178 | for_each_set_bit(bit, &uda1380_cache_dirty, UDA1380_CACHEREGNUM - 0x10) { |
@@ -145,6 +183,7 @@ static void uda1380_flush_work(struct work_struct *work) | |||
145 | uda1380_read_reg_cache(uda1380_codec, reg)); | 183 | uda1380_read_reg_cache(uda1380_codec, reg)); |
146 | clear_bit(bit, &uda1380_cache_dirty); | 184 | clear_bit(bit, &uda1380_cache_dirty); |
147 | } | 185 | } |
186 | |||
148 | } | 187 | } |
149 | 188 | ||
150 | /* declarations of ALSA reg_elem_REAL controls */ | 189 | /* declarations of ALSA reg_elem_REAL controls */ |
@@ -373,10 +412,11 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
373 | 412 | ||
374 | static int uda1380_add_widgets(struct snd_soc_codec *codec) | 413 | static int uda1380_add_widgets(struct snd_soc_codec *codec) |
375 | { | 414 | { |
376 | snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, | 415 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
377 | ARRAY_SIZE(uda1380_dapm_widgets)); | ||
378 | 416 | ||
379 | snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); | 417 | snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, |
418 | ARRAY_SIZE(uda1380_dapm_widgets)); | ||
419 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
380 | 420 | ||
381 | return 0; | 421 | return 0; |
382 | } | 422 | } |
@@ -474,8 +514,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd, | |||
474 | struct snd_soc_dai *dai) | 514 | struct snd_soc_dai *dai) |
475 | { | 515 | { |
476 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 516 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
477 | struct snd_soc_device *socdev = rtd->socdev; | 517 | struct snd_soc_codec *codec = rtd->codec; |
478 | struct snd_soc_codec *codec = socdev->card->codec; | ||
479 | struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); | 518 | struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); |
480 | int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); | 519 | int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); |
481 | 520 | ||
@@ -501,8 +540,7 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream, | |||
501 | struct snd_soc_dai *dai) | 540 | struct snd_soc_dai *dai) |
502 | { | 541 | { |
503 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 542 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
504 | struct snd_soc_device *socdev = rtd->socdev; | 543 | struct snd_soc_codec *codec = rtd->codec; |
505 | struct snd_soc_codec *codec = socdev->card->codec; | ||
506 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); | 544 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); |
507 | 545 | ||
508 | /* set WSPLL power and divider if running from this clock */ | 546 | /* set WSPLL power and divider if running from this clock */ |
@@ -540,8 +578,7 @@ static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream, | |||
540 | struct snd_soc_dai *dai) | 578 | struct snd_soc_dai *dai) |
541 | { | 579 | { |
542 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 580 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
543 | struct snd_soc_device *socdev = rtd->socdev; | 581 | struct snd_soc_codec *codec = rtd->codec; |
544 | struct snd_soc_codec *codec = socdev->card->codec; | ||
545 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); | 582 | u16 clk = uda1380_read_reg_cache(codec, UDA1380_CLK); |
546 | 583 | ||
547 | /* shut down WSPLL power if running from this clock */ | 584 | /* shut down WSPLL power if running from this clock */ |
@@ -562,20 +599,43 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, | |||
562 | enum snd_soc_bias_level level) | 599 | enum snd_soc_bias_level level) |
563 | { | 600 | { |
564 | int pm = uda1380_read_reg_cache(codec, UDA1380_PM); | 601 | int pm = uda1380_read_reg_cache(codec, UDA1380_PM); |
602 | int reg; | ||
603 | struct uda1380_platform_data *pdata = codec->dev->platform_data; | ||
604 | |||
605 | if (codec->dapm.bias_level == level) | ||
606 | return 0; | ||
565 | 607 | ||
566 | switch (level) { | 608 | switch (level) { |
567 | case SND_SOC_BIAS_ON: | 609 | case SND_SOC_BIAS_ON: |
568 | case SND_SOC_BIAS_PREPARE: | 610 | case SND_SOC_BIAS_PREPARE: |
611 | /* ADC, DAC on */ | ||
569 | uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm); | 612 | uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm); |
570 | break; | 613 | break; |
571 | case SND_SOC_BIAS_STANDBY: | 614 | case SND_SOC_BIAS_STANDBY: |
572 | uda1380_write(codec, UDA1380_PM, R02_PON_BIAS); | 615 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
573 | break; | 616 | if (gpio_is_valid(pdata->gpio_power)) { |
574 | case SND_SOC_BIAS_OFF: | 617 | gpio_set_value(pdata->gpio_power, 1); |
618 | mdelay(1); | ||
619 | uda1380_reset(codec); | ||
620 | } | ||
621 | |||
622 | uda1380_sync_cache(codec); | ||
623 | } | ||
575 | uda1380_write(codec, UDA1380_PM, 0x0); | 624 | uda1380_write(codec, UDA1380_PM, 0x0); |
576 | break; | 625 | break; |
626 | case SND_SOC_BIAS_OFF: | ||
627 | if (!gpio_is_valid(pdata->gpio_power)) | ||
628 | break; | ||
629 | |||
630 | gpio_set_value(pdata->gpio_power, 0); | ||
631 | |||
632 | /* Mark mixer regs cache dirty to sync them with | ||
633 | * codec regs on power on. | ||
634 | */ | ||
635 | for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++) | ||
636 | set_bit(reg - 0x10, &uda1380_cache_dirty); | ||
577 | } | 637 | } |
578 | codec->bias_level = level; | 638 | codec->dapm.bias_level = level; |
579 | return 0; | 639 | return 0; |
580 | } | 640 | } |
581 | 641 | ||
@@ -604,9 +664,9 @@ static struct snd_soc_dai_ops uda1380_dai_ops_capture = { | |||
604 | .set_fmt = uda1380_set_dai_fmt_capture, | 664 | .set_fmt = uda1380_set_dai_fmt_capture, |
605 | }; | 665 | }; |
606 | 666 | ||
607 | struct snd_soc_dai uda1380_dai[] = { | 667 | static struct snd_soc_dai_driver uda1380_dai[] = { |
608 | { | 668 | { |
609 | .name = "UDA1380", | 669 | .name = "uda1380-hifi", |
610 | .playback = { | 670 | .playback = { |
611 | .stream_name = "Playback", | 671 | .stream_name = "Playback", |
612 | .channels_min = 1, | 672 | .channels_min = 1, |
@@ -622,7 +682,7 @@ struct snd_soc_dai uda1380_dai[] = { | |||
622 | .ops = &uda1380_dai_ops, | 682 | .ops = &uda1380_dai_ops, |
623 | }, | 683 | }, |
624 | { /* playback only - dual interface */ | 684 | { /* playback only - dual interface */ |
625 | .name = "UDA1380", | 685 | .name = "uda1380-hifi-playback", |
626 | .playback = { | 686 | .playback = { |
627 | .stream_name = "Playback", | 687 | .stream_name = "Playback", |
628 | .channels_min = 1, | 688 | .channels_min = 1, |
@@ -633,7 +693,7 @@ struct snd_soc_dai uda1380_dai[] = { | |||
633 | .ops = &uda1380_dai_ops_playback, | 693 | .ops = &uda1380_dai_ops_playback, |
634 | }, | 694 | }, |
635 | { /* capture only - dual interface*/ | 695 | { /* capture only - dual interface*/ |
636 | .name = "UDA1380", | 696 | .name = "uda1380-hifi-capture", |
637 | .capture = { | 697 | .capture = { |
638 | .stream_name = "Capture", | 698 | .stream_name = "Capture", |
639 | .channels_min = 1, | 699 | .channels_min = 1, |
@@ -644,67 +704,69 @@ struct snd_soc_dai uda1380_dai[] = { | |||
644 | .ops = &uda1380_dai_ops_capture, | 704 | .ops = &uda1380_dai_ops_capture, |
645 | }, | 705 | }, |
646 | }; | 706 | }; |
647 | EXPORT_SYMBOL_GPL(uda1380_dai); | ||
648 | 707 | ||
649 | static int uda1380_suspend(struct platform_device *pdev, pm_message_t state) | 708 | static int uda1380_suspend(struct snd_soc_codec *codec, pm_message_t state) |
650 | { | 709 | { |
651 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
652 | struct snd_soc_codec *codec = socdev->card->codec; | ||
653 | |||
654 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); | 710 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); |
655 | return 0; | 711 | return 0; |
656 | } | 712 | } |
657 | 713 | ||
658 | static int uda1380_resume(struct platform_device *pdev) | 714 | static int uda1380_resume(struct snd_soc_codec *codec) |
659 | { | 715 | { |
660 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
661 | struct snd_soc_codec *codec = socdev->card->codec; | ||
662 | int i; | ||
663 | u8 data[2]; | ||
664 | u16 *cache = codec->reg_cache; | ||
665 | |||
666 | /* Sync reg_cache with the hardware */ | ||
667 | for (i = 0; i < ARRAY_SIZE(uda1380_reg); i++) { | ||
668 | data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); | ||
669 | data[1] = cache[i] & 0x00ff; | ||
670 | codec->hw_write(codec->control_data, data, 2); | ||
671 | } | ||
672 | uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 716 | uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
673 | return 0; | 717 | return 0; |
674 | } | 718 | } |
675 | 719 | ||
676 | static int uda1380_probe(struct platform_device *pdev) | 720 | static int uda1380_probe(struct snd_soc_codec *codec) |
677 | { | 721 | { |
678 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 722 | struct uda1380_platform_data *pdata =codec->dev->platform_data; |
679 | struct snd_soc_codec *codec; | 723 | struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); |
680 | struct uda1380_platform_data *pdata; | 724 | int ret; |
681 | int ret = 0; | ||
682 | 725 | ||
683 | if (uda1380_codec == NULL) { | 726 | uda1380->codec = codec; |
684 | dev_err(&pdev->dev, "Codec device not registered\n"); | 727 | |
685 | return -ENODEV; | 728 | codec->hw_write = (hw_write_t)i2c_master_send; |
686 | } | 729 | codec->control_data = uda1380->control_data; |
687 | 730 | ||
688 | socdev->card->codec = uda1380_codec; | 731 | if (!pdata) |
689 | codec = uda1380_codec; | 732 | return -EINVAL; |
690 | pdata = codec->dev->platform_data; | 733 | |
734 | if (gpio_is_valid(pdata->gpio_reset)) { | ||
735 | ret = gpio_request(pdata->gpio_reset, "uda1380 reset"); | ||
736 | if (ret) | ||
737 | goto err_out; | ||
738 | ret = gpio_direction_output(pdata->gpio_reset, 0); | ||
739 | if (ret) | ||
740 | goto err_gpio_reset_conf; | ||
741 | } | ||
691 | 742 | ||
692 | /* register pcms */ | 743 | if (gpio_is_valid(pdata->gpio_power)) { |
693 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 744 | ret = gpio_request(pdata->gpio_power, "uda1380 power"); |
694 | if (ret < 0) { | 745 | if (ret) |
695 | dev_err(codec->dev, "failed to create pcms: %d\n", ret); | 746 | goto err_gpio; |
696 | goto pcm_err; | 747 | ret = gpio_direction_output(pdata->gpio_power, 0); |
748 | if (ret) | ||
749 | goto err_gpio_power_conf; | ||
750 | } else { | ||
751 | ret = uda1380_reset(codec); | ||
752 | if (ret) { | ||
753 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
754 | goto err_reset; | ||
755 | } | ||
697 | } | 756 | } |
698 | 757 | ||
758 | INIT_WORK(&uda1380->work, uda1380_flush_work); | ||
759 | |||
699 | /* power on device */ | 760 | /* power on device */ |
700 | uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 761 | uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
701 | /* set clock input */ | 762 | /* set clock input */ |
702 | switch (pdata->dac_clk) { | 763 | switch (pdata->dac_clk) { |
703 | case UDA1380_DAC_CLK_SYSCLK: | 764 | case UDA1380_DAC_CLK_SYSCLK: |
704 | uda1380_write(codec, UDA1380_CLK, 0); | 765 | uda1380_write_reg_cache(codec, UDA1380_CLK, 0); |
705 | break; | 766 | break; |
706 | case UDA1380_DAC_CLK_WSPLL: | 767 | case UDA1380_DAC_CLK_WSPLL: |
707 | uda1380_write(codec, UDA1380_CLK, R00_DAC_CLK); | 768 | uda1380_write_reg_cache(codec, UDA1380_CLK, |
769 | R00_DAC_CLK); | ||
708 | break; | 770 | break; |
709 | } | 771 | } |
710 | 772 | ||
@@ -712,167 +774,73 @@ static int uda1380_probe(struct platform_device *pdev) | |||
712 | ARRAY_SIZE(uda1380_snd_controls)); | 774 | ARRAY_SIZE(uda1380_snd_controls)); |
713 | uda1380_add_widgets(codec); | 775 | uda1380_add_widgets(codec); |
714 | 776 | ||
715 | return ret; | ||
716 | |||
717 | pcm_err: | ||
718 | return ret; | ||
719 | } | ||
720 | |||
721 | /* power down chip */ | ||
722 | static int uda1380_remove(struct platform_device *pdev) | ||
723 | { | ||
724 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
725 | struct snd_soc_codec *codec = socdev->card->codec; | ||
726 | |||
727 | if (codec->control_data) | ||
728 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
729 | |||
730 | snd_soc_free_pcms(socdev); | ||
731 | snd_soc_dapm_free(socdev); | ||
732 | |||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | struct snd_soc_codec_device soc_codec_dev_uda1380 = { | ||
737 | .probe = uda1380_probe, | ||
738 | .remove = uda1380_remove, | ||
739 | .suspend = uda1380_suspend, | ||
740 | .resume = uda1380_resume, | ||
741 | }; | ||
742 | EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); | ||
743 | |||
744 | static int uda1380_register(struct uda1380_priv *uda1380) | ||
745 | { | ||
746 | int ret, i; | ||
747 | struct snd_soc_codec *codec = &uda1380->codec; | ||
748 | struct uda1380_platform_data *pdata = codec->dev->platform_data; | ||
749 | |||
750 | if (uda1380_codec) { | ||
751 | dev_err(codec->dev, "Another UDA1380 is registered\n"); | ||
752 | return -EINVAL; | ||
753 | } | ||
754 | |||
755 | if (!pdata || !pdata->gpio_power || !pdata->gpio_reset) | ||
756 | return -EINVAL; | ||
757 | |||
758 | ret = gpio_request(pdata->gpio_power, "uda1380 power"); | ||
759 | if (ret) | ||
760 | goto err_out; | ||
761 | ret = gpio_request(pdata->gpio_reset, "uda1380 reset"); | ||
762 | if (ret) | ||
763 | goto err_gpio; | ||
764 | |||
765 | gpio_direction_output(pdata->gpio_power, 1); | ||
766 | |||
767 | /* we may need to have the clock running here - pH5 */ | ||
768 | gpio_direction_output(pdata->gpio_reset, 1); | ||
769 | udelay(5); | ||
770 | gpio_set_value(pdata->gpio_reset, 0); | ||
771 | |||
772 | mutex_init(&codec->mutex); | ||
773 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
774 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
775 | |||
776 | snd_soc_codec_set_drvdata(codec, uda1380); | ||
777 | codec->name = "UDA1380"; | ||
778 | codec->owner = THIS_MODULE; | ||
779 | codec->read = uda1380_read_reg_cache; | ||
780 | codec->write = uda1380_write; | ||
781 | codec->bias_level = SND_SOC_BIAS_OFF; | ||
782 | codec->set_bias_level = uda1380_set_bias_level; | ||
783 | codec->dai = uda1380_dai; | ||
784 | codec->num_dai = ARRAY_SIZE(uda1380_dai); | ||
785 | codec->reg_cache_size = ARRAY_SIZE(uda1380_reg); | ||
786 | codec->reg_cache = &uda1380->reg_cache; | ||
787 | codec->reg_cache_step = 1; | ||
788 | |||
789 | memcpy(codec->reg_cache, uda1380_reg, sizeof(uda1380_reg)); | ||
790 | |||
791 | ret = uda1380_reset(codec); | ||
792 | if (ret < 0) { | ||
793 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
794 | goto err_reset; | ||
795 | } | ||
796 | |||
797 | INIT_WORK(&uda1380->work, uda1380_flush_work); | ||
798 | |||
799 | for (i = 0; i < ARRAY_SIZE(uda1380_dai); i++) | ||
800 | uda1380_dai[i].dev = codec->dev; | ||
801 | |||
802 | uda1380_codec = codec; | ||
803 | |||
804 | ret = snd_soc_register_codec(codec); | ||
805 | if (ret != 0) { | ||
806 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | ||
807 | goto err_reset; | ||
808 | } | ||
809 | |||
810 | ret = snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); | ||
811 | if (ret != 0) { | ||
812 | dev_err(codec->dev, "Failed to register DAIs: %d\n", ret); | ||
813 | goto err_dai; | ||
814 | } | ||
815 | |||
816 | return 0; | 777 | return 0; |
817 | 778 | ||
818 | err_dai: | ||
819 | snd_soc_unregister_codec(codec); | ||
820 | err_reset: | 779 | err_reset: |
821 | gpio_set_value(pdata->gpio_power, 0); | 780 | err_gpio_power_conf: |
822 | gpio_free(pdata->gpio_reset); | 781 | if (gpio_is_valid(pdata->gpio_power)) |
782 | gpio_free(pdata->gpio_power); | ||
783 | |||
784 | err_gpio_reset_conf: | ||
823 | err_gpio: | 785 | err_gpio: |
824 | gpio_free(pdata->gpio_power); | 786 | if (gpio_is_valid(pdata->gpio_reset)) |
787 | gpio_free(pdata->gpio_reset); | ||
825 | err_out: | 788 | err_out: |
826 | return ret; | 789 | return ret; |
827 | } | 790 | } |
828 | 791 | ||
829 | static void uda1380_unregister(struct uda1380_priv *uda1380) | 792 | /* power down chip */ |
793 | static int uda1380_remove(struct snd_soc_codec *codec) | ||
830 | { | 794 | { |
831 | struct snd_soc_codec *codec = &uda1380->codec; | 795 | struct uda1380_platform_data *pdata =codec->dev->platform_data; |
832 | struct uda1380_platform_data *pdata = codec->dev->platform_data; | ||
833 | 796 | ||
834 | snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); | 797 | uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF); |
835 | snd_soc_unregister_codec(&uda1380->codec); | ||
836 | 798 | ||
837 | gpio_set_value(pdata->gpio_power, 0); | ||
838 | gpio_free(pdata->gpio_reset); | 799 | gpio_free(pdata->gpio_reset); |
839 | gpio_free(pdata->gpio_power); | 800 | gpio_free(pdata->gpio_power); |
840 | 801 | ||
841 | kfree(uda1380); | 802 | return 0; |
842 | uda1380_codec = NULL; | ||
843 | } | 803 | } |
844 | 804 | ||
805 | static struct snd_soc_codec_driver soc_codec_dev_uda1380 = { | ||
806 | .probe = uda1380_probe, | ||
807 | .remove = uda1380_remove, | ||
808 | .suspend = uda1380_suspend, | ||
809 | .resume = uda1380_resume, | ||
810 | .read = uda1380_read_reg_cache, | ||
811 | .write = uda1380_write, | ||
812 | .set_bias_level = uda1380_set_bias_level, | ||
813 | .reg_cache_size = ARRAY_SIZE(uda1380_reg), | ||
814 | .reg_word_size = sizeof(u16), | ||
815 | .reg_cache_default = uda1380_reg, | ||
816 | .reg_cache_step = 1, | ||
817 | }; | ||
818 | |||
845 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 819 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
846 | static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, | 820 | static __devinit int uda1380_i2c_probe(struct i2c_client *i2c, |
847 | const struct i2c_device_id *id) | 821 | const struct i2c_device_id *id) |
848 | { | 822 | { |
849 | struct uda1380_priv *uda1380; | 823 | struct uda1380_priv *uda1380; |
850 | struct snd_soc_codec *codec; | ||
851 | int ret; | 824 | int ret; |
852 | 825 | ||
853 | uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL); | 826 | uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL); |
854 | if (uda1380 == NULL) | 827 | if (uda1380 == NULL) |
855 | return -ENOMEM; | 828 | return -ENOMEM; |
856 | 829 | ||
857 | codec = &uda1380->codec; | ||
858 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
859 | |||
860 | i2c_set_clientdata(i2c, uda1380); | 830 | i2c_set_clientdata(i2c, uda1380); |
861 | codec->control_data = i2c; | 831 | uda1380->control_data = i2c; |
862 | 832 | ||
863 | codec->dev = &i2c->dev; | 833 | ret = snd_soc_register_codec(&i2c->dev, |
864 | 834 | &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai)); | |
865 | ret = uda1380_register(uda1380); | 835 | if (ret < 0) |
866 | if (ret != 0) | ||
867 | kfree(uda1380); | 836 | kfree(uda1380); |
868 | |||
869 | return ret; | 837 | return ret; |
870 | } | 838 | } |
871 | 839 | ||
872 | static int __devexit uda1380_i2c_remove(struct i2c_client *i2c) | 840 | static int __devexit uda1380_i2c_remove(struct i2c_client *i2c) |
873 | { | 841 | { |
874 | struct uda1380_priv *uda1380 = i2c_get_clientdata(i2c); | 842 | snd_soc_unregister_codec(&i2c->dev); |
875 | uda1380_unregister(uda1380); | 843 | kfree(i2c_get_clientdata(i2c)); |
876 | return 0; | 844 | return 0; |
877 | } | 845 | } |
878 | 846 | ||
@@ -884,7 +852,7 @@ MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id); | |||
884 | 852 | ||
885 | static struct i2c_driver uda1380_i2c_driver = { | 853 | static struct i2c_driver uda1380_i2c_driver = { |
886 | .driver = { | 854 | .driver = { |
887 | .name = "UDA1380 I2C Codec", | 855 | .name = "uda1380-codec", |
888 | .owner = THIS_MODULE, | 856 | .owner = THIS_MODULE, |
889 | }, | 857 | }, |
890 | .probe = uda1380_i2c_probe, | 858 | .probe = uda1380_i2c_probe, |