/*
 * Abilis Systems Single DVB-T Receiver
 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
 *
 * 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, 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/errno.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/usb.h>

#include "as102_drv.h"
#include "as102_usb_drv.h"
#include "as102_fw.h"

static void as102_usb_disconnect(struct usb_interface *interface);
static int as102_usb_probe(struct usb_interface *interface,
			   const struct usb_device_id *id);

static int as102_usb_start_stream(struct as102_dev_t *dev);
static void as102_usb_stop_stream(struct as102_dev_t *dev);

static int as102_open(struct inode *inode, struct file *file);
static int as102_release(struct inode *inode, struct file *file);

static struct usb_device_id as102_usb_id_table[] = {
	{ USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) },
	{ USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) },
	{ USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) },
	{ USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) },
	{ USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID) },
	{ } /* Terminating entry */
};

/* Note that this table must always have the same number of entries as the
   as102_usb_id_table struct */
static const char * const as102_device_names[] = {
	AS102_REFERENCE_DESIGN,
	AS102_PCTV_74E,
	AS102_ELGATO_EYETV_DTT_NAME,
	AS102_NBOX_DVBT_DONGLE_NAME,
	AS102_SKY_IT_DIGITAL_KEY_NAME,
	NULL /* Terminating entry */
};

struct usb_driver as102_usb_driver = {
	.name		= DRIVER_FULL_NAME,
	.probe		= as102_usb_probe,
	.disconnect	= as102_usb_disconnect,
	.id_table	= as102_usb_id_table
};

static const struct file_operations as102_dev_fops = {
	.owner		= THIS_MODULE,
	.open		= as102_open,
	.release	= as102_release,
};

static struct usb_class_driver as102_usb_class_driver = {
	.name		= "aton2-%d",
	.fops		= &as102_dev_fops,
	.minor_base	= AS102_DEVICE_MAJOR,
};

static int as102_usb_xfer_cmd(struct as10x_bus_adapter_t *bus_adap,
			      unsigned char *send_buf, int send_buf_len,
			      unsigned char *recv_buf, int recv_buf_len)
{
	int ret = 0;
	ENTER();

	if (send_buf != NULL) {
		ret = usb_control_msg(bus_adap->usb_dev,
				      usb_sndctrlpipe(bus_adap->usb_dev, 0),
				      AS102_USB_DEVICE_TX_CTRL_CMD,
				      USB_DIR_OUT | USB_TYPE_VENDOR |
				      USB_RECIP_DEVICE,
				      bus_adap->cmd_xid, /* value */
				      0, /* index */
				      send_buf, send_buf_len,
				      USB_CTRL_SET_TIMEOUT /* 200 */);
		if (ret < 0) {
			dprintk(debug, "usb_control_msg(send) failed, err %i\n",
					ret);
			return ret;
		}

		if (ret != send_buf_len) {
			dprintk(debug, "only wrote %d of %d bytes\n",
					ret, send_buf_len);
			return -1;
		}
	}

	if (recv_buf != NULL) {
#ifdef TRACE
		dprintk(debug, "want to read: %d bytes\n", recv_buf_len);
#endif
		ret = usb_control_msg(bus_adap->usb_dev,
				      usb_rcvctrlpipe(bus_adap->usb_dev, 0),
				      AS102_USB_DEVICE_RX_CTRL_CMD,
				      USB_DIR_IN | USB_TYPE_VENDOR |
				      USB_RECIP_DEVICE,
				      bus_adap->cmd_xid, /* value */
				      0, /* index */
				      recv_buf, recv_buf_len,
				      USB_CTRL_GET_TIMEOUT /* 200 */);
		if (ret < 0) {
			dprintk(debug, "usb_control_msg(recv) failed, err %i\n",
					ret);
			return ret;
		}
#ifdef TRACE
		dprintk(debug, "read %d bytes\n", recv_buf_len);
#endif
	}

	LEAVE();
	return ret;
}

static int as102_send_ep1(struct as10x_bus_adapter_t *bus_adap,
			  unsigned char *send_buf,
			  int send_buf_len,
			  int swap32)
{
	int ret = 0, actual_len;

	ret = usb_bulk_msg(bus_adap->usb_dev,
			   usb_sndbulkpipe(bus_adap->usb_dev, 1),
			   send_buf, send_buf_len, &actual_len, 200);
	if (ret) {
		dprintk(debug, "usb_bulk_msg(send) failed, err %i\n", ret);
		return ret;
	}

	if (actual_len != send_buf_len) {
		dprintk(debug, "only wrote %d of %d bytes\n",
				actual_len, send_buf_len);
		return -1;
	}
	return ret ? ret : actual_len;
}

static int as102_read_ep2(struct as10x_bus_adapter_t *bus_adap,
		   unsigned char *recv_buf, int recv_buf_len)
{
	int ret = 0, actual_len;

	if (recv_buf == NULL)
		return -EINVAL;

	ret = usb_bulk_msg(bus_adap->usb_dev,
			   usb_rcvbulkpipe(bus_adap->usb_dev, 2),
			   recv_buf, recv_buf_len, &actual_len, 200);
	if (ret) {
		dprintk(debug, "usb_bulk_msg(recv) failed, err %i\n", ret);
		return ret;
	}

	if (actual_len != recv_buf_len) {
		dprintk(debug, "only read %d of %d bytes\n",
				actual_len, recv_buf_len);
		return -1;
	}
	return ret ? ret : actual_len;
}

struct as102_priv_ops_t as102_priv_ops = {
	.upload_fw_pkt	= as102_send_ep1,
	.xfer_cmd	= as102_usb_xfer_cmd,
	.as102_read_ep2	= as102_read_ep2,
	.start_stream	= as102_usb_start_stream,
	.stop_stream	= as102_usb_stop_stream,
};

static int as102_submit_urb_stream(struct as102_dev_t *dev, struct urb *urb)
{
	int err;

	usb_fill_bulk_urb(urb,
			  dev->bus_adap.usb_dev,
			  usb_rcvbulkpipe(dev->bus_adap.usb_dev, 0x2),
			  urb->transfer_buffer,
			  AS102_USB_BUF_SIZE,
			  as102_urb_stream_irq,
			  dev);

	err = usb_submit_urb(urb, GFP_ATOMIC);
	if (err)
		dprintk(debug, "%s: usb_submit_urb failed\n", __func__);

	return err;
}

void as102_urb_stream_irq(struct urb *urb)
{
	struct as102_dev_t *as102_dev = urb->context;

	if (urb->actual_length > 0) {
		dvb_dmx_swfilter(&as102_dev->dvb_dmx,
				 urb->transfer_buffer,
				 urb->actual_length);
	} else {
		if (urb->actual_length == 0)
			memset(urb->transfer_buffer, 0, AS102_USB_BUF_SIZE);
	}

	/* is not stopped, re-submit urb */
	if (as102_dev->streaming)
		as102_submit_urb_stream(as102_dev, urb);
}

static void as102_free_usb_stream_buffer(struct as102_dev_t *dev)
{
	int i;

	ENTER();

	for (i = 0; i < MAX_STREAM_URB; i++)
		usb_free_urb(dev->stream_urb[i]);

	usb_free_coherent(dev->bus_adap.usb_dev,
			MAX_STREAM_URB * AS102_USB_BUF_SIZE,
			dev->stream,
			dev->dma_addr);
	LEAVE();
}

static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev)
{
	int i, ret = 0;

	ENTER();

	dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev,
				       MAX_STREAM_URB * AS102_USB_BUF_SIZE,
				       GFP_KERNEL,
				       &dev->dma_addr);
	if (!dev->stream) {
		dprintk(debug, "%s: usb_buffer_alloc failed\n", __func__);
		return -ENOMEM;
	}

	memset(dev->stream, 0, MAX_STREAM_URB * AS102_USB_BUF_SIZE);

	/* init urb buffers */
	for (i = 0; i < MAX_STREAM_URB; i++) {
		struct urb *urb;

		urb = usb_alloc_urb(0, GFP_ATOMIC);
		if (urb == NULL) {
			dprintk(debug, "%s: usb_alloc_urb failed\n", __func__);
			as102_free_usb_stream_buffer(dev);
			return -ENOMEM;
		}

		urb->transfer_buffer = dev->stream + (i * AS102_USB_BUF_SIZE);
		urb->transfer_buffer_length = AS102_USB_BUF_SIZE;

		dev->stream_urb[i] = urb;
	}
	LEAVE();
	return ret;
}

static void as102_usb_stop_stream(struct as102_dev_t *dev)
{
	int i;

	for (i = 0; i < MAX_STREAM_URB; i++)
		usb_kill_urb(dev->stream_urb[i]);
}

static int as102_usb_start_stream(struct as102_dev_t *dev)
{
	int i, ret = 0;

	for (i = 0; i < MAX_STREAM_URB; i++) {
		ret = as102_submit_urb_stream(dev, dev->stream_urb[i]);
		if (ret) {
			as102_usb_stop_stream(dev);
			return ret;
		}
	}

	return 0;
}

static void as102_usb_release(struct kref *kref)
{
	struct as102_dev_t *as102_dev;

	ENTER();

	as102_dev = container_of(kref, struct as102_dev_t, kref);
	if (as102_dev != NULL) {
		usb_put_dev(as102_dev->bus_adap.usb_dev);
		kfree(as102_dev);
	}

	LEAVE();
}

static void as102_usb_disconnect(struct usb_interface *intf)
{
	struct as102_dev_t *as102_dev;

	ENTER();

	/* extract as102_dev_t from usb_device private data */
	as102_dev = usb_get_intfdata(intf);

	/* unregister dvb layer */
	as102_dvb_unregister(as102_dev);

	/* free usb buffers */
	as102_free_usb_stream_buffer(as102_dev);

	usb_set_intfdata(intf, NULL);

	/* usb unregister device */
	usb_deregister_dev(intf, &as102_usb_class_driver);

	/* decrement usage counter */
	kref_put(&as102_dev->kref, as102_usb_release);

	pr_info("%s: device has been disconnected\n", DRIVER_NAME);

	LEAVE();
}

static int as102_usb_probe(struct usb_interface *intf,
			   const struct usb_device_id *id)
{
	int ret;
	struct as102_dev_t *as102_dev;
	int i;

	ENTER();

	/* This should never actually happen */
	if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) !=
	    (sizeof(as102_device_names) / sizeof(const char *))) {
		pr_err("Device names table invalid size");
		return -EINVAL;
	}

	as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL);
	if (as102_dev == NULL) {
		err("%s: kzalloc failed", __func__);
		return -ENOMEM;
	}

	/* Assign the user-friendly device name */
	for (i = 0; i < (sizeof(as102_usb_id_table) /
			 sizeof(struct usb_device_id)); i++) {
		if (id == &as102_usb_id_table[i])
			as102_dev->name = as102_device_names[i];
	}

	if (as102_dev->name == NULL)
		as102_dev->name = "Unknown AS102 device";

	/* set private callback functions */
	as102_dev->bus_adap.ops = &as102_priv_ops;

	/* init cmd token for usb bus */
	as102_dev->bus_adap.cmd = &as102_dev->bus_adap.token.usb.c;
	as102_dev->bus_adap.rsp = &as102_dev->bus_adap.token.usb.r;

	/* init kernel device reference */
	kref_init(&as102_dev->kref);

	/* store as102 device to usb_device private data */
	usb_set_intfdata(intf, (void *) as102_dev);

	/* store in as102 device the usb_device pointer */
	as102_dev->bus_adap.usb_dev = usb_get_dev(interface_to_usbdev(intf));

	/* we can register the device now, as it is ready */
	ret = usb_register_dev(intf, &as102_usb_class_driver);
	if (ret < 0) {
		/* something prevented us from registering this driver */
		err("%s: usb_register_dev() failed (errno = %d)",
		    __func__, ret);
		goto failed;
	}

	pr_info("%s: device has been detected\n", DRIVER_NAME);

	/* request buffer allocation for streaming */
	ret = as102_alloc_usb_stream_buffer(as102_dev);
	if (ret != 0)
		goto failed;

	/* register dvb layer */
	ret = as102_dvb_register(as102_dev);

	LEAVE();
	return ret;

failed:
	usb_set_intfdata(intf, NULL);
	kfree(as102_dev);
	return ret;
}

static int as102_open(struct inode *inode, struct file *file)
{
	int ret = 0, minor = 0;
	struct usb_interface *intf = NULL;
	struct as102_dev_t *dev = NULL;

	ENTER();

	/* read minor from inode */
	minor = iminor(inode);

	/* fetch device from usb interface */
	intf = usb_find_interface(&as102_usb_driver, minor);
	if (intf == NULL) {
		pr_err("%s: can't find device for minor %d\n",
		       __func__, minor);
		ret = -ENODEV;
		goto exit;
	}

	/* get our device */
	dev = usb_get_intfdata(intf);
	if (dev == NULL) {
		ret = -EFAULT;
		goto exit;
	}

	/* save our device object in the file's private structure */
	file->private_data = dev;

	/* increment our usage count for the device */
	kref_get(&dev->kref);

exit:
	LEAVE();
	return ret;
}

static int as102_release(struct inode *inode, struct file *file)
{
	int ret = 0;
	struct as102_dev_t *dev = NULL;

	ENTER();

	dev = file->private_data;
	if (dev != NULL) {
		/* decrement the count on our device */
		kref_put(&dev->kref, as102_usb_release);
	}

	LEAVE();
	return ret;
}

MODULE_DEVICE_TABLE(usb, as102_usb_id_table);
