/*
 * gspca ViCam subdriver
 *
 * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com>
 *
 * Based on the usbvideo vicam driver, which is:
 *
 * Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
 *                    Christopher L Cheney (ccheney@cheney.cx),
 *                    Pavel Machek (pavel@ucw.cz),
 *                    John Tyner (jtyner@cs.ucr.edu),
 *                    Monroe Williams (monroe@pobox.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 of the License, or
 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#define MODULE_NAME "vicam"
#define HEADER_SIZE 64

#include <linux/workqueue.h>
#include <linux/slab.h>
#include <linux/firmware.h>
#include <linux/ihex.h>
#include "gspca.h"

MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_DESCRIPTION("GSPCA ViCam USB Camera Driver");
MODULE_LICENSE("GPL");

enum e_ctrl {
	GAIN,
	EXPOSURE,
	NCTRL		/* number of controls */
};

struct sd {
	struct gspca_dev gspca_dev;	/* !! must be the first item */
	struct work_struct work_struct;
	struct workqueue_struct *work_thread;
	struct gspca_ctrl ctrls[NCTRL];
};

/* The vicam sensor has a resolution of 512 x 244, with I believe square
   pixels, but this is forced to a 4:3 ratio by optics. So it has
   non square pixels :( */
static struct v4l2_pix_format vicam_mode[] = {
	{ 256, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
		.bytesperline = 256,
		.sizeimage = 256 * 122,
		.colorspace = V4L2_COLORSPACE_SRGB,},
	/* 2 modes with somewhat more square pixels */
	{ 256, 200, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
		.bytesperline = 256,
		.sizeimage = 256 * 200,
		.colorspace = V4L2_COLORSPACE_SRGB,},
	{ 256, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
		.bytesperline = 256,
		.sizeimage = 256 * 240,
		.colorspace = V4L2_COLORSPACE_SRGB,},
#if 0   /* This mode has extremely non square pixels, testing use only */
	{ 512, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
		.bytesperline = 512,
		.sizeimage = 512 * 122,
		.colorspace = V4L2_COLORSPACE_SRGB,},
#endif
	{ 512, 244, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
		.bytesperline = 512,
		.sizeimage = 512 * 244,
		.colorspace = V4L2_COLORSPACE_SRGB,},
};

static const struct ctrl sd_ctrls[] = {
[GAIN] = {
	    {
		.id      = V4L2_CID_GAIN,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Gain",
		.minimum = 0,
		.maximum = 255,
		.step    = 1,
		.default_value = 200,
	    },
	},
[EXPOSURE] = {
	    {
		.id      = V4L2_CID_EXPOSURE,
		.type    = V4L2_CTRL_TYPE_INTEGER,
		.name    = "Exposure",
		.minimum = 0,
		.maximum = 2047,
		.step    = 1,
		.default_value = 256,
	    },
	},
};

static int vicam_control_msg(struct gspca_dev *gspca_dev, u8 request,
	u16 value, u16 index, u8 *data, u16 len)
{
	int ret;

	ret = usb_control_msg(gspca_dev->dev,
			      usb_sndctrlpipe(gspca_dev->dev, 0),
			      request,
			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
			      value, index, data, len, 1000);
	if (ret < 0)
		err("control msg req %02X error %d", request, ret);

	return ret;
}

static int vicam_set_camera_power(struct gspca_dev *gspca_dev, int state)
{
	int ret;

	ret = vicam_control_msg(gspca_dev, 0x50, state, 0, NULL, 0);
	if (ret < 0)
		return ret;

	if (state)
		ret = vicam_control_msg(gspca_dev, 0x55, 1, 0, NULL, 0);

	return ret;
}

/*
 *  request and read a block of data - see warning on vicam_command.
 */
static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size)
{
	struct sd *sd = (struct sd *)gspca_dev;
	int ret, unscaled_height, act_len = 0;
	u8 *req_data = gspca_dev->usb_buf;

	memset(req_data, 0, 16);
	req_data[0] = sd->ctrls[GAIN].val;
	if (gspca_dev->width == 256)
		req_data[1] |= 0x01; /* low nibble x-scale */
	if (gspca_dev->height <= 122) {
		req_data[1] |= 0x10; /* high nibble y-scale */
		unscaled_height = gspca_dev->height * 2;
	} else
		unscaled_height = gspca_dev->height;
	req_data[2] = 0x90; /* unknown, does not seem to do anything */
	if (unscaled_height <= 200)
		req_data[3] = 0x06; /* vend? */
	else if (unscaled_height <= 242) /* Yes 242 not 240 */
		req_data[3] = 0x07; /* vend? */
	else /* Up to 244 lines with req_data[3] == 0x08 */
		req_data[3] = 0x08; /* vend? */

	if (sd->ctrls[EXPOSURE].val < 256) {
		/* Frame rate maxed out, use partial frame expo time */
		req_data[4] = 255 - sd->ctrls[EXPOSURE].val;
		req_data[5] = 0x00;
		req_data[6] = 0x00;
		req_data[7] = 0x01;
	} else {
		/* Modify frame rate */
		req_data[4] = 0x00;
		req_data[5] = 0x00;
		req_data[6] = sd->ctrls[EXPOSURE].val & 0xFF;
		req_data[7] = sd->ctrls[EXPOSURE].val >> 8;
	}
	req_data[8] = ((244 - unscaled_height) / 2) & ~0x01; /* vstart */
	/* bytes 9-15 do not seem to affect exposure or image quality */

	mutex_lock(&gspca_dev->usb_lock);
	ret = vicam_control_msg(gspca_dev, 0x51, 0x80, 0, req_data, 16);
	mutex_unlock(&gspca_dev->usb_lock);
	if (ret < 0)
		return ret;

	ret = usb_bulk_msg(gspca_dev->dev,
			   usb_rcvbulkpipe(gspca_dev->dev, 0x81),
			   data, size, &act_len, 10000);
	/* successful, it returns 0, otherwise  negative */
	if (ret < 0 || act_len != size) {
		err("bulk read fail (%d) len %d/%d",
			ret, act_len, size);
		return -EIO;
	}
	return 0;
}

/* This function is called as a workqueue function and runs whenever the camera
 * is streaming data. Because it is a workqueue function it is allowed to sleep
 * so we can use synchronous USB calls. To avoid possible collisions with other
 * threads attempting to use the camera's USB interface we take the gspca
 * usb_lock when performing USB operations. In practice the only thing we need
 * to protect against is the usb_set_interface call that gspca makes during
 * stream_off as the camera doesn't provide any controls that the user could try
 * to change.
 */
static void vicam_dostream(struct work_struct *work)
{
	struct sd *sd = container_of(work, struct sd, work_struct);
	struct gspca_dev *gspca_dev = &sd->gspca_dev;
	int ret, frame_sz;
	u8 *buffer;

	frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage +
		   HEADER_SIZE;
	buffer = kmalloc(frame_sz, GFP_KERNEL | GFP_DMA);
	if (!buffer) {
		err("Couldn't allocate USB buffer");
		goto exit;
	}

	while (gspca_dev->present && gspca_dev->streaming) {
		ret = vicam_read_frame(gspca_dev, buffer, frame_sz);
		if (ret < 0)
			break;

		/* Note the frame header contents seem to be completely
		   constant, they do not change with either image, or
		   settings. So we simply discard it. The frames have
		   a very similar 64 byte footer, which we don't even
		   bother reading from the cam */
		gspca_frame_add(gspca_dev, FIRST_PACKET,
				buffer + HEADER_SIZE,
				frame_sz - HEADER_SIZE);
		gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
	}
exit:
	kfree(buffer);
}

/* This function is called at probe time just before sd_init */
static int sd_config(struct gspca_dev *gspca_dev,
		const struct usb_device_id *id)
{
	struct cam *cam = &gspca_dev->cam;
	struct sd *sd = (struct sd *)gspca_dev;

	/* We don't use the buffer gspca allocates so make it small. */
	cam->bulk = 1;
	cam->bulk_size = 64;
	cam->cam_mode = vicam_mode;
	cam->nmodes = ARRAY_SIZE(vicam_mode);
	cam->ctrls = sd->ctrls;

	INIT_WORK(&sd->work_struct, vicam_dostream);

	return 0;
}

/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
	int ret;
	const struct ihex_binrec *rec;
	const struct firmware *uninitialized_var(fw);
	u8 *firmware_buf;

	ret = request_ihex_firmware(&fw, "vicam/firmware.fw",
				    &gspca_dev->dev->dev);
	if (ret) {
		err("Failed to load \"vicam/firmware.fw\": %d\n", ret);
		return ret;
	}

	firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
	if (!firmware_buf) {
		ret = -ENOMEM;
		goto exit;
	}
	for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
		memcpy(firmware_buf, rec->data, be16_to_cpu(rec->len));
		ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf,
					be16_to_cpu(rec->len));
		if (ret < 0)
			break;
	}

	kfree(firmware_buf);
exit:
	release_firmware(fw);
	return ret;
}

/* Set up for getting frames. */
static int sd_start(struct gspca_dev *gspca_dev)
{
	struct sd *sd = (struct sd *)gspca_dev;
	int ret;

	ret = vicam_set_camera_power(gspca_dev, 1);
	if (ret < 0)
		return ret;

	/* Start the workqueue function to do the streaming */
	sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
	queue_work(sd->work_thread, &sd->work_struct);

	return 0;
}

/* called on streamoff with alt==0 and on disconnect */
/* the usb_lock is held at entry - restore on exit */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
	struct sd *dev = (struct sd *)gspca_dev;

	/* wait for the work queue to terminate */
	mutex_unlock(&gspca_dev->usb_lock);
	/* This waits for vicam_dostream to finish */
	destroy_workqueue(dev->work_thread);
	dev->work_thread = NULL;
	mutex_lock(&gspca_dev->usb_lock);

	vicam_set_camera_power(gspca_dev, 0);
}

/* Table of supported USB devices */
static const struct usb_device_id device_table[] = {
	{USB_DEVICE(0x04c1, 0x009d)},
	{USB_DEVICE(0x0602, 0x1001)},
	{}
};

MODULE_DEVICE_TABLE(usb, device_table);

/* sub-driver description */
static const struct sd_desc sd_desc = {
	.name   = MODULE_NAME,
	.ctrls  = sd_ctrls,
	.nctrls = ARRAY_SIZE(sd_ctrls),
	.config = sd_config,
	.init   = sd_init,
	.start  = sd_start,
	.stop0  = sd_stop0,
};

/* -- device connect -- */
static int sd_probe(struct usb_interface *intf,
		const struct usb_device_id *id)
{
	return gspca_dev_probe(intf, id,
			&sd_desc,
			sizeof(struct sd),
			THIS_MODULE);
}

static struct usb_driver sd_driver = {
	.name       = MODULE_NAME,
	.id_table   = device_table,
	.probe      = sd_probe,
	.disconnect = gspca_disconnect,
#ifdef CONFIG_PM
	.suspend = gspca_suspend,
	.resume  = gspca_resume,
#endif
};

/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
	return usb_register(&sd_driver);
}

static void __exit sd_mod_exit(void)
{
	usb_deregister(&sd_driver);
}

module_init(sd_mod_init);
module_exit(sd_mod_exit);
