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