Lines Matching +full:dmic +full:- +full:init +full:- +full:delay +full:- +full:ms
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>
6 #include <linux/init.h>
16 #include <sound/soc-dapm.h>
19 #include "lpass-macro-common.h"
165 static const DECLARE_TLV_DB_SCALE(digital_gain, -8400, 100, -8400);
454 struct regmap *regmap = va->regmap; in va_clk_rsc_fs_gen_request()
487 struct regmap *regmap = va->regmap; in va_macro_mclk_enable()
503 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); in va_macro_mclk_event()
508 return clk_prepare_enable(va->fsgen); in va_macro_mclk_event()
510 clk_disable_unprepare(va->fsgen); in va_macro_mclk_event()
522 snd_soc_dapm_to_component(widget->dapm); in va_macro_put_dec_enum()
523 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in va_macro_put_dec_enum()
527 val = ucontrol->value.enumerated.item[0]; in va_macro_put_dec_enum()
529 switch (e->reg) { in va_macro_put_dec_enum()
543 dev_err(component->dev, "%s: e->reg: 0x%x not expected\n", in va_macro_put_dec_enum()
544 __func__, e->reg); in va_macro_put_dec_enum()
545 return -EINVAL; in va_macro_put_dec_enum()
562 snd_soc_dapm_to_component(widget->dapm); in va_macro_tx_mixer_get()
564 (struct soc_mixer_control *)kcontrol->private_value; in va_macro_tx_mixer_get()
565 u32 dai_id = widget->shift; in va_macro_tx_mixer_get()
566 u32 dec_id = mc->shift; in va_macro_tx_mixer_get()
569 if (test_bit(dec_id, &va->active_ch_mask[dai_id])) in va_macro_tx_mixer_get()
570 ucontrol->value.integer.value[0] = 1; in va_macro_tx_mixer_get()
572 ucontrol->value.integer.value[0] = 0; in va_macro_tx_mixer_get()
583 snd_soc_dapm_to_component(widget->dapm); in va_macro_tx_mixer_put()
586 (struct soc_mixer_control *)kcontrol->private_value; in va_macro_tx_mixer_put()
587 u32 dai_id = widget->shift; in va_macro_tx_mixer_put()
588 u32 dec_id = mc->shift; in va_macro_tx_mixer_put()
589 u32 enable = ucontrol->value.integer.value[0]; in va_macro_tx_mixer_put()
593 set_bit(dec_id, &va->active_ch_mask[dai_id]); in va_macro_tx_mixer_put()
594 va->active_ch_cnt[dai_id]++; in va_macro_tx_mixer_put()
596 clear_bit(dec_id, &va->active_ch_mask[dai_id]); in va_macro_tx_mixer_put()
597 va->active_ch_cnt[dai_id]--; in va_macro_tx_mixer_put()
600 snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update); in va_macro_tx_mixer_put()
606 u32 dmic, bool enable) in va_dmic_clk_enable() argument
615 switch (dmic) { in va_dmic_clk_enable()
618 dmic_clk_cnt = &(va->dmic_0_1_clk_cnt); in va_dmic_clk_enable()
619 dmic_clk_div = &(va->dmic_0_1_clk_div); in va_dmic_clk_enable()
625 dmic_clk_cnt = &(va->dmic_2_3_clk_cnt); in va_dmic_clk_enable()
626 dmic_clk_div = &(va->dmic_2_3_clk_div); in va_dmic_clk_enable()
632 dmic_clk_cnt = &(va->dmic_4_5_clk_cnt); in va_dmic_clk_enable()
633 dmic_clk_div = &(va->dmic_4_5_clk_div); in va_dmic_clk_enable()
639 dmic_clk_cnt = &(va->dmic_6_7_clk_cnt); in va_dmic_clk_enable()
640 dmic_clk_div = &(va->dmic_6_7_clk_div); in va_dmic_clk_enable()
645 dev_err(component->dev, "%s: Invalid DMIC Selection\n", in va_dmic_clk_enable()
647 return -EINVAL; in va_dmic_clk_enable()
651 clk_div = va->dmic_clk_div; in va_dmic_clk_enable()
683 (*dmic_clk_cnt)--; in va_dmic_clk_enable()
692 clk_div = va->dmic_clk_div; in va_dmic_clk_enable()
694 clk_div = va->dmic_clk_div; in va_dmic_clk_enable()
719 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); in va_macro_enable_dmic()
720 unsigned int dmic = w->shift; in va_macro_enable_dmic() local
724 va_dmic_clk_enable(comp, dmic, true); in va_macro_enable_dmic()
727 va_dmic_clk_enable(comp, dmic, false); in va_macro_enable_dmic()
737 struct snd_soc_component *comp = snd_soc_dapm_to_component(w->dapm); in va_macro_enable_dec()
745 decimator = w->shift; in va_macro_enable_dec()
760 va->dec_mode[decimator] << CDC_VA_ADC_MODE_SHIFT); in va_macro_enable_dec()
786 * Minimum 1 clk cycle delay is required as per HW spec in va_macro_enable_dec()
802 * 6ms delay is required as per HW spec in va_macro_enable_dec()
824 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in va_macro_dec_mode_get()
825 int path = e->shift_l; in va_macro_dec_mode_get()
827 ucontrol->value.enumerated.item[0] = va->dec_mode[path]; in va_macro_dec_mode_get()
836 int value = ucontrol->value.enumerated.item[0]; in va_macro_dec_mode_put()
837 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; in va_macro_dec_mode_put()
838 int path = e->shift_l; in va_macro_dec_mode_put()
841 va->dec_mode[path] = value; in va_macro_dec_mode_put()
851 struct snd_soc_component *component = dai->component; in va_macro_hw_params()
854 struct device *va_dev = component->dev; in va_macro_hw_params()
883 return -EINVAL; in va_macro_hw_params()
886 for_each_set_bit(decimator, &va->active_ch_mask[dai->id], in va_macro_hw_params()
900 struct snd_soc_component *component = dai->component; in va_macro_get_channel_map()
901 struct device *va_dev = component->dev; in va_macro_get_channel_map()
904 switch (dai->id) { in va_macro_get_channel_map()
908 *tx_slot = va->active_ch_mask[dai->id]; in va_macro_get_channel_map()
909 *tx_num = va->active_ch_cnt[dai->id]; in va_macro_get_channel_map()
920 struct snd_soc_component *component = dai->component; in va_macro_digital_mute()
924 for_each_set_bit(decimator, &va->active_ch_mask[dai->id], in va_macro_digital_mute()
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),
1206 SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
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"},
1302 -84, 40, digital_gain),
1304 -84, 40, digital_gain),
1306 -84, 40, digital_gain),
1308 -84, 40, digital_gain),
1324 snd_soc_component_init_regmap(component, va->regmap); in va_macro_component_probe()
1343 struct regmap *regmap = va->regmap; in fsgen_gate_enable()
1346 if (va->has_swr_master) { in fsgen_gate_enable()
1347 ret = clk_prepare_enable(va->mclk); in fsgen_gate_enable()
1353 if (va->has_swr_master) in fsgen_gate_enable()
1363 struct regmap *regmap = va->regmap; in fsgen_gate_disable()
1365 if (va->has_swr_master) in fsgen_gate_disable()
1370 if (va->has_swr_master) in fsgen_gate_disable()
1371 clk_disable_unprepare(va->mclk); in fsgen_gate_disable()
1379 regmap_read(va->regmap, CDC_VA_TOP_CSR_TOP_CFG0, &val); in fsgen_gate_is_enabled()
1392 struct clk *parent = va->mclk; in va_macro_register_fsgen_output()
1393 struct device *dev = va->dev; in va_macro_register_fsgen_output()
1394 struct device_node *np = dev->of_node; in va_macro_register_fsgen_output()
1397 struct clk_init_data init; in va_macro_register_fsgen_output() local
1400 if (va->has_npl_clk) in va_macro_register_fsgen_output()
1401 parent = va->npl; in va_macro_register_fsgen_output()
1405 of_property_read_string(np, "clock-output-names", &clk_name); in va_macro_register_fsgen_output()
1407 init.name = clk_name; in va_macro_register_fsgen_output()
1408 init.ops = &fsgen_gate_ops; in va_macro_register_fsgen_output()
1409 init.flags = 0; in va_macro_register_fsgen_output()
1410 init.parent_names = &parent_clk_name; in va_macro_register_fsgen_output()
1411 init.num_parents = 1; in va_macro_register_fsgen_output()
1412 va->hw.init = &init; in va_macro_register_fsgen_output()
1413 ret = devm_clk_hw_register(va->dev, &va->hw); in va_macro_register_fsgen_output()
1417 return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &va->hw); in va_macro_register_fsgen_output()
1433 va->dmic_clk_div = VA_MACRO_CLK_DIV_2; in va_macro_validate_dmic_sample_rate()
1436 va->dmic_clk_div = VA_MACRO_CLK_DIV_3; in va_macro_validate_dmic_sample_rate()
1439 va->dmic_clk_div = VA_MACRO_CLK_DIV_4; in va_macro_validate_dmic_sample_rate()
1442 va->dmic_clk_div = VA_MACRO_CLK_DIV_6; in va_macro_validate_dmic_sample_rate()
1445 va->dmic_clk_div = VA_MACRO_CLK_DIV_8; in va_macro_validate_dmic_sample_rate()
1448 va->dmic_clk_div = VA_MACRO_CLK_DIV_16; in va_macro_validate_dmic_sample_rate()
1458 dev_err(va->dev, "%s: Invalid rate %d, for mclk %d\n", in va_macro_validate_dmic_sample_rate()
1470 regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_0, &core_id_0); in va_macro_set_lpass_codec_version()
1471 regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_1, &core_id_1); in va_macro_set_lpass_codec_version()
1472 regmap_read(va->regmap, CDC_VA_TOP_CSR_CORE_ID_2, &core_id_2); in va_macro_set_lpass_codec_version()
1492 dev_warn(va->dev, "Unknown Codec version, ID: %02x / %02x / %02x\n", in va_macro_set_lpass_codec_version()
1497 dev_dbg(va->dev, "LPASS Codec Version %s\n", lpass_macro_get_codec_version_string(version)); in va_macro_set_lpass_codec_version()
1502 struct device *dev = &pdev->dev; in va_macro_probe()
1511 return -ENOMEM; in va_macro_probe()
1513 va->dev = dev; in va_macro_probe()
1515 va->macro = devm_clk_get_optional(dev, "macro"); in va_macro_probe()
1516 if (IS_ERR(va->macro)) in va_macro_probe()
1517 return dev_err_probe(dev, PTR_ERR(va->macro), "unable to get macro clock\n"); in va_macro_probe()
1519 va->dcodec = devm_clk_get_optional(dev, "dcodec"); in va_macro_probe()
1520 if (IS_ERR(va->dcodec)) in va_macro_probe()
1521 return dev_err_probe(dev, PTR_ERR(va->dcodec), "unable to get dcodec clock\n"); in va_macro_probe()
1523 va->mclk = devm_clk_get(dev, "mclk"); in va_macro_probe()
1524 if (IS_ERR(va->mclk)) in va_macro_probe()
1525 return dev_err_probe(dev, PTR_ERR(va->mclk), "unable to get mclk clock\n"); in va_macro_probe()
1527 va->pds = lpass_macro_pds_init(dev); in va_macro_probe()
1528 if (IS_ERR(va->pds)) in va_macro_probe()
1529 return PTR_ERR(va->pds); in va_macro_probe()
1531 ret = of_property_read_u32(dev->of_node, "qcom,dmic-sample-rate", in va_macro_probe()
1534 dev_err(dev, "qcom,dmic-sample-rate dt entry missing\n"); in va_macro_probe()
1535 va->dmic_clk_div = VA_MACRO_CLK_DIV_2; in va_macro_probe()
1539 ret = -EINVAL; in va_macro_probe()
1550 va->regmap = devm_regmap_init_mmio(dev, base, &va_regmap_config); in va_macro_probe()
1551 if (IS_ERR(va->regmap)) { in va_macro_probe()
1552 ret = -EINVAL; in va_macro_probe()
1559 va->has_swr_master = data->has_swr_master; in va_macro_probe()
1560 va->has_npl_clk = data->has_npl_clk; in va_macro_probe()
1563 clk_set_rate(va->mclk, 2 * VA_MACRO_MCLK_FREQ); in va_macro_probe()
1565 if (va->has_npl_clk) { in va_macro_probe()
1566 va->npl = devm_clk_get(dev, "npl"); in va_macro_probe()
1567 if (IS_ERR(va->npl)) { in va_macro_probe()
1568 ret = PTR_ERR(va->npl); in va_macro_probe()
1572 clk_set_rate(va->npl, 2 * VA_MACRO_MCLK_FREQ); in va_macro_probe()
1575 ret = clk_prepare_enable(va->macro); in va_macro_probe()
1579 ret = clk_prepare_enable(va->dcodec); in va_macro_probe()
1583 ret = clk_prepare_enable(va->mclk); in va_macro_probe()
1587 if (va->has_npl_clk) { in va_macro_probe()
1588 ret = clk_prepare_enable(va->npl); in va_macro_probe()
1597 if (data->version) in va_macro_probe()
1598 lpass_macro_set_codec_version(data->version); in va_macro_probe()
1602 if (va->has_swr_master) { in va_macro_probe()
1604 regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL0, in va_macro_probe()
1607 regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL1, in va_macro_probe()
1610 regmap_update_bits(va->regmap, CDC_VA_TOP_CSR_SWR_MIC_CTL2, in va_macro_probe()
1616 if (va->has_swr_master) { in va_macro_probe()
1617 regmap_update_bits(va->regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL, in va_macro_probe()
1619 regmap_update_bits(va->regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL, in va_macro_probe()
1621 regmap_update_bits(va->regmap, CDC_VA_CLK_RST_CTRL_SWR_CONTROL, in va_macro_probe()
1641 va->fsgen = devm_clk_hw_get_clk(dev, &va->hw, "fsgen"); in va_macro_probe()
1642 if (IS_ERR(va->fsgen)) { in va_macro_probe()
1643 ret = PTR_ERR(va->fsgen); in va_macro_probe()
1650 if (va->has_npl_clk) in va_macro_probe()
1651 clk_disable_unprepare(va->npl); in va_macro_probe()
1653 clk_disable_unprepare(va->mclk); in va_macro_probe()
1655 clk_disable_unprepare(va->dcodec); in va_macro_probe()
1657 clk_disable_unprepare(va->macro); in va_macro_probe()
1659 lpass_macro_pds_exit(va->pds); in va_macro_probe()
1666 struct va_macro *va = dev_get_drvdata(&pdev->dev); in va_macro_remove()
1668 if (va->has_npl_clk) in va_macro_remove()
1669 clk_disable_unprepare(va->npl); in va_macro_remove()
1671 clk_disable_unprepare(va->mclk); in va_macro_remove()
1672 clk_disable_unprepare(va->dcodec); in va_macro_remove()
1673 clk_disable_unprepare(va->macro); in va_macro_remove()
1675 lpass_macro_pds_exit(va->pds); in va_macro_remove()
1682 regcache_cache_only(va->regmap, true); in va_macro_runtime_suspend()
1683 regcache_mark_dirty(va->regmap); in va_macro_runtime_suspend()
1685 if (va->has_npl_clk) in va_macro_runtime_suspend()
1686 clk_disable_unprepare(va->npl); in va_macro_runtime_suspend()
1688 clk_disable_unprepare(va->mclk); in va_macro_runtime_suspend()
1698 ret = clk_prepare_enable(va->mclk); in va_macro_runtime_resume()
1700 dev_err(va->dev, "unable to prepare mclk\n"); in va_macro_runtime_resume()
1704 if (va->has_npl_clk) { in va_macro_runtime_resume()
1705 ret = clk_prepare_enable(va->npl); in va_macro_runtime_resume()
1707 clk_disable_unprepare(va->mclk); in va_macro_runtime_resume()
1708 dev_err(va->dev, "unable to prepare npl\n"); in va_macro_runtime_resume()
1713 regcache_cache_only(va->regmap, false); in va_macro_runtime_resume()
1714 regcache_sync(va->regmap); in va_macro_runtime_resume()
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 },