On 03/14/2016 04:57 PM, Timur Karaldin wrote: > Hi, Peter! > What's about placing capture controls in the Playback section of Alsamixer > view? Yeah, it is annoying. They can be fixed by: "Line1L Switch" -> "Line1L Capture Switch" and so on. On the other hand we had these unfortunate control names I think since the beginning and it is kind of an ABI for existing products. I don't have issue changing them, but existing setups relying on the control names might break... > Does resetting of some registers during start/stop of recording > connect with it? Not sure what you mean. -- Péter > > 14.03.2016 17:47, Peter Ujfalusi пишет: >> Hi Timur, >> >> On 03/14/16 13:06, Timur Karaldin wrote: >>> Hi, colleagues! >>> >>> I'm newbie with ALSA devel. I need to get extra functionality from codec >>> through ALSA mixer. >>> Task: 1. making possibility to set-up gain for each input (XXX_2_LADCCTRL and >>> XXX_2_RADCCTRL registers) >> This part is a bit tricky as in the registers: >> value 0..8 is gain from 0dB to -12dB in steps of -1.5dB and value 0xf means >> basically mute/disconnect. >> >>> 2. making possibility to set-up debounce for button and headset detection ( >>> HEADSET_DETECT_CTRL_A register) >>> 3. making possibility to enable high-power AC-coupled output >>> (HEADSET_DETECT_CTRL_A register) >>> 4. making possibility to enable stereo pseudo differential output >>> (HEADSET_DETECT_CTRL_B register) >>> 5. enable headset detection (HEADSET_DETECT_CTRL_A) >>> 6. getting headset detect status (HEADSET_DETECT_CTRL_A) >>> >>> Well, my patch works in generally, but I don't like it very much, because: >>> 1. All controls for input amplifiers' gain are shown in Alsamixer-Playback >>> section. But not only mine, capture controls from base codec's version are >>> shown in playback section too, for example (Right or Left) PGA Mixer Line1(L >>> or R)/2(L or R)/MIC3(L or R), which is definitely capture settings. Should I >>> worried about it? because, as I understand, it could not be setted correctly >>> during changing playback/capture mode for power-saving reason. >>> 2. "Right PGA Mixer Line1R" control (and similar) using the same bits in >>> LINE1R_2_RADCCTRL register as my "Line1R RADC Gain" control (and similar) and >>> put there b"1111" when user switch disconnect it from ADC. So my control is >>> not shown when user disconnect it from ADC. >>> 3. When I start/stop arecord some of my options were reset (debounces, headset >>> enable, high-power AC-coupled, pseudo differential output). When I set up it >>> in shell and then start arecord, it's reset again. Is it the reason because of >>> displaying controls in playback mixer section? >>> >>> I will be very pleased for any advise, thank you! >>> >>> >>> here is my patch for tlv320aic3x.c >>> --- >>> sound/soc/codecs/tlv320aic3x.c | 55 >>> +++++++++++++++++++++++++++++++++++++++--- >>> 1 file changed, 52 insertions(+), 3 deletions(-) >>> >>> diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c >>> index d7349bc..27d031e 100644 >>> --- a/sound/soc/codecs/tlv320aic3x.c >>> +++ b/sound/soc/codecs/tlv320aic3x.c >>> @@ -122,11 +122,24 @@ static const struct reg_default aic3x_reg[] = { >>> { 108, 0x00 }, { 109, 0x00 }, >>> }; >>> >>> +static bool aic3106_volatile(struct device *dev, unsigned int reg) >>> +{ >>> + switch(reg) >>> + { >>> + case AIC3X_HEADSET_DETECT_CTRL_A: >>> + case AIC3X_HEADSET_DETECT_CTRL_B: >>> + return true; >>> + default: >>> + return false; >>> + } >>> +} >>> + >>> static const struct regmap_config aic3x_regmap = { >>> .reg_bits = 8, >>> .val_bits = 8, >>> >>> .max_register = DAC_ICC_ADJ, >>> + .volatile_reg = aic3106_volatile, >>> .reg_defaults = aic3x_reg, >>> .num_reg_defaults = ARRAY_SIZE(aic3x_reg), >>> .cache_type = REGCACHE_RBTREE, >>> @@ -196,7 +209,7 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, >>> struct snd_kcontrol *kcontrol, int event) >>> { >>> struct snd_soc_codec *codec = w->codec; >>> - struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); >>> + struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); >> You have couple of these nop changes in the patch... >> >>> switch (event) { >>> case SND_SOC_DAPM_POST_PMU: >>> @@ -270,6 +283,26 @@ static const struct soc_enum aic3x_agc_decay_enum[] = { >>> SOC_ENUM_SINGLE(RAGC_CTRL_A, 0, 4, aic3x_agc_decay), >>> }; >>> >>> +static const char *aic3x_adc_gain[] = { "0dB", "-1.5dB", "-3dB", "-4.5dB", >>> "-6dB", "-7.5dB", "-9dB", "-10.5dB", "-12dB" }; >>> +static const struct soc_enum aic3x_adc_gain_enum[] = { >>> + SOC_ENUM_SINGLE(MIC3LR_2_LADC_CTRL, 4, 9, aic3x_adc_gain), >>> + SOC_ENUM_SINGLE(MIC3LR_2_RADC_CTRL, 0, 9, aic3x_adc_gain), >>> + SOC_ENUM_SINGLE(LINE1L_2_LADC_CTRL, 3, 9, aic3x_adc_gain), >>> + SOC_ENUM_SINGLE(LINE1R_2_RADC_CTRL, 3, 9, aic3x_adc_gain), >>> + SOC_ENUM_SINGLE(LINE2L_2_LADC_CTRL, 3, 9, aic3x_adc_gain), >>> + SOC_ENUM_SINGLE(LINE2R_2_RADC_CTRL, 3, 9, aic3x_adc_gain), >>> +}; >> So the issue is that we have the DAPM switches controlling exactly the same >> registers. I believe if you would set the gain in a way that bit0 is 1, then >> DAPM will think that the path is disconnected. >> Also if you would set the gain and then mute and unmute the path you would >> have lost the gain you wanted to have.. >> >> The only way I can think of implementing these mixers is to have two sets of >> custom callbacks. one set is to set/get the gain and the other is to set/get >> the mute/disconnect on these. >> When the path is disconnected you should not write the gain change to the >> chip, but cache it and if the path is unmuted, you write the cached gain. When >> you mute the path you should take the set gain first, cache it, then >> disconnect the path. >> >> For these gains you should have DECLARE_TLV_DB_SCALE() and use >> SOC_SINGLE_TLV(). Make sure that the control name matches with the >> corresponding DAPM widget's name so ALSA can match them correctly. >> >>> +static const char *aic3x_headset_debounce[] = { "16ms", "32ms", "64ms", >>> "128ms", "256ms", "512ms" }; >>> +static const struct soc_enum aic3x_headset_debounce_enum[] = { >>> + SOC_ENUM_SINGLE(AIC3X_HEADSET_DETECT_CTRL_A, 2, 6, >>> aic3x_headset_debounce), >>> +}; >>> +static const char *aic3x_button_debounce[] = { "0ms", "8ms", "16ms", >>> "32ms" }; >>> +static const struct soc_enum aic3x_button_debounce_enum[] = { >>> + SOC_ENUM_SINGLE(AIC3X_HEADSET_DETECT_CTRL_A, 0, 4, >>> aic3x_button_debounce), >>> +}; >>> + >>> + >>> + >>> /* >>> * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps >>> */ >>> @@ -399,6 +432,19 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] >>> = { >>> SOC_DOUBLE_R("PGA Capture Switch", LADC_VOL, RADC_VOL, 7, 0x01, 1), >>> >>> SOC_ENUM("ADC HPF Cut-off", aic3x_enum[ADC_HPF_ENUM]), >>> + /* Additional controls */ >>> + SOC_ENUM("Mic3L LADC Gain", aic3x_adc_gain_enum[0]), >>> + SOC_ENUM("Mic3R RADC Gain", aic3x_adc_gain_enum[1]), >>> + SOC_ENUM("Line1L LADC Gain", aic3x_adc_gain_enum[2]), >>> + SOC_ENUM("Line1R RADC Gain", aic3x_adc_gain_enum[3]), >>> + SOC_ENUM("Line2L LADC Gain", aic3x_adc_gain_enum[4]), >>> + SOC_ENUM("Line2R RADC Gain", aic3x_adc_gain_enum[5]), >> Please avoid using arrays as the driver no longer use these anymore. >> >>> + SOC_ENUM("Headset Debounce", aic3x_headset_debounce_enum), >>> + SOC_ENUM("Button Debounce", aic3x_button_debounce_enum), >>> + SOC_SINGLE("Headset Detected", AIC3X_HEADSET_DETECT_CTRL_A, >>> AIC3X_HEADSET_DETECT_SHIFT, AIC3X_HEADSET_DETECT_MASK, 0), >>> + SOC_SINGLE("Headset Detect Enable", AIC3X_HEADSET_DETECT_CTRL_A, 7, 1, >>> 0), >>> + SOC_SINGLE("High power output Ac-coupled", AIC3X_HEADSET_DETECT_CTRL_B, >>> 7, 1, 0), >>> + SOC_SINGLE("Stereo pseudodifferential output", >>> AIC3X_HEADSET_DETECT_CTRL_B, 3, 1, 0), >>> }; >>> >>> static const struct snd_kcontrol_new aic3x_mono_controls[] = { >>> @@ -614,7 +660,7 @@ static const struct snd_soc_dapm_widget >>> aic3x_dapm_widgets[] = { >>> SND_SOC_DAPM_REG(snd_soc_dapm_micbias, "DMic Rate 32", >>> AIC3X_ASD_INTF_CTRLA, 0, 3, 3, 0), >>> >>> - /* Mic Bias */ >>> + /* Mic Bias */ >> nop change >> >>> SND_SOC_DAPM_SUPPLY("Mic Bias", MICBIAS_CTRL, 6, 0, >>> mic_bias_event, >>> SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), >>> @@ -692,7 +738,7 @@ static const struct snd_soc_dapm_route intercon[] = { >>> {"Left Line2L Mux", "single-ended", "LINE2L"}, >>> {"Left Line2L Mux", "differential", "LINE2L"}, >>> >>> - {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"}, >>> + {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"}, >> nop change >> >>> {"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"}, >>> {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"}, >>> {"Left PGA Mixer", "Mic3L Switch", "MIC3L"}, >>> @@ -814,6 +860,7 @@ static const struct snd_soc_dapm_route intercon[] = { >>> {"Right HPCOM Mux", "external feedback", "Right HPCOM Mixer"}, >>> {"Right HP Com", NULL, "Right HPCOM Mux"}, >>> {"HPRCOM", NULL, "Right HP Com"}, >>> + >> why? >> >>> }; >>> >>> static const struct snd_soc_dapm_route intercon_mono[] = { >>> @@ -918,7 +965,9 @@ static int aic3x_hw_params(struct snd_pcm_substream >>> *substream, >>> data = (LDAC2LCH | RDAC2RCH); >>> data |= (fsref == 44100) ? FSREF_44100 : FSREF_48000; >>> if (params_rate(params) >= 64000) >>> + { >>> data |= DUAL_RATE_MODE; >>> + } >> why? >> >>> snd_soc_write(codec, AIC3X_CODEC_DATAPATH_REG, data); >>> >>> /* codec sample rate select */ >>> -- >>> and tlv320aic3x.h >>> --- >>> sound/soc/codecs/tlv320aic3x.h | 6 ++++++ >>> 1 file changed, 6 insertions(+) >>> >>> diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h >>> index e521ac3..8ff42d2 100644 >>> --- a/sound/soc/codecs/tlv320aic3x.h >>> +++ b/sound/soc/codecs/tlv320aic3x.h >>> @@ -271,6 +271,12 @@ enum { >>> AIC3X_BUTTON_DEBOUNCE_32MS = 3 >>> }; >>> >>> +typedef struct { >>> + struct platform_device* pdev; >>> + struct proc_dir_entry *proc_value; >>> + struct snd_soc_codec *codec; >>> +} aic3106_detect_t; >>> + >>> #define AIC3X_HEADSET_DETECT_ENABLED 0x80 >>> #define AIC3X_HEADSET_DETECT_SHIFT 5 >>> #define AIC3X_HEADSET_DETECT_MASK 3 >>> -- >> >> When submitting please separate the patches by functionality. It is easier to >> review the changes. >> > > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel