14c98834addfee3fdd42c505c37569261bf669d94Erik Andren/*
24c98834addfee3fdd42c505c37569261bf669d94Erik Andren * Copyright (c) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher
34c98834addfee3fdd42c505c37569261bf669d94Erik Andren *		      Mark Cave-Ayland, Carlo E Prelz, Dick Streefland
44c98834addfee3fdd42c505c37569261bf669d94Erik Andren * Copyright (c) 2002, 2003 Tuukka Toivonen
54c98834addfee3fdd42c505c37569261bf669d94Erik Andren * Copyright (c) 2008 Erik Andrén
64c98834addfee3fdd42c505c37569261bf669d94Erik Andren *
74c98834addfee3fdd42c505c37569261bf669d94Erik Andren * This program is free software; you can redistribute it and/or modify
84c98834addfee3fdd42c505c37569261bf669d94Erik Andren * it under the terms of the GNU General Public License as published by
94c98834addfee3fdd42c505c37569261bf669d94Erik Andren * the Free Software Foundation; either version 2 of the License, or
104c98834addfee3fdd42c505c37569261bf669d94Erik Andren * (at your option) any later version.
114c98834addfee3fdd42c505c37569261bf669d94Erik Andren *
124c98834addfee3fdd42c505c37569261bf669d94Erik Andren * This program is distributed in the hope that it will be useful,
134c98834addfee3fdd42c505c37569261bf669d94Erik Andren * but WITHOUT ANY WARRANTY; without even the implied warranty of
144c98834addfee3fdd42c505c37569261bf669d94Erik Andren * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
154c98834addfee3fdd42c505c37569261bf669d94Erik Andren * GNU General Public License for more details.
164c98834addfee3fdd42c505c37569261bf669d94Erik Andren *
174c98834addfee3fdd42c505c37569261bf669d94Erik Andren * You should have received a copy of the GNU General Public License
184c98834addfee3fdd42c505c37569261bf669d94Erik Andren * along with this program; if not, write to the Free Software
194c98834addfee3fdd42c505c37569261bf669d94Erik Andren * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
204c98834addfee3fdd42c505c37569261bf669d94Erik Andren *
214c98834addfee3fdd42c505c37569261bf669d94Erik Andren * P/N 861037:      Sensor HDCS1000        ASIC STV0600
224c98834addfee3fdd42c505c37569261bf669d94Erik Andren * P/N 861050-0010: Sensor HDCS1000        ASIC STV0600
234c98834addfee3fdd42c505c37569261bf669d94Erik Andren * P/N 861050-0020: Sensor Photobit PB100  ASIC STV0600-1 - QuickCam Express
244c98834addfee3fdd42c505c37569261bf669d94Erik Andren * P/N 861055:      Sensor ST VV6410       ASIC STV0610   - LEGO cam
254c98834addfee3fdd42c505c37569261bf669d94Erik Andren * P/N 861075-0040: Sensor HDCS1000        ASIC
264c98834addfee3fdd42c505c37569261bf669d94Erik Andren * P/N 961179-0700: Sensor ST VV6410       ASIC STV0602   - Dexxa WebCam USB
274c98834addfee3fdd42c505c37569261bf669d94Erik Andren * P/N 861040-0000: Sensor ST VV6410       ASIC STV0610   - QuickCam Web
284c98834addfee3fdd42c505c37569261bf669d94Erik Andren */
294c98834addfee3fdd42c505c37569261bf669d94Erik Andren
30133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches
320158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede#include <linux/input.h>
334c98834addfee3fdd42c505c37569261bf669d94Erik Andren#include "stv06xx_sensor.h"
344c98834addfee3fdd42c505c37569261bf669d94Erik Andren
354c98834addfee3fdd42c505c37569261bf669d94Erik AndrenMODULE_AUTHOR("Erik Andrén");
364c98834addfee3fdd42c505c37569261bf669d94Erik AndrenMODULE_DESCRIPTION("STV06XX USB Camera Driver");
374c98834addfee3fdd42c505c37569261bf669d94Erik AndrenMODULE_LICENSE("GPL");
384c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3990ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool dump_bridge;
4090ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool dump_sensor;
414c98834addfee3fdd42c505c37569261bf669d94Erik Andren
424c98834addfee3fdd42c505c37569261bf669d94Erik Andrenint stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
434c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
444c98834addfee3fdd42c505c37569261bf669d94Erik Andren	int err;
45c93396e13576928a073154b5715761ff8a998368Theodore Kilgore	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
464c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct usb_device *udev = sd->gspca_dev.dev;
474c98834addfee3fdd42c505c37569261bf669d94Erik Andren	__u8 *buf = sd->gspca_dev.usb_buf;
48c93396e13576928a073154b5715761ff8a998368Theodore Kilgore
494c98834addfee3fdd42c505c37569261bf669d94Erik Andren	u8 len = (i2c_data > 0xff) ? 2 : 1;
504c98834addfee3fdd42c505c37569261bf669d94Erik Andren
514c98834addfee3fdd42c505c37569261bf669d94Erik Andren	buf[0] = i2c_data & 0xff;
524c98834addfee3fdd42c505c37569261bf669d94Erik Andren	buf[1] = (i2c_data >> 8) & 0xff;
534c98834addfee3fdd42c505c37569261bf669d94Erik Andren
544c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
554c98834addfee3fdd42c505c37569261bf669d94Erik Andren			      0x04, 0x40, address, 0, buf, len,
564c98834addfee3fdd42c505c37569261bf669d94Erik Andren			      STV06XX_URB_MSG_TIMEOUT);
574c98834addfee3fdd42c505c37569261bf669d94Erik Andren
584c98834addfee3fdd42c505c37569261bf669d94Erik Andren	PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d",
594c98834addfee3fdd42c505c37569261bf669d94Erik Andren	       i2c_data, address, err);
604c98834addfee3fdd42c505c37569261bf669d94Erik Andren
614c98834addfee3fdd42c505c37569261bf669d94Erik Andren	return (err < 0) ? err : 0;
624c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
634c98834addfee3fdd42c505c37569261bf669d94Erik Andren
644c98834addfee3fdd42c505c37569261bf669d94Erik Andrenint stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data)
654c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
664c98834addfee3fdd42c505c37569261bf669d94Erik Andren	int err;
67c93396e13576928a073154b5715761ff8a998368Theodore Kilgore	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
684c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct usb_device *udev = sd->gspca_dev.dev;
694c98834addfee3fdd42c505c37569261bf669d94Erik Andren	__u8 *buf = sd->gspca_dev.usb_buf;
704c98834addfee3fdd42c505c37569261bf669d94Erik Andren
714c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
724c98834addfee3fdd42c505c37569261bf669d94Erik Andren			      0x04, 0xc0, address, 0, buf, 1,
734c98834addfee3fdd42c505c37569261bf669d94Erik Andren			      STV06XX_URB_MSG_TIMEOUT);
744c98834addfee3fdd42c505c37569261bf669d94Erik Andren
754c98834addfee3fdd42c505c37569261bf669d94Erik Andren	*i2c_data = buf[0];
764c98834addfee3fdd42c505c37569261bf669d94Erik Andren
77be3bdfb6e01f3e72b814758606e89d4829e9e88fErik Andrén	PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d",
784c98834addfee3fdd42c505c37569261bf669d94Erik Andren	       *i2c_data, address, err);
794c98834addfee3fdd42c505c37569261bf669d94Erik Andren
804c98834addfee3fdd42c505c37569261bf669d94Erik Andren	return (err < 0) ? err : 0;
814c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
824c98834addfee3fdd42c505c37569261bf669d94Erik Andren
834c98834addfee3fdd42c505c37569261bf669d94Erik Andren/* Wraps the normal write sensor bytes / words functions for writing a
844c98834addfee3fdd42c505c37569261bf669d94Erik Andren   single value */
854c98834addfee3fdd42c505c37569261bf669d94Erik Andrenint stv06xx_write_sensor(struct sd *sd, u8 address, u16 value)
864c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
874c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (sd->sensor->i2c_len == 2) {
884c98834addfee3fdd42c505c37569261bf669d94Erik Andren		u16 data[2] = { address, value };
894c98834addfee3fdd42c505c37569261bf669d94Erik Andren		return stv06xx_write_sensor_words(sd, data, 1);
904c98834addfee3fdd42c505c37569261bf669d94Erik Andren	} else {
914c98834addfee3fdd42c505c37569261bf669d94Erik Andren		u8 data[2] = { address, value };
924c98834addfee3fdd42c505c37569261bf669d94Erik Andren		return stv06xx_write_sensor_bytes(sd, data, 1);
934c98834addfee3fdd42c505c37569261bf669d94Erik Andren	}
944c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
954c98834addfee3fdd42c505c37569261bf669d94Erik Andren
964c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic int stv06xx_write_sensor_finish(struct sd *sd)
974c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
984c98834addfee3fdd42c505c37569261bf669d94Erik Andren	int err = 0;
994c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1008668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	if (sd->bridge == BRIDGE_STV610) {
1014c98834addfee3fdd42c505c37569261bf669d94Erik Andren		struct usb_device *udev = sd->gspca_dev.dev;
1024c98834addfee3fdd42c505c37569261bf669d94Erik Andren		__u8 *buf = sd->gspca_dev.usb_buf;
1034c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1044c98834addfee3fdd42c505c37569261bf669d94Erik Andren		buf[0] = 0;
1054c98834addfee3fdd42c505c37569261bf669d94Erik Andren		err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
1064c98834addfee3fdd42c505c37569261bf669d94Erik Andren				      0x04, 0x40, 0x1704, 0, buf, 1,
1074c98834addfee3fdd42c505c37569261bf669d94Erik Andren				      STV06XX_URB_MSG_TIMEOUT);
1084c98834addfee3fdd42c505c37569261bf669d94Erik Andren	}
1094c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1104c98834addfee3fdd42c505c37569261bf669d94Erik Andren	return (err < 0) ? err : 0;
1114c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
1124c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1134c98834addfee3fdd42c505c37569261bf669d94Erik Andrenint stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
1144c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
1154c98834addfee3fdd42c505c37569261bf669d94Erik Andren	int err, i, j;
116c93396e13576928a073154b5715761ff8a998368Theodore Kilgore	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
1174c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct usb_device *udev = sd->gspca_dev.dev;
1184c98834addfee3fdd42c505c37569261bf669d94Erik Andren	__u8 *buf = sd->gspca_dev.usb_buf;
1194c98834addfee3fdd42c505c37569261bf669d94Erik Andren
120be3bdfb6e01f3e72b814758606e89d4829e9e88fErik Andrén	PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
1214c98834addfee3fdd42c505c37569261bf669d94Erik Andren	for (i = 0; i < len;) {
1224c98834addfee3fdd42c505c37569261bf669d94Erik Andren		/* Build the command buffer */
1234c98834addfee3fdd42c505c37569261bf669d94Erik Andren		memset(buf, 0, I2C_BUFFER_LENGTH);
1244c98834addfee3fdd42c505c37569261bf669d94Erik Andren		for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) {
1254c98834addfee3fdd42c505c37569261bf669d94Erik Andren			buf[j] = data[2*i];
1264c98834addfee3fdd42c505c37569261bf669d94Erik Andren			buf[0x10 + j] = data[2*i+1];
127be3bdfb6e01f3e72b814758606e89d4829e9e88fErik Andrén			PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x",
1284c98834addfee3fdd42c505c37569261bf669d94Erik Andren			data[2*i+1], data[2*i]);
1294c98834addfee3fdd42c505c37569261bf669d94Erik Andren		}
1304c98834addfee3fdd42c505c37569261bf669d94Erik Andren		buf[0x20] = sd->sensor->i2c_addr;
1314c98834addfee3fdd42c505c37569261bf669d94Erik Andren		buf[0x21] = j - 1; /* Number of commands to send - 1 */
1324c98834addfee3fdd42c505c37569261bf669d94Erik Andren		buf[0x22] = I2C_WRITE_CMD;
1334c98834addfee3fdd42c505c37569261bf669d94Erik Andren		err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
1344c98834addfee3fdd42c505c37569261bf669d94Erik Andren				      0x04, 0x40, 0x0400, 0, buf,
1354c98834addfee3fdd42c505c37569261bf669d94Erik Andren				      I2C_BUFFER_LENGTH,
1364c98834addfee3fdd42c505c37569261bf669d94Erik Andren				      STV06XX_URB_MSG_TIMEOUT);
137a8ca20b209addeae0d3017c2928048fc7f75ff70Erik Andrén		if (err < 0)
138a8ca20b209addeae0d3017c2928048fc7f75ff70Erik Andrén			return err;
139272ece5e798b7ff0d9bc083fe7df2e960e8d5db8Mauro Carvalho Chehab	}
140272ece5e798b7ff0d9bc083fe7df2e960e8d5db8Mauro Carvalho Chehab	return stv06xx_write_sensor_finish(sd);
1414c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
1424c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1434c98834addfee3fdd42c505c37569261bf669d94Erik Andrenint stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
1444c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
1454c98834addfee3fdd42c505c37569261bf669d94Erik Andren	int err, i, j;
146c93396e13576928a073154b5715761ff8a998368Theodore Kilgore	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
1474c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct usb_device *udev = sd->gspca_dev.dev;
1484c98834addfee3fdd42c505c37569261bf669d94Erik Andren	__u8 *buf = sd->gspca_dev.usb_buf;
1494c98834addfee3fdd42c505c37569261bf669d94Erik Andren
150be3bdfb6e01f3e72b814758606e89d4829e9e88fErik Andrén	PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
1514c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1524c98834addfee3fdd42c505c37569261bf669d94Erik Andren	for (i = 0; i < len;) {
1534c98834addfee3fdd42c505c37569261bf669d94Erik Andren		/* Build the command buffer */
1544c98834addfee3fdd42c505c37569261bf669d94Erik Andren		memset(buf, 0, I2C_BUFFER_LENGTH);
1554c98834addfee3fdd42c505c37569261bf669d94Erik Andren		for (j = 0; j < I2C_MAX_WORDS && i < len; j++, i++) {
1564c98834addfee3fdd42c505c37569261bf669d94Erik Andren			buf[j] = data[2*i];
1574c98834addfee3fdd42c505c37569261bf669d94Erik Andren			buf[0x10 + j * 2] = data[2*i+1];
1584c98834addfee3fdd42c505c37569261bf669d94Erik Andren			buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8;
159be3bdfb6e01f3e72b814758606e89d4829e9e88fErik Andrén			PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x",
1604c98834addfee3fdd42c505c37569261bf669d94Erik Andren				data[2*i+1], data[2*i]);
1614c98834addfee3fdd42c505c37569261bf669d94Erik Andren		}
1624c98834addfee3fdd42c505c37569261bf669d94Erik Andren		buf[0x20] = sd->sensor->i2c_addr;
1634c98834addfee3fdd42c505c37569261bf669d94Erik Andren		buf[0x21] = j - 1; /* Number of commands to send - 1 */
1644c98834addfee3fdd42c505c37569261bf669d94Erik Andren		buf[0x22] = I2C_WRITE_CMD;
1654c98834addfee3fdd42c505c37569261bf669d94Erik Andren		err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
1664c98834addfee3fdd42c505c37569261bf669d94Erik Andren				0x04, 0x40, 0x0400, 0, buf,
1674c98834addfee3fdd42c505c37569261bf669d94Erik Andren				I2C_BUFFER_LENGTH,
1684c98834addfee3fdd42c505c37569261bf669d94Erik Andren				STV06XX_URB_MSG_TIMEOUT);
1694c98834addfee3fdd42c505c37569261bf669d94Erik Andren		if (err < 0)
1704c98834addfee3fdd42c505c37569261bf669d94Erik Andren			return err;
1714c98834addfee3fdd42c505c37569261bf669d94Erik Andren	}
1724c98834addfee3fdd42c505c37569261bf669d94Erik Andren	return stv06xx_write_sensor_finish(sd);
1734c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
1744c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1754c98834addfee3fdd42c505c37569261bf669d94Erik Andrenint stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
1764c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
1774c98834addfee3fdd42c505c37569261bf669d94Erik Andren	int err;
178c93396e13576928a073154b5715761ff8a998368Theodore Kilgore	struct gspca_dev *gspca_dev = (struct gspca_dev *)sd;
1794c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct usb_device *udev = sd->gspca_dev.dev;
1804c98834addfee3fdd42c505c37569261bf669d94Erik Andren	__u8 *buf = sd->gspca_dev.usb_buf;
1814c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1824c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = stv06xx_write_bridge(sd, STV_I2C_FLUSH, sd->sensor->i2c_flush);
1834c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (err < 0)
1844c98834addfee3fdd42c505c37569261bf669d94Erik Andren		return err;
1854c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1864c98834addfee3fdd42c505c37569261bf669d94Erik Andren	/* Clear mem */
1874c98834addfee3fdd42c505c37569261bf669d94Erik Andren	memset(buf, 0, I2C_BUFFER_LENGTH);
1884c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1894c98834addfee3fdd42c505c37569261bf669d94Erik Andren	buf[0] = address;
1904c98834addfee3fdd42c505c37569261bf669d94Erik Andren	buf[0x20] = sd->sensor->i2c_addr;
1914c98834addfee3fdd42c505c37569261bf669d94Erik Andren	buf[0x21] = 0;
1924c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1934c98834addfee3fdd42c505c37569261bf669d94Erik Andren	/* Read I2C register */
1944c98834addfee3fdd42c505c37569261bf669d94Erik Andren	buf[0x22] = I2C_READ_CMD;
1954c98834addfee3fdd42c505c37569261bf669d94Erik Andren
1964c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
1974c98834addfee3fdd42c505c37569261bf669d94Erik Andren			      0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH,
1984c98834addfee3fdd42c505c37569261bf669d94Erik Andren			      STV06XX_URB_MSG_TIMEOUT);
1994c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (err < 0) {
200133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches		pr_err("I2C: Read error writing address: %d\n", err);
2014c98834addfee3fdd42c505c37569261bf669d94Erik Andren		return err;
2024c98834addfee3fdd42c505c37569261bf669d94Erik Andren	}
2034c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2044c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
2054c98834addfee3fdd42c505c37569261bf669d94Erik Andren			      0x04, 0xc0, 0x1410, 0, buf, sd->sensor->i2c_len,
2064c98834addfee3fdd42c505c37569261bf669d94Erik Andren			      STV06XX_URB_MSG_TIMEOUT);
2074c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (sd->sensor->i2c_len == 2)
2084c98834addfee3fdd42c505c37569261bf669d94Erik Andren		*value = buf[0] | (buf[1] << 8);
2094c98834addfee3fdd42c505c37569261bf669d94Erik Andren	else
2104c98834addfee3fdd42c505c37569261bf669d94Erik Andren		*value = buf[0];
2114c98834addfee3fdd42c505c37569261bf669d94Erik Andren
212be3bdfb6e01f3e72b814758606e89d4829e9e88fErik Andrén	PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d",
2134c98834addfee3fdd42c505c37569261bf669d94Erik Andren	       *value, address, err);
2144c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2154c98834addfee3fdd42c505c37569261bf669d94Erik Andren	return (err < 0) ? err : 0;
2164c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
2174c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2184c98834addfee3fdd42c505c37569261bf669d94Erik Andren/* Dumps all bridge registers */
2194c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic void stv06xx_dump_bridge(struct sd *sd)
2204c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
2214c98834addfee3fdd42c505c37569261bf669d94Erik Andren	int i;
2224c98834addfee3fdd42c505c37569261bf669d94Erik Andren	u8 data, buf;
2234c98834addfee3fdd42c505c37569261bf669d94Erik Andren
224133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches	pr_info("Dumping all stv06xx bridge registers\n");
2254c98834addfee3fdd42c505c37569261bf669d94Erik Andren	for (i = 0x1400; i < 0x160f; i++) {
2264c98834addfee3fdd42c505c37569261bf669d94Erik Andren		stv06xx_read_bridge(sd, i, &data);
2274c98834addfee3fdd42c505c37569261bf669d94Erik Andren
228133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches		pr_info("Read 0x%x from address 0x%x\n", data, i);
2294c98834addfee3fdd42c505c37569261bf669d94Erik Andren	}
2304c98834addfee3fdd42c505c37569261bf669d94Erik Andren
231133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches	pr_info("Testing stv06xx bridge registers for writability\n");
2324c98834addfee3fdd42c505c37569261bf669d94Erik Andren	for (i = 0x1400; i < 0x160f; i++) {
2334c98834addfee3fdd42c505c37569261bf669d94Erik Andren		stv06xx_read_bridge(sd, i, &data);
2344c98834addfee3fdd42c505c37569261bf669d94Erik Andren		buf = data;
2354c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2364c98834addfee3fdd42c505c37569261bf669d94Erik Andren		stv06xx_write_bridge(sd, i, 0xff);
2374c98834addfee3fdd42c505c37569261bf669d94Erik Andren		stv06xx_read_bridge(sd, i, &data);
2384c98834addfee3fdd42c505c37569261bf669d94Erik Andren		if (data == 0xff)
239133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches			pr_info("Register 0x%x is read/write\n", i);
2404c98834addfee3fdd42c505c37569261bf669d94Erik Andren		else if (data != buf)
241133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches			pr_info("Register 0x%x is read/write, but only partially\n",
242133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches				i);
2434c98834addfee3fdd42c505c37569261bf669d94Erik Andren		else
244133a9fe949862d9ed8411fb423739f4cee08232dJoe Perches			pr_info("Register 0x%x is read-only\n", i);
2454c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2464c98834addfee3fdd42c505c37569261bf669d94Erik Andren		stv06xx_write_bridge(sd, i, buf);
2474c98834addfee3fdd42c505c37569261bf669d94Erik Andren	}
2484c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
2494c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2504c98834addfee3fdd42c505c37569261bf669d94Erik Andren/* this function is called at probe and resume time */
2514c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic int stv06xx_init(struct gspca_dev *gspca_dev)
2524c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
2534c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct sd *sd = (struct sd *) gspca_dev;
2544c98834addfee3fdd42c505c37569261bf669d94Erik Andren	int err;
2554c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2564c98834addfee3fdd42c505c37569261bf669d94Erik Andren	PDEBUG(D_PROBE, "Initializing camera");
2574c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2584c98834addfee3fdd42c505c37569261bf669d94Erik Andren	/* Let the usb init settle for a bit
2594c98834addfee3fdd42c505c37569261bf669d94Erik Andren	   before performing the initialization */
2604c98834addfee3fdd42c505c37569261bf669d94Erik Andren	msleep(250);
2614c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2624c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = sd->sensor->init(sd);
2634c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2648668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	if (dump_sensor && sd->sensor->dump)
2654c98834addfee3fdd42c505c37569261bf669d94Erik Andren		sd->sensor->dump(sd);
2664c98834addfee3fdd42c505c37569261bf669d94Erik Andren
2674c98834addfee3fdd42c505c37569261bf669d94Erik Andren	return (err < 0) ? err : 0;
2684c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
2694c98834addfee3fdd42c505c37569261bf669d94Erik Andren
270dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil/* this function is called at probe time */
271dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuilstatic int stv06xx_init_controls(struct gspca_dev *gspca_dev)
272dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil{
273dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil	struct sd *sd = (struct sd *) gspca_dev;
274dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil
275dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil	PDEBUG(D_PROBE, "Initializing controls");
276dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil
277a8a478601ac1d8877e23cb832fe4b44042ce6f20Hans de Goede	gspca_dev->vdev.ctrl_handler = &gspca_dev->ctrl_handler;
278dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil	return sd->sensor->init_controls(sd);
279dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil}
280dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil
2814c98834addfee3fdd42c505c37569261bf669d94Erik Andren/* Start the camera */
2824c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic int stv06xx_start(struct gspca_dev *gspca_dev)
2834c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
2844c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct sd *sd = (struct sd *) gspca_dev;
285c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	struct usb_host_interface *alt;
286c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	struct usb_interface *intf;
287c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	int err, packet_size;
288c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
289c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
290c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
291c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	if (!alt) {
292c93396e13576928a073154b5715761ff8a998368Theodore Kilgore		PERR("Couldn't get altsetting");
293c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede		return -EIO;
294c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	}
295c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
296c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
297c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	err = stv06xx_write_bridge(sd, STV_ISO_SIZE_L, packet_size);
298c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	if (err < 0)
299c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede		return err;
3004c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3014c98834addfee3fdd42c505c37569261bf669d94Erik Andren	/* Prepare the sensor for start */
3024c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = sd->sensor->start(sd);
3034c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (err < 0)
3044c98834addfee3fdd42c505c37569261bf669d94Erik Andren		goto out;
3054c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3064c98834addfee3fdd42c505c37569261bf669d94Erik Andren	/* Start isochronous streaming */
3074c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 1);
3084c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3094c98834addfee3fdd42c505c37569261bf669d94Erik Andrenout:
3104c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (err < 0)
3114c98834addfee3fdd42c505c37569261bf669d94Erik Andren		PDEBUG(D_STREAM, "Starting stream failed");
3124c98834addfee3fdd42c505c37569261bf669d94Erik Andren	else
3134c98834addfee3fdd42c505c37569261bf669d94Erik Andren		PDEBUG(D_STREAM, "Started streaming");
3144c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3154c98834addfee3fdd42c505c37569261bf669d94Erik Andren	return (err < 0) ? err : 0;
3164c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
3174c98834addfee3fdd42c505c37569261bf669d94Erik Andren
318c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goedestatic int stv06xx_isoc_init(struct gspca_dev *gspca_dev)
319c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede{
320c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	struct usb_host_interface *alt;
321c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	struct sd *sd = (struct sd *) gspca_dev;
322c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
323c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	/* Start isoc bandwidth "negotiation" at max isoc bandwidth */
3245dae603d84ff5b6b24186b521f4353b3860b11e2Hans de Goede	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
325c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	alt->endpoint[0].desc.wMaxPacketSize =
326c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede		cpu_to_le16(sd->sensor->max_packet_size[gspca_dev->curr_mode]);
327c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
328c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	return 0;
329c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede}
330c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
331c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goedestatic int stv06xx_isoc_nego(struct gspca_dev *gspca_dev)
332c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede{
333c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	int ret, packet_size, min_packet_size;
334c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	struct usb_host_interface *alt;
335c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	struct sd *sd = (struct sd *) gspca_dev;
336c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
3375dae603d84ff5b6b24186b521f4353b3860b11e2Hans de Goede	alt = &gspca_dev->dev->actconfig->intf_cache[0]->altsetting[1];
338c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
339c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	min_packet_size = sd->sensor->min_packet_size[gspca_dev->curr_mode];
340c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	if (packet_size <= min_packet_size)
341c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede		return -EIO;
342c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
343c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	packet_size -= 100;
344c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	if (packet_size < min_packet_size)
345c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede		packet_size = min_packet_size;
346c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	alt->endpoint[0].desc.wMaxPacketSize = cpu_to_le16(packet_size);
347c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
348c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
349c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	if (ret < 0)
350c93396e13576928a073154b5715761ff8a998368Theodore Kilgore		PERR("set alt 1 err %d", ret);
351c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
352c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	return ret;
353c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede}
354c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede
3554c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic void stv06xx_stopN(struct gspca_dev *gspca_dev)
3564c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
3574c98834addfee3fdd42c505c37569261bf669d94Erik Andren	int err;
3584c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct sd *sd = (struct sd *) gspca_dev;
3594c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3604c98834addfee3fdd42c505c37569261bf669d94Erik Andren	/* stop ISO-streaming */
3614c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = stv06xx_write_bridge(sd, STV_ISO_ENABLE, 0);
3624c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (err < 0)
3634c98834addfee3fdd42c505c37569261bf669d94Erik Andren		goto out;
3644c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3654c98834addfee3fdd42c505c37569261bf669d94Erik Andren	err = sd->sensor->stop(sd);
3664c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3674c98834addfee3fdd42c505c37569261bf669d94Erik Andrenout:
3684c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (err < 0)
3694c98834addfee3fdd42c505c37569261bf669d94Erik Andren		PDEBUG(D_STREAM, "Failed to stop stream");
3704c98834addfee3fdd42c505c37569261bf669d94Erik Andren	else
3714c98834addfee3fdd42c505c37569261bf669d94Erik Andren		PDEBUG(D_STREAM, "Stopped streaming");
3724c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
3734c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3744c98834addfee3fdd42c505c37569261bf669d94Erik Andren/*
3754c98834addfee3fdd42c505c37569261bf669d94Erik Andren * Analyse an USB packet of the data stream and store it appropriately.
3764c98834addfee3fdd42c505c37569261bf669d94Erik Andren * Each packet contains an integral number of chunks. Each chunk has
3774c98834addfee3fdd42c505c37569261bf669d94Erik Andren * 2-bytes identification, followed by 2-bytes that describe the chunk
3784c98834addfee3fdd42c505c37569261bf669d94Erik Andren * length. Known/guessed chunk identifications are:
3794c98834addfee3fdd42c505c37569261bf669d94Erik Andren * 8001/8005/C001/C005 - Begin new frame
3804c98834addfee3fdd42c505c37569261bf669d94Erik Andren * 8002/8006/C002/C006 - End frame
3814c98834addfee3fdd42c505c37569261bf669d94Erik Andren * 0200/4200           - Contains actual image data, bayer or compressed
3824c98834addfee3fdd42c505c37569261bf669d94Erik Andren * 0005                - 11 bytes of unknown data
3834c98834addfee3fdd42c505c37569261bf669d94Erik Andren * 0100                - 2 bytes of unknown data
3844c98834addfee3fdd42c505c37569261bf669d94Erik Andren * The 0005 and 0100 chunks seem to appear only in compressed stream.
3854c98834addfee3fdd42c505c37569261bf669d94Erik Andren */
3864c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic void stv06xx_pkt_scan(struct gspca_dev *gspca_dev,
38776dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine			u8 *data,			/* isoc packet */
3884c98834addfee3fdd42c505c37569261bf669d94Erik Andren			int len)			/* iso packet length */
3894c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
3908668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	struct sd *sd = (struct sd *) gspca_dev;
3918668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede
3924c98834addfee3fdd42c505c37569261bf669d94Erik Andren	PDEBUG(D_PACK, "Packet of length %d arrived", len);
3934c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3944c98834addfee3fdd42c505c37569261bf669d94Erik Andren	/* A packet may contain several frames
3954c98834addfee3fdd42c505c37569261bf669d94Erik Andren	   loop until the whole packet is reached */
3964c98834addfee3fdd42c505c37569261bf669d94Erik Andren	while (len) {
3974c98834addfee3fdd42c505c37569261bf669d94Erik Andren		int id, chunk_len;
3984c98834addfee3fdd42c505c37569261bf669d94Erik Andren
3994c98834addfee3fdd42c505c37569261bf669d94Erik Andren		if (len < 4) {
4004c98834addfee3fdd42c505c37569261bf669d94Erik Andren			PDEBUG(D_PACK, "Packet is smaller than 4 bytes");
4014c98834addfee3fdd42c505c37569261bf669d94Erik Andren			return;
4024c98834addfee3fdd42c505c37569261bf669d94Erik Andren		}
4034c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4044c98834addfee3fdd42c505c37569261bf669d94Erik Andren		/* Capture the id */
4054c98834addfee3fdd42c505c37569261bf669d94Erik Andren		id = (data[0] << 8) | data[1];
4064c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4074c98834addfee3fdd42c505c37569261bf669d94Erik Andren		/* Capture the chunk length */
4084c98834addfee3fdd42c505c37569261bf669d94Erik Andren		chunk_len = (data[2] << 8) | data[3];
4094c98834addfee3fdd42c505c37569261bf669d94Erik Andren		PDEBUG(D_PACK, "Chunk id: %x, length: %d", id, chunk_len);
4104c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4114c98834addfee3fdd42c505c37569261bf669d94Erik Andren		data += 4;
4124c98834addfee3fdd42c505c37569261bf669d94Erik Andren		len -= 4;
4134c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4144c98834addfee3fdd42c505c37569261bf669d94Erik Andren		if (len < chunk_len) {
415c93396e13576928a073154b5715761ff8a998368Theodore Kilgore			PERR("URB packet length is smaller"
4164c98834addfee3fdd42c505c37569261bf669d94Erik Andren				" than the specified chunk length");
4178668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede			gspca_dev->last_packet_type = DISCARD_PACKET;
4184c98834addfee3fdd42c505c37569261bf669d94Erik Andren			return;
4194c98834addfee3fdd42c505c37569261bf669d94Erik Andren		}
4204c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4218668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede		/* First byte seem to be 02=data 2nd byte is unknown??? */
4221d00d6c1ff13607974fcd9469aa9466fcd253c3aJean-François Moine		if (sd->bridge == BRIDGE_ST6422 && (id & 0xff00) == 0x0200)
4238668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede			goto frame_data;
4248668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede
4254c98834addfee3fdd42c505c37569261bf669d94Erik Andren		switch (id) {
4264c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0x0200:
4274c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0x4200:
4288668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goedeframe_data:
4294c98834addfee3fdd42c505c37569261bf669d94Erik Andren			PDEBUG(D_PACK, "Frame data packet detected");
4304c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4318668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede			if (sd->to_skip) {
4328668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede				int skip = (sd->to_skip < chunk_len) ?
4338668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede					    sd->to_skip : chunk_len;
4348668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede				data += skip;
4358668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede				len -= skip;
4368668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede				chunk_len -= skip;
4378668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede				sd->to_skip -= skip;
4388668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede			}
4398668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede
44076dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine			gspca_frame_add(gspca_dev, INTER_PACKET,
4414c98834addfee3fdd42c505c37569261bf669d94Erik Andren					data, chunk_len);
4424c98834addfee3fdd42c505c37569261bf669d94Erik Andren			break;
4434c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4444c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0x8001:
4454c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0x8005:
4464c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0xc001:
4474c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0xc005:
4484c98834addfee3fdd42c505c37569261bf669d94Erik Andren			PDEBUG(D_PACK, "Starting new frame");
4494c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4504c98834addfee3fdd42c505c37569261bf669d94Erik Andren			/* Create a new frame, chunk length should be zero */
4514c98834addfee3fdd42c505c37569261bf669d94Erik Andren			gspca_frame_add(gspca_dev, FIRST_PACKET,
45276dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine					NULL, 0);
4534c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4548668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede			if (sd->bridge == BRIDGE_ST6422)
4551966bc2a48f12d5d11c4fbe0880955cc4bfda0f9Ondrej Zary				sd->to_skip = gspca_dev->pixfmt.width * 4;
4568668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede
4574c98834addfee3fdd42c505c37569261bf669d94Erik Andren			if (chunk_len)
458c93396e13576928a073154b5715761ff8a998368Theodore Kilgore				PERR("Chunk length is "
4594c98834addfee3fdd42c505c37569261bf669d94Erik Andren					      "non-zero on a SOF");
4604c98834addfee3fdd42c505c37569261bf669d94Erik Andren			break;
4614c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4624c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0x8002:
4634c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0x8006:
4644c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0xc002:
4654c98834addfee3fdd42c505c37569261bf669d94Erik Andren			PDEBUG(D_PACK, "End of frame detected");
4664c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4674c98834addfee3fdd42c505c37569261bf669d94Erik Andren			/* Complete the last frame (if any) */
46876dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine			gspca_frame_add(gspca_dev, LAST_PACKET,
46976dd272b56cd1c7fa013ef5d7eb28c4d319e322bJean-Francois Moine					NULL, 0);
4704c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4714c98834addfee3fdd42c505c37569261bf669d94Erik Andren			if (chunk_len)
472c93396e13576928a073154b5715761ff8a998368Theodore Kilgore				PERR("Chunk length is "
4734c98834addfee3fdd42c505c37569261bf669d94Erik Andren					      "non-zero on a EOF");
4744c98834addfee3fdd42c505c37569261bf669d94Erik Andren			break;
4754c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4764c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0x0005:
4774c98834addfee3fdd42c505c37569261bf669d94Erik Andren			PDEBUG(D_PACK, "Chunk 0x005 detected");
4784c98834addfee3fdd42c505c37569261bf669d94Erik Andren			/* Unknown chunk with 11 bytes of data,
4794c98834addfee3fdd42c505c37569261bf669d94Erik Andren			   occurs just before end of each frame
4804c98834addfee3fdd42c505c37569261bf669d94Erik Andren			   in compressed mode */
4814c98834addfee3fdd42c505c37569261bf669d94Erik Andren			break;
4824c98834addfee3fdd42c505c37569261bf669d94Erik Andren
4834c98834addfee3fdd42c505c37569261bf669d94Erik Andren		case 0x0100:
4844c98834addfee3fdd42c505c37569261bf669d94Erik Andren			PDEBUG(D_PACK, "Chunk 0x0100 detected");
4854c98834addfee3fdd42c505c37569261bf669d94Erik Andren			/* Unknown chunk with 2 bytes of data,
4864c98834addfee3fdd42c505c37569261bf669d94Erik Andren			   occurs 2-3 times per USB interrupt */
4874c98834addfee3fdd42c505c37569261bf669d94Erik Andren			break;
4888668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede		case 0x42ff:
4898668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede			PDEBUG(D_PACK, "Chunk 0x42ff detected");
4908668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede			/* Special chunk seen sometimes on the ST6422 */
4918668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede			break;
4924c98834addfee3fdd42c505c37569261bf669d94Erik Andren		default:
4938668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede			PDEBUG(D_PACK, "Unknown chunk 0x%04x detected", id);
4944c98834addfee3fdd42c505c37569261bf669d94Erik Andren			/* Unknown chunk */
4954c98834addfee3fdd42c505c37569261bf669d94Erik Andren		}
4964c98834addfee3fdd42c505c37569261bf669d94Erik Andren		data    += chunk_len;
4974c98834addfee3fdd42c505c37569261bf669d94Erik Andren		len     -= chunk_len;
4984c98834addfee3fdd42c505c37569261bf669d94Erik Andren	}
4994c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
5004c98834addfee3fdd42c505c37569261bf669d94Erik Andren
50100ddb70702275aabcc7f9f999adaf8bc81756b54Peter Senna Tschudin#if IS_ENABLED(CONFIG_INPUT)
5020158e98fa15f6980568d7c3f67f035d3783319cdHans de Goedestatic int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
5030158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede			u8 *data,		/* interrupt packet data */
5040158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede			int len)		/* interrupt packet length */
5050158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede{
5060158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede	int ret = -EINVAL;
5070158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede
5080158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede	if (len == 1 && data[0] == 0x80) {
5090158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
5100158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede		input_sync(gspca_dev->input_dev);
5110158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede		ret = 0;
5120158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede	}
5130158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede
5140158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede	if (len == 1 && data[0] == 0x88) {
5150158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede		input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
5160158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede		input_sync(gspca_dev->input_dev);
5170158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede		ret = 0;
5180158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede	}
5190158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede
5200158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede	return ret;
5210158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede}
5220158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede#endif
5230158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede
5244c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic int stv06xx_config(struct gspca_dev *gspca_dev,
5254c98834addfee3fdd42c505c37569261bf669d94Erik Andren			  const struct usb_device_id *id);
5264c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5274c98834addfee3fdd42c505c37569261bf669d94Erik Andren/* sub-driver description */
5284c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic const struct sd_desc sd_desc = {
5294c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.name = MODULE_NAME,
5304c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.config = stv06xx_config,
5314c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.init = stv06xx_init,
532dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil	.init_controls = stv06xx_init_controls,
5334c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.start = stv06xx_start,
5344c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.stopN = stv06xx_stopN,
5350158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede	.pkt_scan = stv06xx_pkt_scan,
536c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	.isoc_init = stv06xx_isoc_init,
537c0b33bdc5b8d9c1120dece660480d4dd86b817eeHans de Goede	.isoc_nego = stv06xx_isoc_nego,
53800ddb70702275aabcc7f9f999adaf8bc81756b54Peter Senna Tschudin#if IS_ENABLED(CONFIG_INPUT)
5390158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede	.int_pkt_scan = sd_int_pkt_scan,
5400158e98fa15f6980568d7c3f67f035d3783319cdHans de Goede#endif
5414c98834addfee3fdd42c505c37569261bf669d94Erik Andren};
5424c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5434c98834addfee3fdd42c505c37569261bf669d94Erik Andren/* This function is called at probe time */
5444c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic int stv06xx_config(struct gspca_dev *gspca_dev,
5454c98834addfee3fdd42c505c37569261bf669d94Erik Andren			  const struct usb_device_id *id)
5464c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
5474c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct sd *sd = (struct sd *) gspca_dev;
5484c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5494c98834addfee3fdd42c505c37569261bf669d94Erik Andren	PDEBUG(D_PROBE, "Configuring camera");
5504c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5518668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	sd->bridge = id->driver_info;
552d67a1adaea29da942291145fa3964a453e017274Hans de Goede	gspca_dev->sd_desc = &sd_desc;
5534c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5544c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (dump_bridge)
5554c98834addfee3fdd42c505c37569261bf669d94Erik Andren		stv06xx_dump_bridge(sd);
5564c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5578668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	sd->sensor = &stv06xx_sensor_st6422;
5588668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	if (!sd->sensor->probe(sd))
5598668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede		return 0;
5608668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede
5614c98834addfee3fdd42c505c37569261bf669d94Erik Andren	sd->sensor = &stv06xx_sensor_vv6410;
5624c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (!sd->sensor->probe(sd))
5634c98834addfee3fdd42c505c37569261bf669d94Erik Andren		return 0;
5644c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5654c98834addfee3fdd42c505c37569261bf669d94Erik Andren	sd->sensor = &stv06xx_sensor_hdcs1x00;
5664c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (!sd->sensor->probe(sd))
5674c98834addfee3fdd42c505c37569261bf669d94Erik Andren		return 0;
5684c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5694c98834addfee3fdd42c505c37569261bf669d94Erik Andren	sd->sensor = &stv06xx_sensor_hdcs1020;
5704c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (!sd->sensor->probe(sd))
5714c98834addfee3fdd42c505c37569261bf669d94Erik Andren		return 0;
5724c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5734c98834addfee3fdd42c505c37569261bf669d94Erik Andren	sd->sensor = &stv06xx_sensor_pb0100;
5744c98834addfee3fdd42c505c37569261bf669d94Erik Andren	if (!sd->sensor->probe(sd))
5754c98834addfee3fdd42c505c37569261bf669d94Erik Andren		return 0;
5764c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5774c98834addfee3fdd42c505c37569261bf669d94Erik Andren	sd->sensor = NULL;
5784c98834addfee3fdd42c505c37569261bf669d94Erik Andren	return -ENODEV;
5794c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
5804c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5814c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5824c98834addfee3fdd42c505c37569261bf669d94Erik Andren
5834c98834addfee3fdd42c505c37569261bf669d94Erik Andren/* -- module initialisation -- */
58495c967c167785eb991cf6b22fb854dd8d61d0ff8Jean-François Moinestatic const struct usb_device_id device_table[] = {
5858668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	/* QuickCam Express */
5868668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	{USB_DEVICE(0x046d, 0x0840), .driver_info = BRIDGE_STV600 },
5878668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	/* LEGO cam / QuickCam Web */
5888668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	{USB_DEVICE(0x046d, 0x0850), .driver_info = BRIDGE_STV610 },
5898668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	/* Dexxa WebCam USB */
5908668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	{USB_DEVICE(0x046d, 0x0870), .driver_info = BRIDGE_STV602 },
5918668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	/* QuickCam Messenger */
5928668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	{USB_DEVICE(0x046D, 0x08F0), .driver_info = BRIDGE_ST6422 },
5938668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	/* QuickCam Communicate */
5948668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	{USB_DEVICE(0x046D, 0x08F5), .driver_info = BRIDGE_ST6422 },
5958668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	/* QuickCam Messenger (new) */
5968668d504d72c384fbfb6ab6f5d02a9fe4d813554Hans de Goede	{USB_DEVICE(0x046D, 0x08F6), .driver_info = BRIDGE_ST6422 },
5974c98834addfee3fdd42c505c37569261bf669d94Erik Andren	{}
5984c98834addfee3fdd42c505c37569261bf669d94Erik Andren};
5994c98834addfee3fdd42c505c37569261bf669d94Erik AndrenMODULE_DEVICE_TABLE(usb, device_table);
6004c98834addfee3fdd42c505c37569261bf669d94Erik Andren
6014c98834addfee3fdd42c505c37569261bf669d94Erik Andren/* -- device connect -- */
6024c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic int sd_probe(struct usb_interface *intf,
6034c98834addfee3fdd42c505c37569261bf669d94Erik Andren			const struct usb_device_id *id)
6044c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
6054c98834addfee3fdd42c505c37569261bf669d94Erik Andren	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
6064c98834addfee3fdd42c505c37569261bf669d94Erik Andren			       THIS_MODULE);
6074c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
6084c98834addfee3fdd42c505c37569261bf669d94Erik Andren
6098a787b40ecf29e5d8cc95bf9f12986862d230d8eMauro Carvalho Chehabstatic void sd_disconnect(struct usb_interface *intf)
6104c98834addfee3fdd42c505c37569261bf669d94Erik Andren{
6114c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct gspca_dev *gspca_dev = usb_get_intfdata(intf);
6124c98834addfee3fdd42c505c37569261bf669d94Erik Andren	struct sd *sd = (struct sd *) gspca_dev;
613dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil	void *priv = sd->sensor_priv;
6144c98834addfee3fdd42c505c37569261bf669d94Erik Andren	PDEBUG(D_PROBE, "Disconnecting the stv06xx device");
6154c98834addfee3fdd42c505c37569261bf669d94Erik Andren
616dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil	sd->sensor = NULL;
6174c98834addfee3fdd42c505c37569261bf669d94Erik Andren	gspca_disconnect(intf);
618dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil	kfree(priv);
6194c98834addfee3fdd42c505c37569261bf669d94Erik Andren}
6204c98834addfee3fdd42c505c37569261bf669d94Erik Andren
6214c98834addfee3fdd42c505c37569261bf669d94Erik Andrenstatic struct usb_driver sd_driver = {
6224c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.name = MODULE_NAME,
6234c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.id_table = device_table,
6244c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.probe = sd_probe,
6254c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.disconnect = sd_disconnect,
6264c98834addfee3fdd42c505c37569261bf669d94Erik Andren#ifdef CONFIG_PM
6274c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.suspend = gspca_suspend,
6284c98834addfee3fdd42c505c37569261bf669d94Erik Andren	.resume = gspca_resume,
629dec9c51442b5a524c137b6f4a54ec109a197a65aHans Verkuil	.reset_resume = gspca_resume,
6304c98834addfee3fdd42c505c37569261bf669d94Erik Andren#endif
6314c98834addfee3fdd42c505c37569261bf669d94Erik Andren};
6324c98834addfee3fdd42c505c37569261bf669d94Erik Andren
633ecb3b2b35db49778b6d89e3ffd0c400776c20735Greg Kroah-Hartmanmodule_usb_driver(sd_driver);
6344c98834addfee3fdd42c505c37569261bf669d94Erik Andren
6354c98834addfee3fdd42c505c37569261bf669d94Erik Andrenmodule_param(dump_bridge, bool, S_IRUGO | S_IWUSR);
6364c98834addfee3fdd42c505c37569261bf669d94Erik AndrenMODULE_PARM_DESC(dump_bridge, "Dumps all usb bridge registers at startup");
6374c98834addfee3fdd42c505c37569261bf669d94Erik Andren
6384c98834addfee3fdd42c505c37569261bf669d94Erik Andrenmodule_param(dump_sensor, bool, S_IRUGO | S_IWUSR);
6394c98834addfee3fdd42c505c37569261bf669d94Erik AndrenMODULE_PARM_DESC(dump_sensor, "Dumps all sensor registers at startup");
640