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 const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
423	.hw_params	= tegra_admaif_hw_params,
424	.trigger	= tegra_admaif_trigger,
425};
426
427static 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
440static 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
456static 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
469static 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
485static 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
498static 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
514static 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
527static 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
543static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
544{
545	struct tegra_admaif *admaif = snd_soc_dai_get_drvdata(dai);
546
547	dai->capture_dma_data = &admaif->capture_dma_data[dai->id];
548	dai->playback_dma_data = &admaif->playback_dma_data[dai->id];
549
550	return 0;
551}
552
553#define DAI(dai_name)					\
554	{							\
555		.name = dai_name,				\
556		.probe = tegra_admaif_dai_probe,		\
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	.pcm_destruct		= tegra_pcm_destruct,
696	.open			= tegra_pcm_open,
697	.close			= tegra_pcm_close,
698	.hw_params		= tegra_pcm_hw_params,
699	.hw_free		= tegra_pcm_hw_free,
700	.mmap			= tegra_pcm_mmap,
701	.pointer		= tegra_pcm_pointer,
702};
703
704static const struct snd_soc_component_driver tegra186_admaif_cmpnt = {
705	.controls		= tegra186_admaif_controls,
706	.num_controls		= ARRAY_SIZE(tegra186_admaif_controls),
707	.pcm_construct		= tegra_pcm_construct,
708	.pcm_destruct		= tegra_pcm_destruct,
709	.open			= tegra_pcm_open,
710	.close			= tegra_pcm_close,
711	.hw_params		= tegra_pcm_hw_params,
712	.hw_free		= tegra_pcm_hw_free,
713	.mmap			= tegra_pcm_mmap,
714	.pointer		= tegra_pcm_pointer,
715};
716
717static const struct tegra_admaif_soc_data soc_data_tegra210 = {
718	.num_ch		= TEGRA210_ADMAIF_CHANNEL_COUNT,
719	.cmpnt		= &tegra210_admaif_cmpnt,
720	.dais		= tegra210_admaif_cmpnt_dais,
721	.regmap_conf	= &tegra210_admaif_regmap_config,
722	.global_base	= TEGRA210_ADMAIF_GLOBAL_BASE,
723	.tx_base	= TEGRA210_ADMAIF_TX_BASE,
724	.rx_base	= TEGRA210_ADMAIF_RX_BASE,
725};
726
727static const struct tegra_admaif_soc_data soc_data_tegra186 = {
728	.num_ch		= TEGRA186_ADMAIF_CHANNEL_COUNT,
729	.cmpnt		= &tegra186_admaif_cmpnt,
730	.dais		= tegra186_admaif_cmpnt_dais,
731	.regmap_conf	= &tegra186_admaif_regmap_config,
732	.global_base	= TEGRA186_ADMAIF_GLOBAL_BASE,
733	.tx_base	= TEGRA186_ADMAIF_TX_BASE,
734	.rx_base	= TEGRA186_ADMAIF_RX_BASE,
735};
736
737static const struct of_device_id tegra_admaif_of_match[] = {
738	{ .compatible = "nvidia,tegra210-admaif", .data = &soc_data_tegra210 },
739	{ .compatible = "nvidia,tegra186-admaif", .data = &soc_data_tegra186 },
740	{},
741};
742MODULE_DEVICE_TABLE(of, tegra_admaif_of_match);
743
744static int tegra_admaif_probe(struct platform_device *pdev)
745{
746	struct tegra_admaif *admaif;
747	void __iomem *regs;
748	struct resource *res;
749	int err, i;
750
751	admaif = devm_kzalloc(&pdev->dev, sizeof(*admaif), GFP_KERNEL);
752	if (!admaif)
753		return -ENOMEM;
754
755	admaif->soc_data = of_device_get_match_data(&pdev->dev);
756
757	dev_set_drvdata(&pdev->dev, admaif);
758
759	admaif->capture_dma_data =
760		devm_kcalloc(&pdev->dev,
761			     admaif->soc_data->num_ch,
762			     sizeof(struct snd_dmaengine_dai_dma_data),
763			     GFP_KERNEL);
764	if (!admaif->capture_dma_data)
765		return -ENOMEM;
766
767	admaif->playback_dma_data =
768		devm_kcalloc(&pdev->dev,
769			     admaif->soc_data->num_ch,
770			     sizeof(struct snd_dmaengine_dai_dma_data),
771			     GFP_KERNEL);
772	if (!admaif->playback_dma_data)
773		return -ENOMEM;
774
775	for (i = 0; i < ADMAIF_PATHS; i++) {
776		admaif->mono_to_stereo[i] =
777			devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
778				     sizeof(unsigned int), GFP_KERNEL);
779		if (!admaif->mono_to_stereo[i])
780			return -ENOMEM;
781
782		admaif->stereo_to_mono[i] =
783			devm_kcalloc(&pdev->dev, admaif->soc_data->num_ch,
784				     sizeof(unsigned int), GFP_KERNEL);
785		if (!admaif->stereo_to_mono[i])
786			return -ENOMEM;
787	}
788
789	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
790
791	regs = devm_ioremap_resource(&pdev->dev, res);
792	if (IS_ERR(regs))
793		return PTR_ERR(regs);
794
795	admaif->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
796					       admaif->soc_data->regmap_conf);
797	if (IS_ERR(admaif->regmap)) {
798		dev_err(&pdev->dev, "regmap init failed\n");
799		return PTR_ERR(admaif->regmap);
800	}
801
802	regcache_cache_only(admaif->regmap, true);
803
804	regmap_update_bits(admaif->regmap, admaif->soc_data->global_base +
805			   TEGRA_ADMAIF_GLOBAL_ENABLE, 1, 1);
806
807	for (i = 0; i < admaif->soc_data->num_ch; i++) {
808		admaif->playback_dma_data[i].addr = res->start +
809			CH_TX_REG(TEGRA_ADMAIF_TX_FIFO_WRITE, i);
810
811		admaif->capture_dma_data[i].addr = res->start +
812			CH_RX_REG(TEGRA_ADMAIF_RX_FIFO_READ, i);
813
814		admaif->playback_dma_data[i].addr_width = 32;
815
816		if (of_property_read_string_index(pdev->dev.of_node,
817				"dma-names", (i * 2) + 1,
818				&admaif->playback_dma_data[i].chan_name) < 0) {
819			dev_err(&pdev->dev,
820				"missing property nvidia,dma-names\n");
821
822			return -ENODEV;
823		}
824
825		admaif->capture_dma_data[i].addr_width = 32;
826
827		if (of_property_read_string_index(pdev->dev.of_node,
828				"dma-names",
829				(i * 2),
830				&admaif->capture_dma_data[i].chan_name) < 0) {
831			dev_err(&pdev->dev,
832				"missing property nvidia,dma-names\n");
833
834			return -ENODEV;
835		}
836	}
837
838	err = devm_snd_soc_register_component(&pdev->dev,
839					      admaif->soc_data->cmpnt,
840					      admaif->soc_data->dais,
841					      admaif->soc_data->num_ch);
842	if (err) {
843		dev_err(&pdev->dev,
844			"can't register ADMAIF component, err: %d\n", err);
845		return err;
846	}
847
848	pm_runtime_enable(&pdev->dev);
849
850	return 0;
851}
852
853static int tegra_admaif_remove(struct platform_device *pdev)
854{
855	pm_runtime_disable(&pdev->dev);
856
857	return 0;
858}
859
860static const struct dev_pm_ops tegra_admaif_pm_ops = {
861	SET_RUNTIME_PM_OPS(tegra_admaif_runtime_suspend,
862			   tegra_admaif_runtime_resume, NULL)
863	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
864				pm_runtime_force_resume)
865};
866
867static struct platform_driver tegra_admaif_driver = {
868	.probe = tegra_admaif_probe,
869	.remove = tegra_admaif_remove,
870	.driver = {
871		.name = "tegra210-admaif",
872		.of_match_table = tegra_admaif_of_match,
873		.pm = &tegra_admaif_pm_ops,
874	},
875};
876module_platform_driver(tegra_admaif_driver);
877
878MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>");
879MODULE_DESCRIPTION("Tegra210 ASoC ADMAIF driver");
880MODULE_LICENSE("GPL v2");
881