// SPDX-License-Identifier: GPL-2.0-or-later
/*
 */
 
/*
 * Vortex PCM ALSA driver.
 *
 * Supports ADB and WT DMA. Unfortunately, WT channels do not run yet.
 * It remains stuck,and DMA transfers do not happen. 
 */
#include <sound/asoundef.h>
#include <linux/time.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "au88x0.h"

#define VORTEX_PCM_TYPE(x) (x->name[40])

/* hardware definition */
static const struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
	.info =
	    (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
	     SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
	     SNDRV_PCM_INFO_MMAP_VALID),
	.formats =
	    SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
	    SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
	.rates = SNDRV_PCM_RATE_CONTINUOUS,
	.rate_min = 5000,
	.rate_max = 48000,
	.channels_min = 1,
	.channels_max = 2,
	.buffer_bytes_max = 0x10000,
	.period_bytes_min = 0x20,
	.period_bytes_max = 0x1000,
	.periods_min = 2,
	.periods_max = 1024,
};

#ifndef CHIP_AU8820
static const struct snd_pcm_hardware snd_vortex_playback_hw_a3d = {
	.info =
	    (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
	     SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
	     SNDRV_PCM_INFO_MMAP_VALID),
	.formats =
	    SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
	    SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW,
	.rates = SNDRV_PCM_RATE_CONTINUOUS,
	.rate_min = 5000,
	.rate_max = 48000,
	.channels_min = 1,
	.channels_max = 1,
	.buffer_bytes_max = 0x10000,
	.period_bytes_min = 0x100,
	.period_bytes_max = 0x1000,
	.periods_min = 2,
	.periods_max = 64,
};
#endif
static const struct snd_pcm_hardware snd_vortex_playback_hw_spdif = {
	.info =
	    (SNDRV_PCM_INFO_MMAP | /* SNDRV_PCM_INFO_RESUME | */
	     SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_INTERLEAVED |
	     SNDRV_PCM_INFO_MMAP_VALID),
	.formats =
	    SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 |
	    SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | SNDRV_PCM_FMTBIT_MU_LAW |
	    SNDRV_PCM_FMTBIT_A_LAW,
	.rates =
	    SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
	.rate_min = 32000,
	.rate_max = 48000,
	.channels_min = 1,
	.channels_max = 2,
	.buffer_bytes_max = 0x10000,
	.period_bytes_min = 0x100,
	.period_bytes_max = 0x1000,
	.periods_min = 2,
	.periods_max = 64,
};

#ifndef CHIP_AU8810
static const struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
	.info = (SNDRV_PCM_INFO_MMAP |
		 SNDRV_PCM_INFO_INTERLEAVED |
		 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID),
	.formats = SNDRV_PCM_FMTBIT_S16_LE,
	.rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS,	// SNDRV_PCM_RATE_48000,
	.rate_min = 8000,
	.rate_max = 48000,
	.channels_min = 1,
	.channels_max = 2,
	.buffer_bytes_max = 0x10000,
	.period_bytes_min = 0x0400,
	.period_bytes_max = 0x1000,
	.periods_min = 2,
	.periods_max = 64,
};
#endif
#ifdef CHIP_AU8830
static const unsigned int au8830_channels[3] = {
	1, 2, 4,
};

static const struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
	.count = ARRAY_SIZE(au8830_channels),
	.list = au8830_channels,
	.mask = 0,
};
#endif

static void vortex_notify_pcm_vol_change(struct snd_card *card,
			struct snd_kcontrol *kctl, int activate)
{
	if (activate)
		kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
	else
		kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
	snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_VALUE |
				SNDRV_CTL_EVENT_MASK_INFO, &(kctl->id));
}

/* open callback */
static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
{
	vortex_t *vortex = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	int err;
	
	/* Force equal size periods */
	err = snd_pcm_hw_constraint_integer(runtime,
					    SNDRV_PCM_HW_PARAM_PERIODS);
	if (err < 0)
		return err;
	/* Avoid PAGE_SIZE boundary to fall inside of a period. */
	err = snd_pcm_hw_constraint_pow2(runtime, 0,
					 SNDRV_PCM_HW_PARAM_PERIOD_BYTES);
	if (err < 0)
		return err;

	snd_pcm_hw_constraint_step(runtime, 0,
					SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 64);

	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
#ifndef CHIP_AU8820
		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) {
			runtime->hw = snd_vortex_playback_hw_a3d;
		}
#endif
		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_SPDIF) {
			runtime->hw = snd_vortex_playback_hw_spdif;
			switch (vortex->spdif_sr) {
			case 32000:
				runtime->hw.rates = SNDRV_PCM_RATE_32000;
				break;
			case 44100:
				runtime->hw.rates = SNDRV_PCM_RATE_44100;
				break;
			case 48000:
				runtime->hw.rates = SNDRV_PCM_RATE_48000;
				break;
			}
		}
		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
		    || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
			runtime->hw = snd_vortex_playback_hw_adb;
#ifdef CHIP_AU8830
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
			VORTEX_IS_QUAD(vortex) &&
			VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
			runtime->hw.channels_max = 4;
			snd_pcm_hw_constraint_list(runtime, 0,
				SNDRV_PCM_HW_PARAM_CHANNELS,
				&hw_constraints_au8830_channels);
		}
#endif
		substream->runtime->private_data = NULL;
	}
#ifndef CHIP_AU8810
	else {
		runtime->hw = snd_vortex_playback_hw_wt;
		substream->runtime->private_data = NULL;
	}
#endif
	return 0;
}

/* close callback */
static int snd_vortex_pcm_close(struct snd_pcm_substream *substream)
{
	//vortex_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) substream->runtime->private_data;

	// the hardware-specific codes will be here
	if (stream != NULL) {
		stream->substream = NULL;
		stream->nr_ch = 0;
	}
	substream->runtime->private_data = NULL;
	return 0;
}

/* hw_params callback */
static int
snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream,
			 struct snd_pcm_hw_params *hw_params)
{
	vortex_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) (substream->runtime->private_data);

	/*
	   pr_info( "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params),
	   params_period_bytes(hw_params), params_channels(hw_params));
	 */
	spin_lock_irq(&chip->lock);
	// Make audio routes and config buffer DMA.
	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
		int dma, type = VORTEX_PCM_TYPE(substream->pcm);
		/* Dealloc any routes. */
		if (stream != NULL)
			vortex_adb_allocroute(chip, stream->dma,
					      stream->nr_ch, stream->dir,
					      stream->type,
					      substream->number);
		/* Alloc routes. */
		dma =
		    vortex_adb_allocroute(chip, -1,
					  params_channels(hw_params),
					  substream->stream, type,
					  substream->number);
		if (dma < 0) {
			spin_unlock_irq(&chip->lock);
			return dma;
		}
		stream = substream->runtime->private_data = &chip->dma_adb[dma];
		stream->substream = substream;
		/* Setup Buffers. */
		vortex_adbdma_setbuffers(chip, dma,
					 params_period_bytes(hw_params),
					 params_periods(hw_params));
		if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
			chip->pcm_vol[substream->number].active = 1;
			vortex_notify_pcm_vol_change(chip->card,
				chip->pcm_vol[substream->number].kctl, 1);
		}
	}
#ifndef CHIP_AU8810
	else {
		/* if (stream != NULL)
		   vortex_wt_allocroute(chip, substream->number, 0); */
		vortex_wt_allocroute(chip, substream->number,
				     params_channels(hw_params));
		stream = substream->runtime->private_data =
		    &chip->dma_wt[substream->number];
		stream->dma = substream->number;
		stream->substream = substream;
		vortex_wtdma_setbuffers(chip, substream->number,
					params_period_bytes(hw_params),
					params_periods(hw_params));
	}
#endif
	spin_unlock_irq(&chip->lock);
	return 0;
}

/* hw_free callback */
static int snd_vortex_pcm_hw_free(struct snd_pcm_substream *substream)
{
	vortex_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) (substream->runtime->private_data);

	spin_lock_irq(&chip->lock);
	// Delete audio routes.
	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
		if (stream != NULL) {
			if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
				chip->pcm_vol[substream->number].active = 0;
				vortex_notify_pcm_vol_change(chip->card,
					chip->pcm_vol[substream->number].kctl,
					0);
			}
			vortex_adb_allocroute(chip, stream->dma,
					      stream->nr_ch, stream->dir,
					      stream->type,
					      substream->number);
		}
	}
#ifndef CHIP_AU8810
	else {
		if (stream != NULL)
			vortex_wt_allocroute(chip, stream->dma, 0);
	}
#endif
	substream->runtime->private_data = NULL;
	spin_unlock_irq(&chip->lock);

	return 0;
}

/* prepare callback */
static int snd_vortex_pcm_prepare(struct snd_pcm_substream *substream)
{
	vortex_t *chip = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	stream_t *stream = (stream_t *) substream->runtime->private_data;
	int dma = stream->dma, fmt, dir;

	// set up the hardware with the current configuration.
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		dir = 1;
	else
		dir = 0;
	fmt = vortex_alsafmt_aspfmt(runtime->format, chip);
	spin_lock_irq(&chip->lock);
	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
		vortex_adbdma_setmode(chip, dma, 1, dir, fmt,
				runtime->channels == 1 ? 0 : 1, 0);
		vortex_adbdma_setstartbuffer(chip, dma, 0);
		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_SPDIF)
			vortex_adb_setsrc(chip, dma, runtime->rate, dir);
	}
#ifndef CHIP_AU8810
	else {
		vortex_wtdma_setmode(chip, dma, 1, fmt, 0, 0);
		// FIXME: Set rate (i guess using vortex_wt_writereg() somehow).
		vortex_wtdma_setstartbuffer(chip, dma, 0);
	}
#endif
	spin_unlock_irq(&chip->lock);
	return 0;
}

/* trigger callback */
static int snd_vortex_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	vortex_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) substream->runtime->private_data;
	int dma = stream->dma;

	spin_lock(&chip->lock);
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		// do something to start the PCM engine
		//printk(KERN_INFO "vortex: start %d\n", dma);
		stream->fifo_enabled = 1;
		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) {
			vortex_adbdma_resetup(chip, dma);
			vortex_adbdma_startfifo(chip, dma);
		}
#ifndef CHIP_AU8810
		else {
			dev_info(chip->card->dev, "wt start %d\n", dma);
			vortex_wtdma_startfifo(chip, dma);
		}
#endif
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		// do something to stop the PCM engine
		//printk(KERN_INFO "vortex: stop %d\n", dma);
		stream->fifo_enabled = 0;
		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
			vortex_adbdma_stopfifo(chip, dma);
#ifndef CHIP_AU8810
		else {
			dev_info(chip->card->dev, "wt stop %d\n", dma);
			vortex_wtdma_stopfifo(chip, dma);
		}
#endif
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
		//printk(KERN_INFO "vortex: pause %d\n", dma);
		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
			vortex_adbdma_pausefifo(chip, dma);
#ifndef CHIP_AU8810
		else
			vortex_wtdma_pausefifo(chip, dma);
#endif
		break;
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		//printk(KERN_INFO "vortex: resume %d\n", dma);
		if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
			vortex_adbdma_resumefifo(chip, dma);
#ifndef CHIP_AU8810
		else
			vortex_wtdma_resumefifo(chip, dma);
#endif
		break;
	default:
		spin_unlock(&chip->lock);
		return -EINVAL;
	}
	spin_unlock(&chip->lock);
	return 0;
}

/* pointer callback */
static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substream)
{
	vortex_t *chip = snd_pcm_substream_chip(substream);
	stream_t *stream = (stream_t *) substream->runtime->private_data;
	int dma = stream->dma;
	snd_pcm_uframes_t current_ptr = 0;

	spin_lock(&chip->lock);
	if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT)
		current_ptr = vortex_adbdma_getlinearpos(chip, dma);
#ifndef CHIP_AU8810
	else
		current_ptr = vortex_wtdma_getlinearpos(chip, dma);
#endif
	//printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr);
	spin_unlock(&chip->lock);
	current_ptr = bytes_to_frames(substream->runtime, current_ptr);
	if (current_ptr >= substream->runtime->buffer_size)
		current_ptr = 0;
	return current_ptr;
}

/* operators */
static const struct snd_pcm_ops snd_vortex_playback_ops = {
	.open = snd_vortex_pcm_open,
	.close = snd_vortex_pcm_close,
	.hw_params = snd_vortex_pcm_hw_params,
	.hw_free = snd_vortex_pcm_hw_free,
	.prepare = snd_vortex_pcm_prepare,
	.trigger = snd_vortex_pcm_trigger,
	.pointer = snd_vortex_pcm_pointer,
};

/*
*  definitions of capture are omitted here...
*/

static const char * const vortex_pcm_prettyname[VORTEX_PCM_LAST] = {
	CARD_NAME " ADB",
	CARD_NAME " SPDIF",
	CARD_NAME " A3D",
	CARD_NAME " WT",
	CARD_NAME " I2S",
};
static const char * const vortex_pcm_name[VORTEX_PCM_LAST] = {
	"adb",
	"spdif",
	"a3d",
	"wt",
	"i2s",
};

/* SPDIF kcontrol */

static int snd_vortex_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
	uinfo->count = 1;
	return 0;
}

static int snd_vortex_spdif_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	ucontrol->value.iec958.status[0] = 0xff;
	ucontrol->value.iec958.status[1] = 0xff;
	ucontrol->value.iec958.status[2] = 0xff;
	ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS;
	return 0;
}

static int snd_vortex_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
	ucontrol->value.iec958.status[0] = 0x00;
	ucontrol->value.iec958.status[1] = IEC958_AES1_CON_ORIGINAL|IEC958_AES1_CON_DIGDIGCONV_ID;
	ucontrol->value.iec958.status[2] = 0x00;
	switch (vortex->spdif_sr) {
	case 32000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_32000; break;
	case 44100: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_44100; break;
	case 48000: ucontrol->value.iec958.status[3] = IEC958_AES3_CON_FS_48000; break;
	}
	return 0;
}

static int snd_vortex_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
{
	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
	int spdif_sr = 48000;
	switch (ucontrol->value.iec958.status[3] & IEC958_AES3_CON_FS) {
	case IEC958_AES3_CON_FS_32000: spdif_sr = 32000; break;
	case IEC958_AES3_CON_FS_44100: spdif_sr = 44100; break;
	case IEC958_AES3_CON_FS_48000: spdif_sr = 48000; break;
	}
	if (spdif_sr == vortex->spdif_sr)
		return 0;
	vortex->spdif_sr = spdif_sr;
	vortex_spdif_init(vortex, vortex->spdif_sr, 1);
	return 1;
}

/* spdif controls */
static const struct snd_kcontrol_new snd_vortex_mixer_spdif[] = {
	{
		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
		.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
		.info =		snd_vortex_spdif_info,
		.get =		snd_vortex_spdif_get,
		.put =		snd_vortex_spdif_put,
	},
	{
		.access =	SNDRV_CTL_ELEM_ACCESS_READ,
		.iface =	SNDRV_CTL_ELEM_IFACE_PCM,
		.name =		SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
		.info =		snd_vortex_spdif_info,
		.get =		snd_vortex_spdif_mask_get
	},
};

/* subdevice PCM Volume control */

static int snd_vortex_pcm_vol_info(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_info *uinfo)
{
	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
	uinfo->value.integer.min = -128;
	uinfo->value.integer.max = 32;
	return 0;
}

static int snd_vortex_pcm_vol_get(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int i;
	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
	int subdev = kcontrol->id.subdevice;
	struct pcm_vol *p = &vortex->pcm_vol[subdev];
	int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
	for (i = 0; i < max_chn; i++)
		ucontrol->value.integer.value[i] = p->vol[i];
	return 0;
}

static int snd_vortex_pcm_vol_put(struct snd_kcontrol *kcontrol,
				struct snd_ctl_elem_value *ucontrol)
{
	int i;
	int changed = 0;
	int mixin;
	unsigned char vol;
	vortex_t *vortex = snd_kcontrol_chip(kcontrol);
	int subdev = kcontrol->id.subdevice;
	struct pcm_vol *p = &vortex->pcm_vol[subdev];
	int max_chn = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
	for (i = 0; i < max_chn; i++) {
		if (p->vol[i] != ucontrol->value.integer.value[i]) {
			p->vol[i] = ucontrol->value.integer.value[i];
			if (p->active) {
				switch (vortex->dma_adb[p->dma].nr_ch) {
				case 1:
					mixin = p->mixin[0];
					break;
				case 2:
				default:
					mixin = p->mixin[(i < 2) ? i : (i - 2)];
					break;
				case 4:
					mixin = p->mixin[i];
					break;
				}
				vol = p->vol[i];
				vortex_mix_setinputvolumebyte(vortex,
					vortex->mixplayb[i], mixin, vol);
			}
			changed = 1;
		}
	}
	return changed;
}

static const DECLARE_TLV_DB_MINMAX(vortex_pcm_vol_db_scale, -9600, 2400);

static const struct snd_kcontrol_new snd_vortex_pcm_vol = {
	.iface = SNDRV_CTL_ELEM_IFACE_PCM,
	.name = "PCM Playback Volume",
	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
		SNDRV_CTL_ELEM_ACCESS_TLV_READ |
		SNDRV_CTL_ELEM_ACCESS_INACTIVE,
	.info = snd_vortex_pcm_vol_info,
	.get = snd_vortex_pcm_vol_get,
	.put = snd_vortex_pcm_vol_put,
	.tlv = { .p = vortex_pcm_vol_db_scale },
};

/* create a pcm device */
static int snd_vortex_new_pcm(vortex_t *chip, int idx, int nr)
{
	struct snd_pcm *pcm;
	struct snd_kcontrol *kctl;
	int i;
	int err, nr_capt;

	if (!chip || idx < 0 || idx >= VORTEX_PCM_LAST)
		return -ENODEV;

	/* idx indicates which kind of PCM device. ADB, SPDIF, I2S and A3D share the 
	 * same dma engine. WT uses it own separate dma engine which can't capture. */
	if (idx == VORTEX_PCM_ADB)
		nr_capt = nr;
	else
		nr_capt = 0;
	err = snd_pcm_new(chip->card, vortex_pcm_prettyname[idx], idx, nr,
			  nr_capt, &pcm);
	if (err < 0)
		return err;
	snprintf(pcm->name, sizeof(pcm->name),
		"%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]);
	chip->pcm[idx] = pcm;
	// This is an evil hack, but it saves a lot of duplicated code.
	VORTEX_PCM_TYPE(pcm) = idx;
	pcm->private_data = chip;
	/* set operators */
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
			&snd_vortex_playback_ops);
	if (idx == VORTEX_PCM_ADB)
		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
				&snd_vortex_playback_ops);
	
	/* pre-allocation of Scatter-Gather buffers */
	
	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
				       &chip->pci_dev->dev, 0x10000, 0x10000);

	switch (VORTEX_PCM_TYPE(pcm)) {
	case VORTEX_PCM_ADB:
		err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
					     snd_pcm_std_chmaps,
					     VORTEX_IS_QUAD(chip) ? 4 : 2,
					     0, NULL);
		if (err < 0)
			return err;
		err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
					     snd_pcm_std_chmaps, 2, 0, NULL);
		if (err < 0)
			return err;
		break;
#ifdef CHIP_AU8830
	case VORTEX_PCM_A3D:
		err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
					     snd_pcm_std_chmaps, 1, 0, NULL);
		if (err < 0)
			return err;
		break;
#endif
	}

	if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_SPDIF) {
		for (i = 0; i < ARRAY_SIZE(snd_vortex_mixer_spdif); i++) {
			kctl = snd_ctl_new1(&snd_vortex_mixer_spdif[i], chip);
			if (!kctl)
				return -ENOMEM;
			err = snd_ctl_add(chip->card, kctl);
			if (err < 0)
				return err;
		}
	}
	if (VORTEX_PCM_TYPE(pcm) == VORTEX_PCM_ADB) {
		for (i = 0; i < NR_PCM; i++) {
			chip->pcm_vol[i].active = 0;
			chip->pcm_vol[i].dma = -1;
			kctl = snd_ctl_new1(&snd_vortex_pcm_vol, chip);
			if (!kctl)
				return -ENOMEM;
			chip->pcm_vol[i].kctl = kctl;
			kctl->id.device = 0;
			kctl->id.subdevice = i;
			err = snd_ctl_add(chip->card, kctl);
			if (err < 0)
				return err;
		}
	}
	return 0;
}
