121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede/*
221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * STV0680 USB Camera Driver
321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede *
41fddcf0e8b3b6e6405b051da0a6faa93ea7af5cfHans de Goede * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede *
621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * This module is adapted from the in kernel v4l1 stv680 driver:
721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede *
821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede *  STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede *
1021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * Thanks to STMicroelectronics for information on the usb commands, and
1121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * to Steve Miller at STM for his help and encouragement while I was
1221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * writing this driver.
1321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede *
1421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * This program is free software; you can redistribute it and/or modify
1521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * it under the terms of the GNU General Public License as published by
1621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * the Free Software Foundation; either version 2 of the License, or
1721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * (at your option) any later version.
1821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede *
1921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * This program is distributed in the hope that it will be useful,
2021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * but WITHOUT ANY WARRANTY; without even the implied warranty of
2121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * GNU General Public License for more details.
2321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede *
2421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * You should have received a copy of the GNU General Public License
2521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * along with this program; if not, write to the Free Software
2621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
2721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede *
2821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede */
2921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
30133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches
3221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede#define MODULE_NAME "stv0680"
3321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
3421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede#include "gspca.h"
3521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
361fddcf0e8b3b6e6405b051da0a6faa93ea7af5cfHans de GoedeMODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
3721f1b932dbcc5ed18444e6995aeb856e583804aeHans de GoedeMODULE_DESCRIPTION("STV0680 USB Camera Driver");
3821f1b932dbcc5ed18444e6995aeb856e583804aeHans de GoedeMODULE_LICENSE("GPL");
3921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
4021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede/* specific webcam descriptor */
4121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestruct sd {
4221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	struct gspca_dev gspca_dev;		/* !! must be the first item */
4321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	struct v4l2_pix_format mode;
4421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	u8 orig_mode;
4521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	u8 video_mode;
4621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	u8 current_mode;
4721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede};
4821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
4921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic int stv_sndctrl(struct gspca_dev *gspca_dev, int set, u8 req, u16 val,
5021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		       int size)
5121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
5221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	int ret = -1;
5321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	u8 req_type = 0;
54388a6d54168923d0243d4c752586e87231a75291Hans de Goede	unsigned int pipe = 0;
5521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
5621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	switch (set) {
5721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	case 0: /*  0xc1  */
5821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		req_type = USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
59388a6d54168923d0243d4c752586e87231a75291Hans de Goede		pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
6021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		break;
6121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	case 1: /*  0x41  */
6221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT;
63388a6d54168923d0243d4c752586e87231a75291Hans de Goede		pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
6421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		break;
6521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	case 2:	/*  0x80  */
6621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		req_type = USB_DIR_IN | USB_RECIP_DEVICE;
67388a6d54168923d0243d4c752586e87231a75291Hans de Goede		pipe = usb_rcvctrlpipe(gspca_dev->dev, 0);
6821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		break;
6921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	case 3:	/*  0x40  */
7021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		req_type = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
71388a6d54168923d0243d4c752586e87231a75291Hans de Goede		pipe = usb_sndctrlpipe(gspca_dev->dev, 0);
7221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		break;
7321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	}
7421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
75388a6d54168923d0243d4c752586e87231a75291Hans de Goede	ret = usb_control_msg(gspca_dev->dev, pipe,
7621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			      req, req_type,
7721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			      val, 0, gspca_dev->usb_buf, size, 500);
7821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
7921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if ((ret < 0) && (req != 0x0a))
80133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches		pr_err("usb_control_msg error %i, request = 0x%x, error = %i\n",
8121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		       set, req, ret);
8221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
8321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	return ret;
8421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
8521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
8621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic int stv0680_handle_error(struct gspca_dev *gspca_dev, int ret)
8721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
8821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	stv_sndctrl(gspca_dev, 0, 0x80, 0, 0x02); /* Get Last Error */
89c93396e13576928a073154b5715761ff8a998368Theodore Kilgore	PERR("last error: %i,  command = 0x%x",
9021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	       gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
9121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	return ret;
9221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
9321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
9421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic int stv0680_get_video_mode(struct gspca_dev *gspca_dev)
9521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
9621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* Note not sure if this init of usb_buf is really necessary */
9721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	memset(gspca_dev->usb_buf, 0, 8);
9821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	gspca_dev->usb_buf[0] = 0x0f;
9921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
10021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 0, 0x87, 0, 0x08) != 0x08) {
101c93396e13576928a073154b5715761ff8a998368Theodore Kilgore		PERR("Get_Camera_Mode failed");
10221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -EIO);
10321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	}
10421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
10521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	return gspca_dev->usb_buf[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
10621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
10721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
10821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic int stv0680_set_video_mode(struct gspca_dev *gspca_dev, u8 mode)
10921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
11021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	struct sd *sd = (struct sd *) gspca_dev;
11121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
11221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (sd->current_mode == mode)
11321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return 0;
11421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
11521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	memset(gspca_dev->usb_buf, 0, 8);
11621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	gspca_dev->usb_buf[0] = mode;
11721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
11821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 3, 0x07, 0x0100, 0x08) != 0x08) {
119c93396e13576928a073154b5715761ff8a998368Theodore Kilgore		PERR("Set_Camera_Mode failed");
12021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -EIO);
12121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	}
12221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
12321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* Verify we got what we've asked for */
12421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv0680_get_video_mode(gspca_dev) != mode) {
125c93396e13576928a073154b5715761ff8a998368Theodore Kilgore		PERR("Error setting camera video mode!");
12621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return -EIO;
12721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	}
12821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
12921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	sd->current_mode = mode;
13021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
13121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	return 0;
13221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
13321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
13421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede/* this function is called at probe time */
13521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic int sd_config(struct gspca_dev *gspca_dev,
13621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			const struct usb_device_id *id)
13721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
13821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	int ret;
13921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	struct sd *sd = (struct sd *) gspca_dev;
14021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	struct cam *cam = &gspca_dev->cam;
14121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
142f58c91ce82cbb55a48fbc1a0cb7c84c0d0a4e1bdJonathan McCrohan	/* Give the camera some time to settle, otherwise initialization will
143ab269d300ef9fe7e2f60613d0ac160e12b84658eHans de Goede	   fail on hotplug, and yes it really needs a full second. */
144ab269d300ef9fe7e2f60613d0ac160e12b84658eHans de Goede	msleep(1000);
145ab269d300ef9fe7e2f60613d0ac160e12b84658eHans de Goede
14621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* ping camera to be sure STV0680 is present */
14721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 0, 0x88, 0x5678, 0x02) != 0x02 ||
14821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	    gspca_dev->usb_buf[0] != 0x56 || gspca_dev->usb_buf[1] != 0x78) {
149c93396e13576928a073154b5715761ff8a998368Theodore Kilgore		PERR("STV(e): camera ping failed!!");
15021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -ENODEV);
15121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	}
15221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
15321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* get camera descriptor */
15421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x09) != 0x09)
15521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -ENODEV);
15621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
15721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0200, 0x22) != 0x22 ||
15821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	    gspca_dev->usb_buf[7] != 0xa0 || gspca_dev->usb_buf[8] != 0x23) {
159c93396e13576928a073154b5715761ff8a998368Theodore Kilgore		PERR("Could not get descriptor 0200.");
16021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -ENODEV);
16121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	}
16221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 0, 0x8a, 0, 0x02) != 0x02)
16321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -ENODEV);
16421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 0, 0x8b, 0, 0x24) != 0x24)
16521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -ENODEV);
16621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
16721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -ENODEV);
16821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
16921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (!(gspca_dev->usb_buf[7] & 0x09)) {
170c93396e13576928a073154b5715761ff8a998368Theodore Kilgore		PERR("Camera supports neither CIF nor QVGA mode");
17121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return -ENODEV;
17221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	}
17321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (gspca_dev->usb_buf[7] & 0x01)
17421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		PDEBUG(D_PROBE, "Camera supports CIF mode");
17521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (gspca_dev->usb_buf[7] & 0x02)
17621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		PDEBUG(D_PROBE, "Camera supports VGA mode");
177388a6d54168923d0243d4c752586e87231a75291Hans de Goede	if (gspca_dev->usb_buf[7] & 0x04)
178388a6d54168923d0243d4c752586e87231a75291Hans de Goede		PDEBUG(D_PROBE, "Camera supports QCIF mode");
17921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (gspca_dev->usb_buf[7] & 0x08)
18021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		PDEBUG(D_PROBE, "Camera supports QVGA mode");
18121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
18221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (gspca_dev->usb_buf[7] & 0x01)
18321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		sd->video_mode = 0x00; /* CIF */
18421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	else
18521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		sd->video_mode = 0x03; /* QVGA */
18621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
18721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* FW rev, ASIC rev, sensor ID  */
18821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	PDEBUG(D_PROBE, "Firmware rev is %i.%i",
18921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	       gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
19021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	PDEBUG(D_PROBE, "ASIC rev is %i.%i",
19121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	       gspca_dev->usb_buf[2], gspca_dev->usb_buf[3]);
19221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	PDEBUG(D_PROBE, "Sensor ID is %i",
19321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	       (gspca_dev->usb_buf[4]*16) + (gspca_dev->usb_buf[5]>>4));
19421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
19521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
19621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	ret = stv0680_get_video_mode(gspca_dev);
19721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (ret < 0)
19821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return ret;
19921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	sd->current_mode = sd->orig_mode = ret;
20021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
20121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
20221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (ret < 0)
20321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return ret;
20421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
20521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* Get mode details */
20621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 0, 0x8f, 0, 0x10) != 0x10)
20721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -EIO);
20821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
20921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	cam->bulk = 1;
21021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	cam->bulk_nurbs = 1; /* The cam cannot handle more */
21121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	cam->bulk_size = (gspca_dev->usb_buf[0] << 24) |
21221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			 (gspca_dev->usb_buf[1] << 16) |
21321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			 (gspca_dev->usb_buf[2] << 8) |
21421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			 (gspca_dev->usb_buf[3]);
21521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	sd->mode.width = (gspca_dev->usb_buf[4] << 8) |
21621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			 (gspca_dev->usb_buf[5]);  /* 322, 356, 644 */
21721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	sd->mode.height = (gspca_dev->usb_buf[6] << 8) |
21821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			  (gspca_dev->usb_buf[7]); /* 242, 292, 484 */
21921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	sd->mode.pixelformat = V4L2_PIX_FMT_STV0680;
22021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	sd->mode.field = V4L2_FIELD_NONE;
22121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	sd->mode.bytesperline = sd->mode.width;
22221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	sd->mode.sizeimage = cam->bulk_size;
22321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	sd->mode.colorspace = V4L2_COLORSPACE_SRGB;
22421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
22521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* origGain = gspca_dev->usb_buf[12]; */
22621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
22721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	cam->cam_mode = &sd->mode;
22821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	cam->nmodes = 1;
22921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
23021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
23121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	ret = stv0680_set_video_mode(gspca_dev, sd->orig_mode);
23221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (ret < 0)
23321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return ret;
23421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
23521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 2, 0x06, 0x0100, 0x12) != 0x12 ||
23621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	    gspca_dev->usb_buf[8] != 0x53 || gspca_dev->usb_buf[9] != 0x05) {
237133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches		pr_err("Could not get descriptor 0100\n");
23821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -EIO);
23921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	}
24021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
24121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	return 0;
24221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
24321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
24421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede/* this function is called at probe and resume time */
24521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic int sd_init(struct gspca_dev *gspca_dev)
24621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
24721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	return 0;
24821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
24921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
25021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede/* -- start the camera -- */
25121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic int sd_start(struct gspca_dev *gspca_dev)
25221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
25321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	int ret;
25421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	struct sd *sd = (struct sd *) gspca_dev;
25521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
25621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	ret = stv0680_set_video_mode(gspca_dev, sd->video_mode);
25721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (ret < 0)
25821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return ret;
25921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
26021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 0, 0x85, 0, 0x10) != 0x10)
26121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -EIO);
26221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
26321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* Start stream at:
26421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	   0x0000 = CIF (352x288)
26521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	   0x0100 = VGA (640x480)
26621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	   0x0300 = QVGA (320x240) */
26721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 1, 0x09, sd->video_mode << 8, 0x0) != 0x0)
26821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return stv0680_handle_error(gspca_dev, -EIO);
26921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
27021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	return 0;
27121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
27221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
27321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic void sd_stopN(struct gspca_dev *gspca_dev)
27421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
27521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* This is a high priority command; it stops all lower order cmds */
27621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (stv_sndctrl(gspca_dev, 1, 0x04, 0x0000, 0x0) != 0x0)
27721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		stv0680_handle_error(gspca_dev, -EIO);
27821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
27921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
28021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic void sd_stop0(struct gspca_dev *gspca_dev)
28121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
28221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	struct sd *sd = (struct sd *) gspca_dev;
28321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
28421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (!sd->gspca_dev.present)
28521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return;
28621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
28721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	stv0680_set_video_mode(gspca_dev, sd->orig_mode);
28821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
28921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
29021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic void sd_pkt_scan(struct gspca_dev *gspca_dev,
29176dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine			u8 *data,
29221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			int len)
29321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
29421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	struct sd *sd = (struct sd *) gspca_dev;
29521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
29621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* Every now and then the camera sends a 16 byte packet, no idea
29721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	   what it contains, but it is not image data, when this
29821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	   happens the frame received before this packet is corrupt,
29921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	   so discard it. */
30021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	if (len != sd->mode.sizeimage) {
30121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		gspca_dev->last_packet_type = DISCARD_PACKET;
30221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede		return;
30321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	}
30421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
30521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* Finish the previous frame, we do this upon reception of the next
30621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	   packet, even though it is already complete so that the strange 16
30721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	   byte packets send after a corrupt frame can discard it. */
30876dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine	gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
30921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
31021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	/* Store the just received frame */
31176dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine	gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
31221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
31321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
31421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede/* sub-driver description */
31521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic const struct sd_desc sd_desc = {
31621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.name = MODULE_NAME,
31721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.config = sd_config,
31821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.init = sd_init,
31921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.start = sd_start,
32021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.stopN = sd_stopN,
32121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.stop0 = sd_stop0,
32221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.pkt_scan = sd_pkt_scan,
32321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede};
32421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
32521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede/* -- module initialisation -- */
32695c967c167785eb991cf6b22fb854dd8d61d0ff8Jean-François Moinestatic const struct usb_device_id device_table[] = {
32721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	{USB_DEVICE(0x0553, 0x0202)},
32821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	{USB_DEVICE(0x041e, 0x4007)},
32921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	{}
33021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede};
33121f1b932dbcc5ed18444e6995aeb856e583804aeHans de GoedeMODULE_DEVICE_TABLE(usb, device_table);
33221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
33321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede/* -- device connect -- */
33421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic int sd_probe(struct usb_interface *intf,
33521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede			const struct usb_device_id *id)
33621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede{
33721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
33821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede				THIS_MODULE);
33921f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede}
34021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
34121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goedestatic struct usb_driver sd_driver = {
34221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.name = MODULE_NAME,
34321f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.id_table = device_table,
34421f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.probe = sd_probe,
34521f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.disconnect = gspca_disconnect,
34621f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede#ifdef CONFIG_PM
34721f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.suspend = gspca_suspend,
34821f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede	.resume = gspca_resume,
3498bb58964bc139d5ff5285f84aa302977d221754dHans de Goede	.reset_resume = gspca_resume,
35021f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede#endif
35121f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede};
35221f1b932dbcc5ed18444e6995aeb856e583804aeHans de Goede
353ecb3b2b35db49778b6d89e3ffd0c400776c20735Greg Kroah-Hartmanmodule_usb_driver(sd_driver);
354