aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/adau1373.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/adau1373.c')
-rw-r--r--sound/soc/codecs/adau1373.c298
1 files changed, 237 insertions, 61 deletions
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 1aa10ddf3a61..59654b1e7f3f 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -32,6 +32,7 @@ struct adau1373_dai {
32}; 32};
33 33
34struct adau1373 { 34struct adau1373 {
35 struct regmap *regmap;
35 struct adau1373_dai dais[3]; 36 struct adau1373_dai dais[3];
36}; 37};
37 38
@@ -73,7 +74,6 @@ struct adau1373 {
73#define ADAU1373_PLL_CTRL4(x) (0x2c + (x) * 7) 74#define ADAU1373_PLL_CTRL4(x) (0x2c + (x) * 7)
74#define ADAU1373_PLL_CTRL5(x) (0x2d + (x) * 7) 75#define ADAU1373_PLL_CTRL5(x) (0x2d + (x) * 7)
75#define ADAU1373_PLL_CTRL6(x) (0x2e + (x) * 7) 76#define ADAU1373_PLL_CTRL6(x) (0x2e + (x) * 7)
76#define ADAU1373_PLL_CTRL7(x) (0x2f + (x) * 7)
77#define ADAU1373_HEADDECT 0x36 77#define ADAU1373_HEADDECT 0x36
78#define ADAU1373_ADC_DAC_STATUS 0x37 78#define ADAU1373_ADC_DAC_STATUS 0x37
79#define ADAU1373_ADC_CTRL 0x3c 79#define ADAU1373_ADC_CTRL 0x3c
@@ -152,37 +152,172 @@ struct adau1373 {
152#define ADAU1373_EP_CTRL_MICBIAS1_OFFSET 4 152#define ADAU1373_EP_CTRL_MICBIAS1_OFFSET 4
153#define ADAU1373_EP_CTRL_MICBIAS2_OFFSET 2 153#define ADAU1373_EP_CTRL_MICBIAS2_OFFSET 2
154 154
155static const uint8_t adau1373_default_regs[] = { 155static const struct reg_default adau1373_reg_defaults[] = {
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00 */ 156 { ADAU1373_INPUT_MODE, 0x00 },
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 157 { ADAU1373_AINL_CTRL(0), 0x00 },
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */ 158 { ADAU1373_AINR_CTRL(0), 0x00 },
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 159 { ADAU1373_AINL_CTRL(1), 0x00 },
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */ 160 { ADAU1373_AINR_CTRL(1), 0x00 },
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 161 { ADAU1373_AINL_CTRL(2), 0x00 },
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x30 */ 162 { ADAU1373_AINR_CTRL(2), 0x00 },
163 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 163 { ADAU1373_AINL_CTRL(3), 0x00 },
164 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, /* 0x40 */ 164 { ADAU1373_AINR_CTRL(3), 0x00 },
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 165 { ADAU1373_LLINE_OUT(0), 0x00 },
166 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ 166 { ADAU1373_RLINE_OUT(0), 0x00 },
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 167 { ADAU1373_LLINE_OUT(1), 0x00 },
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ 168 { ADAU1373_RLINE_OUT(1), 0x00 },
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 169 { ADAU1373_LSPK_OUT, 0x00 },
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */ 170 { ADAU1373_RSPK_OUT, 0x00 },
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 171 { ADAU1373_LHP_OUT, 0x00 },
172 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x80 */ 172 { ADAU1373_RHP_OUT, 0x00 },
173 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00, 173 { ADAU1373_ADC_GAIN, 0x00 },
174 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x90 */ 174 { ADAU1373_LADC_MIXER, 0x00 },
175 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00, 175 { ADAU1373_RADC_MIXER, 0x00 },
176 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0xa0 */ 176 { ADAU1373_LLINE1_MIX, 0x00 },
177 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00, 177 { ADAU1373_RLINE1_MIX, 0x00 },
178 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */ 178 { ADAU1373_LLINE2_MIX, 0x00 },
179 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 179 { ADAU1373_RLINE2_MIX, 0x00 },
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ 180 { ADAU1373_LSPK_MIX, 0x00 },
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 181 { ADAU1373_RSPK_MIX, 0x00 },
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */ 182 { ADAU1373_LHP_MIX, 0x00 },
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 183 { ADAU1373_RHP_MIX, 0x00 },
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* 0xe0 */ 184 { ADAU1373_EP_MIX, 0x00 },
185 0x00, 0x1f, 0x0f, 0x00, 0x00, 185 { ADAU1373_HP_CTRL, 0x00 },
186 { ADAU1373_HP_CTRL2, 0x00 },
187 { ADAU1373_LS_CTRL, 0x00 },
188 { ADAU1373_EP_CTRL, 0x00 },
189 { ADAU1373_MICBIAS_CTRL1, 0x00 },
190 { ADAU1373_MICBIAS_CTRL2, 0x00 },
191 { ADAU1373_OUTPUT_CTRL, 0x00 },
192 { ADAU1373_PWDN_CTRL1, 0x00 },
193 { ADAU1373_PWDN_CTRL2, 0x00 },
194 { ADAU1373_PWDN_CTRL3, 0x00 },
195 { ADAU1373_DPLL_CTRL(0), 0x00 },
196 { ADAU1373_PLL_CTRL1(0), 0x00 },
197 { ADAU1373_PLL_CTRL2(0), 0x00 },
198 { ADAU1373_PLL_CTRL3(0), 0x00 },
199 { ADAU1373_PLL_CTRL4(0), 0x00 },
200 { ADAU1373_PLL_CTRL5(0), 0x00 },
201 { ADAU1373_PLL_CTRL6(0), 0x02 },
202 { ADAU1373_DPLL_CTRL(1), 0x00 },
203 { ADAU1373_PLL_CTRL1(1), 0x00 },
204 { ADAU1373_PLL_CTRL2(1), 0x00 },
205 { ADAU1373_PLL_CTRL3(1), 0x00 },
206 { ADAU1373_PLL_CTRL4(1), 0x00 },
207 { ADAU1373_PLL_CTRL5(1), 0x00 },
208 { ADAU1373_PLL_CTRL6(1), 0x02 },
209 { ADAU1373_HEADDECT, 0x00 },
210 { ADAU1373_ADC_CTRL, 0x00 },
211 { ADAU1373_CLK_SRC_DIV(0), 0x00 },
212 { ADAU1373_CLK_SRC_DIV(1), 0x00 },
213 { ADAU1373_DAI(0), 0x0a },
214 { ADAU1373_DAI(1), 0x0a },
215 { ADAU1373_DAI(2), 0x0a },
216 { ADAU1373_BCLKDIV(0), 0x00 },
217 { ADAU1373_BCLKDIV(1), 0x00 },
218 { ADAU1373_BCLKDIV(2), 0x00 },
219 { ADAU1373_SRC_RATIOA(0), 0x00 },
220 { ADAU1373_SRC_RATIOB(0), 0x00 },
221 { ADAU1373_SRC_RATIOA(1), 0x00 },
222 { ADAU1373_SRC_RATIOB(1), 0x00 },
223 { ADAU1373_SRC_RATIOA(2), 0x00 },
224 { ADAU1373_SRC_RATIOB(2), 0x00 },
225 { ADAU1373_DEEMP_CTRL, 0x00 },
226 { ADAU1373_SRC_DAI_CTRL(0), 0x08 },
227 { ADAU1373_SRC_DAI_CTRL(1), 0x08 },
228 { ADAU1373_SRC_DAI_CTRL(2), 0x08 },
229 { ADAU1373_DIN_MIX_CTRL(0), 0x00 },
230 { ADAU1373_DIN_MIX_CTRL(1), 0x00 },
231 { ADAU1373_DIN_MIX_CTRL(2), 0x00 },
232 { ADAU1373_DIN_MIX_CTRL(3), 0x00 },
233 { ADAU1373_DIN_MIX_CTRL(4), 0x00 },
234 { ADAU1373_DOUT_MIX_CTRL(0), 0x00 },
235 { ADAU1373_DOUT_MIX_CTRL(1), 0x00 },
236 { ADAU1373_DOUT_MIX_CTRL(2), 0x00 },
237 { ADAU1373_DOUT_MIX_CTRL(3), 0x00 },
238 { ADAU1373_DOUT_MIX_CTRL(4), 0x00 },
239 { ADAU1373_DAI_PBL_VOL(0), 0x00 },
240 { ADAU1373_DAI_PBR_VOL(0), 0x00 },
241 { ADAU1373_DAI_PBL_VOL(1), 0x00 },
242 { ADAU1373_DAI_PBR_VOL(1), 0x00 },
243 { ADAU1373_DAI_PBL_VOL(2), 0x00 },
244 { ADAU1373_DAI_PBR_VOL(2), 0x00 },
245 { ADAU1373_DAI_RECL_VOL(0), 0x00 },
246 { ADAU1373_DAI_RECR_VOL(0), 0x00 },
247 { ADAU1373_DAI_RECL_VOL(1), 0x00 },
248 { ADAU1373_DAI_RECR_VOL(1), 0x00 },
249 { ADAU1373_DAI_RECL_VOL(2), 0x00 },
250 { ADAU1373_DAI_RECR_VOL(2), 0x00 },
251 { ADAU1373_DAC1_PBL_VOL, 0x00 },
252 { ADAU1373_DAC1_PBR_VOL, 0x00 },
253 { ADAU1373_DAC2_PBL_VOL, 0x00 },
254 { ADAU1373_DAC2_PBR_VOL, 0x00 },
255 { ADAU1373_ADC_RECL_VOL, 0x00 },
256 { ADAU1373_ADC_RECR_VOL, 0x00 },
257 { ADAU1373_DMIC_RECL_VOL, 0x00 },
258 { ADAU1373_DMIC_RECR_VOL, 0x00 },
259 { ADAU1373_VOL_GAIN1, 0x00 },
260 { ADAU1373_VOL_GAIN2, 0x00 },
261 { ADAU1373_VOL_GAIN3, 0x00 },
262 { ADAU1373_HPF_CTRL, 0x00 },
263 { ADAU1373_BASS1, 0x00 },
264 { ADAU1373_BASS2, 0x00 },
265 { ADAU1373_DRC(0) + 0x0, 0x78 },
266 { ADAU1373_DRC(0) + 0x1, 0x18 },
267 { ADAU1373_DRC(0) + 0x2, 0x00 },
268 { ADAU1373_DRC(0) + 0x3, 0x00 },
269 { ADAU1373_DRC(0) + 0x4, 0x00 },
270 { ADAU1373_DRC(0) + 0x5, 0xc0 },
271 { ADAU1373_DRC(0) + 0x6, 0x00 },
272 { ADAU1373_DRC(0) + 0x7, 0x00 },
273 { ADAU1373_DRC(0) + 0x8, 0x00 },
274 { ADAU1373_DRC(0) + 0x9, 0xc0 },
275 { ADAU1373_DRC(0) + 0xa, 0x88 },
276 { ADAU1373_DRC(0) + 0xb, 0x7a },
277 { ADAU1373_DRC(0) + 0xc, 0xdf },
278 { ADAU1373_DRC(0) + 0xd, 0x20 },
279 { ADAU1373_DRC(0) + 0xe, 0x00 },
280 { ADAU1373_DRC(0) + 0xf, 0x00 },
281 { ADAU1373_DRC(1) + 0x0, 0x78 },
282 { ADAU1373_DRC(1) + 0x1, 0x18 },
283 { ADAU1373_DRC(1) + 0x2, 0x00 },
284 { ADAU1373_DRC(1) + 0x3, 0x00 },
285 { ADAU1373_DRC(1) + 0x4, 0x00 },
286 { ADAU1373_DRC(1) + 0x5, 0xc0 },
287 { ADAU1373_DRC(1) + 0x6, 0x00 },
288 { ADAU1373_DRC(1) + 0x7, 0x00 },
289 { ADAU1373_DRC(1) + 0x8, 0x00 },
290 { ADAU1373_DRC(1) + 0x9, 0xc0 },
291 { ADAU1373_DRC(1) + 0xa, 0x88 },
292 { ADAU1373_DRC(1) + 0xb, 0x7a },
293 { ADAU1373_DRC(1) + 0xc, 0xdf },
294 { ADAU1373_DRC(1) + 0xd, 0x20 },
295 { ADAU1373_DRC(1) + 0xe, 0x00 },
296 { ADAU1373_DRC(1) + 0xf, 0x00 },
297 { ADAU1373_DRC(2) + 0x0, 0x78 },
298 { ADAU1373_DRC(2) + 0x1, 0x18 },
299 { ADAU1373_DRC(2) + 0x2, 0x00 },
300 { ADAU1373_DRC(2) + 0x3, 0x00 },
301 { ADAU1373_DRC(2) + 0x4, 0x00 },
302 { ADAU1373_DRC(2) + 0x5, 0xc0 },
303 { ADAU1373_DRC(2) + 0x6, 0x00 },
304 { ADAU1373_DRC(2) + 0x7, 0x00 },
305 { ADAU1373_DRC(2) + 0x8, 0x00 },
306 { ADAU1373_DRC(2) + 0x9, 0xc0 },
307 { ADAU1373_DRC(2) + 0xa, 0x88 },
308 { ADAU1373_DRC(2) + 0xb, 0x7a },
309 { ADAU1373_DRC(2) + 0xc, 0xdf },
310 { ADAU1373_DRC(2) + 0xd, 0x20 },
311 { ADAU1373_DRC(2) + 0xe, 0x00 },
312 { ADAU1373_DRC(2) + 0xf, 0x00 },
313 { ADAU1373_3D_CTRL1, 0x00 },
314 { ADAU1373_3D_CTRL2, 0x00 },
315 { ADAU1373_FDSP_SEL1, 0x00 },
316 { ADAU1373_FDSP_SEL2, 0x00 },
317 { ADAU1373_FDSP_SEL2, 0x00 },
318 { ADAU1373_FDSP_SEL4, 0x00 },
319 { ADAU1373_DIGMICCTRL, 0x00 },
320 { ADAU1373_DIGEN, 0x00 },
186}; 321};
187 322
188static const unsigned int adau1373_out_tlv[] = { 323static const unsigned int adau1373_out_tlv[] = {
@@ -418,6 +553,7 @@ static int adau1373_pll_event(struct snd_soc_dapm_widget *w,
418 struct snd_kcontrol *kcontrol, int event) 553 struct snd_kcontrol *kcontrol, int event)
419{ 554{
420 struct snd_soc_codec *codec = w->codec; 555 struct snd_soc_codec *codec = w->codec;
556 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
421 unsigned int pll_id = w->name[3] - '1'; 557 unsigned int pll_id = w->name[3] - '1';
422 unsigned int val; 558 unsigned int val;
423 559
@@ -426,7 +562,7 @@ static int adau1373_pll_event(struct snd_soc_dapm_widget *w,
426 else 562 else
427 val = 0; 563 val = 0;
428 564
429 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id), 565 regmap_update_bits(adau1373->regmap, ADAU1373_PLL_CTRL6(pll_id),
430 ADAU1373_PLL_CTRL6_PLL_EN, val); 566 ADAU1373_PLL_CTRL6_PLL_EN, val);
431 567
432 if (SND_SOC_DAPM_EVENT_ON(event)) 568 if (SND_SOC_DAPM_EVENT_ON(event))
@@ -938,7 +1074,7 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream,
938 1074
939 adau1373_dai->enable_src = (div != 0); 1075 adau1373_dai->enable_src = (div != 0);
940 1076
941 snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id), 1077 regmap_update_bits(adau1373->regmap, ADAU1373_BCLKDIV(dai->id),
942 ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK, 1078 ADAU1373_BCLKDIV_SR_MASK | ADAU1373_BCLKDIV_BCLK_MASK,
943 (div << 2) | ADAU1373_BCLKDIV_64); 1079 (div << 2) | ADAU1373_BCLKDIV_64);
944 1080
@@ -959,7 +1095,7 @@ static int adau1373_hw_params(struct snd_pcm_substream *substream,
959 return -EINVAL; 1095 return -EINVAL;
960 } 1096 }
961 1097
962 return snd_soc_update_bits(codec, ADAU1373_DAI(dai->id), 1098 return regmap_update_bits(adau1373->regmap, ADAU1373_DAI(dai->id),
963 ADAU1373_DAI_WLEN_MASK, ctrl); 1099 ADAU1373_DAI_WLEN_MASK, ctrl);
964} 1100}
965 1101
@@ -1016,7 +1152,7 @@ static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1016 return -EINVAL; 1152 return -EINVAL;
1017 } 1153 }
1018 1154
1019 snd_soc_update_bits(codec, ADAU1373_DAI(dai->id), 1155 regmap_update_bits(adau1373->regmap, ADAU1373_DAI(dai->id),
1020 ~ADAU1373_DAI_WLEN_MASK, ctrl); 1156 ~ADAU1373_DAI_WLEN_MASK, ctrl);
1021 1157
1022 return 0; 1158 return 0;
@@ -1039,7 +1175,7 @@ static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai,
1039 adau1373_dai->sysclk = freq; 1175 adau1373_dai->sysclk = freq;
1040 adau1373_dai->clk_src = clk_id; 1176 adau1373_dai->clk_src = clk_id;
1041 1177
1042 snd_soc_update_bits(dai->codec, ADAU1373_BCLKDIV(dai->id), 1178 regmap_update_bits(adau1373->regmap, ADAU1373_BCLKDIV(dai->id),
1043 ADAU1373_BCLKDIV_SOURCE, clk_id << 5); 1179 ADAU1373_BCLKDIV_SOURCE, clk_id << 5);
1044 1180
1045 return 0; 1181 return 0;
@@ -1120,6 +1256,7 @@ static struct snd_soc_dai_driver adau1373_dai_driver[] = {
1120static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id, 1256static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
1121 int source, unsigned int freq_in, unsigned int freq_out) 1257 int source, unsigned int freq_in, unsigned int freq_out)
1122{ 1258{
1259 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
1123 unsigned int dpll_div = 0; 1260 unsigned int dpll_div = 0;
1124 unsigned int x, r, n, m, i, j, mode; 1261 unsigned int x, r, n, m, i, j, mode;
1125 1262
@@ -1187,36 +1324,36 @@ static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id,
1187 1324
1188 if (dpll_div) { 1325 if (dpll_div) {
1189 dpll_div = 11 - dpll_div; 1326 dpll_div = 11 - dpll_div;
1190 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id), 1327 regmap_update_bits(adau1373->regmap, ADAU1373_PLL_CTRL6(pll_id),
1191 ADAU1373_PLL_CTRL6_DPLL_BYPASS, 0); 1328 ADAU1373_PLL_CTRL6_DPLL_BYPASS, 0);
1192 } else { 1329 } else {
1193 snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id), 1330 regmap_update_bits(adau1373->regmap, ADAU1373_PLL_CTRL6(pll_id),
1194 ADAU1373_PLL_CTRL6_DPLL_BYPASS, 1331 ADAU1373_PLL_CTRL6_DPLL_BYPASS,
1195 ADAU1373_PLL_CTRL6_DPLL_BYPASS); 1332 ADAU1373_PLL_CTRL6_DPLL_BYPASS);
1196 } 1333 }
1197 1334
1198 snd_soc_write(codec, ADAU1373_DPLL_CTRL(pll_id), 1335 regmap_write(adau1373->regmap, ADAU1373_DPLL_CTRL(pll_id),
1199 (source << 4) | dpll_div); 1336 (source << 4) | dpll_div);
1200 snd_soc_write(codec, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff); 1337 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff);
1201 snd_soc_write(codec, ADAU1373_PLL_CTRL2(pll_id), m & 0xff); 1338 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL2(pll_id), m & 0xff);
1202 snd_soc_write(codec, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff); 1339 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff);
1203 snd_soc_write(codec, ADAU1373_PLL_CTRL4(pll_id), n & 0xff); 1340 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL4(pll_id), n & 0xff);
1204 snd_soc_write(codec, ADAU1373_PLL_CTRL5(pll_id), 1341 regmap_write(adau1373->regmap, ADAU1373_PLL_CTRL5(pll_id),
1205 (r << 3) | (x << 1) | mode); 1342 (r << 3) | (x << 1) | mode);
1206 1343
1207 /* Set sysclk to pll_rate / 4 */ 1344 /* Set sysclk to pll_rate / 4 */
1208 snd_soc_update_bits(codec, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09); 1345 regmap_update_bits(adau1373->regmap, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09);
1209 1346
1210 return 0; 1347 return 0;
1211} 1348}
1212 1349
1213static void adau1373_load_drc_settings(struct snd_soc_codec *codec, 1350static void adau1373_load_drc_settings(struct adau1373 *adau1373,
1214 unsigned int nr, uint8_t *drc) 1351 unsigned int nr, uint8_t *drc)
1215{ 1352{
1216 unsigned int i; 1353 unsigned int i;
1217 1354
1218 for (i = 0; i < ADAU1373_DRC_SIZE; ++i) 1355 for (i = 0; i < ADAU1373_DRC_SIZE; ++i)
1219 snd_soc_write(codec, ADAU1373_DRC(nr) + i, drc[i]); 1356 regmap_write(adau1373->regmap, ADAU1373_DRC(nr) + i, drc[i]);
1220} 1357}
1221 1358
1222static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias) 1359static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
@@ -1235,13 +1372,14 @@ static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias)
1235 1372
1236static int adau1373_probe(struct snd_soc_codec *codec) 1373static int adau1373_probe(struct snd_soc_codec *codec)
1237{ 1374{
1375 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
1238 struct adau1373_platform_data *pdata = codec->dev->platform_data; 1376 struct adau1373_platform_data *pdata = codec->dev->platform_data;
1239 bool lineout_differential = false; 1377 bool lineout_differential = false;
1240 unsigned int val; 1378 unsigned int val;
1241 int ret; 1379 int ret;
1242 int i; 1380 int i;
1243 1381
1244 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); 1382 ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
1245 if (ret) { 1383 if (ret) {
1246 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); 1384 dev_err(codec->dev, "failed to set cache I/O: %d\n", ret);
1247 return ret; 1385 return ret;
@@ -1256,7 +1394,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1256 return -EINVAL; 1394 return -EINVAL;
1257 1395
1258 for (i = 0; i < pdata->num_drc; ++i) { 1396 for (i = 0; i < pdata->num_drc; ++i) {
1259 adau1373_load_drc_settings(codec, i, 1397 adau1373_load_drc_settings(adau1373, i,
1260 pdata->drc_setting[i]); 1398 pdata->drc_setting[i]);
1261 } 1399 }
1262 1400
@@ -1268,18 +1406,18 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1268 if (pdata->input_differential[i]) 1406 if (pdata->input_differential[i])
1269 val |= BIT(i); 1407 val |= BIT(i);
1270 } 1408 }
1271 snd_soc_write(codec, ADAU1373_INPUT_MODE, val); 1409 regmap_write(adau1373->regmap, ADAU1373_INPUT_MODE, val);
1272 1410
1273 val = 0; 1411 val = 0;
1274 if (pdata->lineout_differential) 1412 if (pdata->lineout_differential)
1275 val |= ADAU1373_OUTPUT_CTRL_LDIFF; 1413 val |= ADAU1373_OUTPUT_CTRL_LDIFF;
1276 if (pdata->lineout_ground_sense) 1414 if (pdata->lineout_ground_sense)
1277 val |= ADAU1373_OUTPUT_CTRL_LNFBEN; 1415 val |= ADAU1373_OUTPUT_CTRL_LNFBEN;
1278 snd_soc_write(codec, ADAU1373_OUTPUT_CTRL, val); 1416 regmap_write(adau1373->regmap, ADAU1373_OUTPUT_CTRL, val);
1279 1417
1280 lineout_differential = pdata->lineout_differential; 1418 lineout_differential = pdata->lineout_differential;
1281 1419
1282 snd_soc_write(codec, ADAU1373_EP_CTRL, 1420 regmap_write(adau1373->regmap, ADAU1373_EP_CTRL,
1283 (pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) | 1421 (pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) |
1284 (pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET)); 1422 (pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET));
1285 } 1423 }
@@ -1289,7 +1427,7 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1289 ARRAY_SIZE(adau1373_lineout2_controls)); 1427 ARRAY_SIZE(adau1373_lineout2_controls));
1290 } 1428 }
1291 1429
1292 snd_soc_write(codec, ADAU1373_ADC_CTRL, 1430 regmap_write(adau1373->regmap, ADAU1373_ADC_CTRL,
1293 ADAU1373_ADC_CTRL_RESET_FORCE | ADAU1373_ADC_CTRL_PEAK_DETECT); 1431 ADAU1373_ADC_CTRL_RESET_FORCE | ADAU1373_ADC_CTRL_PEAK_DETECT);
1294 1432
1295 return 0; 1433 return 0;
@@ -1298,17 +1436,19 @@ static int adau1373_probe(struct snd_soc_codec *codec)
1298static int adau1373_set_bias_level(struct snd_soc_codec *codec, 1436static int adau1373_set_bias_level(struct snd_soc_codec *codec,
1299 enum snd_soc_bias_level level) 1437 enum snd_soc_bias_level level)
1300{ 1438{
1439 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
1440
1301 switch (level) { 1441 switch (level) {
1302 case SND_SOC_BIAS_ON: 1442 case SND_SOC_BIAS_ON:
1303 break; 1443 break;
1304 case SND_SOC_BIAS_PREPARE: 1444 case SND_SOC_BIAS_PREPARE:
1305 break; 1445 break;
1306 case SND_SOC_BIAS_STANDBY: 1446 case SND_SOC_BIAS_STANDBY:
1307 snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3, 1447 regmap_update_bits(adau1373->regmap, ADAU1373_PWDN_CTRL3,
1308 ADAU1373_PWDN_CTRL3_PWR_EN, ADAU1373_PWDN_CTRL3_PWR_EN); 1448 ADAU1373_PWDN_CTRL3_PWR_EN, ADAU1373_PWDN_CTRL3_PWR_EN);
1309 break; 1449 break;
1310 case SND_SOC_BIAS_OFF: 1450 case SND_SOC_BIAS_OFF:
1311 snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3, 1451 regmap_update_bits(adau1373->regmap, ADAU1373_PWDN_CTRL3,
1312 ADAU1373_PWDN_CTRL3_PWR_EN, 0); 1452 ADAU1373_PWDN_CTRL3_PWR_EN, 0);
1313 break; 1453 break;
1314 } 1454 }
@@ -1324,17 +1464,49 @@ static int adau1373_remove(struct snd_soc_codec *codec)
1324 1464
1325static int adau1373_suspend(struct snd_soc_codec *codec) 1465static int adau1373_suspend(struct snd_soc_codec *codec)
1326{ 1466{
1327 return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF); 1467 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
1468 int ret;
1469
1470 ret = adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
1471 regcache_cache_only(adau1373->regmap, true);
1472
1473 return ret;
1328} 1474}
1329 1475
1330static int adau1373_resume(struct snd_soc_codec *codec) 1476static int adau1373_resume(struct snd_soc_codec *codec)
1331{ 1477{
1478 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
1479
1480 regcache_cache_only(adau1373->regmap, false);
1332 adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1481 adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1333 snd_soc_cache_sync(codec); 1482 regcache_sync(adau1373->regmap);
1334 1483
1335 return 0; 1484 return 0;
1336} 1485}
1337 1486
1487static bool adau1373_register_volatile(struct device *dev, unsigned int reg)
1488{
1489 switch (reg) {
1490 case ADAU1373_SOFT_RESET:
1491 case ADAU1373_ADC_DAC_STATUS:
1492 return true;
1493 default:
1494 return false;
1495 }
1496}
1497
1498static const struct regmap_config adau1373_regmap_config = {
1499 .val_bits = 8,
1500 .reg_bits = 8,
1501
1502 .volatile_reg = adau1373_register_volatile,
1503 .max_register = ADAU1373_SOFT_RESET,
1504
1505 .cache_type = REGCACHE_RBTREE,
1506 .reg_defaults = adau1373_reg_defaults,
1507 .num_reg_defaults = ARRAY_SIZE(adau1373_reg_defaults),
1508};
1509
1338static struct snd_soc_codec_driver adau1373_codec_driver = { 1510static struct snd_soc_codec_driver adau1373_codec_driver = {
1339 .probe = adau1373_probe, 1511 .probe = adau1373_probe,
1340 .remove = adau1373_remove, 1512 .remove = adau1373_remove,
@@ -1342,9 +1514,6 @@ static struct snd_soc_codec_driver adau1373_codec_driver = {
1342 .resume = adau1373_resume, 1514 .resume = adau1373_resume,
1343 .set_bias_level = adau1373_set_bias_level, 1515 .set_bias_level = adau1373_set_bias_level,
1344 .idle_bias_off = true, 1516 .idle_bias_off = true,
1345 .reg_cache_size = ARRAY_SIZE(adau1373_default_regs),
1346 .reg_cache_default = adau1373_default_regs,
1347 .reg_word_size = sizeof(uint8_t),
1348 1517
1349 .set_pll = adau1373_set_pll, 1518 .set_pll = adau1373_set_pll,
1350 1519
@@ -1366,6 +1535,13 @@ static int adau1373_i2c_probe(struct i2c_client *client,
1366 if (!adau1373) 1535 if (!adau1373)
1367 return -ENOMEM; 1536 return -ENOMEM;
1368 1537
1538 adau1373->regmap = devm_regmap_init_i2c(client,
1539 &adau1373_regmap_config);
1540 if (IS_ERR(adau1373->regmap))
1541 return PTR_ERR(adau1373->regmap);
1542
1543 regmap_write(adau1373->regmap, ADAU1373_SOFT_RESET, 0x00);
1544
1369 dev_set_drvdata(&client->dev, adau1373); 1545 dev_set_drvdata(&client->dev, adau1373);
1370 1546
1371 ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver, 1547 ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver,