.. | .. |
---|
97 | 97 | unsigned int mic_mute_l; |
---|
98 | 98 | unsigned int mic_mute_r; |
---|
99 | 99 | |
---|
| 100 | + /* DAC Control Manually */ |
---|
| 101 | + unsigned int dac_ctrl_manual; |
---|
| 102 | + |
---|
100 | 103 | /* For the high pass filter */ |
---|
101 | 104 | unsigned int hpf_cutoff; |
---|
102 | 105 | |
---|
.. | .. |
---|
182 | 185 | struct snd_ctl_elem_value *ucontrol); |
---|
183 | 186 | static int rv1106_codec_main_micbias_put(struct snd_kcontrol *kcontrol, |
---|
184 | 187 | struct snd_ctl_elem_value *ucontrol); |
---|
| 188 | +static int rv1106_codec_dac_ctrl_manual_get(struct snd_kcontrol *kcontrol, |
---|
| 189 | + struct snd_ctl_elem_value *ucontrol); |
---|
| 190 | +static int rv1106_codec_dac_ctrl_manual_put(struct snd_kcontrol *kcontrol, |
---|
| 191 | + struct snd_ctl_elem_value *ucontrol); |
---|
185 | 192 | |
---|
186 | 193 | static const char *offon_text[2] = { |
---|
187 | 194 | [0] = "Off", |
---|
188 | 195 | [1] = "On", |
---|
| 196 | +}; |
---|
| 197 | + |
---|
| 198 | +static const char *noneoffon_text[3] = { |
---|
| 199 | + [0] = "None", |
---|
| 200 | + [1] = "Off", |
---|
| 201 | + [2] = "On", |
---|
189 | 202 | }; |
---|
190 | 203 | |
---|
191 | 204 | static const char *mute_text[2] = { |
---|
.. | .. |
---|
252 | 265 | static const struct soc_enum rv1106_mic_mute_enum_array[] = { |
---|
253 | 266 | SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(mute_text), mute_text), |
---|
254 | 267 | SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(mute_text), mute_text), |
---|
| 268 | +}; |
---|
| 269 | + |
---|
| 270 | +/* DAC Control Manually */ |
---|
| 271 | +static const struct soc_enum rv1106_dac_pa_ctrl_maunal_enum_array[] = { |
---|
| 272 | + SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(noneoffon_text), noneoffon_text), |
---|
255 | 273 | }; |
---|
256 | 274 | |
---|
257 | 275 | /* ALC AGC Approximate Sample Rate */ |
---|
.. | .. |
---|
422 | 440 | rv1106_codec_hpmix_gain_get, |
---|
423 | 441 | rv1106_codec_hpmix_gain_put, |
---|
424 | 442 | rv1106_codec_dac_hpmix_gain_tlv), |
---|
| 443 | + |
---|
| 444 | + /* DAC Control Manually */ |
---|
| 445 | + SOC_ENUM_EXT("DAC Control Manually", rv1106_dac_pa_ctrl_maunal_enum_array[0], |
---|
| 446 | + rv1106_codec_dac_ctrl_manual_get, rv1106_codec_dac_ctrl_manual_put), |
---|
425 | 447 | }; |
---|
426 | 448 | |
---|
427 | 449 | static unsigned int using_adc_lr(enum adc_mode_e adc_mode) |
---|
.. | .. |
---|
1015 | 1037 | return 0; |
---|
1016 | 1038 | } |
---|
1017 | 1039 | |
---|
| 1040 | +static int rv1106_codec_dac_mute(struct rv1106_codec_priv *rv1106, int mute) |
---|
| 1041 | +{ |
---|
| 1042 | + if (mute) { |
---|
| 1043 | + /* Mute DAC HPMIX/LINEOUT */ |
---|
| 1044 | + regmap_update_bits(rv1106->regmap, |
---|
| 1045 | + ACODEC_DAC_ANA_CTL1, |
---|
| 1046 | + ACODEC_DAC_L_LINEOUT_MUTE_MSK, |
---|
| 1047 | + ACODEC_DAC_L_LINEOUT_MUTE); |
---|
| 1048 | + regmap_update_bits(rv1106->regmap, |
---|
| 1049 | + ACODEC_DAC_HPMIX_CTL, |
---|
| 1050 | + ACODEC_DAC_HPMIX_MUTE_MSK, |
---|
| 1051 | + ACODEC_DAC_HPMIX_MUTE); |
---|
| 1052 | + rv1106_codec_pa_ctrl(rv1106, false); |
---|
| 1053 | + } else { |
---|
| 1054 | + /* Unmute DAC HPMIX/LINEOUT */ |
---|
| 1055 | + regmap_update_bits(rv1106->regmap, |
---|
| 1056 | + ACODEC_DAC_HPMIX_CTL, |
---|
| 1057 | + ACODEC_DAC_HPMIX_MUTE_MSK, |
---|
| 1058 | + ACODEC_DAC_HPMIX_WORK); |
---|
| 1059 | + regmap_update_bits(rv1106->regmap, |
---|
| 1060 | + ACODEC_DAC_ANA_CTL1, |
---|
| 1061 | + ACODEC_DAC_L_LINEOUT_MUTE_MSK, |
---|
| 1062 | + ACODEC_DAC_L_LINEOUT_WORK); |
---|
| 1063 | + rv1106_codec_pa_ctrl(rv1106, true); |
---|
| 1064 | + } |
---|
| 1065 | + |
---|
| 1066 | + return 0; |
---|
| 1067 | +} |
---|
| 1068 | + |
---|
1018 | 1069 | static int rv1106_mute_stream(struct snd_soc_dai *dai, int mute, int stream) |
---|
1019 | 1070 | { |
---|
1020 | 1071 | struct snd_soc_component *component = dai->component; |
---|
1021 | 1072 | struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component); |
---|
1022 | 1073 | |
---|
1023 | 1074 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
---|
1024 | | - if (mute) { |
---|
1025 | | - /* Mute DAC HPMIX/LINEOUT */ |
---|
1026 | | - regmap_update_bits(rv1106->regmap, |
---|
1027 | | - ACODEC_DAC_ANA_CTL1, |
---|
1028 | | - ACODEC_DAC_L_LINEOUT_MUTE_MSK, |
---|
1029 | | - ACODEC_DAC_L_LINEOUT_MUTE); |
---|
1030 | | - regmap_update_bits(rv1106->regmap, |
---|
1031 | | - ACODEC_DAC_HPMIX_CTL, |
---|
1032 | | - ACODEC_DAC_HPMIX_MUTE_MSK, |
---|
1033 | | - ACODEC_DAC_HPMIX_MUTE); |
---|
1034 | | - rv1106_codec_pa_ctrl(rv1106, false); |
---|
1035 | | - } else { |
---|
1036 | | - /* Unmute DAC HPMIX/LINEOUT */ |
---|
1037 | | - regmap_update_bits(rv1106->regmap, |
---|
1038 | | - ACODEC_DAC_HPMIX_CTL, |
---|
1039 | | - ACODEC_DAC_HPMIX_MUTE_MSK, |
---|
1040 | | - ACODEC_DAC_HPMIX_WORK); |
---|
1041 | | - regmap_update_bits(rv1106->regmap, |
---|
1042 | | - ACODEC_DAC_L_LINEOUT_MUTE_MSK, |
---|
1043 | | - ACODEC_DAC_MUTE_MSK, |
---|
1044 | | - ACODEC_DAC_L_LINEOUT_WORK); |
---|
1045 | | - rv1106_codec_pa_ctrl(rv1106, true); |
---|
1046 | | - } |
---|
| 1075 | + if (rv1106->dac_ctrl_manual == 1) |
---|
| 1076 | + mute = 1; /* Force DAC control off manually */ |
---|
| 1077 | + else if (rv1106->dac_ctrl_manual == 2) |
---|
| 1078 | + mute = 0; /* Force DAC control on manually */ |
---|
| 1079 | + |
---|
| 1080 | + rv1106_codec_dac_mute(rv1106, mute); |
---|
1047 | 1081 | } |
---|
1048 | 1082 | |
---|
1049 | 1083 | return 0; |
---|
.. | .. |
---|
1341 | 1375 | } |
---|
1342 | 1376 | |
---|
1343 | 1377 | return snd_soc_put_volsw_range(kcontrol, ucontrol); |
---|
| 1378 | +} |
---|
| 1379 | + |
---|
| 1380 | +static int rv1106_codec_dac_ctrl_manual_get(struct snd_kcontrol *kcontrol, |
---|
| 1381 | + struct snd_ctl_elem_value *ucontrol) |
---|
| 1382 | +{ |
---|
| 1383 | + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
---|
| 1384 | + struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component); |
---|
| 1385 | + |
---|
| 1386 | + ucontrol->value.integer.value[0] = rv1106->dac_ctrl_manual; |
---|
| 1387 | + |
---|
| 1388 | + return 0; |
---|
| 1389 | +} |
---|
| 1390 | + |
---|
| 1391 | +static int rv1106_codec_dac_ctrl_manual_put(struct snd_kcontrol *kcontrol, |
---|
| 1392 | + struct snd_ctl_elem_value *ucontrol) |
---|
| 1393 | +{ |
---|
| 1394 | + struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); |
---|
| 1395 | + struct rv1106_codec_priv *rv1106 = snd_soc_component_get_drvdata(component); |
---|
| 1396 | + |
---|
| 1397 | + rv1106->dac_ctrl_manual = ucontrol->value.integer.value[0]; |
---|
| 1398 | + |
---|
| 1399 | + if (rv1106->dac_ctrl_manual == 0) |
---|
| 1400 | + return 0; |
---|
| 1401 | + |
---|
| 1402 | + if (rv1106->dac_ctrl_manual == 1) |
---|
| 1403 | + rv1106_codec_dac_mute(rv1106, 1); /* Force DAC control off manually */ |
---|
| 1404 | + else if (rv1106->dac_ctrl_manual == 2) |
---|
| 1405 | + rv1106_codec_dac_mute(rv1106, 0); /* Force DAC control on manually */ |
---|
| 1406 | + |
---|
| 1407 | + return 0; |
---|
1344 | 1408 | } |
---|
1345 | 1409 | |
---|
1346 | 1410 | static int rv1106_codec_adc_enable(struct rv1106_codec_priv *rv1106) |
---|
.. | .. |
---|
1774 | 1838 | static int rv1106_codec_dapm_controls_prepare(struct rv1106_codec_priv *rv1106) |
---|
1775 | 1839 | { |
---|
1776 | 1840 | rv1106->adc_mode = DIFF_ADCL; |
---|
| 1841 | + rv1106->dac_ctrl_manual = 0; |
---|
1777 | 1842 | rv1106->hpf_cutoff = 0; |
---|
1778 | 1843 | rv1106->agc_l = 0; |
---|
1779 | 1844 | rv1106->agc_r = 0; |
---|