1 // SPDX-License-Identifier: GPL-2.0-only
2 // SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES.
3 // All rights reserved.
4 //
5 // tegra210_admaif.c - Tegra ADMAIF driver
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 "tegra_isomgr_bw.h"
17 #include "tegra210_admaif.h"
18 #include "tegra_cif.h"
19 #include "tegra_pcm.h"
20
21 #define CH_REG(offset, reg, id) \
22 ((offset) + (reg) + (TEGRA_ADMAIF_CHANNEL_REG_STRIDE * (id)))
23
24 #define CH_TX_REG(reg, id) CH_REG(admaif->soc_data->tx_base, reg, id)
25
26 #define CH_RX_REG(reg, id) CH_REG(admaif->soc_data->rx_base, reg, id)
27
28 #define REG_DEFAULTS(id, rx_ctrl, tx_ctrl, tx_base, rx_base, cif_ctrl) \
29 { CH_REG(rx_base, TEGRA_ADMAIF_RX_INT_MASK, id), 0x00000001 }, \
30 { CH_REG(rx_base, TEGRA_ADMAIF_CH_ACIF_RX_CTRL, id), cif_ctrl }, \
31 { CH_REG(rx_base, TEGRA_ADMAIF_RX_FIFO_CTRL, id), rx_ctrl }, \
32 { CH_REG(tx_base, TEGRA_ADMAIF_TX_INT_MASK, id), 0x00000001 }, \
33 { CH_REG(tx_base, TEGRA_ADMAIF_CH_ACIF_TX_CTRL, id), cif_ctrl }, \
34 { CH_REG(tx_base, TEGRA_ADMAIF_TX_FIFO_CTRL, id), tx_ctrl }
35
36 #define ADMAIF_REG_DEFAULTS(id, chip) \
37 REG_DEFAULTS((id) - 1, \
38 chip ## _ADMAIF_RX ## id ## _FIFO_CTRL_REG_DEFAULT, \
39 chip ## _ADMAIF_TX ## id ## _FIFO_CTRL_REG_DEFAULT, \
40 chip ## _ADMAIF_TX_BASE, \
41 chip ## _ADMAIF_RX_BASE, \
42 chip ## _ADMAIF_CIF_REG_DEFAULT)
43
44 static const struct reg_default tegra186_admaif_reg_defaults[] = {
45 {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA186_ADMAIF_GLOBAL_BASE), 0x00000003},
46 ADMAIF_REG_DEFAULTS(1, TEGRA186),
47 ADMAIF_REG_DEFAULTS(2, TEGRA186),
48 ADMAIF_REG_DEFAULTS(3, TEGRA186),
49 ADMAIF_REG_DEFAULTS(4, TEGRA186),
50 ADMAIF_REG_DEFAULTS(5, TEGRA186),
51 ADMAIF_REG_DEFAULTS(6, TEGRA186),
52 ADMAIF_REG_DEFAULTS(7, TEGRA186),
53 ADMAIF_REG_DEFAULTS(8, TEGRA186),
54 ADMAIF_REG_DEFAULTS(9, TEGRA186),
55 ADMAIF_REG_DEFAULTS(10, TEGRA186),
56 ADMAIF_REG_DEFAULTS(11, TEGRA186),
57 ADMAIF_REG_DEFAULTS(12, TEGRA186),
58 ADMAIF_REG_DEFAULTS(13, TEGRA186),
59 ADMAIF_REG_DEFAULTS(14, TEGRA186),
60 ADMAIF_REG_DEFAULTS(15, TEGRA186),
61 ADMAIF_REG_DEFAULTS(16, TEGRA186),
62 ADMAIF_REG_DEFAULTS(17, TEGRA186),
63 ADMAIF_REG_DEFAULTS(18, TEGRA186),
64 ADMAIF_REG_DEFAULTS(19, TEGRA186),
65 ADMAIF_REG_DEFAULTS(20, TEGRA186)
66 };
67
68 static const struct reg_default tegra210_admaif_reg_defaults[] = {
69 {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA210_ADMAIF_GLOBAL_BASE), 0x00000003},
70 ADMAIF_REG_DEFAULTS(1, TEGRA210),
71 ADMAIF_REG_DEFAULTS(2, TEGRA210),
72 ADMAIF_REG_DEFAULTS(3, TEGRA210),
73 ADMAIF_REG_DEFAULTS(4, TEGRA210),
74 ADMAIF_REG_DEFAULTS(5, TEGRA210),
75 ADMAIF_REG_DEFAULTS(6, TEGRA210),
76 ADMAIF_REG_DEFAULTS(7, TEGRA210),
77 ADMAIF_REG_DEFAULTS(8, TEGRA210),
78 ADMAIF_REG_DEFAULTS(9, TEGRA210),
79 ADMAIF_REG_DEFAULTS(10, TEGRA210)
80 };
81
82 static const struct reg_default tegra264_admaif_reg_defaults[] = {
83 {(TEGRA_ADMAIF_GLOBAL_CG_0 + TEGRA264_ADMAIF_GLOBAL_BASE), 0x00000003},
84 ADMAIF_REG_DEFAULTS(1, TEGRA264),
85 ADMAIF_REG_DEFAULTS(2, TEGRA264),
86 ADMAIF_REG_DEFAULTS(3, TEGRA264),
87 ADMAIF_REG_DEFAULTS(4, TEGRA264),
88 ADMAIF_REG_DEFAULTS(5, TEGRA264),
89 ADMAIF_REG_DEFAULTS(6, TEGRA264),
90 ADMAIF_REG_DEFAULTS(7, TEGRA264),
91 ADMAIF_REG_DEFAULTS(8, TEGRA264),
92 ADMAIF_REG_DEFAULTS(9, TEGRA264),
93 ADMAIF_REG_DEFAULTS(10, TEGRA264),
94 ADMAIF_REG_DEFAULTS(11, TEGRA264),
95 ADMAIF_REG_DEFAULTS(12, TEGRA264),
96 ADMAIF_REG_DEFAULTS(13, TEGRA264),
97 ADMAIF_REG_DEFAULTS(14, TEGRA264),
98 ADMAIF_REG_DEFAULTS(15, TEGRA264),
99 ADMAIF_REG_DEFAULTS(16, TEGRA264),
100 ADMAIF_REG_DEFAULTS(17, TEGRA264),
101 ADMAIF_REG_DEFAULTS(18, TEGRA264),
102 ADMAIF_REG_DEFAULTS(19, TEGRA264),
103 ADMAIF_REG_DEFAULTS(20, TEGRA264),
104 ADMAIF_REG_DEFAULTS(21, TEGRA264),
105 ADMAIF_REG_DEFAULTS(22, TEGRA264),
106 ADMAIF_REG_DEFAULTS(23, TEGRA264),
107 ADMAIF_REG_DEFAULTS(24, TEGRA264),
108 ADMAIF_REG_DEFAULTS(25, TEGRA264),
109 ADMAIF_REG_DEFAULTS(26, TEGRA264),
110 ADMAIF_REG_DEFAULTS(27, TEGRA264),
111 ADMAIF_REG_DEFAULTS(28, TEGRA264),
112 ADMAIF_REG_DEFAULTS(29, TEGRA264),
113 ADMAIF_REG_DEFAULTS(30, TEGRA264),
114 ADMAIF_REG_DEFAULTS(31, TEGRA264),
115 ADMAIF_REG_DEFAULTS(32, TEGRA264)
116 };
117
tegra_admaif_wr_reg(struct device * dev,unsigned int reg)118 static bool tegra_admaif_wr_reg(struct device *dev, unsigned int reg)
119 {
120 struct tegra_admaif *admaif = dev_get_drvdata(dev);
121 unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
122 unsigned int num_ch = admaif->soc_data->num_ch;
123 unsigned int rx_base = admaif->soc_data->rx_base;
124 unsigned int tx_base = admaif->soc_data->tx_base;
125 unsigned int global_base = admaif->soc_data->global_base;
126 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
127 unsigned int rx_max = rx_base + (num_ch * ch_stride);
128 unsigned int tx_max = tx_base + (num_ch * ch_stride);
129
130 if ((reg >= rx_base) && (reg < rx_max)) {
131 reg = (reg - rx_base) % ch_stride;
132 if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
133 (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) ||
134 (reg == TEGRA_ADMAIF_RX_SOFT_RESET) ||
135 (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL))
136 return true;
137 } else if ((reg >= tx_base) && (reg < tx_max)) {
138 reg = (reg - tx_base) % ch_stride;
139 if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
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 return true;
147 }
148
149 return false;
150 }
151
tegra_admaif_rd_reg(struct device * dev,unsigned int reg)152 static bool tegra_admaif_rd_reg(struct device *dev, unsigned int reg)
153 {
154 struct tegra_admaif *admaif = dev_get_drvdata(dev);
155 unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
156 unsigned int num_ch = admaif->soc_data->num_ch;
157 unsigned int rx_base = admaif->soc_data->rx_base;
158 unsigned int tx_base = admaif->soc_data->tx_base;
159 unsigned int global_base = admaif->soc_data->global_base;
160 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
161 unsigned int rx_max = rx_base + (num_ch * ch_stride);
162 unsigned int tx_max = tx_base + (num_ch * ch_stride);
163
164 if ((reg >= rx_base) && (reg < rx_max)) {
165 reg = (reg - rx_base) % ch_stride;
166 if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
167 (reg == TEGRA_ADMAIF_RX_STATUS) ||
168 (reg == TEGRA_ADMAIF_RX_INT_STATUS) ||
169 (reg == TEGRA_ADMAIF_RX_FIFO_CTRL) ||
170 (reg == TEGRA_ADMAIF_RX_SOFT_RESET) ||
171 (reg == TEGRA_ADMAIF_CH_ACIF_RX_CTRL))
172 return true;
173 } else if ((reg >= tx_base) && (reg < tx_max)) {
174 reg = (reg - tx_base) % ch_stride;
175 if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
176 (reg == TEGRA_ADMAIF_TX_STATUS) ||
177 (reg == TEGRA_ADMAIF_TX_INT_STATUS) ||
178 (reg == TEGRA_ADMAIF_TX_FIFO_CTRL) ||
179 (reg == TEGRA_ADMAIF_TX_SOFT_RESET) ||
180 (reg == TEGRA_ADMAIF_CH_ACIF_TX_CTRL))
181 return true;
182 } else if ((reg >= global_base) && (reg < reg_max)) {
183 if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_ENABLE)) ||
184 (reg == (global_base + TEGRA_ADMAIF_GLOBAL_CG_0)) ||
185 (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
tegra_admaif_volatile_reg(struct device * dev,unsigned int reg)196 static bool tegra_admaif_volatile_reg(struct device *dev, unsigned int reg)
197 {
198 struct tegra_admaif *admaif = dev_get_drvdata(dev);
199 unsigned int ch_stride = TEGRA_ADMAIF_CHANNEL_REG_STRIDE;
200 unsigned int num_ch = admaif->soc_data->num_ch;
201 unsigned int rx_base = admaif->soc_data->rx_base;
202 unsigned int tx_base = admaif->soc_data->tx_base;
203 unsigned int global_base = admaif->soc_data->global_base;
204 unsigned int reg_max = admaif->soc_data->regmap_conf->max_register;
205 unsigned int rx_max = rx_base + (num_ch * ch_stride);
206 unsigned int tx_max = tx_base + (num_ch * ch_stride);
207
208 if ((reg >= rx_base) && (reg < rx_max)) {
209 reg = (reg - rx_base) % ch_stride;
210 if ((reg == TEGRA_ADMAIF_RX_ENABLE) ||
211 (reg == TEGRA_ADMAIF_RX_STATUS) ||
212 (reg == TEGRA_ADMAIF_RX_INT_STATUS) ||
213 (reg == TEGRA_ADMAIF_RX_SOFT_RESET))
214 return true;
215 } else if ((reg >= tx_base) && (reg < tx_max)) {
216 reg = (reg - tx_base) % ch_stride;
217 if ((reg == TEGRA_ADMAIF_TX_ENABLE) ||
218 (reg == TEGRA_ADMAIF_TX_STATUS) ||
219 (reg == TEGRA_ADMAIF_TX_INT_STATUS) ||
220 (reg == TEGRA_ADMAIF_TX_SOFT_RESET))
221 return true;
222 } else if ((reg >= global_base) && (reg < reg_max)) {
223 if ((reg == (global_base + TEGRA_ADMAIF_GLOBAL_STATUS)) ||
224 (reg == (global_base +
225 TEGRA_ADMAIF_GLOBAL_RX_ENABLE_STATUS)) ||
226 (reg == (global_base +
227 TEGRA_ADMAIF_GLOBAL_TX_ENABLE_STATUS)))
228 return true;
229 }
230
231 return false;
232 }
233
234 static const struct regmap_config tegra210_admaif_regmap_config = {
235 .reg_bits = 32,
236 .reg_stride = 4,
237 .val_bits = 32,
238 .max_register = TEGRA210_ADMAIF_LAST_REG,
239 .writeable_reg = tegra_admaif_wr_reg,
240 .readable_reg = tegra_admaif_rd_reg,
241 .volatile_reg = tegra_admaif_volatile_reg,
242 .reg_defaults = tegra210_admaif_reg_defaults,
243 .num_reg_defaults = TEGRA210_ADMAIF_CHANNEL_COUNT * 6 + 1,
244 .cache_type = REGCACHE_FLAT,
245 };
246
247 static const struct regmap_config tegra186_admaif_regmap_config = {
248 .reg_bits = 32,
249 .reg_stride = 4,
250 .val_bits = 32,
251 .max_register = TEGRA186_ADMAIF_LAST_REG,
252 .writeable_reg = tegra_admaif_wr_reg,
253 .readable_reg = tegra_admaif_rd_reg,
254 .volatile_reg = tegra_admaif_volatile_reg,
255 .reg_defaults = tegra186_admaif_reg_defaults,
256 .num_reg_defaults = TEGRA186_ADMAIF_CHANNEL_COUNT * 6 + 1,
257 .cache_type = REGCACHE_FLAT,
258 };
259
260 static const struct regmap_config tegra264_admaif_regmap_config = {
261 .reg_bits = 32,
262 .reg_stride = 4,
263 .val_bits = 32,
264 .max_register = TEGRA264_ADMAIF_LAST_REG,
265 .writeable_reg = tegra_admaif_wr_reg,
266 .readable_reg = tegra_admaif_rd_reg,
267 .volatile_reg = tegra_admaif_volatile_reg,
268 .reg_defaults = tegra264_admaif_reg_defaults,
269 .num_reg_defaults = TEGRA264_ADMAIF_CHANNEL_COUNT * 6 + 1,
270 .cache_type = REGCACHE_FLAT,
271 };
272
tegra_admaif_runtime_suspend(struct device * dev)273 static int tegra_admaif_runtime_suspend(struct device *dev)
274 {
275 struct tegra_admaif *admaif = dev_get_drvdata(dev);
276
277 regcache_cache_only(admaif->regmap, true);
278 regcache_mark_dirty(admaif->regmap);
279
280 return 0;
281 }
282
tegra_admaif_runtime_resume(struct device * dev)283 static int tegra_admaif_runtime_resume(struct device *dev)
284 {
285 struct tegra_admaif *admaif = dev_get_drvdata(dev);
286
287 regcache_cache_only(admaif->regmap, false);
288 regcache_sync(admaif->regmap);
289
290 return 0;
291 }
292
tegra_admaif_set_pack_mode(struct regmap * map,unsigned int reg,int valid_bit)293 static int tegra_admaif_set_pack_mode(struct regmap *map, unsigned int reg,
294 int valid_bit)
295 {
296 switch (valid_bit) {
297 case DATA_8BIT:
298 regmap_update_bits(map, reg, PACK8_EN_MASK, PACK8_EN);
299 regmap_update_bits(map, reg, PACK16_EN_MASK, 0);
300 break;
301 case DATA_16BIT:
302 regmap_update_bits(map, reg, PACK16_EN_MASK, PACK16_EN);
303 regmap_update_bits(map, reg, PACK8_EN_MASK, 0);
304 break;
305 case DATA_32BIT:
306 regmap_update_bits(map, reg, PACK16_EN_MASK, 0);
307 regmap_update_bits(map, reg, PACK8_EN_MASK, 0);
308 break;
309 default:
310 return -EINVAL;
311 }
312
313 return 0;
314 }
315
tegra_admaif_prepare(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)316 static int tegra_admaif_prepare(struct snd_pcm_substream *substream,
317 struct snd_soc_dai *dai)
318 {
319 return tegra_isomgr_adma_setbw(substream, dai, true);
320 }
321
tegra_admaif_shutdown(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)322 static void tegra_admaif_shutdown(struct snd_pcm_substream *substream,
323 struct snd_soc_dai *dai)
324 {
325 tegra_isomgr_adma_setbw(substream, dai, false);
326 }
327
tegra_admaif_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)328 static int tegra_admaif_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *params,
330 struct snd_soc_dai *dai)
331 {
332 struct device *dev = dai->dev;
333 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
334 struct tegra_cif_conf cif_conf;
335 unsigned int reg, path;
336 int valid_bit, channels;
337
338 memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
339
340 switch (params_format(params)) {
341 case SNDRV_PCM_FORMAT_S8:
342 cif_conf.audio_bits = TEGRA_ACIF_BITS_8;
343 cif_conf.client_bits = TEGRA_ACIF_BITS_8;
344 valid_bit = DATA_8BIT;
345 break;
346 case SNDRV_PCM_FORMAT_S16_LE:
347 cif_conf.audio_bits = TEGRA_ACIF_BITS_16;
348 cif_conf.client_bits = TEGRA_ACIF_BITS_16;
349 valid_bit = DATA_16BIT;
350 break;
351 case SNDRV_PCM_FORMAT_S24_LE:
352 cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
353 cif_conf.client_bits = TEGRA_ACIF_BITS_24;
354 valid_bit = DATA_32BIT;
355 break;
356 case SNDRV_PCM_FORMAT_S32_LE:
357 cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
358 cif_conf.client_bits = TEGRA_ACIF_BITS_32;
359 valid_bit = DATA_32BIT;
360 break;
361 default:
362 dev_err(dev, "unsupported format!\n");
363 return -EOPNOTSUPP;
364 }
365
366 channels = params_channels(params);
367 cif_conf.client_ch = channels;
368 cif_conf.audio_ch = channels;
369
370 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
371 path = ADMAIF_TX_PATH;
372 reg = CH_TX_REG(TEGRA_ADMAIF_CH_ACIF_TX_CTRL, dai->id);
373 } else {
374 path = ADMAIF_RX_PATH;
375 reg = CH_RX_REG(TEGRA_ADMAIF_CH_ACIF_RX_CTRL, dai->id);
376 }
377
378 cif_conf.mono_conv = admaif->mono_to_stereo[path][dai->id];
379 cif_conf.stereo_conv = admaif->stereo_to_mono[path][dai->id];
380
381 tegra_admaif_set_pack_mode(admaif->regmap, reg, valid_bit);
382
383 if (admaif->soc_data->max_stream_ch == TEGRA264_ADMAIF_MAX_CHANNEL)
384 tegra264_set_cif(admaif->regmap, reg, &cif_conf);
385 else
386 tegra_set_cif(admaif->regmap, reg, &cif_conf);
387
388 return 0;
389 }
390
tegra_admaif_start(struct snd_soc_dai * dai,int direction)391 static int tegra_admaif_start(struct snd_soc_dai *dai, int direction)
392 {
393 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
394 unsigned int reg, mask, val;
395
396 switch (direction) {
397 case SNDRV_PCM_STREAM_PLAYBACK:
398 mask = TX_ENABLE_MASK;
399 val = TX_ENABLE;
400 reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
401 break;
402 case SNDRV_PCM_STREAM_CAPTURE:
403 mask = RX_ENABLE_MASK;
404 val = RX_ENABLE;
405 reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
406 break;
407 default:
408 return -EINVAL;
409 }
410
411 regmap_update_bits(admaif->regmap, reg, mask, val);
412
413 return 0;
414 }
415
tegra_admaif_stop(struct snd_soc_dai * dai,int direction)416 static int tegra_admaif_stop(struct snd_soc_dai *dai, int direction)
417 {
418 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
419 unsigned int enable_reg, status_reg, reset_reg, mask, val;
420 char *dir_name;
421 int err, enable;
422
423 switch (direction) {
424 case SNDRV_PCM_STREAM_PLAYBACK:
425 mask = TX_ENABLE_MASK;
426 enable = TX_ENABLE;
427 dir_name = "TX";
428 enable_reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
429 status_reg = CH_TX_REG(TEGRA_ADMAIF_TX_STATUS, dai->id);
430 reset_reg = CH_TX_REG(TEGRA_ADMAIF_TX_SOFT_RESET, dai->id);
431 break;
432 case SNDRV_PCM_STREAM_CAPTURE:
433 mask = RX_ENABLE_MASK;
434 enable = RX_ENABLE;
435 dir_name = "RX";
436 enable_reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
437 status_reg = CH_RX_REG(TEGRA_ADMAIF_RX_STATUS, dai->id);
438 reset_reg = CH_RX_REG(TEGRA_ADMAIF_RX_SOFT_RESET, dai->id);
439 break;
440 default:
441 return -EINVAL;
442 }
443
444 /* Disable TX/RX channel */
445 regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable);
446
447 /* Wait until ADMAIF TX/RX status is disabled */
448 err = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val,
449 !(val & enable), 10, 10000);
450 if (err < 0)
451 dev_warn(dai->dev, "timeout: failed to disable ADMAIF%d_%s\n",
452 dai->id + 1, dir_name);
453
454 /* SW reset */
455 regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET);
456
457 /* Wait till SW reset is complete */
458 err = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val,
459 !(val & SW_RESET_MASK & SW_RESET),
460 10, 10000);
461 if (err) {
462 dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n",
463 dai->id + 1, dir_name);
464 return err;
465 }
466
467 return 0;
468 }
469
tegra_admaif_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)470 static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
471 struct snd_soc_dai *dai)
472 {
473 int err;
474
475 err = snd_dmaengine_pcm_trigger(substream, cmd);
476 if (err)
477 return err;
478
479 switch (cmd) {
480 case SNDRV_PCM_TRIGGER_START:
481 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
482 case SNDRV_PCM_TRIGGER_RESUME:
483 return tegra_admaif_start(dai, substream->stream);
484 case SNDRV_PCM_TRIGGER_STOP:
485 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
486 case SNDRV_PCM_TRIGGER_SUSPEND:
487 return tegra_admaif_stop(dai, substream->stream);
488 default:
489 return -EINVAL;
490 }
491 }
492
tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)493 static int tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol *kcontrol,
494 struct snd_ctl_elem_value *ucontrol)
495 {
496 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
497 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
498 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
499
500 ucontrol->value.enumerated.item[0] =
501 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
502
503 return 0;
504 }
505
tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)506 static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol,
507 struct snd_ctl_elem_value *ucontrol)
508 {
509 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
510 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
511 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
512 unsigned int value = ucontrol->value.enumerated.item[0];
513
514 if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg])
515 return 0;
516
517 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
518
519 return 1;
520 }
521
tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)522 static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol,
523 struct snd_ctl_elem_value *ucontrol)
524 {
525 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
526 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
527 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
528
529 ucontrol->value.enumerated.item[0] =
530 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
531
532 return 0;
533 }
534
tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)535 static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol,
536 struct snd_ctl_elem_value *ucontrol)
537 {
538 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
539 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
540 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
541 unsigned int value = ucontrol->value.enumerated.item[0];
542
543 if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg])
544 return 0;
545
546 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
547
548 return 1;
549 }
550
tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)551 static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol,
552 struct snd_ctl_elem_value *ucontrol)
553 {
554 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
555 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
556 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
557
558 ucontrol->value.enumerated.item[0] =
559 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
560
561 return 0;
562 }
563
tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)564 static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol,
565 struct snd_ctl_elem_value *ucontrol)
566 {
567 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
568 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
569 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
570 unsigned int value = ucontrol->value.enumerated.item[0];
571
572 if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg])
573 return 0;
574
575 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
576
577 return 1;
578 }
579
tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)580 static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol,
581 struct snd_ctl_elem_value *ucontrol)
582 {
583 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
584 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
585 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
586
587 ucontrol->value.enumerated.item[0] =
588 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
589
590 return 0;
591 }
592
tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)593 static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol,
594 struct snd_ctl_elem_value *ucontrol)
595 {
596 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
597 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
598 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
599 unsigned int value = ucontrol->value.enumerated.item[0];
600
601 if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg])
602 return 0;
603
604 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
605
606 return 1;
607 }
608
tegra_admaif_dai_probe(struct snd_soc_dai * dai)609 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
610 {
611 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
612
613 snd_soc_dai_init_dma_data(dai, &admaif->playback_dma_data[dai->id],
614 &admaif->capture_dma_data[dai->id]);
615
616 return 0;
617 }
618
619 static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
620 .probe = tegra_admaif_dai_probe,
621 .hw_params = tegra_admaif_hw_params,
622 .trigger = tegra_admaif_trigger,
623 .shutdown = tegra_admaif_shutdown,
624 .prepare = tegra_admaif_prepare,
625 };
626
627 #define DAI(dai_name, channel) \
628 { \
629 .name = dai_name, \
630 .playback = { \
631 .stream_name = dai_name " Playback", \
632 .channels_min = 1, \
633 .channels_max = channel, \
634 .rates = SNDRV_PCM_RATE_8000_192000, \
635 .formats = SNDRV_PCM_FMTBIT_S8 | \
636 SNDRV_PCM_FMTBIT_S16_LE | \
637 SNDRV_PCM_FMTBIT_S24_LE | \
638 SNDRV_PCM_FMTBIT_S32_LE, \
639 }, \
640 .capture = { \
641 .stream_name = dai_name " Capture", \
642 .channels_min = 1, \
643 .channels_max = channel, \
644 .rates = SNDRV_PCM_RATE_8000_192000, \
645 .formats = SNDRV_PCM_FMTBIT_S8 | \
646 SNDRV_PCM_FMTBIT_S16_LE | \
647 SNDRV_PCM_FMTBIT_S24_LE | \
648 SNDRV_PCM_FMTBIT_S32_LE, \
649 }, \
650 .ops = &tegra_admaif_dai_ops, \
651 }
652
653 static struct snd_soc_dai_driver tegra210_admaif_cmpnt_dais[] = {
654 DAI("ADMAIF1", TEGRA210_ADMAIF_MAX_CHANNEL),
655 DAI("ADMAIF2", TEGRA210_ADMAIF_MAX_CHANNEL),
656 DAI("ADMAIF3", TEGRA210_ADMAIF_MAX_CHANNEL),
657 DAI("ADMAIF4", TEGRA210_ADMAIF_MAX_CHANNEL),
658 DAI("ADMAIF5", TEGRA210_ADMAIF_MAX_CHANNEL),
659 DAI("ADMAIF6", TEGRA210_ADMAIF_MAX_CHANNEL),
660 DAI("ADMAIF7", TEGRA210_ADMAIF_MAX_CHANNEL),
661 DAI("ADMAIF8", TEGRA210_ADMAIF_MAX_CHANNEL),
662 DAI("ADMAIF9", TEGRA210_ADMAIF_MAX_CHANNEL),
663 DAI("ADMAIF10", TEGRA210_ADMAIF_MAX_CHANNEL),
664 };
665
666 static struct snd_soc_dai_driver tegra186_admaif_cmpnt_dais[] = {
667 DAI("ADMAIF1", TEGRA186_ADMAIF_MAX_CHANNEL),
668 DAI("ADMAIF2", TEGRA186_ADMAIF_MAX_CHANNEL),
669 DAI("ADMAIF3", TEGRA186_ADMAIF_MAX_CHANNEL),
670 DAI("ADMAIF4", TEGRA186_ADMAIF_MAX_CHANNEL),
671 DAI("ADMAIF5", TEGRA186_ADMAIF_MAX_CHANNEL),
672 DAI("ADMAIF6", TEGRA186_ADMAIF_MAX_CHANNEL),
673 DAI("ADMAIF7", TEGRA186_ADMAIF_MAX_CHANNEL),
674 DAI("ADMAIF8", TEGRA186_ADMAIF_MAX_CHANNEL),
675 DAI("ADMAIF9", TEGRA186_ADMAIF_MAX_CHANNEL),
676 DAI("ADMAIF10", TEGRA186_ADMAIF_MAX_CHANNEL),
677 DAI("ADMAIF11", TEGRA186_ADMAIF_MAX_CHANNEL),
678 DAI("ADMAIF12", TEGRA186_ADMAIF_MAX_CHANNEL),
679 DAI("ADMAIF13", TEGRA186_ADMAIF_MAX_CHANNEL),
680 DAI("ADMAIF14", TEGRA186_ADMAIF_MAX_CHANNEL),
681 DAI("ADMAIF15", TEGRA186_ADMAIF_MAX_CHANNEL),
682 DAI("ADMAIF16", TEGRA186_ADMAIF_MAX_CHANNEL),
683 DAI("ADMAIF17", TEGRA186_ADMAIF_MAX_CHANNEL),
684 DAI("ADMAIF18", TEGRA186_ADMAIF_MAX_CHANNEL),
685 DAI("ADMAIF19", TEGRA186_ADMAIF_MAX_CHANNEL),
686 DAI("ADMAIF20", TEGRA186_ADMAIF_MAX_CHANNEL),
687 };
688
689 static struct snd_soc_dai_driver tegra264_admaif_cmpnt_dais[] = {
690 DAI("ADMAIF1", TEGRA264_ADMAIF_MAX_CHANNEL),
691 DAI("ADMAIF2", TEGRA264_ADMAIF_MAX_CHANNEL),
692 DAI("ADMAIF3", TEGRA264_ADMAIF_MAX_CHANNEL),
693 DAI("ADMAIF4", TEGRA264_ADMAIF_MAX_CHANNEL),
694 DAI("ADMAIF5", TEGRA264_ADMAIF_MAX_CHANNEL),
695 DAI("ADMAIF6", TEGRA264_ADMAIF_MAX_CHANNEL),
696 DAI("ADMAIF7", TEGRA264_ADMAIF_MAX_CHANNEL),
697 DAI("ADMAIF8", TEGRA264_ADMAIF_MAX_CHANNEL),
698 DAI("ADMAIF9", TEGRA264_ADMAIF_MAX_CHANNEL),
699 DAI("ADMAIF10", TEGRA264_ADMAIF_MAX_CHANNEL),
700 DAI("ADMAIF11", TEGRA264_ADMAIF_MAX_CHANNEL),
701 DAI("ADMAIF12", TEGRA264_ADMAIF_MAX_CHANNEL),
702 DAI("ADMAIF13", TEGRA264_ADMAIF_MAX_CHANNEL),
703 DAI("ADMAIF14", TEGRA264_ADMAIF_MAX_CHANNEL),
704 DAI("ADMAIF15", TEGRA264_ADMAIF_MAX_CHANNEL),
705 DAI("ADMAIF16", TEGRA264_ADMAIF_MAX_CHANNEL),
706 DAI("ADMAIF17", TEGRA264_ADMAIF_MAX_CHANNEL),
707 DAI("ADMAIF18", TEGRA264_ADMAIF_MAX_CHANNEL),
708 DAI("ADMAIF19", TEGRA264_ADMAIF_MAX_CHANNEL),
709 DAI("ADMAIF20", TEGRA264_ADMAIF_MAX_CHANNEL),
710 DAI("ADMAIF21", TEGRA264_ADMAIF_MAX_CHANNEL),
711 DAI("ADMAIF22", TEGRA264_ADMAIF_MAX_CHANNEL),
712 DAI("ADMAIF23", TEGRA264_ADMAIF_MAX_CHANNEL),
713 DAI("ADMAIF24", TEGRA264_ADMAIF_MAX_CHANNEL),
714 DAI("ADMAIF25", TEGRA264_ADMAIF_MAX_CHANNEL),
715 DAI("ADMAIF26", TEGRA264_ADMAIF_MAX_CHANNEL),
716 DAI("ADMAIF27", TEGRA264_ADMAIF_MAX_CHANNEL),
717 DAI("ADMAIF28", TEGRA264_ADMAIF_MAX_CHANNEL),
718 DAI("ADMAIF29", TEGRA264_ADMAIF_MAX_CHANNEL),
719 DAI("ADMAIF30", TEGRA264_ADMAIF_MAX_CHANNEL),
720 DAI("ADMAIF31", TEGRA264_ADMAIF_MAX_CHANNEL),
721 DAI("ADMAIF32", TEGRA264_ADMAIF_MAX_CHANNEL),
722 };
723
724 static const char * const tegra_admaif_stereo_conv_text[] = {
725 "CH0", "CH1", "AVG",
726 };
727
728 static const char * const tegra_admaif_mono_conv_text[] = {
729 "Zero", "Copy",
730 };
731
732 /*
733 * Below macro is added to avoid looping over all ADMAIFx controls related
734 * to mono/stereo conversions in get()/put() callbacks.
735 */
736 #define NV_SOC_ENUM_EXT(xname, xreg, xhandler_get, xhandler_put, xenum_text) \
737 { \
738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
739 .info = snd_soc_info_enum_double, \
740 .name = xname, \
741 .get = xhandler_get, \
742 .put = xhandler_put, \
743 .private_value = (unsigned long)&(struct soc_enum) \
744 SOC_ENUM_SINGLE(xreg, 0, ARRAY_SIZE(xenum_text), xenum_text) \
745 }
746
747 #define TEGRA_ADMAIF_CIF_CTRL(reg) \
748 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1, \
749 tegra210_admaif_pget_mono_to_stereo, \
750 tegra210_admaif_pput_mono_to_stereo, \
751 tegra_admaif_mono_conv_text), \
752 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1, \
753 tegra210_admaif_pget_stereo_to_mono, \
754 tegra210_admaif_pput_stereo_to_mono, \
755 tegra_admaif_stereo_conv_text), \
756 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \
757 tegra210_admaif_cget_mono_to_stereo, \
758 tegra210_admaif_cput_mono_to_stereo, \
759 tegra_admaif_mono_conv_text), \
760 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \
761 tegra210_admaif_cget_stereo_to_mono, \
762 tegra210_admaif_cput_stereo_to_mono, \
763 tegra_admaif_stereo_conv_text)
764
765 static struct snd_kcontrol_new tegra210_admaif_controls[] = {
766 TEGRA_ADMAIF_CIF_CTRL(1),
767 TEGRA_ADMAIF_CIF_CTRL(2),
768 TEGRA_ADMAIF_CIF_CTRL(3),
769 TEGRA_ADMAIF_CIF_CTRL(4),
770 TEGRA_ADMAIF_CIF_CTRL(5),
771 TEGRA_ADMAIF_CIF_CTRL(6),
772 TEGRA_ADMAIF_CIF_CTRL(7),
773 TEGRA_ADMAIF_CIF_CTRL(8),
774 TEGRA_ADMAIF_CIF_CTRL(9),
775 TEGRA_ADMAIF_CIF_CTRL(10),
776 };
777
778 static struct snd_kcontrol_new tegra186_admaif_controls[] = {
779 TEGRA_ADMAIF_CIF_CTRL(1),
780 TEGRA_ADMAIF_CIF_CTRL(2),
781 TEGRA_ADMAIF_CIF_CTRL(3),
782 TEGRA_ADMAIF_CIF_CTRL(4),
783 TEGRA_ADMAIF_CIF_CTRL(5),
784 TEGRA_ADMAIF_CIF_CTRL(6),
785 TEGRA_ADMAIF_CIF_CTRL(7),
786 TEGRA_ADMAIF_CIF_CTRL(8),
787 TEGRA_ADMAIF_CIF_CTRL(9),
788 TEGRA_ADMAIF_CIF_CTRL(10),
789 TEGRA_ADMAIF_CIF_CTRL(11),
790 TEGRA_ADMAIF_CIF_CTRL(12),
791 TEGRA_ADMAIF_CIF_CTRL(13),
792 TEGRA_ADMAIF_CIF_CTRL(14),
793 TEGRA_ADMAIF_CIF_CTRL(15),
794 TEGRA_ADMAIF_CIF_CTRL(16),
795 TEGRA_ADMAIF_CIF_CTRL(17),
796 TEGRA_ADMAIF_CIF_CTRL(18),
797 TEGRA_ADMAIF_CIF_CTRL(19),
798 TEGRA_ADMAIF_CIF_CTRL(20),
799 };
800
801 static struct snd_kcontrol_new tegra264_admaif_controls[] = {
802 TEGRA_ADMAIF_CIF_CTRL(1),
803 TEGRA_ADMAIF_CIF_CTRL(2),
804 TEGRA_ADMAIF_CIF_CTRL(3),
805 TEGRA_ADMAIF_CIF_CTRL(4),
806 TEGRA_ADMAIF_CIF_CTRL(5),
807 TEGRA_ADMAIF_CIF_CTRL(6),
808 TEGRA_ADMAIF_CIF_CTRL(7),
809 TEGRA_ADMAIF_CIF_CTRL(8),
810 TEGRA_ADMAIF_CIF_CTRL(9),
811 TEGRA_ADMAIF_CIF_CTRL(10),
812 TEGRA_ADMAIF_CIF_CTRL(11),
813 TEGRA_ADMAIF_CIF_CTRL(12),
814 TEGRA_ADMAIF_CIF_CTRL(13),
815 TEGRA_ADMAIF_CIF_CTRL(14),
816 TEGRA_ADMAIF_CIF_CTRL(15),
817 TEGRA_ADMAIF_CIF_CTRL(16),
818 TEGRA_ADMAIF_CIF_CTRL(17),
819 TEGRA_ADMAIF_CIF_CTRL(18),
820 TEGRA_ADMAIF_CIF_CTRL(19),
821 TEGRA_ADMAIF_CIF_CTRL(20),
822 TEGRA_ADMAIF_CIF_CTRL(21),
823 TEGRA_ADMAIF_CIF_CTRL(22),
824 TEGRA_ADMAIF_CIF_CTRL(23),
825 TEGRA_ADMAIF_CIF_CTRL(24),
826 TEGRA_ADMAIF_CIF_CTRL(25),
827 TEGRA_ADMAIF_CIF_CTRL(26),
828 TEGRA_ADMAIF_CIF_CTRL(27),
829 TEGRA_ADMAIF_CIF_CTRL(28),
830 TEGRA_ADMAIF_CIF_CTRL(29),
831 TEGRA_ADMAIF_CIF_CTRL(30),
832 TEGRA_ADMAIF_CIF_CTRL(31),
833 TEGRA_ADMAIF_CIF_CTRL(32),
834 };
835
836 static const struct snd_soc_component_driver tegra210_admaif_cmpnt = {
837 .controls = tegra210_admaif_controls,
838 .num_controls = ARRAY_SIZE(tegra210_admaif_controls),
839 .pcm_construct = tegra_pcm_construct,
840 .open = tegra_pcm_open,
841 .close = tegra_pcm_close,
842 .hw_params = tegra_pcm_hw_params,
843 .pointer = tegra_pcm_pointer,
844 };
845
846 static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
847 .controls = tegra186_admaif_controls,
848 .num_controls = ARRAY_SIZE(tegra186_admaif_controls),
849 .pcm_construct = tegra_pcm_construct,
850 .open = tegra_pcm_open,
851 .close = tegra_pcm_close,
852 .hw_params = tegra_pcm_hw_params,
853 .pointer = tegra_pcm_pointer,
854 };
855
856 static const struct snd_soc_component_driver tegra264_admaif_cmpnt = {
857 .controls = tegra264_admaif_controls,
858 .num_controls = ARRAY_SIZE(tegra264_admaif_controls),
859 .pcm_construct = tegra_pcm_construct,
860 .open = tegra_pcm_open,
861 .close = tegra_pcm_close,
862 .hw_params = tegra_pcm_hw_params,
863 .pointer = tegra_pcm_pointer,
864 };
865
866 static const struct tegra_admaif_soc_data soc_data_tegra210 = {
867 .num_ch = TEGRA210_ADMAIF_CHANNEL_COUNT,
868 .max_stream_ch = TEGRA210_ADMAIF_MAX_CHANNEL,
869 .cmpnt = &tegra210_admaif_cmpnt,
870 .dais = tegra210_admaif_cmpnt_dais,
871 .regmap_conf = &tegra210_admaif_regmap_config,
872 .global_base = TEGRA210_ADMAIF_GLOBAL_BASE,
873 .tx_base = TEGRA210_ADMAIF_TX_BASE,
874 .rx_base = TEGRA210_ADMAIF_RX_BASE,
875 };
876
877 static const struct tegra_admaif_soc_data soc_data_tegra186 = {
878 .num_ch = TEGRA186_ADMAIF_CHANNEL_COUNT,
879 .max_stream_ch = TEGRA186_ADMAIF_MAX_CHANNEL,
880 .cmpnt = &tegra186_admaif_cmpnt,
881 .dais = tegra186_admaif_cmpnt_dais,
882 .regmap_conf = &tegra186_admaif_regmap_config,
883 .global_base = TEGRA186_ADMAIF_GLOBAL_BASE,
884 .tx_base = TEGRA186_ADMAIF_TX_BASE,
885 .rx_base = TEGRA186_ADMAIF_RX_BASE,
886 };
887
888 static const struct tegra_admaif_soc_data soc_data_tegra264 = {
889 .num_ch = TEGRA264_ADMAIF_CHANNEL_COUNT,
890 .max_stream_ch = TEGRA264_ADMAIF_MAX_CHANNEL,
891 .cmpnt = &tegra264_admaif_cmpnt,
892 .dais = tegra264_admaif_cmpnt_dais,
893 .regmap_conf = &tegra264_admaif_regmap_config,
894 .global_base = TEGRA264_ADMAIF_GLOBAL_BASE,
895 .tx_base = TEGRA264_ADMAIF_TX_BASE,
896 .rx_base = TEGRA264_ADMAIF_RX_BASE,
897 };
898
899 static const struct of_device_id tegra_admaif_of_match[] = {
900 { .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
901 { .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 },
902 { .compatible = "nvidia,tegra264-admaif", .data = &soc_data_tegra264 },
903 {},
904 };
905 MODULE_DEVICE_TABLE(of, tegra_admaif_of_match);
906
tegra_admaif_probe(struct platform_device * pdev)907 static int tegra_admaif_probe(struct platform_device *pdev)
908 {
909 struct tegra_admaif *admaif;
910 void __iomem *regs;
911 struct resource *res;
912 int err, i;
913
914 admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
915 if (!admaif)
916 return -ENOMEM;
917
918 admaif->soc_data = of_device_get_match_data(&pdev->dev);
919
920 dev_set_drvdata(&pdev->dev, admaif);
921
922 admaif->capture_dma_data =
923 devm_kcalloc(&pdev->dev,
924 admaif->soc_data->num_ch,
925 sizeof(struct snd_dmaengine_dai_dma_data),
926 GFP_KERNEL);
927 if (!admaif->capture_dma_data)
928 return -ENOMEM;
929
930 admaif->playback_dma_data =
931 devm_kcalloc(&pdev->dev,
932 admaif->soc_data->num_ch,
933 sizeof(struct snd_dmaengine_dai_dma_data),
934 GFP_KERNEL);
935 if (!admaif->playback_dma_data)
936 return -ENOMEM;
937
938 for (i = 0; i < ADMAIF_PATHS; i++) {
939 admaif->mono_to_stereo[i] =
940 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
941 sizeof(unsigned int), GFP_KERNEL);
942 if (!admaif->mono_to_stereo[i])
943 return -ENOMEM;
944
945 admaif->stereo_to_mono[i] =
946 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
947 sizeof(unsigned int), GFP_KERNEL);
948 if (!admaif->stereo_to_mono[i])
949 return -ENOMEM;
950 }
951
952 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
953 if (IS_ERR(regs))
954 return PTR_ERR(regs);
955
956 admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
957 admaif->soc_data->regmap_conf);
958 if (IS_ERR(admaif->regmap)) {
959 dev_err(&pdev->dev, "regmap init failed\n");
960 return PTR_ERR(admaif->regmap);
961 }
962
963 regcache_cache_only(admaif->regmap, true);
964
965 err = tegra_isomgr_adma_register(&pdev->dev);
966 if (err) {
967 dev_err(&pdev->dev, "Failed to add interconnect path\n");
968 return err;
969 }
970
971 regmap_update_bits(admaif->regmap, admaif->soc_data->global_base +
972 TEGRA_ADMAIF_GLOBAL_ENABLE, 1, 1);
973
974 for (i = 0; i < admaif->soc_data->num_ch; i++) {
975 admaif->playback_dma_data[i].addr = res->start +
976 CH_TX_REG(TEGRA_ADMAIF_TX_FIFO_WRITE, i);
977
978 admaif->capture_dma_data[i].addr = res->start +
979 CH_RX_REG(TEGRA_ADMAIF_RX_FIFO_READ, i);
980
981 admaif->playback_dma_data[i].addr_width = 32;
982
983 if (of_property_read_string_index(pdev->dev.of_node,
984 "dma-names", (i * 2) + 1,
985 &admaif->playback_dma_data[i].chan_name) < 0) {
986 dev_err(&pdev->dev,
987 "missing property nvidia,dma-names\n");
988
989 return -ENODEV;
990 }
991
992 admaif->capture_dma_data[i].addr_width = 32;
993
994 if (of_property_read_string_index(pdev->dev.of_node,
995 "dma-names",
996 (i * 2),
997 &admaif->capture_dma_data[i].chan_name) < 0) {
998 dev_err(&pdev->dev,
999 "missing property nvidia,dma-names\n");
1000
1001 return -ENODEV;
1002 }
1003 }
1004
1005 err = devm_snd_soc_register_component(&pdev->dev,
1006 admaif->soc_data->cmpnt,
1007 admaif->soc_data->dais,
1008 admaif->soc_data->num_ch);
1009 if (err) {
1010 dev_err(&pdev->dev,
1011 "can't register ADMAIF component, err: %d\n", err);
1012 return err;
1013 }
1014
1015 pm_runtime_enable(&pdev->dev);
1016
1017 return 0;
1018 }
1019
tegra_admaif_remove(struct platform_device * pdev)1020 static void tegra_admaif_remove(struct platform_device *pdev)
1021 {
1022 tegra_isomgr_adma_unregister(&pdev->dev);
1023 pm_runtime_disable(&pdev->dev);
1024 }
1025
1026 static const struct dev_pm_ops tegra_admaif_pm_ops = {
1027 RUNTIME_PM_OPS(tegra_admaif_runtime_suspend,
1028 tegra_admaif_runtime_resume, NULL)
1029 SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
1030 };
1031
1032 static struct platform_driver tegra_admaif_driver = {
1033 .probe = tegra_admaif_probe,
1034 .remove = tegra_admaif_remove,
1035 .driver = {
1036 .name = "tegra210-admaif",
1037 .of_match_table = tegra_admaif_of_match,
1038 .pm = pm_ptr(&tegra_admaif_pm_ops),
1039 },
1040 };
1041 module_platform_driver(tegra_admaif_driver);
1042
1043 MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>");
1044 MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver");
1045 MODULE_LICENSE("GPL v2");
1046