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/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"
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
;
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 },
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);
61 regmap_write(rk3328
->regmap
, CODEC_RESET
, 0x03);
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
);
72 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
73 case SND_SOC_DAIFMT_CBS_CFS
:
74 val
= PIN_DIRECTION_IN
| DAC_I2S_MODE_SLAVE
;
76 case SND_SOC_DAIFMT_CBM_CFM
:
77 val
= PIN_DIRECTION_OUT
| DAC_I2S_MODE_MASTER
;
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
:
91 case SND_SOC_DAIFMT_I2S
:
94 case SND_SOC_DAIFMT_RIGHT_J
:
97 case SND_SOC_DAIFMT_LEFT_J
:
104 regmap_update_bits(rk3328
->regmap
, DAC_INIT_CTRL2
,
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
);
117 val
= HPOUTL_MUTE
| HPOUTR_MUTE
;
119 val
= HPOUTL_UNMUTE
| HPOUTR_UNMUTE
;
121 regmap_update_bits(rk3328
->regmap
, HPOUT_CTRL
,
122 HPOUTL_MUTE_MASK
| HPOUTR_MUTE_MASK
, val
);
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
);
132 regmap_update_bits(rk3328
->regmap
, DAC_PRECHARGE_CTRL
,
133 DAC_CHARGE_CURRENT_ALL_MASK
,
134 DAC_CHARGE_CURRENT_ALL_ON
);
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
);
145 regmap_update_bits(rk3328
->regmap
, DAC_PRECHARGE_CTRL
,
146 DAC_CHARGE_CURRENT_ALL_MASK
,
147 DAC_CHARGE_CURRENT_ALL_ON
);
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
)
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
);
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
);
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
)
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
);
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
);
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
;
277 case SNDRV_PCM_FORMAT_S20_3LE
:
278 val
= DAC_VDL_20BITS
;
280 case SNDRV_PCM_FORMAT_S24_LE
:
281 val
= DAC_VDL_24BITS
;
283 case SNDRV_PCM_FORMAT_S32_LE
:
284 val
= DAC_VDL_32BITS
;
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
);
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",
330 .stream_name
= "HIFI Playback",
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
),
340 .stream_name
= "HIFI Capture",
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);
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
)
385 case DAC_PRECHARGE_CTRL
:
391 case HPOUTL_GAIN_CTRL
:
392 case HPOUTR_GAIN_CTRL
:
400 static bool rk3328_codec_volatile_reg(struct device
*dev
, unsigned int reg
)
410 static const struct regmap_config rk3328_codec_regmap_config
= {
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
;
431 rk3328
= devm_kzalloc(&pdev
->dev
, sizeof(*rk3328
), GFP_KERNEL
);
435 grf
= syscon_regmap_lookup_by_phandle(rk3328_np
,
438 dev_err(&pdev
->dev
, "missing 'rockchip,grf'\n");
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
);
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
);
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
);
482 dev_err(&pdev
->dev
, "failed to enable acodec pclk\n");
486 base
= devm_platform_ioremap_resource(pdev
, 0);
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
,
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
= {
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");