.. | .. |
---|
67 | 67 | struct regmap *regmap; |
---|
68 | 68 | struct rk808 *rk817; |
---|
69 | 69 | struct clk *mclk; |
---|
| 70 | + struct mutex clk_lock; |
---|
70 | 71 | |
---|
| 72 | + unsigned int clk_capture; |
---|
| 73 | + unsigned int clk_playback; |
---|
71 | 74 | unsigned int stereo_sysclk; |
---|
72 | 75 | unsigned int rate; |
---|
73 | 76 | |
---|
.. | .. |
---|
79 | 82 | bool pdmdata_out_enable; |
---|
80 | 83 | bool use_ext_amplifier; |
---|
81 | 84 | bool adc_for_loopback; |
---|
| 85 | + bool resume_path; |
---|
82 | 86 | |
---|
83 | 87 | bool out_l2spk_r2hp; |
---|
84 | 88 | long int playback_path; |
---|
.. | .. |
---|
282 | 286 | {RK817_CODEC_AREF_RTCFG1, 0x40}, |
---|
283 | 287 | {RK817_CODEC_DDAC_POPD_DACST, 0x02}, |
---|
284 | 288 | /* APLL */ |
---|
285 | | - {RK817_CODEC_APLL_CFG0, 0x04}, |
---|
| 289 | + /* {RK817_CODEC_APLL_CFG0, 0x04}, */ |
---|
286 | 290 | {RK817_CODEC_APLL_CFG1, 0x58}, |
---|
287 | 291 | {RK817_CODEC_APLL_CFG2, 0x2d}, |
---|
288 | | - {RK817_CODEC_APLL_CFG4, 0xa5}, |
---|
| 292 | + /* {RK817_CODEC_APLL_CFG4, 0xa5}, */ |
---|
289 | 293 | {RK817_CODEC_APLL_CFG5, 0x00}, |
---|
290 | 294 | |
---|
291 | 295 | {RK817_CODEC_DI2S_RXCMD_TSD, 0x00}, |
---|
.. | .. |
---|
320 | 324 | {RK817_CODEC_AREF_RTCFG1, 0x40}, |
---|
321 | 325 | {RK817_CODEC_DADC_SR_ACL0, 0x02}, |
---|
322 | 326 | /* {RK817_CODEC_DTOP_DIGEN_CLKE, 0xff}, */ |
---|
323 | | - {RK817_CODEC_APLL_CFG0, 0x04}, |
---|
| 327 | + /* {RK817_CODEC_APLL_CFG0, 0x04}, */ |
---|
324 | 328 | {RK817_CODEC_APLL_CFG1, 0x58}, |
---|
325 | 329 | {RK817_CODEC_APLL_CFG2, 0x2d}, |
---|
326 | | - {RK817_CODEC_APLL_CFG4, 0xa5}, |
---|
| 330 | + /* {RK817_CODEC_APLL_CFG4, 0xa5}, */ |
---|
327 | 331 | {RK817_CODEC_APLL_CFG5, 0x00}, |
---|
328 | 332 | |
---|
329 | 333 | /*{RK817_CODEC_DI2S_RXCMD_TSD, 0x00},*/ |
---|
.. | .. |
---|
374 | 378 | playback_power_up_list[i].value); |
---|
375 | 379 | } |
---|
376 | 380 | |
---|
377 | | - /* Re-configure APLL CFG0/4 if (chip_ver <= 0x4) */ |
---|
| 381 | + /* configure APLL CFG0/4 */ |
---|
378 | 382 | if (rk817->chip_ver <= 0x4) { |
---|
379 | 383 | DBG("%s (%d): SMIC TudorAG and previous versions\n", |
---|
380 | 384 | __func__, __LINE__); |
---|
381 | 385 | snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); |
---|
382 | 386 | snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); |
---|
| 387 | + } else { |
---|
| 388 | + DBG("%s: SMIC TudorAG version later\n", __func__); |
---|
| 389 | + snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); |
---|
| 390 | + snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); |
---|
383 | 391 | } |
---|
384 | 392 | |
---|
385 | 393 | snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
.. | .. |
---|
401 | 409 | capture_power_up_list[i].value); |
---|
402 | 410 | } |
---|
403 | 411 | |
---|
404 | | - /* Re-configure APLL CFG0/4 if (chip_ver <= 0x4) */ |
---|
| 412 | + /* configure APLL CFG0/4 */ |
---|
405 | 413 | if (rk817->chip_ver <= 0x4) { |
---|
406 | 414 | DBG("%s (%d): SMIC TudorAG and previous versions\n", |
---|
407 | 415 | __func__, __LINE__); |
---|
408 | 416 | snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x0c); |
---|
409 | 417 | snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0x95); |
---|
| 418 | + } else { |
---|
| 419 | + DBG("%s: SMIC TudorAG version later\n", __func__); |
---|
| 420 | + snd_soc_component_write(component, RK817_CODEC_APLL_CFG0, 0x04); |
---|
| 421 | + snd_soc_component_write(component, RK817_CODEC_APLL_CFG4, 0xa5); |
---|
410 | 422 | } |
---|
411 | 423 | |
---|
412 | 424 | snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
413 | | - ADC_DIG_CLK_MASK, DAC_DIG_CLK_DIS); |
---|
| 425 | + ADC_DIG_CLK_MASK, ADC_DIG_CLK_DIS); |
---|
414 | 426 | usleep_range(2000, 2500); |
---|
415 | 427 | snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
416 | 428 | ADC_DIG_CLK_MASK, ADC_DIG_CLK_EN); |
---|
.. | .. |
---|
506 | 518 | static const char * const rk817_capture_path_mode[] = { |
---|
507 | 519 | "MIC OFF", "Main Mic", "Hands Free Mic", "BT Sco Mic"}; |
---|
508 | 520 | |
---|
509 | | -static const char * const rk817_call_path_mode[] = { |
---|
510 | | - "OFF", "RCV", "SPK", "HP", "HP_NO_MIC", "BT"}; /* 0-5 */ |
---|
511 | | - |
---|
512 | | -static const char * const rk817_modem_input_mode[] = {"OFF", "ON"}; |
---|
| 521 | +static const char * const rk817_binary_mode[] = {"OFF", "ON"}; |
---|
513 | 522 | |
---|
514 | 523 | static SOC_ENUM_SINGLE_DECL(rk817_playback_path_type, |
---|
515 | 524 | 0, 0, rk817_playback_path_mode); |
---|
.. | .. |
---|
517 | 526 | static SOC_ENUM_SINGLE_DECL(rk817_capture_path_type, |
---|
518 | 527 | 0, 0, rk817_capture_path_mode); |
---|
519 | 528 | |
---|
520 | | -static SOC_ENUM_SINGLE_DECL(rk817_call_path_type, |
---|
521 | | - 0, 0, rk817_call_path_mode); |
---|
522 | | - |
---|
523 | | -static SOC_ENUM_SINGLE_DECL(rk817_modem_input_type, |
---|
524 | | - 0, 0, rk817_modem_input_mode); |
---|
| 529 | +static SOC_ENUM_SINGLE_DECL(rk817_resume_path_type, |
---|
| 530 | + 0, 0, rk817_binary_mode); |
---|
525 | 531 | |
---|
526 | 532 | static int rk817_playback_path_config(struct snd_soc_component *component, |
---|
527 | 533 | long pre_path, long target_path) |
---|
.. | .. |
---|
533 | 539 | DBG("%s : set playback_path %ld, pre_path %ld\n", |
---|
534 | 540 | __func__, rk817->playback_path, pre_path); |
---|
535 | 541 | |
---|
536 | | - if (rk817->playback_path != OFF) |
---|
537 | | - clk_prepare_enable(rk817->mclk); |
---|
538 | | - else |
---|
539 | | - clk_disable_unprepare(rk817->mclk); |
---|
| 542 | + mutex_lock(&rk817->clk_lock); |
---|
| 543 | + if (rk817->playback_path != OFF) { |
---|
| 544 | + if (rk817->clk_playback == 0) { |
---|
| 545 | + clk_prepare_enable(rk817->mclk); |
---|
| 546 | + rk817->clk_playback++; |
---|
| 547 | + } |
---|
| 548 | + } else { |
---|
| 549 | + if (rk817->clk_playback > 0) { |
---|
| 550 | + clk_disable_unprepare(rk817->mclk); |
---|
| 551 | + rk817->clk_playback--; |
---|
| 552 | + } |
---|
| 553 | + } |
---|
| 554 | + mutex_unlock(&rk817->clk_lock); |
---|
540 | 555 | |
---|
541 | 556 | switch (rk817->playback_path) { |
---|
542 | 557 | case OFF: |
---|
.. | .. |
---|
720 | 735 | DBG("%s : set capture_path %ld, pre_path %ld\n", __func__, |
---|
721 | 736 | rk817->capture_path, pre_path); |
---|
722 | 737 | |
---|
723 | | - if (rk817->capture_path != MIC_OFF) |
---|
724 | | - clk_prepare_enable(rk817->mclk); |
---|
725 | | - else |
---|
726 | | - clk_disable_unprepare(rk817->mclk); |
---|
| 738 | + mutex_lock(&rk817->clk_lock); |
---|
| 739 | + if (rk817->capture_path != MIC_OFF) { |
---|
| 740 | + if (rk817->clk_capture == 0) { |
---|
| 741 | + clk_prepare_enable(rk817->mclk); |
---|
| 742 | + rk817->clk_capture++; |
---|
| 743 | + } |
---|
| 744 | + } else { |
---|
| 745 | + if (rk817->clk_capture > 0) { |
---|
| 746 | + clk_disable_unprepare(rk817->mclk); |
---|
| 747 | + rk817->clk_capture--; |
---|
| 748 | + } |
---|
| 749 | + } |
---|
| 750 | + mutex_unlock(&rk817->clk_lock); |
---|
727 | 751 | |
---|
728 | 752 | switch (rk817->capture_path) { |
---|
729 | 753 | case MIC_OFF: |
---|
.. | .. |
---|
842 | 866 | ucontrol->value.integer.value[0]); |
---|
843 | 867 | } |
---|
844 | 868 | |
---|
| 869 | +static int rk817_resume_path_get(struct snd_kcontrol *kcontrol, |
---|
| 870 | + struct snd_ctl_elem_value *ucontrol) |
---|
| 871 | +{ |
---|
| 872 | + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
---|
| 873 | + struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); |
---|
| 874 | + |
---|
| 875 | + DBG("%s : resume_path %ld\n", __func__, rk817->resume_path); |
---|
| 876 | + |
---|
| 877 | + ucontrol->value.integer.value[0] = rk817->resume_path; |
---|
| 878 | + |
---|
| 879 | + return 0; |
---|
| 880 | +} |
---|
| 881 | + |
---|
| 882 | +static int rk817_resume_path_put(struct snd_kcontrol *kcontrol, |
---|
| 883 | + struct snd_ctl_elem_value *ucontrol) |
---|
| 884 | +{ |
---|
| 885 | + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
---|
| 886 | + struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); |
---|
| 887 | + |
---|
| 888 | + rk817->resume_path = ucontrol->value.integer.value[0]; |
---|
| 889 | + |
---|
| 890 | + return 0; |
---|
| 891 | +} |
---|
| 892 | + |
---|
845 | 893 | static struct snd_kcontrol_new rk817_snd_path_controls[] = { |
---|
846 | 894 | SOC_ENUM_EXT("Playback Path", rk817_playback_path_type, |
---|
847 | 895 | rk817_playback_path_get, rk817_playback_path_put), |
---|
848 | 896 | |
---|
849 | 897 | SOC_ENUM_EXT("Capture MIC Path", rk817_capture_path_type, |
---|
850 | 898 | rk817_capture_path_get, rk817_capture_path_put), |
---|
| 899 | + |
---|
| 900 | + SOC_ENUM_EXT("Resume Path", rk817_resume_path_type, |
---|
| 901 | + rk817_resume_path_get, rk817_resume_path_put), |
---|
851 | 902 | }; |
---|
852 | 903 | |
---|
853 | 904 | static int rk817_set_dai_sysclk(struct snd_soc_dai *codec_dai, |
---|
.. | .. |
---|
892 | 943 | struct snd_pcm_hw_params *params, |
---|
893 | 944 | struct snd_soc_dai *dai) |
---|
894 | 945 | { |
---|
895 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
896 | | - struct snd_soc_component *component = rtd->codec_dai->component; |
---|
| 946 | + struct snd_soc_component *component = dai->component; |
---|
897 | 947 | struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); |
---|
898 | 948 | unsigned int rate = params_rate(params); |
---|
899 | 949 | unsigned char apll_cfg3_val; |
---|
.. | .. |
---|
946 | 996 | * is before playback/capture_path_put, therefore, we need to configure |
---|
947 | 997 | * APLL_CFG3/DTOP_DIGEN_CLKE/DDAC_SR_LMT0 for different sample rates. |
---|
948 | 998 | */ |
---|
949 | | - snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, apll_cfg3_val); |
---|
950 | | - /* The 0x00 contains ADC_DIG_CLK_DIS and DAC_DIG_CLK_DIS */ |
---|
951 | | - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
952 | | - dtop_digen_clke, 0x00); |
---|
953 | | - snd_soc_component_update_bits(component, RK817_CODEC_DDAC_SR_LMT0, |
---|
954 | | - DACSRT_MASK, dtop_digen_sr_lmt0); |
---|
955 | | - snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
956 | | - dtop_digen_clke, dtop_digen_clke); |
---|
| 999 | + if (!((substream->stream == SNDRV_PCM_STREAM_CAPTURE) && rk817->pdmdata_out_enable)) { |
---|
| 1000 | + snd_soc_component_write(component, RK817_CODEC_APLL_CFG3, apll_cfg3_val); |
---|
| 1001 | + /* The 0x00 contains ADC_DIG_CLK_DIS and DAC_DIG_CLK_DIS */ |
---|
| 1002 | + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
| 1003 | + dtop_digen_clke, 0x00); |
---|
| 1004 | + snd_soc_component_update_bits(component, RK817_CODEC_DDAC_SR_LMT0, |
---|
| 1005 | + DACSRT_MASK, dtop_digen_sr_lmt0); |
---|
| 1006 | + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
| 1007 | + dtop_digen_clke, dtop_digen_clke); |
---|
| 1008 | + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, |
---|
| 1009 | + PLL_PW_DOWN, PLL_PW_DOWN); |
---|
| 1010 | + usleep_range(50, 60); |
---|
| 1011 | + snd_soc_component_update_bits(component, RK817_CODEC_APLL_CFG5, |
---|
| 1012 | + PLL_PW_DOWN, PLL_PW_UP); |
---|
| 1013 | + usleep_range(500, 600); |
---|
| 1014 | + } |
---|
957 | 1015 | |
---|
958 | 1016 | switch (params_format(params)) { |
---|
959 | 1017 | case SNDRV_PCM_FORMAT_S16_LE: |
---|
.. | .. |
---|
976 | 1034 | return 0; |
---|
977 | 1035 | } |
---|
978 | 1036 | |
---|
979 | | -static int rk817_digital_mute(struct snd_soc_dai *dai, int mute) |
---|
| 1037 | +static int rk817_digital_mute_dac(struct snd_soc_dai *dai, int mute, int stream) |
---|
980 | 1038 | { |
---|
981 | 1039 | struct snd_soc_component *component = dai->component; |
---|
982 | 1040 | struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); |
---|
.. | .. |
---|
998 | 1056 | DAC_DIG_CLK_EN, DAC_DIG_CLK_DIS); |
---|
999 | 1057 | snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
1000 | 1058 | DAC_DIG_CLK_EN, DAC_DIG_CLK_EN); |
---|
| 1059 | + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
| 1060 | + I2SRX_EN_MASK, I2SRX_DIS); |
---|
1001 | 1061 | } else { |
---|
| 1062 | + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
| 1063 | + I2SRX_EN_MASK, I2SRX_EN); |
---|
1002 | 1064 | snd_soc_component_update_bits(component, |
---|
1003 | 1065 | RK817_CODEC_DDAC_MUTE_MIXCTL, |
---|
1004 | 1066 | DACMT_ENABLE, DACMT_DISABLE); |
---|
.. | .. |
---|
1048 | 1110 | return 0; |
---|
1049 | 1111 | } |
---|
1050 | 1112 | |
---|
| 1113 | +static int rk817_digital_mute_adc(struct snd_soc_dai *dai, int mute, int stream) |
---|
| 1114 | +{ |
---|
| 1115 | + struct snd_soc_component *component = dai->component; |
---|
| 1116 | + |
---|
| 1117 | + if (mute) |
---|
| 1118 | + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
| 1119 | + I2STX_EN_MASK, I2STX_DIS); |
---|
| 1120 | + else |
---|
| 1121 | + snd_soc_component_update_bits(component, RK817_CODEC_DTOP_DIGEN_CLKE, |
---|
| 1122 | + I2STX_EN_MASK, I2STX_EN); |
---|
| 1123 | + |
---|
| 1124 | + return 0; |
---|
| 1125 | +} |
---|
| 1126 | + |
---|
| 1127 | +static int rk817_digital_mute(struct snd_soc_dai *dai, int mute, int stream) |
---|
| 1128 | +{ |
---|
| 1129 | + if (stream == SNDRV_PCM_STREAM_PLAYBACK) |
---|
| 1130 | + return rk817_digital_mute_dac(dai, mute, stream); |
---|
| 1131 | + else |
---|
| 1132 | + return rk817_digital_mute_adc(dai, mute, stream); |
---|
| 1133 | +} |
---|
| 1134 | + |
---|
1051 | 1135 | #define RK817_PLAYBACK_RATES (SNDRV_PCM_RATE_8000 |\ |
---|
1052 | 1136 | SNDRV_PCM_RATE_16000 | \ |
---|
1053 | 1137 | SNDRV_PCM_RATE_32000 | \ |
---|
.. | .. |
---|
1090 | 1174 | .hw_params = rk817_hw_params, |
---|
1091 | 1175 | .set_fmt = rk817_set_dai_fmt, |
---|
1092 | 1176 | .set_sysclk = rk817_set_dai_sysclk, |
---|
1093 | | - .digital_mute = rk817_digital_mute, |
---|
| 1177 | + .mute_stream = rk817_digital_mute, |
---|
1094 | 1178 | .shutdown = rk817_codec_shutdown, |
---|
1095 | 1179 | }; |
---|
1096 | 1180 | |
---|
.. | .. |
---|
1144 | 1228 | |
---|
1145 | 1229 | static int rk817_resume(struct snd_soc_component *component) |
---|
1146 | 1230 | { |
---|
| 1231 | + struct rk817_codec_priv *rk817 = snd_soc_component_get_drvdata(component); |
---|
| 1232 | + |
---|
| 1233 | + if (rk817->resume_path) { |
---|
| 1234 | + if (rk817->capture_path != MIC_OFF) |
---|
| 1235 | + rk817_capture_path_config(component, OFF, rk817->capture_path); |
---|
| 1236 | + if (rk817->playback_path != OFF) |
---|
| 1237 | + rk817_playback_path_config(component, OFF, rk817->playback_path); |
---|
| 1238 | + } |
---|
| 1239 | + |
---|
1147 | 1240 | return 0; |
---|
1148 | 1241 | } |
---|
1149 | 1242 | |
---|
.. | .. |
---|
1165 | 1258 | rk817->playback_path = OFF; |
---|
1166 | 1259 | rk817->capture_path = MIC_OFF; |
---|
1167 | 1260 | |
---|
1168 | | - chip_name = snd_soc_component_read32(component, RK817_PMIC_CHIP_NAME); |
---|
1169 | | - chip_ver = snd_soc_component_read32(component, RK817_PMIC_CHIP_VER); |
---|
| 1261 | + chip_name = snd_soc_component_read(component, RK817_PMIC_CHIP_NAME); |
---|
| 1262 | + chip_ver = snd_soc_component_read(component, RK817_PMIC_CHIP_VER); |
---|
1170 | 1263 | rk817->chip_ver = (chip_ver & 0x0f); |
---|
1171 | 1264 | dev_info(component->dev, "%s: chip_name:0x%x, chip_ver:0x%x\n", __func__, chip_name, chip_ver); |
---|
1172 | 1265 | |
---|
| 1266 | + /* always enable mclk, and will disable mclk in rk817_remove */ |
---|
1173 | 1267 | clk_prepare_enable(rk817->mclk); |
---|
1174 | 1268 | rk817_reset(component); |
---|
1175 | | - clk_disable_unprepare(rk817->mclk); |
---|
| 1269 | + mutex_init(&rk817->clk_lock); |
---|
| 1270 | + rk817->clk_capture = 0; |
---|
| 1271 | + rk817->clk_playback = 0; |
---|
1176 | 1272 | |
---|
1177 | 1273 | snd_soc_add_component_controls(component, rk817_snd_path_controls, |
---|
1178 | 1274 | ARRAY_SIZE(rk817_snd_path_controls)); |
---|
.. | .. |
---|
1193 | 1289 | |
---|
1194 | 1290 | rk817_codec_power_down(component, RK817_CODEC_ALL); |
---|
1195 | 1291 | snd_soc_component_exit_regmap(component); |
---|
| 1292 | + mutex_destroy(&rk817->clk_lock); |
---|
| 1293 | + clk_disable_unprepare(rk817->mclk); |
---|
1196 | 1294 | mdelay(10); |
---|
1197 | 1295 | |
---|
1198 | 1296 | } |
---|