Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: codecs: jz4725b: Various improvements and fixes

Merge series from Siarhei Volkau <lis8215@gmail.com>:

The patchset fixes:
- Line In path stays powered off during capturing or
bypass to mixer.
- incorrectly represented dB values in alsamixer, et al.
- incorrect represented Capture input selector in alsamixer
in Playback tab.
- wrong control selected as Capture Master

The patchset improves:
- Exposes output stage (post mixer) gain control and makes it new
Master playback gain, DAC gain was the previous master.
However, no Master mute now.
- Exposes all mixer inputs (both Mics, LineIn and DAC) with their
gain controls.
- Exposes microphones widgets: single/differential input, boost.

Known issues:
- Bypass path enablement isn't applied immediately, for make
things going bit clock needs to be triggered for a bit,
e.g. by aplay dummy.wav
It might be a hardware bug, since the bit clock isn't
declared as required for codec operation.

Tested on:
- Ritmix RZX-27 (jz4725b).
- Ritmix RZX-50 (jz4755).

+91 -16
+91 -16
sound/soc/codecs/jz4725b.c
··· 136 136 #define REG_CGR3_GO1L_OFFSET 0 137 137 #define REG_CGR3_GO1L_MASK (0x1f << REG_CGR3_GO1L_OFFSET) 138 138 139 + #define REG_CGR4_GO2R_OFFSET 0 140 + #define REG_CGR4_GO2R_MASK (0x1f << REG_CGR4_GO2R_OFFSET) 141 + 142 + #define REG_CGR5_GO2L_OFFSET 0 143 + #define REG_CGR5_GO2L_MASK (0x1f << REG_CGR5_GO2L_OFFSET) 144 + 145 + #define REG_CGR6_GO3R_OFFSET 0 146 + #define REG_CGR6_GO3R_MASK (0x1f << REG_CGR6_GO3R_OFFSET) 147 + 148 + #define REG_CGR7_GO3L_OFFSET 0 149 + #define REG_CGR7_GO3L_MASK (0x1f << REG_CGR7_GO3L_OFFSET) 150 + 151 + #define REG_CGR8_GOR_OFFSET 0 152 + #define REG_CGR8_GOR_MASK (0x1f << REG_CGR8_GOR_OFFSET) 153 + 154 + #define REG_CGR9_GOL_OFFSET 0 155 + #define REG_CGR9_GOL_MASK (0x1f << REG_CGR9_GOL_OFFSET) 156 + 157 + #define REG_CGR10_GIL_OFFSET 0 158 + #define REG_CGR10_GIR_OFFSET 4 159 + 139 160 struct jz_icdc { 140 161 struct regmap *regmap; 141 162 void __iomem *base; 142 163 struct clk *clk; 143 164 }; 144 165 145 - static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_dac_tlv, -2250, 0); 146 - static const SNDRV_CTL_TLVD_DECLARE_DB_LINEAR(jz4725b_line_tlv, -1500, 600); 166 + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_adc_tlv, 0, 150, 0); 167 + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_dac_tlv, -2250, 150, 0); 168 + static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(jz4725b_mix_tlv, 169 + 0, 11, TLV_DB_SCALE_ITEM(-2250, 0, 0), 170 + 12, 31, TLV_DB_SCALE_ITEM(-2250, 150, 0), 171 + ); 172 + 173 + static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(jz4725b_out_tlv, 174 + 0, 11, TLV_DB_SCALE_ITEM(-3350, 200, 0), 175 + 12, 23, TLV_DB_SCALE_ITEM(-1050, 100, 0), 176 + 24, 31, TLV_DB_SCALE_ITEM( 100, 50, 0), 177 + ); 178 + static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(jz4725b_mic_boost_tlv, 0, 2000, 0); 179 + 180 + static const char * const jz4725b_mic_mode_texts[] = { 181 + "Single Ended", "Differential", 182 + }; 183 + 184 + static const struct soc_enum jz4725b_mic_mode_enum = 185 + SOC_ENUM_SINGLE(JZ4725B_CODEC_REG_CR3, REG_CR3_MICDIFF_OFFSET, 186 + 2, jz4725b_mic_mode_texts); 147 187 148 188 static const struct snd_kcontrol_new jz4725b_codec_controls[] = { 149 - SOC_DOUBLE_TLV("Master Playback Volume", 189 + SOC_DOUBLE_TLV("DAC Playback Volume", 150 190 JZ4725B_CODEC_REG_CGR1, 151 191 REG_CGR1_GODL_OFFSET, 152 192 REG_CGR1_GODR_OFFSET, 153 193 0xf, 1, jz4725b_dac_tlv), 154 - SOC_DOUBLE_R_TLV("Master Capture Volume", 194 + SOC_DOUBLE_TLV("Master Capture Volume", 195 + JZ4725B_CODEC_REG_CGR10, 196 + REG_CGR10_GIL_OFFSET, 197 + REG_CGR10_GIR_OFFSET, 198 + 0xf, 0, jz4725b_adc_tlv), 199 + SOC_DOUBLE_R_TLV("Mixer Line In Bypass Playback Volume", 155 200 JZ4725B_CODEC_REG_CGR3, 156 201 JZ4725B_CODEC_REG_CGR2, 157 202 REG_CGR2_GO1R_OFFSET, 158 - 0x1f, 1, jz4725b_line_tlv), 203 + 0x1f, 1, jz4725b_mix_tlv), 204 + SOC_DOUBLE_R_TLV("Mixer Mic 1 Bypass Playback Volume", 205 + JZ4725B_CODEC_REG_CGR5, 206 + JZ4725B_CODEC_REG_CGR4, 207 + REG_CGR4_GO2R_OFFSET, 208 + 0x1f, 1, jz4725b_mix_tlv), 209 + SOC_DOUBLE_R_TLV("Mixer Mic 2 Bypass Playback Volume", 210 + JZ4725B_CODEC_REG_CGR7, 211 + JZ4725B_CODEC_REG_CGR6, 212 + REG_CGR6_GO3R_OFFSET, 213 + 0x1f, 1, jz4725b_mix_tlv), 159 214 160 - SOC_SINGLE("Master Playback Switch", JZ4725B_CODEC_REG_CR1, 215 + SOC_DOUBLE_R_TLV("Master Playback Volume", 216 + JZ4725B_CODEC_REG_CGR9, 217 + JZ4725B_CODEC_REG_CGR8, 218 + REG_CGR8_GOR_OFFSET, 219 + 0x1f, 1, jz4725b_out_tlv), 220 + 221 + SOC_SINGLE("DAC Playback Switch", JZ4725B_CODEC_REG_CR1, 161 222 REG_CR1_DAC_MUTE_OFFSET, 1, 1), 162 223 163 224 SOC_SINGLE("Deemphasize Filter Playback Switch", ··· 228 167 SOC_SINGLE("High-Pass Filter Capture Switch", 229 168 JZ4725B_CODEC_REG_CR2, 230 169 REG_CR2_ADC_HPF_OFFSET, 1, 0), 170 + 171 + SOC_ENUM("Mic Mode Capture Switch", jz4725b_mic_mode_enum), 172 + 173 + SOC_SINGLE_TLV("Mic1 Boost Capture Volume", 174 + JZ4725B_CODEC_REG_PMR2, 175 + REG_PMR2_GIM_OFFSET, 176 + 1, 0, jz4725b_mic_boost_tlv), 231 177 }; 232 178 233 179 static const char * const jz4725b_codec_adc_src_texts[] = { ··· 248 180 jz4725b_codec_adc_src_texts, 249 181 jz4725b_codec_adc_src_values); 250 182 static const struct snd_kcontrol_new jz4725b_codec_adc_src_ctrl = 251 - SOC_DAPM_ENUM("Route", jz4725b_codec_adc_src_enum); 183 + SOC_DAPM_ENUM("ADC Source Capture Route", jz4725b_codec_adc_src_enum); 252 184 253 185 static const struct snd_kcontrol_new jz4725b_codec_mixer_controls[] = { 254 - SOC_DAPM_SINGLE("Line In Bypass", JZ4725B_CODEC_REG_CR1, 186 + SOC_DAPM_SINGLE("Line In Bypass Playback Switch", JZ4725B_CODEC_REG_CR1, 255 187 REG_CR1_BYPASS_OFFSET, 1, 0), 188 + SOC_DAPM_SINGLE("Mic 1 Bypass Playback Switch", JZ4725B_CODEC_REG_CR3, 189 + REG_CR3_SIDETONE1_OFFSET, 1, 0), 190 + SOC_DAPM_SINGLE("Mic 2 Bypass Playback Switch", JZ4725B_CODEC_REG_CR3, 191 + REG_CR3_SIDETONE2_OFFSET, 1, 0), 256 192 }; 257 193 258 194 static int jz4725b_out_stage_enable(struct snd_soc_dapm_widget *w, ··· 297 225 SND_SOC_DAPM_ADC("ADC", "Capture", 298 226 JZ4725B_CODEC_REG_PMR1, REG_PMR1_SB_ADC_OFFSET, 1), 299 227 300 - SND_SOC_DAPM_MUX("ADC Source", SND_SOC_NOPM, 0, 0, 228 + SND_SOC_DAPM_MUX("ADC Source Capture Route", SND_SOC_NOPM, 0, 0, 301 229 &jz4725b_codec_adc_src_ctrl), 302 230 303 231 /* Mixer */ ··· 308 236 SND_SOC_DAPM_MIXER("DAC to Mixer", JZ4725B_CODEC_REG_CR1, 309 237 REG_CR1_DACSEL_OFFSET, 0, NULL, 0), 310 238 311 - SND_SOC_DAPM_MIXER("Line In", SND_SOC_NOPM, 0, 0, NULL, 0), 239 + SND_SOC_DAPM_MIXER("Line In", JZ4725B_CODEC_REG_PMR1, 240 + REG_PMR1_SB_LIN_OFFSET, 1, NULL, 0), 312 241 SND_SOC_DAPM_MIXER("HP Out", JZ4725B_CODEC_REG_CR1, 313 242 REG_CR1_HP_DIS_OFFSET, 1, NULL, 0), 314 243 ··· 351 278 {"Line In", NULL, "LLINEIN"}, 352 279 {"Line In", NULL, "RLINEIN"}, 353 280 354 - {"Mixer", "Line In Bypass", "Line In"}, 281 + {"Mixer", "Mic 1 Bypass Playback Switch", "Mic 1"}, 282 + {"Mixer", "Mic 2 Bypass Playback Switch", "Mic 2"}, 283 + {"Mixer", "Line In Bypass Playback Switch", "Line In"}, 355 284 {"DAC to Mixer", NULL, "DAC"}, 356 285 {"Mixer", NULL, "DAC to Mixer"}, 357 286 358 287 {"Mixer to ADC", NULL, "Mixer"}, 359 - {"ADC Source", "Mixer", "Mixer to ADC"}, 360 - {"ADC Source", "Line In", "Line In"}, 361 - {"ADC Source", "Mic 1", "Mic 1"}, 362 - {"ADC Source", "Mic 2", "Mic 2"}, 363 - {"ADC", NULL, "ADC Source"}, 288 + {"ADC Source Capture Route", "Mixer", "Mixer to ADC"}, 289 + {"ADC Sourc Capture Routee", "Line In", "Line In"}, 290 + {"ADC Source Capture Route", "Mic 1", "Mic 1"}, 291 + {"ADC Source Capture Route", "Mic 2", "Mic 2"}, 292 + {"ADC", NULL, "ADC Source Capture Route"}, 364 293 365 294 {"Out Stage", NULL, "Mixer"}, 366 295 {"HP Out", NULL, "Out Stage"},