1 // SPDX-License-Identifier: GPL-2.0
3 // rk3328 ALSA SoC Audio driver
5 // Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd All rights reserved.
8 #include <linux/delay.h>
9 #include <linux/device.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/module.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
15 #include <linux/mfd/syscon.h>
16 #include <sound/dmaengine_pcm.h>
17 #include <sound/pcm_params.h>
18 #include "rk3328_codec.h"
27 #define OUT_VOLUME (0x18)
28 #define RK3328_GRF_SOC_CON2 (0x0408)
29 #define RK3328_GRF_SOC_CON10 (0x0428)
30 #define INITIAL_FREQ (11289600)
32 struct rk3328_codec_priv
{
33 struct regmap
*regmap
;
34 struct gpio_desc
*mute
;
38 int spk_depop_time
; /* msec */
41 static const struct reg_default rk3328_codec_reg_defaults
[] = {
42 { CODEC_RESET
, 0x03 },
43 { DAC_INIT_CTRL1
, 0x00 },
44 { DAC_INIT_CTRL2
, 0x50 },
45 { DAC_INIT_CTRL3
, 0x0e },
46 { DAC_PRECHARGE_CTRL
, 0x01 },
47 { DAC_PWR_CTRL
, 0x00 },
48 { DAC_CLK_CTRL
, 0x00 },
51 { HPOUTL_GAIN_CTRL
, 0x00 },
52 { HPOUTR_GAIN_CTRL
, 0x00 },
53 { HPOUT_POP_CTRL
, 0x11 },
56 static int rk3328_codec_reset(struct rk3328_codec_priv
*rk3328
)
58 regmap_write(rk3328
->regmap
, CODEC_RESET
, 0x00);
60 regmap_write(rk3328
->regmap
, CODEC_RESET
, 0x03);
65 static int rk3328_set_dai_fmt(struct snd_soc_dai
*dai
, unsigned int fmt
)
67 struct rk3328_codec_priv
*rk3328
=
68 snd_soc_component_get_drvdata(dai
->component
);
71 switch (fmt
& SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK
) {
72 case SND_SOC_DAIFMT_CBC_CFC
:
73 val
= PIN_DIRECTION_IN
| DAC_I2S_MODE_SLAVE
;
75 case SND_SOC_DAIFMT_CBP_CFP
:
76 val
= PIN_DIRECTION_OUT
| DAC_I2S_MODE_MASTER
;
82 regmap_update_bits(rk3328
->regmap
, DAC_INIT_CTRL1
,
83 PIN_DIRECTION_MASK
| DAC_I2S_MODE_MASK
, val
);
85 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
86 case SND_SOC_DAIFMT_DSP_A
:
87 case SND_SOC_DAIFMT_DSP_B
:
90 case SND_SOC_DAIFMT_I2S
:
93 case SND_SOC_DAIFMT_RIGHT_J
:
96 case SND_SOC_DAIFMT_LEFT_J
:
103 regmap_update_bits(rk3328
->regmap
, DAC_INIT_CTRL2
,
109 static int rk3328_mute_stream(struct snd_soc_dai
*dai
, int mute
, int direction
)
111 struct rk3328_codec_priv
*rk3328
=
112 snd_soc_component_get_drvdata(dai
->component
);
116 val
= HPOUTL_MUTE
| HPOUTR_MUTE
;
118 val
= HPOUTL_UNMUTE
| HPOUTR_UNMUTE
;
120 regmap_update_bits(rk3328
->regmap
, HPOUT_CTRL
,
121 HPOUTL_MUTE_MASK
| HPOUTR_MUTE_MASK
, val
);
126 static int rk3328_codec_power_on(struct rk3328_codec_priv
*rk3328
, int wait_ms
)
128 regmap_update_bits(rk3328
->regmap
, DAC_PRECHARGE_CTRL
,
129 DAC_CHARGE_XCHARGE_MASK
, DAC_CHARGE_PRECHARGE
);
131 regmap_update_bits(rk3328
->regmap
, DAC_PRECHARGE_CTRL
,
132 DAC_CHARGE_CURRENT_ALL_MASK
,
133 DAC_CHARGE_CURRENT_ALL_ON
);
139 static int rk3328_codec_power_off(struct rk3328_codec_priv
*rk3328
, int wait_ms
)
141 regmap_update_bits(rk3328
->regmap
, DAC_PRECHARGE_CTRL
,
142 DAC_CHARGE_XCHARGE_MASK
, DAC_CHARGE_DISCHARGE
);
144 regmap_update_bits(rk3328
->regmap
, DAC_PRECHARGE_CTRL
,
145 DAC_CHARGE_CURRENT_ALL_MASK
,
146 DAC_CHARGE_CURRENT_ALL_ON
);
152 static const struct rk3328_reg_msk_val playback_open_list
[] = {
153 { DAC_PWR_CTRL
, DAC_PWR_MASK
, DAC_PWR_ON
},
154 { DAC_PWR_CTRL
, DACL_PATH_REFV_MASK
| DACR_PATH_REFV_MASK
,
155 DACL_PATH_REFV_ON
| DACR_PATH_REFV_ON
},
156 { DAC_PWR_CTRL
, HPOUTL_ZERO_CROSSING_MASK
| HPOUTR_ZERO_CROSSING_MASK
,
157 HPOUTL_ZERO_CROSSING_ON
| HPOUTR_ZERO_CROSSING_ON
},
158 { HPOUT_POP_CTRL
, HPOUTR_POP_MASK
| HPOUTL_POP_MASK
,
159 HPOUTR_POP_WORK
| HPOUTL_POP_WORK
},
160 { HPMIX_CTRL
, HPMIXL_MASK
| HPMIXR_MASK
, HPMIXL_EN
| HPMIXR_EN
},
161 { HPMIX_CTRL
, HPMIXL_INIT_MASK
| HPMIXR_INIT_MASK
,
162 HPMIXL_INIT_EN
| HPMIXR_INIT_EN
},
163 { HPOUT_CTRL
, HPOUTL_MASK
| HPOUTR_MASK
, HPOUTL_EN
| HPOUTR_EN
},
164 { HPOUT_CTRL
, HPOUTL_INIT_MASK
| HPOUTR_INIT_MASK
,
165 HPOUTL_INIT_EN
| HPOUTR_INIT_EN
},
166 { DAC_CLK_CTRL
, DACL_REFV_MASK
| DACR_REFV_MASK
,
167 DACL_REFV_ON
| DACR_REFV_ON
},
168 { DAC_CLK_CTRL
, DACL_CLK_MASK
| DACR_CLK_MASK
,
169 DACL_CLK_ON
| DACR_CLK_ON
},
170 { DAC_CLK_CTRL
, DACL_MASK
| DACR_MASK
, DACL_ON
| DACR_ON
},
171 { DAC_CLK_CTRL
, DACL_INIT_MASK
| DACR_INIT_MASK
,
172 DACL_INIT_ON
| DACR_INIT_ON
},
173 { DAC_SELECT
, DACL_SELECT_MASK
| DACR_SELECT_MASK
,
174 DACL_SELECT
| DACR_SELECT
},
175 { HPMIX_CTRL
, HPMIXL_INIT2_MASK
| HPMIXR_INIT2_MASK
,
176 HPMIXL_INIT2_EN
| HPMIXR_INIT2_EN
},
177 { HPOUT_CTRL
, HPOUTL_MUTE_MASK
| HPOUTR_MUTE_MASK
,
178 HPOUTL_UNMUTE
| HPOUTR_UNMUTE
},
181 static int rk3328_codec_open_playback(struct rk3328_codec_priv
*rk3328
)
185 regmap_update_bits(rk3328
->regmap
, DAC_PRECHARGE_CTRL
,
186 DAC_CHARGE_CURRENT_ALL_MASK
,
187 DAC_CHARGE_CURRENT_I
);
189 for (i
= 0; i
< ARRAY_SIZE(playback_open_list
); i
++) {
190 regmap_update_bits(rk3328
->regmap
,
191 playback_open_list
[i
].reg
,
192 playback_open_list
[i
].msk
,
193 playback_open_list
[i
].val
);
197 msleep(rk3328
->spk_depop_time
);
198 gpiod_set_value(rk3328
->mute
, 0);
200 regmap_update_bits(rk3328
->regmap
, HPOUTL_GAIN_CTRL
,
201 HPOUTL_GAIN_MASK
, OUT_VOLUME
);
202 regmap_update_bits(rk3328
->regmap
, HPOUTR_GAIN_CTRL
,
203 HPOUTR_GAIN_MASK
, OUT_VOLUME
);
208 static const struct rk3328_reg_msk_val playback_close_list
[] = {
209 { HPMIX_CTRL
, HPMIXL_INIT2_MASK
| HPMIXR_INIT2_MASK
,
210 HPMIXL_INIT2_DIS
| HPMIXR_INIT2_DIS
},
211 { DAC_SELECT
, DACL_SELECT_MASK
| DACR_SELECT_MASK
,
212 DACL_UNSELECT
| DACR_UNSELECT
},
213 { HPOUT_CTRL
, HPOUTL_MUTE_MASK
| HPOUTR_MUTE_MASK
,
214 HPOUTL_MUTE
| HPOUTR_MUTE
},
215 { HPOUT_CTRL
, HPOUTL_INIT_MASK
| HPOUTR_INIT_MASK
,
216 HPOUTL_INIT_DIS
| HPOUTR_INIT_DIS
},
217 { HPOUT_CTRL
, HPOUTL_MASK
| HPOUTR_MASK
, HPOUTL_DIS
| HPOUTR_DIS
},
218 { HPMIX_CTRL
, HPMIXL_MASK
| HPMIXR_MASK
, HPMIXL_DIS
| HPMIXR_DIS
},
219 { DAC_CLK_CTRL
, DACL_MASK
| DACR_MASK
, DACL_OFF
| DACR_OFF
},
220 { DAC_CLK_CTRL
, DACL_CLK_MASK
| DACR_CLK_MASK
,
221 DACL_CLK_OFF
| DACR_CLK_OFF
},
222 { DAC_CLK_CTRL
, DACL_REFV_MASK
| DACR_REFV_MASK
,
223 DACL_REFV_OFF
| DACR_REFV_OFF
},
224 { HPOUT_POP_CTRL
, HPOUTR_POP_MASK
| HPOUTL_POP_MASK
,
225 HPOUTR_POP_XCHARGE
| HPOUTL_POP_XCHARGE
},
226 { DAC_PWR_CTRL
, DACL_PATH_REFV_MASK
| DACR_PATH_REFV_MASK
,
227 DACL_PATH_REFV_OFF
| DACR_PATH_REFV_OFF
},
228 { DAC_PWR_CTRL
, DAC_PWR_MASK
, DAC_PWR_OFF
},
229 { HPMIX_CTRL
, HPMIXL_INIT_MASK
| HPMIXR_INIT_MASK
,
230 HPMIXL_INIT_DIS
| HPMIXR_INIT_DIS
},
231 { DAC_CLK_CTRL
, DACL_INIT_MASK
| DACR_INIT_MASK
,
232 DACL_INIT_OFF
| DACR_INIT_OFF
},
235 static int rk3328_codec_close_playback(struct rk3328_codec_priv
*rk3328
)
239 gpiod_set_value(rk3328
->mute
, 1);
241 regmap_update_bits(rk3328
->regmap
, HPOUTL_GAIN_CTRL
,
242 HPOUTL_GAIN_MASK
, 0);
243 regmap_update_bits(rk3328
->regmap
, HPOUTR_GAIN_CTRL
,
244 HPOUTR_GAIN_MASK
, 0);
246 for (i
= 0; i
< ARRAY_SIZE(playback_close_list
); i
++) {
247 regmap_update_bits(rk3328
->regmap
,
248 playback_close_list
[i
].reg
,
249 playback_close_list
[i
].msk
,
250 playback_close_list
[i
].val
);
254 /* Workaround for silence when changed Fs 48 -> 44.1kHz */
255 rk3328_codec_reset(rk3328
);
257 regmap_update_bits(rk3328
->regmap
, DAC_PRECHARGE_CTRL
,
258 DAC_CHARGE_CURRENT_ALL_MASK
,
259 DAC_CHARGE_CURRENT_ALL_ON
);
264 static int rk3328_hw_params(struct snd_pcm_substream
*substream
,
265 struct snd_pcm_hw_params
*params
,
266 struct snd_soc_dai
*dai
)
268 struct rk3328_codec_priv
*rk3328
=
269 snd_soc_component_get_drvdata(dai
->component
);
270 unsigned int val
= 0;
272 switch (params_format(params
)) {
273 case SNDRV_PCM_FORMAT_S16_LE
:
274 val
= DAC_VDL_16BITS
;
276 case SNDRV_PCM_FORMAT_S20_3LE
:
277 val
= DAC_VDL_20BITS
;
279 case SNDRV_PCM_FORMAT_S24_LE
:
280 val
= DAC_VDL_24BITS
;
282 case SNDRV_PCM_FORMAT_S32_LE
:
283 val
= DAC_VDL_32BITS
;
288 regmap_update_bits(rk3328
->regmap
, DAC_INIT_CTRL2
, DAC_VDL_MASK
, val
);
290 val
= DAC_WL_32BITS
| DAC_RST_DIS
;
291 regmap_update_bits(rk3328
->regmap
, DAC_INIT_CTRL3
,
292 DAC_WL_MASK
| DAC_RST_MASK
, val
);
297 static int rk3328_pcm_startup(struct snd_pcm_substream
*substream
,
298 struct snd_soc_dai
*dai
)
300 struct rk3328_codec_priv
*rk3328
=
301 snd_soc_component_get_drvdata(dai
->component
);
303 return rk3328_codec_open_playback(rk3328
);
306 static void rk3328_pcm_shutdown(struct snd_pcm_substream
*substream
,
307 struct snd_soc_dai
*dai
)
309 struct rk3328_codec_priv
*rk3328
=
310 snd_soc_component_get_drvdata(dai
->component
);
312 rk3328_codec_close_playback(rk3328
);
315 static const struct snd_soc_dai_ops rk3328_dai_ops
= {
316 .hw_params
= rk3328_hw_params
,
317 .set_fmt
= rk3328_set_dai_fmt
,
318 .mute_stream
= rk3328_mute_stream
,
319 .startup
= rk3328_pcm_startup
,
320 .shutdown
= rk3328_pcm_shutdown
,
321 .no_capture_mute
= 1,
324 static struct snd_soc_dai_driver rk3328_dai
[] = {
326 .name
= "rk3328-hifi",
329 .stream_name
= "HIFI Playback",
332 .rates
= SNDRV_PCM_RATE_8000_96000
,
333 .formats
= (SNDRV_PCM_FMTBIT_S16_LE
|
334 SNDRV_PCM_FMTBIT_S20_3LE
|
335 SNDRV_PCM_FMTBIT_S24_LE
|
336 SNDRV_PCM_FMTBIT_S32_LE
),
339 .stream_name
= "HIFI Capture",
342 .rates
= SNDRV_PCM_RATE_8000_96000
,
343 .formats
= (SNDRV_PCM_FMTBIT_S16_LE
|
344 SNDRV_PCM_FMTBIT_S20_3LE
|
345 SNDRV_PCM_FMTBIT_S24_LE
|
346 SNDRV_PCM_FMTBIT_S32_LE
),
348 .ops
= &rk3328_dai_ops
,
352 static int rk3328_codec_probe(struct snd_soc_component
*component
)
354 struct rk3328_codec_priv
*rk3328
=
355 snd_soc_component_get_drvdata(component
);
357 rk3328_codec_reset(rk3328
);
358 rk3328_codec_power_on(rk3328
, 0);
363 static void rk3328_codec_remove(struct snd_soc_component
*component
)
365 struct rk3328_codec_priv
*rk3328
=
366 snd_soc_component_get_drvdata(component
);
368 rk3328_codec_close_playback(rk3328
);
369 rk3328_codec_power_off(rk3328
, 0);
372 static const struct snd_soc_component_driver soc_codec_rk3328
= {
373 .probe
= rk3328_codec_probe
,
374 .remove
= rk3328_codec_remove
,
377 static bool rk3328_codec_write_read_reg(struct device
*dev
, unsigned int reg
)
384 case DAC_PRECHARGE_CTRL
:
390 case HPOUTL_GAIN_CTRL
:
391 case HPOUTR_GAIN_CTRL
:
399 static bool rk3328_codec_volatile_reg(struct device
*dev
, unsigned int reg
)
409 static const struct regmap_config rk3328_codec_regmap_config
= {
413 .max_register
= HPOUT_POP_CTRL
,
414 .writeable_reg
= rk3328_codec_write_read_reg
,
415 .readable_reg
= rk3328_codec_write_read_reg
,
416 .volatile_reg
= rk3328_codec_volatile_reg
,
417 .reg_defaults
= rk3328_codec_reg_defaults
,
418 .num_reg_defaults
= ARRAY_SIZE(rk3328_codec_reg_defaults
),
419 .cache_type
= REGCACHE_FLAT
,
422 static int rk3328_platform_probe(struct platform_device
*pdev
)
424 struct device_node
*rk3328_np
= pdev
->dev
.of_node
;
425 struct rk3328_codec_priv
*rk3328
;
430 rk3328
= devm_kzalloc(&pdev
->dev
, sizeof(*rk3328
), GFP_KERNEL
);
434 grf
= syscon_regmap_lookup_by_phandle(rk3328_np
,
437 dev_err(&pdev
->dev
, "missing 'rockchip,grf'\n");
440 /* enable i2s_acodec_en */
441 regmap_write(grf
, RK3328_GRF_SOC_CON2
,
442 (BIT(14) << 16 | BIT(14)));
444 ret
= of_property_read_u32(rk3328_np
, "spk-depop-time-ms",
445 &rk3328
->spk_depop_time
);
447 dev_info(&pdev
->dev
, "spk_depop_time use default value.\n");
448 rk3328
->spk_depop_time
= 200;
451 rk3328
->mute
= gpiod_get_optional(&pdev
->dev
, "mute", GPIOD_OUT_HIGH
);
452 if (IS_ERR(rk3328
->mute
))
453 return PTR_ERR(rk3328
->mute
);
455 * Rock64 is the only supported platform to have widely relied on
456 * this; if we do happen to come across an old DTB, just leave the
457 * external mute forced off.
459 if (!rk3328
->mute
&& of_machine_is_compatible("pine64,rock64")) {
460 dev_warn(&pdev
->dev
, "assuming implicit control of GPIO_MUTE; update devicetree if possible\n");
461 regmap_write(grf
, RK3328_GRF_SOC_CON10
, BIT(17) | BIT(1));
464 rk3328
->mclk
= devm_clk_get(&pdev
->dev
, "mclk");
465 if (IS_ERR(rk3328
->mclk
))
466 return PTR_ERR(rk3328
->mclk
);
468 ret
= clk_prepare_enable(rk3328
->mclk
);
471 clk_set_rate(rk3328
->mclk
, INITIAL_FREQ
);
473 rk3328
->pclk
= devm_clk_get(&pdev
->dev
, "pclk");
474 if (IS_ERR(rk3328
->pclk
)) {
475 dev_err(&pdev
->dev
, "can't get acodec pclk\n");
476 ret
= PTR_ERR(rk3328
->pclk
);
477 goto err_unprepare_mclk
;
480 ret
= clk_prepare_enable(rk3328
->pclk
);
482 dev_err(&pdev
->dev
, "failed to enable acodec pclk\n");
483 goto err_unprepare_mclk
;
486 base
= devm_platform_ioremap_resource(pdev
, 0);
489 goto err_unprepare_pclk
;
492 rk3328
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, base
,
493 &rk3328_codec_regmap_config
);
494 if (IS_ERR(rk3328
->regmap
)) {
495 ret
= PTR_ERR(rk3328
->regmap
);
496 goto err_unprepare_pclk
;
499 platform_set_drvdata(pdev
, rk3328
);
501 ret
= devm_snd_soc_register_component(&pdev
->dev
, &soc_codec_rk3328
,
503 ARRAY_SIZE(rk3328_dai
));
505 goto err_unprepare_pclk
;
510 clk_disable_unprepare(rk3328
->pclk
);
513 clk_disable_unprepare(rk3328
->mclk
);
517 static const struct of_device_id rk3328_codec_of_match
[] __maybe_unused
= {
518 { .compatible
= "rockchip,rk3328-codec", },
521 MODULE_DEVICE_TABLE(of
, rk3328_codec_of_match
);
523 static struct platform_driver rk3328_codec_driver
= {
525 .name
= "rk3328-codec",
526 .of_match_table
= of_match_ptr(rk3328_codec_of_match
),
528 .probe
= rk3328_platform_probe
,
530 module_platform_driver(rk3328_codec_driver
);
532 MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>");
533 MODULE_DESCRIPTION("ASoC rk3328 codec driver");
534 MODULE_LICENSE("GPL v2");