// SPDX-License-Identifier: GPL-2.0-only
/*
 *   SAA713x ALSA support for V4L
 */

#include "saa7134.h"
#include "saa7134-reg.h"

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/module.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>

/*
 * Configuration macros
 */

/* defaults */
#define MIXER_ADDR_UNSELECTED	-1
#define MIXER_ADDR_TVTUNER	0
#define MIXER_ADDR_LINE1	1
#define MIXER_ADDR_LINE2	2
#define MIXER_ADDR_LAST		2


static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;	/* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;	/* ID for this card */
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};

module_param_array(index, int, NULL, 0444);
module_param_array(enable, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for SAA7134 capture interface(s).");
MODULE_PARM_DESC(enable, "Enable (or not) the SAA7134 capture interface(s).");

/*
 * Main chip structure
 */

typedef struct snd_card_saa7134 {
	struct snd_card *card;
	spinlock_t mixer_lock;
	int mixer_volume[MIXER_ADDR_LAST+1][2];
	int capture_source_addr;
	int capture_source[2];
	struct snd_kcontrol *capture_ctl[MIXER_ADDR_LAST+1];
	struct pci_dev *pci;
	struct saa7134_dev *dev;

	unsigned long iobase;
	s16 irq;
	u16 mute_was_on;

	spinlock_t lock;
} snd_card_saa7134_t;


/*
 * PCM structure
 */

typedef struct snd_card_saa7134_pcm {
	struct saa7134_dev *dev;

	spinlock_t lock;

	struct snd_pcm_substream *substream;
} snd_card_saa7134_pcm_t;

static struct snd_card *snd_saa7134_cards[SNDRV_CARDS];


/*
 * saa7134 DMA audio stop
 *
 *   Called when the capture device is released or the buffer overflows
 *
 *   - Copied verbatim from saa7134-oss's dsp_dma_stop.
 *
 */

static void saa7134_dma_stop(struct saa7134_dev *dev)
{
	dev->dmasound.dma_blk     = -1;
	dev->dmasound.dma_running = 0;
	saa7134_set_dmabits(dev);
}

/*
 * saa7134 DMA audio start
 *
 *   Called when preparing the capture device for use
 *
 *   - Copied verbatim from saa7134-oss's dsp_dma_start.
 *
 */

static void saa7134_dma_start(struct saa7134_dev *dev)
{
	dev->dmasound.dma_blk     = 0;
	dev->dmasound.dma_running = 1;
	saa7134_set_dmabits(dev);
}

/*
 * saa7134 audio DMA IRQ handler
 *
 *   Called whenever we get an SAA7134_IRQ_REPORT_DONE_RA3 interrupt
 *   Handles shifting between the 2 buffers, manages the read counters,
 *  and notifies ALSA when periods elapse
 *
 *   - Mostly copied from saa7134-oss's saa7134_irq_oss_done.
 *
 */

static void saa7134_irq_alsa_done(struct saa7134_dev *dev,
				  unsigned long status)
{
	int next_blk, reg = 0;

	spin_lock(&dev->slock);
	if (UNSET == dev->dmasound.dma_blk) {
		pr_debug("irq: recording stopped\n");
		goto done;
	}
	if (0 != (status & 0x0f000000))
		pr_debug("irq: lost %ld\n", (status >> 24) & 0x0f);
	if (0 == (status & 0x10000000)) {
		/* odd */
		if (0 == (dev->dmasound.dma_blk & 0x01))
			reg = SAA7134_RS_BA1(6);
	} else {
		/* even */
		if (1 == (dev->dmasound.dma_blk & 0x01))
			reg = SAA7134_RS_BA2(6);
	}
	if (0 == reg) {
		pr_debug("irq: field oops [%s]\n",
			(status & 0x10000000) ? "even" : "odd");
		goto done;
	}

	if (dev->dmasound.read_count >= dev->dmasound.blksize * (dev->dmasound.blocks-2)) {
		pr_debug("irq: overrun [full=%d/%d] - Blocks in %d\n",
			dev->dmasound.read_count,
			dev->dmasound.bufsize, dev->dmasound.blocks);
		spin_unlock(&dev->slock);
		snd_pcm_stop_xrun(dev->dmasound.substream);
		return;
	}

	/* next block addr */
	next_blk = (dev->dmasound.dma_blk + 2) % dev->dmasound.blocks;
	saa_writel(reg,next_blk * dev->dmasound.blksize);
	pr_debug("irq: ok, %s, next_blk=%d, addr=%x, blocks=%u, size=%u, read=%u\n",
		(status & 0x10000000) ? "even" : "odd ", next_blk,
		 next_blk * dev->dmasound.blksize, dev->dmasound.blocks,
		 dev->dmasound.blksize, dev->dmasound.read_count);

	/* update status & wake waiting readers */
	dev->dmasound.dma_blk = (dev->dmasound.dma_blk + 1) % dev->dmasound.blocks;
	dev->dmasound.read_count += dev->dmasound.blksize;

	dev->dmasound.recording_on = reg;

	if (dev->dmasound.read_count >= snd_pcm_lib_period_bytes(dev->dmasound.substream)) {
		spin_unlock(&dev->slock);
		snd_pcm_period_elapsed(dev->dmasound.substream);
		spin_lock(&dev->slock);
	}

 done:
	spin_unlock(&dev->slock);

}

/*
 * IRQ request handler
 *
 *   Runs along with saa7134's IRQ handler, discards anything that isn't
 *   DMA sound
 *
 */

static irqreturn_t saa7134_alsa_irq(int irq, void *dev_id)
{
	struct saa7134_dmasound *dmasound = dev_id;
	struct saa7134_dev *dev = dmasound->priv_data;

	unsigned long report, status;
	int loop, handled = 0;

	for (loop = 0; loop < 10; loop++) {
		report = saa_readl(SAA7134_IRQ_REPORT);
		status = saa_readl(SAA7134_IRQ_STATUS);

		if (report & SAA7134_IRQ_REPORT_DONE_RA3) {
			handled = 1;
			saa_writel(SAA7134_IRQ_REPORT,
				   SAA7134_IRQ_REPORT_DONE_RA3);
			saa7134_irq_alsa_done(dev, status);
		} else {
			goto out;
		}
	}

	if (loop == 10) {
		pr_debug("error! looping IRQ!");
	}

out:
	return IRQ_RETVAL(handled);
}

/*
 * ALSA capture trigger
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called whenever a capture is started or stopped. Must be defined,
 *   but there's nothing we want to do here
 *
 */

static int snd_card_saa7134_capture_trigger(struct snd_pcm_substream * substream,
					  int cmd)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
	struct saa7134_dev *dev=pcm->dev;
	int err = 0;

	spin_lock(&dev->slock);
	if (cmd == SNDRV_PCM_TRIGGER_START) {
		/* start dma */
		saa7134_dma_start(dev);
	} else if (cmd == SNDRV_PCM_TRIGGER_STOP) {
		/* stop dma */
		saa7134_dma_stop(dev);
	} else {
		err = -EINVAL;
	}
	spin_unlock(&dev->slock);

	return err;
}

static int saa7134_alsa_dma_init(struct saa7134_dev *dev, int nr_pages)
{
	struct saa7134_dmasound *dma = &dev->dmasound;
	struct page *pg;
	int i;

	dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
	if (NULL == dma->vaddr) {
		pr_debug("vmalloc_32(%d pages) failed\n", nr_pages);
		return -ENOMEM;
	}

	pr_debug("vmalloc is at addr %p, size=%d\n",
		 dma->vaddr, nr_pages << PAGE_SHIFT);

	memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT);
	dma->nr_pages = nr_pages;

	dma->sglist = vzalloc(array_size(sizeof(*dma->sglist), dma->nr_pages));
	if (NULL == dma->sglist)
		goto vzalloc_err;

	sg_init_table(dma->sglist, dma->nr_pages);
	for (i = 0; i < dma->nr_pages; i++) {
		pg = vmalloc_to_page(dma->vaddr + i * PAGE_SIZE);
		if (NULL == pg)
			goto vmalloc_to_page_err;
		sg_set_page(&dma->sglist[i], pg, PAGE_SIZE, 0);
	}
	return 0;

vmalloc_to_page_err:
	vfree(dma->sglist);
	dma->sglist = NULL;
vzalloc_err:
	vfree(dma->vaddr);
	dma->vaddr = NULL;
	return -ENOMEM;
}

static int saa7134_alsa_dma_map(struct saa7134_dev *dev)
{
	struct saa7134_dmasound *dma = &dev->dmasound;

	dma->sglen = dma_map_sg(&dev->pci->dev, dma->sglist,
			dma->nr_pages, PCI_DMA_FROMDEVICE);

	if (0 == dma->sglen) {
		pr_warn("%s: saa7134_alsa_map_sg failed\n", __func__);
		return -ENOMEM;
	}
	return 0;
}

static int saa7134_alsa_dma_unmap(struct saa7134_dev *dev)
{
	struct saa7134_dmasound *dma = &dev->dmasound;

	if (!dma->sglen)
		return 0;

	dma_unmap_sg(&dev->pci->dev, dma->sglist, dma->sglen, PCI_DMA_FROMDEVICE);
	dma->sglen = 0;
	return 0;
}

static int saa7134_alsa_dma_free(struct saa7134_dmasound *dma)
{
	vfree(dma->sglist);
	dma->sglist = NULL;
	vfree(dma->vaddr);
	dma->vaddr = NULL;
	return 0;
}

/*
 * DMA buffer initialization
 *
 *   Uses V4L functions to initialize the DMA. Shouldn't be necessary in
 *  ALSA, but I was unable to use ALSA's own DMA, and had to force the
 *  usage of V4L's
 *
 *   - Copied verbatim from saa7134-oss.
 *
 */

static int dsp_buffer_init(struct saa7134_dev *dev)
{
	int err;

	BUG_ON(!dev->dmasound.bufsize);

	err = saa7134_alsa_dma_init(dev,
			       (dev->dmasound.bufsize + PAGE_SIZE) >> PAGE_SHIFT);
	if (0 != err)
		return err;
	return 0;
}

/*
 * DMA buffer release
 *
 *   Called after closing the device, during snd_card_saa7134_capture_close
 *
 */

static int dsp_buffer_free(struct saa7134_dev *dev)
{
	BUG_ON(!dev->dmasound.blksize);

	saa7134_alsa_dma_free(&dev->dmasound);

	dev->dmasound.blocks  = 0;
	dev->dmasound.blksize = 0;
	dev->dmasound.bufsize = 0;

	return 0;
}

/*
 * Setting the capture source and updating the ALSA controls
 */
static int snd_saa7134_capsrc_set(struct snd_kcontrol *kcontrol,
				  int left, int right, bool force_notify)
{
	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
	int change = 0, addr = kcontrol->private_value;
	int active, old_addr;
	u32 anabar, xbarin;
	int analog_io, rate;
	struct saa7134_dev *dev;

	dev = chip->dev;

	spin_lock_irq(&chip->mixer_lock);

	active = left != 0 || right != 0;
	old_addr = chip->capture_source_addr;

	/* The active capture source cannot be deactivated */
	if (active) {
		change = old_addr != addr ||
			 chip->capture_source[0] != left ||
			 chip->capture_source[1] != right;

		chip->capture_source[0] = left;
		chip->capture_source[1] = right;
		chip->capture_source_addr = addr;
		dev->dmasound.input = addr;
	}
	spin_unlock_irq(&chip->mixer_lock);

	if (change) {
		switch (dev->pci->device) {

		case PCI_DEVICE_ID_PHILIPS_SAA7134:
			switch (addr) {
			case MIXER_ADDR_TVTUNER:
				saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
					   0xc0, 0xc0);
				saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
					   0x03, 0x00);
				break;
			case MIXER_ADDR_LINE1:
			case MIXER_ADDR_LINE2:
				analog_io = (MIXER_ADDR_LINE1 == addr) ?
					     0x00 : 0x08;
				rate = (32000 == dev->dmasound.rate) ?
					0x01 : 0x03;
				saa_andorb(SAA7134_ANALOG_IO_SELECT,
					   0x08, analog_io);
				saa_andorb(SAA7134_AUDIO_FORMAT_CTRL,
					   0xc0, 0x80);
				saa_andorb(SAA7134_SIF_SAMPLE_FREQ,
					   0x03, rate);
				break;
			}

			break;
		case PCI_DEVICE_ID_PHILIPS_SAA7133:
		case PCI_DEVICE_ID_PHILIPS_SAA7135:
			xbarin = 0x03; /* adc */
			anabar = 0;
			switch (addr) {
			case MIXER_ADDR_TVTUNER:
				xbarin = 0; /* Demodulator */
				anabar = 2; /* DACs */
				break;
			case MIXER_ADDR_LINE1:
				anabar = 0;  /* aux1, aux1 */
				break;
			case MIXER_ADDR_LINE2:
				anabar = 9;  /* aux2, aux2 */
				break;
			}

			/* output xbar always main channel */
			saa_dsp_writel(dev, SAA7133_DIGITAL_OUTPUT_SEL1,
				       0xbbbb10);

			if (left || right) {
				/* We've got data, turn the input on */
				saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
					       xbarin);
				saa_writel(SAA7133_ANALOG_IO_SELECT, anabar);
			} else {
				saa_dsp_writel(dev, SAA7133_DIGITAL_INPUT_XBAR1,
					       0);
				saa_writel(SAA7133_ANALOG_IO_SELECT, 0);
			}
			break;
		}
	}

	if (change) {
		if (force_notify)
			snd_ctl_notify(chip->card,
				       SNDRV_CTL_EVENT_MASK_VALUE,
				       &chip->capture_ctl[addr]->id);

		if (old_addr != MIXER_ADDR_UNSELECTED && old_addr != addr)
			snd_ctl_notify(chip->card,
				       SNDRV_CTL_EVENT_MASK_VALUE,
				       &chip->capture_ctl[old_addr]->id);
	}

	return change;
}

/*
 * ALSA PCM preparation
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called right after the capture device is opened, this function configures
 *  the buffer using the previously defined functions, allocates the memory,
 *  sets up the hardware registers, and then starts the DMA. When this function
 *  returns, the audio should be flowing.
 *
 */

static int snd_card_saa7134_capture_prepare(struct snd_pcm_substream * substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	int bswap, sign;
	u32 fmt, control;
	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
	struct saa7134_dev *dev;
	snd_card_saa7134_pcm_t *pcm = runtime->private_data;

	pcm->dev->dmasound.substream = substream;

	dev = saa7134->dev;

	if (snd_pcm_format_width(runtime->format) == 8)
		fmt = 0x00;
	else
		fmt = 0x01;

	if (snd_pcm_format_signed(runtime->format))
		sign = 1;
	else
		sign = 0;

	if (snd_pcm_format_big_endian(runtime->format))
		bswap = 1;
	else
		bswap = 0;

	switch (dev->pci->device) {
	  case PCI_DEVICE_ID_PHILIPS_SAA7134:
		if (1 == runtime->channels)
			fmt |= (1 << 3);
		if (2 == runtime->channels)
			fmt |= (3 << 3);
		if (sign)
			fmt |= 0x04;

		fmt |= (MIXER_ADDR_TVTUNER == dev->dmasound.input) ? 0xc0 : 0x80;
		saa_writeb(SAA7134_NUM_SAMPLES0, ((dev->dmasound.blksize - 1) & 0x0000ff));
		saa_writeb(SAA7134_NUM_SAMPLES1, ((dev->dmasound.blksize - 1) & 0x00ff00) >>  8);
		saa_writeb(SAA7134_NUM_SAMPLES2, ((dev->dmasound.blksize - 1) & 0xff0000) >> 16);
		saa_writeb(SAA7134_AUDIO_FORMAT_CTRL, fmt);

		break;
	  case PCI_DEVICE_ID_PHILIPS_SAA7133:
	  case PCI_DEVICE_ID_PHILIPS_SAA7135:
		if (1 == runtime->channels)
			fmt |= (1 << 4);
		if (2 == runtime->channels)
			fmt |= (2 << 4);
		if (!sign)
			fmt |= 0x04;
		saa_writel(SAA7133_NUM_SAMPLES, dev->dmasound.blksize -1);
		saa_writel(SAA7133_AUDIO_CHANNEL, 0x543210 | (fmt << 24));
		break;
	}

	pr_debug("rec_start: afmt=%d ch=%d  =>  fmt=0x%x swap=%c\n",
		runtime->format, runtime->channels, fmt,
		bswap ? 'b' : '-');
	/* dma: setup channel 6 (= AUDIO) */
	control = SAA7134_RS_CONTROL_BURST_16 |
		SAA7134_RS_CONTROL_ME |
		(dev->dmasound.pt.dma >> 12);
	if (bswap)
		control |= SAA7134_RS_CONTROL_BSWAP;

	saa_writel(SAA7134_RS_BA1(6),0);
	saa_writel(SAA7134_RS_BA2(6),dev->dmasound.blksize);
	saa_writel(SAA7134_RS_PITCH(6),0);
	saa_writel(SAA7134_RS_CONTROL(6),control);

	dev->dmasound.rate = runtime->rate;

	/* Setup and update the card/ALSA controls */
	snd_saa7134_capsrc_set(saa7134->capture_ctl[dev->dmasound.input], 1, 1,
			       true);

	return 0;

}

/*
 * ALSA pointer fetching
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called whenever a period elapses, it must return the current hardware
 *  position of the buffer.
 *   Also resets the read counter used to prevent overruns
 *
 */

static snd_pcm_uframes_t
snd_card_saa7134_capture_pointer(struct snd_pcm_substream * substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	snd_card_saa7134_pcm_t *pcm = runtime->private_data;
	struct saa7134_dev *dev=pcm->dev;

	if (dev->dmasound.read_count) {
		dev->dmasound.read_count  -= snd_pcm_lib_period_bytes(substream);
		dev->dmasound.read_offset += snd_pcm_lib_period_bytes(substream);
		if (dev->dmasound.read_offset == dev->dmasound.bufsize)
			dev->dmasound.read_offset = 0;
	}

	return bytes_to_frames(runtime, dev->dmasound.read_offset);
}

/*
 * ALSA hardware capabilities definition
 *
 *  Report only 32kHz for ALSA:
 *
 *  - SAA7133/35 uses DDEP (DemDec Easy Programming mode), which works in 32kHz
 *    only
 *  - SAA7134 for TV mode uses DemDec mode (32kHz)
 *  - Radio works in 32kHz only
 *  - When recording 48kHz from Line1/Line2, switching of capture source to TV
 *    means
 *    switching to 32kHz without any frequency translation
 */

static const struct snd_pcm_hardware snd_card_saa7134_capture =
{
	.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 | \
				SNDRV_PCM_FMTBIT_S16_BE | \
				SNDRV_PCM_FMTBIT_S8 | \
				SNDRV_PCM_FMTBIT_U8 | \
				SNDRV_PCM_FMTBIT_U16_LE | \
				SNDRV_PCM_FMTBIT_U16_BE,
	.rates =		SNDRV_PCM_RATE_32000,
	.rate_min =		32000,
	.rate_max =		32000,
	.channels_min =		1,
	.channels_max =		2,
	.buffer_bytes_max =	(256*1024),
	.period_bytes_min =	64,
	.period_bytes_max =	(256*1024),
	.periods_min =		4,
	.periods_max =		1024,
};

static void snd_card_saa7134_runtime_free(struct snd_pcm_runtime *runtime)
{
	snd_card_saa7134_pcm_t *pcm = runtime->private_data;

	kfree(pcm);
}


/*
 * ALSA hardware params
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called on initialization, right before the PCM preparation
 *
 */

static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
				      struct snd_pcm_hw_params * hw_params)
{
	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
	struct saa7134_dev *dev;
	unsigned int period_size, periods;
	int err;

	period_size = params_period_bytes(hw_params);
	periods = params_periods(hw_params);

	if (period_size < 0x100 || period_size > 0x10000)
		return -EINVAL;
	if (periods < 4)
		return -EINVAL;
	if (period_size * periods > 1024 * 1024)
		return -EINVAL;

	dev = saa7134->dev;

	if (dev->dmasound.blocks == periods &&
	    dev->dmasound.blksize == period_size)
		return 0;

	/* release the old buffer */
	if (substream->runtime->dma_area) {
		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
		saa7134_alsa_dma_unmap(dev);
		dsp_buffer_free(dev);
		substream->runtime->dma_area = NULL;
	}
	dev->dmasound.blocks  = periods;
	dev->dmasound.blksize = period_size;
	dev->dmasound.bufsize = period_size * periods;

	err = dsp_buffer_init(dev);
	if (0 != err) {
		dev->dmasound.blocks  = 0;
		dev->dmasound.blksize = 0;
		dev->dmasound.bufsize = 0;
		return err;
	}

	err = saa7134_alsa_dma_map(dev);
	if (err) {
		dsp_buffer_free(dev);
		return err;
	}
	err = saa7134_pgtable_alloc(dev->pci, &dev->dmasound.pt);
	if (err) {
		saa7134_alsa_dma_unmap(dev);
		dsp_buffer_free(dev);
		return err;
	}
	err = saa7134_pgtable_build(dev->pci, &dev->dmasound.pt,
				dev->dmasound.sglist, dev->dmasound.sglen, 0);
	if (err) {
		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
		saa7134_alsa_dma_unmap(dev);
		dsp_buffer_free(dev);
		return err;
	}

	/* I should be able to use runtime->dma_addr in the control
	   byte, but it doesn't work. So I allocate the DMA using the
	   V4L functions, and force ALSA to use that as the DMA area */

	substream->runtime->dma_area = dev->dmasound.vaddr;
	substream->runtime->dma_bytes = dev->dmasound.bufsize;
	substream->runtime->dma_addr = 0;

	return 0;

}

/*
 * ALSA hardware release
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called after closing the device, but before snd_card_saa7134_capture_close
 *   It stops the DMA audio and releases the buffers.
 *
 */

static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
{
	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
	struct saa7134_dev *dev;

	dev = saa7134->dev;

	if (substream->runtime->dma_area) {
		saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
		saa7134_alsa_dma_unmap(dev);
		dsp_buffer_free(dev);
		substream->runtime->dma_area = NULL;
	}

	return 0;
}

/*
 * ALSA capture finish
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called after closing the device.
 *
 */

static int snd_card_saa7134_capture_close(struct snd_pcm_substream * substream)
{
	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
	struct saa7134_dev *dev = saa7134->dev;

	if (saa7134->mute_was_on) {
		dev->ctl_mute = 1;
		saa7134_tvaudio_setmute(dev);
	}
	return 0;
}

/*
 * ALSA capture start
 *
 *   - One of the ALSA capture callbacks.
 *
 *   Called when opening the device. It creates and populates the PCM
 *  structure
 *
 */

static int snd_card_saa7134_capture_open(struct snd_pcm_substream * substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	snd_card_saa7134_pcm_t *pcm;
	snd_card_saa7134_t *saa7134 = snd_pcm_substream_chip(substream);
	struct saa7134_dev *dev;
	int amux, err;

	if (!saa7134) {
		pr_err("BUG: saa7134 can't find device struct. Can't proceed with open\n");
		return -ENODEV;
	}
	dev = saa7134->dev;
	mutex_lock(&dev->dmasound.lock);

	dev->dmasound.read_count  = 0;
	dev->dmasound.read_offset = 0;

	amux = dev->input->amux;
	if ((amux < 1) || (amux > 3))
		amux = 1;
	dev->dmasound.input  =  amux - 1;

	mutex_unlock(&dev->dmasound.lock);

	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
	if (pcm == NULL)
		return -ENOMEM;

	pcm->dev=saa7134->dev;

	spin_lock_init(&pcm->lock);

	pcm->substream = substream;
	runtime->private_data = pcm;
	runtime->private_free = snd_card_saa7134_runtime_free;
	runtime->hw = snd_card_saa7134_capture;

	if (dev->ctl_mute != 0) {
		saa7134->mute_was_on = 1;
		dev->ctl_mute = 0;
		saa7134_tvaudio_setmute(dev);
	}

	err = snd_pcm_hw_constraint_integer(runtime,
						SNDRV_PCM_HW_PARAM_PERIODS);
	if (err < 0)
		return err;

	err = snd_pcm_hw_constraint_step(runtime, 0,
						SNDRV_PCM_HW_PARAM_PERIODS, 2);
	if (err < 0)
		return err;

	return 0;
}

/*
 * page callback (needed for mmap)
 */

static struct page *snd_card_saa7134_page(struct snd_pcm_substream *substream,
					unsigned long offset)
{
	void *pageptr = substream->runtime->dma_area + offset;
	return vmalloc_to_page(pageptr);
}

/*
 * ALSA capture callbacks definition
 */

static const struct snd_pcm_ops snd_card_saa7134_capture_ops = {
	.open =			snd_card_saa7134_capture_open,
	.close =		snd_card_saa7134_capture_close,
	.ioctl =		snd_pcm_lib_ioctl,
	.hw_params =		snd_card_saa7134_hw_params,
	.hw_free =		snd_card_saa7134_hw_free,
	.prepare =		snd_card_saa7134_capture_prepare,
	.trigger =		snd_card_saa7134_capture_trigger,
	.pointer =		snd_card_saa7134_capture_pointer,
	.page =			snd_card_saa7134_page,
};

/*
 * ALSA PCM setup
 *
 *   Called when initializing the board. Sets up the name and hooks up
 *  the callbacks
 *
 */

static int snd_card_saa7134_pcm(snd_card_saa7134_t *saa7134, int device)
{
	struct snd_pcm *pcm;
	int err;

	if ((err = snd_pcm_new(saa7134->card, "SAA7134 PCM", device, 0, 1, &pcm)) < 0)
		return err;
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_saa7134_capture_ops);
	pcm->private_data = saa7134;
	pcm->info_flags = 0;
	strscpy(pcm->name, "SAA7134 PCM", sizeof(pcm->name));
	return 0;
}

#define SAA713x_VOLUME(xname, xindex, addr) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
  .info = snd_saa7134_volume_info, \
  .get = snd_saa7134_volume_get, .put = snd_saa7134_volume_put, \
  .private_value = addr }

static int snd_saa7134_volume_info(struct snd_kcontrol * kcontrol,
				   struct snd_ctl_elem_info * uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 20;
	return 0;
}

static int snd_saa7134_volume_get(struct snd_kcontrol * kcontrol,
				  struct snd_ctl_elem_value * ucontrol)
{
	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
	int addr = kcontrol->private_value;

	ucontrol->value.integer.value[0] = chip->mixer_volume[addr][0];
	ucontrol->value.integer.value[1] = chip->mixer_volume[addr][1];
	return 0;
}

static int snd_saa7134_volume_put(struct snd_kcontrol * kcontrol,
				  struct snd_ctl_elem_value * ucontrol)
{
	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
	struct saa7134_dev *dev = chip->dev;

	int change, addr = kcontrol->private_value;
	int left, right;

	left = ucontrol->value.integer.value[0];
	if (left < 0)
		left = 0;
	if (left > 20)
		left = 20;
	right = ucontrol->value.integer.value[1];
	if (right < 0)
		right = 0;
	if (right > 20)
		right = 20;
	spin_lock_irq(&chip->mixer_lock);
	change = 0;
	if (chip->mixer_volume[addr][0] != left) {
		change = 1;
		right = left;
	}
	if (chip->mixer_volume[addr][1] != right) {
		change = 1;
		left = right;
	}
	if (change) {
		switch (dev->pci->device) {
			case PCI_DEVICE_ID_PHILIPS_SAA7134:
				switch (addr) {
					case MIXER_ADDR_TVTUNER:
						left = 20;
						break;
					case MIXER_ADDR_LINE1:
						saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x10,
							   (left > 10) ? 0x00 : 0x10);
						break;
					case MIXER_ADDR_LINE2:
						saa_andorb(SAA7134_ANALOG_IO_SELECT,  0x20,
							   (left > 10) ? 0x00 : 0x20);
						break;
				}
				break;
			case PCI_DEVICE_ID_PHILIPS_SAA7133:
			case PCI_DEVICE_ID_PHILIPS_SAA7135:
				switch (addr) {
					case MIXER_ADDR_TVTUNER:
						left = 20;
						break;
					case MIXER_ADDR_LINE1:
						saa_andorb(0x0594,  0x10,
							   (left > 10) ? 0x00 : 0x10);
						break;
					case MIXER_ADDR_LINE2:
						saa_andorb(0x0594,  0x20,
							   (left > 10) ? 0x00 : 0x20);
						break;
				}
				break;
		}
		chip->mixer_volume[addr][0] = left;
		chip->mixer_volume[addr][1] = right;
	}
	spin_unlock_irq(&chip->mixer_lock);
	return change;
}

#define SAA713x_CAPSRC(xname, xindex, addr) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
  .info = snd_saa7134_capsrc_info, \
  .get = snd_saa7134_capsrc_get, .put = snd_saa7134_capsrc_put, \
  .private_value = addr }

static int snd_saa7134_capsrc_info(struct snd_kcontrol * kcontrol,
				   struct snd_ctl_elem_info * uinfo)
{
	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
	uinfo->count = 2;
	uinfo->value.integer.min = 0;
	uinfo->value.integer.max = 1;
	return 0;
}

static int snd_saa7134_capsrc_get(struct snd_kcontrol * kcontrol,
				  struct snd_ctl_elem_value * ucontrol)
{
	snd_card_saa7134_t *chip = snd_kcontrol_chip(kcontrol);
	int addr = kcontrol->private_value;

	spin_lock_irq(&chip->mixer_lock);
	if (chip->capture_source_addr == addr) {
		ucontrol->value.integer.value[0] = chip->capture_source[0];
		ucontrol->value.integer.value[1] = chip->capture_source[1];
	} else {
		ucontrol->value.integer.value[0] = 0;
		ucontrol->value.integer.value[1] = 0;
	}
	spin_unlock_irq(&chip->mixer_lock);

	return 0;
}

static int snd_saa7134_capsrc_put(struct snd_kcontrol * kcontrol,
				  struct snd_ctl_elem_value * ucontrol)
{
	int left, right;
	left = ucontrol->value.integer.value[0] & 1;
	right = ucontrol->value.integer.value[1] & 1;

	return snd_saa7134_capsrc_set(kcontrol, left, right, false);
}

static struct snd_kcontrol_new snd_saa7134_volume_controls[] = {
SAA713x_VOLUME("Video Volume", 0, MIXER_ADDR_TVTUNER),
SAA713x_VOLUME("Line Volume", 1, MIXER_ADDR_LINE1),
SAA713x_VOLUME("Line Volume", 2, MIXER_ADDR_LINE2),
};

static struct snd_kcontrol_new snd_saa7134_capture_controls[] = {
SAA713x_CAPSRC("Video Capture Switch", 0, MIXER_ADDR_TVTUNER),
SAA713x_CAPSRC("Line Capture Switch", 1, MIXER_ADDR_LINE1),
SAA713x_CAPSRC("Line Capture Switch", 2, MIXER_ADDR_LINE2),
};

/*
 * ALSA mixer setup
 *
 *   Called when initializing the board. Sets up the name and hooks up
 *  the callbacks
 *
 */

static int snd_card_saa7134_new_mixer(snd_card_saa7134_t * chip)
{
	struct snd_card *card = chip->card;
	struct snd_kcontrol *kcontrol;
	unsigned int idx;
	int err, addr;

	strscpy(card->mixername, "SAA7134 Mixer", sizeof(card->mixername));

	for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_volume_controls); idx++) {
		kcontrol = snd_ctl_new1(&snd_saa7134_volume_controls[idx],
					chip);
		err = snd_ctl_add(card, kcontrol);
		if (err < 0)
			return err;
	}

	for (idx = 0; idx < ARRAY_SIZE(snd_saa7134_capture_controls); idx++) {
		kcontrol = snd_ctl_new1(&snd_saa7134_capture_controls[idx],
					chip);
		addr = snd_saa7134_capture_controls[idx].private_value;
		chip->capture_ctl[addr] = kcontrol;
		err = snd_ctl_add(card, kcontrol);
		if (err < 0)
			return err;
	}

	chip->capture_source_addr = MIXER_ADDR_UNSELECTED;
	return 0;
}

static void snd_saa7134_free(struct snd_card * card)
{
	snd_card_saa7134_t *chip = card->private_data;

	if (chip->dev->dmasound.priv_data == NULL)
		return;

	if (chip->irq >= 0)
		free_irq(chip->irq, &chip->dev->dmasound);

	chip->dev->dmasound.priv_data = NULL;

}

/*
 * ALSA initialization
 *
 *   Called by the init routine, once for each saa7134 device present,
 *  it creates the basic structures and registers the ALSA devices
 *
 */

static int alsa_card_saa7134_create(struct saa7134_dev *dev, int devnum)
{

	struct snd_card *card;
	snd_card_saa7134_t *chip;
	int err;


	if (devnum >= SNDRV_CARDS)
		return -ENODEV;
	if (!enable[devnum])
		return -ENODEV;

	err = snd_card_new(&dev->pci->dev, index[devnum], id[devnum],
			   THIS_MODULE, sizeof(snd_card_saa7134_t), &card);
	if (err < 0)
		return err;

	strscpy(card->driver, "SAA7134", sizeof(card->driver));

	/* Card "creation" */

	card->private_free = snd_saa7134_free;
	chip = card->private_data;

	spin_lock_init(&chip->lock);
	spin_lock_init(&chip->mixer_lock);

	chip->dev = dev;

	chip->card = card;

	chip->pci = dev->pci;
	chip->iobase = pci_resource_start(dev->pci, 0);


	err = request_irq(dev->pci->irq, saa7134_alsa_irq,
				IRQF_SHARED, dev->name,
				(void*) &dev->dmasound);

	if (err < 0) {
		pr_err("%s: can't get IRQ %d for ALSA\n",
			dev->name, dev->pci->irq);
		goto __nodev;
	}

	chip->irq = dev->pci->irq;

	mutex_init(&dev->dmasound.lock);

	if ((err = snd_card_saa7134_new_mixer(chip)) < 0)
		goto __nodev;

	if ((err = snd_card_saa7134_pcm(chip, 0)) < 0)
		goto __nodev;

	/* End of "creation" */

	strscpy(card->shortname, "SAA7134", sizeof(card->shortname));
	sprintf(card->longname, "%s at 0x%lx irq %d",
		chip->dev->name, chip->iobase, chip->irq);

	pr_info("%s/alsa: %s registered as card %d\n",
		dev->name, card->longname, index[devnum]);

	if ((err = snd_card_register(card)) == 0) {
		snd_saa7134_cards[devnum] = card;
		return 0;
	}

__nodev:
	snd_card_free(card);
	return err;
}


static int alsa_device_init(struct saa7134_dev *dev)
{
	dev->dmasound.priv_data = dev;
	alsa_card_saa7134_create(dev,dev->nr);
	return 1;
}

static int alsa_device_exit(struct saa7134_dev *dev)
{
	if (!snd_saa7134_cards[dev->nr])
		return 1;

	snd_card_free(snd_saa7134_cards[dev->nr]);
	snd_saa7134_cards[dev->nr] = NULL;
	return 1;
}

/*
 * Module initializer
 *
 * Loops through present saa7134 cards, and assigns an ALSA device
 * to each one
 *
 */

static int saa7134_alsa_init(void)
{
	struct saa7134_dev *dev = NULL;
	struct list_head *list;

	saa7134_dmasound_init = alsa_device_init;
	saa7134_dmasound_exit = alsa_device_exit;

	pr_info("saa7134 ALSA driver for DMA sound loaded\n");

	list_for_each(list,&saa7134_devlist) {
		dev = list_entry(list, struct saa7134_dev, devlist);
		if (dev->pci->device == PCI_DEVICE_ID_PHILIPS_SAA7130)
			pr_info("%s/alsa: %s doesn't support digital audio\n",
				dev->name, saa7134_boards[dev->board].name);
		else
			alsa_device_init(dev);
	}

	if (dev == NULL)
		pr_info("saa7134 ALSA: no saa7134 cards found\n");

	return 0;

}

/*
 * Module destructor
 */

static void saa7134_alsa_exit(void)
{
	int idx;

	for (idx = 0; idx < SNDRV_CARDS; idx++) {
		if (snd_saa7134_cards[idx])
			snd_card_free(snd_saa7134_cards[idx]);
	}

	saa7134_dmasound_init = NULL;
	saa7134_dmasound_exit = NULL;
	pr_info("saa7134 ALSA driver for DMA sound unloaded\n");

	return;
}

/* We initialize this late, to make sure the sound system is up and running */
late_initcall(saa7134_alsa_init);
module_exit(saa7134_alsa_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ricardo Cerqueira");
