/*
 * 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 */
};

/* eLNA configuration: devices built on the reference design work best
   with 0xA0, while custom designs seem to require 0xC0 */
static uint8_t const as102_elna_cfg[] = {
	0xA0,
	0xC0,
	0xC0,
	0xA0,
	0xA0,
	0x00 /* 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_dma = dev->dma_addr + (i * AS102_USB_BUF_SIZE);
		urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
		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 (ARRAY_SIZE(as102_usb_id_table) !=
	    (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) {
		dev_err(&intf->dev, "%s: kzalloc failed\n", __func__);
		return -ENOMEM;
	}

	/* Assign the user-friendly device name */
	for (i = 0; i < ARRAY_SIZE(as102_usb_id_table); i++) {
		if (id == &as102_usb_id_table[i]) {
			as102_dev->name = as102_device_names[i];
			as102_dev->elna_cfg = as102_elna_cfg[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 */
		dev_err(&intf->dev,
			"%s: usb_register_dev() failed (errno = %d)\n",
			__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);
