Lines Matching +full:ext +full:- +full:reset +full:- +full:output

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 512 CPCAP_REG_VAUDIOC --- Audio Regulator and Bias Voltage */
27 /* Register 513 CPCAP_REG_CC --- CODEC */
45 /* Register 514 CPCAP_REG_CDI --- CODEC Digital Audio Interface */
62 /* Register 515 CPCAP_REG_SDAC --- Stereo DAC */
76 /* Register 516 CPCAP_REG_SDACDI --- Stereo DAC Digital Audio Interface */
92 /* Register 517 CPCAP_REG_TXI --- TX Interface */
110 /* Register 518 CPCAP_REG_TXMP --- Mic Gain */
124 /* Register 519 CPCAP_REG_RXOA --- RX Output Amplifier */
142 /* Register 520 CPCAP_REG_RXVC --- RX Volume Control */
160 /* Register 521 CPCAP_REG_RXCOA --- Codec to Output Amp Switches */
173 /* Register 522 CPCAP_REG_RXSDOA --- RX Stereo DAC to Output Amp Switches */
188 /* Register 523 CPCAP_REG_RXEPOA --- RX External PGA to Output Amp Switches */
205 /* Register 525 CPCAP_REG_A2LA --- SPK Amplifier and Clock Config for Headset */
268 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cpcap_st_workaround()
273 if (cpcap->vendor != CPCAP_VENDOR_ST) in cpcap_st_workaround()
278 err = regmap_write(cpcap->regmap, CPCAP_REG_TEST, in cpcap_st_workaround()
282 err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1, in cpcap_st_workaround()
288 err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1, in cpcap_st_workaround()
292 err = regmap_write(cpcap->regmap, CPCAP_REG_TEST, in cpcap_st_workaround()
305 /* Playback Gain Control: -33dB to 12dB in 3dB steps */
306 static const DECLARE_TLV_DB_SCALE(vol_tlv, -3300, 300, 0);
314 SOC_SINGLE_TLV("Ext Playback Volume",
326 SOC_SINGLE("Ext Left Phase Invert Switch",
331 "Off", "Voice", "HiFi", "Ext"
335 "Off", "Mic 1", "Headset Mic", "EMU Mic", "Ext Right"
339 "Off", "Mic 2", "Ext Left"
371 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_output_mux_get_enum()
372 unsigned int shift = e->shift_l; in cpcap_output_mux_get_enum()
376 err = regmap_read(cpcap->regmap, CPCAP_REG_RXCOA, &reg_voice); in cpcap_output_mux_get_enum()
379 err = regmap_read(cpcap->regmap, CPCAP_REG_RXSDOA, &reg_hifi); in cpcap_output_mux_get_enum()
382 err = regmap_read(cpcap->regmap, CPCAP_REG_RXEPOA, &reg_ext); in cpcap_output_mux_get_enum()
393 ucontrol->value.enumerated.item[0] = 3; in cpcap_output_mux_get_enum()
396 ucontrol->value.enumerated.item[0] = 2; in cpcap_output_mux_get_enum()
399 ucontrol->value.enumerated.item[0] = 1; in cpcap_output_mux_get_enum()
402 ucontrol->value.enumerated.item[0] = 0; in cpcap_output_mux_get_enum()
416 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_output_mux_put_enum()
417 unsigned int muxval = ucontrol->value.enumerated.item[0]; in cpcap_output_mux_put_enum()
418 unsigned int mask = BIT(e->shift_l); in cpcap_output_mux_put_enum()
436 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, in cpcap_output_mux_put_enum()
440 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXSDOA, in cpcap_output_mux_put_enum()
444 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXEPOA, in cpcap_output_mux_put_enum()
462 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval); in cpcap_input_right_mux_get_enum()
474 ucontrol->value.enumerated.item[0] = 4; in cpcap_input_right_mux_get_enum()
477 ucontrol->value.enumerated.item[0] = 3; in cpcap_input_right_mux_get_enum()
480 ucontrol->value.enumerated.item[0] = 2; in cpcap_input_right_mux_get_enum()
483 ucontrol->value.enumerated.item[0] = 1; in cpcap_input_right_mux_get_enum()
486 ucontrol->value.enumerated.item[0] = 0; in cpcap_input_right_mux_get_enum()
500 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_input_right_mux_put_enum()
501 unsigned int muxval = ucontrol->value.enumerated.item[0]; in cpcap_input_right_mux_put_enum()
528 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_input_right_mux_put_enum()
546 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, &regval); in cpcap_input_left_mux_get_enum()
556 ucontrol->value.enumerated.item[0] = 2; in cpcap_input_left_mux_get_enum()
559 ucontrol->value.enumerated.item[0] = 1; in cpcap_input_left_mux_get_enum()
562 ucontrol->value.enumerated.item[0] = 0; in cpcap_input_left_mux_get_enum()
576 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_input_left_mux_put_enum()
577 unsigned int muxval = ucontrol->value.enumerated.item[0]; in cpcap_input_left_mux_put_enum()
596 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_input_left_mux_put_enum()
647 SOC_DAPM_SINGLE("Ext Mono Playback Switch",
732 SND_SOC_DAPM_PGA_E("Ext Right PGA",
737 SND_SOC_DAPM_PGA_E("Ext Left PGA",
744 SND_SOC_DAPM_SWITCH("Ext Right Enable", SND_SOC_NOPM, 0, 0,
746 SND_SOC_DAPM_SWITCH("Ext Left Enable", SND_SOC_NOPM, 0, 0,
758 SOC_MIXER_ARRAY("Ext Mono Left Mixer", SND_SOC_NOPM, 0, 0,
760 SOC_MIXER_ARRAY("Ext Mono Right Mixer", SND_SOC_NOPM, 0, 0,
763 /* Output Routes */
783 /* Output Amplifier */
823 {"Ext Right PGA", NULL, "VAUDIO"},
824 {"Ext Left PGA", NULL, "VAUDIO"},
828 /* Stream -> AIF */
846 /* AIF -> DAC mapping */
850 /* DAC -> PGA */
854 /* Ext Input -> PGA */
855 {"Ext Right PGA", NULL, "EXTR"},
856 {"Ext Left PGA", NULL, "EXTL"},
858 /* Ext PGA -> Ext Playback Switch */
859 {"Ext Right Enable", "Switch", "Ext Right PGA"},
860 {"Ext Left Enable", "Switch", "Ext Left PGA"},
862 /* HiFi PGA -> Mono Mixer */
868 /* Ext Playback Switch -> Ext Mono Mixer */
869 {"Ext Mono Right Mixer", NULL, "Ext Right Enable"},
870 {"Ext Mono Right Mixer", "Ext Mono Playback Switch", "Ext Left Enable"},
871 {"Ext Mono Left Mixer", NULL, "Ext Left Enable"},
872 {"Ext Mono Left Mixer", "Ext Mono Playback Switch", "Ext Right Enable"},
874 /* HiFi Mono Mixer -> Output Route */
885 /* Voice PGA -> Output Route */
896 /* Ext Mono Mixer -> Output Route */
897 {"Earpiece Playback Route", "Ext", "Ext Mono Right Mixer"},
898 {"Speaker Right Playback Route", "Ext", "Ext Mono Right Mixer"},
899 {"Speaker Left Playback Route", "Ext", "Ext Mono Left Mixer"},
900 {"Lineout Right Playback Route", "Ext", "Ext Mono Right Mixer"},
901 {"Lineout Left Playback Route", "Ext", "Ext Mono Left Mixer"},
902 {"Headset Right Playback Route", "Ext", "Ext Mono Right Mixer"},
903 {"Headset Left Playback Route", "Ext", "Ext Mono Left Mixer"},
904 {"EMU Right Playback Route", "Ext", "Ext Mono Right Mixer"},
905 {"EMU Left Playback Route", "Ext", "Ext Mono Left Mixer"},
907 /* Output Route -> Output Amplifier */
918 /* Output Amplifier -> Output */
929 /* Headset Charge Pump -> Headset */
933 /* Mic -> Mic Route */
937 {"Right Capture Route", "Ext Right", "EXTR"},
939 {"Left Capture Route", "Ext Left", "EXTL"},
941 /* Input Route -> Microphone PGA */
945 /* Microphone PGA -> ADC */
949 /* ADC -> Stream */
981 dev_err(cpcap->component->dev, "invalid DAI: %d", dai); in cpcap_set_sysclk()
982 return -EINVAL; in cpcap_set_sysclk()
987 dev_err(cpcap->component->dev, "invalid clk id %d", clk_id); in cpcap_set_sysclk()
988 return -EINVAL; in cpcap_set_sysclk()
990 err = regmap_update_bits(cpcap->regmap, clkidreg, BIT(clkidshift), in cpcap_set_sysclk()
999 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_set_sysclk()
1027 dev_err(cpcap->component->dev, "unsupported freq %u", freq); in cpcap_set_sysclk()
1028 return -EINVAL; in cpcap_set_sysclk()
1031 err = regmap_update_bits(cpcap->regmap, clkfreqreg, in cpcap_set_sysclk()
1037 cpcap->codec_clk_id = clk_id; in cpcap_set_sysclk()
1038 cpcap->codec_freq = freq; in cpcap_set_sysclk()
1047 struct snd_soc_component *component = cpcap->component; in cpcap_set_samprate()
1065 dev_err(component->dev, "invalid DAI: %d", dai); in cpcap_set_samprate()
1066 return -EINVAL; in cpcap_set_samprate()
1099 dev_err(component->dev, "unsupported samplerate %d", samplerate); in cpcap_set_samprate()
1100 return -EINVAL; in cpcap_set_samprate()
1102 err = regmap_update_bits(cpcap->regmap, sampreg, in cpcap_set_samprate()
1107 /* Wait for clock tree reset to complete */ in cpcap_set_samprate()
1110 err = regmap_read(cpcap->regmap, sampreg, &sampreadval); in cpcap_set_samprate()
1115 dev_err(component->dev, "reset self-clear failed: %04x", in cpcap_set_samprate()
1117 return -EIO; in cpcap_set_samprate()
1127 struct snd_soc_component *component = dai->component; in cpcap_hifi_hw_params()
1131 dev_dbg(component->dev, "HiFi setup HW params: rate=%d", rate); in cpcap_hifi_hw_params()
1138 struct snd_soc_component *component = codec_dai->component; in cpcap_hifi_set_dai_sysclk()
1140 struct device *dev = component->dev; in cpcap_hifi_set_dai_sysclk()
1149 struct snd_soc_component *component = codec_dai->component; in cpcap_hifi_set_dai_fmt()
1151 struct device *dev = component->dev; in cpcap_hifi_set_dai_fmt()
1171 * SND_SOC_DAIFMT_CBP_CFP - codec clk & frm provider in cpcap_hifi_set_dai_fmt()
1172 * SND_SOC_DAIFMT_I2S - I2S mode in cpcap_hifi_set_dai_fmt()
1180 return -EINVAL; in cpcap_hifi_set_dai_fmt()
1202 return -EINVAL; in cpcap_hifi_set_dai_fmt()
1216 /* 01 - 4 slots network mode */ in cpcap_hifi_set_dai_fmt()
1225 return regmap_update_bits(cpcap->regmap, reg, mask, val); in cpcap_hifi_set_dai_fmt()
1230 struct snd_soc_component *component = dai->component; in cpcap_hifi_set_mute()
1241 dev_dbg(component->dev, "HiFi mute: %d", mute); in cpcap_hifi_set_mute()
1242 return regmap_update_bits(cpcap->regmap, reg, mask, val); in cpcap_hifi_set_mute()
1257 struct snd_soc_component *component = dai->component; in cpcap_voice_hw_params()
1258 struct device *dev = component->dev; in cpcap_voice_hw_params()
1263 int direction = substream->stream; in cpcap_voice_hw_params()
1285 err = regmap_update_bits(cpcap->regmap, reg_cdi, mask, val); in cpcap_voice_hw_params()
1296 struct snd_soc_component *component = codec_dai->component; in cpcap_voice_set_dai_sysclk()
1299 dev_dbg(component->dev, "Voice setup sysclk: clk_id=%u, freq=%u", in cpcap_voice_set_dai_sysclk()
1307 struct snd_soc_component *component = codec_dai->component; in cpcap_voice_set_dai_fmt()
1317 dev_dbg(component->dev, "Voice setup dai format (%08x)", fmt); in cpcap_voice_set_dai_fmt()
1321 * configured as SND_SOC_DAIFMT_CBP_CFP - codec clk & frm in cpcap_voice_set_dai_fmt()
1329 dev_err(component->dev, "Voice dai fmt failed: CPCAP should be the provider"); in cpcap_voice_set_dai_fmt()
1352 dev_err(component->dev, "Voice dai fmt failed: unsupported clock invert mode"); in cpcap_voice_set_dai_fmt()
1363 /* 11 - true I2S mode */ in cpcap_voice_set_dai_fmt()
1374 dev_dbg(component->dev, "Voice dai format: val=%04x", val); in cpcap_voice_set_dai_fmt()
1375 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, mask, val); in cpcap_voice_set_dai_fmt()
1379 cpcap->codec_format = val; in cpcap_voice_set_dai_fmt()
1398 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC, in cpcap_voice_call()
1405 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_voice_call()
1413 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_voice_call()
1420 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA, in cpcap_voice_call()
1427 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, in cpcap_voice_call()
1444 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, in cpcap_voice_call()
1451 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_voice_call()
1461 struct snd_soc_component *component = dai->component; in cpcap_voice_set_tdm_slot()
1468 * later on for 16-bit calls detected, Bluetooth headset etc. in cpcap_voice_set_tdm_slot()
1481 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_voice_set_tdm_slot()
1499 struct snd_soc_component *component = dai->component; in cpcap_voice_set_mute()
1510 dev_dbg(component->dev, "Voice mute: %d", mute); in cpcap_voice_set_mute()
1511 return regmap_update_bits(cpcap->regmap, reg, mask, val); in cpcap_voice_set_mute()
1526 .name = "cpcap-hifi",
1538 .name = "cpcap-voice",
1576 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_dai_mux()
1581 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_SDACDI, in cpcap_dai_mux()
1595 dev_dbg(component->dev, "init audio codec"); in cpcap_audio_reset()
1598 err = regmap_update_bits(cpcap->regmap, in cpcap_audio_reset()
1634 cpcap = devm_kzalloc(component->dev, sizeof(*cpcap), GFP_KERNEL); in cpcap_soc_probe()
1636 return -ENOMEM; in cpcap_soc_probe()
1638 cpcap->component = component; in cpcap_soc_probe()
1640 cpcap->regmap = dev_get_regmap(component->dev->parent, NULL); in cpcap_soc_probe()
1641 if (!cpcap->regmap) in cpcap_soc_probe()
1642 return -ENODEV; in cpcap_soc_probe()
1643 snd_soc_component_init_regmap(component, cpcap->regmap); in cpcap_soc_probe()
1645 err = cpcap_get_vendor(component->dev, cpcap->regmap, &cpcap->vendor); in cpcap_soc_probe()
1668 of_get_child_by_name(pdev->dev.parent->of_node, "audio-codec"); in cpcap_codec_probe()
1670 return -ENODEV; in cpcap_codec_probe()
1672 pdev->dev.of_node = codec_node; in cpcap_codec_probe()
1674 return devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_cpcap, in cpcap_codec_probe()
1681 .name = "cpcap-codec",
1686 MODULE_ALIAS("platform:cpcap-codec");