aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2010-12-28 15:38:03 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-12-28 18:22:37 -0500
commit776065e36de1d5eb9e33ff908352fef4050ab38d (patch)
tree72251b08da56728d86d6fa406f42d2271a9724c3 /sound/soc
parentda280f51d0b341282b4181eb3235f774b0446584 (diff)
ASoC: codecs: wm8753: Fix register cache incoherency
The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but the wm8753 driver still uses its own register cache for its private functions, while functions from the ASoC core use the generic cache. Furthermore the generic cache uses zero-based numbering while the wm8753 cache uses one-based numbering. Thus we end up with two from each other incoherent caches, which leads to undefined behaviour and crashes. This patch fixes the issue by changing the wm8753 driver to use the generic register cache in its private functions. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/codecs/wm8753.c226
1 files changed, 83 insertions, 143 deletions
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 8f679a13f2bc..87caae59e939 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -65,22 +65,22 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
65 * are using 2 wire for device control, so we cache them instead. 65 * are using 2 wire for device control, so we cache them instead.
66 */ 66 */
67static const u16 wm8753_reg[] = { 67static const u16 wm8753_reg[] = {
68 0x0008, 0x0000, 0x000a, 0x000a, 68 0x0000, 0x0008, 0x0000, 0x000a,
69 0x0033, 0x0000, 0x0007, 0x00ff, 69 0x000a, 0x0033, 0x0000, 0x0007,
70 0x00ff, 0x000f, 0x000f, 0x007b, 70 0x00ff, 0x00ff, 0x000f, 0x000f,
71 0x0000, 0x0032, 0x0000, 0x00c3, 71 0x007b, 0x0000, 0x0032, 0x0000,
72 0x00c3, 0x00c0, 0x0000, 0x0000, 72 0x00c3, 0x00c3, 0x00c0, 0x0000,
73 0x0000, 0x0000, 0x0000, 0x0000, 73 0x0000, 0x0000, 0x0000, 0x0000,
74 0x0000, 0x0000, 0x0000, 0x0000, 74 0x0000, 0x0000, 0x0000, 0x0000,
75 0x0000, 0x0000, 0x0000, 0x0055,
76 0x0005, 0x0050, 0x0055, 0x0050,
77 0x0055, 0x0050, 0x0055, 0x0079,
78 0x0079, 0x0079, 0x0079, 0x0079,
79 0x0000, 0x0000, 0x0000, 0x0000, 75 0x0000, 0x0000, 0x0000, 0x0000,
80 0x0097, 0x0097, 0x0000, 0x0004, 76 0x0055, 0x0005, 0x0050, 0x0055,
81 0x0000, 0x0083, 0x0024, 0x01ba, 77 0x0050, 0x0055, 0x0050, 0x0055,
82 0x0000, 0x0083, 0x0024, 0x01ba, 78 0x0079, 0x0079, 0x0079, 0x0079,
83 0x0000, 0x0000, 0x0000 79 0x0079, 0x0000, 0x0000, 0x0000,
80 0x0000, 0x0097, 0x0097, 0x0000,
81 0x0004, 0x0000, 0x0083, 0x0024,
82 0x01ba, 0x0000, 0x0083, 0x0024,
83 0x01ba, 0x0000, 0x0000, 0x0000
84}; 84};
85 85
86/* codec private data */ 86/* codec private data */
@@ -88,57 +88,10 @@ struct wm8753_priv {
88 enum snd_soc_control_type control_type; 88 enum snd_soc_control_type control_type;
89 unsigned int sysclk; 89 unsigned int sysclk;
90 unsigned int pcmclk; 90 unsigned int pcmclk;
91 u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
92 int dai_func; 91 int dai_func;
93}; 92};
94 93
95/* 94#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
96 * read wm8753 register cache
97 */
98static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
99 unsigned int reg)
100{
101 u16 *cache = codec->reg_cache;
102 if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
103 return -1;
104 return cache[reg - 1];
105}
106
107/*
108 * write wm8753 register cache
109 */
110static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
111 unsigned int reg, unsigned int value)
112{
113 u16 *cache = codec->reg_cache;
114 if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
115 return;
116 cache[reg - 1] = value;
117}
118
119/*
120 * write to the WM8753 register space
121 */
122static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
123 unsigned int value)
124{
125 u8 data[2];
126
127 /* data is
128 * D15..D9 WM8753 register offset
129 * D8...D0 register data
130 */
131 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
132 data[1] = value & 0x00ff;
133
134 wm8753_write_reg_cache(codec, reg, value);
135 if (codec->hw_write(codec->control_data, data, 2) == 2)
136 return 0;
137 else
138 return -EIO;
139}
140
141#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)
142 95
143/* 96/*
144 * WM8753 Controls 97 * WM8753 Controls
@@ -218,7 +171,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
218 struct snd_ctl_elem_value *ucontrol) 171 struct snd_ctl_elem_value *ucontrol)
219{ 172{
220 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 173 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
221 int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); 174 int mode = snd_soc_read(codec, WM8753_IOCTL);
222 175
223 ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; 176 ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
224 return 0; 177 return 0;
@@ -228,7 +181,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
228 struct snd_ctl_elem_value *ucontrol) 181 struct snd_ctl_elem_value *ucontrol)
229{ 182{
230 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 183 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
231 int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); 184 int mode = snd_soc_read(codec, WM8753_IOCTL);
232 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 185 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
233 186
234 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0]) 187 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
@@ -738,17 +691,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
738 if (pll_id == WM8753_PLL1) { 691 if (pll_id == WM8753_PLL1) {
739 offset = 0; 692 offset = 0;
740 enable = 0x10; 693 enable = 0x10;
741 reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef; 694 reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
742 } else { 695 } else {
743 offset = 4; 696 offset = 4;
744 enable = 0x8; 697 enable = 0x8;
745 reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7; 698 reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
746 } 699 }
747 700
748 if (!freq_in || !freq_out) { 701 if (!freq_in || !freq_out) {
749 /* disable PLL */ 702 /* disable PLL */
750 wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026); 703 snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
751 wm8753_write(codec, WM8753_CLOCK, reg); 704 snd_soc_write(codec, WM8753_CLOCK, reg);
752 return 0; 705 return 0;
753 } else { 706 } else {
754 u16 value = 0; 707 u16 value = 0;
@@ -759,20 +712,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
759 /* set up N and K PLL divisor ratios */ 712 /* set up N and K PLL divisor ratios */
760 /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */ 713 /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
761 value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18); 714 value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
762 wm8753_write(codec, WM8753_PLL1CTL2 + offset, value); 715 snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
763 716
764 /* bits 8:0 = PLL_K[17:9] */ 717 /* bits 8:0 = PLL_K[17:9] */
765 value = (pll_div.k & 0x03fe00) >> 9; 718 value = (pll_div.k & 0x03fe00) >> 9;
766 wm8753_write(codec, WM8753_PLL1CTL3 + offset, value); 719 snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
767 720
768 /* bits 8:0 = PLL_K[8:0] */ 721 /* bits 8:0 = PLL_K[8:0] */
769 value = pll_div.k & 0x0001ff; 722 value = pll_div.k & 0x0001ff;
770 wm8753_write(codec, WM8753_PLL1CTL4 + offset, value); 723 snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
771 724
772 /* set PLL as input and enable */ 725 /* set PLL as input and enable */
773 wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 | 726 snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
774 (pll_div.div2 << 3)); 727 (pll_div.div2 << 3));
775 wm8753_write(codec, WM8753_CLOCK, reg | enable); 728 snd_soc_write(codec, WM8753_CLOCK, reg | enable);
776 } 729 }
777 return 0; 730 return 0;
778} 731}
@@ -879,7 +832,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
879 unsigned int fmt) 832 unsigned int fmt)
880{ 833{
881 struct snd_soc_codec *codec = codec_dai->codec; 834 struct snd_soc_codec *codec = codec_dai->codec;
882 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec; 835 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
883 836
884 /* interface format */ 837 /* interface format */
885 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 838 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -901,7 +854,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
901 return -EINVAL; 854 return -EINVAL;
902 } 855 }
903 856
904 wm8753_write(codec, WM8753_PCM, voice); 857 snd_soc_write(codec, WM8753_PCM, voice);
905 return 0; 858 return 0;
906} 859}
907 860
@@ -922,8 +875,8 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
922 struct snd_soc_pcm_runtime *rtd = substream->private_data; 875 struct snd_soc_pcm_runtime *rtd = substream->private_data;
923 struct snd_soc_codec *codec = rtd->codec; 876 struct snd_soc_codec *codec = rtd->codec;
924 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 877 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
925 u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; 878 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
926 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; 879 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
927 880
928 /* bit size */ 881 /* bit size */
929 switch (params_format(params)) { 882 switch (params_format(params)) {
@@ -943,9 +896,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
943 /* sample rate */ 896 /* sample rate */
944 if (params_rate(params) * 384 == wm8753->pcmclk) 897 if (params_rate(params) * 384 == wm8753->pcmclk)
945 srate |= 0x80; 898 srate |= 0x80;
946 wm8753_write(codec, WM8753_SRATE1, srate); 899 snd_soc_write(codec, WM8753_SRATE1, srate);
947 900
948 wm8753_write(codec, WM8753_PCM, voice); 901 snd_soc_write(codec, WM8753_PCM, voice);
949 return 0; 902 return 0;
950} 903}
951 904
@@ -958,8 +911,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
958 struct snd_soc_codec *codec = codec_dai->codec; 911 struct snd_soc_codec *codec = codec_dai->codec;
959 u16 voice, ioctl; 912 u16 voice, ioctl;
960 913
961 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f; 914 voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
962 ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d; 915 ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
963 916
964 /* set master/slave audio interface */ 917 /* set master/slave audio interface */
965 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 918 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1013,8 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
1013 return -EINVAL; 966 return -EINVAL;
1014 } 967 }
1015 968
1016 wm8753_write(codec, WM8753_PCM, voice); 969 snd_soc_write(codec, WM8753_PCM, voice);
1017 wm8753_write(codec, WM8753_IOCTL, ioctl); 970 snd_soc_write(codec, WM8753_IOCTL, ioctl);
1018 return 0; 971 return 0;
1019} 972}
1020 973
@@ -1026,16 +979,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1026 979
1027 switch (div_id) { 980 switch (div_id) {
1028 case WM8753_PCMDIV: 981 case WM8753_PCMDIV:
1029 reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f; 982 reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
1030 wm8753_write(codec, WM8753_CLOCK, reg | div); 983 snd_soc_write(codec, WM8753_CLOCK, reg | div);
1031 break; 984 break;
1032 case WM8753_BCLKDIV: 985 case WM8753_BCLKDIV:
1033 reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7; 986 reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
1034 wm8753_write(codec, WM8753_SRATE2, reg | div); 987 snd_soc_write(codec, WM8753_SRATE2, reg | div);
1035 break; 988 break;
1036 case WM8753_VXCLKDIV: 989 case WM8753_VXCLKDIV:
1037 reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f; 990 reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
1038 wm8753_write(codec, WM8753_SRATE2, reg | div); 991 snd_soc_write(codec, WM8753_SRATE2, reg | div);
1039 break; 992 break;
1040 default: 993 default:
1041 return -EINVAL; 994 return -EINVAL;
@@ -1050,7 +1003,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
1050 unsigned int fmt) 1003 unsigned int fmt)
1051{ 1004{
1052 struct snd_soc_codec *codec = codec_dai->codec; 1005 struct snd_soc_codec *codec = codec_dai->codec;
1053 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0; 1006 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
1054 1007
1055 /* interface format */ 1008 /* interface format */
1056 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1009 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -1072,7 +1025,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
1072 return -EINVAL; 1025 return -EINVAL;
1073 } 1026 }
1074 1027
1075 wm8753_write(codec, WM8753_HIFI, hifi); 1028 snd_soc_write(codec, WM8753_HIFI, hifi);
1076 return 0; 1029 return 0;
1077} 1030}
1078 1031
@@ -1085,8 +1038,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1085 struct snd_soc_codec *codec = codec_dai->codec; 1038 struct snd_soc_codec *codec = codec_dai->codec;
1086 u16 ioctl, hifi; 1039 u16 ioctl, hifi;
1087 1040
1088 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f; 1041 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
1089 ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae; 1042 ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
1090 1043
1091 /* set master/slave audio interface */ 1044 /* set master/slave audio interface */
1092 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1045 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1140,8 +1093,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1140 return -EINVAL; 1093 return -EINVAL;
1141 } 1094 }
1142 1095
1143 wm8753_write(codec, WM8753_HIFI, hifi); 1096 snd_soc_write(codec, WM8753_HIFI, hifi);
1144 wm8753_write(codec, WM8753_IOCTL, ioctl); 1097 snd_soc_write(codec, WM8753_IOCTL, ioctl);
1145 return 0; 1098 return 0;
1146} 1099}
1147 1100
@@ -1162,8 +1115,8 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1162 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1115 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1163 struct snd_soc_codec *codec = rtd->codec; 1116 struct snd_soc_codec *codec = rtd->codec;
1164 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1117 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1165 u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; 1118 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
1166 u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; 1119 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
1167 int coeff; 1120 int coeff;
1168 1121
1169 /* is digital filter coefficient valid ? */ 1122 /* is digital filter coefficient valid ? */
@@ -1172,7 +1125,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1172 printk(KERN_ERR "wm8753 invalid MCLK or rate\n"); 1125 printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
1173 return coeff; 1126 return coeff;
1174 } 1127 }
1175 wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) | 1128 snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
1176 coeff_div[coeff].usb); 1129 coeff_div[coeff].usb);
1177 1130
1178 /* bit size */ 1131 /* bit size */
@@ -1190,7 +1143,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1190 break; 1143 break;
1191 } 1144 }
1192 1145
1193 wm8753_write(codec, WM8753_HIFI, hifi); 1146 snd_soc_write(codec, WM8753_HIFI, hifi);
1194 return 0; 1147 return 0;
1195} 1148}
1196 1149
@@ -1201,8 +1154,8 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai,
1201 u16 clock; 1154 u16 clock;
1202 1155
1203 /* set clk source as pcmclk */ 1156 /* set clk source as pcmclk */
1204 clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; 1157 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1205 wm8753_write(codec, WM8753_CLOCK, clock); 1158 snd_soc_write(codec, WM8753_CLOCK, clock);
1206 1159
1207 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1160 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
1208 return -EINVAL; 1161 return -EINVAL;
@@ -1224,8 +1177,8 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai,
1224 u16 clock; 1177 u16 clock;
1225 1178
1226 /* set clk source as pcmclk */ 1179 /* set clk source as pcmclk */
1227 clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; 1180 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1228 wm8753_write(codec, WM8753_CLOCK, clock); 1181 snd_soc_write(codec, WM8753_CLOCK, clock);
1229 1182
1230 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) 1183 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
1231 return -EINVAL; 1184 return -EINVAL;
@@ -1239,8 +1192,8 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
1239 u16 clock; 1192 u16 clock;
1240 1193
1241 /* set clk source as mclk */ 1194 /* set clk source as mclk */
1242 clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; 1195 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1243 wm8753_write(codec, WM8753_CLOCK, clock | 0x4); 1196 snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
1244 1197
1245 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) 1198 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
1246 return -EINVAL; 1199 return -EINVAL;
@@ -1252,19 +1205,19 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
1252static int wm8753_mute(struct snd_soc_dai *dai, int mute) 1205static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1253{ 1206{
1254 struct snd_soc_codec *codec = dai->codec; 1207 struct snd_soc_codec *codec = dai->codec;
1255 u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; 1208 u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
1256 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1209 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1257 1210
1258 /* the digital mute covers the HiFi and Voice DAC's on the WM8753. 1211 /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
1259 * make sure we check if they are not both active when we mute */ 1212 * make sure we check if they are not both active when we mute */
1260 if (mute && wm8753->dai_func == 1) { 1213 if (mute && wm8753->dai_func == 1) {
1261 if (!codec->active) 1214 if (!codec->active)
1262 wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); 1215 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
1263 } else { 1216 } else {
1264 if (mute) 1217 if (mute)
1265 wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); 1218 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
1266 else 1219 else
1267 wm8753_write(codec, WM8753_DAC, mute_reg); 1220 snd_soc_write(codec, WM8753_DAC, mute_reg);
1268 } 1221 }
1269 1222
1270 return 0; 1223 return 0;
@@ -1273,23 +1226,23 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1273static int wm8753_set_bias_level(struct snd_soc_codec *codec, 1226static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1274 enum snd_soc_bias_level level) 1227 enum snd_soc_bias_level level)
1275{ 1228{
1276 u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e; 1229 u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
1277 1230
1278 switch (level) { 1231 switch (level) {
1279 case SND_SOC_BIAS_ON: 1232 case SND_SOC_BIAS_ON:
1280 /* set vmid to 50k and unmute dac */ 1233 /* set vmid to 50k and unmute dac */
1281 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); 1234 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
1282 break; 1235 break;
1283 case SND_SOC_BIAS_PREPARE: 1236 case SND_SOC_BIAS_PREPARE:
1284 /* set vmid to 5k for quick power up */ 1237 /* set vmid to 5k for quick power up */
1285 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); 1238 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
1286 break; 1239 break;
1287 case SND_SOC_BIAS_STANDBY: 1240 case SND_SOC_BIAS_STANDBY:
1288 /* mute dac and set vmid to 500k, enable VREF */ 1241 /* mute dac and set vmid to 500k, enable VREF */
1289 wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141); 1242 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
1290 break; 1243 break;
1291 case SND_SOC_BIAS_OFF: 1244 case SND_SOC_BIAS_OFF:
1292 wm8753_write(codec, WM8753_PWR1, 0x0001); 1245 snd_soc_write(codec, WM8753_PWR1, 0x0001);
1293 break; 1246 break;
1294 } 1247 }
1295 codec->bias_level = level; 1248 codec->bias_level = level;
@@ -1477,7 +1430,7 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
1477 else 1430 else
1478 dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1]; 1431 dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
1479 } 1432 }
1480 wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func); 1433 snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
1481} 1434}
1482 1435
1483static void wm8753_work(struct work_struct *work) 1436static void wm8753_work(struct work_struct *work)
@@ -1495,22 +1448,19 @@ static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
1495 1448
1496static int wm8753_resume(struct snd_soc_codec *codec) 1449static int wm8753_resume(struct snd_soc_codec *codec)
1497{ 1450{
1451 u16 *reg_cache = codec->reg_cache;
1498 int i; 1452 int i;
1499 u8 data[2];
1500 u16 *cache = codec->reg_cache;
1501 1453
1502 /* Sync reg_cache with the hardware */ 1454 /* Sync reg_cache with the hardware */
1503 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { 1455 for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
1504 if (i + 1 == WM8753_RESET) 1456 if (i == WM8753_RESET)
1505 continue; 1457 continue;
1506 1458
1507 /* No point in writing hardware default values back */ 1459 /* No point in writing hardware default values back */
1508 if (cache[i] == wm8753_reg[i]) 1460 if (reg_cache[i] == wm8753_reg[i])
1509 continue; 1461 continue;
1510 1462
1511 data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); 1463 snd_soc_write(codec, i, reg_cache[i]);
1512 data[1] = cache[i] & 0x00ff;
1513 codec->hw_write(codec->control_data, data, 2);
1514 } 1464 }
1515 1465
1516 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1466 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1548,7 +1498,7 @@ static int run_delayed_work(struct delayed_work *dwork)
1548static int wm8753_probe(struct snd_soc_codec *codec) 1498static int wm8753_probe(struct snd_soc_codec *codec)
1549{ 1499{
1550 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1500 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1551 int ret = 0, reg; 1501 int ret;
1552 1502
1553 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); 1503 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
1554 1504
@@ -1573,26 +1523,16 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1573 msecs_to_jiffies(caps_charge)); 1523 msecs_to_jiffies(caps_charge));
1574 1524
1575 /* set the update bits */ 1525 /* set the update bits */
1576 reg = wm8753_read_reg_cache(codec, WM8753_LDAC); 1526 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1577 wm8753_write(codec, WM8753_LDAC, reg | 0x0100); 1527 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
1578 reg = wm8753_read_reg_cache(codec, WM8753_RDAC); 1528 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1579 wm8753_write(codec, WM8753_RDAC, reg | 0x0100); 1529 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
1580 reg = wm8753_read_reg_cache(codec, WM8753_LADC); 1530 snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
1581 wm8753_write(codec, WM8753_LADC, reg | 0x0100); 1531 snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
1582 reg = wm8753_read_reg_cache(codec, WM8753_RADC); 1532 snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
1583 wm8753_write(codec, WM8753_RADC, reg | 0x0100); 1533 snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
1584 reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V); 1534 snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
1585 wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100); 1535 snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
1586 reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
1587 wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
1588 reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
1589 wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
1590 reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
1591 wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
1592 reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
1593 wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
1594 reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
1595 wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
1596 1536
1597 snd_soc_add_controls(codec, wm8753_snd_controls, 1537 snd_soc_add_controls(codec, wm8753_snd_controls,
1598 ARRAY_SIZE(wm8753_snd_controls)); 1538 ARRAY_SIZE(wm8753_snd_controls));