Lines Matching +full:dac +full:- +full:mode +full:- +full:mask
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 */
227 u16 mask; member
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);
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, ®_voice); in cpcap_output_mux_get_enum()
379 err = regmap_read(cpcap->regmap, CPCAP_REG_RXSDOA, ®_hifi); in cpcap_output_mux_get_enum()
382 err = regmap_read(cpcap->regmap, CPCAP_REG_RXEPOA, ®_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() local
424 reg_voice = mask; in cpcap_output_mux_put_enum()
427 reg_hifi = mask; in cpcap_output_mux_put_enum()
430 reg_ext = mask; in cpcap_output_mux_put_enum()
436 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, in cpcap_output_mux_put_enum()
437 mask, reg_voice); in cpcap_output_mux_put_enum()
440 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXSDOA, in cpcap_output_mux_put_enum()
441 mask, reg_hifi); in cpcap_output_mux_put_enum()
444 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXEPOA, in cpcap_output_mux_put_enum()
445 mask, reg_ext); in cpcap_output_mux_put_enum()
459 int regval, mask; in cpcap_input_right_mux_get_enum() local
462 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, ®val); in cpcap_input_right_mux_get_enum()
466 mask = 0; in cpcap_input_right_mux_get_enum()
467 mask |= BIT(CPCAP_BIT_MIC1_MUX); in cpcap_input_right_mux_get_enum()
468 mask |= BIT(CPCAP_BIT_HS_MIC_MUX); in cpcap_input_right_mux_get_enum()
469 mask |= BIT(CPCAP_BIT_EMU_MIC_MUX); in cpcap_input_right_mux_get_enum()
470 mask |= BIT(CPCAP_BIT_RX_R_ENCODE); in cpcap_input_right_mux_get_enum()
472 switch (regval & mask) { 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()
502 int regval = 0, mask; in cpcap_input_right_mux_put_enum() local
505 mask = 0; in cpcap_input_right_mux_put_enum()
506 mask |= BIT(CPCAP_BIT_MIC1_MUX); in cpcap_input_right_mux_put_enum()
507 mask |= BIT(CPCAP_BIT_HS_MIC_MUX); in cpcap_input_right_mux_put_enum()
508 mask |= BIT(CPCAP_BIT_EMU_MIC_MUX); in cpcap_input_right_mux_put_enum()
509 mask |= BIT(CPCAP_BIT_RX_R_ENCODE); in cpcap_input_right_mux_put_enum()
528 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_input_right_mux_put_enum()
529 mask, regval); in cpcap_input_right_mux_put_enum()
543 int regval, mask; in cpcap_input_left_mux_get_enum() local
546 err = regmap_read(cpcap->regmap, CPCAP_REG_TXI, ®val); in cpcap_input_left_mux_get_enum()
550 mask = 0; in cpcap_input_left_mux_get_enum()
551 mask |= BIT(CPCAP_BIT_MIC2_MUX); in cpcap_input_left_mux_get_enum()
552 mask |= BIT(CPCAP_BIT_RX_L_ENCODE); in cpcap_input_left_mux_get_enum()
554 switch (regval & mask) { 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()
578 int regval = 0, mask; in cpcap_input_left_mux_put_enum() local
581 mask = 0; in cpcap_input_left_mux_put_enum()
582 mask |= BIT(CPCAP_BIT_MIC2_MUX); in cpcap_input_left_mux_put_enum()
583 mask |= BIT(CPCAP_BIT_RX_L_ENCODE); in cpcap_input_left_mux_put_enum()
596 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_input_left_mux_put_enum()
597 mask, regval); in cpcap_input_left_mux_put_enum()
717 /* DAC */
718 SND_SOC_DAPM_DAC_E("DAC HiFi", NULL,
722 SND_SOC_DAPM_DAC_E("DAC Voice", NULL,
828 /* Stream -> AIF */
846 /* AIF -> DAC mapping */
847 {"DAC HiFi", NULL, "HiFi RX"},
848 {"DAC Voice", NULL, "Highpass Filter RX"},
850 /* DAC -> PGA */
851 {"HiFi PGA", NULL, "DAC HiFi"},
852 {"Voice PGA", NULL, "DAC Voice"},
854 /* Ext Input -> PGA */
858 /* Ext PGA -> Ext Playback Switch */
862 /* HiFi PGA -> Mono Mixer */
868 /* Ext Playback Switch -> Ext Mono Mixer */
874 /* HiFi Mono Mixer -> Output Route */
885 /* Voice PGA -> Output Route */
896 /* Ext Mono Mixer -> Output Route */
907 /* Output Route -> Output Amplifier */
918 /* Output Amplifier -> Output */
929 /* Headset Charge Pump -> Headset */
933 /* Mic -> Mic Route */
941 /* Input Route -> Microphone PGA */
945 /* Microphone PGA -> ADC */
949 /* ADC -> Stream */
964 u16 mask, val; in cpcap_set_sysclk() local
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()
997 mask = BIT(CPCAP_BIT_CDC_PLL_SEL); in cpcap_set_sysclk()
999 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_set_sysclk()
1000 mask, val); 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()
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()
1153 static const u16 mask = in cpcap_hifi_set_dai_fmt() local
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()
1201 dev_err(dev, "HiFi dai fmt failed: unsupported clock invert mode"); 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()
1233 static const u16 mask = BIT(CPCAP_BIT_ST_DAC_SW); in cpcap_hifi_set_mute() local
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()
1264 u16 val, mask; in cpcap_voice_hw_params() local
1275 mask = 0x0000; in cpcap_voice_hw_params()
1276 mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0); in cpcap_voice_hw_params()
1277 mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT1); in cpcap_voice_hw_params()
1278 mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT2); in cpcap_voice_hw_params()
1279 mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT0); in cpcap_voice_hw_params()
1280 mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT1); in cpcap_voice_hw_params()
1281 mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT2); 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()
1309 static const u16 mask = BIT(CPCAP_BIT_SMB_CDC) | in cpcap_voice_set_dai_fmt() local
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()
1368 /* 4 timeslots network 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()
1394 int mask, err; in cpcap_voice_call() local
1397 mask = BIT(CPCAP_BIT_VAUDIO_MODE1); in cpcap_voice_call()
1398 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_VAUDIOC, in cpcap_voice_call()
1399 mask, voice_call ? mask : 0); in cpcap_voice_call()
1404 mask = BIT(CPCAP_BIT_MIC1_MUX); in cpcap_voice_call()
1405 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_voice_call()
1406 mask, voice_call ? 0 : mask); in cpcap_voice_call()
1411 mask = BIT(CPCAP_BIT_MB_ON1L) | BIT(CPCAP_BIT_MB_ON1R) | in cpcap_voice_call()
1413 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_TXI, in cpcap_voice_call()
1414 mask, voice_call ? mask : 0); in cpcap_voice_call()
1419 mask = BIT(CPCAP_BIT_A2_LDSP_L_EN) | BIT(CPCAP_BIT_A2_LDSP_R_EN); in cpcap_voice_call()
1420 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXOA, in cpcap_voice_call()
1421 mask, voice_call ? mask : 0); in cpcap_voice_call()
1426 mask = BIT(CPCAP_BIT_PGA_CDC_EN); in cpcap_voice_call()
1427 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_RXCOA, in cpcap_voice_call()
1428 mask, voice_call ? mask : 0); in cpcap_voice_call()
1441 mask = BIT(CPCAP_BIT_MIC2_CDC_EN) | BIT(CPCAP_BIT_CDC_EN_RX) | in cpcap_voice_call()
1444 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CC, in cpcap_voice_call()
1445 mask, voice_call ? mask : 0); in cpcap_voice_call()
1450 mask = BIT(CPCAP_BIT_CDC_CLK_EN); in cpcap_voice_call()
1451 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_voice_call()
1452 mask, voice_call ? mask : 0); in cpcap_voice_call()
1461 struct snd_soc_component *component = dai->component; in cpcap_voice_set_tdm_slot()
1463 int err, ts_mask, mask; in cpcap_voice_set_tdm_slot() local
1468 * later on for 16-bit calls detected, Bluetooth headset etc. in cpcap_voice_set_tdm_slot()
1478 mask = (tx_mask & 0x7) << CPCAP_BIT_MIC2_TIMESLOT0; in cpcap_voice_set_tdm_slot()
1479 mask |= (rx_mask & 0x7) << CPCAP_BIT_MIC1_RX_TIMESLOT0; in cpcap_voice_set_tdm_slot()
1481 err = regmap_update_bits(cpcap->regmap, CPCAP_REG_CDI, in cpcap_voice_set_tdm_slot()
1482 ts_mask, mask); in cpcap_voice_set_tdm_slot()
1499 struct snd_soc_component *component = dai->component; in cpcap_voice_set_mute()
1502 static const u16 mask = BIT(CPCAP_BIT_CDC_SW); in cpcap_voice_set_mute() local
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()
1600 cpcap_default_regs[i].mask, 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");