2 * tegra210_dmic_alt.c - Tegra210 DMIC driver
4 * Copyright (c) 2014-2017 NVIDIA CORPORATION. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <linux/clk.h>
19 #include <linux/device.h>
21 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/pm_runtime.h>
25 #include <linux/regmap.h>
26 #include <linux/slab.h>
27 #include <soc/tegra/chip-id.h>
28 #include <sound/core.h>
29 #include <sound/pcm.h>
30 #include <sound/pcm_params.h>
31 #include <sound/soc.h>
32 #include <linux/of_device.h>
33 #include <linux/debugfs.h>
34 #include <linux/pinctrl/consumer.h>
35 #include <linux/pinctrl/pinconf-tegra.h>
37 #include "tegra210_xbar_alt.h"
38 #include "tegra210_dmic_alt.h"
39 #include "ahub_unit_fpga_clock.h"
41 #define DRV_NAME "tegra210-dmic"
43 static const struct reg_default tegra210_dmic_reg_defaults[] = {
44 { TEGRA210_DMIC_TX_INT_MASK, 0x00000001},
45 { TEGRA210_DMIC_TX_CIF_CTRL, 0x00007700},
46 { TEGRA210_DMIC_CG, 0x1},
47 { TEGRA210_DMIC_CTRL, 0x00000301},
48 { TEGRA210_DMIC_DCR_FILTER_GAIN, 0x00800000},
49 { TEGRA210_DMIC_DCR_BIQUAD_0_COEF_0, 0x00800000},
50 { TEGRA210_DMIC_DCR_BIQUAD_0_COEF_1, 0xff800000},
51 { TEGRA210_DMIC_DCR_BIQUAD_0_COEF_3, 0xff800347},
52 { TEGRA210_DMIC_DCR_BIQUAD_0_COEF_4, 0xffc0ff97},
53 { TEGRA210_DMIC_LP_FILTER_GAIN, 0x004c255a},
54 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_0, 0x00800000},
55 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_1, 0x00ffa74b},
56 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_2, 0x00800000},
57 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_3, 0x009e382a},
58 { TEGRA210_DMIC_LP_BIQUAD_0_COEF_4, 0x00380f38},
59 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_0, 0x00800000},
60 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_1, 0x00fe1178},
61 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_2, 0x00800000},
62 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_3, 0x00e05f02},
63 { TEGRA210_DMIC_LP_BIQUAD_1_COEF_4, 0x006fc80d},
64 { TEGRA210_DMIC_CORRECTION_FILTER_GAIN, 0x010628f6},
65 { TEGRA210_DMIC_CORRECTION_BIQUAD_0_COEF_0, 0x00800000},
66 { TEGRA210_DMIC_CORRECTION_BIQUAD_0_COEF_3, 0x0067ffff},
67 { TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_0, 0x00800000},
68 { TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_1, 0x0048f5c2},
69 { TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_3, 0x00562394},
70 { TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_4, 0x00169446},
73 static int tegra210_dmic_runtime_suspend(struct device *dev)
75 struct tegra210_dmic *dmic = dev_get_drvdata(dev);
78 regcache_cache_only(dmic->regmap, true);
79 regcache_mark_dirty(dmic->regmap);
81 if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) {
82 if (!IS_ERR(dmic->pin_idle_state) && dmic->is_pinctrl) {
83 ret = pinctrl_select_state(
84 dmic->pinctrl, dmic->pin_idle_state);
87 "setting dap pinctrl idle state failed\n");
90 clk_disable_unprepare(dmic->clk_dmic);
96 static int tegra210_dmic_runtime_resume(struct device *dev)
98 struct tegra210_dmic *dmic = dev_get_drvdata(dev);
101 if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) {
102 if (!IS_ERR(dmic->pin_active_state) && dmic->is_pinctrl) {
103 ret = pinctrl_select_state(dmic->pinctrl,
104 dmic->pin_active_state);
107 "setting dap pinctrl active state failed\n");
110 ret = clk_prepare_enable(dmic->clk_dmic);
112 dev_err(dev, "clk_enable failed: %d\n", ret);
117 regcache_cache_only(dmic->regmap, false);
119 if (!dmic->is_shutdown)
120 regcache_sync(dmic->regmap);
125 #ifdef CONFIG_PM_SLEEP
126 static int tegra210_dmic_suspend(struct device *dev)
128 if (pm_runtime_status_suspended(dev))
131 return tegra210_dmic_runtime_suspend(dev);
134 static int tegra210_dmic_resume(struct device *dev)
136 if (pm_runtime_status_suspended(dev))
139 return tegra210_dmic_runtime_resume(dev);
143 static int tegra210_dmic_set_dai_bclk_ratio(struct snd_soc_dai *dai,
149 static const int tegra210_dmic_fmt_values[] = {
151 TEGRA210_AUDIOCIF_BITS_16,
152 TEGRA210_AUDIOCIF_BITS_32,
155 static int tegra210_dmic_hw_params(struct snd_pcm_substream *substream,
156 struct snd_pcm_hw_params *params,
157 struct snd_soc_dai *dai)
159 struct device *dev = dai->dev;
160 struct tegra210_dmic *dmic = snd_soc_dai_get_drvdata(dai);
161 int channels, srate, dmic_clk, osr = TEGRA210_DMIC_OSR_64, ret;
162 struct tegra210_xbar_cif_conf cif_conf;
163 unsigned long long boost_gain;
166 memset(&cif_conf, 0, sizeof(struct tegra210_xbar_cif_conf));
168 srate = params_rate(params);
169 dmic_clk = (1 << (6+osr)) * srate;
171 if (dmic->ch_select == DMIC_CH_SELECT_NONE) {
173 channel_select = DMIC_CH_SELECT_STEREO;
176 channel_select = dmic->ch_select;
179 cif_conf.client_channels = channels;
180 cif_conf.audio_channels = channels;
182 /* For capture path, the mono input from client channel
183 * can be converted to stereo with cif controls.
185 if (dmic->tx_mono_to_stereo > 0) {
186 cif_conf.mono_conv = dmic->tx_mono_to_stereo - 1;
187 cif_conf.audio_channels = 2;
190 if ((tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) {
192 program_dmic_clk(dmic_clk);
194 ret = clk_set_rate(dmic->clk_dmic, dmic_clk);
196 dev_err(dev, "Can't set dmic clock rate: %d\n", ret);
201 regmap_update_bits(dmic->regmap,
203 TEGRA210_DMIC_CTRL_OSR_MASK,
204 osr << TEGRA210_DMIC_CTRL_OSR_SHIFT);
206 regmap_update_bits(dmic->regmap,
207 TEGRA210_DMIC_DBG_CTRL,
208 TEGRA210_DMIC_DBG_CTRL_SC_ENABLE,
209 TEGRA210_DMIC_DBG_CTRL_SC_ENABLE);
211 regmap_update_bits(dmic->regmap,
212 TEGRA210_DMIC_DBG_CTRL,
213 TEGRA210_DMIC_DBG_CTRL_DCR_ENABLE,
214 TEGRA210_DMIC_DBG_CTRL_DCR_ENABLE);
216 regmap_update_bits(dmic->regmap,
218 TEGRA210_DMIC_CTRL_CHANNEL_SELECT_MASK,
220 TEGRA210_DMIC_CTRL_CHANNEL_SELECT_SHIFT);
222 /* Configure LPF for passthrough and use */
223 /* its gain register for applying boost; */
224 /* Boost Gain control has 100x factor */
225 boost_gain = 0x00800000;
226 if (dmic->boost_gain > 0) {
227 boost_gain = ((boost_gain * dmic->boost_gain) / 100);
228 if (boost_gain > 0x7FFFFFFF) {
229 dev_warn(dev, "Boost Gain overflow\n");
230 boost_gain = 0x7FFFFFFF;
233 regmap_write(dmic->regmap,
234 TEGRA210_DMIC_LP_FILTER_GAIN,
235 (unsigned int)boost_gain);
237 regmap_update_bits(dmic->regmap,
238 TEGRA210_DMIC_DBG_CTRL,
239 TEGRA210_DMIC_DBG_CTRL_LP_ENABLE,
240 TEGRA210_DMIC_DBG_CTRL_LP_ENABLE);
242 /* Configure the two biquads for passthrough, */
243 /* i.e. b0=1, b1=0, b2=0, a1=0, a2=0 */
244 regmap_write(dmic->regmap,
245 TEGRA210_DMIC_LP_BIQUAD_0_COEF_0, 0x00800000);
246 regmap_write(dmic->regmap,
247 TEGRA210_DMIC_LP_BIQUAD_0_COEF_1, 0x00000000);
248 regmap_write(dmic->regmap,
249 TEGRA210_DMIC_LP_BIQUAD_0_COEF_2, 0x00000000);
250 regmap_write(dmic->regmap,
251 TEGRA210_DMIC_LP_BIQUAD_0_COEF_3, 0x00000000);
252 regmap_write(dmic->regmap,
253 TEGRA210_DMIC_LP_BIQUAD_0_COEF_4, 0x00000000);
254 regmap_write(dmic->regmap,
255 TEGRA210_DMIC_LP_BIQUAD_1_COEF_0, 0x00800000);
256 regmap_write(dmic->regmap,
257 TEGRA210_DMIC_LP_BIQUAD_1_COEF_1, 0x00000000);
258 regmap_write(dmic->regmap,
259 TEGRA210_DMIC_LP_BIQUAD_1_COEF_2, 0x00000000);
260 regmap_write(dmic->regmap,
261 TEGRA210_DMIC_LP_BIQUAD_1_COEF_3, 0x00000000);
262 regmap_write(dmic->regmap,
263 TEGRA210_DMIC_LP_BIQUAD_1_COEF_4, 0x00000000);
265 switch (params_format(params)) {
266 case SNDRV_PCM_FORMAT_S16_LE:
267 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_16;
269 case SNDRV_PCM_FORMAT_S32_LE:
270 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_32;
273 dev_err(dev, "Wrong format!\n");
277 if (dmic->format_out)
278 cif_conf.audio_bits = tegra210_dmic_fmt_values[dmic->format_out];
280 cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_24;
282 dmic->soc_data->set_audio_cif(dmic->regmap, TEGRA210_DMIC_TX_CIF_CTRL,
288 static int tegra210_dmic_get_control(struct snd_kcontrol *kcontrol,
289 struct snd_ctl_elem_value *ucontrol)
291 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
292 struct tegra210_dmic *dmic = snd_soc_codec_get_drvdata(codec);
294 if (strstr(kcontrol->id.name, "Boost"))
295 ucontrol->value.integer.value[0] = dmic->boost_gain;
296 else if (strstr(kcontrol->id.name, "Mono"))
297 ucontrol->value.integer.value[0] = dmic->ch_select;
298 else if (strstr(kcontrol->id.name, "TX mono to stereo"))
299 ucontrol->value.integer.value[0] =
300 dmic->tx_mono_to_stereo;
301 else if (strstr(kcontrol->id.name, "output bit format"))
302 ucontrol->value.integer.value[0] = dmic->format_out;
307 static int tegra210_dmic_put_control(struct snd_kcontrol *kcontrol,
308 struct snd_ctl_elem_value *ucontrol)
310 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
311 struct tegra210_dmic *dmic = snd_soc_codec_get_drvdata(codec);
312 int value = ucontrol->value.integer.value[0];
314 if (strstr(kcontrol->id.name, "Boost"))
315 dmic->boost_gain = value;
316 else if (strstr(kcontrol->id.name, "Mono"))
317 dmic->ch_select = ucontrol->value.integer.value[0];
318 else if (strstr(kcontrol->id.name, "TX mono to stereo"))
319 dmic->tx_mono_to_stereo = value;
320 else if (strstr(kcontrol->id.name, "output bit format"))
321 dmic->format_out = value;
326 static int tegra210_dmic_codec_probe(struct snd_soc_codec *codec)
328 struct tegra210_dmic *dmic = snd_soc_codec_get_drvdata(codec);
330 codec->control_data = dmic->regmap;
335 static struct snd_soc_dai_ops tegra210_dmic_dai_ops = {
336 .hw_params = tegra210_dmic_hw_params,
337 .set_bclk_ratio = tegra210_dmic_set_dai_bclk_ratio,
340 static struct snd_soc_dai_driver tegra210_dmic_dais[] = {
344 .stream_name = "DMIC Transmit",
347 .rates = SNDRV_PCM_RATE_8000_48000,
348 .formats = SNDRV_PCM_FMTBIT_S16_LE,
350 .ops = &tegra210_dmic_dai_ops,
351 .symmetric_rates = 1,
356 .stream_name = "DMIC Receive",
359 .rates = SNDRV_PCM_RATE_8000_48000,
360 .formats = SNDRV_PCM_FMTBIT_S16_LE,
362 .ops = &tegra210_dmic_dai_ops,
363 .symmetric_rates = 1,
367 static const struct snd_soc_dapm_widget tegra210_dmic_widgets[] = {
368 SND_SOC_DAPM_AIF_OUT("DMIC TX", NULL, 0, SND_SOC_NOPM,
370 SND_SOC_DAPM_AIF_IN("DMIC RX", NULL, 0, TEGRA210_DMIC_ENABLE,
371 TEGRA210_DMIC_ENABLE_EN_SHIFT, 0),
374 static const struct snd_soc_dapm_route tegra210_dmic_routes[] = {
375 { "DMIC RX", NULL, "DMIC Receive" },
376 { "DMIC TX", NULL, "DMIC RX" },
377 { "DMIC Transmit", NULL, "DMIC TX" },
380 static const char * const tegra210_dmic_ch_select[] = {
384 static const struct soc_enum tegra210_dmic_ch_enum =
385 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
386 ARRAY_SIZE(tegra210_dmic_ch_select),
387 tegra210_dmic_ch_select);
389 static const char * const tegra210_dmic_mono_conv_text[] = {
390 "None", "ZERO", "COPY",
393 static const struct soc_enum tegra210_dmic_mono_conv_enum =
394 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
395 ARRAY_SIZE(tegra210_dmic_mono_conv_text),
396 tegra210_dmic_mono_conv_text);
398 static const char * const tegra210_dmic_format_text[] = {
404 static const struct soc_enum tegra210_dmic_format_enum =
405 SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
406 ARRAY_SIZE(tegra210_dmic_format_text),
407 tegra210_dmic_format_text);
409 static const struct snd_kcontrol_new tegra210_dmic_controls[] = {
410 SOC_SINGLE_EXT("Boost Gain", 0, 0, 25600, 0,
411 tegra210_dmic_get_control, tegra210_dmic_put_control),
412 SOC_ENUM_EXT("Mono Channel Select", tegra210_dmic_ch_enum,
413 tegra210_dmic_get_control, tegra210_dmic_put_control),
414 SOC_ENUM_EXT("TX mono to stereo conv", tegra210_dmic_mono_conv_enum,
415 tegra210_dmic_get_control, tegra210_dmic_put_control),
416 SOC_ENUM_EXT("output bit format", tegra210_dmic_format_enum,
417 tegra210_dmic_get_control, tegra210_dmic_put_control),
420 static struct snd_soc_codec_driver tegra210_dmic_codec = {
421 .probe = tegra210_dmic_codec_probe,
422 .dapm_widgets = tegra210_dmic_widgets,
423 .num_dapm_widgets = ARRAY_SIZE(tegra210_dmic_widgets),
424 .dapm_routes = tegra210_dmic_routes,
425 .num_dapm_routes = ARRAY_SIZE(tegra210_dmic_routes),
426 .controls = tegra210_dmic_controls,
427 .num_controls = ARRAY_SIZE(tegra210_dmic_controls),
431 /* Regmap callback functions */
432 static bool tegra210_dmic_wr_reg(struct device *dev, unsigned int reg)
435 case TEGRA210_DMIC_TX_INT_MASK:
436 case TEGRA210_DMIC_TX_INT_SET:
437 case TEGRA210_DMIC_TX_INT_CLEAR:
438 case TEGRA210_DMIC_TX_CIF_CTRL:
440 case TEGRA210_DMIC_ENABLE:
441 case TEGRA210_DMIC_SOFT_RESET:
442 case TEGRA210_DMIC_CG:
443 case TEGRA210_DMIC_CTRL:
446 if (((reg % 4) == 0) && (reg >= TEGRA210_DMIC_DBG_CTRL) &&
447 (reg <= TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_4))
454 static bool tegra210_dmic_rd_reg(struct device *dev, unsigned int reg)
457 case TEGRA210_DMIC_TX_STATUS:
458 case TEGRA210_DMIC_TX_INT_STATUS:
459 case TEGRA210_DMIC_TX_INT_MASK:
460 case TEGRA210_DMIC_TX_INT_SET:
461 case TEGRA210_DMIC_TX_INT_CLEAR:
462 case TEGRA210_DMIC_TX_CIF_CTRL:
464 case TEGRA210_DMIC_ENABLE:
465 case TEGRA210_DMIC_SOFT_RESET:
466 case TEGRA210_DMIC_CG:
467 case TEGRA210_DMIC_STATUS:
468 case TEGRA210_DMIC_INT_STATUS:
469 case TEGRA210_DMIC_CTRL:
472 if (((reg % 4) == 0) && (reg >= TEGRA210_DMIC_DBG_CTRL) &&
473 (reg <= TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_4))
480 static bool tegra210_dmic_volatile_reg(struct device *dev, unsigned int reg)
483 case TEGRA210_DMIC_TX_STATUS:
484 case TEGRA210_DMIC_TX_INT_STATUS:
485 case TEGRA210_DMIC_TX_INT_SET:
487 case TEGRA210_DMIC_SOFT_RESET:
488 case TEGRA210_DMIC_STATUS:
489 case TEGRA210_DMIC_INT_STATUS:
496 static const struct regmap_config tegra210_dmic_regmap_config = {
500 .max_register = TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_4,
501 .writeable_reg = tegra210_dmic_wr_reg,
502 .readable_reg = tegra210_dmic_rd_reg,
503 .volatile_reg = tegra210_dmic_volatile_reg,
504 .precious_reg = NULL,
505 .reg_defaults = tegra210_dmic_reg_defaults,
506 .num_reg_defaults = ARRAY_SIZE(tegra210_dmic_reg_defaults),
507 .cache_type = REGCACHE_FLAT,
510 static const struct tegra210_dmic_soc_data soc_data_tegra210 = {
511 .set_audio_cif = tegra210_xbar_set_cif,
514 static const struct of_device_id tegra210_dmic_of_match[] = {
515 { .compatible = "nvidia,tegra210-dmic", .data = &soc_data_tegra210 },
519 static int tegra210_dmic_platform_probe(struct platform_device *pdev)
521 struct tegra210_dmic *dmic;
522 struct device_node *np = pdev->dev.of_node;
523 struct resource *mem, *memregion;
526 const struct of_device_id *match;
527 struct tegra210_dmic_soc_data *soc_data;
528 const char *prod_name;
530 match = of_match_device(tegra210_dmic_of_match, &pdev->dev);
532 dev_err(&pdev->dev, "Error: No device match found\n");
536 soc_data = (struct tegra210_dmic_soc_data *)match->data;
538 dmic = devm_kzalloc(&pdev->dev, sizeof(struct tegra210_dmic), GFP_KERNEL);
540 dev_err(&pdev->dev, "Can't allocate dmic\n");
545 dmic->soc_data = soc_data;
546 dmic->is_shutdown = false;
548 if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) {
549 dmic->clk_dmic = devm_clk_get(&pdev->dev, NULL);
550 if (IS_ERR(dmic->clk_dmic)) {
551 dev_err(&pdev->dev, "Can't retrieve dmic clock\n");
552 ret = PTR_ERR(dmic->clk_dmic);
555 #if defined(CONFIG_ARCH_TEGRA_210_SOC)
556 dmic->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
558 dmic->clk_pll_a_out0 = devm_clk_get(&pdev->dev, "pll_a_out0");
560 if (IS_ERR_OR_NULL(dmic->clk_pll_a_out0)) {
561 dev_err(&pdev->dev, "Can't retrieve pll_a_out0 clock\n");
566 ret = clk_set_parent(dmic->clk_dmic, dmic->clk_pll_a_out0);
568 dev_err(&pdev->dev, "Can't set parent of dmic clock\n");
569 goto err_plla_clk_put;
573 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
575 dev_err(&pdev->dev, "No memory resource\n");
577 goto err_plla_clk_put;
580 memregion = devm_request_mem_region(&pdev->dev, mem->start,
581 resource_size(mem), pdev->name);
583 dev_err(&pdev->dev, "Memory region already claimed\n");
585 goto err_plla_clk_put;
588 regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
590 dev_err(&pdev->dev, "ioremap failed\n");
592 goto err_plla_clk_put;
595 dmic->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
596 &tegra210_dmic_regmap_config);
597 if (IS_ERR(dmic->regmap)) {
598 dev_err(&pdev->dev, "regmap init failed\n");
599 ret = PTR_ERR(dmic->regmap);
600 goto err_plla_clk_put;
602 regcache_cache_only(dmic->regmap, true);
604 /* Below patch is as per latest POR value */
605 regmap_write(dmic->regmap,
606 TEGRA210_DMIC_DCR_BIQUAD_0_COEF_4, 0x00000000);
608 if (of_property_read_u32(np, "nvidia,ahub-dmic-id",
609 &pdev->dev.id) < 0) {
611 "Missing property nvidia,ahub-dmic-id\n");
613 goto err_plla_clk_put;
616 pm_runtime_enable(&pdev->dev);
617 if (!pm_runtime_enabled(&pdev->dev)) {
618 ret = tegra210_dmic_runtime_resume(&pdev->dev);
623 ret = snd_soc_register_codec(&pdev->dev, &tegra210_dmic_codec,
625 ARRAY_SIZE(tegra210_dmic_dais));
627 dev_err(&pdev->dev, "Could not register CODEC: %d\n", ret);
631 if (of_property_read_string(np, "prod-name", &prod_name) == 0) {
632 ret = tegra_pinctrl_config_prod(&pdev->dev, prod_name);
634 dev_warn(&pdev->dev, "Failed to set %s setting\n",
638 if (of_property_read_u32(np, "nvidia,is-pinctrl",
639 &dmic->is_pinctrl) < 0)
640 dmic->is_pinctrl = 0;
642 if (dmic->is_pinctrl) {
643 dmic->pinctrl = devm_pinctrl_get(&pdev->dev);
644 if (IS_ERR(dmic->pinctrl)) {
645 dev_warn(&pdev->dev, "Missing pinctrl device\n");
649 dmic->pin_active_state = pinctrl_lookup_state(dmic->pinctrl,
651 if (IS_ERR(dmic->pin_active_state)) {
652 dev_warn(&pdev->dev, "Missing dap-active state\n");
656 dmic->pin_idle_state = pinctrl_lookup_state(dmic->pinctrl,
658 if (IS_ERR(dmic->pin_idle_state)) {
659 dev_warn(&pdev->dev, "Missing dap-inactive state\n");
663 ret = pinctrl_select_state(dmic->pinctrl, dmic->pin_idle_state);
665 dev_err(&pdev->dev, "setting state failed\n");
671 dev_set_drvdata(&pdev->dev, dmic);
676 if (!pm_runtime_status_suspended(&pdev->dev))
677 tegra210_dmic_runtime_suspend(&pdev->dev);
679 pm_runtime_disable(&pdev->dev);
681 devm_clk_put(&pdev->dev, dmic->clk_pll_a_out0);
683 if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga()))
684 devm_clk_put(&pdev->dev, dmic->clk_dmic);
689 static void tegra210_dmic_platform_shutdown(struct platform_device *pdev)
691 struct tegra210_dmic *dmic = dev_get_drvdata(&pdev->dev);
693 dmic->is_shutdown = true;
696 static int tegra210_dmic_platform_remove(struct platform_device *pdev)
698 struct tegra210_dmic *dmic;
700 dmic = dev_get_drvdata(&pdev->dev);
701 snd_soc_unregister_codec(&pdev->dev);
703 pm_runtime_disable(&pdev->dev);
704 if (!pm_runtime_status_suspended(&pdev->dev))
705 tegra210_dmic_runtime_suspend(&pdev->dev);
707 devm_clk_put(&pdev->dev, dmic->clk_pll_a_out0);
708 devm_clk_put(&pdev->dev, dmic->clk_dmic);
712 static const struct dev_pm_ops tegra210_dmic_pm_ops = {
713 SET_RUNTIME_PM_OPS(tegra210_dmic_runtime_suspend,
714 tegra210_dmic_runtime_resume, NULL)
715 SET_LATE_SYSTEM_SLEEP_PM_OPS(tegra210_dmic_suspend,
716 tegra210_dmic_resume)
719 static struct platform_driver tegra210_dmic_driver = {
722 .owner = THIS_MODULE,
723 .of_match_table = tegra210_dmic_of_match,
724 .pm = &tegra210_dmic_pm_ops,
726 .probe = tegra210_dmic_platform_probe,
727 .remove = tegra210_dmic_platform_remove,
728 .shutdown = tegra210_dmic_platform_shutdown,
730 module_platform_driver(tegra210_dmic_driver)
732 MODULE_AUTHOR("Rahul Mittal <rmittal@nvidia.com>");
733 MODULE_DESCRIPTION("Tegra210 DMIC ASoC driver");
734 MODULE_LICENSE("GPL");
735 MODULE_ALIAS("platform:" DRV_NAME);
736 MODULE_DEVICE_TABLE(of, tegra210_dmic_of_match);