Lines Matching +full:invert +full:- +full:ext
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2017 - 2018 Sebastian Reichel <sre@kernel.org>
8 * Copyright (C) 2007 - 2009 Motorola, Inc.
15 #include <linux/mfd/motorola-cpcap.h>
22 /* Register 8 - CPCAP_REG_INTS1 --- Interrupt Sense 1 */
26 /* Register 9 - CPCAP_REG_INTS2 --- Interrupt Sense 2 */
29 /* Register 512 CPCAP_REG_VAUDIOC --- Audio Regulator and Bias Voltage */
37 /* Register 513 CPCAP_REG_CC --- CODEC */
55 /* Register 514 CPCAP_REG_CDI --- CODEC Digital Audio Interface */
72 /* Register 515 CPCAP_REG_SDAC --- Stereo DAC */
86 /* Register 516 CPCAP_REG_SDACDI --- Stereo DAC Digital Audio Interface */
102 /* Register 517 CPCAP_REG_TXI --- TX Interface */
120 /* Register 518 CPCAP_REG_TXMP --- Mic Gain */
134 /* Register 519 CPCAP_REG_RXOA --- RX Output Amplifier */
152 /* Register 520 CPCAP_REG_RXVC --- RX Volume Control */
170 /* Register 521 CPCAP_REG_RXCOA --- Codec to Output Amp Switches */
183 /* Register 522 CPCAP_REG_RXSDOA --- RX Stereo DAC to Output Amp Switches */
198 /* Register 523 CPCAP_REG_RXEPOA --- RX External PGA to Output Amp Switches */
215 /* Register 525 CPCAP_REG_A2LA --- SPK Amplifier and Clock Config for Headset */
282 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); in cpcap_st_workaround()
287 if (cpcap->vendor != CPCAP_VENDOR_ST) in cpcap_st_workaround()
292 err = regmap_write(cpcap->regmap, CPCAP_REG_TEST, in cpcap_st_workaround()
296 err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1, in cpcap_st_workaround()
302 err = regmap_write(cpcap->regmap, CPCAP_REG_ST_TEST1, in cpcap_st_workaround()
306 err = regmap_write(cpcap->regmap, CPCAP_REG_TEST, in cpcap_st_workaround()
319 /* Playback Gain Control: -33dB to 12dB in 3dB steps */
320 static const DECLARE_TLV_DB_SCALE(vol_tlv, -3300, 300, 0);
328 SOC_SINGLE_TLV("Ext Playback Volume",
337 /* Phase Invert */
338 SOC_SINGLE("Hifi Left Phase Invert Switch",
340 SOC_SINGLE("Ext Left Phase Invert Switch",
345 "Off", "Voice", "HiFi", "Ext"
349 "Off", "Mic 1", "Headset Mic", "EMU Mic", "Ext Right"
353 "Off", "Mic 2", "Ext Left"
385 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_output_mux_get_enum()
386 unsigned int shift = e->shift_l; in cpcap_output_mux_get_enum()
390 err = regmap_read(cpcap->regmap, CPCAP_REG_RXCOA, ®_voice); in cpcap_output_mux_get_enum()
393 err = regmap_read(cpcap->regmap, CPCAP_REG_RXSDOA, ®_hifi); in cpcap_output_mux_get_enum()
396 err = regmap_read(cpcap->regmap, CPCAP_REG_RXEPOA, ®_ext); in cpcap_output_mux_get_enum()
407 ucontrol->value.enumerated.item[0] = 3; in cpcap_output_mux_get_enum()
410 ucontrol->value.enumerated.item[0] = 2; in cpcap_output_mux_get_enum()
413 ucontrol->value.enumerated.item[0] = 1; in cpcap_output_mux_get_enum()
416 ucontrol->value.enumerated.item[0] = 0; in cpcap_output_mux_get_enum()
430 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_output_mux_put_enum()
431 unsigned int muxval = ucontrol->value.enumerated.item[0]; in cpcap_output_mux_put_enum()
432 unsigned int mask = BIT(e->shift_l); in cpcap_output_mux_put_enum()
450 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, in cpcap_output_mux_put_enum()
454 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXSDOA, in cpcap_output_mux_put_enum()
458 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXEPOA, in cpcap_output_mux_put_enum()
476 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, ®val); in cpcap_input_right_mux_get_enum()
488 ucontrol->value.enumerated.item[0] = 4; in cpcap_input_right_mux_get_enum()
491 ucontrol->value.enumerated.item[0] = 3; in cpcap_input_right_mux_get_enum()
494 ucontrol->value.enumerated.item[0] = 2; in cpcap_input_right_mux_get_enum()
497 ucontrol->value.enumerated.item[0] = 1; in cpcap_input_right_mux_get_enum()
500 ucontrol->value.enumerated.item[0] = 0; in cpcap_input_right_mux_get_enum()
514 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_input_right_mux_put_enum()
515 unsigned int muxval = ucontrol->value.enumerated.item[0]; in cpcap_input_right_mux_put_enum()
542 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_input_right_mux_put_enum()
560 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, ®val); in cpcap_input_left_mux_get_enum()
570 ucontrol->value.enumerated.item[0] = 2; in cpcap_input_left_mux_get_enum()
573 ucontrol->value.enumerated.item[0] = 1; in cpcap_input_left_mux_get_enum()
576 ucontrol->value.enumerated.item[0] = 0; in cpcap_input_left_mux_get_enum()
590 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in cpcap_input_left_mux_put_enum()
591 unsigned int muxval = ucontrol->value.enumerated.item[0]; in cpcap_input_left_mux_put_enum()
610 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_input_left_mux_put_enum()
661 SOC_DAPM_SINGLE("Ext Mono Playback Switch",
746 SND_SOC_DAPM_PGA_E("Ext Right PGA",
751 SND_SOC_DAPM_PGA_E("Ext Left PGA",
758 SND_SOC_DAPM_SWITCH("Ext Right Enable", SND_SOC_NOPM, 0, 0,
760 SND_SOC_DAPM_SWITCH("Ext Left Enable", SND_SOC_NOPM, 0, 0,
772 SOC_MIXER_ARRAY("Ext Mono Left Mixer", SND_SOC_NOPM, 0, 0,
774 SOC_MIXER_ARRAY("Ext Mono Right Mixer", SND_SOC_NOPM, 0, 0,
837 {"Ext Right PGA", NULL, "VAUDIO"},
838 {"Ext Left PGA", NULL, "VAUDIO"},
842 /* Stream -> AIF */
860 /* AIF -> DAC mapping */
864 /* DAC -> PGA */
868 /* Ext Input -> PGA */
869 {"Ext Right PGA", NULL, "EXTR"},
870 {"Ext Left PGA", NULL, "EXTL"},
872 /* Ext PGA -> Ext Playback Switch */
873 {"Ext Right Enable", "Switch", "Ext Right PGA"},
874 {"Ext Left Enable", "Switch", "Ext Left PGA"},
876 /* HiFi PGA -> Mono Mixer */
882 /* Ext Playback Switch -> Ext Mono Mixer */
883 {"Ext Mono Right Mixer", NULL, "Ext Right Enable"},
884 {"Ext Mono Right Mixer", "Ext Mono Playback Switch", "Ext Left Enable"},
885 {"Ext Mono Left Mixer", NULL, "Ext Left Enable"},
886 {"Ext Mono Left Mixer", "Ext Mono Playback Switch", "Ext Right Enable"},
888 /* HiFi Mono Mixer -> Output Route */
899 /* Voice PGA -> Output Route */
910 /* Ext Mono Mixer -> Output Route */
911 {"Earpiece Playback Route", "Ext", "Ext Mono Right Mixer"},
912 {"Speaker Right Playback Route", "Ext", "Ext Mono Right Mixer"},
913 {"Speaker Left Playback Route", "Ext", "Ext Mono Left Mixer"},
914 {"Lineout Right Playback Route", "Ext", "Ext Mono Right Mixer"},
915 {"Lineout Left Playback Route", "Ext", "Ext Mono Left Mixer"},
916 {"Headset Right Playback Route", "Ext", "Ext Mono Right Mixer"},
917 {"Headset Left Playback Route", "Ext", "Ext Mono Left Mixer"},
918 {"EMU Right Playback Route", "Ext", "Ext Mono Right Mixer"},
919 {"EMU Left Playback Route", "Ext", "Ext Mono Left Mixer"},
921 /* Output Route -> Output Amplifier */
932 /* Output Amplifier -> Output */
943 /* Headset Charge Pump -> Headset */
947 /* Mic -> Mic Route */
951 {"Right Capture Route", "Ext Right", "EXTR"},
953 {"Left Capture Route", "Ext Left", "EXTL"},
955 /* Input Route -> Microphone PGA */
959 /* Microphone PGA -> ADC */
963 /* ADC -> Stream */
995 dev_err(cpcap->component->dev, "invalid DAI: %d", dai); in cpcap_set_sysclk()
996 return -EINVAL; in cpcap_set_sysclk()
1001 dev_err(cpcap->component->dev, "invalid clk id %d", clk_id); in cpcap_set_sysclk()
1002 return -EINVAL; in cpcap_set_sysclk()
1004 err = regmap_update_bits(cpcap->regmap, clkidreg, BIT(clkidshift), in cpcap_set_sysclk()
1013 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_set_sysclk()
1041 dev_err(cpcap->component->dev, "unsupported freq %u", freq); in cpcap_set_sysclk()
1042 return -EINVAL; in cpcap_set_sysclk()
1045 err = regmap_update_bits(cpcap->regmap, clkfreqreg, in cpcap_set_sysclk()
1051 cpcap->codec_clk_id = clk_id; in cpcap_set_sysclk()
1052 cpcap->codec_freq = freq; in cpcap_set_sysclk()
1061 struct snd_soc_component *component = cpcap->component; in cpcap_set_samprate()
1079 dev_err(component->dev, "invalid DAI: %d", dai); in cpcap_set_samprate()
1080 return -EINVAL; in cpcap_set_samprate()
1113 dev_err(component->dev, "unsupported samplerate %d", samplerate); in cpcap_set_samprate()
1114 return -EINVAL; in cpcap_set_samprate()
1116 err = regmap_update_bits(cpcap->regmap, sampreg, in cpcap_set_samprate()
1124 err = regmap_read(cpcap->regmap, sampreg, &sampreadval); in cpcap_set_samprate()
1129 dev_err(component->dev, "reset self-clear failed: %04x", in cpcap_set_samprate()
1131 return -EIO; in cpcap_set_samprate()
1141 struct snd_soc_component *component = dai->component; in cpcap_hifi_hw_params()
1145 dev_dbg(component->dev, "HiFi setup HW params: rate=%d", rate); in cpcap_hifi_hw_params()
1152 struct snd_soc_component *component = codec_dai->component; in cpcap_hifi_set_dai_sysclk()
1154 struct device *dev = component->dev; in cpcap_hifi_set_dai_sysclk()
1163 struct snd_soc_component *component = codec_dai->component; in cpcap_hifi_set_dai_fmt()
1165 struct device *dev = component->dev; in cpcap_hifi_set_dai_fmt()
1185 * SND_SOC_DAIFMT_CBP_CFP - codec clk & frm provider in cpcap_hifi_set_dai_fmt()
1186 * SND_SOC_DAIFMT_I2S - I2S mode in cpcap_hifi_set_dai_fmt()
1194 return -EINVAL; in cpcap_hifi_set_dai_fmt()
1215 dev_err(dev, "HiFi dai fmt failed: unsupported clock invert mode"); in cpcap_hifi_set_dai_fmt()
1216 return -EINVAL; in cpcap_hifi_set_dai_fmt()
1230 /* 01 - 4 slots network mode */ in cpcap_hifi_set_dai_fmt()
1239 return regmap_update_bits(cpcap->regmap, reg, mask, val); in cpcap_hifi_set_dai_fmt()
1244 struct snd_soc_component *component = dai->component; in cpcap_hifi_set_mute()
1255 dev_dbg(component->dev, "HiFi mute: %d", mute); in cpcap_hifi_set_mute()
1256 return regmap_update_bits(cpcap->regmap, reg, mask, val); in cpcap_hifi_set_mute()
1271 struct snd_soc_component *component = dai->component; in cpcap_voice_hw_params()
1272 struct device *dev = component->dev; in cpcap_voice_hw_params()
1277 int direction = substream->stream; in cpcap_voice_hw_params()
1299 err = regmap_update_bits(cpcap->regmap, reg_cdi, mask, val); in cpcap_voice_hw_params()
1310 struct snd_soc_component *component = codec_dai->component; in cpcap_voice_set_dai_sysclk()
1313 dev_dbg(component->dev, "Voice setup sysclk: clk_id=%u, freq=%u", in cpcap_voice_set_dai_sysclk()
1321 struct snd_soc_component *component = codec_dai->component; in cpcap_voice_set_dai_fmt()
1331 dev_dbg(component->dev, "Voice setup dai format (%08x)", fmt); in cpcap_voice_set_dai_fmt()
1335 * configured as SND_SOC_DAIFMT_CBP_CFP - codec clk & frm in cpcap_voice_set_dai_fmt()
1343 dev_err(component->dev, "Voice dai fmt failed: CPCAP should be the provider"); in cpcap_voice_set_dai_fmt()
1366 dev_err(component->dev, "Voice dai fmt failed: unsupported clock invert mode"); in cpcap_voice_set_dai_fmt()
1377 /* 11 - true I2S mode */ in cpcap_voice_set_dai_fmt()
1388 dev_dbg(component->dev, "Voice dai format: val=%04x", val); in cpcap_voice_set_dai_fmt()
1389 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, mask, val); in cpcap_voice_set_dai_fmt()
1393 cpcap->codec_format = val; in cpcap_voice_set_dai_fmt()
1412 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC, in cpcap_voice_call()
1419 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_voice_call()
1427 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_voice_call()
1434 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA, in cpcap_voice_call()
1441 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, in cpcap_voice_call()
1458 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, in cpcap_voice_call()
1465 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_voice_call()
1475 struct snd_soc_component *component = dai->component; in cpcap_voice_set_tdm_slot()
1482 * later on for 16-bit calls detected, Bluetooth headset etc. in cpcap_voice_set_tdm_slot()
1495 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_voice_set_tdm_slot()
1513 struct snd_soc_component *component = dai->component; in cpcap_voice_set_mute()
1524 dev_dbg(component->dev, "Voice mute: %d", mute); in cpcap_voice_set_mute()
1525 return regmap_update_bits(cpcap->regmap, reg, mask, val); in cpcap_voice_set_mute()
1540 .name = "cpcap-hifi",
1552 .name = "cpcap-voice",
1590 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_dai_mux()
1595 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_SDACDI, in cpcap_dai_mux()
1609 dev_dbg(component->dev, "init audio codec"); in cpcap_audio_reset()
1612 err = regmap_update_bits(cpcap->regmap, in cpcap_audio_reset()
1647 struct regmap *regmap = cpcap->regmap; in cpcap_hs_irq_thread()
1659 regulator_set_mode(cpcap->vaudio, REGULATOR_MODE_NORMAL); in cpcap_hs_irq_thread()
1670 dev_info(component->dev, "HP plugged in\n"); in cpcap_hs_irq_thread()
1674 dev_info(component->dev, "HS plugged in\n"); in cpcap_hs_irq_thread()
1676 dev_info(component->dev, "Unsupported HS plugged in\n"); in cpcap_hs_irq_thread()
1678 bool mic = cpcap->jack.status & SND_JACK_MICROPHONE; in cpcap_hs_irq_thread()
1680 dev_info(component->dev, "H%s disconnect\n", mic ? "S" : "P"); in cpcap_hs_irq_thread()
1682 regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, val, 0); in cpcap_hs_irq_thread()
1685 regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA, val, 0); in cpcap_hs_irq_thread()
1687 regulator_set_mode(cpcap->vaudio, REGULATOR_MODE_STANDBY); in cpcap_hs_irq_thread()
1692 snd_soc_jack_report(&cpcap->jack, status, mask); in cpcap_hs_irq_thread()
1701 struct regmap *regmap = cpcap->regmap; in cpcap_mb2_irq_thread()
1713 if (!(cpcap->jack.status & SND_JACK_MICROPHONE)) { in cpcap_mb2_irq_thread()
1715 dev_info(component->dev, "MIC plugged in\n"); in cpcap_mb2_irq_thread()
1716 snd_soc_jack_report(&cpcap->jack, SND_JACK_MICROPHONE, in cpcap_mb2_irq_thread()
1726 snd_soc_jack_report(&cpcap->jack, status, SND_JACK_BTN_0); in cpcap_mb2_irq_thread()
1733 struct platform_device *pdev = to_platform_device(component->dev); in cpcap_soc_probe()
1734 struct snd_soc_card *card = component->card; in cpcap_soc_probe()
1738 cpcap = devm_kzalloc(component->dev, sizeof(*cpcap), GFP_KERNEL); in cpcap_soc_probe()
1740 return -ENOMEM; in cpcap_soc_probe()
1743 cpcap->component = component; in cpcap_soc_probe()
1745 cpcap->vaudio = devm_regulator_get(component->dev, "VAUDIO"); in cpcap_soc_probe()
1746 if (IS_ERR(cpcap->vaudio)) in cpcap_soc_probe()
1747 return dev_err_probe(component->dev, PTR_ERR(cpcap->vaudio), in cpcap_soc_probe()
1752 &cpcap->jack); in cpcap_soc_probe()
1754 dev_err(component->dev, "Cannot create HS jack: %i\n", err); in cpcap_soc_probe()
1758 snd_jack_set_key(cpcap->jack.jack, SND_JACK_BTN_0, KEY_MEDIA); in cpcap_soc_probe()
1760 cpcap->regmap = dev_get_regmap(component->dev->parent, NULL); in cpcap_soc_probe()
1761 if (!cpcap->regmap) in cpcap_soc_probe()
1762 return -ENODEV; in cpcap_soc_probe()
1763 snd_soc_component_init_regmap(component, cpcap->regmap); in cpcap_soc_probe()
1765 err = cpcap_get_vendor(component->dev, cpcap->regmap, &cpcap->vendor); in cpcap_soc_probe()
1769 cpcap->hsirq = platform_get_irq_byname(pdev, "hs"); in cpcap_soc_probe()
1770 if (cpcap->hsirq < 0) in cpcap_soc_probe()
1771 return cpcap->hsirq; in cpcap_soc_probe()
1773 err = devm_request_threaded_irq(component->dev, cpcap->hsirq, NULL, in cpcap_soc_probe()
1778 "cpcap-codec-hs", in cpcap_soc_probe()
1781 dev_warn(component->dev, "no HS irq%i: %i\n", in cpcap_soc_probe()
1782 cpcap->hsirq, err); in cpcap_soc_probe()
1786 cpcap->mb2irq = platform_get_irq_byname(pdev, "mb2"); in cpcap_soc_probe()
1787 if (cpcap->mb2irq < 0) in cpcap_soc_probe()
1788 return cpcap->mb2irq; in cpcap_soc_probe()
1790 err = devm_request_threaded_irq(component->dev, cpcap->mb2irq, NULL, in cpcap_soc_probe()
1795 "cpcap-codec-mb2", in cpcap_soc_probe()
1798 dev_warn(component->dev, "no MB2 irq%i: %i\n", in cpcap_soc_probe()
1799 cpcap->mb2irq, err); in cpcap_soc_probe()
1807 cpcap_hs_irq_thread(cpcap->hsirq, component); in cpcap_soc_probe()
1809 enable_irq_wake(cpcap->hsirq); in cpcap_soc_probe()
1810 enable_irq_wake(cpcap->mb2irq); in cpcap_soc_probe()
1819 disable_irq_wake(cpcap->hsirq); in cpcap_soc_remove()
1820 disable_irq_wake(cpcap->mb2irq); in cpcap_soc_remove()
1829 if (cpcap->jack.status & SND_JACK_MICROPHONE) in cpcap_set_bias_level()
1836 regulator_set_mode(cpcap->vaudio, REGULATOR_MODE_NORMAL); in cpcap_set_bias_level()
1839 regulator_set_mode(cpcap->vaudio, REGULATOR_MODE_STANDBY); in cpcap_set_bias_level()
1866 of_get_child_by_name(pdev->dev.parent->of_node, "audio-codec"); in cpcap_codec_probe()
1868 return -ENODEV; in cpcap_codec_probe()
1870 pdev->dev.of_node = codec_node; in cpcap_codec_probe()
1872 return devm_snd_soc_register_component(&pdev->dev, &soc_codec_dev_cpcap, in cpcap_codec_probe()
1879 .name = "cpcap-codec",
1884 MODULE_ALIAS("platform:cpcap-codec");