/*
 * STK1160 driver
 *
 * Copyright (C) 2012 Ezequiel Garcia
 * <elezegarcia--a.t--gmail.com>
 *
 * Based on Easycap driver by R.M. Thomas
 *	Copyright (C) 2010 R.M. Thomas
 *	<rmthomas--a.t--sciolus.org>
 *
 * 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.
 *
 * TODO:
 *
 * 1. (Try to) detect if we must register ac97 mixer
 * 2. Support stream at lower speed: lower frame rate or lower frame size.
 *
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/slab.h>

#include <linux/usb.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <media/saa7115.h>

#include "stk1160.h"
#include "stk1160-reg.h"

static unsigned int input;
module_param(input, int, 0644);
MODULE_PARM_DESC(input, "Set default input");

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ezequiel Garcia");
MODULE_DESCRIPTION("STK1160 driver");

/* Devices supported by this driver */
static struct usb_device_id stk1160_id_table[] = {
	{ USB_DEVICE(0x05e1, 0x0408) },
	{ }
};
MODULE_DEVICE_TABLE(usb, stk1160_id_table);

/* saa7113 I2C address */
static unsigned short saa7113_addrs[] = {
	0x4a >> 1,
	I2C_CLIENT_END
};

/*
 * Read/Write stk registers
 */
int stk1160_read_reg(struct stk1160 *dev, u16 reg, u8 *value)
{
	int ret;
	int pipe = usb_rcvctrlpipe(dev->udev, 0);
	u8 *buf;

	*value = 0;

	buf = kmalloc(sizeof(u8), GFP_KERNEL);
	if (!buf)
		return -ENOMEM;
	ret = usb_control_msg(dev->udev, pipe, 0x00,
			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			0x00, reg, buf, sizeof(u8), HZ);
	if (ret < 0) {
		stk1160_err("read failed on reg 0x%x (%d)\n",
			reg, ret);
		kfree(buf);
		return ret;
	}

	*value = *buf;
	kfree(buf);
	return 0;
}

int stk1160_write_reg(struct stk1160 *dev, u16 reg, u16 value)
{
	int ret;
	int pipe = usb_sndctrlpipe(dev->udev, 0);

	ret =  usb_control_msg(dev->udev, pipe, 0x01,
			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			value, reg, NULL, 0, HZ);
	if (ret < 0) {
		stk1160_err("write failed on reg 0x%x (%d)\n",
			reg, ret);
		return ret;
	}

	return 0;
}

void stk1160_select_input(struct stk1160 *dev)
{
	int route;
	static const u8 gctrl[] = {
		0x98, 0x90, 0x88, 0x80, 0x98
	};

	if (dev->ctl_input == STK1160_SVIDEO_INPUT)
		route = SAA7115_SVIDEO3;
	else
		route = SAA7115_COMPOSITE0;

	if (dev->ctl_input < ARRAY_SIZE(gctrl)) {
		v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
				route, 0, 0);
		stk1160_write_reg(dev, STK1160_GCTRL, gctrl[dev->ctl_input]);
	}
}

/* TODO: We should break this into pieces */
static void stk1160_reg_reset(struct stk1160 *dev)
{
	int i;

	static const struct regval ctl[] = {
		{STK1160_GCTRL+2, 0x0078},

		{STK1160_RMCTL+1, 0x0000},
		{STK1160_RMCTL+3, 0x0002},

		{STK1160_PLLSO,   0x0010},
		{STK1160_PLLSO+1, 0x0000},
		{STK1160_PLLSO+2, 0x0014},
		{STK1160_PLLSO+3, 0x000E},

		{STK1160_PLLFD,   0x0046},

		/* Timing generator setup */
		{STK1160_TIGEN,   0x0012},
		{STK1160_TICTL,   0x002D},
		{STK1160_TICTL+1, 0x0001},
		{STK1160_TICTL+2, 0x0000},
		{STK1160_TICTL+3, 0x0000},
		{STK1160_TIGEN,   0x0080},

		{0xffff, 0xffff}
	};

	for (i = 0; ctl[i].reg != 0xffff; i++)
		stk1160_write_reg(dev, ctl[i].reg, ctl[i].val);
}

static void stk1160_release(struct v4l2_device *v4l2_dev)
{
	struct stk1160 *dev = container_of(v4l2_dev, struct stk1160, v4l2_dev);

	stk1160_info("releasing all resources\n");

	stk1160_i2c_unregister(dev);

	v4l2_ctrl_handler_free(&dev->ctrl_handler);
	v4l2_device_unregister(&dev->v4l2_dev);
	kfree(dev->alt_max_pkt_size);
	kfree(dev);
}

/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */
#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))

/*
 * Scan usb interface and populate max_pkt_size array
 * with information on each alternate setting.
 * The array should be allocated by the caller.
 */
static int stk1160_scan_usb(struct usb_interface *intf, struct usb_device *udev,
		unsigned int *max_pkt_size)
{
	int i, e, sizedescr, size, ifnum;
	const struct usb_endpoint_descriptor *desc;

	bool has_video = false, has_audio = false;
	const char *speed;

	ifnum = intf->altsetting[0].desc.bInterfaceNumber;

	/* Get endpoints */
	for (i = 0; i < intf->num_altsetting; i++) {

		for (e = 0; e < intf->altsetting[i].desc.bNumEndpoints; e++) {

			/* This isn't clear enough, at least to me */
			desc = &intf->altsetting[i].endpoint[e].desc;
			sizedescr = le16_to_cpu(desc->wMaxPacketSize);
			size = sizedescr & 0x7ff;

			if (udev->speed == USB_SPEED_HIGH)
				size = size * hb_mult(sizedescr);

			if (usb_endpoint_xfer_isoc(desc) &&
			    usb_endpoint_dir_in(desc)) {
				switch (desc->bEndpointAddress) {
				case STK1160_EP_AUDIO:
					has_audio = true;
					break;
				case STK1160_EP_VIDEO:
					has_video = true;
					max_pkt_size[i] = size;
					break;
				}
			}
		}
	}

	/* Is this even possible? */
	if (!(has_audio || has_video)) {
		dev_err(&udev->dev, "no audio or video endpoints found\n");
		return -ENODEV;
	}

	switch (udev->speed) {
	case USB_SPEED_LOW:
		speed = "1.5";
		break;
	case USB_SPEED_FULL:
		speed = "12";
		break;
	case USB_SPEED_HIGH:
		speed = "480";
		break;
	default:
		speed = "unknown";
	}

	dev_info(&udev->dev, "New device %s %s @ %s Mbps (%04x:%04x, interface %d, class %d)\n",
		udev->manufacturer ? udev->manufacturer : "",
		udev->product ? udev->product : "",
		speed,
		le16_to_cpu(udev->descriptor.idVendor),
		le16_to_cpu(udev->descriptor.idProduct),
		ifnum,
		intf->altsetting->desc.bInterfaceNumber);

	/* This should never happen, since we rejected audio interfaces */
	if (has_audio)
		dev_warn(&udev->dev, "audio interface %d found.\n\
				This is not implemented by this driver,\
				you should use snd-usb-audio instead\n", ifnum);

	if (has_video)
		dev_info(&udev->dev, "video interface %d found\n",
				ifnum);

	/*
	 * Make sure we have 480 Mbps of bandwidth, otherwise things like
	 * video stream wouldn't likely work, since 12 Mbps is generally
	 * not enough even for most streams.
	 */
	if (udev->speed != USB_SPEED_HIGH)
		dev_warn(&udev->dev, "must be connected to a high-speed USB 2.0 port\n\
				You may not be able to stream video smoothly\n");

	return 0;
}

static int stk1160_probe(struct usb_interface *interface,
		const struct usb_device_id *id)
{
	int rc = 0;

	unsigned int *alt_max_pkt_size;	/* array of wMaxPacketSize */
	struct usb_device *udev;
	struct stk1160 *dev;

	udev = interface_to_usbdev(interface);

	/*
	 * Since usb audio class is supported by snd-usb-audio,
	 * we reject audio interface.
	 */
	if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO)
		return -ENODEV;

	/* Alloc an array for all possible max_pkt_size */
	alt_max_pkt_size = kmalloc(sizeof(alt_max_pkt_size[0]) *
			interface->num_altsetting, GFP_KERNEL);
	if (alt_max_pkt_size == NULL)
		return -ENOMEM;

	/*
	 * Scan usb posibilities and populate alt_max_pkt_size array.
	 * Also, check if device speed is fast enough.
	 */
	rc = stk1160_scan_usb(interface, udev, alt_max_pkt_size);
	if (rc < 0) {
		kfree(alt_max_pkt_size);
		return rc;
	}

	dev = kzalloc(sizeof(struct stk1160), GFP_KERNEL);
	if (dev == NULL) {
		kfree(alt_max_pkt_size);
		return -ENOMEM;
	}

	dev->alt_max_pkt_size = alt_max_pkt_size;
	dev->udev = udev;
	dev->num_alt = interface->num_altsetting;
	dev->ctl_input = input;

	/* We save struct device for debug purposes only */
	dev->dev = &interface->dev;

	usb_set_intfdata(interface, dev);

	/* initialize videobuf2 stuff */
	rc = stk1160_vb2_setup(dev);
	if (rc < 0)
		goto free_err;

	/*
	 * There is no need to take any locks here in probe
	 * because we register the device node as the *last* thing.
	 */
	spin_lock_init(&dev->buf_lock);
	mutex_init(&dev->v4l_lock);
	mutex_init(&dev->vb_queue_lock);

	rc = v4l2_ctrl_handler_init(&dev->ctrl_handler, 0);
	if (rc) {
		stk1160_err("v4l2_ctrl_handler_init failed (%d)\n", rc);
		goto free_err;
	}

	/*
	 * We obtain a v4l2_dev but defer
	 * registration of video device node as the last thing.
	 * There is no need to set the name if we give a device struct
	 */
	dev->v4l2_dev.release = stk1160_release;
	dev->v4l2_dev.ctrl_handler = &dev->ctrl_handler;
	rc = v4l2_device_register(dev->dev, &dev->v4l2_dev);
	if (rc) {
		stk1160_err("v4l2_device_register failed (%d)\n", rc);
		goto free_ctrl;
	}

	rc = stk1160_i2c_register(dev);
	if (rc < 0)
		goto unreg_v4l2;

	/*
	 * To the best of my knowledge stk1160 boards only have
	 * saa7113, but it doesn't hurt to support them all.
	 */
	dev->sd_saa7115 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
		"saa7115_auto", 0, saa7113_addrs);

	stk1160_info("driver ver %s successfully loaded\n",
		STK1160_VERSION);

	/* i2c reset saa711x */
	v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0);
	v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);

	/* reset stk1160 to default values */
	stk1160_reg_reset(dev);

	/* select default input */
	stk1160_select_input(dev);

	stk1160_ac97_register(dev);

	rc = stk1160_video_register(dev);
	if (rc < 0)
		goto unreg_i2c;

	return 0;

unreg_i2c:
	stk1160_i2c_unregister(dev);
unreg_v4l2:
	v4l2_device_unregister(&dev->v4l2_dev);
free_ctrl:
	v4l2_ctrl_handler_free(&dev->ctrl_handler);
free_err:
	kfree(alt_max_pkt_size);
	kfree(dev);

	return rc;
}

static void stk1160_disconnect(struct usb_interface *interface)
{
	struct stk1160 *dev;

	dev = usb_get_intfdata(interface);
	usb_set_intfdata(interface, NULL);

	/*
	 * Wait until all current v4l2 operation are finished
	 * then deallocate resources
	 */
	mutex_lock(&dev->vb_queue_lock);
	mutex_lock(&dev->v4l_lock);

	/* Here is the only place where isoc get released */
	stk1160_uninit_isoc(dev);

	/* ac97 unregister needs to be done before usb_device is cleared */
	stk1160_ac97_unregister(dev);

	stk1160_clear_queue(dev);

	video_unregister_device(&dev->vdev);
	v4l2_device_disconnect(&dev->v4l2_dev);

	/* This way current users can detect device is gone */
	dev->udev = NULL;

	mutex_unlock(&dev->v4l_lock);
	mutex_unlock(&dev->vb_queue_lock);

	/*
	 * This calls stk1160_release if it's the last reference.
	 * therwise, release is posponed until there are no users left.
	 */
	v4l2_device_put(&dev->v4l2_dev);
}

static struct usb_driver stk1160_usb_driver = {
	.name = "stk1160",
	.id_table = stk1160_id_table,
	.probe = stk1160_probe,
	.disconnect = stk1160_disconnect,
};

module_usb_driver(stk1160_usb_driver);
