Lines Matching +full:sm8250 +full:- +full:lpass +full:- +full:va +full:- +full:macro

1 // SPDX-License-Identifier: GPL-2.0-only
2 // Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
5 #include <linux/clk-provider.h>
16 #include <sound/soc-dapm.h>
19 #include "lpass-macro-common.h"
21 /* VA macro registers */
165 static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
209 struct clk *macro;
266 /* VA macro */
290 /* VA core */
452 static int va_clk_rsc_fs_gen_request(struct va_macro *va, bool enable)
454 struct regmap *regmap = va->regmap;
485 static int va_macro_mclk_enable(struct va_macro *va, bool mclk_enable)
487 struct regmap *regmap = va->regmap;
490 va_clk_rsc_fs_gen_request(va, true);
494 va_clk_rsc_fs_gen_request(va, false);
503 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
504 struct va_macro *va = snd_soc_component_get_drvdata(comp);
508 return clk_prepare_enable(va->fsgen);
510 clk_disable_unprepare(va->fsgen);
522 snd_soc_dapm_to_component(widget->dapm);
523 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
527 val = ucontrol->value.enumerated.item[0];
529 switch (e->reg) {
543 dev_err(component->dev, "%s: e->reg: 0x%x not expected\n",
544 __func__, e->reg);
545 return -EINVAL;
562 snd_soc_dapm_to_component(widget->dapm);
564 (struct soc_mixer_control *)kcontrol->private_value;
565 u32 dai_id = widget->shift;
566 u32 dec_id = mc->shift;
567 struct va_macro *va = snd_soc_component_get_drvdata(component);
569 if (test_bit(dec_id, &va->active_ch_mask[dai_id]))
570 ucontrol->value.integer.value[0] = 1;
572 ucontrol->value.integer.value[0] = 0;
583 snd_soc_dapm_to_component(widget->dapm);
586 (struct soc_mixer_control *)kcontrol->private_value;
587 u32 dai_id = widget->shift;
588 u32 dec_id = mc->shift;
589 u32 enable = ucontrol->value.integer.value[0];
590 struct va_macro *va = snd_soc_component_get_drvdata(component);
593 set_bit(dec_id, &va->active_ch_mask[dai_id]);
594 va->active_ch_cnt[dai_id]++;
596 clear_bit(dec_id, &va->active_ch_mask[dai_id]);
597 va->active_ch_cnt[dai_id]--;
600 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
608 struct va_macro *va = snd_soc_component_get_drvdata(component);
618 dmic_clk_cnt = &(va->dmic_0_1_clk_cnt);
619 dmic_clk_div = &(va->dmic_0_1_clk_div);
625 dmic_clk_cnt = &(va->dmic_2_3_clk_cnt);
626 dmic_clk_div = &(va->dmic_2_3_clk_div);
632 dmic_clk_cnt = &(va->dmic_4_5_clk_cnt);
633 dmic_clk_div = &(va->dmic_4_5_clk_div);
639 dmic_clk_cnt = &(va->dmic_6_7_clk_cnt);
640 dmic_clk_div = &(va->dmic_6_7_clk_div);
645 dev_err(component->dev, "%s: Invalid DMIC Selection\n",
647 return -EINVAL;
651 clk_div = va->dmic_clk_div;
683 (*dmic_clk_cnt)--;
692 clk_div = va->dmic_clk_div;
694 clk_div = va->dmic_clk_div;
719 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
720 unsigned int dmic = w->shift;
737 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm);
743 struct va_macro *va = snd_soc_component_get_drvdata(comp);
745 decimator = w->shift;
760 va->dec_mode[decimator] << CDC_VA_ADC_MODE_SHIFT);
823 struct va_macro *va = snd_soc_component_get_drvdata(comp);
824 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
825 int path = e->shift_l;
827 ucontrol->value.enumerated.item[0] = va->dec_mode[path];
836 int value = ucontrol->value.enumerated.item[0];
837 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
838 int path = e->shift_l;
839 struct va_macro *va = snd_soc_component_get_drvdata(comp);
841 va->dec_mode[path] = value;
851 struct snd_soc_component *component = dai->component;
854 struct device *va_dev = component->dev;
855 struct va_macro *va = snd_soc_component_get_drvdata(component);
883 return -EINVAL;
886 for_each_set_bit(decimator, &va->active_ch_mask[dai->id],
900 struct snd_soc_component *component = dai->component;
901 struct device *va_dev = component->dev;
902 struct va_macro *va = snd_soc_component_get_drvdata(component);
904 switch (dai->id) {
908 *tx_slot = va->active_ch_mask[dai->id];
909 *tx_num = va->active_ch_cnt[dai->id];
920 struct snd_soc_component *component = dai->component;
921 struct va_macro *va = snd_soc_component_get_drvdata(component);
924 for_each_set_bit(decimator, &va->active_ch_mask[dai->id],
1126 SND_SOC_DAPM_MUX("VA DMIC MUX0", SND_SOC_NOPM, 0, 0, &va_dmic0_mux),
1127 SND_SOC_DAPM_MUX("VA DMIC MUX1", SND_SOC_NOPM, 0, 0, &va_dmic1_mux),
1128 SND_SOC_DAPM_MUX("VA DMIC MUX2", SND_SOC_NOPM, 0, 0, &va_dmic2_mux),
1129 SND_SOC_DAPM_MUX("VA DMIC MUX3", SND_SOC_NOPM, 0, 0, &va_dmic3_mux),
1131 SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-micb", 0, 0),
1141 SND_SOC_DAPM_ADC_E("VA DMIC0", NULL, SND_SOC_NOPM, 0, 0,
1145 SND_SOC_DAPM_ADC_E("VA DMIC1", NULL, SND_SOC_NOPM, 1, 0,
1149 SND_SOC_DAPM_ADC_E("VA DMIC2", NULL, SND_SOC_NOPM, 2, 0,
1153 SND_SOC_DAPM_ADC_E("VA DMIC3", NULL, SND_SOC_NOPM, 3, 0,
1157 SND_SOC_DAPM_ADC_E("VA DMIC4", NULL, SND_SOC_NOPM, 4, 0,
1161 SND_SOC_DAPM_ADC_E("VA DMIC5", NULL, SND_SOC_NOPM, 5, 0,
1165 SND_SOC_DAPM_ADC_E("VA DMIC6", NULL, SND_SOC_NOPM, 6, 0,
1169 SND_SOC_DAPM_ADC_E("VA DMIC7", NULL, SND_SOC_NOPM, 7, 0,
1173 SND_SOC_DAPM_INPUT("VA SWR_ADC0"),
1174 SND_SOC_DAPM_INPUT("VA SWR_ADC1"),
1175 SND_SOC_DAPM_INPUT("VA SWR_ADC2"),
1176 SND_SOC_DAPM_INPUT("VA SWR_ADC3"),
1177 SND_SOC_DAPM_INPUT("VA SWR_MIC0"),
1178 SND_SOC_DAPM_INPUT("VA SWR_MIC1"),
1179 SND_SOC_DAPM_INPUT("VA SWR_MIC2"),
1180 SND_SOC_DAPM_INPUT("VA SWR_MIC3"),
1181 SND_SOC_DAPM_INPUT("VA SWR_MIC4"),
1182 SND_SOC_DAPM_INPUT("VA SWR_MIC5"),
1183 SND_SOC_DAPM_INPUT("VA SWR_MIC6"),
1184 SND_SOC_DAPM_INPUT("VA SWR_MIC7"),
1186 SND_SOC_DAPM_MUX_E("VA DEC0 MUX", SND_SOC_NOPM, VA_MACRO_DEC0, 0,
1191 SND_SOC_DAPM_MUX_E("VA DEC1 MUX", SND_SOC_NOPM, VA_MACRO_DEC1, 0,
1196 SND_SOC_DAPM_MUX_E("VA DEC2 MUX", SND_SOC_NOPM, VA_MACRO_DEC2, 0,
1201 SND_SOC_DAPM_MUX_E("VA DEC3 MUX", SND_SOC_NOPM, VA_MACRO_DEC3, 0,
1206 SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
1220 {"VA_AIF1_CAP Mixer", "DEC0", "VA DEC0 MUX"},
1221 {"VA_AIF1_CAP Mixer", "DEC1", "VA DEC1 MUX"},
1222 {"VA_AIF1_CAP Mixer", "DEC2", "VA DEC2 MUX"},
1223 {"VA_AIF1_CAP Mixer", "DEC3", "VA DEC3 MUX"},
1225 {"VA_AIF2_CAP Mixer", "DEC0", "VA DEC0 MUX"},
1226 {"VA_AIF2_CAP Mixer", "DEC1", "VA DEC1 MUX"},
1227 {"VA_AIF2_CAP Mixer", "DEC2", "VA DEC2 MUX"},
1228 {"VA_AIF2_CAP Mixer", "DEC3", "VA DEC3 MUX"},
1230 {"VA_AIF3_CAP Mixer", "DEC0", "VA DEC0 MUX"},
1231 {"VA_AIF3_CAP Mixer", "DEC1", "VA DEC1 MUX"},
1232 {"VA_AIF3_CAP Mixer", "DEC2", "VA DEC2 MUX"},
1233 {"VA_AIF3_CAP Mixer", "DEC3", "VA DEC3 MUX"},
1235 {"VA DEC0 MUX", "VA_DMIC", "VA DMIC MUX0"},
1236 {"VA DMIC MUX0", "DMIC0", "VA DMIC0"},
1237 {"VA DMIC MUX0", "DMIC1", "VA DMIC1"},
1238 {"VA DMIC MUX0", "DMIC2", "VA DMIC2"},
1239 {"VA DMIC MUX0", "DMIC3", "VA DMIC3"},
1240 {"VA DMIC MUX0", "DMIC4", "VA DMIC4"},
1241 {"VA DMIC MUX0", "DMIC5", "VA DMIC5"},
1242 {"VA DMIC MUX0", "DMIC6", "VA DMIC6"},
1243 {"VA DMIC MUX0", "DMIC7", "VA DMIC7"},
1245 {"VA DEC1 MUX", "VA_DMIC", "VA DMIC MUX1"},
1246 {"VA DMIC MUX1", "DMIC0", "VA DMIC0"},
1247 {"VA DMIC MUX1", "DMIC1", "VA DMIC1"},
1248 {"VA DMIC MUX1", "DMIC2", "VA DMIC2"},
1249 {"VA DMIC MUX1", "DMIC3", "VA DMIC3"},
1250 {"VA DMIC MUX1", "DMIC4", "VA DMIC4"},
1251 {"VA DMIC MUX1", "DMIC5", "VA DMIC5"},
1252 {"VA DMIC MUX1", "DMIC6", "VA DMIC6"},
1253 {"VA DMIC MUX1", "DMIC7", "VA DMIC7"},
1255 {"VA DEC2 MUX", "VA_DMIC", "VA DMIC MUX2"},
1256 {"VA DMIC MUX2", "DMIC0", "VA DMIC0"},
1257 {"VA DMIC MUX2", "DMIC1", "VA DMIC1"},
1258 {"VA DMIC MUX2", "DMIC2", "VA DMIC2"},
1259 {"VA DMIC MUX2", "DMIC3", "VA DMIC3"},
1260 {"VA DMIC MUX2", "DMIC4", "VA DMIC4"},
1261 {"VA DMIC MUX2", "DMIC5", "VA DMIC5"},
1262 {"VA DMIC MUX2", "DMIC6", "VA DMIC6"},
1263 {"VA DMIC MUX2", "DMIC7", "VA DMIC7"},
1265 {"VA DEC3 MUX", "VA_DMIC", "VA DMIC MUX3"},
1266 {"VA DMIC MUX3", "DMIC0", "VA DMIC0"},
1267 {"VA DMIC MUX3", "DMIC1", "VA DMIC1"},
1268 {"VA DMIC MUX3", "DMIC2", "VA DMIC2"},
1269 {"VA DMIC MUX3", "DMIC3", "VA DMIC3"},
1270 {"VA DMIC MUX3", "DMIC4", "VA DMIC4"},
1271 {"VA DMIC MUX3", "DMIC5", "VA DMIC5"},
1272 {"VA DMIC MUX3", "DMIC6", "VA DMIC6"},
1273 {"VA DMIC MUX3", "DMIC7", "VA DMIC7"},
1275 { "VA DMIC0", NULL, "DMIC0 Pin" },
1276 { "VA DMIC1", NULL, "DMIC1 Pin" },
1277 { "VA DMIC2", NULL, "DMIC2 Pin" },
1278 { "VA DMIC3", NULL, "DMIC3 Pin" },
1279 { "VA DMIC4", NULL, "DMIC4 Pin" },
1280 { "VA DMIC5", NULL, "DMIC5 Pin" },
1281 { "VA DMIC6", NULL, "DMIC6 Pin" },
1282 { "VA DMIC7", NULL, "DMIC7 Pin" },
1302 -84, 40, digital_gain),
1304 -84, 40, digital_gain),
1306 -84, 40, digital_gain),
1308 -84, 40, digital_gain),
1322 struct va_macro *va = snd_soc_component_get_drvdata(component);
1324 snd_soc_component_init_regmap(component, va->regmap);
1330 .name = "VA MACRO",
1342 struct va_macro *va = to_va_macro(hw);
1343 struct regmap *regmap = va->regmap;
1346 if (va->has_swr_master) {
1347 ret = clk_prepare_enable(va->mclk);
1352 ret = va_macro_mclk_enable(va, true);
1353 if (va->has_swr_master)
1362 struct va_macro *va = to_va_macro(hw);
1363 struct regmap *regmap = va->regmap;
1365 if (va->has_swr_master)
1369 va_macro_mclk_enable(va, false);
1370 if (va->has_swr_master)
1371 clk_disable_unprepare(va->mclk);
1376 struct va_macro *va = to_va_macro(hw);
1379 regmap_read(va->regmap, CDC_VA_TOP_CSR_TOP_CFG0, &val);
1390 static int va_macro_register_fsgen_output(struct va_macro *va)
1392 struct clk *parent = va->mclk;
1393 struct device *dev = va->dev;
1394 struct device_node *np = dev->of_node;
1400 if (va->has_npl_clk)
1401 parent = va->npl;
1405 of_property_read_string(np, "clock-output-names", &clk_name);
1412 va->hw.init = &init;
1413 ret = devm_clk_hw_register(va->dev, &va->hw);
1417 return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &va->hw);
1421 struct va_macro *va)
1433 va->dmic_clk_div = VA_MACRO_CLK_DIV_2;
1436 va->dmic_clk_div = VA_MACRO_CLK_DIV_3;
1439 va->dmic_clk_div = VA_MACRO_CLK_DIV_4;
1442 va->dmic_clk_div = VA_MACRO_CLK_DIV_6;
1445 va->dmic_clk_div = VA_MACRO_CLK_DIV_8;
1448 va->dmic_clk_div = VA_MACRO_CLK_DIV_16;
1458 dev_err(va->dev, "%s: Invalid rate %d, for mclk %d\n",
1465 static void va_macro_set_lpass_codec_version(struct va_macro *va)
1470 regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_0, &core_id_0);
1471 regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_1, &core_id_1);
1472 regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_2, &core_id_2);
1492 dev_warn(va->dev, "Unknown Codec version, ID: %02x / %02x / %02x\n",
1497 dev_dbg(va->dev, "LPASS Codec Version %s\n", lpass_macro_get_codec_version_string(version));
1502 struct device *dev = &pdev->dev;
1504 struct va_macro *va;
1509 va = devm_kzalloc(dev, sizeof(*va), GFP_KERNEL);
1510 if (!va)
1511 return -ENOMEM;
1513 va->dev = dev;
1515 va->macro = devm_clk_get_optional(dev, "macro");
1516 if (IS_ERR(va->macro))
1517 return dev_err_probe(dev, PTR_ERR(va->macro), "unable to get macro clock\n");
1519 va->dcodec = devm_clk_get_optional(dev, "dcodec");
1520 if (IS_ERR(va->dcodec))
1521 return dev_err_probe(dev, PTR_ERR(va->dcodec), "unable to get dcodec clock\n");
1523 va->mclk = devm_clk_get(dev, "mclk");
1524 if (IS_ERR(va->mclk))
1525 return dev_err_probe(dev, PTR_ERR(va->mclk), "unable to get mclk clock\n");
1527 va->pds = lpass_macro_pds_init(dev);
1528 if (IS_ERR(va->pds))
1529 return PTR_ERR(va->pds);
1531 ret = of_property_read_u32(dev->of_node, "qcom,dmic-sample-rate",
1534 dev_err(dev, "qcom,dmic-sample-rate dt entry missing\n");
1535 va->dmic_clk_div = VA_MACRO_CLK_DIV_2;
1537 ret = va_macro_validate_dmic_sample_rate(sample_rate, va);
1539 ret = -EINVAL;
1550 va->regmap = devm_regmap_init_mmio(dev, base, &va_regmap_config);
1551 if (IS_ERR(va->regmap)) {
1552 ret = -EINVAL;
1556 dev_set_drvdata(dev, va);
1559 va->has_swr_master = data->has_swr_master;
1560 va->has_npl_clk = data->has_npl_clk;
1563 clk_set_rate(va->mclk, 2 * VA_MACRO_MCLK_FREQ);
1565 if (va->has_npl_clk) {
1566 va->npl = devm_clk_get(dev, "npl");
1567 if (IS_ERR(va->npl)) {
1568 ret = PTR_ERR(va->npl);
1572 clk_set_rate(va->npl, 2 * VA_MACRO_MCLK_FREQ);
1575 ret = clk_prepare_enable(va->macro);
1579 ret = clk_prepare_enable(va->dcodec);
1583 ret = clk_prepare_enable(va->mclk);
1587 if (va->has_npl_clk) {
1588 ret = clk_prepare_enable(va->npl);
1597 if (data->version)
1598 lpass_macro_set_codec_version(data->version);
1600 va_macro_set_lpass_codec_version(va);
1602 if (va->has_swr_master) {
1604 regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL0,
1607 regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL1,
1610 regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL2,
1616 if (va->has_swr_master) {
1617 regmap_update_bits(va->regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
1619 regmap_update_bits(va->regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
1621 regmap_update_bits(va->regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
1637 ret = va_macro_register_fsgen_output(va);
1641 va->fsgen = clk_hw_get_clk(&va->hw, "fsgen");
1642 if (IS_ERR(va->fsgen)) {
1643 ret = PTR_ERR(va->fsgen);
1650 if (va->has_npl_clk)
1651 clk_disable_unprepare(va->npl);
1653 clk_disable_unprepare(va->mclk);
1655 clk_disable_unprepare(va->dcodec);
1657 clk_disable_unprepare(va->macro);
1659 lpass_macro_pds_exit(va->pds);
1666 struct va_macro *va = dev_get_drvdata(&pdev->dev);
1668 if (va->has_npl_clk)
1669 clk_disable_unprepare(va->npl);
1671 clk_disable_unprepare(va->mclk);
1672 clk_disable_unprepare(va->dcodec);
1673 clk_disable_unprepare(va->macro);
1675 lpass_macro_pds_exit(va->pds);
1680 struct va_macro *va = dev_get_drvdata(dev);
1682 regcache_cache_only(va->regmap, true);
1683 regcache_mark_dirty(va->regmap);
1685 if (va->has_npl_clk)
1686 clk_disable_unprepare(va->npl);
1688 clk_disable_unprepare(va->mclk);
1695 struct va_macro *va = dev_get_drvdata(dev);
1698 ret = clk_prepare_enable(va->mclk);
1700 dev_err(va->dev, "unable to prepare mclk\n");
1704 if (va->has_npl_clk) {
1705 ret = clk_prepare_enable(va->npl);
1707 clk_disable_unprepare(va->mclk);
1708 dev_err(va->dev, "unable to prepare npl\n");
1713 regcache_cache_only(va->regmap, false);
1714 regcache_sync(va->regmap);
1725 { .compatible = "qcom,sc7280-lpass-va-macro", .data = &sm8250_va_data },
1726 { .compatible = "qcom,sm8250-lpass-va-macro", .data = &sm8250_va_data },
1727 { .compatible = "qcom,sm8450-lpass-va-macro", .data = &sm8450_va_data },
1728 { .compatible = "qcom,sm8550-lpass-va-macro", .data = &sm8550_va_data },
1729 { .compatible = "qcom,sc8280xp-lpass-va-macro", .data = &sm8450_va_data },
1746 MODULE_DESCRIPTION("VA macro driver");