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