| .. | .. |
|---|
| 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 | } |
|---|