]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - sound/soc/tegra-alt/tegra210_dmic_alt.c
tegra-alt: dmic: Add output bit-width control
[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 const int tegra210_dmic_fmt_values[] = {
150         0,
151         TEGRA210_AUDIOCIF_BITS_16,
152         TEGRA210_AUDIOCIF_BITS_32,
153 };
154
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)
158 {
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;
164         int channel_select;
165
166         memset(&cif_conf, 0, sizeof(struct tegra210_xbar_cif_conf));
167
168         srate = params_rate(params);
169         dmic_clk = (1 << (6+osr)) * srate;
170
171         if (dmic->ch_select == DMIC_CH_SELECT_NONE) {
172                 channels = 2;
173                 channel_select = DMIC_CH_SELECT_STEREO;
174         } else {
175                 channels = 1;
176                 channel_select = dmic->ch_select;
177         }
178
179         cif_conf.client_channels = channels;
180         cif_conf.audio_channels = channels;
181
182         /* For capture path, the mono input from client channel
183          * can be converted to stereo with cif controls.
184         */
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;
188         }
189
190         if ((tegra_platform_is_unit_fpga() || tegra_platform_is_fpga())) {
191                 program_dmic_gpio();
192                 program_dmic_clk(dmic_clk);
193         } else {
194                 ret = clk_set_rate(dmic->clk_dmic, dmic_clk);
195                 if (ret) {
196                         dev_err(dev, "Can't set dmic clock rate: %d\n", ret);
197                         return ret;
198                 }
199         }
200
201         regmap_update_bits(dmic->regmap,
202                                 TEGRA210_DMIC_CTRL,
203                                 TEGRA210_DMIC_CTRL_OSR_MASK,
204                                 osr << TEGRA210_DMIC_CTRL_OSR_SHIFT);
205
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);
210
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);
215
216         regmap_update_bits(dmic->regmap,
217                                 TEGRA210_DMIC_CTRL,
218                                 TEGRA210_DMIC_CTRL_CHANNEL_SELECT_MASK,
219                                 channel_select <<
220                                    TEGRA210_DMIC_CTRL_CHANNEL_SELECT_SHIFT);
221
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;
231                 }
232         }
233         regmap_write(dmic->regmap,
234                                 TEGRA210_DMIC_LP_FILTER_GAIN,
235                                 (unsigned int)boost_gain);
236
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);
241
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);
264
265         switch (params_format(params)) {
266         case SNDRV_PCM_FORMAT_S16_LE:
267                 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_16;
268                 break;
269         case SNDRV_PCM_FORMAT_S32_LE:
270                 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_32;
271                 break;
272         default:
273                 dev_err(dev, "Wrong format!\n");
274                 return -EINVAL;
275         }
276
277         if (dmic->format_out)
278                 cif_conf.audio_bits = tegra210_dmic_fmt_values[dmic->format_out];
279
280         cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_24;
281
282         dmic->soc_data->set_audio_cif(dmic->regmap, TEGRA210_DMIC_TX_CIF_CTRL,
283                 &cif_conf);
284
285         return 0;
286 }
287
288 static int tegra210_dmic_get_control(struct snd_kcontrol *kcontrol,
289         struct snd_ctl_elem_value *ucontrol)
290 {
291         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
292         struct tegra210_dmic *dmic = snd_soc_codec_get_drvdata(codec);
293
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;
303
304         return 0;
305 }
306
307 static int tegra210_dmic_put_control(struct snd_kcontrol *kcontrol,
308         struct snd_ctl_elem_value *ucontrol)
309 {
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];
313
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;
322
323         return 0;
324 }
325
326 static int tegra210_dmic_codec_probe(struct snd_soc_codec *codec)
327 {
328         struct tegra210_dmic *dmic = snd_soc_codec_get_drvdata(codec);
329
330         codec->control_data = dmic->regmap;
331
332         return 0;
333 }
334
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,
338 };
339
340 static struct snd_soc_dai_driver tegra210_dmic_dais[] = {
341         {
342                 .name = "CIF",
343                 .capture = {
344                         .stream_name = "DMIC Transmit",
345                         .channels_min = 1,
346                         .channels_max = 2,
347                         .rates = SNDRV_PCM_RATE_8000_48000,
348                         .formats = SNDRV_PCM_FMTBIT_S16_LE,
349                 },
350                 .ops = &tegra210_dmic_dai_ops,
351                 .symmetric_rates = 1,
352         },
353         {
354                 .name = "DAP",
355                 .playback = {
356                         .stream_name = "DMIC Receive",
357                         .channels_min = 1,
358                         .channels_max = 2,
359                         .rates = SNDRV_PCM_RATE_8000_48000,
360                         .formats = SNDRV_PCM_FMTBIT_S16_LE,
361                 },
362                 .ops = &tegra210_dmic_dai_ops,
363                 .symmetric_rates = 1,
364         }
365 };
366
367 static const struct snd_soc_dapm_widget tegra210_dmic_widgets[] = {
368         SND_SOC_DAPM_AIF_OUT("DMIC TX", NULL, 0, SND_SOC_NOPM,
369                                 0, 0),
370         SND_SOC_DAPM_AIF_IN("DMIC RX", NULL, 0, TEGRA210_DMIC_ENABLE,
371                                 TEGRA210_DMIC_ENABLE_EN_SHIFT, 0),
372 };
373
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" },
378 };
379
380 static const char * const tegra210_dmic_ch_select[] = {
381         "None", "L", "R",
382 };
383
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);
388
389 static const char * const tegra210_dmic_mono_conv_text[] = {
390         "None", "ZERO", "COPY",
391 };
392
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);
397
398 static const char * const tegra210_dmic_format_text[] = {
399         "None",
400         "16",
401         "32",
402 };
403
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);
408
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),
418         };
419
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),
428         .idle_bias_off = 1,
429 };
430
431 /* Regmap callback functions */
432 static bool tegra210_dmic_wr_reg(struct device *dev, unsigned int reg)
433 {
434         switch (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:
439
440         case TEGRA210_DMIC_ENABLE:
441         case TEGRA210_DMIC_SOFT_RESET:
442         case TEGRA210_DMIC_CG:
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_rd_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_MASK:
460         case TEGRA210_DMIC_TX_INT_SET:
461         case TEGRA210_DMIC_TX_INT_CLEAR:
462         case TEGRA210_DMIC_TX_CIF_CTRL:
463
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:
470                 return true;
471         default:
472                 if (((reg % 4) == 0) && (reg >= TEGRA210_DMIC_DBG_CTRL) &&
473                     (reg <= TEGRA210_DMIC_CORRECTION_BIQUAD_1_COEF_4))
474                         return true;
475                 else
476                         return false;
477         };
478 }
479
480 static bool tegra210_dmic_volatile_reg(struct device *dev, unsigned int reg)
481 {
482         switch (reg) {
483         case TEGRA210_DMIC_TX_STATUS:
484         case TEGRA210_DMIC_TX_INT_STATUS:
485         case TEGRA210_DMIC_TX_INT_SET:
486
487         case TEGRA210_DMIC_SOFT_RESET:
488         case TEGRA210_DMIC_STATUS:
489         case TEGRA210_DMIC_INT_STATUS:
490                 return true;
491         default:
492                 return false;
493         };
494 }
495
496 static const struct regmap_config tegra210_dmic_regmap_config = {
497         .reg_bits = 32,
498         .reg_stride = 4,
499         .val_bits = 32,
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,
508 };
509
510 static const struct tegra210_dmic_soc_data soc_data_tegra210 = {
511         .set_audio_cif = tegra210_xbar_set_cif,
512 };
513
514 static const struct of_device_id tegra210_dmic_of_match[] = {
515         { .compatible = "nvidia,tegra210-dmic", .data = &soc_data_tegra210 },
516         {},
517 };
518
519 static int tegra210_dmic_platform_probe(struct platform_device *pdev)
520 {
521         struct tegra210_dmic *dmic;
522         struct device_node *np = pdev->dev.of_node;
523         struct resource *mem, *memregion;
524         void __iomem *regs;
525         int ret = 0;
526         const struct of_device_id *match;
527         struct tegra210_dmic_soc_data *soc_data;
528         const char *prod_name;
529
530         match = of_match_device(tegra210_dmic_of_match, &pdev->dev);
531         if (!match) {
532                 dev_err(&pdev->dev, "Error: No device match found\n");
533                 ret = -ENODEV;
534                 goto err;
535         }
536         soc_data = (struct tegra210_dmic_soc_data *)match->data;
537
538         dmic = devm_kzalloc(&pdev->dev, sizeof(struct tegra210_dmic), GFP_KERNEL);
539         if (!dmic) {
540                 dev_err(&pdev->dev, "Can't allocate dmic\n");
541                 ret = -ENOMEM;
542                 goto err;
543         }
544
545         dmic->soc_data = soc_data;
546         dmic->is_shutdown = false;
547
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);
553                         goto err;
554                 }
555 #if defined(CONFIG_ARCH_TEGRA_210_SOC)
556                 dmic->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
557 #else
558                 dmic->clk_pll_a_out0 = devm_clk_get(&pdev->dev, "pll_a_out0");
559 #endif
560                 if (IS_ERR_OR_NULL(dmic->clk_pll_a_out0)) {
561                         dev_err(&pdev->dev, "Can't retrieve pll_a_out0 clock\n");
562                         ret = -ENOENT;
563                         goto err_clk_put;
564                 }
565
566                 ret = clk_set_parent(dmic->clk_dmic, dmic->clk_pll_a_out0);
567                 if (ret) {
568                         dev_err(&pdev->dev, "Can't set parent of dmic clock\n");
569                         goto err_plla_clk_put;
570                 }
571         }
572
573         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
574         if (!mem) {
575                 dev_err(&pdev->dev, "No memory resource\n");
576                 ret = -ENODEV;
577                 goto err_plla_clk_put;
578         }
579
580         memregion = devm_request_mem_region(&pdev->dev, mem->start,
581                                             resource_size(mem), pdev->name);
582         if (!memregion) {
583                 dev_err(&pdev->dev, "Memory region already claimed\n");
584                 ret = -EBUSY;
585                 goto err_plla_clk_put;
586         }
587
588         regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
589         if (!regs) {
590                 dev_err(&pdev->dev, "ioremap failed\n");
591                 ret = -ENOMEM;
592                 goto err_plla_clk_put;
593         }
594
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;
601         }
602         regcache_cache_only(dmic->regmap, true);
603
604         /* Below patch is as per latest POR value */
605         regmap_write(dmic->regmap,
606                         TEGRA210_DMIC_DCR_BIQUAD_0_COEF_4, 0x00000000);
607
608         if (of_property_read_u32(np, "nvidia,ahub-dmic-id",
609                                 &pdev->dev.id) < 0) {
610                 dev_err(&pdev->dev,
611                         "Missing property nvidia,ahub-dmic-id\n");
612                 ret = -ENODEV;
613                 goto err_plla_clk_put;
614         }
615
616         pm_runtime_enable(&pdev->dev);
617         if (!pm_runtime_enabled(&pdev->dev)) {
618                 ret = tegra210_dmic_runtime_resume(&pdev->dev);
619                 if (ret)
620                         goto err_pm_disable;
621         }
622
623         ret = snd_soc_register_codec(&pdev->dev, &tegra210_dmic_codec,
624                                      tegra210_dmic_dais,
625                                      ARRAY_SIZE(tegra210_dmic_dais));
626         if (ret != 0) {
627                 dev_err(&pdev->dev, "Could not register CODEC: %d\n", ret);
628                 goto err_suspend;
629         }
630
631         if (of_property_read_string(np, "prod-name", &prod_name) == 0) {
632                 ret = tegra_pinctrl_config_prod(&pdev->dev, prod_name);
633                 if (ret < 0)
634                         dev_warn(&pdev->dev, "Failed to set %s setting\n",
635                                         prod_name);
636         }
637
638         if (of_property_read_u32(np, "nvidia,is-pinctrl",
639                                 &dmic->is_pinctrl) < 0)
640                 dmic->is_pinctrl = 0;
641
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");
646                         goto err_dap;
647                 }
648
649                 dmic->pin_active_state = pinctrl_lookup_state(dmic->pinctrl,
650                                                                         "dap_active");
651                 if (IS_ERR(dmic->pin_active_state)) {
652                         dev_warn(&pdev->dev, "Missing dap-active state\n");
653                         goto err_dap;
654                 }
655
656                 dmic->pin_idle_state = pinctrl_lookup_state(dmic->pinctrl,
657                                                                 "dap_inactive");
658                 if (IS_ERR(dmic->pin_idle_state)) {
659                         dev_warn(&pdev->dev, "Missing dap-inactive state\n");
660                         goto err_dap;
661                 }
662
663                 ret = pinctrl_select_state(dmic->pinctrl, dmic->pin_idle_state);
664                 if (ret < 0) {
665                         dev_err(&pdev->dev, "setting state failed\n");
666                         goto err_dap;
667                 }
668         }
669
670 err_dap:
671         dev_set_drvdata(&pdev->dev, dmic);
672
673         return 0;
674
675 err_suspend:
676         if (!pm_runtime_status_suspended(&pdev->dev))
677                 tegra210_dmic_runtime_suspend(&pdev->dev);
678 err_pm_disable:
679         pm_runtime_disable(&pdev->dev);
680 err_plla_clk_put:
681         devm_clk_put(&pdev->dev, dmic->clk_pll_a_out0);
682 err_clk_put:
683         if (!(tegra_platform_is_unit_fpga() || tegra_platform_is_fpga()))
684                 devm_clk_put(&pdev->dev, dmic->clk_dmic);
685 err:
686         return ret;
687 }
688
689 static void tegra210_dmic_platform_shutdown(struct platform_device *pdev)
690 {
691         struct tegra210_dmic *dmic = dev_get_drvdata(&pdev->dev);
692
693         dmic->is_shutdown = true;
694 }
695
696 static int tegra210_dmic_platform_remove(struct platform_device *pdev)
697 {
698         struct tegra210_dmic *dmic;
699
700         dmic = dev_get_drvdata(&pdev->dev);
701         snd_soc_unregister_codec(&pdev->dev);
702
703         pm_runtime_disable(&pdev->dev);
704         if (!pm_runtime_status_suspended(&pdev->dev))
705                 tegra210_dmic_runtime_suspend(&pdev->dev);
706
707         devm_clk_put(&pdev->dev, dmic->clk_pll_a_out0);
708         devm_clk_put(&pdev->dev, dmic->clk_dmic);
709         return 0;
710 }
711
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)
717 };
718
719 static struct platform_driver tegra210_dmic_driver = {
720         .driver = {
721                 .name = DRV_NAME,
722                 .owner = THIS_MODULE,
723                 .of_match_table = tegra210_dmic_of_match,
724                 .pm = &tegra210_dmic_pm_ops,
725         },
726         .probe = tegra210_dmic_platform_probe,
727         .remove = tegra210_dmic_platform_remove,
728         .shutdown = tegra210_dmic_platform_shutdown,
729 };
730 module_platform_driver(tegra210_dmic_driver)
731
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);