aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8580.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8580.c')
-rw-r--r--sound/soc/codecs/wm8580.c321
1 files changed, 152 insertions, 169 deletions
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 72deeabef4fe..a2e0ed59b376 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -94,6 +94,8 @@
94 94
95#define WM8580_MAX_REGISTER 0x35 95#define WM8580_MAX_REGISTER 0x35
96 96
97#define WM8580_DACOSR 0x40
98
97/* PLLB4 (register 7h) */ 99/* PLLB4 (register 7h) */
98#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60 100#define WM8580_PLLB4_MCLKOUTSRC_MASK 0x60
99#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20 101#define WM8580_PLLB4_MCLKOUTSRC_PLLA 0x20
@@ -112,19 +114,7 @@
112 114
113/* AIF control 1 (registers 9h-bh) */ 115/* AIF control 1 (registers 9h-bh) */
114#define WM8580_AIF_RATE_MASK 0x7 116#define WM8580_AIF_RATE_MASK 0x7
115#define WM8580_AIF_RATE_128 0x0
116#define WM8580_AIF_RATE_192 0x1
117#define WM8580_AIF_RATE_256 0x2
118#define WM8580_AIF_RATE_384 0x3
119#define WM8580_AIF_RATE_512 0x4
120#define WM8580_AIF_RATE_768 0x5
121#define WM8580_AIF_RATE_1152 0x6
122
123#define WM8580_AIF_BCLKSEL_MASK 0x18 117#define WM8580_AIF_BCLKSEL_MASK 0x18
124#define WM8580_AIF_BCLKSEL_64 0x00
125#define WM8580_AIF_BCLKSEL_128 0x08
126#define WM8580_AIF_BCLKSEL_256 0x10
127#define WM8580_AIF_BCLKSEL_SYSCLK 0x18
128 118
129#define WM8580_AIF_MS 0x20 119#define WM8580_AIF_MS 0x20
130 120
@@ -199,11 +189,12 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
199 189
200/* codec private data */ 190/* codec private data */
201struct wm8580_priv { 191struct wm8580_priv {
202 struct snd_soc_codec codec; 192 enum snd_soc_control_type control_type;
203 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; 193 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
204 u16 reg_cache[WM8580_MAX_REGISTER + 1]; 194 u16 reg_cache[WM8580_MAX_REGISTER + 1];
205 struct pll_state a; 195 struct pll_state a;
206 struct pll_state b; 196 struct pll_state b;
197 int sysclk[2];
207}; 198};
208 199
209static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); 200static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
@@ -273,8 +264,8 @@ SOC_SINGLE("DAC1 Switch", WM8580_DAC_CONTROL5, 0, 1, 1),
273SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 1), 264SOC_SINGLE("DAC2 Switch", WM8580_DAC_CONTROL5, 1, 1, 1),
274SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 1), 265SOC_SINGLE("DAC3 Switch", WM8580_DAC_CONTROL5, 2, 1, 1),
275 266
276SOC_DOUBLE("ADC Mute Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 0), 267SOC_DOUBLE("Capture Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 1),
277SOC_SINGLE("ADC High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), 268SOC_SINGLE("Capture High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0),
278}; 269};
279 270
280static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = { 271static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = {
@@ -476,6 +467,10 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
476 return 0; 467 return 0;
477} 468}
478 469
470static const int wm8580_sysclk_ratios[] = {
471 128, 192, 256, 384, 512, 768, 1152,
472};
473
479/* 474/*
480 * Set PCM DAI bit size and sample rate. 475 * Set PCM DAI bit size and sample rate.
481 */ 476 */
@@ -484,29 +479,68 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
484 struct snd_soc_dai *dai) 479 struct snd_soc_dai *dai)
485{ 480{
486 struct snd_soc_pcm_runtime *rtd = substream->private_data; 481 struct snd_soc_pcm_runtime *rtd = substream->private_data;
487 struct snd_soc_device *socdev = rtd->socdev; 482 struct snd_soc_codec *codec = rtd->codec;
488 struct snd_soc_codec *codec = socdev->card->codec; 483 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
489 u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->id); 484 u16 paifa = 0;
485 u16 paifb = 0;
486 int i, ratio, osr;
490 487
491 paifb &= ~WM8580_AIF_LENGTH_MASK;
492 /* bit size */ 488 /* bit size */
493 switch (params_format(params)) { 489 switch (params_format(params)) {
494 case SNDRV_PCM_FORMAT_S16_LE: 490 case SNDRV_PCM_FORMAT_S16_LE:
491 paifa |= 0x8;
495 break; 492 break;
496 case SNDRV_PCM_FORMAT_S20_3LE: 493 case SNDRV_PCM_FORMAT_S20_3LE:
494 paifa |= 0x10;
497 paifb |= WM8580_AIF_LENGTH_20; 495 paifb |= WM8580_AIF_LENGTH_20;
498 break; 496 break;
499 case SNDRV_PCM_FORMAT_S24_LE: 497 case SNDRV_PCM_FORMAT_S24_LE:
498 paifa |= 0x10;
500 paifb |= WM8580_AIF_LENGTH_24; 499 paifb |= WM8580_AIF_LENGTH_24;
501 break; 500 break;
502 case SNDRV_PCM_FORMAT_S32_LE: 501 case SNDRV_PCM_FORMAT_S32_LE:
502 paifa |= 0x10;
503 paifb |= WM8580_AIF_LENGTH_24; 503 paifb |= WM8580_AIF_LENGTH_24;
504 break; 504 break;
505 default: 505 default:
506 return -EINVAL; 506 return -EINVAL;
507 } 507 }
508 508
509 snd_soc_write(codec, WM8580_PAIF3 + dai->id, paifb); 509 /* Look up the SYSCLK ratio; accept only exact matches */
510 ratio = wm8580->sysclk[dai->id] / params_rate(params);
511 for (i = 0; i < ARRAY_SIZE(wm8580_sysclk_ratios); i++)
512 if (ratio == wm8580_sysclk_ratios[i])
513 break;
514 if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) {
515 dev_err(codec->dev, "Invalid clock ratio %d/%d\n",
516 wm8580->sysclk[dai->id], params_rate(params));
517 return -EINVAL;
518 }
519 paifa |= i;
520 dev_dbg(codec->dev, "Running at %dfs with %dHz clock\n",
521 wm8580_sysclk_ratios[i], wm8580->sysclk[dai->driver->id]);
522
523 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
524 switch (ratio) {
525 case 128:
526 case 192:
527 osr = WM8580_DACOSR;
528 dev_dbg(codec->dev, "Selecting 64x OSR\n");
529 break;
530 default:
531 osr = 0;
532 dev_dbg(codec->dev, "Selecting 128x OSR\n");
533 break;
534 }
535
536 snd_soc_update_bits(codec, WM8580_PAIF3, WM8580_DACOSR, osr);
537 }
538
539 snd_soc_update_bits(codec, WM8580_PAIF1 + dai->driver->id,
540 WM8580_AIF_RATE_MASK | WM8580_AIF_BCLKSEL_MASK,
541 paifa);
542 snd_soc_update_bits(codec, WM8580_PAIF3 + dai->driver->id,
543 WM8580_AIF_LENGTH_MASK, paifb);
510 return 0; 544 return 0;
511} 545}
512 546
@@ -518,8 +552,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
518 unsigned int aifb; 552 unsigned int aifb;
519 int can_invert_lrclk; 553 int can_invert_lrclk;
520 554
521 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->id); 555 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->driver->id);
522 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->id); 556 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->driver->id);
523 557
524 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP); 558 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
525 559
@@ -585,8 +619,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
585 return -EINVAL; 619 return -EINVAL;
586 } 620 }
587 621
588 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->id, aifa); 622 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->driver->id, aifa);
589 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->id, aifb); 623 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->driver->id, aifb);
590 624
591 return 0; 625 return 0;
592} 626}
@@ -624,28 +658,6 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
624 snd_soc_write(codec, WM8580_PLLB4, reg); 658 snd_soc_write(codec, WM8580_PLLB4, reg);
625 break; 659 break;
626 660
627 case WM8580_DAC_CLKSEL:
628 reg = snd_soc_read(codec, WM8580_CLKSEL);
629 reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK;
630
631 switch (div) {
632 case WM8580_CLKSRC_MCLK:
633 break;
634
635 case WM8580_CLKSRC_PLLA:
636 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLA;
637 break;
638
639 case WM8580_CLKSRC_PLLB:
640 reg |= WM8580_CLKSEL_DAC_CLKSEL_PLLB;
641 break;
642
643 default:
644 return -EINVAL;
645 }
646 snd_soc_write(codec, WM8580_CLKSEL, reg);
647 break;
648
649 case WM8580_CLKOUTSRC: 661 case WM8580_CLKOUTSRC:
650 reg = snd_soc_read(codec, WM8580_PLLB4); 662 reg = snd_soc_read(codec, WM8580_PLLB4);
651 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK; 663 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
@@ -679,6 +691,55 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
679 return 0; 691 return 0;
680} 692}
681 693
694static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
695 unsigned int freq, int dir)
696{
697 struct snd_soc_codec *codec = dai->codec;
698 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
699 int sel, sel_mask, sel_shift;
700
701 switch (dai->driver->id) {
702 case WM8580_DAI_PAIFRX:
703 sel_mask = 0x3;
704 sel_shift = 0;
705 break;
706
707 case WM8580_DAI_PAIFTX:
708 sel_mask = 0xc;
709 sel_shift = 2;
710 break;
711
712 default:
713 BUG_ON("Unknown DAI driver ID\n");
714 return -EINVAL;
715 }
716
717 switch (clk_id) {
718 case WM8580_CLKSRC_ADCMCLK:
719 if (dai->id != WM8580_DAI_PAIFTX)
720 return -EINVAL;
721 sel = 0 << sel_shift;
722 break;
723 case WM8580_CLKSRC_PLLA:
724 sel = 1 << sel_shift;
725 break;
726 case WM8580_CLKSRC_PLLB:
727 sel = 2 << sel_shift;
728 break;
729 case WM8580_CLKSRC_MCLK:
730 sel = 3 << sel_shift;
731 break;
732 default:
733 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
734 return -EINVAL;
735 }
736
737 /* We really should validate PLL settings but not yet */
738 wm8580->sysclk[dai->id] = freq;
739
740 return snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
741}
742
682static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute) 743static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
683{ 744{
684 struct snd_soc_codec *codec = codec_dai->codec; 745 struct snd_soc_codec *codec = codec_dai->codec;
@@ -732,6 +793,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
732 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) 793 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
733 794
734static struct snd_soc_dai_ops wm8580_dai_ops_playback = { 795static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
796 .set_sysclk = wm8580_set_sysclk,
735 .hw_params = wm8580_paif_hw_params, 797 .hw_params = wm8580_paif_hw_params,
736 .set_fmt = wm8580_set_paif_dai_fmt, 798 .set_fmt = wm8580_set_paif_dai_fmt,
737 .set_clkdiv = wm8580_set_dai_clkdiv, 799 .set_clkdiv = wm8580_set_dai_clkdiv,
@@ -740,16 +802,17 @@ static struct snd_soc_dai_ops wm8580_dai_ops_playback = {
740}; 802};
741 803
742static struct snd_soc_dai_ops wm8580_dai_ops_capture = { 804static struct snd_soc_dai_ops wm8580_dai_ops_capture = {
805 .set_sysclk = wm8580_set_sysclk,
743 .hw_params = wm8580_paif_hw_params, 806 .hw_params = wm8580_paif_hw_params,
744 .set_fmt = wm8580_set_paif_dai_fmt, 807 .set_fmt = wm8580_set_paif_dai_fmt,
745 .set_clkdiv = wm8580_set_dai_clkdiv, 808 .set_clkdiv = wm8580_set_dai_clkdiv,
746 .set_pll = wm8580_set_dai_pll, 809 .set_pll = wm8580_set_dai_pll,
747}; 810};
748 811
749struct snd_soc_dai wm8580_dai[] = { 812static struct snd_soc_dai_driver wm8580_dai[] = {
750 { 813 {
751 .name = "WM8580 PAIFRX", 814 .name = "wm8580-hifi-playback",
752 .id = 0, 815 .id = WM8580_DAI_PAIFRX,
753 .playback = { 816 .playback = {
754 .stream_name = "Playback", 817 .stream_name = "Playback",
755 .channels_min = 1, 818 .channels_min = 1,
@@ -760,8 +823,8 @@ struct snd_soc_dai wm8580_dai[] = {
760 .ops = &wm8580_dai_ops_playback, 823 .ops = &wm8580_dai_ops_playback,
761 }, 824 },
762 { 825 {
763 .name = "WM8580 PAIFTX", 826 .name = "wm8580-hifi-capture",
764 .id = 1, 827 .id = WM8580_DAI_PAIFTX,
765 .capture = { 828 .capture = {
766 .stream_name = "Capture", 829 .stream_name = "Capture",
767 .channels_min = 2, 830 .channels_min = 2,
@@ -772,90 +835,16 @@ struct snd_soc_dai wm8580_dai[] = {
772 .ops = &wm8580_dai_ops_capture, 835 .ops = &wm8580_dai_ops_capture,
773 }, 836 },
774}; 837};
775EXPORT_SYMBOL_GPL(wm8580_dai);
776
777static struct snd_soc_codec *wm8580_codec;
778 838
779static int wm8580_probe(struct platform_device *pdev) 839static int wm8580_probe(struct snd_soc_codec *codec)
780{ 840{
781 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 841 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
782 struct snd_soc_codec *codec; 842 int ret = 0,i;
783 int ret = 0;
784
785 if (wm8580_codec == NULL) {
786 dev_err(&pdev->dev, "Codec device not registered\n");
787 return -ENODEV;
788 }
789
790 socdev->card->codec = wm8580_codec;
791 codec = wm8580_codec;
792
793 /* register pcms */
794 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
795 if (ret < 0) {
796 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
797 goto pcm_err;
798 }
799
800 snd_soc_add_controls(codec, wm8580_snd_controls,
801 ARRAY_SIZE(wm8580_snd_controls));
802 wm8580_add_widgets(codec);
803
804 return ret;
805
806pcm_err:
807 return ret;
808}
809
810/* power down chip */
811static int wm8580_remove(struct platform_device *pdev)
812{
813 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
814
815 snd_soc_free_pcms(socdev);
816 snd_soc_dapm_free(socdev);
817
818 return 0;
819}
820
821struct snd_soc_codec_device soc_codec_dev_wm8580 = {
822 .probe = wm8580_probe,
823 .remove = wm8580_remove,
824};
825EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
826
827static int wm8580_register(struct wm8580_priv *wm8580,
828 enum snd_soc_control_type control)
829{
830 int ret, i;
831 struct snd_soc_codec *codec = &wm8580->codec;
832
833 if (wm8580_codec) {
834 dev_err(codec->dev, "Another WM8580 is registered\n");
835 ret = -EINVAL;
836 goto err;
837 }
838
839 mutex_init(&codec->mutex);
840 INIT_LIST_HEAD(&codec->dapm_widgets);
841 INIT_LIST_HEAD(&codec->dapm_paths);
842
843 snd_soc_codec_set_drvdata(codec, wm8580);
844 codec->name = "WM8580";
845 codec->owner = THIS_MODULE;
846 codec->bias_level = SND_SOC_BIAS_OFF;
847 codec->set_bias_level = wm8580_set_bias_level;
848 codec->dai = wm8580_dai;
849 codec->num_dai = ARRAY_SIZE(wm8580_dai);
850 codec->reg_cache_size = ARRAY_SIZE(wm8580->reg_cache);
851 codec->reg_cache = &wm8580->reg_cache;
852
853 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
854 843
855 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); 844 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8580->control_type);
856 if (ret < 0) { 845 if (ret < 0) {
857 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); 846 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
858 goto err; 847 return ret;
859 } 848 }
860 849
861 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++) 850 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
@@ -865,7 +854,7 @@ static int wm8580_register(struct wm8580_priv *wm8580,
865 wm8580->supplies); 854 wm8580->supplies);
866 if (ret != 0) { 855 if (ret != 0) {
867 dev_err(codec->dev, "Failed to request supplies: %d\n", ret); 856 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
868 goto err; 857 return ret;
869 } 858 }
870 859
871 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), 860 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
@@ -882,74 +871,68 @@ static int wm8580_register(struct wm8580_priv *wm8580,
882 goto err_regulator_enable; 871 goto err_regulator_enable;
883 } 872 }
884 873
885 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
886 wm8580_dai[i].dev = codec->dev;
887
888 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 874 wm8580_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
889 875
890 wm8580_codec = codec; 876 snd_soc_add_controls(codec, wm8580_snd_controls,
891 877 ARRAY_SIZE(wm8580_snd_controls));
892 ret = snd_soc_register_codec(codec); 878 wm8580_add_widgets(codec);
893 if (ret != 0) {
894 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
895 goto err_regulator_enable;
896 }
897
898 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
899 if (ret != 0) {
900 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
901 goto err_codec;
902 }
903 879
904 return 0; 880 return 0;
905 881
906err_codec:
907 snd_soc_unregister_codec(codec);
908err_regulator_enable: 882err_regulator_enable:
909 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 883 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
910err_regulator_get: 884err_regulator_get:
911 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 885 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
912err:
913 kfree(wm8580);
914 return ret; 886 return ret;
915} 887}
916 888
917static void wm8580_unregister(struct wm8580_priv *wm8580) 889/* power down chip */
890static int wm8580_remove(struct snd_soc_codec *codec)
918{ 891{
919 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF); 892 struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec);
920 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 893
921 snd_soc_unregister_codec(&wm8580->codec); 894 wm8580_set_bias_level(codec, SND_SOC_BIAS_OFF);
895
922 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 896 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
923 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); 897 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
924 kfree(wm8580); 898
925 wm8580_codec = NULL; 899 return 0;
926} 900}
927 901
902static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
903 .probe = wm8580_probe,
904 .remove = wm8580_remove,
905 .set_bias_level = wm8580_set_bias_level,
906 .reg_cache_size = ARRAY_SIZE(wm8580_reg),
907 .reg_word_size = sizeof(u16),
908 .reg_cache_default = &wm8580_reg,
909};
910
928#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 911#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
929static int wm8580_i2c_probe(struct i2c_client *i2c, 912static int wm8580_i2c_probe(struct i2c_client *i2c,
930 const struct i2c_device_id *id) 913 const struct i2c_device_id *id)
931{ 914{
932 struct wm8580_priv *wm8580; 915 struct wm8580_priv *wm8580;
933 struct snd_soc_codec *codec; 916 int ret;
934 917
935 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL); 918 wm8580 = kzalloc(sizeof(struct wm8580_priv), GFP_KERNEL);
936 if (wm8580 == NULL) 919 if (wm8580 == NULL)
937 return -ENOMEM; 920 return -ENOMEM;
938 921
939 codec = &wm8580->codec;
940
941 i2c_set_clientdata(i2c, wm8580); 922 i2c_set_clientdata(i2c, wm8580);
942 codec->control_data = i2c; 923 wm8580->control_type = SND_SOC_I2C;
943 924
944 codec->dev = &i2c->dev; 925 ret = snd_soc_register_codec(&i2c->dev,
945 926 &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai));
946 return wm8580_register(wm8580, SND_SOC_I2C); 927 if (ret < 0)
928 kfree(wm8580);
929 return ret;
947} 930}
948 931
949static int wm8580_i2c_remove(struct i2c_client *client) 932static int wm8580_i2c_remove(struct i2c_client *client)
950{ 933{
951 struct wm8580_priv *wm8580 = i2c_get_clientdata(client); 934 snd_soc_unregister_codec(&client->dev);
952 wm8580_unregister(wm8580); 935 kfree(i2c_get_clientdata(client));
953 return 0; 936 return 0;
954} 937}
955 938
@@ -961,7 +944,7 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
961 944
962static struct i2c_driver wm8580_i2c_driver = { 945static struct i2c_driver wm8580_i2c_driver = {
963 .driver = { 946 .driver = {
964 .name = "wm8580", 947 .name = "wm8580-codec",
965 .owner = THIS_MODULE, 948 .owner = THIS_MODULE,
966 }, 949 },
967 .probe = wm8580_i2c_probe, 950 .probe = wm8580_i2c_probe,
@@ -972,7 +955,7 @@ static struct i2c_driver wm8580_i2c_driver = {
972 955
973static int __init wm8580_modinit(void) 956static int __init wm8580_modinit(void)
974{ 957{
975 int ret; 958 int ret = 0;
976 959
977#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 960#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
978 ret = i2c_add_driver(&wm8580_i2c_driver); 961 ret = i2c_add_driver(&wm8580_i2c_driver);
@@ -981,7 +964,7 @@ static int __init wm8580_modinit(void)
981 } 964 }
982#endif 965#endif
983 966
984 return 0; 967 return ret;
985} 968}
986module_init(wm8580_modinit); 969module_init(wm8580_modinit);
987 970