xref: /linux/sound/soc/codecs/wm8731.c (revision e5c91aac491def6ab3f90c4cc246e3fcb0f8f058)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * wm8731.c  --  WM8731 ALSA SoC Audio driver
4  *
5  * Copyright 2005 Openedhand Ltd.
6  * Copyright 2006-12 Wolfson Microelectronics, plc
7  *
8  * Author: Richard Purdie <richard@openedhand.com>
9  *
10  * Based on wm8753.c by Liam Girdwood
11  */
12 
13 #include <linux/cleanup.h>
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/init.h>
17 #include <linux/delay.h>
18 #include <linux/pm.h>
19 #include <linux/slab.h>
20 #include <linux/regmap.h>
21 #include <linux/regulator/consumer.h>
22 #include <linux/clk.h>
23 #include <sound/core.h>
24 #include <sound/pcm.h>
25 #include <sound/pcm_params.h>
26 #include <sound/soc.h>
27 #include <sound/initval.h>
28 #include <sound/tlv.h>
29 
30 #include "wm8731.h"
31 
32 static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
33 	"AVDD",
34 	"HPVDD",
35 	"DCVDD",
36 	"DBVDD",
37 };
38 
39 /*
40  * wm8731 register cache
41  */
42 static const struct reg_default wm8731_reg_defaults[] = {
43 	{ 0, 0x0097 },
44 	{ 1, 0x0097 },
45 	{ 2, 0x0079 },
46 	{ 3, 0x0079 },
47 	{ 4, 0x000a },
48 	{ 5, 0x0008 },
49 	{ 6, 0x009f },
50 	{ 7, 0x000a },
51 	{ 8, 0x0000 },
52 	{ 9, 0x0000 },
53 };
54 
55 static bool wm8731_volatile(struct device *dev, unsigned int reg)
56 {
57 	return reg == WM8731_RESET;
58 }
59 
60 #define wm8731_reset(m)	regmap_write(m, WM8731_RESET, 0)
61 
62 static const char *wm8731_input_select[] = {"Line In", "Mic"};
63 
64 static SOC_ENUM_SINGLE_DECL(wm8731_insel_enum,
65 			    WM8731_APANA, 2, wm8731_input_select);
66 
67 static int wm8731_deemph[] = { 0, 32000, 44100, 48000 };
68 
69 static int wm8731_set_deemph(struct snd_soc_component *component)
70 {
71 	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
72 	int val, i, best;
73 
74 	/* If we're using deemphasis select the nearest available sample
75 	 * rate.
76 	 */
77 	if (wm8731->deemph) {
78 		best = 1;
79 		for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) {
80 			if (abs(wm8731_deemph[i] - wm8731->playback_fs) <
81 			    abs(wm8731_deemph[best] - wm8731->playback_fs))
82 				best = i;
83 		}
84 
85 		val = best << 1;
86 	} else {
87 		best = 0;
88 		val = 0;
89 	}
90 
91 	dev_dbg(component->dev, "Set deemphasis %d (%dHz)\n",
92 		best, wm8731_deemph[best]);
93 
94 	return snd_soc_component_update_bits(component, WM8731_APDIGI, 0x6, val);
95 }
96 
97 static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
98 			     struct snd_ctl_elem_value *ucontrol)
99 {
100 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
101 	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
102 
103 	ucontrol->value.integer.value[0] = wm8731->deemph;
104 
105 	return 0;
106 }
107 
108 static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
109 			     struct snd_ctl_elem_value *ucontrol)
110 {
111 	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
112 	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
113 	unsigned int deemph = ucontrol->value.integer.value[0];
114 
115 	if (deemph > 1)
116 		return -EINVAL;
117 
118 	guard(mutex)(&wm8731->lock);
119 	if (wm8731->deemph != deemph) {
120 		wm8731->deemph = deemph;
121 
122 		wm8731_set_deemph(component);
123 
124 		return 1;
125 	}
126 
127 	return 0;
128 }
129 
130 static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0);
131 static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0);
132 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
133 static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0);
134 
135 static const struct snd_kcontrol_new wm8731_snd_controls[] = {
136 
137 SOC_DOUBLE_R_TLV("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V,
138 		 0, 127, 0, out_tlv),
139 SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V,
140 	7, 1, 0),
141 
142 SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0,
143 		 in_tlv),
144 SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
145 
146 SOC_SINGLE_TLV("Mic Boost Volume", WM8731_APANA, 0, 1, 0, mic_tlv),
147 SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1),
148 
149 SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
150 	       sidetone_tlv),
151 
152 SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
153 SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
154 
155 SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
156 		    wm8731_get_deemph, wm8731_put_deemph),
157 };
158 
159 /* Output Mixer */
160 static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = {
161 SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
162 SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0),
163 SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
164 };
165 
166 /* Input mux */
167 static const struct snd_kcontrol_new wm8731_input_mux_controls =
168 SOC_DAPM_ENUM("Input Select", wm8731_insel_enum);
169 
170 static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
171 SND_SOC_DAPM_SUPPLY("ACTIVE",WM8731_ACTIVE, 0, 0, NULL, 0),
172 SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0),
173 SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1,
174 	&wm8731_output_mixer_controls[0],
175 	ARRAY_SIZE(wm8731_output_mixer_controls)),
176 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8731_PWR, 3, 1),
177 SND_SOC_DAPM_OUTPUT("LOUT"),
178 SND_SOC_DAPM_OUTPUT("LHPOUT"),
179 SND_SOC_DAPM_OUTPUT("ROUT"),
180 SND_SOC_DAPM_OUTPUT("RHPOUT"),
181 SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8731_PWR, 2, 1),
182 SND_SOC_DAPM_MUX("Input Mux", SND_SOC_NOPM, 0, 0, &wm8731_input_mux_controls),
183 SND_SOC_DAPM_PGA("Line Input", WM8731_PWR, 0, 1, NULL, 0),
184 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8731_PWR, 1, 1),
185 SND_SOC_DAPM_INPUT("MICIN"),
186 SND_SOC_DAPM_INPUT("RLINEIN"),
187 SND_SOC_DAPM_INPUT("LLINEIN"),
188 };
189 
190 static int wm8731_check_osc(struct snd_soc_dapm_widget *source,
191 			    struct snd_soc_dapm_widget *sink)
192 {
193 	struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);
194 	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
195 
196 	return wm8731->sysclk_type == WM8731_SYSCLK_XTAL;
197 }
198 
199 static const struct snd_soc_dapm_route wm8731_intercon[] = {
200 	{"DAC", NULL, "OSC", wm8731_check_osc},
201 	{"ADC", NULL, "OSC", wm8731_check_osc},
202 	{"DAC", NULL, "ACTIVE"},
203 	{"ADC", NULL, "ACTIVE"},
204 
205 	/* output mixer */
206 	{"Output Mixer", "Line Bypass Switch", "Line Input"},
207 	{"Output Mixer", "HiFi Playback Switch", "DAC"},
208 	{"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
209 
210 	/* outputs */
211 	{"RHPOUT", NULL, "Output Mixer"},
212 	{"ROUT", NULL, "Output Mixer"},
213 	{"LHPOUT", NULL, "Output Mixer"},
214 	{"LOUT", NULL, "Output Mixer"},
215 
216 	/* input mux */
217 	{"Input Mux", "Line In", "Line Input"},
218 	{"Input Mux", "Mic", "Mic Bias"},
219 	{"ADC", NULL, "Input Mux"},
220 
221 	/* inputs */
222 	{"Line Input", NULL, "LLINEIN"},
223 	{"Line Input", NULL, "RLINEIN"},
224 	{"Mic Bias", NULL, "MICIN"},
225 };
226 
227 struct _coeff_div {
228 	u32 mclk;
229 	u32 rate;
230 	u16 fs;
231 	u8 sr:4;
232 	u8 bosr:1;
233 	u8 usb:1;
234 };
235 
236 /* codec mclk clock divider coefficients */
237 static const struct _coeff_div coeff_div[] = {
238 	/* 48k */
239 	{12288000, 48000, 256, 0x0, 0x0, 0x0},
240 	{18432000, 48000, 384, 0x0, 0x1, 0x0},
241 	{12000000, 48000, 250, 0x0, 0x0, 0x1},
242 
243 	/* 32k */
244 	{12288000, 32000, 384, 0x6, 0x0, 0x0},
245 	{18432000, 32000, 576, 0x6, 0x1, 0x0},
246 	{12000000, 32000, 375, 0x6, 0x0, 0x1},
247 
248 	/* 8k */
249 	{12288000, 8000, 1536, 0x3, 0x0, 0x0},
250 	{18432000, 8000, 2304, 0x3, 0x1, 0x0},
251 	{11289600, 8000, 1408, 0xb, 0x0, 0x0},
252 	{16934400, 8000, 2112, 0xb, 0x1, 0x0},
253 	{12000000, 8000, 1500, 0x3, 0x0, 0x1},
254 
255 	/* 96k */
256 	{12288000, 96000, 128, 0x7, 0x0, 0x0},
257 	{18432000, 96000, 192, 0x7, 0x1, 0x0},
258 	{12000000, 96000, 125, 0x7, 0x0, 0x1},
259 
260 	/* 44.1k */
261 	{11289600, 44100, 256, 0x8, 0x0, 0x0},
262 	{16934400, 44100, 384, 0x8, 0x1, 0x0},
263 	{12000000, 44100, 272, 0x8, 0x1, 0x1},
264 
265 	/* 88.2k */
266 	{11289600, 88200, 128, 0xf, 0x0, 0x0},
267 	{16934400, 88200, 192, 0xf, 0x1, 0x0},
268 	{12000000, 88200, 136, 0xf, 0x1, 0x1},
269 };
270 
271 /* rates constraints */
272 static const unsigned int wm8731_rates_12000000[] = {
273 	8000, 32000, 44100, 48000, 96000, 88200,
274 };
275 
276 static const unsigned int wm8731_rates_12288000_18432000[] = {
277 	8000, 32000, 48000, 96000,
278 };
279 
280 static const unsigned int wm8731_rates_11289600_16934400[] = {
281 	8000, 44100, 88200,
282 };
283 
284 static const struct snd_pcm_hw_constraint_list wm8731_constraints_12000000 = {
285 	.list = wm8731_rates_12000000,
286 	.count = ARRAY_SIZE(wm8731_rates_12000000),
287 };
288 
289 static const
290 struct snd_pcm_hw_constraint_list wm8731_constraints_12288000_18432000 = {
291 	.list = wm8731_rates_12288000_18432000,
292 	.count = ARRAY_SIZE(wm8731_rates_12288000_18432000),
293 };
294 
295 static const
296 struct snd_pcm_hw_constraint_list wm8731_constraints_11289600_16934400 = {
297 	.list = wm8731_rates_11289600_16934400,
298 	.count = ARRAY_SIZE(wm8731_rates_11289600_16934400),
299 };
300 
301 static inline int get_coeff(int mclk, int rate)
302 {
303 	int i;
304 
305 	for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
306 		if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
307 			return i;
308 	}
309 	return 0;
310 }
311 
312 static int wm8731_hw_params(struct snd_pcm_substream *substream,
313 			    struct snd_pcm_hw_params *params,
314 			    struct snd_soc_dai *dai)
315 {
316 	struct snd_soc_component *component = dai->component;
317 	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
318 	u16 iface = snd_soc_component_read(component, WM8731_IFACE) & 0xfff3;
319 	int i = get_coeff(wm8731->sysclk, params_rate(params));
320 	u16 srate = (coeff_div[i].sr << 2) |
321 		(coeff_div[i].bosr << 1) | coeff_div[i].usb;
322 
323 	wm8731->playback_fs = params_rate(params);
324 
325 	snd_soc_component_write(component, WM8731_SRATE, srate);
326 
327 	/* bit size */
328 	switch (params_width(params)) {
329 	case 16:
330 		break;
331 	case 20:
332 		iface |= 0x0004;
333 		break;
334 	case 24:
335 		iface |= 0x0008;
336 		break;
337 	case 32:
338 		iface |= 0x000c;
339 		break;
340 	}
341 
342 	wm8731_set_deemph(component);
343 
344 	snd_soc_component_write(component, WM8731_IFACE, iface);
345 	return 0;
346 }
347 
348 static int wm8731_mute(struct snd_soc_dai *dai, int mute, int direction)
349 {
350 	struct snd_soc_component *component = dai->component;
351 	u16 mute_reg = snd_soc_component_read(component, WM8731_APDIGI) & 0xfff7;
352 
353 	if (mute)
354 		snd_soc_component_write(component, WM8731_APDIGI, mute_reg | 0x8);
355 	else
356 		snd_soc_component_write(component, WM8731_APDIGI, mute_reg);
357 	return 0;
358 }
359 
360 static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
361 		int clk_id, unsigned int freq, int dir)
362 {
363 	struct snd_soc_component *component = codec_dai->component;
364 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
365 	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
366 
367 	switch (clk_id) {
368 	case WM8731_SYSCLK_XTAL:
369 	case WM8731_SYSCLK_MCLK:
370 		if (wm8731->mclk && clk_set_rate(wm8731->mclk, freq))
371 			return -EINVAL;
372 		wm8731->sysclk_type = clk_id;
373 		break;
374 	default:
375 		return -EINVAL;
376 	}
377 
378 	switch (freq) {
379 	case 0:
380 		wm8731->constraints = NULL;
381 		break;
382 	case 12000000:
383 		wm8731->constraints = &wm8731_constraints_12000000;
384 		break;
385 	case 12288000:
386 	case 18432000:
387 		wm8731->constraints = &wm8731_constraints_12288000_18432000;
388 		break;
389 	case 16934400:
390 	case 11289600:
391 		wm8731->constraints = &wm8731_constraints_11289600_16934400;
392 		break;
393 	default:
394 		return -EINVAL;
395 	}
396 
397 	wm8731->sysclk = freq;
398 
399 	snd_soc_dapm_sync(dapm);
400 
401 	return 0;
402 }
403 
404 
405 static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
406 		unsigned int fmt)
407 {
408 	struct snd_soc_component *component = codec_dai->component;
409 	u16 iface = 0;
410 
411 	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
412 	case SND_SOC_DAIFMT_CBP_CFP:
413 		iface |= 0x0040;
414 		break;
415 	case SND_SOC_DAIFMT_CBC_CFC:
416 		break;
417 	default:
418 		return -EINVAL;
419 	}
420 
421 	/* interface format */
422 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
423 	case SND_SOC_DAIFMT_I2S:
424 		iface |= 0x0002;
425 		break;
426 	case SND_SOC_DAIFMT_RIGHT_J:
427 		break;
428 	case SND_SOC_DAIFMT_LEFT_J:
429 		iface |= 0x0001;
430 		break;
431 	case SND_SOC_DAIFMT_DSP_A:
432 		iface |= 0x0013;
433 		break;
434 	case SND_SOC_DAIFMT_DSP_B:
435 		iface |= 0x0003;
436 		break;
437 	default:
438 		return -EINVAL;
439 	}
440 
441 	/* clock inversion */
442 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
443 	case SND_SOC_DAIFMT_NB_NF:
444 		break;
445 	case SND_SOC_DAIFMT_IB_IF:
446 		iface |= 0x0090;
447 		break;
448 	case SND_SOC_DAIFMT_IB_NF:
449 		iface |= 0x0080;
450 		break;
451 	case SND_SOC_DAIFMT_NB_IF:
452 		iface |= 0x0010;
453 		break;
454 	default:
455 		return -EINVAL;
456 	}
457 
458 	/* set iface */
459 	snd_soc_component_write(component, WM8731_IFACE, iface);
460 	return 0;
461 }
462 
463 static int wm8731_set_bias_level(struct snd_soc_component *component,
464 				 enum snd_soc_bias_level level)
465 {
466 	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component);
467 	struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
468 	int ret;
469 	u16 reg;
470 
471 	switch (level) {
472 	case SND_SOC_BIAS_ON:
473 		ret = clk_prepare_enable(wm8731->mclk);
474 		if (ret)
475 			return ret;
476 		break;
477 	case SND_SOC_BIAS_PREPARE:
478 		break;
479 	case SND_SOC_BIAS_STANDBY:
480 		if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
481 			ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
482 						    wm8731->supplies);
483 			if (ret != 0)
484 				return ret;
485 
486 			regcache_sync(wm8731->regmap);
487 		}
488 
489 		/* Clear PWROFF, gate CLKOUT, everything else as-is */
490 		reg = snd_soc_component_read(component, WM8731_PWR) & 0xff7f;
491 		snd_soc_component_write(component, WM8731_PWR, reg | 0x0040);
492 		break;
493 	case SND_SOC_BIAS_OFF:
494 		clk_disable_unprepare(wm8731->mclk);
495 		snd_soc_component_write(component, WM8731_PWR, 0xffff);
496 		regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
497 				       wm8731->supplies);
498 		regcache_mark_dirty(wm8731->regmap);
499 		break;
500 	}
501 	return 0;
502 }
503 
504 static int wm8731_startup(struct snd_pcm_substream *substream,
505 	struct snd_soc_dai *dai)
506 {
507 	struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(dai->component);
508 
509 	if (wm8731->constraints)
510 		snd_pcm_hw_constraint_list(substream->runtime, 0,
511 					   SNDRV_PCM_HW_PARAM_RATE,
512 					   wm8731->constraints);
513 
514 	return 0;
515 }
516 
517 #define WM8731_RATES SNDRV_PCM_RATE_8000_96000
518 
519 #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
520 	SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
521 
522 static const struct snd_soc_dai_ops wm8731_dai_ops = {
523 	.startup	= wm8731_startup,
524 	.hw_params	= wm8731_hw_params,
525 	.mute_stream	= wm8731_mute,
526 	.set_sysclk	= wm8731_set_dai_sysclk,
527 	.set_fmt	= wm8731_set_dai_fmt,
528 	.no_capture_mute = 1,
529 };
530 
531 static struct snd_soc_dai_driver wm8731_dai = {
532 	.name = "wm8731-hifi",
533 	.playback = {
534 		.stream_name = "Playback",
535 		.channels_min = 1,
536 		.channels_max = 2,
537 		.rates = WM8731_RATES,
538 		.formats = WM8731_FORMATS,},
539 	.capture = {
540 		.stream_name = "Capture",
541 		.channels_min = 1,
542 		.channels_max = 2,
543 		.rates = WM8731_RATES,
544 		.formats = WM8731_FORMATS,},
545 	.ops = &wm8731_dai_ops,
546 	.symmetric_rate = 1,
547 };
548 
549 static const struct snd_soc_component_driver soc_component_dev_wm8731 = {
550 	.set_bias_level		= wm8731_set_bias_level,
551 	.controls		= wm8731_snd_controls,
552 	.num_controls		= ARRAY_SIZE(wm8731_snd_controls),
553 	.dapm_widgets		= wm8731_dapm_widgets,
554 	.num_dapm_widgets	= ARRAY_SIZE(wm8731_dapm_widgets),
555 	.dapm_routes		= wm8731_intercon,
556 	.num_dapm_routes	= ARRAY_SIZE(wm8731_intercon),
557 	.suspend_bias_off	= 1,
558 	.idle_bias_on		= 1,
559 	.use_pmdown_time	= 1,
560 	.endianness		= 1,
561 };
562 
563 int wm8731_init(struct device *dev, struct wm8731_priv *wm8731)
564 {
565 	int ret = 0, i;
566 
567 	wm8731->mclk = devm_clk_get(dev, "mclk");
568 	if (IS_ERR(wm8731->mclk)) {
569 		ret = PTR_ERR(wm8731->mclk);
570 		if (ret == -ENOENT) {
571 			wm8731->mclk = NULL;
572 			dev_warn(dev, "Assuming static MCLK\n");
573 		} else {
574 			dev_err(dev, "Failed to get MCLK: %d\n", ret);
575 			return ret;
576 		}
577 	}
578 
579 	mutex_init(&wm8731->lock);
580 
581 	for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
582 		wm8731->supplies[i].supply = wm8731_supply_names[i];
583 
584 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(wm8731->supplies),
585 				 wm8731->supplies);
586 	if (ret != 0) {
587 		dev_err(dev, "Failed to request supplies: %d\n", ret);
588 		return ret;
589 	}
590 
591 	ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
592 				    wm8731->supplies);
593 	if (ret != 0) {
594 		dev_err(dev, "Failed to enable supplies: %d\n", ret);
595 		return ret;
596 	}
597 
598 	ret = wm8731_reset(wm8731->regmap);
599 	if (ret < 0) {
600 		dev_err(dev, "Failed to issue reset: %d\n", ret);
601 		goto err_regulator_enable;
602 	}
603 
604 	/* Clear POWEROFF, keep everything else disabled */
605 	regmap_write(wm8731->regmap, WM8731_PWR, 0x7f);
606 
607 	/* Latch the update bits */
608 	regmap_update_bits(wm8731->regmap, WM8731_LOUT1V, 0x100, 0);
609 	regmap_update_bits(wm8731->regmap, WM8731_ROUT1V, 0x100, 0);
610 	regmap_update_bits(wm8731->regmap, WM8731_LINVOL, 0x100, 0);
611 	regmap_update_bits(wm8731->regmap, WM8731_RINVOL, 0x100, 0);
612 
613 	/* Disable bypass path by default */
614 	regmap_update_bits(wm8731->regmap, WM8731_APANA, 0x8, 0);
615 
616 	regcache_mark_dirty(wm8731->regmap);
617 
618 	ret = devm_snd_soc_register_component(dev,
619 			&soc_component_dev_wm8731, &wm8731_dai, 1);
620 	if (ret != 0) {
621 		dev_err(dev, "Failed to register CODEC: %d\n", ret);
622 		goto err_regulator_enable;
623 	}
624 
625 	return 0;
626 
627 err_regulator_enable:
628 	/* Regulators will be enabled by bias management */
629 	regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
630 
631 	return ret;
632 }
633 EXPORT_SYMBOL_GPL(wm8731_init);
634 
635 const struct regmap_config wm8731_regmap = {
636 	.reg_bits = 7,
637 	.val_bits = 9,
638 
639 	.max_register = WM8731_RESET,
640 	.volatile_reg = wm8731_volatile,
641 
642 	.cache_type = REGCACHE_MAPLE,
643 	.reg_defaults = wm8731_reg_defaults,
644 	.num_reg_defaults = ARRAY_SIZE(wm8731_reg_defaults),
645 };
646 EXPORT_SYMBOL_GPL(wm8731_regmap);
647 
648 MODULE_DESCRIPTION("ASoC WM8731 driver");
649 MODULE_AUTHOR("Richard Purdie");
650 MODULE_LICENSE("GPL");
651