]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - sound/soc/tegra-alt/tegra210_dmic_alt.c
393f86d8b7a757047052db14c9c8bc73086dd3eb
[hercules2020/nv-tegra/linux-4.4.git] / sound / soc / tegra-alt / tegra210_dmic_alt.c
1 /*
2  * tegra210_dmic_alt.c - Tegra210 DMIC driver
3  *
4  * Copyright (c) 2014-2017 NVIDIA CORPORATION.  All rights reserved.
5  *
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.
9  *
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
13  * more details.
14  *
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/>.
17  */
18 #include <linux/clk.h>
19 #include <linux/device.h>
20 #include <linux/io.h>
21 #include <linux/module.h>
22 #include <linux/of.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>
36
37 #include "tegra210_xbar_alt.h"
38 #include "tegra210_dmic_alt.h"
39 #include "ahub_unit_fpga_clock.h"
40
41 #define DRV_NAME "tegra210-dmic"
42
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},
71 };
72
73 static int tegra210_dmic_runtime_suspend(struct device *dev)
74 {
75         struct tegra210_dmic *dmic = dev_get_drvdata(dev);
76         int ret;
77
78         regcache_cache_only(dmic->regmap, true);
79         regcache_mark_dirty(dmic->regmap);
80
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);
85                         if (ret < 0)
86                                 dev_err(dev,
87                                 "setting dap pinctrl idle state failed\n");
88                 }
89
90                 clk_disable_unprepare(dmic->clk_dmic);
91         }
92
93         return 0;
94 }
95
96 static int tegra210_dmic_runtime_resume(struct device *dev)
97 {
98         struct tegra210_dmic *dmic = dev_get_drvdata(dev);
99         int ret;
100
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);
105                         if (ret < 0)
106                                 dev_err(dev,
107                                 "setting dap pinctrl active state failed\n");
108                 }
109
110                 ret = clk_prepare_enable(dmic->clk_dmic);
111                 if (ret) {
112                         dev_err(dev, "clk_enable failed: %d\n", ret);
113                         return ret;
114                 }
115         }
116
117         regcache_cache_only(dmic->regmap, false);
118
119         if (!dmic->is_shutdown)
120                 regcache_sync(dmic->regmap);
121
122         return 0;
123 }
124
125 #ifdef CONFIG_PM_SLEEP
126 static int tegra210_dmic_suspend(struct device *dev)
127 {
128         if (pm_runtime_status_suspended(dev))
129                 return 0;
130
131         return tegra210_dmic_runtime_suspend(dev);
132 }
133
134 static int tegra210_dmic_resume(struct device *dev)
135 {
136         if (pm_runtime_status_suspended(dev))
137                 return 0;
138
139         return tegra210_dmic_runtime_resume(dev);
140 }
141 #endif
142
143 static int tegra210_dmic_set_dai_bclk_ratio(struct snd_soc_dai *dai,
144                 unsigned int ratio)
145 {
146         return 0;
147 }
148
149 static int tegra210_dmic_hw_params(struct snd_pcm_substream *substream,
150                                  struct snd_pcm_hw_params *params,
151                                  struct snd_soc_dai *dai)
152 {
153         struct device *dev = dai->dev;
154         struct tegra210_dmic *dmic = snd_soc_dai_get_drvdata(dai);
155         int channels, srate, dmic_clk, osr = TEGRA210_DMIC_OSR_64, ret;
156         struct tegra210_xbar_cif_conf cif_conf;
157         unsigned long long boost_gain;
158         int channel_select;
159
160         memset(&cif_conf, 0, sizeof(struct tegra210_xbar_cif_conf));
161
162         srate = params_rate(params);
163         dmic_clk = (1 << (6+osr)) * srate;
164
165         if (dmic->ch_select == DMIC_CH_SELECT_NONE) {
166                 channels = 2;
167                 channel_select = DMIC_CH_SELECT_STEREO;
168         } else {
169                 channels = 1;
170                 channel_select = dmic->ch_select;
171         }
172
173         cif_conf.client_channels = channels;
174         cif_conf.audio_channels = channels;
175
176         /* For capture path, the mono input from client channel
177          * can be converted to stereo with cif controls.
178         */
179         if (dmic->tx_mono_to_stereo > 0) {
180                 cif_conf.mono_conv = dmic->tx_mono_to_stereo - 1;
181                 cif_conf.audio_channels = 2;
182         }
183
184         if ((tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) {
185                 program_dmic_gpio();
186                 program_dmic_clk(dmic_clk);
187         } else {
188                 ret = clk_set_rate(dmic->clk_dmic, dmic_clk);
189                 if (ret) {
190                         dev_err(dev, "Can't set dmic clock rate: %d\n", ret);
191                         return ret;
192                 }
193         }
194
195         regmap_update_bits(dmic->regmap,
196                                 TEGRA210_DMIC_CTRL,
197                                 TEGRA210_DMIC_CTRL_OSR_MASK,
198                                 osr << TEGRA210_DMIC_CTRL_OSR_SHIFT);
199
200         regmap_update_bits(dmic->regmap,
201                                 TEGRA210_DMIC_DBG_CTRL,
202                                 TEGRA210_DMIC_DBG_CTRL_SC_ENABLE,
203                                 TEGRA210_DMIC_DBG_CTRL_SC_ENABLE);
204
205         regmap_update_bits(dmic->regmap,
206                                 TEGRA210_DMIC_DBG_CTRL,
207                                 TEGRA210_DMIC_DBG_CTRL_DCR_ENABLE,
208                                 TEGRA210_DMIC_DBG_CTRL_DCR_ENABLE);
209
210         regmap_update_bits(dmic->regmap,
211                                 TEGRA210_DMIC_CTRL,
212                                 TEGRA210_DMIC_CTRL_CHANNEL_SELECT_MASK,
213                                 channel_select <<
214                                    TEGRA210_DMIC_CTRL_CHANNEL_SELECT_SHIFT);
215
216         /* Configure LPF for passthrough and use */
217         /* its gain register for applying boost; */
218         /* Boost Gain control has 100x factor    */
219         boost_gain = 0x00800000;
220         if (dmic->boost_gain > 0) {
221                 boost_gain = ((boost_gain * dmic->boost_gain) / 100);
222                 if (boost_gain > 0x7FFFFFFF) {
223                         dev_warn(dev, "Boost Gain overflow\n");
224                         boost_gain = 0x7FFFFFFF;
225                 }
226         }
227         regmap_write(dmic->regmap,
228                                 TEGRA210_DMIC_LP_FILTER_GAIN,
229                                 (unsigned int)boost_gain);
230
231         regmap_update_bits(dmic->regmap,
232                                 TEGRA210_DMIC_DBG_CTRL,
233                                 TEGRA210_DMIC_DBG_CTRL_LP_ENABLE,
234                                 TEGRA210_DMIC_DBG_CTRL_LP_ENABLE);
235
236         /* Configure the two biquads for passthrough, */
237         /* i.e. b0=1, b1=0, b2=0, a1=0, a2=0          */
238         regmap_write(dmic->regmap,
239                                 TEGRA210_DMIC_LP_BIQUAD_0_COEF_0, 0x00800000);
240         regmap_write(dmic->regmap,
241                                 TEGRA210_DMIC_LP_BIQUAD_0_COEF_1, 0x00000000);
242         regmap_write(dmic->regmap,
243                                 TEGRA210_DMIC_LP_BIQUAD_0_COEF_2, 0x00000000);
244         regmap_write(dmic->regmap,
245                                 TEGRA210_DMIC_LP_BIQUAD_0_COEF_3, 0x00000000);
246         regmap_write(dmic->regmap,
247                                 TEGRA210_DMIC_LP_BIQUAD_0_COEF_4, 0x00000000);
248         regmap_write(dmic->regmap,
249                                 TEGRA210_DMIC_LP_BIQUAD_1_COEF_0, 0x00800000);
250         regmap_write(dmic->regmap,
251                                 TEGRA210_DMIC_LP_BIQUAD_1_COEF_1, 0x00000000);
252         regmap_write(dmic->regmap,
253                                 TEGRA210_DMIC_LP_BIQUAD_1_COEF_2, 0x00000000);
254         regmap_write(dmic->regmap,
255                                 TEGRA210_DMIC_LP_BIQUAD_1_COEF_3, 0x00000000);
256         regmap_write(dmic->regmap,
257                                 TEGRA210_DMIC_LP_BIQUAD_1_COEF_4, 0x00000000);
258
259         switch (params_format(params)) {
260         case SNDRV_PCM_FORMAT_S16_LE:
261                 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_16;
262                 break;
263         case SNDRV_PCM_FORMAT_S32_LE:
264                 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_32;
265                 break;
266         default:
267                 dev_err(dev, "Wrong format!\n");
268                 return -EINVAL;
269         }
270
271         cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_24;
272
273         dmic->soc_data->set_audio_cif(dmic->regmap, TEGRA210_DMIC_TX_CIF_CTRL,
274                 &cif_conf);
275
276         return 0;
277 }
278
279 static int tegra210_dmic_get_control(struct snd_kcontrol *kcontrol,
280         struct snd_ctl_elem_value *ucontrol)
281 {
282         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
283         struct tegra210_dmic *dmic = snd_soc_codec_get_drvdata(codec);
284
285         if (strstr(kcontrol->id.name, "Boost"))
286                 ucontrol->value.integer.value[0] = dmic->boost_gain;
287         else if (strstr(kcontrol->id.name, "Mono"))
288                 ucontrol->value.integer.value[0] = dmic->ch_select;
289         else if (strstr(kcontrol->id.name, "TX mono to stereo"))
290                 ucontrol->value.integer.value[0] =
291                                         dmic->tx_mono_to_stereo;
292
293         return 0;
294 }
295
296 static int tegra210_dmic_put_control(struct snd_kcontrol *kcontrol,
297         struct snd_ctl_elem_value *ucontrol)
298 {
299         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
300         struct tegra210_dmic *dmic = snd_soc_codec_get_drvdata(codec);
301         int value = ucontrol->value.integer.value[0];
302
303         if (strstr(kcontrol->id.name, "Boost"))
304                 dmic->boost_gain = value;
305         else if (strstr(kcontrol->id.name, "Mono"))
306                 dmic->ch_select = ucontrol->value.integer.value[0];
307         else if (strstr(kcontrol->id.name, "TX mono to stereo"))
308                 dmic->tx_mono_to_stereo = value;
309
310         return 0;
311 }
312
313 static int tegra210_dmic_codec_probe(struct snd_soc_codec *codec)
314 {
315         struct tegra210_dmic *dmic = snd_soc_codec_get_drvdata(codec);
316
317         codec->control_data = dmic->regmap;
318
319         return 0;
320 }
321
322 static struct snd_soc_dai_ops tegra210_dmic_dai_ops = {
323         .hw_params      = tegra210_dmic_hw_params,
324         .set_bclk_ratio = tegra210_dmic_set_dai_bclk_ratio,
325 };
326
327 static struct snd_soc_dai_driver tegra210_dmic_dais[] = {
328         {
329                 .name = "CIF",
330                 .capture = {
331                         .stream_name = "DMIC Transmit",
332                         .channels_min = 1,
333                         .channels_max = 2,
334                         .rates = SNDRV_PCM_RATE_8000_48000,
335                         .formats = SNDRV_PCM_FMTBIT_S16_LE,
336                 },
337                 .ops = &tegra210_dmic_dai_ops,
338                 .symmetric_rates = 1,
339         },
340         {
341                 .name = "DAP",
342                 .playback = {
343                         .stream_name = "DMIC Receive",
344                         .channels_min = 1,
345                         .channels_max = 2,
346                         .rates = SNDRV_PCM_RATE_8000_48000,
347                         .formats = SNDRV_PCM_FMTBIT_S16_LE,
348                 },
349                 .ops = &tegra210_dmic_dai_ops,
350                 .symmetric_rates = 1,
351         }
352 };
353
354 static const struct snd_soc_dapm_widget tegra210_dmic_widgets[] = {
355         SND_SOC_DAPM_AIF_OUT("DMIC TX", NULL, 0, SND_SOC_NOPM,
356                                 0, 0),
357         SND_SOC_DAPM_AIF_IN("DMIC RX", NULL, 0, TEGRA210_DMIC_ENABLE,
358                                 TEGRA210_DMIC_ENABLE_EN_SHIFT, 0),
359 };
360
361 static const struct snd_soc_dapm_route tegra210_dmic_routes[] = {
362         { "DMIC RX",       NULL, "DMIC Receive" },
363         { "DMIC TX",       NULL, "DMIC RX" },
364         { "DMIC Transmit", NULL, "DMIC TX" },
365 };
366
367 static const char * const tegra210_dmic_ch_select[] = {
368         "None", "L", "R",
369 };
370
371 static const struct soc_enum tegra210_dmic_ch_enum =
372         SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
373                 ARRAY_SIZE(tegra210_dmic_ch_select),
374                 tegra210_dmic_ch_select);
375
376 static const char * const tegra210_dmic_mono_conv_text[] = {
377         "None", "ZERO", "COPY",
378 };
379
380 static const struct soc_enum tegra210_dmic_mono_conv_enum =
381         SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
382                 ARRAY_SIZE(tegra210_dmic_mono_conv_text),
383                 tegra210_dmic_mono_conv_text);
384
385 static const struct snd_kcontrol_new tegra210_dmic_controls[] = {
386         SOC_SINGLE_EXT("Boost Gain", 0, 0, 25600, 0,
387                 tegra210_dmic_get_control, tegra210_dmic_put_control),
388         SOC_ENUM_EXT("Mono Channel Select", tegra210_dmic_ch_enum,
389                 tegra210_dmic_get_control, tegra210_dmic_put_control),
390         SOC_ENUM_EXT("TX mono to stereo conv", tegra210_dmic_mono_conv_enum,
391                 tegra210_dmic_get_control, tegra210_dmic_put_control),
392         };
393
394 static struct snd_soc_codec_driver tegra210_dmic_codec = {
395         .probe = tegra210_dmic_codec_probe,
396         .dapm_widgets = tegra210_dmic_widgets,
397         .num_dapm_widgets = ARRAY_SIZE(tegra210_dmic_widgets),
398         .dapm_routes = tegra210_dmic_routes,
399         .num_dapm_routes = ARRAY_SIZE(tegra210_dmic_routes),
400         .controls = tegra210_dmic_controls,
401         .num_controls = ARRAY_SIZE(tegra210_dmic_controls),
402         .idle_bias_off = 1,
403 };
404
405 /* Regmap callback functions */
406 static bool tegra210_dmic_wr_reg(struct device *dev, unsigned int reg)
407 {
408         switch (reg) {
409         case TEGRA210_DMIC_TX_INT_MASK:
410         case TEGRA210_DMIC_TX_INT_SET:
411         case TEGRA210_DMIC_TX_INT_CLEAR:
412         case TEGRA210_DMIC_TX_CIF_CTRL:
413
414         case TEGRA210_DMIC_ENABLE:
415         case TEGRA210_DMIC_SOFT_RESET:
416         case TEGRA210_DMIC_CG:
417         case TEGRA210_DMIC_CTRL:
418                 return true;
419         default:
420                 if (((reg % 4) == 0) && (reg >= TEGRA210_DMIC_DBG_CTRL) &&
421                     (reg <= TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_4))
422                         return true;
423                 else
424                         return false;
425         };
426 }
427
428 static bool tegra210_dmic_rd_reg(struct device *dev, unsigned int reg)
429 {
430         switch (reg) {
431         case TEGRA210_DMIC_TX_STATUS:
432         case TEGRA210_DMIC_TX_INT_STATUS:
433         case TEGRA210_DMIC_TX_INT_MASK:
434         case TEGRA210_DMIC_TX_INT_SET:
435         case TEGRA210_DMIC_TX_INT_CLEAR:
436         case TEGRA210_DMIC_TX_CIF_CTRL:
437
438         case TEGRA210_DMIC_ENABLE:
439         case TEGRA210_DMIC_SOFT_RESET:
440         case TEGRA210_DMIC_CG:
441         case TEGRA210_DMIC_STATUS:
442         case TEGRA210_DMIC_INT_STATUS:
443         case TEGRA210_DMIC_CTRL:
444                 return true;
445         default:
446                 if (((reg % 4) == 0) && (reg >= TEGRA210_DMIC_DBG_CTRL) &&
447                     (reg <= TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_4))
448                         return true;
449                 else
450                         return false;
451         };
452 }
453
454 static bool tegra210_dmic_volatile_reg(struct device *dev, unsigned int reg)
455 {
456         switch (reg) {
457         case TEGRA210_DMIC_TX_STATUS:
458         case TEGRA210_DMIC_TX_INT_STATUS:
459         case TEGRA210_DMIC_TX_INT_SET:
460
461         case TEGRA210_DMIC_SOFT_RESET:
462         case TEGRA210_DMIC_STATUS:
463         case TEGRA210_DMIC_INT_STATUS:
464                 return true;
465         default:
466                 return false;
467         };
468 }
469
470 static const struct regmap_config tegra210_dmic_regmap_config = {
471         .reg_bits = 32,
472         .reg_stride = 4,
473         .val_bits = 32,
474         .max_register = TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_4,
475         .writeable_reg = tegra210_dmic_wr_reg,
476         .readable_reg = tegra210_dmic_rd_reg,
477         .volatile_reg = tegra210_dmic_volatile_reg,
478         .precious_reg = NULL,
479         .reg_defaults = tegra210_dmic_reg_defaults,
480         .num_reg_defaults = ARRAY_SIZE(tegra210_dmic_reg_defaults),
481         .cache_type = REGCACHE_FLAT,
482 };
483
484 static const struct tegra210_dmic_soc_data soc_data_tegra210 = {
485         .set_audio_cif = tegra210_xbar_set_cif,
486 };
487
488 static const struct of_device_id tegra210_dmic_of_match[] = {
489         { .compatible = "nvidia,tegra210-dmic", .data = &soc_data_tegra210 },
490         {},
491 };
492
493 static int tegra210_dmic_platform_probe(struct platform_device *pdev)
494 {
495         struct tegra210_dmic *dmic;
496         struct device_node *np = pdev->dev.of_node;
497         struct resource *mem, *memregion;
498         void __iomem *regs;
499         int ret = 0;
500         const struct of_device_id *match;
501         struct tegra210_dmic_soc_data *soc_data;
502         const char *prod_name;
503
504         match = of_match_device(tegra210_dmic_of_match, &pdev->dev);
505         if (!match) {
506                 dev_err(&pdev->dev, "Error: No device match found\n");
507                 ret = -ENODEV;
508                 goto err;
509         }
510         soc_data = (struct tegra210_dmic_soc_data *)match->data;
511
512         dmic = devm_kzalloc(&pdev->dev, sizeof(struct tegra210_dmic), GFP_KERNEL);
513         if (!dmic) {
514                 dev_err(&pdev->dev, "Can't allocate dmic\n");
515                 ret = -ENOMEM;
516                 goto err;
517         }
518
519         dmic->soc_data = soc_data;
520         dmic->is_shutdown = false;
521
522         if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) {
523                 dmic->clk_dmic = devm_clk_get(&pdev->dev, NULL);
524                 if (IS_ERR(dmic->clk_dmic)) {
525                         dev_err(&pdev->dev, "Can't retrieve dmic clock\n");
526                         ret = PTR_ERR(dmic->clk_dmic);
527                         goto err;
528                 }
529 #if defined(CONFIG_ARCH_TEGRA_210_SOC)
530                 dmic->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
531 #else
532                 dmic->clk_pll_a_out0 = devm_clk_get(&pdev->dev, "pll_a_out0");
533 #endif
534                 if (IS_ERR_OR_NULL(dmic->clk_pll_a_out0)) {
535                         dev_err(&pdev->dev, "Can't retrieve pll_a_out0 clock\n");
536                         ret = -ENOENT;
537                         goto err_clk_put;
538                 }
539
540                 ret = clk_set_parent(dmic->clk_dmic, dmic->clk_pll_a_out0);
541                 if (ret) {
542                         dev_err(&pdev->dev, "Can't set parent of dmic clock\n");
543                         goto err_plla_clk_put;
544                 }
545         }
546
547         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
548         if (!mem) {
549                 dev_err(&pdev->dev, "No memory resource\n");
550                 ret = -ENODEV;
551                 goto err_plla_clk_put;
552         }
553
554         memregion = devm_request_mem_region(&pdev->dev, mem->start,
555                                             resource_size(mem), pdev->name);
556         if (!memregion) {
557                 dev_err(&pdev->dev, "Memory region already claimed\n");
558                 ret = -EBUSY;
559                 goto err_plla_clk_put;
560         }
561
562         regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
563         if (!regs) {
564                 dev_err(&pdev->dev, "ioremap failed\n");
565                 ret = -ENOMEM;
566                 goto err_plla_clk_put;
567         }
568
569         dmic->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
570                                             &tegra210_dmic_regmap_config);
571         if (IS_ERR(dmic->regmap)) {
572                 dev_err(&pdev->dev, "regmap init failed\n");
573                 ret = PTR_ERR(dmic->regmap);
574                 goto err_plla_clk_put;
575         }
576         regcache_cache_only(dmic->regmap, true);
577
578         /* Below patch is as per latest POR value */
579         regmap_write(dmic->regmap,
580                         TEGRA210_DMIC_DCR_BIQUAD_0_COEF_4, 0x00000000);
581
582         if (of_property_read_u32(np, "nvidia,ahub-dmic-id",
583                                 &pdev->dev.id) < 0) {
584                 dev_err(&pdev->dev,
585                         "Missing property nvidia,ahub-dmic-id\n");
586                 ret = -ENODEV;
587                 goto err_plla_clk_put;
588         }
589
590         pm_runtime_enable(&pdev->dev);
591         if (!pm_runtime_enabled(&pdev->dev)) {
592                 ret = tegra210_dmic_runtime_resume(&pdev->dev);
593                 if (ret)
594                         goto err_pm_disable;
595         }
596
597         ret = snd_soc_register_codec(&pdev->dev, &tegra210_dmic_codec,
598                                      tegra210_dmic_dais,
599                                      ARRAY_SIZE(tegra210_dmic_dais));
600         if (ret != 0) {
601                 dev_err(&pdev->dev, "Could not register CODEC: %d\n", ret);
602                 goto err_suspend;
603         }
604
605         if (of_property_read_string(np, "prod-name", &prod_name) == 0) {
606                 ret = tegra_pinctrl_config_prod(&pdev->dev, prod_name);
607                 if (ret < 0)
608                         dev_warn(&pdev->dev, "Failed to set %s setting\n",
609                                         prod_name);
610         }
611
612         if (of_property_read_u32(np, "nvidia,is-pinctrl",
613                                 &dmic->is_pinctrl) < 0)
614                 dmic->is_pinctrl = 0;
615
616         if (dmic->is_pinctrl) {
617                 dmic->pinctrl = devm_pinctrl_get(&pdev->dev);
618                 if (IS_ERR(dmic->pinctrl)) {
619                         dev_warn(&pdev->dev, "Missing pinctrl device\n");
620                         goto err_dap;
621                 }
622
623                 dmic->pin_active_state = pinctrl_lookup_state(dmic->pinctrl,
624                                                                         "dap_active");
625                 if (IS_ERR(dmic->pin_active_state)) {
626                         dev_warn(&pdev->dev, "Missing dap-active state\n");
627                         goto err_dap;
628                 }
629
630                 dmic->pin_idle_state = pinctrl_lookup_state(dmic->pinctrl,
631                                                                 "dap_inactive");
632                 if (IS_ERR(dmic->pin_idle_state)) {
633                         dev_warn(&pdev->dev, "Missing dap-inactive state\n");
634                         goto err_dap;
635                 }
636
637                 ret = pinctrl_select_state(dmic->pinctrl, dmic->pin_idle_state);
638                 if (ret < 0) {
639                         dev_err(&pdev->dev, "setting state failed\n");
640                         goto err_dap;
641                 }
642         }
643
644 err_dap:
645         dev_set_drvdata(&pdev->dev, dmic);
646
647         return 0;
648
649 err_suspend:
650         if (!pm_runtime_status_suspended(&pdev->dev))
651                 tegra210_dmic_runtime_suspend(&pdev->dev);
652 err_pm_disable:
653         pm_runtime_disable(&pdev->dev);
654 err_plla_clk_put:
655         devm_clk_put(&pdev->dev, dmic->clk_pll_a_out0);
656 err_clk_put:
657         if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga()))
658                 devm_clk_put(&pdev->dev, dmic->clk_dmic);
659 err:
660         return ret;
661 }
662
663 static void tegra210_dmic_platform_shutdown(struct platform_device *pdev)
664 {
665         struct tegra210_dmic *dmic = dev_get_drvdata(&pdev->dev);
666
667         dmic->is_shutdown = true;
668 }
669
670 static int tegra210_dmic_platform_remove(struct platform_device *pdev)
671 {
672         struct tegra210_dmic *dmic;
673
674         dmic = dev_get_drvdata(&pdev->dev);
675         snd_soc_unregister_codec(&pdev->dev);
676
677         pm_runtime_disable(&pdev->dev);
678         if (!pm_runtime_status_suspended(&pdev->dev))
679                 tegra210_dmic_runtime_suspend(&pdev->dev);
680
681         devm_clk_put(&pdev->dev, dmic->clk_pll_a_out0);
682         devm_clk_put(&pdev->dev, dmic->clk_dmic);
683         return 0;
684 }
685
686 static const struct dev_pm_ops tegra210_dmic_pm_ops = {
687         SET_RUNTIME_PM_OPS(tegra210_dmic_runtime_suspend,
688                            tegra210_dmic_runtime_resume, NULL)
689         SET_LATE_SYSTEM_SLEEP_PM_OPS(tegra210_dmic_suspend,
690                                      tegra210_dmic_resume)
691 };
692
693 static struct platform_driver tegra210_dmic_driver = {
694         .driver = {
695                 .name = DRV_NAME,
696                 .owner = THIS_MODULE,
697                 .of_match_table = tegra210_dmic_of_match,
698                 .pm = &tegra210_dmic_pm_ops,
699         },
700         .probe = tegra210_dmic_platform_probe,
701         .remove = tegra210_dmic_platform_remove,
702         .shutdown = tegra210_dmic_platform_shutdown,
703 };
704 module_platform_driver(tegra210_dmic_driver)
705
706 MODULE_AUTHOR("Rahul Mittal <rmittal@nvidia.com>");
707 MODULE_DESCRIPTION("Tegra210 DMIC ASoC driver");
708 MODULE_LICENSE("GPL");
709 MODULE_ALIAS("platform:" DRV_NAME);
710 MODULE_DEVICE_TABLE(of, tegra210_dmic_of_match);