Lines Matching +full:pga +full:- +full:gain

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2017 - 2018 Sebastian Reichel <sre@kernel.org>
8 * Copyright (C) 2007 - 2009 Motorola, Inc.
14 #include <linux/mfd/motorola-cpcap.h>
19 /* Register 513 CPCAP_REG_CC --- CODEC */
37 /* Register 514 CPCAP_REG_CDI --- CODEC Digital Audio Interface */
54 /* Register 515 CPCAP_REG_SDAC --- Stereo DAC */
68 /* Register 516 CPCAP_REG_SDACDI --- Stereo DAC Digital Audio Interface */
84 /* Register 517 CPCAP_REG_TXI --- TX Interface */
102 /* Register 518 CPCAP_REG_TXMP --- Mic Gain */
116 /* Register 519 CPCAP_REG_RXOA --- RX Output Amplifier */
134 /* Register 520 CPCAP_REG_RXVC --- RX Volume Control */
152 /* Register 521 CPCAP_REG_RXCOA --- Codec to Output Amp Switches */
165 /* Register 522 CPCAP_REG_RXSDOA --- RX Stereo DAC to Output Amp Switches */
180 /* Register 523 CPCAP_REG_RXEPOA --- RX External PGA to Output Amp Switches */
197 /* Register 525 CPCAP_REG_A2LA --- SPK Amplifier and Clock Config for Headset */
259 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cpcap_st_workaround()
264 if (cpcap->vendor != CPCAP_VENDOR_ST) in cpcap_st_workaround()
269 err = regmap_write(cpcap->regmap, CPCAP_REG_TEST, in cpcap_st_workaround()
273 err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1, in cpcap_st_workaround()
279 err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1, in cpcap_st_workaround()
283 err = regmap_write(cpcap->regmap, CPCAP_REG_TEST, in cpcap_st_workaround()
293 /* Capture Gain Control: 0dB to 31dB in 1dB steps */
296 /* Playback Gain Control: -33dB to 12dB in 3dB steps */
297 static const DECLARE_TLV_DB_SCALE(vol_tlv, -3300, 300, 0);
300 /* Playback Gain */
308 /* Capture Gain */
362 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_output_mux_get_enum()
363 unsigned int shift = e->shift_l; in cpcap_output_mux_get_enum()
367 err = regmap_read(cpcap->regmap, CPCAP_REG_RXCOA, &reg_voice); in cpcap_output_mux_get_enum()
370 err = regmap_read(cpcap->regmap, CPCAP_REG_RXSDOA, &reg_hifi); in cpcap_output_mux_get_enum()
373 err = regmap_read(cpcap->regmap, CPCAP_REG_RXEPOA, &reg_ext); in cpcap_output_mux_get_enum()
384 ucontrol->value.enumerated.item[0] = 3; in cpcap_output_mux_get_enum()
387 ucontrol->value.enumerated.item[0] = 2; in cpcap_output_mux_get_enum()
390 ucontrol->value.enumerated.item[0] = 1; in cpcap_output_mux_get_enum()
393 ucontrol->value.enumerated.item[0] = 0; in cpcap_output_mux_get_enum()
407 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_output_mux_put_enum()
408 unsigned int muxval = ucontrol->value.enumerated.item[0]; in cpcap_output_mux_put_enum()
409 unsigned int mask = BIT(e->shift_l); in cpcap_output_mux_put_enum()
427 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, in cpcap_output_mux_put_enum()
431 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXSDOA, in cpcap_output_mux_put_enum()
435 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXEPOA, in cpcap_output_mux_put_enum()
453 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval); in cpcap_input_right_mux_get_enum()
465 ucontrol->value.enumerated.item[0] = 4; in cpcap_input_right_mux_get_enum()
468 ucontrol->value.enumerated.item[0] = 3; in cpcap_input_right_mux_get_enum()
471 ucontrol->value.enumerated.item[0] = 2; in cpcap_input_right_mux_get_enum()
474 ucontrol->value.enumerated.item[0] = 1; in cpcap_input_right_mux_get_enum()
477 ucontrol->value.enumerated.item[0] = 0; in cpcap_input_right_mux_get_enum()
491 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_input_right_mux_put_enum()
492 unsigned int muxval = ucontrol->value.enumerated.item[0]; in cpcap_input_right_mux_put_enum()
519 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_input_right_mux_put_enum()
537 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval); in cpcap_input_left_mux_get_enum()
547 ucontrol->value.enumerated.item[0] = 2; in cpcap_input_left_mux_get_enum()
550 ucontrol->value.enumerated.item[0] = 1; in cpcap_input_left_mux_get_enum()
553 ucontrol->value.enumerated.item[0] = 0; in cpcap_input_left_mux_get_enum()
567 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_input_left_mux_put_enum()
568 unsigned int muxval = ucontrol->value.enumerated.item[0]; in cpcap_input_left_mux_put_enum()
587 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_input_left_mux_put_enum()
697 SND_SOC_DAPM_PGA("Microphone 1 PGA",
699 SND_SOC_DAPM_PGA("Microphone 2 PGA",
718 /* Playback PGA */
719 SND_SOC_DAPM_PGA("HiFi PGA",
721 SND_SOC_DAPM_PGA("Voice PGA",
723 SND_SOC_DAPM_PGA_E("Ext Right PGA",
728 SND_SOC_DAPM_PGA_E("Ext Left PGA",
775 SND_SOC_DAPM_PGA("Earpiece PGA",
777 SND_SOC_DAPM_PGA("Speaker Right PGA",
779 SND_SOC_DAPM_PGA("Speaker Left PGA",
781 SND_SOC_DAPM_PGA("Lineout Right PGA",
783 SND_SOC_DAPM_PGA("Lineout Left PGA",
785 SND_SOC_DAPM_PGA("Headset Right PGA",
787 SND_SOC_DAPM_PGA("Headset Left PGA",
789 SND_SOC_DAPM_PGA("EMU Right PGA",
791 SND_SOC_DAPM_PGA("EMU Left PGA",
812 {"HiFi PGA", NULL, "VAUDIO"},
813 {"Voice PGA", NULL, "VAUDIO"},
814 {"Ext Right PGA", NULL, "VAUDIO"},
815 {"Ext Left PGA", NULL, "VAUDIO"},
816 {"Microphone 1 PGA", NULL, "VAUDIO"},
817 {"Microphone 2 PGA", NULL, "VAUDIO"},
819 /* Stream -> AIF */
837 /* AIF -> DAC mapping */
841 /* DAC -> PGA */
842 {"HiFi PGA", NULL, "DAC HiFi"},
843 {"Voice PGA", NULL, "DAC Voice"},
845 /* Ext Input -> PGA */
846 {"Ext Right PGA", NULL, "EXTR"},
847 {"Ext Left PGA", NULL, "EXTL"},
849 /* Ext PGA -> Ext Playback Switch */
850 {"Ext Right Enable", "Switch", "Ext Right PGA"},
851 {"Ext Left Enable", "Switch", "Ext Left PGA"},
853 /* HiFi PGA -> Mono Mixer */
854 {"HiFi Mono Left Mixer", NULL, "HiFi PGA"},
855 {"HiFi Mono Left Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
856 {"HiFi Mono Right Mixer", NULL, "HiFi PGA"},
857 {"HiFi Mono Right Mixer", "HiFi Mono Playback Switch", "HiFi PGA"},
859 /* Ext Playback Switch -> Ext Mono Mixer */
865 /* HiFi Mono Mixer -> Output Route */
876 /* Voice PGA -> Output Route */
877 {"Earpiece Playback Route", "Voice", "Voice PGA"},
878 {"Speaker Right Playback Route", "Voice", "Voice PGA"},
879 {"Speaker Left Playback Route", "Voice", "Voice PGA"},
880 {"Lineout Right Playback Route", "Voice", "Voice PGA"},
881 {"Lineout Left Playback Route", "Voice", "Voice PGA"},
882 {"Headset Right Playback Route", "Voice", "Voice PGA"},
883 {"Headset Left Playback Route", "Voice", "Voice PGA"},
884 {"EMU Right Playback Route", "Voice", "Voice PGA"},
885 {"EMU Left Playback Route", "Voice", "Voice PGA"},
887 /* Ext Mono Mixer -> Output Route */
898 /* Output Route -> Output Amplifier */
899 {"Earpiece PGA", NULL, "Earpiece Playback Route"},
900 {"Speaker Right PGA", NULL, "Speaker Right Playback Route"},
901 {"Speaker Left PGA", NULL, "Speaker Left Playback Route"},
902 {"Lineout Right PGA", NULL, "Lineout Right Playback Route"},
903 {"Lineout Left PGA", NULL, "Lineout Left Playback Route"},
904 {"Headset Right PGA", NULL, "Headset Right Playback Route"},
905 {"Headset Left PGA", NULL, "Headset Left Playback Route"},
906 {"EMU Right PGA", NULL, "EMU Right Playback Route"},
907 {"EMU Left PGA", NULL, "EMU Left Playback Route"},
909 /* Output Amplifier -> Output */
910 {"EP", NULL, "Earpiece PGA"},
911 {"SPKR", NULL, "Speaker Right PGA"},
912 {"SPKL", NULL, "Speaker Left PGA"},
913 {"LINER", NULL, "Lineout Right PGA"},
914 {"LINEL", NULL, "Lineout Left PGA"},
915 {"HSR", NULL, "Headset Right PGA"},
916 {"HSL", NULL, "Headset Left PGA"},
917 {"EMUR", NULL, "EMU Right PGA"},
918 {"EMUL", NULL, "EMU Left PGA"},
920 /* Headset Charge Pump -> Headset */
924 /* Mic -> Mic Route */
932 /* Input Route -> Microphone PGA */
933 {"Microphone 1 PGA", NULL, "Right Capture Route"},
934 {"Microphone 2 PGA", NULL, "Left Capture Route"},
936 /* Microphone PGA -> ADC */
937 {"ADC Right", NULL, "Microphone 1 PGA"},
938 {"ADC Left", NULL, "Microphone 2 PGA"},
940 /* ADC -> Stream */
972 dev_err(cpcap->component->dev, "invalid DAI: %d", dai); in cpcap_set_sysclk()
973 return -EINVAL; in cpcap_set_sysclk()
978 dev_err(cpcap->component->dev, "invalid clk id %d", clk_id); in cpcap_set_sysclk()
979 return -EINVAL; in cpcap_set_sysclk()
981 err = regmap_update_bits(cpcap->regmap, clkidreg, BIT(clkidshift), in cpcap_set_sysclk()
990 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_set_sysclk()
1018 dev_err(cpcap->component->dev, "unsupported freq %u", freq); in cpcap_set_sysclk()
1019 return -EINVAL; in cpcap_set_sysclk()
1022 err = regmap_update_bits(cpcap->regmap, clkfreqreg, in cpcap_set_sysclk()
1028 cpcap->codec_clk_id = clk_id; in cpcap_set_sysclk()
1029 cpcap->codec_freq = freq; in cpcap_set_sysclk()
1038 struct snd_soc_component *component = cpcap->component; in cpcap_set_samprate()
1056 dev_err(component->dev, "invalid DAI: %d", dai); in cpcap_set_samprate()
1057 return -EINVAL; in cpcap_set_samprate()
1090 dev_err(component->dev, "unsupported samplerate %d", samplerate); in cpcap_set_samprate()
1091 return -EINVAL; in cpcap_set_samprate()
1093 err = regmap_update_bits(cpcap->regmap, sampreg, in cpcap_set_samprate()
1101 err = regmap_read(cpcap->regmap, sampreg, &sampreadval); in cpcap_set_samprate()
1106 dev_err(component->dev, "reset self-clear failed: %04x", in cpcap_set_samprate()
1108 return -EIO; in cpcap_set_samprate()
1118 struct snd_soc_component *component = dai->component; in cpcap_hifi_hw_params()
1122 dev_dbg(component->dev, "HiFi setup HW params: rate=%d", rate); in cpcap_hifi_hw_params()
1129 struct snd_soc_component *component = codec_dai->component; in cpcap_hifi_set_dai_sysclk()
1131 struct device *dev = component->dev; in cpcap_hifi_set_dai_sysclk()
1140 struct snd_soc_component *component = codec_dai->component; in cpcap_hifi_set_dai_fmt()
1142 struct device *dev = component->dev; in cpcap_hifi_set_dai_fmt()
1162 * SND_SOC_DAIFMT_CBM_CFM - codec clk & frm master in cpcap_hifi_set_dai_fmt()
1163 * SND_SOC_DAIFMT_I2S - I2S mode in cpcap_hifi_set_dai_fmt()
1171 return -EINVAL; in cpcap_hifi_set_dai_fmt()
1193 return -EINVAL; in cpcap_hifi_set_dai_fmt()
1207 /* 01 - 4 slots network mode */ in cpcap_hifi_set_dai_fmt()
1216 return regmap_update_bits(cpcap->regmap, reg, mask, val); in cpcap_hifi_set_dai_fmt()
1221 struct snd_soc_component *component = dai->component; in cpcap_hifi_set_mute()
1232 dev_dbg(component->dev, "HiFi mute: %d", mute); in cpcap_hifi_set_mute()
1233 return regmap_update_bits(cpcap->regmap, reg, mask, val); in cpcap_hifi_set_mute()
1248 struct snd_soc_component *component = dai->component; in cpcap_voice_hw_params()
1249 struct device *dev = component->dev; in cpcap_voice_hw_params()
1254 int direction = substream->stream; in cpcap_voice_hw_params()
1276 err = regmap_update_bits(cpcap->regmap, reg_cdi, mask, val); in cpcap_voice_hw_params()
1287 struct snd_soc_component *component = codec_dai->component; in cpcap_voice_set_dai_sysclk()
1290 dev_dbg(component->dev, "Voice setup sysclk: clk_id=%u, freq=%u", in cpcap_voice_set_dai_sysclk()
1298 struct snd_soc_component *component = codec_dai->component; in cpcap_voice_set_dai_fmt()
1308 dev_dbg(component->dev, "Voice setup dai format (%08x)", fmt); in cpcap_voice_set_dai_fmt()
1312 * configured as SND_SOC_DAIFMT_CBM_CFM - codec clk & frm in cpcap_voice_set_dai_fmt()
1320 dev_err(component->dev, "Voice dai fmt failed: CPCAP should be the master"); in cpcap_voice_set_dai_fmt()
1343 dev_err(component->dev, "Voice dai fmt failed: unsupported clock invert mode"); in cpcap_voice_set_dai_fmt()
1354 /* 11 - true I2S mode */ in cpcap_voice_set_dai_fmt()
1365 dev_dbg(component->dev, "Voice dai format: val=%04x", val); in cpcap_voice_set_dai_fmt()
1366 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, mask, val); in cpcap_voice_set_dai_fmt()
1370 cpcap->codec_format = val; in cpcap_voice_set_dai_fmt()
1377 struct snd_soc_component *component = dai->component; in cpcap_voice_set_mute()
1388 dev_dbg(component->dev, "Voice mute: %d", mute); in cpcap_voice_set_mute()
1389 return regmap_update_bits(cpcap->regmap, reg, mask, val); in cpcap_voice_set_mute()
1403 .name = "cpcap-hifi",
1415 .name = "cpcap-voice",
1453 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_dai_mux()
1458 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_SDACDI, in cpcap_dai_mux()
1472 dev_dbg(component->dev, "init audio codec"); in cpcap_audio_reset()
1475 err = regmap_update_bits(cpcap->regmap, in cpcap_audio_reset()
1511 cpcap = devm_kzalloc(component->dev, sizeof(*cpcap), GFP_KERNEL); in cpcap_soc_probe()
1513 return -ENOMEM; in cpcap_soc_probe()
1515 cpcap->component = component; in cpcap_soc_probe()
1517 cpcap->regmap = dev_get_regmap(component->dev->parent, NULL); in cpcap_soc_probe()
1518 if (!cpcap->regmap) in cpcap_soc_probe()
1519 return -ENODEV; in cpcap_soc_probe()
1520 snd_soc_component_init_regmap(component, cpcap->regmap); in cpcap_soc_probe()
1522 err = cpcap_get_vendor(component->dev, cpcap->regmap, &cpcap->vendor); in cpcap_soc_probe()
1546 of_get_child_by_name(pdev->dev.parent->of_node, "audio-codec"); in cpcap_codec_probe()
1548 pdev->dev.of_node = codec_node; in cpcap_codec_probe()
1550 return devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_cpcap, in cpcap_codec_probe()
1557 .name = "cpcap-codec",
1562 MODULE_ALIAS("platform:cpcap-codec");