aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/rt5514.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/rt5514.c')
-rw-r--r--sound/soc/codecs/rt5514.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c
index 2dd6e9f990a4..198df016802f 100644
--- a/sound/soc/codecs/rt5514.c
+++ b/sound/soc/codecs/rt5514.c
@@ -295,6 +295,33 @@ static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol,
295 return 0; 295 return 0;
296} 296}
297 297
298static int rt5514_calibration(struct rt5514_priv *rt5514, bool on)
299{
300 if (on) {
301 regmap_write(rt5514->regmap, RT5514_ANA_CTRL_PLL3, 0x0000000a);
302 regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL, 0xf,
303 0xa);
304 regmap_update_bits(rt5514->regmap, RT5514_PWR_ANA1, 0x301,
305 0x301);
306 regmap_write(rt5514->regmap, RT5514_PLL3_CALIB_CTRL4,
307 0x80000000 | rt5514->pll3_cal_value);
308 regmap_write(rt5514->regmap, RT5514_PLL3_CALIB_CTRL1,
309 0x8bb80800);
310 regmap_update_bits(rt5514->regmap, RT5514_PLL3_CALIB_CTRL5,
311 0xc0000000, 0x80000000);
312 regmap_update_bits(rt5514->regmap, RT5514_PLL3_CALIB_CTRL5,
313 0xc0000000, 0xc0000000);
314 } else {
315 regmap_update_bits(rt5514->regmap, RT5514_PLL3_CALIB_CTRL5,
316 0xc0000000, 0x40000000);
317 regmap_update_bits(rt5514->regmap, RT5514_PWR_ANA1, 0x301, 0);
318 regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL, 0xf,
319 0x4);
320 }
321
322 return 0;
323}
324
298static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, 325static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
299 struct snd_ctl_elem_value *ucontrol) 326 struct snd_ctl_elem_value *ucontrol)
300{ 327{
@@ -302,6 +329,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
302 struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component); 329 struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component);
303 struct snd_soc_codec *codec = rt5514->codec; 330 struct snd_soc_codec *codec = rt5514->codec;
304 const struct firmware *fw = NULL; 331 const struct firmware *fw = NULL;
332 u8 buf[8];
305 333
306 if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled) 334 if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled)
307 return 0; 335 return 0;
@@ -310,6 +338,35 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
310 rt5514->dsp_enabled = ucontrol->value.integer.value[0]; 338 rt5514->dsp_enabled = ucontrol->value.integer.value[0];
311 339
312 if (rt5514->dsp_enabled) { 340 if (rt5514->dsp_enabled) {
341 if (rt5514->pdata.dsp_calib_clk_name &&
342 !IS_ERR(rt5514->dsp_calib_clk)) {
343 if (clk_set_rate(rt5514->dsp_calib_clk,
344 rt5514->pdata.dsp_calib_clk_rate))
345 dev_err(codec->dev,
346 "Can't set rate for mclk");
347
348 if (clk_prepare_enable(rt5514->dsp_calib_clk))
349 dev_err(codec->dev,
350 "Can't enable dsp_calib_clk");
351
352 rt5514_calibration(rt5514, true);
353
354 msleep(20);
355#if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI)
356 rt5514_spi_burst_read(RT5514_PLL3_CALIB_CTRL6 |
357 RT5514_DSP_MAPPING,
358 (u8 *)&buf, sizeof(buf));
359#else
360 dev_err(codec->dev, "There is no SPI driver for"
361 " loading the firmware\n");
362#endif
363 rt5514->pll3_cal_value = buf[0] | buf[1] << 8 |
364 buf[2] << 16 | buf[3] << 24;
365
366 rt5514_calibration(rt5514, false);
367 clk_disable_unprepare(rt5514->dsp_calib_clk);
368 }
369
313 rt5514_enable_dsp_prepare(rt5514); 370 rt5514_enable_dsp_prepare(rt5514);
314 371
315 request_firmware(&fw, RT5514_FIRMWARE1, codec->dev); 372 request_firmware(&fw, RT5514_FIRMWARE1, codec->dev);
@@ -341,6 +398,20 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol,
341 /* DSP run */ 398 /* DSP run */
342 regmap_write(rt5514->i2c_regmap, 0x18002f00, 399 regmap_write(rt5514->i2c_regmap, 0x18002f00,
343 0x00055148); 400 0x00055148);
401
402 if (rt5514->pdata.dsp_calib_clk_name &&
403 !IS_ERR(rt5514->dsp_calib_clk)) {
404 msleep(20);
405
406 regmap_write(rt5514->i2c_regmap, 0x1800211c,
407 rt5514->pll3_cal_value);
408 regmap_write(rt5514->i2c_regmap, 0x18002124,
409 0x00220012);
410 regmap_write(rt5514->i2c_regmap, 0x18002124,
411 0x80220042);
412 regmap_write(rt5514->i2c_regmap, 0x18002124,
413 0xe0220042);
414 }
344 } else { 415 } else {
345 regmap_multi_reg_write(rt5514->i2c_regmap, 416 regmap_multi_reg_write(rt5514->i2c_regmap,
346 rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch)); 417 rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch));
@@ -1024,12 +1095,22 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec,
1024static int rt5514_probe(struct snd_soc_codec *codec) 1095static int rt5514_probe(struct snd_soc_codec *codec)
1025{ 1096{
1026 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); 1097 struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec);
1098 struct platform_device *pdev = container_of(codec->dev,
1099 struct platform_device, dev);
1027 1100
1028 rt5514->mclk = devm_clk_get(codec->dev, "mclk"); 1101 rt5514->mclk = devm_clk_get(codec->dev, "mclk");
1029 if (PTR_ERR(rt5514->mclk) == -EPROBE_DEFER) 1102 if (PTR_ERR(rt5514->mclk) == -EPROBE_DEFER)
1030 return -EPROBE_DEFER; 1103 return -EPROBE_DEFER;
1031 1104
1105 if (rt5514->pdata.dsp_calib_clk_name) {
1106 rt5514->dsp_calib_clk = devm_clk_get(&pdev->dev,
1107 rt5514->pdata.dsp_calib_clk_name);
1108 if (PTR_ERR(rt5514->dsp_calib_clk) == -EPROBE_DEFER)
1109 return -EPROBE_DEFER;
1110 }
1111
1032 rt5514->codec = codec; 1112 rt5514->codec = codec;
1113 rt5514->pll3_cal_value = 0x0078b000;
1033 1114
1034 return 0; 1115 return 0;
1035} 1116}
@@ -1147,6 +1228,10 @@ static int rt5514_parse_dp(struct rt5514_priv *rt5514, struct device *dev)
1147{ 1228{
1148 device_property_read_u32(dev, "realtek,dmic-init-delay-ms", 1229 device_property_read_u32(dev, "realtek,dmic-init-delay-ms",
1149 &rt5514->pdata.dmic_init_delay); 1230 &rt5514->pdata.dmic_init_delay);
1231 device_property_read_string(dev, "realtek,dsp-calib-clk-name",
1232 &rt5514->pdata.dsp_calib_clk_name);
1233 device_property_read_u32(dev, "realtek,dsp-calib-clk-rate",
1234 &rt5514->pdata.dsp_calib_clk_rate);
1150 1235
1151 return 0; 1236 return 0;
1152} 1237}