aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8750.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8750.c')
-rw-r--r--sound/soc/codecs/wm8750.c121
1 files changed, 43 insertions, 78 deletions
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index b64509b01a49..ed09043181e1 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -55,50 +55,7 @@ static const u16 wm8750_reg[] = {
55 0x0079, 0x0079, 0x0079, /* 40 */ 55 0x0079, 0x0079, 0x0079, /* 40 */
56}; 56};
57 57
58/* 58#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
59 * read wm8750 register cache
60 */
61static inline unsigned int wm8750_read_reg_cache(struct snd_soc_codec *codec,
62 unsigned int reg)
63{
64 u16 *cache = codec->reg_cache;
65 if (reg > WM8750_CACHE_REGNUM)
66 return -1;
67 return cache[reg];
68}
69
70/*
71 * write wm8750 register cache
72 */
73static inline void wm8750_write_reg_cache(struct snd_soc_codec *codec,
74 unsigned int reg, unsigned int value)
75{
76 u16 *cache = codec->reg_cache;
77 if (reg > WM8750_CACHE_REGNUM)
78 return;
79 cache[reg] = value;
80}
81
82static int wm8750_write(struct snd_soc_codec *codec, unsigned int reg,
83 unsigned int value)
84{
85 u8 data[2];
86
87 /* data is
88 * D15..D9 WM8753 register offset
89 * D8...D0 register data
90 */
91 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
92 data[1] = value & 0x00ff;
93
94 wm8750_write_reg_cache(codec, reg, value);
95 if (codec->hw_write(codec->control_data, data, 2) == 2)
96 return 0;
97 else
98 return -EIO;
99}
100
101#define wm8750_reset(c) wm8750_write(c, WM8750_RESET, 0)
102 59
103/* 60/*
104 * WM8750 Controls 61 * WM8750 Controls
@@ -594,7 +551,7 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
594 return -EINVAL; 551 return -EINVAL;
595 } 552 }
596 553
597 wm8750_write(codec, WM8750_IFACE, iface); 554 snd_soc_write(codec, WM8750_IFACE, iface);
598 return 0; 555 return 0;
599} 556}
600 557
@@ -606,8 +563,8 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
606 struct snd_soc_device *socdev = rtd->socdev; 563 struct snd_soc_device *socdev = rtd->socdev;
607 struct snd_soc_codec *codec = socdev->card->codec; 564 struct snd_soc_codec *codec = socdev->card->codec;
608 struct wm8750_priv *wm8750 = codec->private_data; 565 struct wm8750_priv *wm8750 = codec->private_data;
609 u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3; 566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
610 u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0; 567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
611 int coeff = get_coeff(wm8750->sysclk, params_rate(params)); 568 int coeff = get_coeff(wm8750->sysclk, params_rate(params));
612 569
613 /* bit size */ 570 /* bit size */
@@ -626,9 +583,9 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
626 } 583 }
627 584
628 /* set iface & srate */ 585 /* set iface & srate */
629 wm8750_write(codec, WM8750_IFACE, iface); 586 snd_soc_write(codec, WM8750_IFACE, iface);
630 if (coeff >= 0) 587 if (coeff >= 0)
631 wm8750_write(codec, WM8750_SRATE, srate | 588 snd_soc_write(codec, WM8750_SRATE, srate |
632 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); 589 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
633 590
634 return 0; 591 return 0;
@@ -637,35 +594,35 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
637static int wm8750_mute(struct snd_soc_dai *dai, int mute) 594static int wm8750_mute(struct snd_soc_dai *dai, int mute)
638{ 595{
639 struct snd_soc_codec *codec = dai->codec; 596 struct snd_soc_codec *codec = dai->codec;
640 u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7; 597 u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7;
641 598
642 if (mute) 599 if (mute)
643 wm8750_write(codec, WM8750_ADCDAC, mute_reg | 0x8); 600 snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
644 else 601 else
645 wm8750_write(codec, WM8750_ADCDAC, mute_reg); 602 snd_soc_write(codec, WM8750_ADCDAC, mute_reg);
646 return 0; 603 return 0;
647} 604}
648 605
649static int wm8750_set_bias_level(struct snd_soc_codec *codec, 606static int wm8750_set_bias_level(struct snd_soc_codec *codec,
650 enum snd_soc_bias_level level) 607 enum snd_soc_bias_level level)
651{ 608{
652 u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e; 609 u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
653 610
654 switch (level) { 611 switch (level) {
655 case SND_SOC_BIAS_ON: 612 case SND_SOC_BIAS_ON:
656 /* set vmid to 50k and unmute dac */ 613 /* set vmid to 50k and unmute dac */
657 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
658 break; 615 break;
659 case SND_SOC_BIAS_PREPARE: 616 case SND_SOC_BIAS_PREPARE:
660 /* set vmid to 5k for quick power up */ 617 /* set vmid to 5k for quick power up */
661 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 618 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
662 break; 619 break;
663 case SND_SOC_BIAS_STANDBY: 620 case SND_SOC_BIAS_STANDBY:
664 /* mute dac and set vmid to 500k, enable VREF */ 621 /* mute dac and set vmid to 500k, enable VREF */
665 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 622 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
666 break; 623 break;
667 case SND_SOC_BIAS_OFF: 624 case SND_SOC_BIAS_OFF:
668 wm8750_write(codec, WM8750_PWR1, 0x0001); 625 snd_soc_write(codec, WM8750_PWR1, 0x0001);
669 break; 626 break;
670 } 627 }
671 codec->bias_level = level; 628 codec->bias_level = level;
@@ -761,8 +718,6 @@ static int wm8750_init(struct snd_soc_device *socdev)
761 718
762 codec->name = "WM8750"; 719 codec->name = "WM8750";
763 codec->owner = THIS_MODULE; 720 codec->owner = THIS_MODULE;
764 codec->read = wm8750_read_reg_cache;
765 codec->write = wm8750_write;
766 codec->set_bias_level = wm8750_set_bias_level; 721 codec->set_bias_level = wm8750_set_bias_level;
767 codec->dai = &wm8750_dai; 722 codec->dai = &wm8750_dai;
768 codec->num_dai = 1; 723 codec->num_dai = 1;
@@ -771,13 +726,23 @@ static int wm8750_init(struct snd_soc_device *socdev)
771 if (codec->reg_cache == NULL) 726 if (codec->reg_cache == NULL)
772 return -ENOMEM; 727 return -ENOMEM;
773 728
774 wm8750_reset(codec); 729 ret = snd_soc_codec_set_cache_io(codec, 7, 9);
730 if (ret < 0) {
731 printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
732 goto err;
733 }
734
735 ret = wm8750_reset(codec);
736 if (ret < 0) {
737 printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
738 goto err;
739 }
775 740
776 /* register pcms */ 741 /* register pcms */
777 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 742 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
778 if (ret < 0) { 743 if (ret < 0) {
779 printk(KERN_ERR "wm8750: failed to create pcms\n"); 744 printk(KERN_ERR "wm8750: failed to create pcms\n");
780 goto pcm_err; 745 goto err;
781 } 746 }
782 747
783 /* charge output caps */ 748 /* charge output caps */
@@ -786,22 +751,22 @@ static int wm8750_init(struct snd_soc_device *socdev)
786 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); 751 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
787 752
788 /* set the update bits */ 753 /* set the update bits */
789 reg = wm8750_read_reg_cache(codec, WM8750_LDAC); 754 reg = snd_soc_read(codec, WM8750_LDAC);
790 wm8750_write(codec, WM8750_LDAC, reg | 0x0100); 755 snd_soc_write(codec, WM8750_LDAC, reg | 0x0100);
791 reg = wm8750_read_reg_cache(codec, WM8750_RDAC); 756 reg = snd_soc_read(codec, WM8750_RDAC);
792 wm8750_write(codec, WM8750_RDAC, reg | 0x0100); 757 snd_soc_write(codec, WM8750_RDAC, reg | 0x0100);
793 reg = wm8750_read_reg_cache(codec, WM8750_LOUT1V); 758 reg = snd_soc_read(codec, WM8750_LOUT1V);
794 wm8750_write(codec, WM8750_LOUT1V, reg | 0x0100); 759 snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100);
795 reg = wm8750_read_reg_cache(codec, WM8750_ROUT1V); 760 reg = snd_soc_read(codec, WM8750_ROUT1V);
796 wm8750_write(codec, WM8750_ROUT1V, reg | 0x0100); 761 snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100);
797 reg = wm8750_read_reg_cache(codec, WM8750_LOUT2V); 762 reg = snd_soc_read(codec, WM8750_LOUT2V);
798 wm8750_write(codec, WM8750_LOUT2V, reg | 0x0100); 763 snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100);
799 reg = wm8750_read_reg_cache(codec, WM8750_ROUT2V); 764 reg = snd_soc_read(codec, WM8750_ROUT2V);
800 wm8750_write(codec, WM8750_ROUT2V, reg | 0x0100); 765 snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100);
801 reg = wm8750_read_reg_cache(codec, WM8750_LINVOL); 766 reg = snd_soc_read(codec, WM8750_LINVOL);
802 wm8750_write(codec, WM8750_LINVOL, reg | 0x0100); 767 snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100);
803 reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); 768 reg = snd_soc_read(codec, WM8750_RINVOL);
804 wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); 769 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
805 770
806 snd_soc_add_controls(codec, wm8750_snd_controls, 771 snd_soc_add_controls(codec, wm8750_snd_controls,
807 ARRAY_SIZE(wm8750_snd_controls)); 772 ARRAY_SIZE(wm8750_snd_controls));
@@ -816,7 +781,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
816card_err: 781card_err:
817 snd_soc_free_pcms(socdev); 782 snd_soc_free_pcms(socdev);
818 snd_soc_dapm_free(socdev); 783 snd_soc_dapm_free(socdev);
819pcm_err: 784err:
820 kfree(codec->reg_cache); 785 kfree(codec->reg_cache);
821 return ret; 786 return ret;
822} 787}