/*
 *  Empiatech em28x1 audio extension
 *
 *  Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com>
 *
 *  Copyright (C) 2007 Mauro Carvalho Chehab <mchehab@infradead.org>
 *	- Port to work with the in-kernel driver
 *	- Several cleanups
 *
 *  This driver is based on my previous au600 usb pstn audio driver
 *  and inherits all the copyrights
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/init.h>
#include <linux/sound.h>
#include <linux/spinlock.h>
#include <linux/soundcard.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/info.h>
#include <sound/initval.h>
#include <sound/control.h>
#include <media/v4l2-common.h>
#include "em28xx.h"

static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "activates debug info");

#define dprintk(fmt, arg...) do {					\
	    if (debug)							\
		printk(KERN_INFO "em28xx-audio %s: " fmt,		\
				  __func__, ##arg); 		\
	} while (0)

static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;

static int em28xx_deinit_isoc_audio(struct em28xx *dev)
{
	int i;

	dprintk("Stopping isoc\n");
	for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
		if (!irqs_disabled())
			usb_kill_urb(dev->adev.urb[i]);
		else
			usb_unlink_urb(dev->adev.urb[i]);

		usb_free_urb(dev->adev.urb[i]);
		dev->adev.urb[i] = NULL;

		kfree(dev->adev.transfer_buffer[i]);
		dev->adev.transfer_buffer[i] = NULL;
	}

	return 0;
}

static void em28xx_audio_isocirq(struct urb *urb)
{
	struct em28xx            *dev = urb->context;
	int                      i;
	unsigned int             oldptr;
	int                      period_elapsed = 0;
	int                      status;
	unsigned char            *cp;
	unsigned int             stride;
	struct snd_pcm_substream *substream;
	struct snd_pcm_runtime   *runtime;

	switch (urb->status) {
	case 0:             /* success */
	case -ETIMEDOUT:    /* NAK */
		break;
	case -ECONNRESET:   /* kill */
	case -ENOENT:
	case -ESHUTDOWN:
		return;
	default:            /* error */
		dprintk("urb completition error %d.\n", urb->status);
		break;
	}

	if (dev->adev.capture_pcm_substream) {
		substream = dev->adev.capture_pcm_substream;
		runtime = substream->runtime;
		stride = runtime->frame_bits >> 3;

		for (i = 0; i < urb->number_of_packets; i++) {
			int length =
			    urb->iso_frame_desc[i].actual_length / stride;
			cp = (unsigned char *)urb->transfer_buffer +
			    urb->iso_frame_desc[i].offset;

			if (!length)
				continue;

			oldptr = dev->adev.hwptr_done_capture;
			if (oldptr + length >= runtime->buffer_size) {
				unsigned int cnt =
				    runtime->buffer_size - oldptr;
				memcpy(runtime->dma_area + oldptr * stride, cp,
				       cnt * stride);
				memcpy(runtime->dma_area, cp + cnt * stride,
				       length * stride - cnt * stride);
			} else {
				memcpy(runtime->dma_area + oldptr * stride, cp,
				       length * stride);
			}

			snd_pcm_stream_lock(substream);

			dev->adev.hwptr_done_capture += length;
			if (dev->adev.hwptr_done_capture >=
			    runtime->buffer_size)
				dev->adev.hwptr_done_capture -=
				    runtime->buffer_size;

			dev->adev.capture_transfer_done += length;
			if (dev->adev.capture_transfer_done >=
			    runtime->period_size) {
				dev->adev.capture_transfer_done -=
				    runtime->period_size;
				period_elapsed = 1;
			}

			snd_pcm_stream_unlock(substream);
		}
		if (period_elapsed)
			snd_pcm_period_elapsed(substream);
	}
	urb->status = 0;

	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status < 0) {
		em28xx_errdev("resubmit of audio urb failed (error=%i)\n",
			      status);
	}
	return;
}

static int em28xx_init_audio_isoc(struct em28xx *dev)
{
	int       i, errCode;
	const int sb_size = EM28XX_NUM_AUDIO_PACKETS *
			    EM28XX_AUDIO_MAX_PACKET_SIZE;

	dprintk("Starting isoc transfers\n");

	for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
		struct urb *urb;
		int j, k;

		dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC);
		if (!dev->adev.transfer_buffer[i])
			return -ENOMEM;

		memset(dev->adev.transfer_buffer[i], 0x80, sb_size);
		urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC);
		if (!urb) {
			em28xx_errdev("usb_alloc_urb failed!\n");
			for (j = 0; j < i; j++) {
				usb_free_urb(dev->adev.urb[j]);
				kfree(dev->adev.transfer_buffer[j]);
			}
			return -ENOMEM;
		}

		urb->dev = dev->udev;
		urb->context = dev;
		urb->pipe = usb_rcvisocpipe(dev->udev, 0x83);
		urb->transfer_flags = URB_ISO_ASAP;
		urb->transfer_buffer = dev->adev.transfer_buffer[i];
		urb->interval = 1;
		urb->complete = em28xx_audio_isocirq;
		urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS;
		urb->transfer_buffer_length = sb_size;

		for (j = k = 0; j < EM28XX_NUM_AUDIO_PACKETS;
			     j++, k += EM28XX_AUDIO_MAX_PACKET_SIZE) {
			urb->iso_frame_desc[j].offset = k;
			urb->iso_frame_desc[j].length =
			    EM28XX_AUDIO_MAX_PACKET_SIZE;
		}
		dev->adev.urb[i] = urb;
	}

	for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
		errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
		if (errCode) {
			em28xx_deinit_isoc_audio(dev);
			return errCode;
		}
	}

	return 0;
}

static int em28xx_cmd(struct em28xx *dev, int cmd, int arg)
{
	dprintk("%s transfer\n", (dev->adev.capture_stream == STREAM_ON) ?
				 "stop" : "start");

	switch (cmd) {
	case EM28XX_CAPTURE_STREAM_EN:
		if (dev->adev.capture_stream == STREAM_OFF &&
		    arg == EM28XX_START_AUDIO) {
			dev->adev.capture_stream = STREAM_ON;
			em28xx_init_audio_isoc(dev);
		} else if (dev->adev.capture_stream == STREAM_ON &&
			   arg == EM28XX_STOP_AUDIO) {
			dev->adev.capture_stream = STREAM_OFF;
			em28xx_deinit_isoc_audio(dev);
		} else {
			em28xx_errdev("An underrun very likely occurred. "
					"Ignoring it.\n");
		}
		return 0;
	default:
		return -EINVAL;
	}
}

static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
					size_t size)
{
	struct snd_pcm_runtime *runtime = subs->runtime;

	dprintk("Allocating vbuffer\n");
	if (runtime->dma_area) {
		if (runtime->dma_bytes > size)
			return 0;

		vfree(runtime->dma_area);
	}
	runtime->dma_area = vmalloc(size);
	if (!runtime->dma_area)
		return -ENOMEM;

	runtime->dma_bytes = size;

	return 0;
}

static struct snd_pcm_hardware snd_em28xx_hw_capture = {
	.info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
		SNDRV_PCM_INFO_MMAP           |
		SNDRV_PCM_INFO_INTERLEAVED    |
		SNDRV_PCM_INFO_MMAP_VALID,

	.formats = SNDRV_PCM_FMTBIT_S16_LE,

	.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT,

	.rate_min = 48000,
	.rate_max = 48000,
	.channels_min = 2,
	.channels_max = 2,
	.buffer_bytes_max = 62720 * 8,	/* just about the value in usbaudio.c */
	.period_bytes_min = 64,		/* 12544/2, */
	.period_bytes_max = 12544,
	.periods_min = 2,
	.periods_max = 98,		/* 12544, */
};

static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
{
	struct em28xx *dev = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	int ret = 0;

	dprintk("opening device and trying to acquire exclusive lock\n");

	if (!dev) {
		em28xx_err("BUG: em28xx can't find device struct."
				" Can't proceed with open\n");
		return -ENODEV;
	}

	/* Sets volume, mute, etc */

	dev->mute = 0;
	mutex_lock(&dev->lock);
	ret = em28xx_audio_analog_set(dev);
	mutex_unlock(&dev->lock);
	if (ret < 0)
		goto err;

	runtime->hw = snd_em28xx_hw_capture;
	if (dev->alt == 0 && dev->adev.users == 0) {
		int errCode;
		dev->alt = 7;
		errCode = usb_set_interface(dev->udev, 0, 7);
		dprintk("changing alternate number to 7\n");
	}

	mutex_lock(&dev->lock);
	dev->adev.users++;
	mutex_unlock(&dev->lock);

	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
	dev->adev.capture_pcm_substream = substream;
	runtime->private_data = dev;

	return 0;
err:
	em28xx_err("Error while configuring em28xx mixer\n");
	return ret;
}

static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
{
	struct em28xx *dev = snd_pcm_substream_chip(substream);

	dprintk("closing device\n");

	dev->mute = 1;
	mutex_lock(&dev->lock);
	dev->adev.users--;
	em28xx_audio_analog_set(dev);
	if (substream->runtime->dma_area) {
		dprintk("freeing\n");
		vfree(substream->runtime->dma_area);
		substream->runtime->dma_area = NULL;
	}
	mutex_unlock(&dev->lock);

	return 0;
}

static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream,
					struct snd_pcm_hw_params *hw_params)
{
	unsigned int channels, rate, format;
	int ret;

	dprintk("Setting capture parameters\n");

	ret = snd_pcm_alloc_vmalloc_buffer(substream,
				params_buffer_bytes(hw_params));
	format = params_format(hw_params);
	rate = params_rate(hw_params);
	channels = params_channels(hw_params);

	/* TODO: set up em28xx audio chip to deliver the correct audio format,
	   current default is 48000hz multiplexed => 96000hz mono
	   which shouldn't matter since analogue TV only supports mono */
	return 0;
}

static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)
{
	struct em28xx *dev = snd_pcm_substream_chip(substream);

	dprintk("Stop capture, if needed\n");

	if (dev->adev.capture_stream == STREAM_ON)
		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);

	return 0;
}

static int snd_em28xx_prepare(struct snd_pcm_substream *substream)
{
	struct em28xx *dev = snd_pcm_substream_chip(substream);

	dev->adev.hwptr_done_capture = 0;
	dev->adev.capture_transfer_done = 0;

	return 0;
}

static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
				      int cmd)
{
	struct em28xx *dev = snd_pcm_substream_chip(substream);
	int retval;

	dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ?
				       "start" : "stop");

	spin_lock(&dev->adev.slock);
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_START_AUDIO);
		retval = 0;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);
		retval = 0;
		break;
	default:
		retval = -EINVAL;
	}

	spin_unlock(&dev->adev.slock);
	return retval;
}

static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
						    *substream)
{
	unsigned long flags;
	struct em28xx *dev;
	snd_pcm_uframes_t hwptr_done;

	dev = snd_pcm_substream_chip(substream);
	spin_lock_irqsave(&dev->adev.slock, flags);
	hwptr_done = dev->adev.hwptr_done_capture;
	spin_unlock_irqrestore(&dev->adev.slock, flags);

	return hwptr_done;
}

static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
					     unsigned long offset)
{
	void *pageptr = subs->runtime->dma_area + offset;

	return vmalloc_to_page(pageptr);
}

static struct snd_pcm_ops snd_em28xx_pcm_capture = {
	.open      = snd_em28xx_capture_open,
	.close     = snd_em28xx_pcm_close,
	.ioctl     = snd_pcm_lib_ioctl,
	.hw_params = snd_em28xx_hw_capture_params,
	.hw_free   = snd_em28xx_hw_capture_free,
	.prepare   = snd_em28xx_prepare,
	.trigger   = snd_em28xx_capture_trigger,
	.pointer   = snd_em28xx_capture_pointer,
	.page      = snd_pcm_get_vmalloc_page,
};

static int em28xx_audio_init(struct em28xx *dev)
{
	struct em28xx_audio *adev = &dev->adev;
	struct snd_pcm      *pcm;
	struct snd_card     *card;
	static int          devnr;
	int                 err;

	if (dev->has_alsa_audio != 1) {
		/* This device does not support the extension (in this case
		   the device is expecting the snd-usb-audio module or
		   doesn't have analog audio support at all) */
		return 0;
	}

	printk(KERN_INFO "em28xx-audio.c: probing for em28x1 "
			 "non standard usbaudio\n");
	printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus "
			 "Rechberger\n");

	err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0,
			      &card);
	if (err < 0)
		return err;

	spin_lock_init(&adev->slock);
	err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm);
	if (err < 0) {
		snd_card_free(card);
		return err;
	}

	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture);
	pcm->info_flags = 0;
	pcm->private_data = dev;
	strcpy(pcm->name, "Empia 28xx Capture");

	snd_card_set_dev(card, &dev->udev->dev);
	strcpy(card->driver, "Em28xx-Audio");
	strcpy(card->shortname, "Em28xx Audio");
	strcpy(card->longname, "Empia Em28xx Audio");

	err = snd_card_register(card);
	if (err < 0) {
		snd_card_free(card);
		return err;
	}
	adev->sndcard = card;
	adev->udev = dev->udev;

	return 0;
}

static int em28xx_audio_fini(struct em28xx *dev)
{
	if (dev == NULL)
		return 0;

	if (dev->has_alsa_audio != 1) {
		/* This device does not support the extension (in this case
		   the device is expecting the snd-usb-audio module or
		   doesn't have analog audio support at all) */
		return 0;
	}

	if (dev->adev.sndcard) {
		snd_card_free(dev->adev.sndcard);
		dev->adev.sndcard = NULL;
	}

	return 0;
}

static struct em28xx_ops audio_ops = {
	.id   = EM28XX_AUDIO,
	.name = "Em28xx Audio Extension",
	.init = em28xx_audio_init,
	.fini = em28xx_audio_fini,
};

static int __init em28xx_alsa_register(void)
{
	return em28xx_register_extension(&audio_ops);
}

static void __exit em28xx_alsa_unregister(void)
{
	em28xx_unregister_extension(&audio_ops);
}

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
MODULE_DESCRIPTION("Em28xx Audio driver");

module_init(em28xx_alsa_register);
module_exit(em28xx_alsa_unregister);
