powerpc/perf/hv-24x7: Move cpumask file to top folder of hv-24x7 driver
[linux-2.6-microblaze.git] / sound / soc / tegra / tegra210_admaif.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // tegra210_admaif.c - Tegra ADMAIF driver
4 //
5 // Copyright (c) 2020 NVIDIA CORPORATION.  All rights reserved.
6
7 #include <linux/clk.h>
8 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/of_platform.h>
11 #include <linux/platform_device.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/regmap.h>
14 #include <sound/pcm_params.h>
15 #include <sound/soc.h>
16 #include "tegra210_admaif.h"
17 #include "tegra_cif.h"
18 #include "tegra_pcm.h"
19
20 #define CH_REG(offset, reg, id)                                                \
21         ((offset) + (reg) + (TEGRA_ADMAIF_CHANNEL_REG_STRIDE * (id)))
22
23 #define CH_TX_REG(reg, id) CH_REG(admaif->soc_data->tx_base, reg, id)
24
25 #define CH_RX_REG(reg, id) CH_REG(admaif->soc_data->rx_base, reg, id)
26
27 #define REG_DEFAULTS(id, rx_ctrl, tx_ctrl, tx_base, rx_base)                   \
28         { CH_REG(rx_base, TEGRA_ADMAIF_RX_INT_MASK, id), 0x00000001 },         \
29         { CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), 0x00007700 },     \
30         { CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl },           \
31         { CH_REG(tx_base, TEGRA_ADMAIF_TX_INT_MASK, id), 0x00000001 },         \
32         { CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), 0x00007700 },     \
33         { CH_REG(tx_base, TEGRA_ADMAIF_TX_FIFO_CTRL, id), tx_ctrl }
34
35 #define ADMAIF_REG_DEFAULTS(id, chip)                                          \
36         REG_DEFAULTS((id) - 1,                                                 \
37                 chip ## _ADMAIF_RX ## id ## _FIFO_CTRL_REG_DEFAULT,            \
38                 chip ## _ADMAIF_TX ## id ## _FIFO_CTRL_REG_DEFAULT,            \
39                 chip ## _ADMAIF_TX_BASE,                                       \
40                 chip ## _ADMAIF_RX_BASE)
41
42 static const struct reg_default tegra186_admaif_reg_defaults[] = {
43         {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA186_ADMAIF_GLOBAL_BASE), 0x00000003},
44         ADMAIF_REG_DEFAULTS(1, TEGRA186),
45         ADMAIF_REG_DEFAULTS(2, TEGRA186),
46         ADMAIF_REG_DEFAULTS(3, TEGRA186),
47         ADMAIF_REG_DEFAULTS(4, TEGRA186),
48         ADMAIF_REG_DEFAULTS(5, TEGRA186),
49         ADMAIF_REG_DEFAULTS(6, TEGRA186),
50         ADMAIF_REG_DEFAULTS(7, TEGRA186),
51         ADMAIF_REG_DEFAULTS(8, TEGRA186),
52         ADMAIF_REG_DEFAULTS(9, TEGRA186),
53         ADMAIF_REG_DEFAULTS(10, TEGRA186),
54         ADMAIF_REG_DEFAULTS(11, TEGRA186),
55         ADMAIF_REG_DEFAULTS(12, TEGRA186),
56         ADMAIF_REG_DEFAULTS(13, TEGRA186),
57         ADMAIF_REG_DEFAULTS(14, TEGRA186),
58         ADMAIF_REG_DEFAULTS(15, TEGRA186),
59         ADMAIF_REG_DEFAULTS(16, TEGRA186),
60         ADMAIF_REG_DEFAULTS(17, TEGRA186),
61         ADMAIF_REG_DEFAULTS(18, TEGRA186),
62         ADMAIF_REG_DEFAULTS(19, TEGRA186),
63         ADMAIF_REG_DEFAULTS(20, TEGRA186)
64 };
65
66 static const struct reg_default tegra210_admaif_reg_defaults[] = {
67         {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA210_ADMAIF_GLOBAL_BASE), 0x00000003},
68         ADMAIF_REG_DEFAULTS(1, TEGRA210),
69         ADMAIF_REG_DEFAULTS(2, TEGRA210),
70         ADMAIF_REG_DEFAULTS(3, TEGRA210),
71         ADMAIF_REG_DEFAULTS(4, TEGRA210),
72         ADMAIF_REG_DEFAULTS(5, TEGRA210),
73         ADMAIF_REG_DEFAULTS(6, TEGRA210),
74         ADMAIF_REG_DEFAULTS(7, TEGRA210),
75         ADMAIF_REG_DEFAULTS(8, TEGRA210),
76         ADMAIF_REG_DEFAULTS(9, TEGRA210),
77         ADMAIF_REG_DEFAULTS(10, TEGRA210)
78 };
79
80 static bool tegra_admaif_wr_reg(struct device *dev, unsigned int reg)
81 {
82         struct tegra_admaif *admaif = dev_get_drvdata(dev);
83         unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
84         unsigned int num_ch = admaif->soc_data->num_ch;
85         unsigned int rx_base = admaif->soc_data->rx_base;
86         unsigned int tx_base = admaif->soc_data->tx_base;
87         unsigned int global_base = admaif->soc_data->global_base;
88         unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
89         unsigned int rx_max = rx_base + (num_ch * ch_stride);
90         unsigned int tx_max = tx_base + (num_ch * ch_stride);
91
92         if ((reg >= rx_base) && (reg < rx_max)) {
93                 reg = (reg - rx_base) % ch_stride;
94                 if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
95                     (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) ||
96                     (reg == TEGRA_ADMAIF_RX_SOFT_RESET) ||
97                     (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL))
98                         return true;
99         } else if ((reg >= tx_base) && (reg < tx_max)) {
100                 reg = (reg - tx_base) % ch_stride;
101                 if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
102                     (reg == TEGRA_ADMAIF_TX_FIFO_CTRL) ||
103                     (reg == TEGRA_ADMAIF_TX_SOFT_RESET) ||
104                     (reg == TEGRA_ADMAIF_CH_ACIF_TX_CTRL))
105                         return true;
106         } else if ((reg >= global_base) && (reg < reg_max)) {
107                 if (reg == (global_base + TEGRA_ADMAIF_GLOBAL_ENABLE))
108                         return true;
109         }
110
111         return false;
112 }
113
114 static bool tegra_admaif_rd_reg(struct device *dev, unsigned int reg)
115 {
116         struct tegra_admaif *admaif = dev_get_drvdata(dev);
117         unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
118         unsigned int num_ch = admaif->soc_data->num_ch;
119         unsigned int rx_base = admaif->soc_data->rx_base;
120         unsigned int tx_base = admaif->soc_data->tx_base;
121         unsigned int global_base = admaif->soc_data->global_base;
122         unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
123         unsigned int rx_max = rx_base + (num_ch * ch_stride);
124         unsigned int tx_max = tx_base + (num_ch * ch_stride);
125
126         if ((reg >= rx_base) && (reg < rx_max)) {
127                 reg = (reg - rx_base) % ch_stride;
128                 if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
129                     (reg == TEGRA_ADMAIF_RX_STATUS) ||
130                     (reg == TEGRA_ADMAIF_RX_INT_STATUS) ||
131                     (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) ||
132                     (reg == TEGRA_ADMAIF_RX_SOFT_RESET) ||
133                     (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL))
134                         return true;
135         } else if ((reg >= tx_base) && (reg < tx_max)) {
136                 reg = (reg - tx_base) % ch_stride;
137                 if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
138                     (reg == TEGRA_ADMAIF_TX_STATUS) ||
139                     (reg == TEGRA_ADMAIF_TX_INT_STATUS) ||
140                     (reg == TEGRA_ADMAIF_TX_FIFO_CTRL) ||
141                     (reg == TEGRA_ADMAIF_TX_SOFT_RESET) ||
142                     (reg == TEGRA_ADMAIF_CH_ACIF_TX_CTRL))
143                         return true;
144         } else if ((reg >= global_base) && (reg < reg_max)) {
145                 if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_ENABLE)) ||
146                     (reg == (global_base + TEGRA_ADMAIF_GLOBAL_CG_0)) ||
147                     (reg == (global_base + TEGRA_ADMAIF_GLOBAL_STATUS)) ||
148                     (reg == (global_base +
149                                 TEGRA_ADMAIF_GLOBAL_RX_ENABLE_STATUS)) ||
150                     (reg == (global_base +
151                                 TEGRA_ADMAIF_GLOBAL_TX_ENABLE_STATUS)))
152                         return true;
153         }
154
155         return false;
156 }
157
158 static bool tegra_admaif_volatile_reg(struct device *dev, unsigned int reg)
159 {
160         struct tegra_admaif *admaif = dev_get_drvdata(dev);
161         unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
162         unsigned int num_ch = admaif->soc_data->num_ch;
163         unsigned int rx_base = admaif->soc_data->rx_base;
164         unsigned int tx_base = admaif->soc_data->tx_base;
165         unsigned int global_base = admaif->soc_data->global_base;
166         unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
167         unsigned int rx_max = rx_base + (num_ch * ch_stride);
168         unsigned int tx_max = tx_base + (num_ch * ch_stride);
169
170         if ((reg >= rx_base) && (reg < rx_max)) {
171                 reg = (reg - rx_base) % ch_stride;
172                 if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
173                     (reg == TEGRA_ADMAIF_RX_STATUS) ||
174                     (reg == TEGRA_ADMAIF_RX_INT_STATUS) ||
175                     (reg == TEGRA_ADMAIF_RX_SOFT_RESET))
176                         return true;
177         } else if ((reg >= tx_base) && (reg < tx_max)) {
178                 reg = (reg - tx_base) % ch_stride;
179                 if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
180                     (reg == TEGRA_ADMAIF_TX_STATUS) ||
181                     (reg == TEGRA_ADMAIF_TX_INT_STATUS) ||
182                     (reg == TEGRA_ADMAIF_TX_SOFT_RESET))
183                         return true;
184         } else if ((reg >= global_base) && (reg < reg_max)) {
185                 if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_STATUS)) ||
186                     (reg == (global_base +
187                                 TEGRA_ADMAIF_GLOBAL_RX_ENABLE_STATUS)) ||
188                     (reg == (global_base +
189                                 TEGRA_ADMAIF_GLOBAL_TX_ENABLE_STATUS)))
190                         return true;
191         }
192
193         return false;
194 }
195
196 static const struct regmap_config tegra210_admaif_regmap_config = {
197         .reg_bits               = 32,
198         .reg_stride             = 4,
199         .val_bits               = 32,
200         .max_register           = TEGRA210_ADMAIF_LAST_REG,
201         .writeable_reg          = tegra_admaif_wr_reg,
202         .readable_reg           = tegra_admaif_rd_reg,
203         .volatile_reg           = tegra_admaif_volatile_reg,
204         .reg_defaults           = tegra210_admaif_reg_defaults,
205         .num_reg_defaults       = TEGRA210_ADMAIF_CHANNEL_COUNT * 6 + 1,
206         .cache_type             = REGCACHE_FLAT,
207 };
208
209 static const struct regmap_config tegra186_admaif_regmap_config = {
210         .reg_bits               = 32,
211         .reg_stride             = 4,
212         .val_bits               = 32,
213         .max_register           = TEGRA186_ADMAIF_LAST_REG,
214         .writeable_reg          = tegra_admaif_wr_reg,
215         .readable_reg           = tegra_admaif_rd_reg,
216         .volatile_reg           = tegra_admaif_volatile_reg,
217         .reg_defaults           = tegra186_admaif_reg_defaults,
218         .num_reg_defaults       = TEGRA186_ADMAIF_CHANNEL_COUNT * 6 + 1,
219         .cache_type             = REGCACHE_FLAT,
220 };
221
222 static int tegra_admaif_runtime_suspend(struct device *dev)
223 {
224         struct tegra_admaif *admaif = dev_get_drvdata(dev);
225
226         regcache_cache_only(admaif->regmap, true);
227         regcache_mark_dirty(admaif->regmap);
228
229         return 0;
230 }
231
232 static int tegra_admaif_runtime_resume(struct device *dev)
233 {
234         struct tegra_admaif *admaif = dev_get_drvdata(dev);
235
236         regcache_cache_only(admaif->regmap, false);
237         regcache_sync(admaif->regmap);
238
239         return 0;
240 }
241
242 static int tegra_admaif_set_pack_mode(struct regmap *map, unsigned int reg,
243                                       int valid_bit)
244 {
245         switch (valid_bit) {
246         case DATA_8BIT:
247                 regmap_update_bits(map, reg, PACK8_EN_MASK, PACK8_EN);
248                 regmap_update_bits(map, reg, PACK16_EN_MASK, 0);
249                 break;
250         case DATA_16BIT:
251                 regmap_update_bits(map, reg, PACK16_EN_MASK, PACK16_EN);
252                 regmap_update_bits(map, reg, PACK8_EN_MASK, 0);
253                 break;
254         case DATA_32BIT:
255                 regmap_update_bits(map, reg, PACK16_EN_MASK, 0);
256                 regmap_update_bits(map, reg, PACK8_EN_MASK, 0);
257                 break;
258         default:
259                 return -EINVAL;
260         }
261
262         return 0;
263 }
264
265 static int tegra_admaif_hw_params(struct snd_pcm_substream *substream,
266                                   struct snd_pcm_hw_params *params,
267                                   struct snd_soc_dai *dai)
268 {
269         struct device *dev = dai->dev;
270         struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
271         struct tegra_cif_conf cif_conf;
272         unsigned int reg, path;
273         int valid_bit, channels;
274
275         memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
276
277         switch (params_format(params)) {
278         case SNDRV_PCM_FORMAT_S8:
279                 cif_conf.audio_bits = TEGRA_ACIF_BITS_8;
280                 cif_conf.client_bits = TEGRA_ACIF_BITS_8;
281                 valid_bit = DATA_8BIT;
282                 break;
283         case SNDRV_PCM_FORMAT_S16_LE:
284                 cif_conf.audio_bits = TEGRA_ACIF_BITS_16;
285                 cif_conf.client_bits = TEGRA_ACIF_BITS_16;
286                 valid_bit = DATA_16BIT;
287                 break;
288         case SNDRV_PCM_FORMAT_S32_LE:
289                 cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
290                 cif_conf.client_bits = TEGRA_ACIF_BITS_32;
291                 valid_bit  = DATA_32BIT;
292                 break;
293         default:
294                 dev_err(dev, "unsupported format!\n");
295                 return -EOPNOTSUPP;
296         }
297
298         channels = params_channels(params);
299         cif_conf.client_ch = channels;
300         cif_conf.audio_ch = channels;
301
302         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
303                 path = ADMAIF_TX_PATH;
304                 reg = CH_TX_REG(TEGRA_ADMAIF_CH_ACIF_TX_CTRL, dai->id);
305         } else {
306                 path = ADMAIF_RX_PATH;
307                 reg = CH_RX_REG(TEGRA_ADMAIF_CH_ACIF_RX_CTRL, dai->id);
308         }
309
310         cif_conf.mono_conv = admaif->mono_to_stereo[path][dai->id];
311         cif_conf.stereo_conv = admaif->stereo_to_mono[path][dai->id];
312
313         tegra_admaif_set_pack_mode(admaif->regmap, reg, valid_bit);
314
315         tegra_set_cif(admaif->regmap, reg, &cif_conf);
316
317         return 0;
318 }
319
320 static int tegra_admaif_start(struct snd_soc_dai *dai, int direction)
321 {
322         struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
323         unsigned int reg, mask, val;
324
325         switch (direction) {
326         case SNDRV_PCM_STREAM_PLAYBACK:
327                 mask = TX_ENABLE_MASK;
328                 val = TX_ENABLE;
329                 reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
330                 break;
331         case SNDRV_PCM_STREAM_CAPTURE:
332                 mask = RX_ENABLE_MASK;
333                 val = RX_ENABLE;
334                 reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
335                 break;
336         default:
337                 return -EINVAL;
338         }
339
340         regmap_update_bits(admaif->regmap, reg, mask, val);
341
342         return 0;
343 }
344
345 static int tegra_admaif_stop(struct snd_soc_dai *dai, int direction)
346 {
347         struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
348         unsigned int enable_reg, status_reg, reset_reg, mask, val;
349         char *dir_name;
350         int err, enable;
351
352         switch (direction) {
353         case SNDRV_PCM_STREAM_PLAYBACK:
354                 mask = TX_ENABLE_MASK;
355                 enable = TX_ENABLE;
356                 dir_name = "TX";
357                 enable_reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
358                 status_reg = CH_TX_REG(TEGRA_ADMAIF_TX_STATUS, dai->id);
359                 reset_reg = CH_TX_REG(TEGRA_ADMAIF_TX_SOFT_RESET, dai->id);
360                 break;
361         case SNDRV_PCM_STREAM_CAPTURE:
362                 mask = RX_ENABLE_MASK;
363                 enable = RX_ENABLE;
364                 dir_name = "RX";
365                 enable_reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
366                 status_reg = CH_RX_REG(TEGRA_ADMAIF_RX_STATUS, dai->id);
367                 reset_reg = CH_RX_REG(TEGRA_ADMAIF_RX_SOFT_RESET, dai->id);
368                 break;
369         default:
370                 return -EINVAL;
371         }
372
373         /* Disable TX/RX channel */
374         regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable);
375
376         /* Wait until ADMAIF TX/RX status is disabled */
377         err = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val,
378                                               !(val & enable), 10, 10000);
379         if (err < 0)
380                 dev_warn(dai->dev, "timeout: failed to disable ADMAIF%d_%s\n",
381                          dai->id + 1, dir_name);
382
383         /* SW reset */
384         regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET);
385
386         /* Wait till SW reset is complete */
387         err = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val,
388                                               !(val & SW_RESET_MASK & SW_RESET),
389                                               10, 10000);
390         if (err) {
391                 dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n",
392                         dai->id + 1, dir_name);
393                 return err;
394         }
395
396         return 0;
397 }
398
399 static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
400                                 struct snd_soc_dai *dai)
401 {
402         int err;
403
404         err = snd_dmaengine_pcm_trigger(substream, cmd);
405         if (err)
406                 return err;
407
408         switch (cmd) {
409         case SNDRV_PCM_TRIGGER_START:
410         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
411         case SNDRV_PCM_TRIGGER_RESUME:
412                 return tegra_admaif_start(dai, substream->stream);
413         case SNDRV_PCM_TRIGGER_STOP:
414         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
415         case SNDRV_PCM_TRIGGER_SUSPEND:
416                 return tegra_admaif_stop(dai, substream->stream);
417         default:
418                 return -EINVAL;
419         }
420 }
421
422 static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
423         .hw_params      = tegra_admaif_hw_params,
424         .trigger        = tegra_admaif_trigger,
425 };
426
427 static int tegra_admaif_get_control(struct snd_kcontrol *kcontrol,
428                                     struct snd_ctl_elem_value *ucontrol)
429 {
430         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
431         struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
432         struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
433         long *uctl_val = &ucontrol->value.integer.value[0];
434
435         if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
436                 *uctl_val = admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
437         else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
438                 *uctl_val = admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
439         else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
440                 *uctl_val = admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
441         else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
442                 *uctl_val = admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
443
444         return 0;
445 }
446
447 static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol,
448                                     struct snd_ctl_elem_value *ucontrol)
449 {
450         struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
451         struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
452         struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
453         int value = ucontrol->value.integer.value[0];
454
455         if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
456                 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
457         else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
458                 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
459         else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
460                 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
461         else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
462                 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
463
464         return 0;
465 }
466
467 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
468 {
469         struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
470
471         dai->capture_dma_data = &admaif->capture_dma_data[dai->id];
472         dai->playback_dma_data = &admaif->playback_dma_data[dai->id];
473
474         return 0;
475 }
476
477 #define DAI(dai_name)                                   \
478         {                                                       \
479                 .name = dai_name,                               \
480                 .probe = tegra_admaif_dai_probe,                \
481                 .playback = {                                   \
482                         .stream_name = dai_name " Playback",    \
483                         .channels_min = 1,                      \
484                         .channels_max = 16,                     \
485                         .rates = SNDRV_PCM_RATE_8000_192000,    \
486                         .formats = SNDRV_PCM_FMTBIT_S8 |        \
487                                 SNDRV_PCM_FMTBIT_S16_LE |       \
488                                 SNDRV_PCM_FMTBIT_S32_LE,        \
489                 },                                              \
490                 .capture = {                                    \
491                         .stream_name = dai_name " Capture",     \
492                         .channels_min = 1,                      \
493                         .channels_max = 16,                     \
494                         .rates = SNDRV_PCM_RATE_8000_192000,    \
495                         .formats = SNDRV_PCM_FMTBIT_S8 |        \
496                                 SNDRV_PCM_FMTBIT_S16_LE |       \
497                                 SNDRV_PCM_FMTBIT_S32_LE,        \
498                 },                                              \
499                 .ops = &tegra_admaif_dai_ops,                   \
500         }
501
502 static struct snd_soc_dai_driver tegra210_admaif_cmpnt_dais[] = {
503         DAI("ADMAIF1"),
504         DAI("ADMAIF2"),
505         DAI("ADMAIF3"),
506         DAI("ADMAIF4"),
507         DAI("ADMAIF5"),
508         DAI("ADMAIF6"),
509         DAI("ADMAIF7"),
510         DAI("ADMAIF8"),
511         DAI("ADMAIF9"),
512         DAI("ADMAIF10"),
513 };
514
515 static struct snd_soc_dai_driver tegra186_admaif_cmpnt_dais[] = {
516         DAI("ADMAIF1"),
517         DAI("ADMAIF2"),
518         DAI("ADMAIF3"),
519         DAI("ADMAIF4"),
520         DAI("ADMAIF5"),
521         DAI("ADMAIF6"),
522         DAI("ADMAIF7"),
523         DAI("ADMAIF8"),
524         DAI("ADMAIF9"),
525         DAI("ADMAIF10"),
526         DAI("ADMAIF11"),
527         DAI("ADMAIF12"),
528         DAI("ADMAIF13"),
529         DAI("ADMAIF14"),
530         DAI("ADMAIF15"),
531         DAI("ADMAIF16"),
532         DAI("ADMAIF17"),
533         DAI("ADMAIF18"),
534         DAI("ADMAIF19"),
535         DAI("ADMAIF20"),
536 };
537
538 static const char * const tegra_admaif_stereo_conv_text[] = {
539         "CH0", "CH1", "AVG",
540 };
541
542 static const char * const tegra_admaif_mono_conv_text[] = {
543         "Zero", "Copy",
544 };
545
546 /*
547  * Below macro is added to avoid looping over all ADMAIFx controls related
548  * to mono/stereo conversions in get()/put() callbacks.
549  */
550 #define NV_SOC_ENUM_EXT(xname, xreg, xhandler_get, xhandler_put, xenum_text)   \
551 {                                                                              \
552         .iface = SNDRV_CTL_ELEM_IFACE_MIXER,                                   \
553         .info = snd_soc_info_enum_double,                                      \
554         .name = xname,                                                         \
555         .get = xhandler_get,                                                   \
556         .put = xhandler_put,                                                   \
557         .private_value = (unsigned long)&(struct soc_enum)                     \
558                 SOC_ENUM_SINGLE(xreg, 0, ARRAY_SIZE(xenum_text), xenum_text)   \
559 }
560
561 #define TEGRA_ADMAIF_CIF_CTRL(reg)                                             \
562         NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1,\
563                         tegra_admaif_get_control, tegra_admaif_put_control,    \
564                         tegra_admaif_mono_conv_text),                          \
565         NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1,\
566                         tegra_admaif_get_control, tegra_admaif_put_control,    \
567                         tegra_admaif_stereo_conv_text),                        \
568         NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \
569                         tegra_admaif_get_control, tegra_admaif_put_control,    \
570                         tegra_admaif_mono_conv_text),                          \
571         NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \
572                         tegra_admaif_get_control, tegra_admaif_put_control,    \
573                         tegra_admaif_stereo_conv_text)
574
575 static struct snd_kcontrol_new tegra210_admaif_controls[] = {
576         TEGRA_ADMAIF_CIF_CTRL(1),
577         TEGRA_ADMAIF_CIF_CTRL(2),
578         TEGRA_ADMAIF_CIF_CTRL(3),
579         TEGRA_ADMAIF_CIF_CTRL(4),
580         TEGRA_ADMAIF_CIF_CTRL(5),
581         TEGRA_ADMAIF_CIF_CTRL(6),
582         TEGRA_ADMAIF_CIF_CTRL(7),
583         TEGRA_ADMAIF_CIF_CTRL(8),
584         TEGRA_ADMAIF_CIF_CTRL(9),
585         TEGRA_ADMAIF_CIF_CTRL(10),
586 };
587
588 static struct snd_kcontrol_new tegra186_admaif_controls[] = {
589         TEGRA_ADMAIF_CIF_CTRL(1),
590         TEGRA_ADMAIF_CIF_CTRL(2),
591         TEGRA_ADMAIF_CIF_CTRL(3),
592         TEGRA_ADMAIF_CIF_CTRL(4),
593         TEGRA_ADMAIF_CIF_CTRL(5),
594         TEGRA_ADMAIF_CIF_CTRL(6),
595         TEGRA_ADMAIF_CIF_CTRL(7),
596         TEGRA_ADMAIF_CIF_CTRL(8),
597         TEGRA_ADMAIF_CIF_CTRL(9),
598         TEGRA_ADMAIF_CIF_CTRL(10),
599         TEGRA_ADMAIF_CIF_CTRL(11),
600         TEGRA_ADMAIF_CIF_CTRL(12),
601         TEGRA_ADMAIF_CIF_CTRL(13),
602         TEGRA_ADMAIF_CIF_CTRL(14),
603         TEGRA_ADMAIF_CIF_CTRL(15),
604         TEGRA_ADMAIF_CIF_CTRL(16),
605         TEGRA_ADMAIF_CIF_CTRL(17),
606         TEGRA_ADMAIF_CIF_CTRL(18),
607         TEGRA_ADMAIF_CIF_CTRL(19),
608         TEGRA_ADMAIF_CIF_CTRL(20),
609 };
610
611 static const struct snd_soc_component_driver tegra210_admaif_cmpnt = {
612         .controls               = tegra210_admaif_controls,
613         .num_controls           = ARRAY_SIZE(tegra210_admaif_controls),
614         .pcm_construct          = tegra_pcm_construct,
615         .pcm_destruct           = tegra_pcm_destruct,
616         .open                   = tegra_pcm_open,
617         .close                  = tegra_pcm_close,
618         .hw_params              = tegra_pcm_hw_params,
619         .hw_free                = tegra_pcm_hw_free,
620         .mmap                   = tegra_pcm_mmap,
621         .pointer                = tegra_pcm_pointer,
622 };
623
624 static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
625         .controls               = tegra186_admaif_controls,
626         .num_controls           = ARRAY_SIZE(tegra186_admaif_controls),
627         .pcm_construct          = tegra_pcm_construct,
628         .pcm_destruct           = tegra_pcm_destruct,
629         .open                   = tegra_pcm_open,
630         .close                  = tegra_pcm_close,
631         .hw_params              = tegra_pcm_hw_params,
632         .hw_free                = tegra_pcm_hw_free,
633         .mmap                   = tegra_pcm_mmap,
634         .pointer                = tegra_pcm_pointer,
635 };
636
637 static const struct tegra_admaif_soc_data soc_data_tegra210 = {
638         .num_ch         = TEGRA210_ADMAIF_CHANNEL_COUNT,
639         .cmpnt          = &tegra210_admaif_cmpnt,
640         .dais           = tegra210_admaif_cmpnt_dais,
641         .regmap_conf    = &tegra210_admaif_regmap_config,
642         .global_base    = TEGRA210_ADMAIF_GLOBAL_BASE,
643         .tx_base        = TEGRA210_ADMAIF_TX_BASE,
644         .rx_base        = TEGRA210_ADMAIF_RX_BASE,
645 };
646
647 static const struct tegra_admaif_soc_data soc_data_tegra186 = {
648         .num_ch         = TEGRA186_ADMAIF_CHANNEL_COUNT,
649         .cmpnt          = &tegra186_admaif_cmpnt,
650         .dais           = tegra186_admaif_cmpnt_dais,
651         .regmap_conf    = &tegra186_admaif_regmap_config,
652         .global_base    = TEGRA186_ADMAIF_GLOBAL_BASE,
653         .tx_base        = TEGRA186_ADMAIF_TX_BASE,
654         .rx_base        = TEGRA186_ADMAIF_RX_BASE,
655 };
656
657 static const struct of_device_id tegra_admaif_of_match[] = {
658         { .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
659         { .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 },
660         {},
661 };
662 MODULE_DEVICE_TABLE(of, tegra_admaif_of_match);
663
664 static int tegra_admaif_probe(struct platform_device *pdev)
665 {
666         struct tegra_admaif *admaif;
667         void __iomem *regs;
668         struct resource *res;
669         int err, i;
670
671         admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
672         if (!admaif)
673                 return -ENOMEM;
674
675         admaif->soc_data = of_device_get_match_data(&pdev->dev);
676
677         dev_set_drvdata(&pdev->dev, admaif);
678
679         admaif->capture_dma_data =
680                 devm_kcalloc(&pdev->dev,
681                              admaif->soc_data->num_ch,
682                              sizeof(struct snd_dmaengine_dai_dma_data),
683                              GFP_KERNEL);
684         if (!admaif->capture_dma_data)
685                 return -ENOMEM;
686
687         admaif->playback_dma_data =
688                 devm_kcalloc(&pdev->dev,
689                              admaif->soc_data->num_ch,
690                              sizeof(struct snd_dmaengine_dai_dma_data),
691                              GFP_KERNEL);
692         if (!admaif->playback_dma_data)
693                 return -ENOMEM;
694
695         for (i = 0; i < ADMAIF_PATHS; i++) {
696                 admaif->mono_to_stereo[i] =
697                         devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
698                                      sizeof(unsigned int), GFP_KERNEL);
699                 if (!admaif->mono_to_stereo[i])
700                         return -ENOMEM;
701
702                 admaif->stereo_to_mono[i] =
703                         devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
704                                      sizeof(unsigned int), GFP_KERNEL);
705                 if (!admaif->stereo_to_mono[i])
706                         return -ENOMEM;
707         }
708
709         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
710
711         regs = devm_ioremap_resource(&pdev->dev, res);
712         if (IS_ERR(regs))
713                 return PTR_ERR(regs);
714
715         admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
716                                                admaif->soc_data->regmap_conf);
717         if (IS_ERR(admaif->regmap)) {
718                 dev_err(&pdev->dev, "regmap init failed\n");
719                 return PTR_ERR(admaif->regmap);
720         }
721
722         regcache_cache_only(admaif->regmap, true);
723
724         regmap_update_bits(admaif->regmap, admaif->soc_data->global_base +
725                            TEGRA_ADMAIF_GLOBAL_ENABLE, 1, 1);
726
727         for (i = 0; i < admaif->soc_data->num_ch; i++) {
728                 admaif->playback_dma_data[i].addr = res->start +
729                         CH_TX_REG(TEGRA_ADMAIF_TX_FIFO_WRITE, i);
730
731                 admaif->capture_dma_data[i].addr = res->start +
732                         CH_RX_REG(TEGRA_ADMAIF_RX_FIFO_READ, i);
733
734                 admaif->playback_dma_data[i].addr_width = 32;
735
736                 if (of_property_read_string_index(pdev->dev.of_node,
737                                 "dma-names", (i * 2) + 1,
738                                 &admaif->playback_dma_data[i].chan_name) < 0) {
739                         dev_err(&pdev->dev,
740                                 "missing property nvidia,dma-names\n");
741
742                         return -ENODEV;
743                 }
744
745                 admaif->capture_dma_data[i].addr_width = 32;
746
747                 if (of_property_read_string_index(pdev->dev.of_node,
748                                 "dma-names",
749                                 (i * 2),
750                                 &admaif->capture_dma_data[i].chan_name) < 0) {
751                         dev_err(&pdev->dev,
752                                 "missing property nvidia,dma-names\n");
753
754                         return -ENODEV;
755                 }
756         }
757
758         err = devm_snd_soc_register_component(&pdev->dev,
759                                               admaif->soc_data->cmpnt,
760                                               admaif->soc_data->dais,
761                                               admaif->soc_data->num_ch);
762         if (err) {
763                 dev_err(&pdev->dev,
764                         "can't register ADMAIF component, err: %d\n", err);
765                 return err;
766         }
767
768         pm_runtime_enable(&pdev->dev);
769
770         return 0;
771 }
772
773 static int tegra_admaif_remove(struct platform_device *pdev)
774 {
775         pm_runtime_disable(&pdev->dev);
776
777         return 0;
778 }
779
780 static const struct dev_pm_ops tegra_admaif_pm_ops = {
781         SET_RUNTIME_PM_OPS(tegra_admaif_runtime_suspend,
782                            tegra_admaif_runtime_resume, NULL)
783         SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
784                                 pm_runtime_force_resume)
785 };
786
787 static struct platform_driver tegra_admaif_driver = {
788         .probe = tegra_admaif_probe,
789         .remove = tegra_admaif_remove,
790         .driver = {
791                 .name = "tegra210-admaif",
792                 .of_match_table = tegra_admaif_of_match,
793                 .pm = &tegra_admaif_pm_ops,
794         },
795 };
796 module_platform_driver(tegra_admaif_driver);
797
798 MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>");
799 MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver");
800 MODULE_LICENSE("GPL v2");