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. 6 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/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" 19 20 /* 21 * volume setting 22 * 0: -39dB 23 * 26: 0dB 24 * 31: 6dB 25 * Step: 1.5dB 26 */ 27 #define OUT_VOLUME (0x18) 28 #define RK3328_GRF_SOC_CON2 (0x0408) 29 #define RK3328_GRF_SOC_CON10 (0x0428) 30 #define INITIAL_FREQ (11289600) 31 32 struct rk3328_codec_priv { 33 struct regmap *regmap; 34 struct gpio_desc *mute; 35 struct clk *mclk; 36 struct clk *pclk; 37 unsigned int sclk; 38 int spk_depop_time; /* msec */ 39 }; 40 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 }, 49 { HPMIX_CTRL, 0x00 }, 50 { HPOUT_CTRL, 0x00 }, 51 { HPOUTL_GAIN_CTRL, 0x00 }, 52 { HPOUTR_GAIN_CTRL, 0x00 }, 53 { HPOUT_POP_CTRL, 0x11 }, 54 }; 55 56 static int rk3328_codec_reset(struct rk3328_codec_priv *rk3328) 57 { 58 regmap_write(rk3328->regmap, CODEC_RESET, 0x00); 59 mdelay(10); 60 regmap_write(rk3328->regmap, CODEC_RESET, 0x03); 61 62 return 0; 63 } 64 65 static int rk3328_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 66 { 67 struct rk3328_codec_priv *rk3328 = 68 snd_soc_component_get_drvdata(dai->component); 69 unsigned int val; 70 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; 74 break; 75 case SND_SOC_DAIFMT_CBP_CFP: 76 val = PIN_DIRECTION_OUT | DAC_I2S_MODE_MASTER; 77 break; 78 default: 79 return -EINVAL; 80 } 81 82 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL1, 83 PIN_DIRECTION_MASK | DAC_I2S_MODE_MASK, val); 84 85 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 86 case SND_SOC_DAIFMT_DSP_A: 87 case SND_SOC_DAIFMT_DSP_B: 88 val = DAC_MODE_PCM; 89 break; 90 case SND_SOC_DAIFMT_I2S: 91 val = DAC_MODE_I2S; 92 break; 93 case SND_SOC_DAIFMT_RIGHT_J: 94 val = DAC_MODE_RJM; 95 break; 96 case SND_SOC_DAIFMT_LEFT_J: 97 val = DAC_MODE_LJM; 98 break; 99 default: 100 return -EINVAL; 101 } 102 103 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL2, 104 DAC_MODE_MASK, val); 105 106 return 0; 107 } 108 109 static int rk3328_mute_stream(struct snd_soc_dai *dai, int mute, int direction) 110 { 111 struct rk3328_codec_priv *rk3328 = 112 snd_soc_component_get_drvdata(dai->component); 113 unsigned int val; 114 115 if (mute) 116 val = HPOUTL_MUTE | HPOUTR_MUTE; 117 else 118 val = HPOUTL_UNMUTE | HPOUTR_UNMUTE; 119 120 regmap_update_bits(rk3328->regmap, HPOUT_CTRL, 121 HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK, val); 122 123 return 0; 124 } 125 126 static int rk3328_codec_power_on(struct rk3328_codec_priv *rk3328, int wait_ms) 127 { 128 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL, 129 DAC_CHARGE_XCHARGE_MASK, DAC_CHARGE_PRECHARGE); 130 mdelay(10); 131 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL, 132 DAC_CHARGE_CURRENT_ALL_MASK, 133 DAC_CHARGE_CURRENT_ALL_ON); 134 mdelay(wait_ms); 135 136 return 0; 137 } 138 139 static int rk3328_codec_power_off(struct rk3328_codec_priv *rk3328, int wait_ms) 140 { 141 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL, 142 DAC_CHARGE_XCHARGE_MASK, DAC_CHARGE_DISCHARGE); 143 mdelay(10); 144 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL, 145 DAC_CHARGE_CURRENT_ALL_MASK, 146 DAC_CHARGE_CURRENT_ALL_ON); 147 mdelay(wait_ms); 148 149 return 0; 150 } 151 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 }, 179 }; 180 181 static int rk3328_codec_open_playback(struct rk3328_codec_priv *rk3328) 182 { 183 int i; 184 185 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL, 186 DAC_CHARGE_CURRENT_ALL_MASK, 187 DAC_CHARGE_CURRENT_I); 188 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); 194 mdelay(1); 195 } 196 197 msleep(rk3328->spk_depop_time); 198 gpiod_set_value(rk3328->mute, 0); 199 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); 204 205 return 0; 206 } 207 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 }, 233 }; 234 235 static int rk3328_codec_close_playback(struct rk3328_codec_priv *rk3328) 236 { 237 size_t i; 238 239 gpiod_set_value(rk3328->mute, 1); 240 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); 245 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); 251 mdelay(1); 252 } 253 254 /* Workaround for silence when changed Fs 48 -> 44.1kHz */ 255 rk3328_codec_reset(rk3328); 256 257 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL, 258 DAC_CHARGE_CURRENT_ALL_MASK, 259 DAC_CHARGE_CURRENT_ALL_ON); 260 261 return 0; 262 } 263 264 static int rk3328_hw_params(struct snd_pcm_substream *substream, 265 struct snd_pcm_hw_params *params, 266 struct snd_soc_dai *dai) 267 { 268 struct rk3328_codec_priv *rk3328 = 269 snd_soc_component_get_drvdata(dai->component); 270 unsigned int val = 0; 271 272 switch (params_format(params)) { 273 case SNDRV_PCM_FORMAT_S16_LE: 274 val = DAC_VDL_16BITS; 275 break; 276 case SNDRV_PCM_FORMAT_S20_3LE: 277 val = DAC_VDL_20BITS; 278 break; 279 case SNDRV_PCM_FORMAT_S24_LE: 280 val = DAC_VDL_24BITS; 281 break; 282 case SNDRV_PCM_FORMAT_S32_LE: 283 val = DAC_VDL_32BITS; 284 break; 285 default: 286 return -EINVAL; 287 } 288 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL2, DAC_VDL_MASK, val); 289 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); 293 294 return 0; 295 } 296 297 static int rk3328_pcm_startup(struct snd_pcm_substream *substream, 298 struct snd_soc_dai *dai) 299 { 300 struct rk3328_codec_priv *rk3328 = 301 snd_soc_component_get_drvdata(dai->component); 302 303 return rk3328_codec_open_playback(rk3328); 304 } 305 306 static void rk3328_pcm_shutdown(struct snd_pcm_substream *substream, 307 struct snd_soc_dai *dai) 308 { 309 struct rk3328_codec_priv *rk3328 = 310 snd_soc_component_get_drvdata(dai->component); 311 312 rk3328_codec_close_playback(rk3328); 313 } 314 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, 322 }; 323 324 static struct snd_soc_dai_driver rk3328_dai[] = { 325 { 326 .name = "rk3328-hifi", 327 .id = RK3328_HIFI, 328 .playback = { 329 .stream_name = "HIFI Playback", 330 .channels_min = 1, 331 .channels_max = 2, 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), 337 }, 338 .capture = { 339 .stream_name = "HIFI Capture", 340 .channels_min = 2, 341 .channels_max = 8, 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), 347 }, 348 .ops = &rk3328_dai_ops, 349 }, 350 }; 351 352 static int rk3328_codec_probe(struct snd_soc_component *component) 353 { 354 struct rk3328_codec_priv *rk3328 = 355 snd_soc_component_get_drvdata(component); 356 357 rk3328_codec_reset(rk3328); 358 rk3328_codec_power_on(rk3328, 0); 359 360 return 0; 361 } 362 363 static void rk3328_codec_remove(struct snd_soc_component *component) 364 { 365 struct rk3328_codec_priv *rk3328 = 366 snd_soc_component_get_drvdata(component); 367 368 rk3328_codec_close_playback(rk3328); 369 rk3328_codec_power_off(rk3328, 0); 370 } 371 372 static const struct snd_soc_component_driver soc_codec_rk3328 = { 373 .probe = rk3328_codec_probe, 374 .remove = rk3328_codec_remove, 375 }; 376 377 static bool rk3328_codec_write_read_reg(struct device *dev, unsigned int reg) 378 { 379 switch (reg) { 380 case CODEC_RESET: 381 case DAC_INIT_CTRL1: 382 case DAC_INIT_CTRL2: 383 case DAC_INIT_CTRL3: 384 case DAC_PRECHARGE_CTRL: 385 case DAC_PWR_CTRL: 386 case DAC_CLK_CTRL: 387 case HPMIX_CTRL: 388 case DAC_SELECT: 389 case HPOUT_CTRL: 390 case HPOUTL_GAIN_CTRL: 391 case HPOUTR_GAIN_CTRL: 392 case HPOUT_POP_CTRL: 393 return true; 394 default: 395 return false; 396 } 397 } 398 399 static bool rk3328_codec_volatile_reg(struct device *dev, unsigned int reg) 400 { 401 switch (reg) { 402 case CODEC_RESET: 403 return true; 404 default: 405 return false; 406 } 407 } 408 409 static const struct regmap_config rk3328_codec_regmap_config = { 410 .reg_bits = 32, 411 .reg_stride = 4, 412 .val_bits = 32, 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, 420 }; 421 422 static int rk3328_platform_probe(struct platform_device *pdev) 423 { 424 struct device_node *rk3328_np = pdev->dev.of_node; 425 struct rk3328_codec_priv *rk3328; 426 struct regmap *grf; 427 void __iomem *base; 428 int ret = 0; 429 430 rk3328 = devm_kzalloc(&pdev->dev, sizeof(*rk3328), GFP_KERNEL); 431 if (!rk3328) 432 return -ENOMEM; 433 434 grf = syscon_regmap_lookup_by_phandle(rk3328_np, 435 "rockchip,grf"); 436 if (IS_ERR(grf)) { 437 dev_err(&pdev->dev, "missing 'rockchip,grf'\n"); 438 return PTR_ERR(grf); 439 } 440 /* enable i2s_acodec_en */ 441 regmap_write(grf, RK3328_GRF_SOC_CON2, 442 (BIT(14) << 16 | BIT(14))); 443 444 ret = of_property_read_u32(rk3328_np, "spk-depop-time-ms", 445 &rk3328->spk_depop_time); 446 if (ret < 0) { 447 dev_info(&pdev->dev, "spk_depop_time use default value.\n"); 448 rk3328->spk_depop_time = 200; 449 } 450 451 rk3328->mute = gpiod_get_optional(&pdev->dev, "mute", GPIOD_OUT_HIGH); 452 if (IS_ERR(rk3328->mute)) 453 return PTR_ERR(rk3328->mute); 454 /* 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. 458 */ 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)); 462 } 463 464 rk3328->mclk = devm_clk_get(&pdev->dev, "mclk"); 465 if (IS_ERR(rk3328->mclk)) 466 return PTR_ERR(rk3328->mclk); 467 468 ret = clk_prepare_enable(rk3328->mclk); 469 if (ret) 470 return ret; 471 clk_set_rate(rk3328->mclk, INITIAL_FREQ); 472 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; 478 } 479 480 ret = clk_prepare_enable(rk3328->pclk); 481 if (ret < 0) { 482 dev_err(&pdev->dev, "failed to enable acodec pclk\n"); 483 goto err_unprepare_mclk; 484 } 485 486 base = devm_platform_ioremap_resource(pdev, 0); 487 if (IS_ERR(base)) { 488 ret = PTR_ERR(base); 489 goto err_unprepare_pclk; 490 } 491 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; 497 } 498 499 platform_set_drvdata(pdev, rk3328); 500 501 ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328, 502 rk3328_dai, 503 ARRAY_SIZE(rk3328_dai)); 504 if (ret) 505 goto err_unprepare_pclk; 506 507 return 0; 508 509 err_unprepare_pclk: 510 clk_disable_unprepare(rk3328->pclk); 511 512 err_unprepare_mclk: 513 clk_disable_unprepare(rk3328->mclk); 514 return ret; 515 } 516 517 static const struct of_device_id rk3328_codec_of_match[] __maybe_unused = { 518 { .compatible = "rockchip,rk3328-codec", }, 519 {}, 520 }; 521 MODULE_DEVICE_TABLE(of, rk3328_codec_of_match); 522 523 static struct platform_driver rk3328_codec_driver = { 524 .driver = { 525 .name = "rk3328-codec", 526 .of_match_table = of_match_ptr(rk3328_codec_of_match), 527 }, 528 .probe = rk3328_platform_probe, 529 }; 530 module_platform_driver(rk3328_codec_driver); 531 532 MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>"); 533 MODULE_DESCRIPTION("ASoC rk3328 codec driver"); 534 MODULE_LICENSE("GPL v2"); 535
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.