blob: 3a0bbb6ab242ff4c1cd325948f06f6788d0a2a59 [file] [log] [blame]
Mark Brown5a3af122014-02-06 12:03:27 +00001/*
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/i2c.h>
22#include <linux/pm_runtime.h>
23#include <linux/regmap.h>
24#include <linux/regulator/consumer.h>
25#include <linux/spi/spi.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/tlv.h>
29
30#include "pcm512x.h"
31
32#define PCM512x_NUM_SUPPLIES 3
Mark Brown06d0ffc2014-02-06 14:33:52 +000033static const char * const pcm512x_supply_names[PCM512x_NUM_SUPPLIES] = {
Mark Brown5a3af122014-02-06 12:03:27 +000034 "AVDD",
35 "DVDD",
36 "CPVDD",
37};
38
39struct pcm512x_priv {
40 struct regmap *regmap;
41 struct clk *sclk;
42 struct regulator_bulk_data supplies[PCM512x_NUM_SUPPLIES];
43 struct notifier_block supply_nb[PCM512x_NUM_SUPPLIES];
44};
45
46/*
47 * We can't use the same notifier block for more than one supply and
48 * there's no way I can see to get from a callback to the caller
49 * except container_of().
50 */
51#define PCM512x_REGULATOR_EVENT(n) \
52static int pcm512x_regulator_event_##n(struct notifier_block *nb, \
53 unsigned long event, void *data) \
54{ \
55 struct pcm512x_priv *pcm512x = container_of(nb, struct pcm512x_priv, \
56 supply_nb[n]); \
57 if (event & REGULATOR_EVENT_DISABLE) { \
58 regcache_mark_dirty(pcm512x->regmap); \
59 regcache_cache_only(pcm512x->regmap, true); \
60 } \
61 return 0; \
62}
63
64PCM512x_REGULATOR_EVENT(0)
65PCM512x_REGULATOR_EVENT(1)
66PCM512x_REGULATOR_EVENT(2)
67
68static const struct reg_default pcm512x_reg_defaults[] = {
Mark Brown806d6462014-02-07 19:08:11 +000069 { PCM512x_RESET, 0x00 },
70 { PCM512x_POWER, 0x00 },
71 { PCM512x_MUTE, 0x00 },
72 { PCM512x_DSP, 0x00 },
73 { PCM512x_PLL_REF, 0x00 },
74 { PCM512x_DAC_ROUTING, 0x11 },
75 { PCM512x_DSP_PROGRAM, 0x01 },
76 { PCM512x_CLKDET, 0x00 },
77 { PCM512x_AUTO_MUTE, 0x00 },
78 { PCM512x_ERROR_DETECT, 0x00 },
79 { PCM512x_DIGITAL_VOLUME_1, 0x00 },
80 { PCM512x_DIGITAL_VOLUME_2, 0x30 },
81 { PCM512x_DIGITAL_VOLUME_3, 0x30 },
82 { PCM512x_DIGITAL_MUTE_1, 0x22 },
83 { PCM512x_DIGITAL_MUTE_2, 0x00 },
84 { PCM512x_DIGITAL_MUTE_3, 0x07 },
85 { PCM512x_OUTPUT_AMPLITUDE, 0x00 },
86 { PCM512x_ANALOG_GAIN_CTRL, 0x00 },
87 { PCM512x_UNDERVOLTAGE_PROT, 0x00 },
88 { PCM512x_ANALOG_MUTE_CTRL, 0x00 },
89 { PCM512x_ANALOG_GAIN_BOOST, 0x00 },
90 { PCM512x_VCOM_CTRL_1, 0x00 },
91 { PCM512x_VCOM_CTRL_2, 0x01 },
Mark Brown5a3af122014-02-06 12:03:27 +000092};
93
94static bool pcm512x_readable(struct device *dev, unsigned int reg)
95{
96 switch (reg) {
97 case PCM512x_RESET:
98 case PCM512x_POWER:
99 case PCM512x_MUTE:
100 case PCM512x_PLL_EN:
101 case PCM512x_SPI_MISO_FUNCTION:
102 case PCM512x_DSP:
103 case PCM512x_GPIO_EN:
104 case PCM512x_BCLK_LRCLK_CFG:
105 case PCM512x_DSP_GPIO_INPUT:
106 case PCM512x_MASTER_MODE:
107 case PCM512x_PLL_REF:
108 case PCM512x_PLL_COEFF_0:
109 case PCM512x_PLL_COEFF_1:
110 case PCM512x_PLL_COEFF_2:
111 case PCM512x_PLL_COEFF_3:
112 case PCM512x_PLL_COEFF_4:
113 case PCM512x_DSP_CLKDIV:
114 case PCM512x_DAC_CLKDIV:
115 case PCM512x_NCP_CLKDIV:
116 case PCM512x_OSR_CLKDIV:
117 case PCM512x_MASTER_CLKDIV_1:
118 case PCM512x_MASTER_CLKDIV_2:
119 case PCM512x_FS_SPEED_MODE:
120 case PCM512x_IDAC_1:
121 case PCM512x_IDAC_2:
122 case PCM512x_ERROR_DETECT:
123 case PCM512x_I2S_1:
124 case PCM512x_I2S_2:
125 case PCM512x_DAC_ROUTING:
126 case PCM512x_DSP_PROGRAM:
127 case PCM512x_CLKDET:
128 case PCM512x_AUTO_MUTE:
129 case PCM512x_DIGITAL_VOLUME_1:
130 case PCM512x_DIGITAL_VOLUME_2:
131 case PCM512x_DIGITAL_VOLUME_3:
132 case PCM512x_DIGITAL_MUTE_1:
133 case PCM512x_DIGITAL_MUTE_2:
134 case PCM512x_DIGITAL_MUTE_3:
135 case PCM512x_GPIO_OUTPUT_1:
136 case PCM512x_GPIO_OUTPUT_2:
137 case PCM512x_GPIO_OUTPUT_3:
138 case PCM512x_GPIO_OUTPUT_4:
139 case PCM512x_GPIO_OUTPUT_5:
140 case PCM512x_GPIO_OUTPUT_6:
141 case PCM512x_GPIO_CONTROL_1:
142 case PCM512x_GPIO_CONTROL_2:
143 case PCM512x_OVERFLOW:
144 case PCM512x_RATE_DET_1:
145 case PCM512x_RATE_DET_2:
146 case PCM512x_RATE_DET_3:
147 case PCM512x_RATE_DET_4:
148 case PCM512x_ANALOG_MUTE_DET:
149 case PCM512x_GPIN:
150 case PCM512x_DIGITAL_MUTE_DET:
Mark Brown806d6462014-02-07 19:08:11 +0000151 case PCM512x_OUTPUT_AMPLITUDE:
152 case PCM512x_ANALOG_GAIN_CTRL:
153 case PCM512x_UNDERVOLTAGE_PROT:
154 case PCM512x_ANALOG_MUTE_CTRL:
155 case PCM512x_ANALOG_GAIN_BOOST:
156 case PCM512x_VCOM_CTRL_1:
157 case PCM512x_VCOM_CTRL_2:
158 case PCM512x_CRAM_CTRL:
Mark Brown5a3af122014-02-06 12:03:27 +0000159 return true;
160 default:
Mark Brown806d6462014-02-07 19:08:11 +0000161 /* There are 256 raw register addresses */
162 return reg < 0xff;
Mark Brown5a3af122014-02-06 12:03:27 +0000163 }
164}
165
166static bool pcm512x_volatile(struct device *dev, unsigned int reg)
167{
168 switch (reg) {
169 case PCM512x_PLL_EN:
170 case PCM512x_OVERFLOW:
171 case PCM512x_RATE_DET_1:
172 case PCM512x_RATE_DET_2:
173 case PCM512x_RATE_DET_3:
174 case PCM512x_RATE_DET_4:
175 case PCM512x_ANALOG_MUTE_DET:
176 case PCM512x_GPIN:
177 case PCM512x_DIGITAL_MUTE_DET:
Mark Brown806d6462014-02-07 19:08:11 +0000178 case PCM512x_CRAM_CTRL:
Mark Brown5a3af122014-02-06 12:03:27 +0000179 return true;
180 default:
Mark Brown806d6462014-02-07 19:08:11 +0000181 /* There are 256 raw register addresses */
182 return reg < 0xff;
Mark Brown5a3af122014-02-06 12:03:27 +0000183 }
184}
185
186static const DECLARE_TLV_DB_SCALE(digital_tlv, -10350, 50, 1);
Mark Brown5be2fc22014-02-07 19:16:56 +0000187static const DECLARE_TLV_DB_SCALE(analog_tlv, -600, 600, 0);
188static const DECLARE_TLV_DB_SCALE(boost_tlv, 0, 80, 0);
Mark Brown5a3af122014-02-06 12:03:27 +0000189
Mark Brown06d0ffc2014-02-06 14:33:52 +0000190static const char * const pcm512x_dsp_program_texts[] = {
Mark Brown5a3af122014-02-06 12:03:27 +0000191 "FIR interpolation with de-emphasis",
192 "Low latency IIR with de-emphasis",
193 "Fixed process flow",
194 "High attenuation with de-emphasis",
195 "Ringing-less low latency FIR",
196};
197
198static const unsigned int pcm512x_dsp_program_values[] = {
199 1,
200 2,
201 3,
202 5,
203 7,
204};
205
206static const SOC_VALUE_ENUM_SINGLE_DECL(pcm512x_dsp_program,
207 PCM512x_DSP_PROGRAM, 0, 0x1f,
208 pcm512x_dsp_program_texts,
209 pcm512x_dsp_program_values);
210
Mark Brown06d0ffc2014-02-06 14:33:52 +0000211static const char * const pcm512x_clk_missing_text[] = {
Mark Brown5a3af122014-02-06 12:03:27 +0000212 "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s"
213};
214
215static const struct soc_enum pcm512x_clk_missing =
216 SOC_ENUM_SINGLE(PCM512x_CLKDET, 0, 8, pcm512x_clk_missing_text);
217
Mark Brown06d0ffc2014-02-06 14:33:52 +0000218static const char * const pcm512x_autom_text[] = {
Mark Brown5a3af122014-02-06 12:03:27 +0000219 "21ms", "106ms", "213ms", "533ms", "1.07s", "2.13s", "5.33s", "10.66s"
220};
221
222static const struct soc_enum pcm512x_autom_l =
223 SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATML_SHIFT, 8,
224 pcm512x_autom_text);
225
226static const struct soc_enum pcm512x_autom_r =
227 SOC_ENUM_SINGLE(PCM512x_AUTO_MUTE, PCM512x_ATMR_SHIFT, 8,
228 pcm512x_autom_text);
229
Mark Brown06d0ffc2014-02-06 14:33:52 +0000230static const char * const pcm512x_ramp_rate_text[] = {
Mark Brown5a3af122014-02-06 12:03:27 +0000231 "1 sample/update", "2 samples/update", "4 samples/update",
232 "Immediate"
233};
234
235static const struct soc_enum pcm512x_vndf =
236 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDF_SHIFT, 4,
237 pcm512x_ramp_rate_text);
238
239static const struct soc_enum pcm512x_vnuf =
240 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUF_SHIFT, 4,
241 pcm512x_ramp_rate_text);
242
243static const struct soc_enum pcm512x_vedf =
244 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDF_SHIFT, 4,
245 pcm512x_ramp_rate_text);
246
Mark Brown06d0ffc2014-02-06 14:33:52 +0000247static const char * const pcm512x_ramp_step_text[] = {
Mark Brown5a3af122014-02-06 12:03:27 +0000248 "4dB/step", "2dB/step", "1dB/step", "0.5dB/step"
249};
250
251static const struct soc_enum pcm512x_vnds =
252 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNDS_SHIFT, 4,
253 pcm512x_ramp_step_text);
254
255static const struct soc_enum pcm512x_vnus =
256 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_1, PCM512x_VNUS_SHIFT, 4,
257 pcm512x_ramp_step_text);
258
259static const struct soc_enum pcm512x_veds =
260 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4,
261 pcm512x_ramp_step_text);
262
263static const struct snd_kcontrol_new pcm512x_controls[] = {
264SOC_DOUBLE_R_TLV("Playback Digital Volume", PCM512x_DIGITAL_VOLUME_2,
265 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
Mark Brown5be2fc22014-02-07 19:16:56 +0000266SOC_DOUBLE_TLV("Playback Volume", PCM512x_ANALOG_GAIN_CTRL,
267 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
268SOC_DOUBLE_TLV("Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
269 PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
Mark Brown5a3af122014-02-06 12:03:27 +0000270SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT,
271 PCM512x_RQMR_SHIFT, 1, 1),
272
273SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1),
274SOC_VALUE_ENUM("DSP Program", pcm512x_dsp_program),
275
276SOC_ENUM("Clock Missing Period", pcm512x_clk_missing),
277SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l),
278SOC_ENUM("Auto Mute Time Right", pcm512x_autom_r),
279SOC_SINGLE("Auto Mute Mono Switch", PCM512x_DIGITAL_MUTE_3,
280 PCM512x_ACTL_SHIFT, 1, 0),
281SOC_DOUBLE("Auto Mute Switch", PCM512x_DIGITAL_MUTE_3, PCM512x_AMLE_SHIFT,
282 PCM512x_AMLR_SHIFT, 1, 0),
283
284SOC_ENUM("Volume Ramp Down Rate", pcm512x_vndf),
285SOC_ENUM("Volume Ramp Down Step", pcm512x_vnds),
286SOC_ENUM("Volume Ramp Up Rate", pcm512x_vnuf),
287SOC_ENUM("Volume Ramp Up Step", pcm512x_vnus),
288SOC_ENUM("Volume Ramp Down Emergency Rate", pcm512x_vedf),
289SOC_ENUM("Volume Ramp Down Emergency Step", pcm512x_veds),
290};
291
292static const struct snd_soc_dapm_widget pcm512x_dapm_widgets[] = {
293SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
294SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
295
296SND_SOC_DAPM_OUTPUT("OUTL"),
297SND_SOC_DAPM_OUTPUT("OUTR"),
298};
299
300static const struct snd_soc_dapm_route pcm512x_dapm_routes[] = {
301 { "DACL", NULL, "Playback" },
302 { "DACR", NULL, "Playback" },
303
304 { "OUTL", NULL, "DACL" },
305 { "OUTR", NULL, "DACR" },
306};
307
308static int pcm512x_set_bias_level(struct snd_soc_codec *codec,
309 enum snd_soc_bias_level level)
310{
311 struct pcm512x_priv *pcm512x = dev_get_drvdata(codec->dev);
312 int ret;
313
314 switch (level) {
315 case SND_SOC_BIAS_ON:
316 case SND_SOC_BIAS_PREPARE:
317 break;
318
319 case SND_SOC_BIAS_STANDBY:
320 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
321 PCM512x_RQST, 0);
322 if (ret != 0) {
323 dev_err(codec->dev, "Failed to remove standby: %d\n",
324 ret);
325 return ret;
326 }
327 break;
328
329 case SND_SOC_BIAS_OFF:
330 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
331 PCM512x_RQST, PCM512x_RQST);
332 if (ret != 0) {
333 dev_err(codec->dev, "Failed to request standby: %d\n",
334 ret);
335 return ret;
336 }
337 break;
338 }
339
340 codec->dapm.bias_level = level;
341
342 return 0;
343}
344
345static struct snd_soc_dai_driver pcm512x_dai = {
346 .name = "pcm512x-hifi",
347 .playback = {
348 .stream_name = "Playback",
349 .channels_min = 2,
350 .channels_max = 2,
351 .rates = SNDRV_PCM_RATE_8000_192000,
352 .formats = SNDRV_PCM_FMTBIT_S16_LE |
353 SNDRV_PCM_FMTBIT_S24_LE |
354 SNDRV_PCM_FMTBIT_S32_LE
355 },
356};
357
358static struct snd_soc_codec_driver pcm512x_codec_driver = {
359 .set_bias_level = pcm512x_set_bias_level,
360 .idle_bias_off = true,
361
362 .controls = pcm512x_controls,
363 .num_controls = ARRAY_SIZE(pcm512x_controls),
364 .dapm_widgets = pcm512x_dapm_widgets,
365 .num_dapm_widgets = ARRAY_SIZE(pcm512x_dapm_widgets),
366 .dapm_routes = pcm512x_dapm_routes,
367 .num_dapm_routes = ARRAY_SIZE(pcm512x_dapm_routes),
368};
369
Mark Brown806d6462014-02-07 19:08:11 +0000370static const struct regmap_range_cfg pcm512x_range = {
371 .name = "Pages", .range_min = PCM512x_VIRT_BASE,
372 .range_max = PCM512x_MAX_REGISTER,
373 .selector_reg = PCM512x_PAGE,
374 .selector_mask = 0xff,
375 .window_start = 0, .window_len = 0x100,
376};
377
Mark Brown5a3af122014-02-06 12:03:27 +0000378static const struct regmap_config pcm512x_regmap = {
379 .reg_bits = 8,
380 .val_bits = 8,
381
382 .readable_reg = pcm512x_readable,
383 .volatile_reg = pcm512x_volatile,
384
Mark Brown806d6462014-02-07 19:08:11 +0000385 .ranges = &pcm512x_range,
386 .num_ranges = 1,
387
Mark Brown5a3af122014-02-06 12:03:27 +0000388 .max_register = PCM512x_MAX_REGISTER,
389 .reg_defaults = pcm512x_reg_defaults,
390 .num_reg_defaults = ARRAY_SIZE(pcm512x_reg_defaults),
391 .cache_type = REGCACHE_RBTREE,
392};
393
394static const struct of_device_id pcm512x_of_match[] = {
395 { .compatible = "ti,pcm5121", },
396 { .compatible = "ti,pcm5122", },
397 { }
398};
399MODULE_DEVICE_TABLE(of, pcm512x_of_match);
400
401static int pcm512x_probe(struct device *dev, struct regmap *regmap)
402{
403 struct pcm512x_priv *pcm512x;
404 int i, ret;
405
406 pcm512x = devm_kzalloc(dev, sizeof(struct pcm512x_priv), GFP_KERNEL);
407 if (!pcm512x)
408 return -ENOMEM;
409
410 dev_set_drvdata(dev, pcm512x);
411 pcm512x->regmap = regmap;
412
413 for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++)
414 pcm512x->supplies[i].supply = pcm512x_supply_names[i];
415
416 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(pcm512x->supplies),
417 pcm512x->supplies);
418 if (ret != 0) {
419 dev_err(dev, "Failed to get supplies: %d\n", ret);
420 return ret;
421 }
422
423 pcm512x->supply_nb[0].notifier_call = pcm512x_regulator_event_0;
424 pcm512x->supply_nb[1].notifier_call = pcm512x_regulator_event_1;
425 pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2;
426
427 for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) {
428 ret = regulator_register_notifier(pcm512x->supplies[i].consumer,
429 &pcm512x->supply_nb[i]);
430 if (ret != 0) {
431 dev_err(dev,
432 "Failed to register regulator notifier: %d\n",
433 ret);
434 }
435 }
436
437 ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
438 pcm512x->supplies);
439 if (ret != 0) {
440 dev_err(dev, "Failed to enable supplies: %d\n", ret);
441 return ret;
442 }
443
444 /* Reset the device, verifying I/O in the process for I2C */
445 ret = regmap_write(regmap, PCM512x_RESET,
446 PCM512x_RSTM | PCM512x_RSTR);
447 if (ret != 0) {
448 dev_err(dev, "Failed to reset device: %d\n", ret);
449 goto err;
450 }
451
452 ret = regmap_write(regmap, PCM512x_RESET, 0);
453 if (ret != 0) {
454 dev_err(dev, "Failed to reset device: %d\n", ret);
455 goto err;
456 }
457
458 pcm512x->sclk = devm_clk_get(dev, NULL);
459 if (IS_ERR(pcm512x->sclk)) {
460 if (PTR_ERR(pcm512x->sclk) == -EPROBE_DEFER)
461 return -EPROBE_DEFER;
462
463 dev_info(dev, "No SCLK, using BCLK: %ld\n",
464 PTR_ERR(pcm512x->sclk));
465
466 /* Disable reporting of missing SCLK as an error */
467 regmap_update_bits(regmap, PCM512x_ERROR_DETECT,
468 PCM512x_IDCH, PCM512x_IDCH);
469
470 /* Switch PLL input to BCLK */
471 regmap_update_bits(regmap, PCM512x_PLL_REF,
472 PCM512x_SREF, PCM512x_SREF);
473 } else {
474 ret = clk_prepare_enable(pcm512x->sclk);
475 if (ret != 0) {
476 dev_err(dev, "Failed to enable SCLK: %d\n", ret);
477 return ret;
478 }
479 }
480
481 /* Default to standby mode */
482 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
483 PCM512x_RQST, PCM512x_RQST);
484 if (ret != 0) {
485 dev_err(dev, "Failed to request standby: %d\n",
486 ret);
487 goto err_clk;
488 }
489
490 pm_runtime_set_active(dev);
491 pm_runtime_enable(dev);
492 pm_runtime_idle(dev);
493
494 ret = snd_soc_register_codec(dev, &pcm512x_codec_driver,
495 &pcm512x_dai, 1);
496 if (ret != 0) {
497 dev_err(dev, "Failed to register CODEC: %d\n", ret);
498 goto err_pm;
499 }
500
501 return 0;
502
503err_pm:
504 pm_runtime_disable(dev);
505err_clk:
506 if (!IS_ERR(pcm512x->sclk))
507 clk_disable_unprepare(pcm512x->sclk);
508err:
509 regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
510 pcm512x->supplies);
511 return ret;
512}
513
514static void pcm512x_remove(struct device *dev)
515{
516 struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
517
518 snd_soc_unregister_codec(dev);
519 pm_runtime_disable(dev);
520 if (!IS_ERR(pcm512x->sclk))
521 clk_disable_unprepare(pcm512x->sclk);
522 regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
523 pcm512x->supplies);
524}
525
526static int pcm512x_suspend(struct device *dev)
527{
528 struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
529 int ret;
530
531 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
532 PCM512x_RQPD, PCM512x_RQPD);
533 if (ret != 0) {
534 dev_err(dev, "Failed to request power down: %d\n", ret);
535 return ret;
536 }
537
538 ret = regulator_bulk_disable(ARRAY_SIZE(pcm512x->supplies),
539 pcm512x->supplies);
540 if (ret != 0) {
541 dev_err(dev, "Failed to disable supplies: %d\n", ret);
542 return ret;
543 }
544
545 if (!IS_ERR(pcm512x->sclk))
546 clk_disable_unprepare(pcm512x->sclk);
547
548 return 0;
549}
550
551static int pcm512x_resume(struct device *dev)
552{
553 struct pcm512x_priv *pcm512x = dev_get_drvdata(dev);
554 int ret;
555
556 if (!IS_ERR(pcm512x->sclk)) {
557 ret = clk_prepare_enable(pcm512x->sclk);
558 if (ret != 0) {
559 dev_err(dev, "Failed to enable SCLK: %d\n", ret);
560 return ret;
561 }
562 }
563
564 ret = regulator_bulk_enable(ARRAY_SIZE(pcm512x->supplies),
565 pcm512x->supplies);
566 if (ret != 0) {
567 dev_err(dev, "Failed to enable supplies: %d\n", ret);
568 return ret;
569 }
570
571 regcache_cache_only(pcm512x->regmap, false);
572 ret = regcache_sync(pcm512x->regmap);
573 if (ret != 0) {
574 dev_err(dev, "Failed to sync cache: %d\n", ret);
575 return ret;
576 }
577
578 ret = regmap_update_bits(pcm512x->regmap, PCM512x_POWER,
579 PCM512x_RQPD, 0);
580 if (ret != 0) {
581 dev_err(dev, "Failed to remove power down: %d\n", ret);
582 return ret;
583 }
584
585 return 0;
586}
587
588static const struct dev_pm_ops pcm512x_pm_ops = {
589 SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL)
590};
591
592#if IS_ENABLED(CONFIG_I2C)
593static int pcm512x_i2c_probe(struct i2c_client *i2c,
594 const struct i2c_device_id *id)
595{
596 struct regmap *regmap;
597
598 regmap = devm_regmap_init_i2c(i2c, &pcm512x_regmap);
599 if (IS_ERR(regmap))
600 return PTR_ERR(regmap);
601
602 return pcm512x_probe(&i2c->dev, regmap);
603}
604
605static int pcm512x_i2c_remove(struct i2c_client *i2c)
606{
607 pcm512x_remove(&i2c->dev);
608 return 0;
609}
610
611static const struct i2c_device_id pcm512x_i2c_id[] = {
612 { "pcm5121", },
613 { "pcm5122", },
614 { }
615};
616MODULE_DEVICE_TABLE(i2c, pcm512x_i2c_id);
617
618static struct i2c_driver pcm512x_i2c_driver = {
619 .probe = pcm512x_i2c_probe,
620 .remove = pcm512x_i2c_remove,
621 .id_table = pcm512x_i2c_id,
622 .driver = {
623 .name = "pcm512x",
624 .owner = THIS_MODULE,
625 .of_match_table = pcm512x_of_match,
626 .pm = &pcm512x_pm_ops,
627 },
628};
629#endif
630
631#if defined(CONFIG_SPI_MASTER)
632static int pcm512x_spi_probe(struct spi_device *spi)
633{
634 struct regmap *regmap;
635 int ret;
636
637 regmap = devm_regmap_init_spi(spi, &pcm512x_regmap);
638 if (IS_ERR(regmap)) {
639 ret = PTR_ERR(regmap);
640 return ret;
641 }
642
643 return pcm512x_probe(&spi->dev, regmap);
644}
645
646static int pcm512x_spi_remove(struct spi_device *spi)
647{
648 pcm512x_remove(&spi->dev);
649 return 0;
650}
651
652static const struct spi_device_id pcm512x_spi_id[] = {
653 { "pcm5121", },
654 { "pcm5122", },
655 { },
656};
657MODULE_DEVICE_TABLE(spi, pcm512x_spi_id);
658
659static struct spi_driver pcm512x_spi_driver = {
660 .probe = pcm512x_spi_probe,
661 .remove = pcm512x_spi_remove,
662 .id_table = pcm512x_spi_id,
663 .driver = {
664 .name = "pcm512x",
665 .owner = THIS_MODULE,
666 .of_match_table = pcm512x_of_match,
667 .pm = &pcm512x_pm_ops,
668 },
669};
670#endif
671
672static int __init pcm512x_modinit(void)
673{
674 int ret = 0;
675
676#if IS_ENABLED(CONFIG_I2C)
677 ret = i2c_add_driver(&pcm512x_i2c_driver);
678 if (ret) {
679 printk(KERN_ERR "Failed to register pcm512x I2C driver: %d\n",
680 ret);
681 }
682#endif
683#if defined(CONFIG_SPI_MASTER)
684 ret = spi_register_driver(&pcm512x_spi_driver);
685 if (ret != 0) {
686 printk(KERN_ERR "Failed to register pcm512x SPI driver: %d\n",
687 ret);
688 }
689#endif
690 return ret;
691}
692module_init(pcm512x_modinit);
693
694static void __exit pcm512x_exit(void)
695{
696#if IS_ENABLED(CONFIG_I2C)
697 i2c_del_driver(&pcm512x_i2c_driver);
698#endif
699#if defined(CONFIG_SPI_MASTER)
700 spi_unregister_driver(&pcm512x_spi_driver);
701#endif
702}
703module_exit(pcm512x_exit);
704
705MODULE_DESCRIPTION("ASoC PCM512x codec driver");
706MODULE_AUTHOR("Mark Brown <broonie@linaro.org>");
707MODULE_LICENSE("GPL v2");