xref: /linux/sound/soc/tegra/tegra210_admaif.c (revision 3fd6c59042dbba50391e30862beac979491145fe)
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