Lines Matching +full:tegra210 +full:- +full:dmic
1 // SPDX-License-Identifier: GPL-2.0-only
2 // SPDX-FileCopyrightText: Copyright (c) 2020-2024 NVIDIA CORPORATION & AFFILIATES.
5 // tegra210_dmic.c - Tegra210 DMIC driver
26 /* Below enables all filters - DCR, LP and SC */
45 struct tegra210_dmic *dmic = dev_get_drvdata(dev);
47 regcache_cache_only(dmic->regmap, true);
48 regcache_mark_dirty(dmic->regmap);
50 clk_disable_unprepare(dmic->clk_dmic);
57 struct tegra210_dmic *dmic = dev_get_drvdata(dev);
60 err = clk_prepare_enable(dmic->clk_dmic);
62 dev_err(dev, "failed to enable DMIC clock, err: %d\n", err);
66 regcache_cache_only(dmic->regmap, false);
67 regcache_sync(dmic->regmap);
76 struct tegra210_dmic *dmic = snd_soc_dai_get_drvdata(dai);
88 switch (dmic->ch_select) {
97 dev_err(dai->dev, "invalid DMIC client channels\n");
98 return -EINVAL;
104 * DMIC clock rate is a multiple of 'Over Sampling Ratio' and
107 clk_rate = (DMIC_OSR_FACTOR << dmic->osr_val) * srate;
109 err = clk_set_rate(dmic->clk_dmic, clk_rate);
111 dev_err(dai->dev, "can't set DMIC clock rate %u, err: %d\n",
116 regmap_update_bits(dmic->regmap,
124 (dmic->lrsel << LRSEL_POL_SHIFT) |
125 (dmic->osr_val << OSR_SHIFT) |
126 ((dmic->ch_select + 1) << CH_SEL_SHIFT));
132 if (dmic->boost_gain)
133 gain_q23 = div_u64(gain_q23 * dmic->boost_gain, 100);
135 regmap_write(dmic->regmap, TEGRA210_DMIC_LP_FILTER_GAIN,
147 dev_err(dai->dev, "unsupported format!\n");
148 return -EOPNOTSUPP;
152 cif_conf.mono_conv = dmic->mono_to_stereo;
153 cif_conf.stereo_conv = dmic->stereo_to_mono;
155 tegra_set_cif(dmic->regmap, TEGRA210_DMIC_TX_CIF_CTRL, &cif_conf);
164 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
166 ucontrol->value.integer.value[0] = dmic->boost_gain;
175 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
176 int value = ucontrol->value.integer.value[0];
178 if (value == dmic->boost_gain)
181 dmic->boost_gain = value;
190 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
192 ucontrol->value.enumerated.item[0] = dmic->ch_select;
201 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
202 unsigned int value = ucontrol->value.enumerated.item[0];
204 if (value == dmic->ch_select)
207 dmic->ch_select = value;
216 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
218 ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo;
227 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
228 unsigned int value = ucontrol->value.enumerated.item[0];
230 if (value == dmic->mono_to_stereo)
233 dmic->mono_to_stereo = value;
242 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
244 ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono;
253 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
254 unsigned int value = ucontrol->value.enumerated.item[0];
256 if (value == dmic->stereo_to_mono)
259 dmic->stereo_to_mono = value;
268 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
270 ucontrol->value.enumerated.item[0] = dmic->osr_val;
279 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
280 unsigned int value = ucontrol->value.enumerated.item[0];
282 if (value == dmic->osr_val)
285 dmic->osr_val = value;
294 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
296 ucontrol->value.enumerated.item[0] = dmic->lrsel;
305 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
306 unsigned int value = ucontrol->value.enumerated.item[0];
308 if (value == dmic->lrsel)
311 dmic->lrsel = value;
322 .name = "DMIC-CIF",
324 .stream_name = "CIF-Capture",
334 .name = "DMIC-DAP",
336 .stream_name = "DAP-Capture",
355 { "XBAR-RX", NULL, "XBAR-Capture" },
356 { "XBAR-Capture", NULL, "CIF-Capture" },
357 { "CIF-Capture", NULL, "TX" },
358 { "TX", NULL, "DAP-Capture" },
359 { "DAP-Capture", NULL, "MIC" },
491 struct device *dev = &pdev->dev;
492 struct tegra210_dmic *dmic;
496 dmic = devm_kzalloc(dev, sizeof(*dmic), GFP_KERNEL);
497 if (!dmic)
498 return -ENOMEM;
500 dmic->osr_val = DMIC_OSR_64;
501 dmic->ch_select = DMIC_CH_SELECT_STEREO;
502 dmic->lrsel = DMIC_LRSEL_LEFT;
503 dmic->boost_gain = 0;
504 dmic->stereo_to_mono = 0; /* "CH0" */
506 dev_set_drvdata(dev, dmic);
508 dmic->clk_dmic = devm_clk_get(dev, "dmic");
509 if (IS_ERR(dmic->clk_dmic)) {
510 dev_err(dev, "can't retrieve DMIC clock\n");
511 return PTR_ERR(dmic->clk_dmic);
518 dmic->regmap = devm_regmap_init_mmio(dev, regs,
520 if (IS_ERR(dmic->regmap)) {
522 return PTR_ERR(dmic->regmap);
525 regcache_cache_only(dmic->regmap, true);
531 dev_err(dev, "can't register DMIC component, err: %d\n", err);
542 pm_runtime_disable(&pdev->dev);
552 { .compatible = "nvidia,tegra210-dmic" },
559 .name = "tegra210-dmic",
569 MODULE_DESCRIPTION("Tegra210 ASoC DMIC driver");