diff options
Diffstat (limited to 'sound/soc/codecs/wm8580.c')
-rw-r--r-- | sound/soc/codecs/wm8580.c | 211 |
1 files changed, 97 insertions, 114 deletions
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 86c4b24db817..6bded8c78150 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
@@ -24,6 +24,8 @@ | |||
24 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/regulator/consumer.h> | ||
28 | |||
27 | #include <sound/core.h> | 29 | #include <sound/core.h> |
28 | #include <sound/pcm.h> | 30 | #include <sound/pcm.h> |
29 | #include <sound/pcm_params.h> | 31 | #include <sound/pcm_params.h> |
@@ -187,82 +189,22 @@ struct pll_state { | |||
187 | unsigned int out; | 189 | unsigned int out; |
188 | }; | 190 | }; |
189 | 191 | ||
192 | #define WM8580_NUM_SUPPLIES 3 | ||
193 | static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = { | ||
194 | "AVDD", | ||
195 | "DVDD", | ||
196 | "PVDD", | ||
197 | }; | ||
198 | |||
190 | /* codec private data */ | 199 | /* codec private data */ |
191 | struct wm8580_priv { | 200 | struct wm8580_priv { |
192 | struct snd_soc_codec codec; | 201 | struct snd_soc_codec codec; |
202 | struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; | ||
193 | u16 reg_cache[WM8580_MAX_REGISTER + 1]; | 203 | u16 reg_cache[WM8580_MAX_REGISTER + 1]; |
194 | struct pll_state a; | 204 | struct pll_state a; |
195 | struct pll_state b; | 205 | struct pll_state b; |
196 | }; | 206 | }; |
197 | 207 | ||
198 | |||
199 | /* | ||
200 | * read wm8580 register cache | ||
201 | */ | ||
202 | static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec, | ||
203 | unsigned int reg) | ||
204 | { | ||
205 | u16 *cache = codec->reg_cache; | ||
206 | BUG_ON(reg >= ARRAY_SIZE(wm8580_reg)); | ||
207 | return cache[reg]; | ||
208 | } | ||
209 | |||
210 | /* | ||
211 | * write wm8580 register cache | ||
212 | */ | ||
213 | static inline void wm8580_write_reg_cache(struct snd_soc_codec *codec, | ||
214 | unsigned int reg, unsigned int value) | ||
215 | { | ||
216 | u16 *cache = codec->reg_cache; | ||
217 | |||
218 | cache[reg] = value; | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * write to the WM8580 register space | ||
223 | */ | ||
224 | static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg, | ||
225 | unsigned int value) | ||
226 | { | ||
227 | u8 data[2]; | ||
228 | |||
229 | BUG_ON(reg >= ARRAY_SIZE(wm8580_reg)); | ||
230 | |||
231 | /* Registers are 9 bits wide */ | ||
232 | value &= 0x1ff; | ||
233 | |||
234 | switch (reg) { | ||
235 | case WM8580_RESET: | ||
236 | /* Uncached */ | ||
237 | break; | ||
238 | default: | ||
239 | if (value == wm8580_read_reg_cache(codec, reg)) | ||
240 | return 0; | ||
241 | } | ||
242 | |||
243 | /* data is | ||
244 | * D15..D9 WM8580 register offset | ||
245 | * D8...D0 register data | ||
246 | */ | ||
247 | data[0] = (reg << 1) | ((value >> 8) & 0x0001); | ||
248 | data[1] = value & 0x00ff; | ||
249 | |||
250 | wm8580_write_reg_cache(codec, reg, value); | ||
251 | if (codec->hw_write(codec->control_data, data, 2) == 2) | ||
252 | return 0; | ||
253 | else | ||
254 | return -EIO; | ||
255 | } | ||
256 | |||
257 | static inline unsigned int wm8580_read(struct snd_soc_codec *codec, | ||
258 | unsigned int reg) | ||
259 | { | ||
260 | switch (reg) { | ||
261 | default: | ||
262 | return wm8580_read_reg_cache(codec, reg); | ||
263 | } | ||
264 | } | ||
265 | |||
266 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); | 208 | static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); |
267 | 209 | ||
268 | static int wm8580_out_vu(struct snd_kcontrol *kcontrol, | 210 | static int wm8580_out_vu(struct snd_kcontrol *kcontrol, |
@@ -271,25 +213,22 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol, | |||
271 | struct soc_mixer_control *mc = | 213 | struct soc_mixer_control *mc = |
272 | (struct soc_mixer_control *)kcontrol->private_value; | 214 | (struct soc_mixer_control *)kcontrol->private_value; |
273 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 215 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
216 | u16 *reg_cache = codec->reg_cache; | ||
274 | unsigned int reg = mc->reg; | 217 | unsigned int reg = mc->reg; |
275 | unsigned int reg2 = mc->rreg; | 218 | unsigned int reg2 = mc->rreg; |
276 | int ret; | 219 | int ret; |
277 | u16 val; | ||
278 | 220 | ||
279 | /* Clear the register cache so we write without VU set */ | 221 | /* Clear the register cache so we write without VU set */ |
280 | wm8580_write_reg_cache(codec, reg, 0); | 222 | reg_cache[reg] = 0; |
281 | wm8580_write_reg_cache(codec, reg2, 0); | 223 | reg_cache[reg2] = 0; |
282 | 224 | ||
283 | ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); | 225 | ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); |
284 | if (ret < 0) | 226 | if (ret < 0) |
285 | return ret; | 227 | return ret; |
286 | 228 | ||
287 | /* Now write again with the volume update bit set */ | 229 | /* Now write again with the volume update bit set */ |
288 | val = wm8580_read_reg_cache(codec, reg); | 230 | snd_soc_update_bits(codec, reg, 0x100, 0x100); |
289 | wm8580_write(codec, reg, val | 0x0100); | 231 | snd_soc_update_bits(codec, reg2, 0x100, 0x100); |
290 | |||
291 | val = wm8580_read_reg_cache(codec, reg2); | ||
292 | wm8580_write(codec, reg2, val | 0x0100); | ||
293 | 232 | ||
294 | return 0; | 233 | return 0; |
295 | } | 234 | } |
@@ -512,27 +451,27 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, | |||
512 | /* Always disable the PLL - it is not safe to leave it running | 451 | /* Always disable the PLL - it is not safe to leave it running |
513 | * while reprogramming it. | 452 | * while reprogramming it. |
514 | */ | 453 | */ |
515 | reg = wm8580_read(codec, WM8580_PWRDN2); | 454 | reg = snd_soc_read(codec, WM8580_PWRDN2); |
516 | wm8580_write(codec, WM8580_PWRDN2, reg | pwr_mask); | 455 | snd_soc_write(codec, WM8580_PWRDN2, reg | pwr_mask); |
517 | 456 | ||
518 | if (!freq_in || !freq_out) | 457 | if (!freq_in || !freq_out) |
519 | return 0; | 458 | return 0; |
520 | 459 | ||
521 | wm8580_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff); | 460 | snd_soc_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff); |
522 | wm8580_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0xff); | 461 | snd_soc_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0x1ff); |
523 | wm8580_write(codec, WM8580_PLLA3 + offset, | 462 | snd_soc_write(codec, WM8580_PLLA3 + offset, |
524 | (pll_div.k >> 18 & 0xf) | (pll_div.n << 4)); | 463 | (pll_div.k >> 18 & 0xf) | (pll_div.n << 4)); |
525 | 464 | ||
526 | reg = wm8580_read(codec, WM8580_PLLA4 + offset); | 465 | reg = snd_soc_read(codec, WM8580_PLLA4 + offset); |
527 | reg &= ~0x3f; | 466 | reg &= ~0x1b; |
528 | reg |= pll_div.prescale | pll_div.postscale << 1 | | 467 | reg |= pll_div.prescale | pll_div.postscale << 1 | |
529 | pll_div.freqmode << 3; | 468 | pll_div.freqmode << 3; |
530 | 469 | ||
531 | wm8580_write(codec, WM8580_PLLA4 + offset, reg); | 470 | snd_soc_write(codec, WM8580_PLLA4 + offset, reg); |
532 | 471 | ||
533 | /* All done, turn it on */ | 472 | /* All done, turn it on */ |
534 | reg = wm8580_read(codec, WM8580_PWRDN2); | 473 | reg = snd_soc_read(codec, WM8580_PWRDN2); |
535 | wm8580_write(codec, WM8580_PWRDN2, reg & ~pwr_mask); | 474 | snd_soc_write(codec, WM8580_PWRDN2, reg & ~pwr_mask); |
536 | 475 | ||
537 | return 0; | 476 | return 0; |
538 | } | 477 | } |
@@ -547,7 +486,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, | |||
547 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 486 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
548 | struct snd_soc_device *socdev = rtd->socdev; | 487 | struct snd_soc_device *socdev = rtd->socdev; |
549 | struct snd_soc_codec *codec = socdev->card->codec; | 488 | struct snd_soc_codec *codec = socdev->card->codec; |
550 | u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id); | 489 | u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->id); |
551 | 490 | ||
552 | paifb &= ~WM8580_AIF_LENGTH_MASK; | 491 | paifb &= ~WM8580_AIF_LENGTH_MASK; |
553 | /* bit size */ | 492 | /* bit size */ |
@@ -567,7 +506,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, | |||
567 | return -EINVAL; | 506 | return -EINVAL; |
568 | } | 507 | } |
569 | 508 | ||
570 | wm8580_write(codec, WM8580_PAIF3 + dai->id, paifb); | 509 | snd_soc_write(codec, WM8580_PAIF3 + dai->id, paifb); |
571 | return 0; | 510 | return 0; |
572 | } | 511 | } |
573 | 512 | ||
@@ -579,8 +518,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai, | |||
579 | unsigned int aifb; | 518 | unsigned int aifb; |
580 | int can_invert_lrclk; | 519 | int can_invert_lrclk; |
581 | 520 | ||
582 | aifa = wm8580_read(codec, WM8580_PAIF1 + codec_dai->id); | 521 | aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->id); |
583 | aifb = wm8580_read(codec, WM8580_PAIF3 + codec_dai->id); | 522 | aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->id); |
584 | 523 | ||
585 | aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP); | 524 | aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP); |
586 | 525 | ||
@@ -646,8 +585,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai, | |||
646 | return -EINVAL; | 585 | return -EINVAL; |
647 | } | 586 | } |
648 | 587 | ||
649 | wm8580_write(codec, WM8580_PAIF1 + codec_dai->id, aifa); | 588 | snd_soc_write(codec, WM8580_PAIF1 + codec_dai->id, aifa); |
650 | wm8580_write(codec, WM8580_PAIF3 + codec_dai->id, aifb); | 589 | snd_soc_write(codec, WM8580_PAIF3 + codec_dai->id, aifb); |
651 | 590 | ||
652 | return 0; | 591 | return 0; |
653 | } | 592 | } |
@@ -660,7 +599,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai, | |||
660 | 599 | ||
661 | switch (div_id) { | 600 | switch (div_id) { |
662 | case WM8580_MCLK: | 601 | case WM8580_MCLK: |
663 | reg = wm8580_read(codec, WM8580_PLLB4); | 602 | reg = snd_soc_read(codec, WM8580_PLLB4); |
664 | reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK; | 603 | reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK; |
665 | 604 | ||
666 | switch (div) { | 605 | switch (div) { |
@@ -682,11 +621,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai, | |||
682 | default: | 621 | default: |
683 | return -EINVAL; | 622 | return -EINVAL; |
684 | } | 623 | } |
685 | wm8580_write(codec, WM8580_PLLB4, reg); | 624 | snd_soc_write(codec, WM8580_PLLB4, reg); |
686 | break; | 625 | break; |
687 | 626 | ||
688 | case WM8580_DAC_CLKSEL: | 627 | case WM8580_DAC_CLKSEL: |
689 | reg = wm8580_read(codec, WM8580_CLKSEL); | 628 | reg = snd_soc_read(codec, WM8580_CLKSEL); |
690 | reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK; | 629 | reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK; |
691 | 630 | ||
692 | switch (div) { | 631 | switch (div) { |
@@ -704,11 +643,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai, | |||
704 | default: | 643 | default: |
705 | return -EINVAL; | 644 | return -EINVAL; |
706 | } | 645 | } |
707 | wm8580_write(codec, WM8580_CLKSEL, reg); | 646 | snd_soc_write(codec, WM8580_CLKSEL, reg); |
708 | break; | 647 | break; |
709 | 648 | ||
710 | case WM8580_CLKOUTSRC: | 649 | case WM8580_CLKOUTSRC: |
711 | reg = wm8580_read(codec, WM8580_PLLB4); | 650 | reg = snd_soc_read(codec, WM8580_PLLB4); |
712 | reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK; | 651 | reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK; |
713 | 652 | ||
714 | switch (div) { | 653 | switch (div) { |
@@ -730,7 +669,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai, | |||
730 | default: | 669 | default: |
731 | return -EINVAL; | 670 | return -EINVAL; |
732 | } | 671 | } |
733 | wm8580_write(codec, WM8580_PLLB4, reg); | 672 | snd_soc_write(codec, WM8580_PLLB4, reg); |
734 | break; | 673 | break; |
735 | 674 | ||
736 | default: | 675 | default: |
@@ -745,14 +684,14 @@ static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute) | |||
745 | struct snd_soc_codec *codec = codec_dai->codec; | 684 | struct snd_soc_codec *codec = codec_dai->codec; |
746 | unsigned int reg; | 685 | unsigned int reg; |
747 | 686 | ||
748 | reg = wm8580_read(codec, WM8580_DAC_CONTROL5); | 687 | reg = snd_soc_read(codec, WM8580_DAC_CONTROL5); |
749 | 688 | ||
750 | if (mute) | 689 | if (mute) |
751 | reg |= WM8580_DAC_CONTROL5_MUTEALL; | 690 | reg |= WM8580_DAC_CONTROL5_MUTEALL; |
752 | else | 691 | else |
753 | reg &= ~WM8580_DAC_CONTROL5_MUTEALL; | 692 | reg &= ~WM8580_DAC_CONTROL5_MUTEALL; |
754 | 693 | ||
755 | wm8580_write(codec, WM8580_DAC_CONTROL5, reg); | 694 | snd_soc_write(codec, WM8580_DAC_CONTROL5, reg); |
756 | 695 | ||
757 | return 0; | 696 | return 0; |
758 | } | 697 | } |
@@ -769,20 +708,20 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, | |||
769 | case SND_SOC_BIAS_STANDBY: | 708 | case SND_SOC_BIAS_STANDBY: |
770 | if (codec->bias_level == SND_SOC_BIAS_OFF) { | 709 | if (codec->bias_level == SND_SOC_BIAS_OFF) { |
771 | /* Power up and get individual control of the DACs */ | 710 | /* Power up and get individual control of the DACs */ |
772 | reg = wm8580_read(codec, WM8580_PWRDN1); | 711 | reg = snd_soc_read(codec, WM8580_PWRDN1); |
773 | reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); | 712 | reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); |
774 | wm8580_write(codec, WM8580_PWRDN1, reg); | 713 | snd_soc_write(codec, WM8580_PWRDN1, reg); |
775 | 714 | ||
776 | /* Make VMID high impedence */ | 715 | /* Make VMID high impedence */ |
777 | reg = wm8580_read(codec, WM8580_ADC_CONTROL1); | 716 | reg = snd_soc_read(codec, WM8580_ADC_CONTROL1); |
778 | reg &= ~0x100; | 717 | reg &= ~0x100; |
779 | wm8580_write(codec, WM8580_ADC_CONTROL1, reg); | 718 | snd_soc_write(codec, WM8580_ADC_CONTROL1, reg); |
780 | } | 719 | } |
781 | break; | 720 | break; |
782 | 721 | ||
783 | case SND_SOC_BIAS_OFF: | 722 | case SND_SOC_BIAS_OFF: |
784 | reg = wm8580_read(codec, WM8580_PWRDN1); | 723 | reg = snd_soc_read(codec, WM8580_PWRDN1); |
785 | wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); | 724 | snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); |
786 | break; | 725 | break; |
787 | } | 726 | } |
788 | codec->bias_level = level; | 727 | codec->bias_level = level; |
@@ -893,7 +832,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8580 = { | |||
893 | }; | 832 | }; |
894 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580); | 833 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580); |
895 | 834 | ||
896 | static int wm8580_register(struct wm8580_priv *wm8580) | 835 | static int wm8580_register(struct wm8580_priv *wm8580, |
836 | enum snd_soc_control_type control) | ||
897 | { | 837 | { |
898 | int ret, i; | 838 | int ret, i; |
899 | struct snd_soc_codec *codec = &wm8580->codec; | 839 | struct snd_soc_codec *codec = &wm8580->codec; |
@@ -911,8 +851,6 @@ static int wm8580_register(struct wm8580_priv *wm8580) | |||
911 | codec->private_data = wm8580; | 851 | codec->private_data = wm8580; |
912 | codec->name = "WM8580"; | 852 | codec->name = "WM8580"; |
913 | codec->owner = THIS_MODULE; | 853 | codec->owner = THIS_MODULE; |
914 | codec->read = wm8580_read_reg_cache; | ||
915 | codec->write = wm8580_write; | ||
916 | codec->bias_level = SND_SOC_BIAS_OFF; | 854 | codec->bias_level = SND_SOC_BIAS_OFF; |
917 | codec->set_bias_level = wm8580_set_bias_level; | 855 | codec->set_bias_level = wm8580_set_bias_level; |
918 | codec->dai = wm8580_dai; | 856 | codec->dai = wm8580_dai; |
@@ -922,11 +860,34 @@ static int wm8580_register(struct wm8580_priv *wm8580) | |||
922 | 860 | ||
923 | memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg)); | 861 | memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg)); |
924 | 862 | ||
863 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, control); | ||
864 | if (ret < 0) { | ||
865 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
866 | goto err; | ||
867 | } | ||
868 | |||
869 | for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++) | ||
870 | wm8580->supplies[i].supply = wm8580_supply_names[i]; | ||
871 | |||
872 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8580->supplies), | ||
873 | wm8580->supplies); | ||
874 | if (ret != 0) { | ||
875 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
876 | goto err; | ||
877 | } | ||
878 | |||
879 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), | ||
880 | wm8580->supplies); | ||
881 | if (ret != 0) { | ||
882 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
883 | goto err_regulator_get; | ||
884 | } | ||
885 | |||
925 | /* Get the codec into a known state */ | 886 | /* Get the codec into a known state */ |
926 | ret = wm8580_write(codec, WM8580_RESET, 0); | 887 | ret = snd_soc_write(codec, WM8580_RESET, 0); |
927 | if (ret != 0) { | 888 | if (ret != 0) { |
928 | dev_err(codec->dev, "Failed to reset codec: %d\n", ret); | 889 | dev_err(codec->dev, "Failed to reset codec: %d\n", ret); |
929 | goto err; | 890 | goto err_regulator_enable; |
930 | } | 891 | } |
931 | 892 | ||
932 | for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++) | 893 | for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++) |
@@ -939,7 +900,7 @@ static int wm8580_register(struct wm8580_priv *wm8580) | |||
939 | ret = snd_soc_register_codec(codec); | 900 | ret = snd_soc_register_codec(codec); |
940 | if (ret != 0) { | 901 | if (ret != 0) { |
941 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | 902 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); |
942 | goto err; | 903 | goto err_regulator_enable; |
943 | } | 904 | } |
944 | 905 | ||
945 | ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); | 906 | ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); |
@@ -952,6 +913,10 @@ static int wm8580_register(struct wm8580_priv *wm8580) | |||
952 | 913 | ||
953 | err_codec: | 914 | err_codec: |
954 | snd_soc_unregister_codec(codec); | 915 | snd_soc_unregister_codec(codec); |
916 | err_regulator_enable: | ||
917 | regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); | ||
918 | err_regulator_get: | ||
919 | regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); | ||
955 | err: | 920 | err: |
956 | kfree(wm8580); | 921 | kfree(wm8580); |
957 | return ret; | 922 | return ret; |
@@ -962,6 +927,8 @@ static void wm8580_unregister(struct wm8580_priv *wm8580) | |||
962 | wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF); | 927 | wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF); |
963 | snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); | 928 | snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); |
964 | snd_soc_unregister_codec(&wm8580->codec); | 929 | snd_soc_unregister_codec(&wm8580->codec); |
930 | regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); | ||
931 | regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); | ||
965 | kfree(wm8580); | 932 | kfree(wm8580); |
966 | wm8580_codec = NULL; | 933 | wm8580_codec = NULL; |
967 | } | 934 | } |
@@ -978,14 +945,13 @@ static int wm8580_i2c_probe(struct i2c_client *i2c, | |||
978 | return -ENOMEM; | 945 | return -ENOMEM; |
979 | 946 | ||
980 | codec = &wm8580->codec; | 947 | codec = &wm8580->codec; |
981 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
982 | 948 | ||
983 | i2c_set_clientdata(i2c, wm8580); | 949 | i2c_set_clientdata(i2c, wm8580); |
984 | codec->control_data = i2c; | 950 | codec->control_data = i2c; |
985 | 951 | ||
986 | codec->dev = &i2c->dev; | 952 | codec->dev = &i2c->dev; |
987 | 953 | ||
988 | return wm8580_register(wm8580); | 954 | return wm8580_register(wm8580, SND_SOC_I2C); |
989 | } | 955 | } |
990 | 956 | ||
991 | static int wm8580_i2c_remove(struct i2c_client *client) | 957 | static int wm8580_i2c_remove(struct i2c_client *client) |
@@ -995,6 +961,21 @@ static int wm8580_i2c_remove(struct i2c_client *client) | |||
995 | return 0; | 961 | return 0; |
996 | } | 962 | } |
997 | 963 | ||
964 | #ifdef CONFIG_PM | ||
965 | static int wm8580_i2c_suspend(struct i2c_client *client, pm_message_t msg) | ||
966 | { | ||
967 | return snd_soc_suspend_device(&client->dev); | ||
968 | } | ||
969 | |||
970 | static int wm8580_i2c_resume(struct i2c_client *client) | ||
971 | { | ||
972 | return snd_soc_resume_device(&client->dev); | ||
973 | } | ||
974 | #else | ||
975 | #define wm8580_i2c_suspend NULL | ||
976 | #define wm8580_i2c_resume NULL | ||
977 | #endif | ||
978 | |||
998 | static const struct i2c_device_id wm8580_i2c_id[] = { | 979 | static const struct i2c_device_id wm8580_i2c_id[] = { |
999 | { "wm8580", 0 }, | 980 | { "wm8580", 0 }, |
1000 | { } | 981 | { } |
@@ -1008,6 +989,8 @@ static struct i2c_driver wm8580_i2c_driver = { | |||
1008 | }, | 989 | }, |
1009 | .probe = wm8580_i2c_probe, | 990 | .probe = wm8580_i2c_probe, |
1010 | .remove = wm8580_i2c_remove, | 991 | .remove = wm8580_i2c_remove, |
992 | .suspend = wm8580_i2c_suspend, | ||
993 | .resume = wm8580_i2c_resume, | ||
1011 | .id_table = wm8580_i2c_id, | 994 | .id_table = wm8580_i2c_id, |
1012 | }; | 995 | }; |
1013 | #endif | 996 | #endif |