xref: /openbmc/linux/sound/soc/codecs/pcm512x.c (revision c819e2cf)
1 /*
2  * Driver for the PCM512x CODECs
3  *
4  * Author:	Mark Brown <broonie@linaro.org>
5  *		Copyright 2014 Linaro Ltd
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  */
16 
17 
18 #include <linux/init.h>
19 #include <linux/module.h>
20 #include <linux/clk.h>
21 #include <linux/pm_runtime.h>
22 #include <linux/regmap.h>
23 #include <linux/regulator/consumer.h>
24 #include <sound/soc.h>
25 #include <sound/soc-dapm.h>
26 #include <sound/tlv.h>
27 
28 #include "pcm512x.h"
29 
30 #define PCM512x_NUM_SUPPLIES 3
31 static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = {
32 	"AVDD",
33 	"DVDD",
34 	"CPVDD",
35 };
36 
37 struct pcm512x_priv {
38 	struct regmap *regmap;
39 	struct clk *sclk;
40 	struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES];
41 	struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES];
42 };
43 
44 /*
45  * We can't use the same notifier block for more than one supply and
46  * there's no way I can see to get from a callback to the caller
47  * except container_of().
48  */
49 #define PCM512x_REGULATOR_EVENT(n) \
50 static int pcm512x_regulator_event_##n(struct notifier_block *nb, \
51 				      unsigned long event, void *data)    \
52 { \
53 	struct pcm512x_priv *pcm512x = container_of(nb, struct pcm512x_priv, \
54 						    supply_nb[n]); \
55 	if (event & REGULATOR_EVENT_DISABLE) { \
56 		regcache_mark_dirty(pcm512x->regmap);	\
57 		regcache_cache_only(pcm512x->regmap, true);	\
58 	} \
59 	return 0; \
60 }
61 
62 PCM512x_REGULATOR_EVENT(0)
63 PCM512x_REGULATOR_EVENT(1)
64 PCM512x_REGULATOR_EVENT(2)
65 
66 static const struct reg_default pcm512x_reg_defaults[] = {
67 	{ PCM512x_RESET,             0x00 },
68 	{ PCM512x_POWER,             0x00 },
69 	{ PCM512x_MUTE,              0x00 },
70 	{ PCM512x_DSP,               0x00 },
71 	{ PCM512x_PLL_REF,           0x00 },
72 	{ PCM512x_DAC_ROUTING,       0x11 },
73 	{ PCM512x_DSP_PROGRAM,       0x01 },
74 	{ PCM512x_CLKDET,            0x00 },
75 	{ PCM512x_AUTO_MUTE,         0x00 },
76 	{ PCM512x_ERROR_DETECT,      0x00 },
77 	{ PCM512x_DIGITAL_VOLUME_1,  0x00 },
78 	{ PCM512x_DIGITAL_VOLUME_2,  0x30 },
79 	{ PCM512x_DIGITAL_VOLUME_3,  0x30 },
80 	{ PCM512x_DIGITAL_MUTE_1,    0x22 },
81 	{ PCM512x_DIGITAL_MUTE_2,    0x00 },
82 	{ PCM512x_DIGITAL_MUTE_3,    0x07 },
83 	{ PCM512x_OUTPUT_AMPLITUDE,  0x00 },
84 	{ PCM512x_ANALOG_GAIN_CTRL,  0x00 },
85 	{ PCM512x_UNDERVOLTAGE_PROT, 0x00 },
86 	{ PCM512x_ANALOG_MUTE_CTRL,  0x00 },
87 	{ PCM512x_ANALOG_GAIN_BOOST, 0x00 },
88 	{ PCM512x_VCOM_CTRL_1,       0x00 },
89 	{ PCM512x_VCOM_CTRL_2,       0x01 },
90 };
91 
92 static bool pcm512x_readable(struct device *dev, unsigned int reg)
93 {
94 	switch (reg) {
95 	case PCM512x_RESET:
96 	case PCM512x_POWER:
97 	case PCM512x_MUTE:
98 	case PCM512x_PLL_EN:
99 	case PCM512x_SPI_MISO_FUNCTION:
100 	case PCM512x_DSP:
101 	case PCM512x_GPIO_EN:
102 	case PCM512x_BCLK_LRCLK_CFG:
103 	case PCM512x_DSP_GPIO_INPUT:
104 	case PCM512x_MASTER_MODE:
105 	case PCM512x_PLL_REF:
106 	case PCM512x_PLL_COEFF_0:
107 	case PCM512x_PLL_COEFF_1:
108 	case PCM512x_PLL_COEFF_2:
109 	case PCM512x_PLL_COEFF_3:
110 	case PCM512x_PLL_COEFF_4:
111 	case PCM512x_DSP_CLKDIV:
112 	case PCM512x_DAC_CLKDIV:
113 	case PCM512x_NCP_CLKDIV:
114 	case PCM512x_OSR_CLKDIV:
115 	case PCM512x_MASTER_CLKDIV_1:
116 	case PCM512x_MASTER_CLKDIV_2:
117 	case PCM512x_FS_SPEED_MODE:
118 	case PCM512x_IDAC_1:
119 	case PCM512x_IDAC_2:
120 	case PCM512x_ERROR_DETECT:
121 	case PCM512x_I2S_1:
122 	case PCM512x_I2S_2:
123 	case PCM512x_DAC_ROUTING:
124 	case PCM512x_DSP_PROGRAM:
125 	case PCM512x_CLKDET:
126 	case PCM512x_AUTO_MUTE:
127 	case PCM512x_DIGITAL_VOLUME_1:
128 	case PCM512x_DIGITAL_VOLUME_2:
129 	case PCM512x_DIGITAL_VOLUME_3:
130 	case PCM512x_DIGITAL_MUTE_1:
131 	case PCM512x_DIGITAL_MUTE_2:
132 	case PCM512x_DIGITAL_MUTE_3:
133 	case PCM512x_GPIO_OUTPUT_1:
134 	case PCM512x_GPIO_OUTPUT_2:
135 	case PCM512x_GPIO_OUTPUT_3:
136 	case PCM512x_GPIO_OUTPUT_4:
137 	case PCM512x_GPIO_OUTPUT_5:
138 	case PCM512x_GPIO_OUTPUT_6:
139 	case PCM512x_GPIO_CONTROL_1:
140 	case PCM512x_GPIO_CONTROL_2:
141 	case PCM512x_OVERFLOW:
142 	case PCM512x_RATE_DET_1:
143 	case PCM512x_RATE_DET_2:
144 	case PCM512x_RATE_DET_3:
145 	case PCM512x_RATE_DET_4:
146 	case PCM512x_ANALOG_MUTE_DET:
147 	case PCM512x_GPIN:
148 	case PCM512x_DIGITAL_MUTE_DET:
149 	case PCM512x_OUTPUT_AMPLITUDE:
150 	case PCM512x_ANALOG_GAIN_CTRL:
151 	case PCM512x_UNDERVOLTAGE_PROT:
152 	case PCM512x_ANALOG_MUTE_CTRL:
153 	case PCM512x_ANALOG_GAIN_BOOST:
154 	case PCM512x_VCOM_CTRL_1:
155 	case PCM512x_VCOM_CTRL_2:
156 	case PCM512x_CRAM_CTRL:
157 		return true;
158 	default:
159 		/* There are 256 raw register addresses */
160 		return reg < 0xff;
161 	}
162 }
163 
164 static bool pcm512x_volatile(struct device *dev, unsigned int reg)
165 {
166 	switch (reg) {
167 	case PCM512x_PLL_EN:
168 	case PCM512x_OVERFLOW:
169 	case PCM512x_RATE_DET_1:
170 	case PCM512x_RATE_DET_2:
171 	case PCM512x_RATE_DET_3:
172 	case PCM512x_RATE_DET_4:
173 	case PCM512x_ANALOG_MUTE_DET:
174 	case PCM512x_GPIN:
175 	case PCM512x_DIGITAL_MUTE_DET:
176 	case PCM512x_CRAM_CTRL:
177 		return true;
178 	default:
179 		/* There are 256 raw register addresses */
180 		return reg < 0xff;
181 	}
182 }
183 
184 static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1);
185 static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0);
186 static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0);
187 
188 static const char * const pcm512x_dsp_program_texts[] = {
189 	"FIR interpolation with de-emphasis",
190 	"Low latency IIR with de-emphasis",
191 	"High attenuation with de-emphasis",
192 	"Fixed process flow",
193 	"Ringing-less low latency FIR",
194 };
195 
196 static const unsigned int pcm512x_dsp_program_values[] = {
197 	1,
198 	2,
199 	3,
200 	5,
201 	7,
202 };
203 
204 static SOC_VALUE_ENUM_SINGLE_DECL(pcm512x_dsp_program,
205 				  PCM512x_DSP_PROGRAM, 0, 0x1f,
206 				  pcm512x_dsp_program_texts,
207 				  pcm512x_dsp_program_values);
208 
209 static const char * const pcm512x_clk_missing_text[] = {
210 	"1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s"
211 };
212 
213 static const struct soc_enum pcm512x_clk_missing =
214 	SOC_ENUM_SINGLE(PCM512x_CLKDET, 0,  8, pcm512x_clk_missing_text);
215 
216 static const char * const pcm512x_autom_text[] = {
217 	"21ms", "106ms", "213ms", "533ms", "1.07s", "2.13s", "5.33s", "10.66s"
218 };
219 
220 static const struct soc_enum pcm512x_autom_l =
221 	SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATML_SHIFT, 8,
222 			pcm512x_autom_text);
223 
224 static const struct soc_enum pcm512x_autom_r =
225 	SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATMR_SHIFT, 8,
226 			pcm512x_autom_text);
227 
228 static const char * const pcm512x_ramp_rate_text[] = {
229 	"1 sample/update", "2 samples/update", "4 samples/update",
230 	"Immediate"
231 };
232 
233 static const struct soc_enum pcm512x_vndf =
234 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDF_SHIFT, 4,
235 			pcm512x_ramp_rate_text);
236 
237 static const struct soc_enum pcm512x_vnuf =
238 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUF_SHIFT, 4,
239 			pcm512x_ramp_rate_text);
240 
241 static const struct soc_enum pcm512x_vedf =
242 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDF_SHIFT, 4,
243 			pcm512x_ramp_rate_text);
244 
245 static const char * const pcm512x_ramp_step_text[] = {
246 	"4dB/step", "2dB/step", "1dB/step", "0.5dB/step"
247 };
248 
249 static const struct soc_enum pcm512x_vnds =
250 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDS_SHIFT, 4,
251 			pcm512x_ramp_step_text);
252 
253 static const struct soc_enum pcm512x_vnus =
254 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUS_SHIFT, 4,
255 			pcm512x_ramp_step_text);
256 
257 static const struct soc_enum pcm512x_veds =
258 	SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4,
259 			pcm512x_ramp_step_text);
260 
261 static const struct snd_kcontrol_new pcm512x_controls[] = {
262 SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2,
263 		 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
264 SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
265 	       PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
266 SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
267 	       PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
268 SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT,
269 	   PCM512x_RQMR_SHIFT, 1, 1),
270 
271 SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1),
272 SOC_ENUM("DSP Program", pcm512x_dsp_program),
273 
274 SOC_ENUM("Clock Missing Period", pcm512x_clk_missing),
275 SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l),
276 SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r),
277 SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3,
278 	   PCM512x_ACTL_SHIFT, 1, 0),
279 SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT,
280 	   PCM512x_AMLR_SHIFT, 1, 0),
281 
282 SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf),
283 SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds),
284 SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf),
285 SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus),
286 SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf),
287 SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds),
288 };
289 
290 static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = {
291 SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
292 SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
293 
294 SND_SOC_DAPM_OUTPUT("OUTL"),
295 SND_SOC_DAPM_OUTPUT("OUTR"),
296 };
297 
298 static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = {
299 	{ "DACL", NULL, "Playback" },
300 	{ "DACR", NULL, "Playback" },
301 
302 	{ "OUTL", NULL, "DACL" },
303 	{ "OUTR", NULL, "DACR" },
304 };
305 
306 static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
307 				  enum snd_soc_bias_level level)
308 {
309 	struct pcm512x_priv *pcm512x = dev_get_drvdata(codec->dev);
310 	int ret;
311 
312 	switch (level) {
313 	case SND_SOC_BIAS_ON:
314 	case SND_SOC_BIAS_PREPARE:
315 		break;
316 
317 	case SND_SOC_BIAS_STANDBY:
318 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
319 					 PCM512x_RQST, 0);
320 		if (ret != 0) {
321 			dev_err(codec->dev, "Failed to remove standby: %d\n",
322 				ret);
323 			return ret;
324 		}
325 		break;
326 
327 	case SND_SOC_BIAS_OFF:
328 		ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
329 					 PCM512x_RQST, PCM512x_RQST);
330 		if (ret != 0) {
331 			dev_err(codec->dev, "Failed to request standby: %d\n",
332 				ret);
333 			return ret;
334 		}
335 		break;
336 	}
337 
338 	codec->dapm.bias_level = level;
339 
340 	return 0;
341 }
342 
343 static struct snd_soc_dai_driver pcm512x_dai = {
344 	.name = "pcm512x-hifi",
345 	.playback = {
346 		.stream_name = "Playback",
347 		.channels_min = 2,
348 		.channels_max = 2,
349 		.rates = SNDRV_PCM_RATE_8000_192000,
350 		.formats = SNDRV_PCM_FMTBIT_S16_LE |
351 			   SNDRV_PCM_FMTBIT_S24_LE |
352 			   SNDRV_PCM_FMTBIT_S32_LE
353 	},
354 };
355 
356 static struct snd_soc_codec_driver pcm512x_codec_driver = {
357 	.set_bias_level = pcm512x_set_bias_level,
358 	.idle_bias_off = true,
359 
360 	.controls = pcm512x_controls,
361 	.num_controls = ARRAY_SIZE(pcm512x_controls),
362 	.dapm_widgets = pcm512x_dapm_widgets,
363 	.num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets),
364 	.dapm_routes = pcm512x_dapm_routes,
365 	.num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes),
366 };
367 
368 static const struct regmap_range_cfg pcm512x_range = {
369 	.name = "Pages", .range_min = PCM512x_VIRT_BASE,
370 	.range_max = PCM512x_MAX_REGISTER,
371 	.selector_reg = PCM512x_PAGE,
372 	.selector_mask = 0xff,
373 	.window_start = 0, .window_len = 0x100,
374 };
375 
376 const struct regmap_config pcm512x_regmap = {
377 	.reg_bits = 8,
378 	.val_bits = 8,
379 
380 	.readable_reg = pcm512x_readable,
381 	.volatile_reg = pcm512x_volatile,
382 
383 	.ranges = &pcm512x_range,
384 	.num_ranges = 1,
385 
386 	.max_register = PCM512x_MAX_REGISTER,
387 	.reg_defaults = pcm512x_reg_defaults,
388 	.num_reg_defaults = ARRAY_SIZE(pcm512x_reg_defaults),
389 	.cache_type = REGCACHE_RBTREE,
390 };
391 EXPORT_SYMBOL_GPL(pcm512x_regmap);
392 
393 int pcm512x_probe(struct device *dev, struct regmap *regmap)
394 {
395 	struct pcm512x_priv *pcm512x;
396 	int i, ret;
397 
398 	pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL);
399 	if (!pcm512x)
400 		return -ENOMEM;
401 
402 	dev_set_drvdata(dev, pcm512x);
403 	pcm512x->regmap = regmap;
404 
405 	for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++)
406 		pcm512x->supplies[i].supply = pcm512x_supply_names[i];
407 
408 	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies),
409 				      pcm512x->supplies);
410 	if (ret != 0) {
411 		dev_err(dev, "Failed to get supplies: %d\n", ret);
412 		return ret;
413 	}
414 
415 	pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0;
416 	pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1;
417 	pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2;
418 
419 	for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) {
420 		ret = regulator_register_notifier(pcm512x->supplies[i].consumer,
421 						  &pcm512x->supply_nb[i]);
422 		if (ret != 0) {
423 			dev_err(dev,
424 				"Failed to register regulator notifier: %d\n",
425 				ret);
426 		}
427 	}
428 
429 	ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
430 				    pcm512x->supplies);
431 	if (ret != 0) {
432 		dev_err(dev, "Failed to enable supplies: %d\n", ret);
433 		return ret;
434 	}
435 
436 	/* Reset the device, verifying I/O in the process for I2C */
437 	ret = regmap_write(regmap, PCM512x_RESET,
438 			   PCM512x_RSTM | PCM512x_RSTR);
439 	if (ret != 0) {
440 		dev_err(dev, "Failed to reset device: %d\n", ret);
441 		goto err;
442 	}
443 
444 	ret = regmap_write(regmap, PCM512x_RESET, 0);
445 	if (ret != 0) {
446 		dev_err(dev, "Failed to reset device: %d\n", ret);
447 		goto err;
448 	}
449 
450 	pcm512x->sclk = devm_clk_get(dev, NULL);
451 	if (IS_ERR(pcm512x->sclk)) {
452 		if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER)
453 			return -EPROBE_DEFER;
454 
455 		dev_info(dev, "No SCLK, using BCLK: %ld\n",
456 			 PTR_ERR(pcm512x->sclk));
457 
458 		/* Disable reporting of missing SCLK as an error */
459 		regmap_update_bits(regmap, PCM512x_ERROR_DETECT,
460 				   PCM512x_IDCH, PCM512x_IDCH);
461 
462 		/* Switch PLL input to BCLK */
463 		regmap_update_bits(regmap, PCM512x_PLL_REF,
464 				   PCM512x_SREF, PCM512x_SREF);
465 	} else {
466 		ret = clk_prepare_enable(pcm512x->sclk);
467 		if (ret != 0) {
468 			dev_err(dev, "Failed to enable SCLK: %d\n", ret);
469 			return ret;
470 		}
471 	}
472 
473 	/* Default to standby mode */
474 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
475 				 PCM512x_RQST, PCM512x_RQST);
476 	if (ret != 0) {
477 		dev_err(dev, "Failed to request standby: %d\n",
478 			ret);
479 		goto err_clk;
480 	}
481 
482 	pm_runtime_set_active(dev);
483 	pm_runtime_enable(dev);
484 	pm_runtime_idle(dev);
485 
486 	ret = snd_soc_register_codec(dev, &pcm512x_codec_driver,
487 				    &pcm512x_dai, 1);
488 	if (ret != 0) {
489 		dev_err(dev, "Failed to register CODEC: %d\n", ret);
490 		goto err_pm;
491 	}
492 
493 	return 0;
494 
495 err_pm:
496 	pm_runtime_disable(dev);
497 err_clk:
498 	if (!IS_ERR(pcm512x->sclk))
499 		clk_disable_unprepare(pcm512x->sclk);
500 err:
501 	regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
502 				     pcm512x->supplies);
503 	return ret;
504 }
505 EXPORT_SYMBOL_GPL(pcm512x_probe);
506 
507 void pcm512x_remove(struct device *dev)
508 {
509 	struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
510 
511 	snd_soc_unregister_codec(dev);
512 	pm_runtime_disable(dev);
513 	if (!IS_ERR(pcm512x->sclk))
514 		clk_disable_unprepare(pcm512x->sclk);
515 	regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
516 			       pcm512x->supplies);
517 }
518 EXPORT_SYMBOL_GPL(pcm512x_remove);
519 
520 #ifdef CONFIG_PM
521 static int pcm512x_suspend(struct device *dev)
522 {
523 	struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
524 	int ret;
525 
526 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
527 				 PCM512x_RQPD, PCM512x_RQPD);
528 	if (ret != 0) {
529 		dev_err(dev, "Failed to request power down: %d\n", ret);
530 		return ret;
531 	}
532 
533 	ret = regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
534 				     pcm512x->supplies);
535 	if (ret != 0) {
536 		dev_err(dev, "Failed to disable supplies: %d\n", ret);
537 		return ret;
538 	}
539 
540 	if (!IS_ERR(pcm512x->sclk))
541 		clk_disable_unprepare(pcm512x->sclk);
542 
543 	return 0;
544 }
545 
546 static int pcm512x_resume(struct device *dev)
547 {
548 	struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
549 	int ret;
550 
551 	if (!IS_ERR(pcm512x->sclk)) {
552 		ret = clk_prepare_enable(pcm512x->sclk);
553 		if (ret != 0) {
554 			dev_err(dev, "Failed to enable SCLK: %d\n", ret);
555 			return ret;
556 		}
557 	}
558 
559 	ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
560 				    pcm512x->supplies);
561 	if (ret != 0) {
562 		dev_err(dev, "Failed to enable supplies: %d\n", ret);
563 		return ret;
564 	}
565 
566 	regcache_cache_only(pcm512x->regmap, false);
567 	ret = regcache_sync(pcm512x->regmap);
568 	if (ret != 0) {
569 		dev_err(dev, "Failed to sync cache: %d\n", ret);
570 		return ret;
571 	}
572 
573 	ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
574 				 PCM512x_RQPD, 0);
575 	if (ret != 0) {
576 		dev_err(dev, "Failed to remove power down: %d\n", ret);
577 		return ret;
578 	}
579 
580 	return 0;
581 }
582 #endif
583 
584 const struct dev_pm_ops pcm512x_pm_ops = {
585 	SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL)
586 };
587 EXPORT_SYMBOL_GPL(pcm512x_pm_ops);
588 
589 MODULE_DESCRIPTION("ASoC PCM512x codec driver");
590 MODULE_AUTHOR("Mark Brown <broonie@linaro.org>");
591 MODULE_LICENSE("GPL v2");
592