WIP FPC-III support
[linux/fpc-iii.git] / sound / soc / codecs / rk3328_codec.c
blobbfefefcc76d81a140a4f5f94137911b4677a050c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // rk3328 ALSA SoC Audio driver
4 //
5 // Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
7 #include <linux/clk.h>
8 #include <linux/delay.h>
9 #include <linux/device.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/regmap.h>
16 #include <linux/mfd/syscon.h>
17 #include <sound/dmaengine_pcm.h>
18 #include <sound/pcm_params.h>
19 #include "rk3328_codec.h"
22 * volume setting
23 * 0: -39dB
24 * 26: 0dB
25 * 31: 6dB
26 * Step: 1.5dB
28 #define OUT_VOLUME (0x18)
29 #define RK3328_GRF_SOC_CON2 (0x0408)
30 #define RK3328_GRF_SOC_CON10 (0x0428)
31 #define INITIAL_FREQ (11289600)
33 struct rk3328_codec_priv {
34 struct regmap *regmap;
35 struct gpio_desc *mute;
36 struct clk *mclk;
37 struct clk *pclk;
38 unsigned int sclk;
39 int spk_depop_time; /* msec */
42 static const struct reg_default rk3328_codec_reg_defaults[] = {
43 { CODEC_RESET, 0x03 },
44 { DAC_INIT_CTRL1, 0x00 },
45 { DAC_INIT_CTRL2, 0x50 },
46 { DAC_INIT_CTRL3, 0x0e },
47 { DAC_PRECHARGE_CTRL, 0x01 },
48 { DAC_PWR_CTRL, 0x00 },
49 { DAC_CLK_CTRL, 0x00 },
50 { HPMIX_CTRL, 0x00 },
51 { HPOUT_CTRL, 0x00 },
52 { HPOUTL_GAIN_CTRL, 0x00 },
53 { HPOUTR_GAIN_CTRL, 0x00 },
54 { HPOUT_POP_CTRL, 0x11 },
57 static int rk3328_codec_reset(struct rk3328_codec_priv *rk3328)
59 regmap_write(rk3328->regmap, CODEC_RESET, 0x00);
60 mdelay(10);
61 regmap_write(rk3328->regmap, CODEC_RESET, 0x03);
63 return 0;
66 static int rk3328_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
68 struct rk3328_codec_priv *rk3328 =
69 snd_soc_component_get_drvdata(dai->component);
70 unsigned int val;
72 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
73 case SND_SOC_DAIFMT_CBS_CFS:
74 val = PIN_DIRECTION_IN | DAC_I2S_MODE_SLAVE;
75 break;
76 case SND_SOC_DAIFMT_CBM_CFM:
77 val = PIN_DIRECTION_OUT | DAC_I2S_MODE_MASTER;
78 break;
79 default:
80 return -EINVAL;
83 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL1,
84 PIN_DIRECTION_MASK | DAC_I2S_MODE_MASK, val);
86 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
87 case SND_SOC_DAIFMT_DSP_A:
88 case SND_SOC_DAIFMT_DSP_B:
89 val = DAC_MODE_PCM;
90 break;
91 case SND_SOC_DAIFMT_I2S:
92 val = DAC_MODE_I2S;
93 break;
94 case SND_SOC_DAIFMT_RIGHT_J:
95 val = DAC_MODE_RJM;
96 break;
97 case SND_SOC_DAIFMT_LEFT_J:
98 val = DAC_MODE_LJM;
99 break;
100 default:
101 return -EINVAL;
104 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL2,
105 DAC_MODE_MASK, val);
107 return 0;
110 static int rk3328_mute_stream(struct snd_soc_dai *dai, int mute, int direction)
112 struct rk3328_codec_priv *rk3328 =
113 snd_soc_component_get_drvdata(dai->component);
114 unsigned int val;
116 if (mute)
117 val = HPOUTL_MUTE | HPOUTR_MUTE;
118 else
119 val = HPOUTL_UNMUTE | HPOUTR_UNMUTE;
121 regmap_update_bits(rk3328->regmap, HPOUT_CTRL,
122 HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK, val);
124 return 0;
127 static int rk3328_codec_power_on(struct rk3328_codec_priv *rk3328, int wait_ms)
129 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
130 DAC_CHARGE_XCHARGE_MASK, DAC_CHARGE_PRECHARGE);
131 mdelay(10);
132 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
133 DAC_CHARGE_CURRENT_ALL_MASK,
134 DAC_CHARGE_CURRENT_ALL_ON);
135 mdelay(wait_ms);
137 return 0;
140 static int rk3328_codec_power_off(struct rk3328_codec_priv *rk3328, int wait_ms)
142 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
143 DAC_CHARGE_XCHARGE_MASK, DAC_CHARGE_DISCHARGE);
144 mdelay(10);
145 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
146 DAC_CHARGE_CURRENT_ALL_MASK,
147 DAC_CHARGE_CURRENT_ALL_ON);
148 mdelay(wait_ms);
150 return 0;
153 static const struct rk3328_reg_msk_val playback_open_list[] = {
154 { DAC_PWR_CTRL, DAC_PWR_MASK, DAC_PWR_ON },
155 { DAC_PWR_CTRL, DACL_PATH_REFV_MASK | DACR_PATH_REFV_MASK,
156 DACL_PATH_REFV_ON | DACR_PATH_REFV_ON },
157 { DAC_PWR_CTRL, HPOUTL_ZERO_CROSSING_MASK | HPOUTR_ZERO_CROSSING_MASK,
158 HPOUTL_ZERO_CROSSING_ON | HPOUTR_ZERO_CROSSING_ON },
159 { HPOUT_POP_CTRL, HPOUTR_POP_MASK | HPOUTL_POP_MASK,
160 HPOUTR_POP_WORK | HPOUTL_POP_WORK },
161 { HPMIX_CTRL, HPMIXL_MASK | HPMIXR_MASK, HPMIXL_EN | HPMIXR_EN },
162 { HPMIX_CTRL, HPMIXL_INIT_MASK | HPMIXR_INIT_MASK,
163 HPMIXL_INIT_EN | HPMIXR_INIT_EN },
164 { HPOUT_CTRL, HPOUTL_MASK | HPOUTR_MASK, HPOUTL_EN | HPOUTR_EN },
165 { HPOUT_CTRL, HPOUTL_INIT_MASK | HPOUTR_INIT_MASK,
166 HPOUTL_INIT_EN | HPOUTR_INIT_EN },
167 { DAC_CLK_CTRL, DACL_REFV_MASK | DACR_REFV_MASK,
168 DACL_REFV_ON | DACR_REFV_ON },
169 { DAC_CLK_CTRL, DACL_CLK_MASK | DACR_CLK_MASK,
170 DACL_CLK_ON | DACR_CLK_ON },
171 { DAC_CLK_CTRL, DACL_MASK | DACR_MASK, DACL_ON | DACR_ON },
172 { DAC_CLK_CTRL, DACL_INIT_MASK | DACR_INIT_MASK,
173 DACL_INIT_ON | DACR_INIT_ON },
174 { DAC_SELECT, DACL_SELECT_MASK | DACR_SELECT_MASK,
175 DACL_SELECT | DACR_SELECT },
176 { HPMIX_CTRL, HPMIXL_INIT2_MASK | HPMIXR_INIT2_MASK,
177 HPMIXL_INIT2_EN | HPMIXR_INIT2_EN },
178 { HPOUT_CTRL, HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK,
179 HPOUTL_UNMUTE | HPOUTR_UNMUTE },
182 static int rk3328_codec_open_playback(struct rk3328_codec_priv *rk3328)
184 int i;
186 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
187 DAC_CHARGE_CURRENT_ALL_MASK,
188 DAC_CHARGE_CURRENT_I);
190 for (i = 0; i < ARRAY_SIZE(playback_open_list); i++) {
191 regmap_update_bits(rk3328->regmap,
192 playback_open_list[i].reg,
193 playback_open_list[i].msk,
194 playback_open_list[i].val);
195 mdelay(1);
198 msleep(rk3328->spk_depop_time);
199 gpiod_set_value(rk3328->mute, 0);
201 regmap_update_bits(rk3328->regmap, HPOUTL_GAIN_CTRL,
202 HPOUTL_GAIN_MASK, OUT_VOLUME);
203 regmap_update_bits(rk3328->regmap, HPOUTR_GAIN_CTRL,
204 HPOUTR_GAIN_MASK, OUT_VOLUME);
206 return 0;
209 static const struct rk3328_reg_msk_val playback_close_list[] = {
210 { HPMIX_CTRL, HPMIXL_INIT2_MASK | HPMIXR_INIT2_MASK,
211 HPMIXL_INIT2_DIS | HPMIXR_INIT2_DIS },
212 { DAC_SELECT, DACL_SELECT_MASK | DACR_SELECT_MASK,
213 DACL_UNSELECT | DACR_UNSELECT },
214 { HPOUT_CTRL, HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK,
215 HPOUTL_MUTE | HPOUTR_MUTE },
216 { HPOUT_CTRL, HPOUTL_INIT_MASK | HPOUTR_INIT_MASK,
217 HPOUTL_INIT_DIS | HPOUTR_INIT_DIS },
218 { HPOUT_CTRL, HPOUTL_MASK | HPOUTR_MASK, HPOUTL_DIS | HPOUTR_DIS },
219 { HPMIX_CTRL, HPMIXL_MASK | HPMIXR_MASK, HPMIXL_DIS | HPMIXR_DIS },
220 { DAC_CLK_CTRL, DACL_MASK | DACR_MASK, DACL_OFF | DACR_OFF },
221 { DAC_CLK_CTRL, DACL_CLK_MASK | DACR_CLK_MASK,
222 DACL_CLK_OFF | DACR_CLK_OFF },
223 { DAC_CLK_CTRL, DACL_REFV_MASK | DACR_REFV_MASK,
224 DACL_REFV_OFF | DACR_REFV_OFF },
225 { HPOUT_POP_CTRL, HPOUTR_POP_MASK | HPOUTL_POP_MASK,
226 HPOUTR_POP_XCHARGE | HPOUTL_POP_XCHARGE },
227 { DAC_PWR_CTRL, DACL_PATH_REFV_MASK | DACR_PATH_REFV_MASK,
228 DACL_PATH_REFV_OFF | DACR_PATH_REFV_OFF },
229 { DAC_PWR_CTRL, DAC_PWR_MASK, DAC_PWR_OFF },
230 { HPMIX_CTRL, HPMIXL_INIT_MASK | HPMIXR_INIT_MASK,
231 HPMIXL_INIT_DIS | HPMIXR_INIT_DIS },
232 { DAC_CLK_CTRL, DACL_INIT_MASK | DACR_INIT_MASK,
233 DACL_INIT_OFF | DACR_INIT_OFF },
236 static int rk3328_codec_close_playback(struct rk3328_codec_priv *rk3328)
238 size_t i;
240 gpiod_set_value(rk3328->mute, 1);
242 regmap_update_bits(rk3328->regmap, HPOUTL_GAIN_CTRL,
243 HPOUTL_GAIN_MASK, 0);
244 regmap_update_bits(rk3328->regmap, HPOUTR_GAIN_CTRL,
245 HPOUTR_GAIN_MASK, 0);
247 for (i = 0; i < ARRAY_SIZE(playback_close_list); i++) {
248 regmap_update_bits(rk3328->regmap,
249 playback_close_list[i].reg,
250 playback_close_list[i].msk,
251 playback_close_list[i].val);
252 mdelay(1);
255 /* Workaround for silence when changed Fs 48 -> 44.1kHz */
256 rk3328_codec_reset(rk3328);
258 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL,
259 DAC_CHARGE_CURRENT_ALL_MASK,
260 DAC_CHARGE_CURRENT_ALL_ON);
262 return 0;
265 static int rk3328_hw_params(struct snd_pcm_substream *substream,
266 struct snd_pcm_hw_params *params,
267 struct snd_soc_dai *dai)
269 struct rk3328_codec_priv *rk3328 =
270 snd_soc_component_get_drvdata(dai->component);
271 unsigned int val = 0;
273 switch (params_format(params)) {
274 case SNDRV_PCM_FORMAT_S16_LE:
275 val = DAC_VDL_16BITS;
276 break;
277 case SNDRV_PCM_FORMAT_S20_3LE:
278 val = DAC_VDL_20BITS;
279 break;
280 case SNDRV_PCM_FORMAT_S24_LE:
281 val = DAC_VDL_24BITS;
282 break;
283 case SNDRV_PCM_FORMAT_S32_LE:
284 val = DAC_VDL_32BITS;
285 break;
286 default:
287 return -EINVAL;
289 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL2, DAC_VDL_MASK, val);
291 val = DAC_WL_32BITS | DAC_RST_DIS;
292 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL3,
293 DAC_WL_MASK | DAC_RST_MASK, val);
295 return 0;
298 static int rk3328_pcm_startup(struct snd_pcm_substream *substream,
299 struct snd_soc_dai *dai)
301 struct rk3328_codec_priv *rk3328 =
302 snd_soc_component_get_drvdata(dai->component);
304 return rk3328_codec_open_playback(rk3328);
307 static void rk3328_pcm_shutdown(struct snd_pcm_substream *substream,
308 struct snd_soc_dai *dai)
310 struct rk3328_codec_priv *rk3328 =
311 snd_soc_component_get_drvdata(dai->component);
313 rk3328_codec_close_playback(rk3328);
316 static const struct snd_soc_dai_ops rk3328_dai_ops = {
317 .hw_params = rk3328_hw_params,
318 .set_fmt = rk3328_set_dai_fmt,
319 .mute_stream = rk3328_mute_stream,
320 .startup = rk3328_pcm_startup,
321 .shutdown = rk3328_pcm_shutdown,
322 .no_capture_mute = 1,
325 static struct snd_soc_dai_driver rk3328_dai[] = {
327 .name = "rk3328-hifi",
328 .id = RK3328_HIFI,
329 .playback = {
330 .stream_name = "HIFI Playback",
331 .channels_min = 1,
332 .channels_max = 2,
333 .rates = SNDRV_PCM_RATE_8000_96000,
334 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
335 SNDRV_PCM_FMTBIT_S20_3LE |
336 SNDRV_PCM_FMTBIT_S24_LE |
337 SNDRV_PCM_FMTBIT_S32_LE),
339 .capture = {
340 .stream_name = "HIFI Capture",
341 .channels_min = 2,
342 .channels_max = 8,
343 .rates = SNDRV_PCM_RATE_8000_96000,
344 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
345 SNDRV_PCM_FMTBIT_S20_3LE |
346 SNDRV_PCM_FMTBIT_S24_LE |
347 SNDRV_PCM_FMTBIT_S32_LE),
349 .ops = &rk3328_dai_ops,
353 static int rk3328_codec_probe(struct snd_soc_component *component)
355 struct rk3328_codec_priv *rk3328 =
356 snd_soc_component_get_drvdata(component);
358 rk3328_codec_reset(rk3328);
359 rk3328_codec_power_on(rk3328, 0);
361 return 0;
364 static void rk3328_codec_remove(struct snd_soc_component *component)
366 struct rk3328_codec_priv *rk3328 =
367 snd_soc_component_get_drvdata(component);
369 rk3328_codec_close_playback(rk3328);
370 rk3328_codec_power_off(rk3328, 0);
373 static const struct snd_soc_component_driver soc_codec_rk3328 = {
374 .probe = rk3328_codec_probe,
375 .remove = rk3328_codec_remove,
378 static bool rk3328_codec_write_read_reg(struct device *dev, unsigned int reg)
380 switch (reg) {
381 case CODEC_RESET:
382 case DAC_INIT_CTRL1:
383 case DAC_INIT_CTRL2:
384 case DAC_INIT_CTRL3:
385 case DAC_PRECHARGE_CTRL:
386 case DAC_PWR_CTRL:
387 case DAC_CLK_CTRL:
388 case HPMIX_CTRL:
389 case DAC_SELECT:
390 case HPOUT_CTRL:
391 case HPOUTL_GAIN_CTRL:
392 case HPOUTR_GAIN_CTRL:
393 case HPOUT_POP_CTRL:
394 return true;
395 default:
396 return false;
400 static bool rk3328_codec_volatile_reg(struct device *dev, unsigned int reg)
402 switch (reg) {
403 case CODEC_RESET:
404 return true;
405 default:
406 return false;
410 static const struct regmap_config rk3328_codec_regmap_config = {
411 .reg_bits = 32,
412 .reg_stride = 4,
413 .val_bits = 32,
414 .max_register = HPOUT_POP_CTRL,
415 .writeable_reg = rk3328_codec_write_read_reg,
416 .readable_reg = rk3328_codec_write_read_reg,
417 .volatile_reg = rk3328_codec_volatile_reg,
418 .reg_defaults = rk3328_codec_reg_defaults,
419 .num_reg_defaults = ARRAY_SIZE(rk3328_codec_reg_defaults),
420 .cache_type = REGCACHE_FLAT,
423 static int rk3328_platform_probe(struct platform_device *pdev)
425 struct device_node *rk3328_np = pdev->dev.of_node;
426 struct rk3328_codec_priv *rk3328;
427 struct regmap *grf;
428 void __iomem *base;
429 int ret = 0;
431 rk3328 = devm_kzalloc(&pdev->dev, sizeof(*rk3328), GFP_KERNEL);
432 if (!rk3328)
433 return -ENOMEM;
435 grf = syscon_regmap_lookup_by_phandle(rk3328_np,
436 "rockchip,grf");
437 if (IS_ERR(grf)) {
438 dev_err(&pdev->dev, "missing 'rockchip,grf'\n");
439 return PTR_ERR(grf);
441 /* enable i2s_acodec_en */
442 regmap_write(grf, RK3328_GRF_SOC_CON2,
443 (BIT(14) << 16 | BIT(14)));
445 ret = of_property_read_u32(rk3328_np, "spk-depop-time-ms",
446 &rk3328->spk_depop_time);
447 if (ret < 0) {
448 dev_info(&pdev->dev, "spk_depop_time use default value.\n");
449 rk3328->spk_depop_time = 200;
452 rk3328->mute = gpiod_get_optional(&pdev->dev, "mute", GPIOD_OUT_HIGH);
453 if (IS_ERR(rk3328->mute))
454 return PTR_ERR(rk3328->mute);
456 * Rock64 is the only supported platform to have widely relied on
457 * this; if we do happen to come across an old DTB, just leave the
458 * external mute forced off.
460 if (!rk3328->mute && of_machine_is_compatible("pine64,rock64")) {
461 dev_warn(&pdev->dev, "assuming implicit control of GPIO_MUTE; update devicetree if possible\n");
462 regmap_write(grf, RK3328_GRF_SOC_CON10, BIT(17) | BIT(1));
465 rk3328->mclk = devm_clk_get(&pdev->dev, "mclk");
466 if (IS_ERR(rk3328->mclk))
467 return PTR_ERR(rk3328->mclk);
469 ret = clk_prepare_enable(rk3328->mclk);
470 if (ret)
471 return ret;
472 clk_set_rate(rk3328->mclk, INITIAL_FREQ);
474 rk3328->pclk = devm_clk_get(&pdev->dev, "pclk");
475 if (IS_ERR(rk3328->pclk)) {
476 dev_err(&pdev->dev, "can't get acodec pclk\n");
477 return PTR_ERR(rk3328->pclk);
480 ret = clk_prepare_enable(rk3328->pclk);
481 if (ret < 0) {
482 dev_err(&pdev->dev, "failed to enable acodec pclk\n");
483 return ret;
486 base = devm_platform_ioremap_resource(pdev, 0);
487 if (IS_ERR(base))
488 return PTR_ERR(base);
490 rk3328->regmap = devm_regmap_init_mmio(&pdev->dev, base,
491 &rk3328_codec_regmap_config);
492 if (IS_ERR(rk3328->regmap))
493 return PTR_ERR(rk3328->regmap);
495 platform_set_drvdata(pdev, rk3328);
497 return devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328,
498 rk3328_dai,
499 ARRAY_SIZE(rk3328_dai));
502 static const struct of_device_id rk3328_codec_of_match[] __maybe_unused = {
503 { .compatible = "rockchip,rk3328-codec", },
506 MODULE_DEVICE_TABLE(of, rk3328_codec_of_match);
508 static struct platform_driver rk3328_codec_driver = {
509 .driver = {
510 .name = "rk3328-codec",
511 .of_match_table = of_match_ptr(rk3328_codec_of_match),
513 .probe = rk3328_platform_probe,
515 module_platform_driver(rk3328_codec_driver);
517 MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
518 MODULE_DESCRIPTION("ASoC rk3328 codec driver");
519 MODULE_LICENSE("GPL v2");