1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 */
4
5/*
6 * Vortex PCM ALSA driver.
7 *
8 * Supports ADB and WT DMA. Unfortunately, WT channels do not run yet.
9 * It remains stuck,and DMA transfers do not happen.
10 */
11#include <sound/asoundef.h>
12#include <linux/time.h>
13#include <sound/core.h>
14#include <sound/pcm.h>
15#include <sound/pcm_params.h>
16#include "au88x0.h"
17
18#define VORTEX_PCM_TYPE(x) (x->name[40])
19
20/* hardware definition */
21static const struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
22	.info =
23	    (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
24	     SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
25	     SNDRV_PCM_INFO_MMAP_VALID),
26	.formats =
27	    SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
28	    SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
29	.rates = SNDRV_PCM_RATE_CONTINUOUS,
30	.rate_min = 5000,
31	.rate_max = 48000,
32	.channels_min = 1,
33	.channels_max = 2,
34	.buffer_bytes_max = 0x10000,
35	.period_bytes_min = 0x20,
36	.period_bytes_max = 0x1000,
37	.periods_min = 2,
38	.periods_max = 1024,
39};
40
41#ifndef CHIP_AU8820
42static const struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
43	.info =
44	    (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
45	     SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
46	     SNDRV_PCM_INFO_MMAP_VALID),
47	.formats =
48	    SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
49	    SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
50	.rates = SNDRV_PCM_RATE_CONTINUOUS,
51	.rate_min = 5000,
52	.rate_max = 48000,
53	.channels_min = 1,
54	.channels_max = 1,
55	.buffer_bytes_max = 0x10000,
56	.period_bytes_min = 0x100,
57	.period_bytes_max = 0x1000,
58	.periods_min = 2,
59	.periods_max = 64,
60};
61#endif
62static const struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
63	.info =
64	    (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
65	     SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
66	     SNDRV_PCM_INFO_MMAP_VALID),
67	.formats =
68	    SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
69	    SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | SNDRV_PCM_FMTBIT_MU_LAW |
70	    SNDRV_PCM_FMTBIT_A_LAW,
71	.rates =
72	    SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
73	.rate_min = 32000,
74	.rate_max = 48000,
75	.channels_min = 1,
76	.channels_max = 2,
77	.buffer_bytes_max = 0x10000,
78	.period_bytes_min = 0x100,
79	.period_bytes_max = 0x1000,
80	.periods_min = 2,
81	.periods_max = 64,
82};
83
84#ifndef CHIP_AU8810
85static const struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
86	.info = (SNDRV_PCM_INFO_MMAP |
87		 SNDRV_PCM_INFO_INTERLEAVED |
88		 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
89	.formats = SNDRV_PCM_FMTBIT_S16_LE,
90	.rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS,	// SNDRV_PCM_RATE_48000,
91	.rate_min = 8000,
92	.rate_max = 48000,
93	.channels_min = 1,
94	.channels_max = 2,
95	.buffer_bytes_max = 0x10000,
96	.period_bytes_min = 0x0400,
97	.period_bytes_max = 0x1000,
98	.periods_min = 2,
99	.periods_max = 64,
100};
101#endif
102#ifdef CHIP_AU8830
103static const unsigned int au8830_channels[3] = {
104	1, 2, 4,
105};
106
107static const struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
108	.count = ARRAY_SIZE(au8830_channels),
109	.list = au8830_channels,
110	.mask = 0,
111};
112#endif
113
114static void vortex_notify_pcm_vol_change(struct snd_card *card,
115			struct snd_kcontrol *kctl, int activate)
116{
117	if (activate)
118		kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
119	else
120		kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
121	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
122				SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
123}
124
125/* open callback */
126static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
127{
128	vortex_t *vortex = snd_pcm_substream_chip(substream);
129	struct snd_pcm_runtime *runtime = substream->runtime;
130	int err;
131
132	/* Force equal size periods */
133	err = snd_pcm_hw_constraint_integer(runtime,
134					    SNDRV_PCM_HW_PARAM_PERIODS);
135	if (err < 0)
136		return err;
137	/* Avoid PAGE_SIZE boundary to fall inside of a period. */
138	err = snd_pcm_hw_constraint_pow2(runtime, 0,
139					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES);
140	if (err < 0)
141		return err;
142
143	snd_pcm_hw_constraint_step(runtime, 0,
144					SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 64);
145
146	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
147#ifndef CHIP_AU8820
148		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
149			runtime->hw = snd_vortex_playback_hw_a3d;
150		}
151#endif
152		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_SPDIF) {
153			runtime->hw = snd_vortex_playback_hw_spdif;
154			switch (vortex->spdif_sr) {
155			case 32000:
156				runtime->hw.rates = SNDRV_PCM_RATE_32000;
157				break;
158			case 44100:
159				runtime->hw.rates = SNDRV_PCM_RATE_44100;
160				break;
161			case 48000:
162				runtime->hw.rates = SNDRV_PCM_RATE_48000;
163				break;
164			}
165		}
166		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
167		    || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
168			runtime->hw = snd_vortex_playback_hw_adb;
169#ifdef CHIP_AU8830
170		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
171			VORTEX_IS_QUAD(vortex) &&
172			VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
173			runtime->hw.channels_max = 4;
174			snd_pcm_hw_constraint_list(runtime, 0,
175				SNDRV_PCM_HW_PARAM_CHANNELS,
176				&hw_constraints_au8830_channels);
177		}
178#endif
179		substream->runtime->private_data = NULL;
180	}
181#ifndef CHIP_AU8810
182	else {
183		runtime->hw = snd_vortex_playback_hw_wt;
184		substream->runtime->private_data = NULL;
185	}
186#endif
187	return 0;
188}
189
190/* close callback */
191static int snd_vortex_pcm_close(struct snd_pcm_substream *substream)
192{
193	//vortex_t *chip = snd_pcm_substream_chip(substream);
194	stream_t *stream = (stream_t *) substream->runtime->private_data;
195
196	// the hardware-specific codes will be here
197	if (stream != NULL) {
198		stream->substream = NULL;
199		stream->nr_ch = 0;
200	}
201	substream->runtime->private_data = NULL;
202	return 0;
203}
204
205/* hw_params callback */
206static int
207snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
208			 struct snd_pcm_hw_params *hw_params)
209{
210	vortex_t *chip = snd_pcm_substream_chip(substream);
211	stream_t *stream = (stream_t *) (substream->runtime->private_data);
212
213	/*
214	   pr_info( "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
215	   params_period_bytes(hw_params), params_channels(hw_params));
216	 */
217	spin_lock_irq(&chip->lock);
218	// Make audio routes and config buffer DMA.
219	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
220		int dma, type = VORTEX_PCM_TYPE(substream->pcm);
221		/* Dealloc any routes. */
222		if (stream != NULL)
223			vortex_adb_allocroute(chip, stream->dma,
224					      stream->nr_ch, stream->dir,
225					      stream->type,
226					      substream->number);
227		/* Alloc routes. */
228		dma =
229		    vortex_adb_allocroute(chip, -1,
230					  params_channels(hw_params),
231					  substream->stream, type,
232					  substream->number);
233		if (dma < 0) {
234			spin_unlock_irq(&chip->lock);
235			return dma;
236		}
237		stream = substream->runtime->private_data = &chip->dma_adb[dma];
238		stream->substream = substream;
239		/* Setup Buffers. */
240		vortex_adbdma_setbuffers(chip, dma,
241					 params_period_bytes(hw_params),
242					 params_periods(hw_params));
243		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
244			chip->pcm_vol[substream->number].active = 1;
245			vortex_notify_pcm_vol_change(chip->card,
246				chip->pcm_vol[substream->number].kctl, 1);
247		}
248	}
249#ifndef CHIP_AU8810
250	else {
251		/* if (stream != NULL)
252		   vortex_wt_allocroute(chip, substream->number, 0); */
253		vortex_wt_allocroute(chip, substream->number,
254				     params_channels(hw_params));
255		stream = substream->runtime->private_data =
256		    &chip->dma_wt[substream->number];
257		stream->dma = substream->number;
258		stream->substream = substream;
259		vortex_wtdma_setbuffers(chip, substream->number,
260					params_period_bytes(hw_params),
261					params_periods(hw_params));
262	}
263#endif
264	spin_unlock_irq(&chip->lock);
265	return 0;
266}
267
268/* hw_free callback */
269static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
270{
271	vortex_t *chip = snd_pcm_substream_chip(substream);
272	stream_t *stream = (stream_t *) (substream->runtime->private_data);
273
274	spin_lock_irq(&chip->lock);
275	// Delete audio routes.
276	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
277		if (stream != NULL) {
278			if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
279				chip->pcm_vol[substream->number].active = 0;
280				vortex_notify_pcm_vol_change(chip->card,
281					chip->pcm_vol[substream->number].kctl,
282					0);
283			}
284			vortex_adb_allocroute(chip, stream->dma,
285					      stream->nr_ch, stream->dir,
286					      stream->type,
287					      substream->number);
288		}
289	}
290#ifndef CHIP_AU8810
291	else {
292		if (stream != NULL)
293			vortex_wt_allocroute(chip, stream->dma, 0);
294	}
295#endif
296	substream->runtime->private_data = NULL;
297	spin_unlock_irq(&chip->lock);
298
299	return 0;
300}
301
302/* prepare callback */
303static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream)
304{
305	vortex_t *chip = snd_pcm_substream_chip(substream);
306	struct snd_pcm_runtime *runtime = substream->runtime;
307	stream_t *stream = (stream_t *) substream->runtime->private_data;
308	int dma = stream->dma, fmt, dir;
309
310	// set up the hardware with the current configuration.
311	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
312		dir = 1;
313	else
314		dir = 0;
315	fmt = vortex_alsafmt_aspfmt(runtime->format, chip);
316	spin_lock_irq(&chip->lock);
317	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
318		vortex_adbdma_setmode(chip, dma, 1, dir, fmt,
319				runtime->channels == 1 ? 0 : 1, 0);
320		vortex_adbdma_setstartbuffer(chip, dma, 0);
321		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_SPDIF)
322			vortex_adb_setsrc(chip, dma, runtime->rate, dir);
323	}
324#ifndef CHIP_AU8810
325	else {
326		vortex_wtdma_setmode(chip, dma, 1, fmt, 0, 0);
327		// FIXME: Set rate (i guess using vortex_wt_writereg() somehow).
328		vortex_wtdma_setstartbuffer(chip, dma, 0);
329	}
330#endif
331	spin_unlock_irq(&chip->lock);
332	return 0;
333}
334
335/* trigger callback */
336static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
337{
338	vortex_t *chip = snd_pcm_substream_chip(substream);
339	stream_t *stream = (stream_t *) substream->runtime->private_data;
340	int dma = stream->dma;
341
342	spin_lock(&chip->lock);
343	switch (cmd) {
344	case SNDRV_PCM_TRIGGER_START:
345		// do something to start the PCM engine
346		//printk(KERN_INFO "vortex: start %d\n", dma);
347		stream->fifo_enabled = 1;
348		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
349			vortex_adbdma_resetup(chip, dma);
350			vortex_adbdma_startfifo(chip, dma);
351		}
352#ifndef CHIP_AU8810
353		else {
354			dev_info(chip->card->dev, "wt start %d\n", dma);
355			vortex_wtdma_startfifo(chip, dma);
356		}
357#endif
358		break;
359	case SNDRV_PCM_TRIGGER_STOP:
360		// do something to stop the PCM engine
361		//printk(KERN_INFO "vortex: stop %d\n", dma);
362		stream->fifo_enabled = 0;
363		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
364			vortex_adbdma_stopfifo(chip, dma);
365#ifndef CHIP_AU8810
366		else {
367			dev_info(chip->card->dev, "wt stop %d\n", dma);
368			vortex_wtdma_stopfifo(chip, dma);
369		}
370#endif
371		break;
372	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
373		//printk(KERN_INFO "vortex: pause %d\n", dma);
374		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
375			vortex_adbdma_pausefifo(chip, dma);
376#ifndef CHIP_AU8810
377		else
378			vortex_wtdma_pausefifo(chip, dma);
379#endif
380		break;
381	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
382		//printk(KERN_INFO "vortex: resume %d\n", dma);
383		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
384			vortex_adbdma_resumefifo(chip, dma);
385#ifndef CHIP_AU8810
386		else
387			vortex_wtdma_resumefifo(chip, dma);
388#endif
389		break;
390	default:
391		spin_unlock(&chip->lock);
392		return -EINVAL;
393	}
394	spin_unlock(&chip->lock);
395	return 0;
396}
397
398/* pointer callback */
399static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substream)
400{
401	vortex_t *chip = snd_pcm_substream_chip(substream);
402	stream_t *stream = (stream_t *) substream->runtime->private_data;
403	int dma = stream->dma;
404	snd_pcm_uframes_t current_ptr = 0;
405
406	spin_lock(&chip->lock);
407	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
408		current_ptr = vortex_adbdma_getlinearpos(chip, dma);
409#ifndef CHIP_AU8810
410	else
411		current_ptr = vortex_wtdma_getlinearpos(chip, dma);
412#endif
413	//printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);
414	spin_unlock(&chip->lock);
415	current_ptr = bytes_to_frames(substream->runtime, current_ptr);
416	if (current_ptr >= substream->runtime->buffer_size)
417		current_ptr = 0;
418	return current_ptr;
419}
420
421/* operators */
422static const struct snd_pcm_ops snd_vortex_playback_ops = {
423	.open = snd_vortex_pcm_open,
424	.close = snd_vortex_pcm_close,
425	.hw_params = snd_vortex_pcm_hw_params,
426	.hw_free = snd_vortex_pcm_hw_free,
427	.prepare = snd_vortex_pcm_prepare,
428	.trigger = snd_vortex_pcm_trigger,
429	.pointer = snd_vortex_pcm_pointer,
430};
431
432/*
433*  definitions of capture are omitted here...
434*/
435
436static const char * const vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
437	CARD_NAME " ADB",
438	CARD_NAME " SPDIF",
439	CARD_NAME " A3D",
440	CARD_NAME " WT",
441	CARD_NAME " I2S",
442};
443static const char * const vortex_pcm_name[VORTEX_PCM_LAST] = {
444	"adb",
445	"spdif",
446	"a3d",
447	"wt",
448	"i2s",
449};
450
451/* SPDIF kcontrol */
452
453static int snd_vortex_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
454{
455	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
456	uinfo->count = 1;
457	return 0;
458}
459
460static int snd_vortex_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
461{
462	ucontrol->value.iec958.status[0] = 0xff;
463	ucontrol->value.iec958.status[1] = 0xff;
464	ucontrol->value.iec958.status[2] = 0xff;
465	ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
466	return 0;
467}
468
469static int snd_vortex_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
470{
471	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
472	ucontrol->value.iec958.status[0] = 0x00;
473	ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL|IEC958_AES1_CON_DIGDIGCONV_ID;
474	ucontrol->value.iec958.status[2] = 0x00;
475	switch (vortex->spdif_sr) {
476	case 32000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_32000; break;
477	case 44100: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_44100; break;
478	case 48000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000; break;
479	}
480	return 0;
481}
482
483static int snd_vortex_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
484{
485	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
486	int spdif_sr = 48000;
487	switch (ucontrol->value.iec958.status[3] & IEC958_AES3_CON_FS) {
488	case IEC958_AES3_CON_FS_32000: spdif_sr = 32000; break;
489	case IEC958_AES3_CON_FS_44100: spdif_sr = 44100; break;
490	case IEC958_AES3_CON_FS_48000: spdif_sr = 48000; break;
491	}
492	if (spdif_sr == vortex->spdif_sr)
493		return 0;
494	vortex->spdif_sr = spdif_sr;
495	vortex_spdif_init(vortex, vortex->spdif_sr, 1);
496	return 1;
497}
498
499/* spdif controls */
500static const struct snd_kcontrol_new snd_vortex_mixer_spdif[] = {
501	{
502		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
503		.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
504		.info =		snd_vortex_spdif_info,
505		.get =		snd_vortex_spdif_get,
506		.put =		snd_vortex_spdif_put,
507	},
508	{
509		.access =	SNDRV_CTL_ELEM_ACCESS_READ,
510		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
511		.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
512		.info =		snd_vortex_spdif_info,
513		.get =		snd_vortex_spdif_mask_get
514	},
515};
516
517/* subdevice PCM Volume control */
518
519static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
520				struct snd_ctl_elem_info *uinfo)
521{
522	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
523	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
524	uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
525	uinfo->value.integer.min = -128;
526	uinfo->value.integer.max = 32;
527	return 0;
528}
529
530static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
531				struct snd_ctl_elem_value *ucontrol)
532{
533	int i;
534	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
535	int subdev = kcontrol->id.subdevice;
536	struct pcm_vol *p = &vortex->pcm_vol[subdev];
537	int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
538	for (i = 0; i < max_chn; i++)
539		ucontrol->value.integer.value[i] = p->vol[i];
540	return 0;
541}
542
543static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
544				struct snd_ctl_elem_value *ucontrol)
545{
546	int i;
547	int changed = 0;
548	int mixin;
549	unsigned char vol;
550	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
551	int subdev = kcontrol->id.subdevice;
552	struct pcm_vol *p = &vortex->pcm_vol[subdev];
553	int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
554	for (i = 0; i < max_chn; i++) {
555		if (p->vol[i] != ucontrol->value.integer.value[i]) {
556			p->vol[i] = ucontrol->value.integer.value[i];
557			if (p->active) {
558				switch (vortex->dma_adb[p->dma].nr_ch) {
559				case 1:
560					mixin = p->mixin[0];
561					break;
562				case 2:
563				default:
564					mixin = p->mixin[(i < 2) ? i : (i - 2)];
565					break;
566				case 4:
567					mixin = p->mixin[i];
568					break;
569				}
570				vol = p->vol[i];
571				vortex_mix_setinputvolumebyte(vortex,
572					vortex->mixplayb[i], mixin, vol);
573			}
574			changed = 1;
575		}
576	}
577	return changed;
578}
579
580static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);
581
582static const struct snd_kcontrol_new snd_vortex_pcm_vol = {
583	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
584	.name = "PCM Playback Volume",
585	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
586		SNDRV_CTL_ELEM_ACCESS_TLV_READ |
587		SNDRV_CTL_ELEM_ACCESS_INACTIVE,
588	.info = snd_vortex_pcm_vol_info,
589	.get = snd_vortex_pcm_vol_get,
590	.put = snd_vortex_pcm_vol_put,
591	.tlv = { .p = vortex_pcm_vol_db_scale },
592};
593
594/* create a pcm device */
595static int snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
596{
597	struct snd_pcm *pcm;
598	struct snd_kcontrol *kctl;
599	int i;
600	int err, nr_capt;
601
602	if (!chip || idx < 0 || idx >= VORTEX_PCM_LAST)
603		return -ENODEV;
604
605	/* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the
606	 * same dma engine. WT uses it own separate dma engine which can't capture. */
607	if (idx == VORTEX_PCM_ADB)
608		nr_capt = nr;
609	else
610		nr_capt = 0;
611	err = snd_pcm_new(chip->card, vortex_pcm_prettyname[idx], idx, nr,
612			  nr_capt, &pcm);
613	if (err < 0)
614		return err;
615	snprintf(pcm->name, sizeof(pcm->name),
616		"%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
617	chip->pcm[idx] = pcm;
618	// This is an evil hack, but it saves a lot of duplicated code.
619	VORTEX_PCM_TYPE(pcm) = idx;
620	pcm->private_data = chip;
621	/* set operators */
622	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
623			&snd_vortex_playback_ops);
624	if (idx == VORTEX_PCM_ADB)
625		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
626				&snd_vortex_playback_ops);
627
628	/* pre-allocation of Scatter-Gather buffers */
629
630	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
631				       &chip->pci_dev->dev, 0x10000, 0x10000);
632
633	switch (VORTEX_PCM_TYPE(pcm)) {
634	case VORTEX_PCM_ADB:
635		err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
636					     snd_pcm_std_chmaps,
637					     VORTEX_IS_QUAD(chip) ? 4 : 2,
638					     0, NULL);
639		if (err < 0)
640			return err;
641		err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
642					     snd_pcm_std_chmaps, 2, 0, NULL);
643		if (err < 0)
644			return err;
645		break;
646#ifdef CHIP_AU8830
647	case VORTEX_PCM_A3D:
648		err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
649					     snd_pcm_std_chmaps, 1, 0, NULL);
650		if (err < 0)
651			return err;
652		break;
653#endif
654	}
655
656	if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_SPDIF) {
657		for (i = 0; i < ARRAY_SIZE(snd_vortex_mixer_spdif); i++) {
658			kctl = snd_ctl_new1(&snd_vortex_mixer_spdif[i], chip);
659			if (!kctl)
660				return -ENOMEM;
661			err = snd_ctl_add(chip->card, kctl);
662			if (err < 0)
663				return err;
664		}
665	}
666	if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
667		for (i = 0; i < NR_PCM; i++) {
668			chip->pcm_vol[i].active = 0;
669			chip->pcm_vol[i].dma = -1;
670			kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
671			if (!kctl)
672				return -ENOMEM;
673			chip->pcm_vol[i].kctl = kctl;
674			kctl->id.device = 0;
675			kctl->id.subdevice = i;
676			err = snd_ctl_add(chip->card, kctl);
677			if (err < 0)
678				return err;
679		}
680	}
681	return 0;
682}
683