]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/blob - sound/soc/tegra-alt/tegra210_admaif_alt.c
0ece9345134fb4081a8f3222537d283bdb0af2c9
[hercules2020/nv-tegra/linux-4.4.git] / sound / soc / tegra-alt / tegra210_admaif_alt.c
1 /*
2  * tegra210_admaif_alt.c - Tegra ADMAIF 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
19 #include <linux/delay.h>
20 #include <linux/clk.h>
21 #include <linux/device.h>
22 #include <linux/io.h>
23 #include <linux/module.h>
24 #include <linux/of_platform.h>
25 #include <linux/platform_device.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/regmap.h>
28 #include <linux/slab.h>
29 #include <linux/clk/tegra.h>
30 #include <sound/soc.h>
31 #include <sound/pcm_params.h>
32
33 #include "tegra_pcm_alt.h"
34 #include "tegra210_xbar_alt.h"
35 #include "tegra_isomgr_bw_alt.h"
36 #if defined(CONFIG_ARCH_TEGRA_18x_SOC)
37 #include <sound/tegra_audio.h>
38 #endif
39 #include "tegra210_admaif_alt.h"
40
41 #define DRV_NAME "tegra210-ape-admaif"
42
43 #define ADMAIF_CH_REG(reg, id) (reg + (TEGRA210_ADMAIF_CHANNEL_REG_STRIDE * id))
44 #define ADMAIF_REG_DEFAULTS(id, rx_fifo_ctrl, tx_fifo_ctrl) \
45         { ADMAIF_CH_REG(TEGRA210_ADMAIF_XBAR_RX_INT_MASK, id), 0x00000001}, \
46         { ADMAIF_CH_REG(TEGRA210_ADMAIF_CHAN_ACIF_RX_CTRL, id), 0x00007700}, \
47         { ADMAIF_CH_REG(TEGRA210_ADMAIF_XBAR_RX_FIFO_CTRL, id), rx_fifo_ctrl}, \
48         { ADMAIF_CH_REG(TEGRA210_ADMAIF_XBAR_TX_INT_MASK, id), 0x00000001}, \
49         { ADMAIF_CH_REG(TEGRA210_ADMAIF_CHAN_ACIF_TX_CTRL, id), 0x00007700}, \
50         { ADMAIF_CH_REG(TEGRA210_ADMAIF_XBAR_TX_FIFO_CTRL, id), tx_fifo_ctrl}
51
52 static const struct reg_default tegra210_admaif_reg_defaults[] = {
53         { TEGRA210_ADMAIF_GLOBAL_CG_0, 0x00000003},
54         ADMAIF_REG_DEFAULTS(0,  ADMAIF_RX1_FIFO_CTRL_REG_DEFAULT,
55                                 ADMAIF_TX1_FIFO_CTRL_REG_DEFAULT),
56         ADMAIF_REG_DEFAULTS(1,  ADMAIF_RX2_FIFO_CTRL_REG_DEFAULT,
57                                 ADMAIF_TX2_FIFO_CTRL_REG_DEFAULT),
58         ADMAIF_REG_DEFAULTS(2,  ADMAIF_RX3_FIFO_CTRL_REG_DEFAULT,
59                                 ADMAIF_TX3_FIFO_CTRL_REG_DEFAULT),
60         ADMAIF_REG_DEFAULTS(3,  ADMAIF_RX4_FIFO_CTRL_REG_DEFAULT,
61                                 ADMAIF_TX4_FIFO_CTRL_REG_DEFAULT),
62         ADMAIF_REG_DEFAULTS(4,  ADMAIF_RX5_FIFO_CTRL_REG_DEFAULT,
63                                 ADMAIF_TX5_FIFO_CTRL_REG_DEFAULT),
64         ADMAIF_REG_DEFAULTS(5,  ADMAIF_RX6_FIFO_CTRL_REG_DEFAULT,
65                                 ADMAIF_TX6_FIFO_CTRL_REG_DEFAULT),
66         ADMAIF_REG_DEFAULTS(6,  ADMAIF_RX7_FIFO_CTRL_REG_DEFAULT,
67                                 ADMAIF_TX7_FIFO_CTRL_REG_DEFAULT),
68         ADMAIF_REG_DEFAULTS(7,  ADMAIF_RX8_FIFO_CTRL_REG_DEFAULT,
69                                 ADMAIF_TX8_FIFO_CTRL_REG_DEFAULT),
70         ADMAIF_REG_DEFAULTS(8,  ADMAIF_RX9_FIFO_CTRL_REG_DEFAULT,
71                                 ADMAIF_TX9_FIFO_CTRL_REG_DEFAULT),
72         ADMAIF_REG_DEFAULTS(9,  ADMAIF_RX10_FIFO_CTRL_REG_DEFAULT,
73                                 ADMAIF_TX10_FIFO_CTRL_REG_DEFAULT),
74         ADMAIF_REG_DEFAULTS(10, ADMAIF_RX11_FIFO_CTRL_REG_DEFAULT,
75                                 ADMAIF_TX11_FIFO_CTRL_REG_DEFAULT),
76         ADMAIF_REG_DEFAULTS(11, ADMAIF_RX12_FIFO_CTRL_REG_DEFAULT,
77                                 ADMAIF_TX12_FIFO_CTRL_REG_DEFAULT),
78         ADMAIF_REG_DEFAULTS(12, ADMAIF_RX13_FIFO_CTRL_REG_DEFAULT,
79                                 ADMAIF_TX13_FIFO_CTRL_REG_DEFAULT),
80         ADMAIF_REG_DEFAULTS(13, ADMAIF_RX14_FIFO_CTRL_REG_DEFAULT,
81                                 ADMAIF_TX14_FIFO_CTRL_REG_DEFAULT),
82         ADMAIF_REG_DEFAULTS(14, ADMAIF_RX15_FIFO_CTRL_REG_DEFAULT,
83                                 ADMAIF_TX15_FIFO_CTRL_REG_DEFAULT),
84         ADMAIF_REG_DEFAULTS(15, ADMAIF_RX16_FIFO_CTRL_REG_DEFAULT,
85                                 ADMAIF_TX16_FIFO_CTRL_REG_DEFAULT),
86         ADMAIF_REG_DEFAULTS(16, ADMAIF_RX17_FIFO_CTRL_REG_DEFAULT,
87                                 ADMAIF_TX17_FIFO_CTRL_REG_DEFAULT),
88         ADMAIF_REG_DEFAULTS(17, ADMAIF_RX18_FIFO_CTRL_REG_DEFAULT,
89                                 ADMAIF_TX18_FIFO_CTRL_REG_DEFAULT),
90         ADMAIF_REG_DEFAULTS(18, ADMAIF_RX19_FIFO_CTRL_REG_DEFAULT,
91                                 ADMAIF_TX19_FIFO_CTRL_REG_DEFAULT),
92         ADMAIF_REG_DEFAULTS(19, ADMAIF_RX20_FIFO_CTRL_REG_DEFAULT,
93                                 ADMAIF_TX20_FIFO_CTRL_REG_DEFAULT),
94 };
95
96 static bool tegra210_admaif_wr_reg(struct device *dev, unsigned int reg)
97 {
98         reg = reg % TEGRA210_ADMAIF_CHANNEL_REG_STRIDE;
99
100         switch (reg) {
101         case TEGRA210_ADMAIF_XBAR_TX_ENABLE:
102         case TEGRA210_ADMAIF_XBAR_TX_STATUS:
103         case TEGRA210_ADMAIF_XBAR_TX_FIFO_CTRL:
104         case TEGRA210_ADMAIF_XBAR_TX_SOFT_RESET:
105         case TEGRA210_ADMAIF_CHAN_ACIF_TX_CTRL:
106         case TEGRA210_ADMAIF_XBAR_RX_ENABLE:
107         case TEGRA210_ADMAIF_XBAR_RX_FIFO_CTRL:
108         case TEGRA210_ADMAIF_XBAR_RX_SOFT_RESET:
109         case TEGRA210_ADMAIF_CHAN_ACIF_RX_CTRL:
110         case TEGRA210_ADMAIF_GLOBAL_ENABLE:
111                 return true;
112         default:
113                 break;
114         };
115
116         return false;
117 }
118
119 static bool tegra210_admaif_rd_reg(struct device *dev, unsigned int reg)
120 {
121         reg = reg % TEGRA210_ADMAIF_CHANNEL_REG_STRIDE;
122
123         switch (reg) {
124         case TEGRA210_ADMAIF_XBAR_RX_STATUS:
125         case TEGRA210_ADMAIF_XBAR_RX_INT_STATUS:
126         case TEGRA210_ADMAIF_XBAR_RX_ENABLE:
127         case TEGRA210_ADMAIF_XBAR_RX_SOFT_RESET:
128         case TEGRA210_ADMAIF_XBAR_RX_FIFO_CTRL:
129         case TEGRA210_ADMAIF_CHAN_ACIF_RX_CTRL:
130         case TEGRA210_ADMAIF_XBAR_TX_STATUS:
131         case TEGRA210_ADMAIF_XBAR_TX_INT_STATUS:
132         case TEGRA210_ADMAIF_XBAR_TX_ENABLE:
133         case TEGRA210_ADMAIF_XBAR_TX_SOFT_RESET:
134         case TEGRA210_ADMAIF_XBAR_TX_FIFO_CTRL:
135         case TEGRA210_ADMAIF_CHAN_ACIF_TX_CTRL:
136         case TEGRA210_ADMAIF_GLOBAL_ENABLE:
137                 return true;
138         default:
139                 return false;
140         };
141 }
142
143 static bool tegra210_admaif_volatile_reg(struct device *dev, unsigned int reg)
144 {
145         if (reg > 0 && (reg < TEGRA210_ADMAIF_CHANNEL_COUNT *
146                                         TEGRA210_ADMAIF_CHANNEL_REG_STRIDE * 2))
147                 reg = reg % TEGRA210_ADMAIF_CHANNEL_REG_STRIDE;
148
149         switch (reg) {
150         case TEGRA210_ADMAIF_XBAR_RX_STATUS:
151         case TEGRA210_ADMAIF_XBAR_TX_STATUS:
152         case TEGRA210_ADMAIF_XBAR_RX_INT_STATUS:
153         case TEGRA210_ADMAIF_XBAR_TX_INT_STATUS:
154         case TEGRA210_ADMAIF_XBAR_RX_SOFT_RESET:
155         case TEGRA210_ADMAIF_XBAR_TX_SOFT_RESET:
156         case TEGRA210_ADMAIF_XBAR_TX_ENABLE:
157         case TEGRA210_ADMAIF_XBAR_RX_ENABLE:
158                 return true;
159         default:
160                 break;
161         };
162
163         return false;
164 }
165
166 static const struct regmap_config tegra210_admaif_regmap_config = {
167         .reg_bits = 32,
168         .reg_stride = 4,
169         .val_bits = 32,
170         .max_register = TEGRA210_ADMAIF_LAST_REG,
171         .writeable_reg = tegra210_admaif_wr_reg,
172         .readable_reg = tegra210_admaif_rd_reg,
173         .volatile_reg = tegra210_admaif_volatile_reg,
174         .reg_defaults = tegra210_admaif_reg_defaults,
175         .num_reg_defaults = TEGRA210_ADMAIF_CHANNEL_COUNT * 6 + 1,
176         .cache_type = REGCACHE_FLAT,
177 };
178
179 static int tegra210_admaif_sw_reset(struct snd_soc_dai *dai,
180                                 int direction, int timeout)
181 {
182         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
183         unsigned int sw_reset_reg, val;
184         int wait = timeout;
185
186         if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
187                 sw_reset_reg = TEGRA210_ADMAIF_XBAR_TX_SOFT_RESET +
188                         (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
189         } else {
190                 sw_reset_reg = TEGRA210_ADMAIF_XBAR_RX_SOFT_RESET +
191                         (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
192         }
193
194         regmap_update_bits(admaif->regmap, sw_reset_reg, 1, 1);
195
196         do {
197                 regmap_read(admaif->regmap, sw_reset_reg, &val);
198                 wait--;
199                 if (!wait)
200                         return -EINVAL;
201         } while (val & 0x00000001);
202
203         return 0;
204 }
205
206 static int tegra210_admaif_get_status(struct snd_soc_dai *dai,
207                                 int direction)
208 {
209         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
210         unsigned int status_reg, val;
211
212         if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
213                 status_reg = TEGRA210_ADMAIF_XBAR_TX_STATUS +
214                         (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
215         } else {
216                 status_reg = TEGRA210_ADMAIF_XBAR_RX_STATUS +
217                         (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
218         }
219         regmap_read(admaif->regmap, status_reg, &val);
220         val = (val & 0x00000001);
221
222         return val;
223 }
224
225 static int tegra210_admaif_runtime_suspend(struct device *dev)
226 {
227         struct tegra210_admaif *admaif = dev_get_drvdata(dev);
228
229         regcache_cache_only(admaif->regmap, true);
230         regcache_mark_dirty(admaif->regmap);
231         pm_runtime_put_sync(dev->parent);
232
233         return 0;
234 }
235
236 static int tegra210_admaif_runtime_resume(struct device *dev)
237 {
238         struct tegra210_admaif *admaif = dev_get_drvdata(dev);
239         int ret;
240
241         ret = pm_runtime_get_sync(dev->parent);
242         if (ret < 0) {
243                 dev_err(dev, "parent get_sync failed: %d\n", ret);
244                 return ret;
245         }
246
247         regcache_cache_only(admaif->regmap, false);
248         if (!admaif->is_shutdown)
249                 regcache_sync(admaif->regmap);
250
251         return 0;
252 }
253
254 #ifdef CONFIG_PM_SLEEP
255 static int tegra210_admaif_suspend(struct device *dev)
256 {
257         return 0;
258 }
259 #endif
260
261 static int tegra210_admaif_set_pack_mode(struct regmap *map, unsigned int reg,
262                                         int valid_bit)
263 {
264         switch (valid_bit) {
265         case DATA_8BIT:
266                 regmap_update_bits(map, reg,
267                         TEGRA210_ADMAIF_CHAN_ACIF_CTRL_PACK8_EN_MASK,
268                         TEGRA210_ADMAIF_CHAN_ACIF_CTRL_PACK8_EN);
269                 regmap_update_bits(map, reg,
270                         TEGRA210_ADMAIF_CHAN_ACIF_CTRL_PACK16_EN_MASK,
271                         0);
272                 break;
273         case DATA_16BIT:
274                 regmap_update_bits(map, reg,
275                         TEGRA210_ADMAIF_CHAN_ACIF_CTRL_PACK16_EN_MASK,
276                         TEGRA210_ADMAIF_CHAN_ACIF_CTRL_PACK16_EN);
277                 regmap_update_bits(map, reg,
278                         TEGRA210_ADMAIF_CHAN_ACIF_CTRL_PACK8_EN_MASK,
279                         0);
280                 break;
281         case DATA_32BIT:
282                 regmap_update_bits(map, reg,
283                         TEGRA210_ADMAIF_CHAN_ACIF_CTRL_PACK16_EN_MASK,
284                         0);
285                 regmap_update_bits(map, reg,
286                         TEGRA210_ADMAIF_CHAN_ACIF_CTRL_PACK8_EN_MASK,
287                         0);
288                 break;
289         default:
290                 return -EINVAL;
291         }
292
293         return 0;
294 }
295
296 static int tegra210_admaif_prepare(struct snd_pcm_substream *substream,
297                                 struct snd_soc_dai *dai)
298 {
299         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
300
301         if (admaif->soc_data->is_isomgr_client)
302                 tegra_isomgr_adma_setbw(substream, true);
303
304         return 0;
305 }
306
307 static int tegra210_admaif_startup(struct snd_pcm_substream *substream,
308                                 struct snd_soc_dai *dai)
309 {
310         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
311
312         if (admaif->is_shutdown)
313                 return -ENODEV;
314
315         return 0;
316 }
317
318 static void tegra210_admaif_shutdown(struct snd_pcm_substream *substream,
319                                 struct snd_soc_dai *dai)
320 {
321         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
322
323         if (admaif->soc_data->is_isomgr_client)
324                 tegra_isomgr_adma_setbw(substream, false);
325 }
326
327 static int tegra210_admaif_hw_params(struct snd_pcm_substream *substream,
328                                  struct snd_pcm_hw_params *params,
329                                  struct snd_soc_dai *dai)
330 {
331         struct device *dev = dai->dev;
332         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
333         struct tegra210_xbar_cif_conf cif_conf;
334         unsigned int reg;
335         int valid_bit, channels;
336
337         memset(&cif_conf, 0, sizeof(struct tegra210_xbar_cif_conf));
338
339         channels = params_channels(params);
340         if (admaif->override_channels[dai->id] > 0)
341                 channels = admaif->override_channels[dai->id];
342
343         cif_conf.audio_channels = channels;
344         cif_conf.client_channels = channels;
345
346         switch (params_format(params)) {
347         case SNDRV_PCM_FORMAT_S8:
348                 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_8;
349                 cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_8;
350                 valid_bit = DATA_8BIT;
351                 break;
352         case SNDRV_PCM_FORMAT_S16_LE:
353                 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_16;
354                 cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_16;
355                 valid_bit = DATA_16BIT;
356                 break;
357         case SNDRV_PCM_FORMAT_S24_LE:
358                 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_24;
359                 cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_24;
360                 valid_bit = DATA_32BIT;
361                 break;
362         case SNDRV_PCM_FORMAT_S32_LE:
363                 cif_conf.audio_bits = TEGRA210_AUDIOCIF_BITS_32;
364                 cif_conf.client_bits = TEGRA210_AUDIOCIF_BITS_32;
365                 valid_bit  = DATA_32BIT;
366                 break;
367         default:
368                 dev_err(dev, "Wrong format!\n");
369                 return -EINVAL;
370         }
371
372         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
373                 reg = TEGRA210_ADMAIF_CHAN_ACIF_TX_CTRL +
374                         (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
375                 /* For playback path, the mono input from client channel
376                  * can be converted to stereo using cif controls.
377                 */
378                 if (admaif->tx_mono_to_stereo[dai->id] > 0) {
379                         cif_conf.mono_conv =
380                                 admaif->tx_mono_to_stereo[dai->id] - 1;
381                         cif_conf.audio_channels = 2;
382                         cif_conf.client_channels = 1;
383                 }
384         } else {
385                 reg = TEGRA210_ADMAIF_CHAN_ACIF_RX_CTRL +
386                         (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
387                 /* For capture path, the stereo audio channel can be
388                  * converted to mono using cif controls.
389                 */
390                 if (admaif->rx_stereo_to_mono[dai->id] > 0) {
391                         cif_conf.stereo_conv =
392                                 admaif->rx_stereo_to_mono[dai->id] - 1;
393                         cif_conf.audio_channels = 2;
394                         cif_conf.client_channels = 1;
395                 }
396         }
397
398         tegra210_admaif_set_pack_mode(admaif->regmap, reg, valid_bit);
399         admaif->soc_data->set_audio_cif(admaif->regmap, reg, &cif_conf);
400
401         return 0;
402 }
403
404 static void tegra210_admaif_start_playback(struct snd_soc_dai *dai)
405 {
406         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
407         unsigned int reg;
408
409         reg = TEGRA210_ADMAIF_XBAR_TX_ENABLE +
410                 (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
411         regmap_update_bits(admaif->regmap, reg,
412                                 TEGRA210_ADMAIF_XBAR_TX_ENABLE_MASK,
413                                 TEGRA210_ADMAIF_XBAR_TX_EN);
414 }
415
416 static void tegra210_admaif_stop_playback(struct snd_soc_dai *dai)
417 {
418         struct device *dev = dai->dev;
419         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
420         unsigned int reg;
421         int dcnt = 10, ret;
422
423         reg = TEGRA210_ADMAIF_XBAR_TX_ENABLE +
424                 (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
425         regmap_update_bits(admaif->regmap, reg,
426                                 TEGRA210_ADMAIF_XBAR_TX_ENABLE_MASK,
427                                 0);
428
429         /* wait until ADMAIF TX status is disabled */
430         while (tegra210_admaif_get_status(dai, SNDRV_PCM_STREAM_PLAYBACK) &&
431                         dcnt--)
432                 udelay(100);
433
434         /* HW needs sw reset to make sure previous transaction be clean */
435         ret = tegra210_admaif_sw_reset(dai, SNDRV_PCM_STREAM_PLAYBACK, 0xffff);
436         if (ret)
437                 dev_err(dev, "Failed at ADMAIF%d_TX sw reset\n", dev->id);
438 }
439
440 static void tegra210_admaif_start_capture(struct snd_soc_dai *dai)
441 {
442         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
443         unsigned int reg;
444
445         reg = TEGRA210_ADMAIF_XBAR_RX_ENABLE +
446                 (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
447         regmap_update_bits(admaif->regmap, reg,
448                                 TEGRA210_ADMAIF_XBAR_RX_ENABLE_MASK,
449                                 TEGRA210_ADMAIF_XBAR_RX_EN);
450 }
451
452 static void tegra210_admaif_stop_capture(struct snd_soc_dai *dai)
453 {
454         struct device *dev = dai->dev;
455         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
456         unsigned int reg;
457         int dcnt = 10, ret;
458
459         reg = TEGRA210_ADMAIF_XBAR_RX_ENABLE +
460                 (dai->id * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
461         regmap_update_bits(admaif->regmap, reg,
462                                 TEGRA210_ADMAIF_XBAR_RX_ENABLE_MASK,
463                                 0);
464
465         /* wait until ADMAIF RX status is disabled */
466         while (tegra210_admaif_get_status(dai, SNDRV_PCM_STREAM_CAPTURE) &&
467                         dcnt--)
468                 udelay(100);
469
470         /* HW needs sw reset to make sure previous transaction be clean */
471         ret = tegra210_admaif_sw_reset(dai, SNDRV_PCM_STREAM_CAPTURE, 0xffff);
472         if (ret)
473                 dev_err(dev, "Failed at ADMAIF%d_RX sw reset\n", dev->id);
474 }
475
476 static int tegra210_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
477                                  struct snd_soc_dai *dai)
478 {
479         switch (cmd) {
480         case SNDRV_PCM_TRIGGER_START:
481         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
482         case SNDRV_PCM_TRIGGER_RESUME:
483                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
484                         tegra210_admaif_start_playback(dai);
485                 else
486                         tegra210_admaif_start_capture(dai);
487                 break;
488         case SNDRV_PCM_TRIGGER_STOP:
489         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
490         case SNDRV_PCM_TRIGGER_SUSPEND:
491                 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
492                         tegra210_admaif_stop_playback(dai);
493                 else
494                         tegra210_admaif_stop_capture(dai);
495                 break;
496         default:
497                 return -EINVAL;
498         }
499
500         return 0;
501 }
502
503 static struct snd_soc_dai_ops tegra210_admaif_dai_ops = {
504         .hw_params      = tegra210_admaif_hw_params,
505         .trigger        = tegra210_admaif_trigger,
506         .startup        = tegra210_admaif_startup,
507         .shutdown       = tegra210_admaif_shutdown,
508         .prepare        = tegra210_admaif_prepare,
509 };
510
511 static int tegra210_admaif_get_format(struct snd_kcontrol *kcontrol,
512                                          struct snd_ctl_elem_value *ucontrol)
513 {
514         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
515         struct soc_mixer_control *mc =
516                 (struct soc_mixer_control *)kcontrol->private_value;
517         struct tegra210_admaif *admaif = snd_soc_codec_get_drvdata(codec);
518         int i;
519         char buf[50];
520
521         if (strstr(kcontrol->id.name, "Channels"))
522                 ucontrol->value.integer.value[0] =
523                                 admaif->override_channels[mc->reg];
524         else {
525                 for (i = 0 ; i < TEGRA210_ADMAIF_CHANNEL_COUNT; i++) {
526                         snprintf(buf, 50, "ADMAIF%d RX stereo to mono", i+1);
527                         if (strstr(kcontrol->id.name, buf)) {
528                                 ucontrol->value.integer.value[0] =
529                                         admaif->rx_stereo_to_mono[i];
530                                 break;
531                         }
532                         snprintf(buf, 50, "ADMAIF%d TX mono to stereo", i+1);
533                         if (strstr(kcontrol->id.name, buf)) {
534                                 ucontrol->value.integer.value[0] =
535                                         admaif->tx_mono_to_stereo[i];
536                                 break;
537                         }
538                 }
539         }
540
541         return 0;
542 }
543
544 static int tegra210_admaif_put_format(struct snd_kcontrol *kcontrol,
545                                          struct snd_ctl_elem_value *ucontrol)
546 {
547         struct soc_mixer_control *mc =
548                 (struct soc_mixer_control *)kcontrol->private_value;
549         struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
550         struct tegra210_admaif *admaif = snd_soc_codec_get_drvdata(codec);
551         int value = ucontrol->value.integer.value[0];
552         int i;
553         char buf[50];
554
555         if (strstr(kcontrol->id.name, "Channels")) {
556                 if (value > 0 && value <= 16)
557                         admaif->override_channels[mc->reg] = value;
558                 else
559                         return -EINVAL;
560         } else {
561                 for (i = 0 ; i < TEGRA210_ADMAIF_CHANNEL_COUNT; i++) {
562                         snprintf(buf, 50, "ADMAIF%d RX stereo to mono", i+1);
563                         if (strstr(kcontrol->id.name, buf)) {
564                                 admaif->rx_stereo_to_mono[i] = value;
565                                 break;
566                         }
567                         snprintf(buf, 50, "ADMAIF%d TX mono to stereo", i+1);
568                         if (strstr(kcontrol->id.name, buf)) {
569                                 admaif->tx_mono_to_stereo[i] = value;
570                                 break;
571                         }
572                 }
573         }
574
575         return 0;
576 }
577
578 static int tegra210_admaif_dai_probe(struct snd_soc_dai *dai)
579 {
580         struct tegra210_admaif *admaif = snd_soc_dai_get_drvdata(dai);
581
582         dai->capture_dma_data = &admaif->capture_dma_data[dai->id];
583         dai->playback_dma_data = &admaif->playback_dma_data[dai->id];
584
585         return 0;
586 }
587
588 #define ADMAIF_DAI(id)                                                  \
589         {                                                       \
590                 .name = "ADMAIF" #id,                           \
591                 .probe = tegra210_admaif_dai_probe,             \
592                 .playback = {                                   \
593                         .stream_name = "Playback " #id,         \
594                         .channels_min = 1,                      \
595                         .channels_max = 16,                     \
596                         .rates = SNDRV_PCM_RATE_8000_192000,    \
597                         .formats = SNDRV_PCM_FMTBIT_S8 |        \
598                                 SNDRV_PCM_FMTBIT_S16_LE |       \
599                                 SNDRV_PCM_FMTBIT_S24_LE |       \
600                                 SNDRV_PCM_FMTBIT_S32_LE,        \
601                 },                                              \
602                 .capture = {                                    \
603                         .stream_name = "Capture " #id,          \
604                         .channels_min = 1,                      \
605                         .channels_max = 16,                     \
606                         .rates = SNDRV_PCM_RATE_8000_192000,            \
607                         .formats = SNDRV_PCM_FMTBIT_S8 |                \
608                                 SNDRV_PCM_FMTBIT_S16_LE |               \
609                                 SNDRV_PCM_FMTBIT_S24_LE |               \
610                                 SNDRV_PCM_FMTBIT_S32_LE,                \
611                 },                                              \
612                 .ops = &tegra210_admaif_dai_ops,                        \
613         }
614
615 static struct snd_soc_dai_driver tegra210_admaif_dais[] = {
616         ADMAIF_DAI(1),
617         ADMAIF_DAI(2),
618         ADMAIF_DAI(3),
619         ADMAIF_DAI(4),
620         ADMAIF_DAI(5),
621         ADMAIF_DAI(6),
622         ADMAIF_DAI(7),
623         ADMAIF_DAI(8),
624         ADMAIF_DAI(9),
625         ADMAIF_DAI(10),
626         ADMAIF_DAI(11),
627         ADMAIF_DAI(12),
628         ADMAIF_DAI(13),
629         ADMAIF_DAI(14),
630         ADMAIF_DAI(15),
631         ADMAIF_DAI(16),
632         ADMAIF_DAI(17),
633         ADMAIF_DAI(18),
634         ADMAIF_DAI(19),
635         ADMAIF_DAI(20),
636 };
637
638 #define ADMAIF_CODEC_FIFO_DAI(id)                                       \
639         {                                                               \
640                 .name = "ADMAIF" #id " FIFO",                           \
641                 .playback = {                                           \
642                         .stream_name = "ADMAIF" #id " FIFO Transmit",   \
643                         .channels_min = 1,                              \
644                         .channels_max = 16,                             \
645                         .rates = SNDRV_PCM_RATE_8000_192000,            \
646                         .formats = SNDRV_PCM_FMTBIT_S8 |                \
647                                 SNDRV_PCM_FMTBIT_S16_LE |               \
648                                 SNDRV_PCM_FMTBIT_S24_LE |               \
649                                 SNDRV_PCM_FMTBIT_S32_LE,                \
650                 },                                                      \
651                 .capture = {                                            \
652                         .stream_name = "ADMAIF" #id " FIFO Receive",    \
653                         .channels_min = 1,                              \
654                         .channels_max = 16,                             \
655                         .rates = SNDRV_PCM_RATE_8000_192000,            \
656                         .formats = SNDRV_PCM_FMTBIT_S8 |                \
657                                 SNDRV_PCM_FMTBIT_S16_LE |               \
658                                 SNDRV_PCM_FMTBIT_S24_LE |               \
659                                 SNDRV_PCM_FMTBIT_S32_LE,                \
660                 },                                                      \
661                 .ops = &tegra210_admaif_dai_ops,                        \
662         }
663
664 #define ADMAIF_CODEC_CIF_DAI(id)                                        \
665         {                                                               \
666                 .name = "ADMAIF" #id " CIF",                            \
667                 .playback = {                                           \
668                         .stream_name = "ADMAIF" #id " CIF Transmit",    \
669                         .channels_min = 1,                              \
670                         .channels_max = 16,                             \
671                         .rates = SNDRV_PCM_RATE_8000_192000,            \
672                         .formats = SNDRV_PCM_FMTBIT_S8 |                \
673                                 SNDRV_PCM_FMTBIT_S16_LE |               \
674                                 SNDRV_PCM_FMTBIT_S24_LE |               \
675                                 SNDRV_PCM_FMTBIT_S32_LE,                \
676                 },                                                      \
677                 .capture = {                                            \
678                         .stream_name = "ADMAIF" #id " CIF Receive",     \
679                         .channels_min = 1,                              \
680                         .channels_max = 16,                             \
681                         .rates = SNDRV_PCM_RATE_8000_192000,            \
682                         .formats = SNDRV_PCM_FMTBIT_S8 |                \
683                                 SNDRV_PCM_FMTBIT_S16_LE |               \
684                                 SNDRV_PCM_FMTBIT_S24_LE |               \
685                                 SNDRV_PCM_FMTBIT_S32_LE,                \
686                 },                                                      \
687         }
688
689 static struct snd_soc_dai_driver tegra210_admaif_codec_dais[] = {
690         ADMAIF_CODEC_FIFO_DAI(1),
691         ADMAIF_CODEC_FIFO_DAI(2),
692         ADMAIF_CODEC_FIFO_DAI(3),
693         ADMAIF_CODEC_FIFO_DAI(4),
694         ADMAIF_CODEC_FIFO_DAI(5),
695         ADMAIF_CODEC_FIFO_DAI(6),
696         ADMAIF_CODEC_FIFO_DAI(7),
697         ADMAIF_CODEC_FIFO_DAI(8),
698         ADMAIF_CODEC_FIFO_DAI(9),
699         ADMAIF_CODEC_FIFO_DAI(10),
700 #if defined(CONFIG_ARCH_TEGRA_18x_SOC)
701         ADMAIF_CODEC_FIFO_DAI(11),
702         ADMAIF_CODEC_FIFO_DAI(12),
703         ADMAIF_CODEC_FIFO_DAI(13),
704         ADMAIF_CODEC_FIFO_DAI(14),
705         ADMAIF_CODEC_FIFO_DAI(15),
706         ADMAIF_CODEC_FIFO_DAI(16),
707         ADMAIF_CODEC_FIFO_DAI(17),
708         ADMAIF_CODEC_FIFO_DAI(18),
709         ADMAIF_CODEC_FIFO_DAI(19),
710         ADMAIF_CODEC_FIFO_DAI(20),
711 #endif
712         ADMAIF_CODEC_CIF_DAI(1),
713         ADMAIF_CODEC_CIF_DAI(2),
714         ADMAIF_CODEC_CIF_DAI(3),
715         ADMAIF_CODEC_CIF_DAI(4),
716         ADMAIF_CODEC_CIF_DAI(5),
717         ADMAIF_CODEC_CIF_DAI(6),
718         ADMAIF_CODEC_CIF_DAI(7),
719         ADMAIF_CODEC_CIF_DAI(8),
720         ADMAIF_CODEC_CIF_DAI(9),
721         ADMAIF_CODEC_CIF_DAI(10),
722 #if defined(CONFIG_ARCH_TEGRA_18x_SOC)
723         ADMAIF_CODEC_CIF_DAI(11),
724         ADMAIF_CODEC_CIF_DAI(12),
725         ADMAIF_CODEC_CIF_DAI(13),
726         ADMAIF_CODEC_CIF_DAI(14),
727         ADMAIF_CODEC_CIF_DAI(15),
728         ADMAIF_CODEC_CIF_DAI(16),
729         ADMAIF_CODEC_CIF_DAI(17),
730         ADMAIF_CODEC_CIF_DAI(18),
731         ADMAIF_CODEC_CIF_DAI(19),
732         ADMAIF_CODEC_CIF_DAI(20),
733 #endif
734 };
735
736 #define ADMAIF_WIDGETS(id)                                      \
737         SND_SOC_DAPM_AIF_IN("ADMAIF" #id " FIFO RX", NULL, 0,   \
738                 SND_SOC_NOPM, 0, 0),                            \
739         SND_SOC_DAPM_AIF_OUT("ADMAIF" #id " FIFO TX", NULL, 0,  \
740                 SND_SOC_NOPM, 0, 0),                            \
741         SND_SOC_DAPM_AIF_IN("ADMAIF" #id " CIF RX", NULL, 0,    \
742                 SND_SOC_NOPM, 0, 0),                            \
743         SND_SOC_DAPM_AIF_OUT("ADMAIF" #id " CIF TX", NULL, 0,   \
744                 SND_SOC_NOPM, 0, 0)
745
746 static const struct snd_soc_dapm_widget tegra210_admaif_widgets[] = {
747         ADMAIF_WIDGETS(1),
748         ADMAIF_WIDGETS(2),
749         ADMAIF_WIDGETS(3),
750         ADMAIF_WIDGETS(4),
751         ADMAIF_WIDGETS(5),
752         ADMAIF_WIDGETS(6),
753         ADMAIF_WIDGETS(7),
754         ADMAIF_WIDGETS(8),
755         ADMAIF_WIDGETS(9),
756         ADMAIF_WIDGETS(10),
757         ADMAIF_WIDGETS(11),
758         ADMAIF_WIDGETS(12),
759         ADMAIF_WIDGETS(13),
760         ADMAIF_WIDGETS(14),
761         ADMAIF_WIDGETS(15),
762         ADMAIF_WIDGETS(16),
763         ADMAIF_WIDGETS(17),
764         ADMAIF_WIDGETS(18),
765         ADMAIF_WIDGETS(19),
766         ADMAIF_WIDGETS(20)
767 };
768
769 #define ADMAIF_ROUTES(id)                                               \
770         { "ADMAIF" #id " FIFO RX",      NULL, "ADMAIF" #id " FIFO Transmit" }, \
771         { "ADMAIF" #id " CIF TX",       NULL, "ADMAIF" #id " FIFO RX" },\
772         { "ADMAIF" #id " CIF Receive",  NULL, "ADMAIF" #id " CIF TX" }, \
773         { "ADMAIF" #id " CIF RX",       NULL, "ADMAIF" #id " CIF Transmit" },  \
774         { "ADMAIF" #id " FIFO TX",      NULL, "ADMAIF" #id " CIF RX" }, \
775         { "ADMAIF" #id " FIFO Receive", NULL, "ADMAIF" #id " FIFO TX" } \
776
777 static const struct snd_soc_dapm_route tegra210_admaif_routes[] = {
778         ADMAIF_ROUTES(1),
779         ADMAIF_ROUTES(2),
780         ADMAIF_ROUTES(3),
781         ADMAIF_ROUTES(4),
782         ADMAIF_ROUTES(5),
783         ADMAIF_ROUTES(6),
784         ADMAIF_ROUTES(7),
785         ADMAIF_ROUTES(8),
786         ADMAIF_ROUTES(9),
787         ADMAIF_ROUTES(10),
788         ADMAIF_ROUTES(11),
789         ADMAIF_ROUTES(12),
790         ADMAIF_ROUTES(13),
791         ADMAIF_ROUTES(14),
792         ADMAIF_ROUTES(15),
793         ADMAIF_ROUTES(16),
794         ADMAIF_ROUTES(17),
795         ADMAIF_ROUTES(18),
796         ADMAIF_ROUTES(19),
797         ADMAIF_ROUTES(20)
798 };
799
800 static const char * const tegra_admaif_stereo_conv_text[] = {
801         "None", "CH0", "CH1", "AVG",
802 };
803
804 static const char * const tegra_admaif_mono_conv_text[] = {
805         "None", "ZERO", "COPY",
806 };
807
808 static const struct soc_enum tegra_admaif_mono_conv_enum =
809         SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
810                 ARRAY_SIZE(tegra_admaif_mono_conv_text),
811                 tegra_admaif_mono_conv_text);
812
813 static const struct soc_enum tegra_admaif_stereo_conv_enum =
814         SOC_ENUM_SINGLE(SND_SOC_NOPM, 0,
815                 ARRAY_SIZE(tegra_admaif_stereo_conv_text),
816                 tegra_admaif_stereo_conv_text);
817
818 #define TEGRA210_ADMAIF_CHANNEL_CTRL(reg) \
819         SOC_SINGLE_EXT("ADMAIF" #reg " Channels", reg - 1, 0, 16, 0, \
820                 tegra210_admaif_get_format, tegra210_admaif_put_format)
821
822 #define TEGRA210_ADMAIF_TX_CIF_CTRL(reg) \
823         SOC_ENUM_EXT("ADMAIF" #reg " TX mono to stereo conv", \
824                  tegra_admaif_mono_conv_enum, tegra210_admaif_get_format, \
825                  tegra210_admaif_put_format)
826
827 #define TEGRA210_ADMAIF_RX_CIF_CTRL(reg) \
828         SOC_ENUM_EXT("ADMAIF" #reg " RX stereo to mono conv", \
829                  tegra_admaif_stereo_conv_enum, tegra210_admaif_get_format, \
830                  tegra210_admaif_put_format)
831
832 static struct snd_kcontrol_new tegra210_admaif_controls[] = {
833         TEGRA210_ADMAIF_CHANNEL_CTRL(1),
834         TEGRA210_ADMAIF_CHANNEL_CTRL(2),
835         TEGRA210_ADMAIF_CHANNEL_CTRL(3),
836         TEGRA210_ADMAIF_CHANNEL_CTRL(4),
837         TEGRA210_ADMAIF_CHANNEL_CTRL(5),
838         TEGRA210_ADMAIF_CHANNEL_CTRL(6),
839         TEGRA210_ADMAIF_CHANNEL_CTRL(7),
840         TEGRA210_ADMAIF_CHANNEL_CTRL(8),
841         TEGRA210_ADMAIF_CHANNEL_CTRL(9),
842         TEGRA210_ADMAIF_CHANNEL_CTRL(10),
843 #if defined(CONFIG_ARCH_TEGRA_18x_SOC)
844         TEGRA210_ADMAIF_CHANNEL_CTRL(11),
845         TEGRA210_ADMAIF_CHANNEL_CTRL(12),
846         TEGRA210_ADMAIF_CHANNEL_CTRL(13),
847         TEGRA210_ADMAIF_CHANNEL_CTRL(14),
848         TEGRA210_ADMAIF_CHANNEL_CTRL(15),
849         TEGRA210_ADMAIF_CHANNEL_CTRL(16),
850         TEGRA210_ADMAIF_CHANNEL_CTRL(17),
851         TEGRA210_ADMAIF_CHANNEL_CTRL(18),
852         TEGRA210_ADMAIF_CHANNEL_CTRL(19),
853         TEGRA210_ADMAIF_CHANNEL_CTRL(20),
854 #endif
855         TEGRA210_ADMAIF_RX_CIF_CTRL(1),
856         TEGRA210_ADMAIF_RX_CIF_CTRL(2),
857         TEGRA210_ADMAIF_RX_CIF_CTRL(3),
858         TEGRA210_ADMAIF_RX_CIF_CTRL(4),
859         TEGRA210_ADMAIF_RX_CIF_CTRL(5),
860         TEGRA210_ADMAIF_RX_CIF_CTRL(6),
861         TEGRA210_ADMAIF_RX_CIF_CTRL(7),
862         TEGRA210_ADMAIF_RX_CIF_CTRL(8),
863         TEGRA210_ADMAIF_RX_CIF_CTRL(9),
864         TEGRA210_ADMAIF_RX_CIF_CTRL(10),
865 #if defined(CONFIG_ARCH_TEGRA_18x_SOC)
866         TEGRA210_ADMAIF_RX_CIF_CTRL(11),
867         TEGRA210_ADMAIF_RX_CIF_CTRL(12),
868         TEGRA210_ADMAIF_RX_CIF_CTRL(13),
869         TEGRA210_ADMAIF_RX_CIF_CTRL(14),
870         TEGRA210_ADMAIF_RX_CIF_CTRL(15),
871         TEGRA210_ADMAIF_RX_CIF_CTRL(16),
872         TEGRA210_ADMAIF_RX_CIF_CTRL(17),
873         TEGRA210_ADMAIF_RX_CIF_CTRL(18),
874         TEGRA210_ADMAIF_RX_CIF_CTRL(19),
875         TEGRA210_ADMAIF_RX_CIF_CTRL(20),
876 #endif
877         TEGRA210_ADMAIF_TX_CIF_CTRL(1),
878         TEGRA210_ADMAIF_TX_CIF_CTRL(2),
879         TEGRA210_ADMAIF_TX_CIF_CTRL(3),
880         TEGRA210_ADMAIF_TX_CIF_CTRL(4),
881         TEGRA210_ADMAIF_TX_CIF_CTRL(5),
882         TEGRA210_ADMAIF_TX_CIF_CTRL(6),
883         TEGRA210_ADMAIF_TX_CIF_CTRL(7),
884         TEGRA210_ADMAIF_TX_CIF_CTRL(8),
885         TEGRA210_ADMAIF_TX_CIF_CTRL(9),
886         TEGRA210_ADMAIF_TX_CIF_CTRL(10),
887 #if defined(CONFIG_ARCH_TEGRA_18x_SOC)
888         TEGRA210_ADMAIF_TX_CIF_CTRL(11),
889         TEGRA210_ADMAIF_TX_CIF_CTRL(12),
890         TEGRA210_ADMAIF_TX_CIF_CTRL(13),
891         TEGRA210_ADMAIF_TX_CIF_CTRL(14),
892         TEGRA210_ADMAIF_TX_CIF_CTRL(15),
893         TEGRA210_ADMAIF_TX_CIF_CTRL(16),
894         TEGRA210_ADMAIF_TX_CIF_CTRL(17),
895         TEGRA210_ADMAIF_TX_CIF_CTRL(18),
896         TEGRA210_ADMAIF_TX_CIF_CTRL(19),
897         TEGRA210_ADMAIF_TX_CIF_CTRL(20),
898 #endif
899 };
900
901 static int tegra210_admaif_codec_probe(struct snd_soc_codec *codec)
902 {
903         struct tegra210_admaif *admaif = snd_soc_codec_get_drvdata(codec);
904
905         codec->control_data = admaif->regmap;
906
907         return 0;
908 }
909
910 static struct snd_soc_codec_driver tegra210_admaif_codec = {
911         .probe = tegra210_admaif_codec_probe,
912         .dapm_widgets = tegra210_admaif_widgets,
913         .num_dapm_widgets = TEGRA210_ADMAIF_CHANNEL_COUNT * 4,
914         .dapm_routes = tegra210_admaif_routes,
915         .num_dapm_routes = TEGRA210_ADMAIF_CHANNEL_COUNT * 6,
916         .controls = tegra210_admaif_controls,
917         .num_controls = ARRAY_SIZE(tegra210_admaif_controls),
918         .idle_bias_off = 1,
919 };
920
921 static const struct snd_soc_component_driver tegra210_admaif_dai_driver = {
922         .name           = DRV_NAME,
923 };
924
925 static struct tegra210_admaif_soc_data soc_data_tegra210 = {
926         .num_ch = TEGRA210_ADMAIF_CHANNEL_COUNT,
927         .set_audio_cif = tegra210_xbar_set_cif,
928 };
929
930 static const struct of_device_id tegra210_admaif_of_match[] = {
931         { .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
932         {},
933 };
934
935 static int tegra210_admaif_probe(struct platform_device *pdev)
936 {
937         int i;
938
939         int ret;
940         struct tegra210_admaif *admaif;
941         void __iomem *regs;
942         struct resource *res;
943         const struct of_device_id *match;
944         struct tegra210_admaif_soc_data *soc_data;
945         unsigned int buffer_size;
946
947         match = of_match_device(tegra210_admaif_of_match, &pdev->dev);
948         if (!match) {
949                 dev_err(&pdev->dev, "Error: No device match found\n");
950                 return -ENODEV;
951         }
952         soc_data = (struct tegra210_admaif_soc_data *)match->data;
953
954         admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
955         if (!admaif) {
956                 dev_err(&pdev->dev, "Can't allocate tegra210_admaif\n");
957                 ret = -ENOMEM;
958                 goto err;
959         }
960
961         admaif->refcnt = 0;
962
963         admaif->soc_data = soc_data;
964         admaif->is_shutdown = false;
965
966         admaif->capture_dma_data = devm_kzalloc(&pdev->dev,
967                         sizeof(struct tegra_alt_pcm_dma_params) *
968                                 admaif->soc_data->num_ch,
969                         GFP_KERNEL);
970         if (!admaif->capture_dma_data) {
971                 dev_err(&pdev->dev, "Can't allocate capture_dma_data\n");
972                 ret = -ENOMEM;
973                 goto err;
974         }
975
976         admaif->playback_dma_data = devm_kzalloc(&pdev->dev,
977                         sizeof(struct tegra_alt_pcm_dma_params) *
978                                 admaif->soc_data->num_ch,
979                         GFP_KERNEL);
980         if (!admaif->playback_dma_data) {
981                 dev_err(&pdev->dev, "Can't allocate playback_dma_data\n");
982                 ret = -ENOMEM;
983                 goto err;
984         }
985
986         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
987         if (!res) {
988                 dev_err(&pdev->dev, "No memory resource for admaif\n");
989                 ret = -ENODEV;
990                 goto err;
991         }
992
993         regs = devm_ioremap_resource(&pdev->dev, res);
994         if (!regs) {
995                 dev_err(&pdev->dev, "request/iomap region failed\n");
996                 ret = -ENODEV;
997                 goto err;
998         }
999
1000         admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
1001                                         &tegra210_admaif_regmap_config);
1002         if (IS_ERR(admaif->regmap)) {
1003                 dev_err(&pdev->dev, "regmap init failed\n");
1004                 ret = PTR_ERR(admaif->regmap);
1005                 goto err;
1006         }
1007         regcache_cache_only(admaif->regmap, true);
1008
1009         pm_runtime_enable(&pdev->dev);
1010         if (!pm_runtime_enabled(&pdev->dev)) {
1011                 ret = tegra210_admaif_runtime_resume(&pdev->dev);
1012                 if (ret)
1013                         goto err_pm_disable;
1014         }
1015
1016         if (admaif->soc_data->is_isomgr_client)
1017                 tegra_isomgr_adma_register();
1018
1019         for (i = 0; i < admaif->soc_data->num_ch; i++) {
1020                 admaif->playback_dma_data[i].addr = res->start +
1021                                 TEGRA210_ADMAIF_XBAR_TX_FIFO_WRITE +
1022                                 (i * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
1023
1024                 admaif->capture_dma_data[i].addr = res->start +
1025                                 TEGRA210_ADMAIF_XBAR_RX_FIFO_READ +
1026                                 (i * TEGRA210_ADMAIF_CHANNEL_REG_STRIDE);
1027
1028                 admaif->playback_dma_data[i].wrap = 4;
1029                 admaif->playback_dma_data[i].width = 32;
1030                 admaif->playback_dma_data[i].req_sel = i + 1;
1031                 if (of_property_read_string_index(pdev->dev.of_node,
1032                                 "dma-names",
1033                                 (i * 2) + 1,
1034                                 &admaif->playback_dma_data[i].chan_name) < 0) {
1035                         dev_err(&pdev->dev,
1036                                 "Missing property nvidia,dma-names\n");
1037                         ret = -ENODEV;
1038                         goto err_suspend;
1039                 }
1040                 buffer_size = 0;
1041                 if (of_property_read_u32_index(pdev->dev.of_node,
1042                                 "dma-buffer-size",
1043                                 (i * 2) + 1,
1044                                 &buffer_size) < 0) {
1045                         dev_dbg(&pdev->dev,
1046                                 "Missing property nvidia,dma-buffer-size\n");
1047                 }
1048                 admaif->playback_dma_data[i].buffer_size = buffer_size;
1049
1050                 admaif->capture_dma_data[i].wrap = 4;
1051                 admaif->capture_dma_data[i].width = 32;
1052                 admaif->capture_dma_data[i].req_sel = i + 1;
1053                 if (of_property_read_string_index(pdev->dev.of_node,
1054                                 "dma-names",
1055                                 (i * 2),
1056                                 &admaif->capture_dma_data[i].chan_name) < 0) {
1057                         dev_err(&pdev->dev,
1058                                 "Missing property nvidia,dma-names\n");
1059                         ret = -ENODEV;
1060                         goto err_suspend;
1061                 }
1062                 buffer_size = 0;
1063                 if (of_property_read_u32_index(pdev->dev.of_node,
1064                                 "dma-buffer-size",
1065                                 (i * 2),
1066                                 &buffer_size) < 0) {
1067                         dev_dbg(&pdev->dev,
1068                                 "Missing property nvidia,dma-buffer-size\n");
1069                 }
1070                 admaif->capture_dma_data[i].buffer_size = buffer_size;
1071         }
1072
1073         ret = snd_soc_register_component(&pdev->dev,
1074                                         &tegra210_admaif_dai_driver,
1075                                         tegra210_admaif_dais,
1076                                         admaif->soc_data->num_ch);
1077         if (ret) {
1078                 dev_err(&pdev->dev, "Could not register DAIs %d: %d\n",
1079                         i, ret);
1080                 ret = -ENOMEM;
1081                 goto err_suspend;
1082         }
1083
1084         ret = snd_soc_register_codec(&pdev->dev, &tegra210_admaif_codec,
1085                                 tegra210_admaif_codec_dais,
1086                                 admaif->soc_data->num_ch * 2);
1087         if (ret != 0) {
1088                 dev_err(&pdev->dev, "Could not register CODEC: %d\n", ret);
1089                 goto err_unregister_dais;
1090         }
1091
1092         ret = tegra_alt_pcm_platform_register(&pdev->dev);
1093         if (ret) {
1094                 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
1095                 goto err_unregister_codec;
1096         }
1097
1098         regmap_update_bits(admaif->regmap,
1099                                 TEGRA210_ADMAIF_GLOBAL_ENABLE, 1, 1);
1100
1101         dev_set_drvdata(&pdev->dev, admaif);
1102
1103         return 0;
1104
1105 err_unregister_codec:
1106         snd_soc_unregister_codec(&pdev->dev);
1107 err_unregister_dais:
1108         snd_soc_unregister_component(&pdev->dev);
1109 err_suspend:
1110         if (!pm_runtime_status_suspended(&pdev->dev))
1111                 tegra210_admaif_runtime_suspend(&pdev->dev);
1112 err_pm_disable:
1113         pm_runtime_disable(&pdev->dev);
1114 err:
1115         return ret;
1116 }
1117
1118 static void tegra210_admaif_platform_shutdown(struct platform_device *pdev)
1119 {
1120         struct tegra210_admaif *admaif = dev_get_drvdata(&pdev->dev);
1121
1122         admaif->is_shutdown = true;
1123 }
1124
1125 static int tegra210_admaif_remove(struct platform_device *pdev)
1126 {
1127         struct tegra210_admaif *admaif =  dev_get_drvdata(&pdev->dev);
1128
1129         if (admaif->soc_data->is_isomgr_client)
1130                 tegra_isomgr_adma_unregister();
1131
1132         snd_soc_unregister_component(&pdev->dev);
1133
1134         snd_soc_unregister_codec(&pdev->dev);
1135
1136         tegra_alt_pcm_platform_unregister(&pdev->dev);
1137
1138         pm_runtime_disable(&pdev->dev);
1139         if (!pm_runtime_status_suspended(&pdev->dev))
1140                 tegra210_admaif_runtime_suspend(&pdev->dev);
1141
1142         return 0;
1143 }
1144
1145 static const struct dev_pm_ops tegra210_admaif_pm_ops = {
1146         SET_RUNTIME_PM_OPS(tegra210_admaif_runtime_suspend,
1147                            tegra210_admaif_runtime_resume, NULL)
1148         SET_SYSTEM_SLEEP_PM_OPS(tegra210_admaif_suspend, NULL)
1149 };
1150
1151 static struct platform_driver tegra210_admaif_driver = {
1152         .probe = tegra210_admaif_probe,
1153         .remove = tegra210_admaif_remove,
1154         .shutdown = tegra210_admaif_platform_shutdown,
1155         .driver = {
1156                 .name = DRV_NAME,
1157                 .owner = THIS_MODULE,
1158                 .of_match_table = tegra210_admaif_of_match,
1159                 .pm = &tegra210_admaif_pm_ops,
1160         },
1161 };
1162 module_platform_driver(tegra210_admaif_driver);
1163
1164 MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>");
1165 MODULE_DESCRIPTION("Tegra210 ADMAIF driver");
1166 MODULE_LICENSE("GPL v2");
1167 MODULE_ALIAS("platform:" DRV_NAME);