1 // SPDX-License-Identifier: GPL-2.0-only
2 // SPDX-FileCopyrightText: Copyright (c) 2020-2024 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 "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
tegra_admaif_wr_reg(struct device * dev,unsigned int reg)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
tegra_admaif_rd_reg(struct device * dev,unsigned int reg)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
tegra_admaif_volatile_reg(struct device * dev,unsigned int reg)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
tegra_admaif_runtime_suspend(struct device * dev)222 static int __maybe_unused 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
tegra_admaif_runtime_resume(struct device * dev)232 static int __maybe_unused 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
tegra_admaif_set_pack_mode(struct regmap * map,unsigned int reg,int valid_bit)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
tegra_admaif_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)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_S24_LE:
289 cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
290 cif_conf.client_bits = TEGRA_ACIF_BITS_24;
291 valid_bit = DATA_32BIT;
292 break;
293 case SNDRV_PCM_FORMAT_S32_LE:
294 cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
295 cif_conf.client_bits = TEGRA_ACIF_BITS_32;
296 valid_bit = DATA_32BIT;
297 break;
298 default:
299 dev_err(dev, "unsupported format!\n");
300 return -EOPNOTSUPP;
301 }
302
303 channels = params_channels(params);
304 cif_conf.client_ch = channels;
305 cif_conf.audio_ch = channels;
306
307 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
308 path = ADMAIF_TX_PATH;
309 reg = CH_TX_REG(TEGRA_ADMAIF_CH_ACIF_TX_CTRL, dai->id);
310 } else {
311 path = ADMAIF_RX_PATH;
312 reg = CH_RX_REG(TEGRA_ADMAIF_CH_ACIF_RX_CTRL, dai->id);
313 }
314
315 cif_conf.mono_conv = admaif->mono_to_stereo[path][dai->id];
316 cif_conf.stereo_conv = admaif->stereo_to_mono[path][dai->id];
317
318 tegra_admaif_set_pack_mode(admaif->regmap, reg, valid_bit);
319
320 tegra_set_cif(admaif->regmap, reg, &cif_conf);
321
322 return 0;
323 }
324
tegra_admaif_start(struct snd_soc_dai * dai,int direction)325 static int tegra_admaif_start(struct snd_soc_dai *dai, int direction)
326 {
327 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
328 unsigned int reg, mask, val;
329
330 switch (direction) {
331 case SNDRV_PCM_STREAM_PLAYBACK:
332 mask = TX_ENABLE_MASK;
333 val = TX_ENABLE;
334 reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
335 break;
336 case SNDRV_PCM_STREAM_CAPTURE:
337 mask = RX_ENABLE_MASK;
338 val = RX_ENABLE;
339 reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
340 break;
341 default:
342 return -EINVAL;
343 }
344
345 regmap_update_bits(admaif->regmap, reg, mask, val);
346
347 return 0;
348 }
349
tegra_admaif_stop(struct snd_soc_dai * dai,int direction)350 static int tegra_admaif_stop(struct snd_soc_dai *dai, int direction)
351 {
352 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
353 unsigned int enable_reg, status_reg, reset_reg, mask, val;
354 char *dir_name;
355 int err, enable;
356
357 switch (direction) {
358 case SNDRV_PCM_STREAM_PLAYBACK:
359 mask = TX_ENABLE_MASK;
360 enable = TX_ENABLE;
361 dir_name = "TX";
362 enable_reg = CH_TX_REG(TEGRA_ADMAIF_TX_ENABLE, dai->id);
363 status_reg = CH_TX_REG(TEGRA_ADMAIF_TX_STATUS, dai->id);
364 reset_reg = CH_TX_REG(TEGRA_ADMAIF_TX_SOFT_RESET, dai->id);
365 break;
366 case SNDRV_PCM_STREAM_CAPTURE:
367 mask = RX_ENABLE_MASK;
368 enable = RX_ENABLE;
369 dir_name = "RX";
370 enable_reg = CH_RX_REG(TEGRA_ADMAIF_RX_ENABLE, dai->id);
371 status_reg = CH_RX_REG(TEGRA_ADMAIF_RX_STATUS, dai->id);
372 reset_reg = CH_RX_REG(TEGRA_ADMAIF_RX_SOFT_RESET, dai->id);
373 break;
374 default:
375 return -EINVAL;
376 }
377
378 /* Disable TX/RX channel */
379 regmap_update_bits(admaif->regmap, enable_reg, mask, ~enable);
380
381 /* Wait until ADMAIF TX/RX status is disabled */
382 err = regmap_read_poll_timeout_atomic(admaif->regmap, status_reg, val,
383 !(val & enable), 10, 10000);
384 if (err < 0)
385 dev_warn(dai->dev, "timeout: failed to disable ADMAIF%d_%s\n",
386 dai->id + 1, dir_name);
387
388 /* SW reset */
389 regmap_update_bits(admaif->regmap, reset_reg, SW_RESET_MASK, SW_RESET);
390
391 /* Wait till SW reset is complete */
392 err = regmap_read_poll_timeout_atomic(admaif->regmap, reset_reg, val,
393 !(val & SW_RESET_MASK & SW_RESET),
394 10, 10000);
395 if (err) {
396 dev_err(dai->dev, "timeout: SW reset failed for ADMAIF%d_%s\n",
397 dai->id + 1, dir_name);
398 return err;
399 }
400
401 return 0;
402 }
403
tegra_admaif_trigger(struct snd_pcm_substream * substream,int cmd,struct snd_soc_dai * dai)404 static int tegra_admaif_trigger(struct snd_pcm_substream *substream, int cmd,
405 struct snd_soc_dai *dai)
406 {
407 int err;
408
409 err = snd_dmaengine_pcm_trigger(substream, cmd);
410 if (err)
411 return err;
412
413 switch (cmd) {
414 case SNDRV_PCM_TRIGGER_START:
415 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
416 case SNDRV_PCM_TRIGGER_RESUME:
417 return tegra_admaif_start(dai, substream->stream);
418 case SNDRV_PCM_TRIGGER_STOP:
419 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
420 case SNDRV_PCM_TRIGGER_SUSPEND:
421 return tegra_admaif_stop(dai, substream->stream);
422 default:
423 return -EINVAL;
424 }
425 }
426
tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)427 static int tegra210_admaif_pget_mono_to_stereo(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 tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
432 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
433
434 ucontrol->value.enumerated.item[0] =
435 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
436
437 return 0;
438 }
439
tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)440 static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol,
441 struct snd_ctl_elem_value *ucontrol)
442 {
443 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
444 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
445 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
446 unsigned int value = ucontrol->value.enumerated.item[0];
447
448 if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg])
449 return 0;
450
451 admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
452
453 return 1;
454 }
455
tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)456 static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol,
457 struct snd_ctl_elem_value *ucontrol)
458 {
459 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
460 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
461 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
462
463 ucontrol->value.enumerated.item[0] =
464 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
465
466 return 0;
467 }
468
tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)469 static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_value *ucontrol)
471 {
472 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
473 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
474 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
475 unsigned int value = ucontrol->value.enumerated.item[0];
476
477 if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg])
478 return 0;
479
480 admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
481
482 return 1;
483 }
484
tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)485 static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
487 {
488 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
489 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
490 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
491
492 ucontrol->value.enumerated.item[0] =
493 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
494
495 return 0;
496 }
497
tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)498 static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol,
499 struct snd_ctl_elem_value *ucontrol)
500 {
501 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
502 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
503 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
504 unsigned int value = ucontrol->value.enumerated.item[0];
505
506 if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg])
507 return 0;
508
509 admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
510
511 return 1;
512 }
513
tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)514 static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol,
515 struct snd_ctl_elem_value *ucontrol)
516 {
517 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
518 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
519 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
520
521 ucontrol->value.enumerated.item[0] =
522 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
523
524 return 0;
525 }
526
tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)527 static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol,
528 struct snd_ctl_elem_value *ucontrol)
529 {
530 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
531 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
532 struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
533 unsigned int value = ucontrol->value.enumerated.item[0];
534
535 if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg])
536 return 0;
537
538 admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
539
540 return 1;
541 }
542
tegra_admaif_dai_probe(struct snd_soc_dai * dai)543 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
544 {
545 struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
546
547 snd_soc_dai_init_dma_data(dai, &admaif->playback_dma_data[dai->id],
548 &admaif->capture_dma_data[dai->id]);
549
550 return 0;
551 }
552
553 static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
554 .probe = tegra_admaif_dai_probe,
555 .hw_params = tegra_admaif_hw_params,
556 .trigger = tegra_admaif_trigger,
557 };
558
559 #define DAI(dai_name) \
560 { \
561 .name = dai_name, \
562 .playback = { \
563 .stream_name = dai_name " Playback", \
564 .channels_min = 1, \
565 .channels_max = 16, \
566 .rates = SNDRV_PCM_RATE_8000_192000, \
567 .formats = SNDRV_PCM_FMTBIT_S8 | \
568 SNDRV_PCM_FMTBIT_S16_LE | \
569 SNDRV_PCM_FMTBIT_S24_LE | \
570 SNDRV_PCM_FMTBIT_S32_LE, \
571 }, \
572 .capture = { \
573 .stream_name = dai_name " Capture", \
574 .channels_min = 1, \
575 .channels_max = 16, \
576 .rates = SNDRV_PCM_RATE_8000_192000, \
577 .formats = SNDRV_PCM_FMTBIT_S8 | \
578 SNDRV_PCM_FMTBIT_S16_LE | \
579 SNDRV_PCM_FMTBIT_S24_LE | \
580 SNDRV_PCM_FMTBIT_S32_LE, \
581 }, \
582 .ops = &tegra_admaif_dai_ops, \
583 }
584
585 static struct snd_soc_dai_driver tegra210_admaif_cmpnt_dais[] = {
586 DAI("ADMAIF1"),
587 DAI("ADMAIF2"),
588 DAI("ADMAIF3"),
589 DAI("ADMAIF4"),
590 DAI("ADMAIF5"),
591 DAI("ADMAIF6"),
592 DAI("ADMAIF7"),
593 DAI("ADMAIF8"),
594 DAI("ADMAIF9"),
595 DAI("ADMAIF10"),
596 };
597
598 static struct snd_soc_dai_driver tegra186_admaif_cmpnt_dais[] = {
599 DAI("ADMAIF1"),
600 DAI("ADMAIF2"),
601 DAI("ADMAIF3"),
602 DAI("ADMAIF4"),
603 DAI("ADMAIF5"),
604 DAI("ADMAIF6"),
605 DAI("ADMAIF7"),
606 DAI("ADMAIF8"),
607 DAI("ADMAIF9"),
608 DAI("ADMAIF10"),
609 DAI("ADMAIF11"),
610 DAI("ADMAIF12"),
611 DAI("ADMAIF13"),
612 DAI("ADMAIF14"),
613 DAI("ADMAIF15"),
614 DAI("ADMAIF16"),
615 DAI("ADMAIF17"),
616 DAI("ADMAIF18"),
617 DAI("ADMAIF19"),
618 DAI("ADMAIF20"),
619 };
620
621 static const char * const tegra_admaif_stereo_conv_text[] = {
622 "CH0", "CH1", "AVG",
623 };
624
625 static const char * const tegra_admaif_mono_conv_text[] = {
626 "Zero", "Copy",
627 };
628
629 /*
630 * Below macro is added to avoid looping over all ADMAIFx controls related
631 * to mono/stereo conversions in get()/put() callbacks.
632 */
633 #define NV_SOC_ENUM_EXT(xname, xreg, xhandler_get, xhandler_put, xenum_text) \
634 { \
635 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
636 .info = snd_soc_info_enum_double, \
637 .name = xname, \
638 .get = xhandler_get, \
639 .put = xhandler_put, \
640 .private_value = (unsigned long)&(struct soc_enum) \
641 SOC_ENUM_SINGLE(xreg, 0, ARRAY_SIZE(xenum_text), xenum_text) \
642 }
643
644 #define TEGRA_ADMAIF_CIF_CTRL(reg) \
645 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1, \
646 tegra210_admaif_pget_mono_to_stereo, \
647 tegra210_admaif_pput_mono_to_stereo, \
648 tegra_admaif_mono_conv_text), \
649 NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1, \
650 tegra210_admaif_pget_stereo_to_mono, \
651 tegra210_admaif_pput_stereo_to_mono, \
652 tegra_admaif_stereo_conv_text), \
653 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \
654 tegra210_admaif_cget_mono_to_stereo, \
655 tegra210_admaif_cput_mono_to_stereo, \
656 tegra_admaif_mono_conv_text), \
657 NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \
658 tegra210_admaif_cget_stereo_to_mono, \
659 tegra210_admaif_cput_stereo_to_mono, \
660 tegra_admaif_stereo_conv_text)
661
662 static struct snd_kcontrol_new tegra210_admaif_controls[] = {
663 TEGRA_ADMAIF_CIF_CTRL(1),
664 TEGRA_ADMAIF_CIF_CTRL(2),
665 TEGRA_ADMAIF_CIF_CTRL(3),
666 TEGRA_ADMAIF_CIF_CTRL(4),
667 TEGRA_ADMAIF_CIF_CTRL(5),
668 TEGRA_ADMAIF_CIF_CTRL(6),
669 TEGRA_ADMAIF_CIF_CTRL(7),
670 TEGRA_ADMAIF_CIF_CTRL(8),
671 TEGRA_ADMAIF_CIF_CTRL(9),
672 TEGRA_ADMAIF_CIF_CTRL(10),
673 };
674
675 static struct snd_kcontrol_new tegra186_admaif_controls[] = {
676 TEGRA_ADMAIF_CIF_CTRL(1),
677 TEGRA_ADMAIF_CIF_CTRL(2),
678 TEGRA_ADMAIF_CIF_CTRL(3),
679 TEGRA_ADMAIF_CIF_CTRL(4),
680 TEGRA_ADMAIF_CIF_CTRL(5),
681 TEGRA_ADMAIF_CIF_CTRL(6),
682 TEGRA_ADMAIF_CIF_CTRL(7),
683 TEGRA_ADMAIF_CIF_CTRL(8),
684 TEGRA_ADMAIF_CIF_CTRL(9),
685 TEGRA_ADMAIF_CIF_CTRL(10),
686 TEGRA_ADMAIF_CIF_CTRL(11),
687 TEGRA_ADMAIF_CIF_CTRL(12),
688 TEGRA_ADMAIF_CIF_CTRL(13),
689 TEGRA_ADMAIF_CIF_CTRL(14),
690 TEGRA_ADMAIF_CIF_CTRL(15),
691 TEGRA_ADMAIF_CIF_CTRL(16),
692 TEGRA_ADMAIF_CIF_CTRL(17),
693 TEGRA_ADMAIF_CIF_CTRL(18),
694 TEGRA_ADMAIF_CIF_CTRL(19),
695 TEGRA_ADMAIF_CIF_CTRL(20),
696 };
697
698 static const struct snd_soc_component_driver tegra210_admaif_cmpnt = {
699 .controls = tegra210_admaif_controls,
700 .num_controls = ARRAY_SIZE(tegra210_admaif_controls),
701 .pcm_construct = tegra_pcm_construct,
702 .open = tegra_pcm_open,
703 .close = tegra_pcm_close,
704 .hw_params = tegra_pcm_hw_params,
705 .pointer = tegra_pcm_pointer,
706 };
707
708 static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
709 .controls = tegra186_admaif_controls,
710 .num_controls = ARRAY_SIZE(tegra186_admaif_controls),
711 .pcm_construct = tegra_pcm_construct,
712 .open = tegra_pcm_open,
713 .close = tegra_pcm_close,
714 .hw_params = tegra_pcm_hw_params,
715 .pointer = tegra_pcm_pointer,
716 };
717
718 static const struct tegra_admaif_soc_data soc_data_tegra210 = {
719 .num_ch = TEGRA210_ADMAIF_CHANNEL_COUNT,
720 .cmpnt = &tegra210_admaif_cmpnt,
721 .dais = tegra210_admaif_cmpnt_dais,
722 .regmap_conf = &tegra210_admaif_regmap_config,
723 .global_base = TEGRA210_ADMAIF_GLOBAL_BASE,
724 .tx_base = TEGRA210_ADMAIF_TX_BASE,
725 .rx_base = TEGRA210_ADMAIF_RX_BASE,
726 };
727
728 static const struct tegra_admaif_soc_data soc_data_tegra186 = {
729 .num_ch = TEGRA186_ADMAIF_CHANNEL_COUNT,
730 .cmpnt = &tegra186_admaif_cmpnt,
731 .dais = tegra186_admaif_cmpnt_dais,
732 .regmap_conf = &tegra186_admaif_regmap_config,
733 .global_base = TEGRA186_ADMAIF_GLOBAL_BASE,
734 .tx_base = TEGRA186_ADMAIF_TX_BASE,
735 .rx_base = TEGRA186_ADMAIF_RX_BASE,
736 };
737
738 static const struct of_device_id tegra_admaif_of_match[] = {
739 { .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
740 { .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 },
741 {},
742 };
743 MODULE_DEVICE_TABLE(of, tegra_admaif_of_match);
744
tegra_admaif_probe(struct platform_device * pdev)745 static int tegra_admaif_probe(struct platform_device *pdev)
746 {
747 struct tegra_admaif *admaif;
748 void __iomem *regs;
749 struct resource *res;
750 int err, i;
751
752 admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
753 if (!admaif)
754 return -ENOMEM;
755
756 admaif->soc_data = of_device_get_match_data(&pdev->dev);
757
758 dev_set_drvdata(&pdev->dev, admaif);
759
760 admaif->capture_dma_data =
761 devm_kcalloc(&pdev->dev,
762 admaif->soc_data->num_ch,
763 sizeof(struct snd_dmaengine_dai_dma_data),
764 GFP_KERNEL);
765 if (!admaif->capture_dma_data)
766 return -ENOMEM;
767
768 admaif->playback_dma_data =
769 devm_kcalloc(&pdev->dev,
770 admaif->soc_data->num_ch,
771 sizeof(struct snd_dmaengine_dai_dma_data),
772 GFP_KERNEL);
773 if (!admaif->playback_dma_data)
774 return -ENOMEM;
775
776 for (i = 0; i < ADMAIF_PATHS; i++) {
777 admaif->mono_to_stereo[i] =
778 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
779 sizeof(unsigned int), GFP_KERNEL);
780 if (!admaif->mono_to_stereo[i])
781 return -ENOMEM;
782
783 admaif->stereo_to_mono[i] =
784 devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
785 sizeof(unsigned int), GFP_KERNEL);
786 if (!admaif->stereo_to_mono[i])
787 return -ENOMEM;
788 }
789
790 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
791 if (IS_ERR(regs))
792 return PTR_ERR(regs);
793
794 admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
795 admaif->soc_data->regmap_conf);
796 if (IS_ERR(admaif->regmap)) {
797 dev_err(&pdev->dev, "regmap init failed\n");
798 return PTR_ERR(admaif->regmap);
799 }
800
801 regcache_cache_only(admaif->regmap, true);
802
803 regmap_update_bits(admaif->regmap, admaif->soc_data->global_base +
804 TEGRA_ADMAIF_GLOBAL_ENABLE, 1, 1);
805
806 for (i = 0; i < admaif->soc_data->num_ch; i++) {
807 admaif->playback_dma_data[i].addr = res->start +
808 CH_TX_REG(TEGRA_ADMAIF_TX_FIFO_WRITE, i);
809
810 admaif->capture_dma_data[i].addr = res->start +
811 CH_RX_REG(TEGRA_ADMAIF_RX_FIFO_READ, i);
812
813 admaif->playback_dma_data[i].addr_width = 32;
814
815 if (of_property_read_string_index(pdev->dev.of_node,
816 "dma-names", (i * 2) + 1,
817 &admaif->playback_dma_data[i].chan_name) < 0) {
818 dev_err(&pdev->dev,
819 "missing property nvidia,dma-names\n");
820
821 return -ENODEV;
822 }
823
824 admaif->capture_dma_data[i].addr_width = 32;
825
826 if (of_property_read_string_index(pdev->dev.of_node,
827 "dma-names",
828 (i * 2),
829 &admaif->capture_dma_data[i].chan_name) < 0) {
830 dev_err(&pdev->dev,
831 "missing property nvidia,dma-names\n");
832
833 return -ENODEV;
834 }
835 }
836
837 err = devm_snd_soc_register_component(&pdev->dev,
838 admaif->soc_data->cmpnt,
839 admaif->soc_data->dais,
840 admaif->soc_data->num_ch);
841 if (err) {
842 dev_err(&pdev->dev,
843 "can't register ADMAIF component, err: %d\n", err);
844 return err;
845 }
846
847 pm_runtime_enable(&pdev->dev);
848
849 return 0;
850 }
851
tegra_admaif_remove(struct platform_device * pdev)852 static void tegra_admaif_remove(struct platform_device *pdev)
853 {
854 pm_runtime_disable(&pdev->dev);
855 }
856
857 static const struct dev_pm_ops tegra_admaif_pm_ops = {
858 SET_RUNTIME_PM_OPS(tegra_admaif_runtime_suspend,
859 tegra_admaif_runtime_resume, NULL)
860 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
861 pm_runtime_force_resume)
862 };
863
864 static struct platform_driver tegra_admaif_driver = {
865 .probe = tegra_admaif_probe,
866 .remove = tegra_admaif_remove,
867 .driver = {
868 .name = "tegra210-admaif",
869 .of_match_table = tegra_admaif_of_match,
870 .pm = &tegra_admaif_pm_ops,
871 },
872 };
873 module_platform_driver(tegra_admaif_driver);
874
875 MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>");
876 MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver");
877 MODULE_LICENSE("GPL v2");
878