diff options
Diffstat (limited to 'sound/soc/codecs/adau1373.c')
-rw-r--r-- | sound/soc/codecs/adau1373.c | 298 |
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 | ||
34 | struct adau1373 { | 34 | struct 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 | ||
155 | static const uint8_t adau1373_default_regs[] = { | 155 | static 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 | ||
188 | static const unsigned int adau1373_out_tlv[] = { | 323 | static 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[] = { | |||
1120 | static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id, | 1256 | static 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 | ||
1213 | static void adau1373_load_drc_settings(struct snd_soc_codec *codec, | 1350 | static 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 | ||
1222 | static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias) | 1359 | static 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 | ||
1236 | static int adau1373_probe(struct snd_soc_codec *codec) | 1373 | static 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) | |||
1298 | static int adau1373_set_bias_level(struct snd_soc_codec *codec, | 1436 | static 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 | ||
1325 | static int adau1373_suspend(struct snd_soc_codec *codec) | 1465 | static 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 | ||
1330 | static int adau1373_resume(struct snd_soc_codec *codec) | 1476 | static 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 | ||
1487 | static 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 | |||
1498 | static 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 | |||
1338 | static struct snd_soc_codec_driver adau1373_codec_driver = { | 1510 | static 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, |