rk3328_codec.c (14442B)
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/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" 20 21/* 22 * volume setting 23 * 0: -39dB 24 * 26: 0dB 25 * 31: 6dB 26 * Step: 1.5dB 27 */ 28#define OUT_VOLUME (0x18) 29#define RK3328_GRF_SOC_CON2 (0x0408) 30#define RK3328_GRF_SOC_CON10 (0x0428) 31#define INITIAL_FREQ (11289600) 32 33struct 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 */ 40}; 41 42static 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 }, 55}; 56 57static int rk3328_codec_reset(struct rk3328_codec_priv *rk3328) 58{ 59 regmap_write(rk3328->regmap, CODEC_RESET, 0x00); 60 mdelay(10); 61 regmap_write(rk3328->regmap, CODEC_RESET, 0x03); 62 63 return 0; 64} 65 66static int rk3328_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 67{ 68 struct rk3328_codec_priv *rk3328 = 69 snd_soc_component_get_drvdata(dai->component); 70 unsigned int val; 71 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; 81 } 82 83 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL1, 84 PIN_DIRECTION_MASK | DAC_I2S_MODE_MASK, val); 85 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; 102 } 103 104 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL2, 105 DAC_MODE_MASK, val); 106 107 return 0; 108} 109 110static int rk3328_mute_stream(struct snd_soc_dai *dai, int mute, int direction) 111{ 112 struct rk3328_codec_priv *rk3328 = 113 snd_soc_component_get_drvdata(dai->component); 114 unsigned int val; 115 116 if (mute) 117 val = HPOUTL_MUTE | HPOUTR_MUTE; 118 else 119 val = HPOUTL_UNMUTE | HPOUTR_UNMUTE; 120 121 regmap_update_bits(rk3328->regmap, HPOUT_CTRL, 122 HPOUTL_MUTE_MASK | HPOUTR_MUTE_MASK, val); 123 124 return 0; 125} 126 127static int rk3328_codec_power_on(struct rk3328_codec_priv *rk3328, int wait_ms) 128{ 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); 136 137 return 0; 138} 139 140static int rk3328_codec_power_off(struct rk3328_codec_priv *rk3328, int wait_ms) 141{ 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); 149 150 return 0; 151} 152 153static 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 }, 180}; 181 182static int rk3328_codec_open_playback(struct rk3328_codec_priv *rk3328) 183{ 184 int i; 185 186 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL, 187 DAC_CHARGE_CURRENT_ALL_MASK, 188 DAC_CHARGE_CURRENT_I); 189 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); 196 } 197 198 msleep(rk3328->spk_depop_time); 199 gpiod_set_value(rk3328->mute, 0); 200 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); 205 206 return 0; 207} 208 209static 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 }, 234}; 235 236static int rk3328_codec_close_playback(struct rk3328_codec_priv *rk3328) 237{ 238 size_t i; 239 240 gpiod_set_value(rk3328->mute, 1); 241 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); 246 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); 253 } 254 255 /* Workaround for silence when changed Fs 48 -> 44.1kHz */ 256 rk3328_codec_reset(rk3328); 257 258 regmap_update_bits(rk3328->regmap, DAC_PRECHARGE_CTRL, 259 DAC_CHARGE_CURRENT_ALL_MASK, 260 DAC_CHARGE_CURRENT_ALL_ON); 261 262 return 0; 263} 264 265static int rk3328_hw_params(struct snd_pcm_substream *substream, 266 struct snd_pcm_hw_params *params, 267 struct snd_soc_dai *dai) 268{ 269 struct rk3328_codec_priv *rk3328 = 270 snd_soc_component_get_drvdata(dai->component); 271 unsigned int val = 0; 272 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; 288 } 289 regmap_update_bits(rk3328->regmap, DAC_INIT_CTRL2, DAC_VDL_MASK, val); 290 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); 294 295 return 0; 296} 297 298static int rk3328_pcm_startup(struct snd_pcm_substream *substream, 299 struct snd_soc_dai *dai) 300{ 301 struct rk3328_codec_priv *rk3328 = 302 snd_soc_component_get_drvdata(dai->component); 303 304 return rk3328_codec_open_playback(rk3328); 305} 306 307static void rk3328_pcm_shutdown(struct snd_pcm_substream *substream, 308 struct snd_soc_dai *dai) 309{ 310 struct rk3328_codec_priv *rk3328 = 311 snd_soc_component_get_drvdata(dai->component); 312 313 rk3328_codec_close_playback(rk3328); 314} 315 316static 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, 323}; 324 325static struct snd_soc_dai_driver rk3328_dai[] = { 326 { 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), 338 }, 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), 348 }, 349 .ops = &rk3328_dai_ops, 350 }, 351}; 352 353static int rk3328_codec_probe(struct snd_soc_component *component) 354{ 355 struct rk3328_codec_priv *rk3328 = 356 snd_soc_component_get_drvdata(component); 357 358 rk3328_codec_reset(rk3328); 359 rk3328_codec_power_on(rk3328, 0); 360 361 return 0; 362} 363 364static void rk3328_codec_remove(struct snd_soc_component *component) 365{ 366 struct rk3328_codec_priv *rk3328 = 367 snd_soc_component_get_drvdata(component); 368 369 rk3328_codec_close_playback(rk3328); 370 rk3328_codec_power_off(rk3328, 0); 371} 372 373static const struct snd_soc_component_driver soc_codec_rk3328 = { 374 .probe = rk3328_codec_probe, 375 .remove = rk3328_codec_remove, 376}; 377 378static bool rk3328_codec_write_read_reg(struct device *dev, unsigned int reg) 379{ 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; 397 } 398} 399 400static bool rk3328_codec_volatile_reg(struct device *dev, unsigned int reg) 401{ 402 switch (reg) { 403 case CODEC_RESET: 404 return true; 405 default: 406 return false; 407 } 408} 409 410static 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, 421}; 422 423static int rk3328_platform_probe(struct platform_device *pdev) 424{ 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; 430 431 rk3328 = devm_kzalloc(&pdev->dev, sizeof(*rk3328), GFP_KERNEL); 432 if (!rk3328) 433 return -ENOMEM; 434 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); 440 } 441 /* enable i2s_acodec_en */ 442 regmap_write(grf, RK3328_GRF_SOC_CON2, 443 (BIT(14) << 16 | BIT(14))); 444 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; 450 } 451 452 rk3328->mute = gpiod_get_optional(&pdev->dev, "mute", GPIOD_OUT_HIGH); 453 if (IS_ERR(rk3328->mute)) 454 return PTR_ERR(rk3328->mute); 455 /* 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. 459 */ 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)); 463 } 464 465 rk3328->mclk = devm_clk_get(&pdev->dev, "mclk"); 466 if (IS_ERR(rk3328->mclk)) 467 return PTR_ERR(rk3328->mclk); 468 469 ret = clk_prepare_enable(rk3328->mclk); 470 if (ret) 471 return ret; 472 clk_set_rate(rk3328->mclk, INITIAL_FREQ); 473 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 ret = PTR_ERR(rk3328->pclk); 478 goto err_unprepare_mclk; 479 } 480 481 ret = clk_prepare_enable(rk3328->pclk); 482 if (ret < 0) { 483 dev_err(&pdev->dev, "failed to enable acodec pclk\n"); 484 goto err_unprepare_mclk; 485 } 486 487 base = devm_platform_ioremap_resource(pdev, 0); 488 if (IS_ERR(base)) { 489 ret = PTR_ERR(base); 490 goto err_unprepare_pclk; 491 } 492 493 rk3328->regmap = devm_regmap_init_mmio(&pdev->dev, base, 494 &rk3328_codec_regmap_config); 495 if (IS_ERR(rk3328->regmap)) { 496 ret = PTR_ERR(rk3328->regmap); 497 goto err_unprepare_pclk; 498 } 499 500 platform_set_drvdata(pdev, rk3328); 501 502 ret = devm_snd_soc_register_component(&pdev->dev, &soc_codec_rk3328, 503 rk3328_dai, 504 ARRAY_SIZE(rk3328_dai)); 505 if (ret) 506 goto err_unprepare_pclk; 507 508 return 0; 509 510err_unprepare_pclk: 511 clk_disable_unprepare(rk3328->pclk); 512 513err_unprepare_mclk: 514 clk_disable_unprepare(rk3328->mclk); 515 return ret; 516} 517 518static const struct of_device_id rk3328_codec_of_match[] __maybe_unused = { 519 { .compatible = "rockchip,rk3328-codec", }, 520 {}, 521}; 522MODULE_DEVICE_TABLE(of, rk3328_codec_of_match); 523 524static struct platform_driver rk3328_codec_driver = { 525 .driver = { 526 .name = "rk3328-codec", 527 .of_match_table = of_match_ptr(rk3328_codec_of_match), 528 }, 529 .probe = rk3328_platform_probe, 530}; 531module_platform_driver(rk3328_codec_driver); 532 533MODULE_AUTHOR("Sugar Zhang <sugar.zhang@rock-chips.com>"); 534MODULE_DESCRIPTION("ASoC rk3328 codec driver"); 535MODULE_LICENSE("GPL v2");