ov534.c revision c06eb61941459b1981817fb675d0104ac0cd6df8
1fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* 2fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * ov534/ov772x gspca driver 3fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 40f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * 6fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * Based on a prototype written by Mark Ferrell <majortrips@gmail.com> 7fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * USB protocol reverse engineered by Jim Paris <jim@jtan.com> 8fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ 9fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * 10fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * This program is free software; you can redistribute it and/or modify 11fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * it under the terms of the GNU General Public License as published by 12fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * the Free Software Foundation; either version 2 of the License, or 13fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * any later version. 14fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * 15fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * This program is distributed in the hope that it will be useful, 16fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * but WITHOUT ANY WARRANTY; without even the implied warranty of 17fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * GNU General Public License for more details. 19fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * 20fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * You should have received a copy of the GNU General Public License 21fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * along with this program; if not, write to the Free Software 22fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 23fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite */ 24fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 25fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define MODULE_NAME "ov534" 26fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 27fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#include "gspca.h" 28fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 29fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define OV534_REG_ADDRESS 0xf1 /* ? */ 30fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define OV534_REG_SUBADDR 0xf2 31fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define OV534_REG_WRITE 0xf3 32fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define OV534_REG_READ 0xf4 33fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define OV534_REG_OPERATION 0xf5 34fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define OV534_REG_STATUS 0xf6 35fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 36fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define OV534_OP_WRITE_3 0x37 37fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define OV534_OP_WRITE_2 0x33 38fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define OV534_OP_READ_2 0xf9 39fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 40fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#define CTRL_TIMEOUT 500 41fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 42fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio OspiteMODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); 43fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio OspiteMODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); 44fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio OspiteMODULE_LICENSE("GPL"); 45fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 46fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* global parameters */ 47fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int frame_rate; 48fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 49fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* specific webcam descriptor */ 50fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestruct sd { 51fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite struct gspca_dev gspca_dev; /* !! must be the first item */ 528c252050146fc6f54e9bf5ef8276b25f3dd67a1cJean-Francois Moine __u32 last_fid; 538c252050146fc6f54e9bf5ef8276b25f3dd67a1cJean-Francois Moine __u32 last_pts; 54fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 55fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 56fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* V4L2 controls supported by the driver */ 57fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic struct ctrl sd_ctrls[] = { 58fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 59fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 60fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic struct v4l2_pix_format vga_mode[] = { 61fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 62fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .bytesperline = 640 * 2, 63fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .sizeimage = 640 * 480 * 2, 64fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .colorspace = V4L2_COLORSPACE_JPEG, 65fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .priv = 0}, 66fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 67fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 689e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospitestatic void ov534_reg_write(struct usb_device *udev, u16 reg, u8 val) 69fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 709e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite u8 data = val; 71fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite int ret; 72fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 739e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val); 74fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ret = usb_control_msg(udev, 75fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite usb_sndctrlpipe(udev, 0), 76fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 0x1, 77fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 78fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 0x0, reg, &data, 1, CTRL_TIMEOUT); 79fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite if (ret < 0) 80fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_ERR, "write failed"); 81fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 82fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 839e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospitestatic u8 ov534_reg_read(struct usb_device *udev, u16 reg) 84fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 859e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite u8 data; 86fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite int ret; 87fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 88fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ret = usb_control_msg(udev, 89fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite usb_rcvctrlpipe(udev, 0), 90fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 0x1, 91fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 92fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 0x0, reg, &data, 1, CTRL_TIMEOUT); 939e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, data); 94fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite if (ret < 0) 95fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_ERR, "read failed"); 96fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return data; 97fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 98fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 99fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. 100fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * (direction and output)? */ 101fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic void ov534_set_led(struct usb_device *udev, int status) 102fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 1039e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite u8 data; 104fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 105fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_CONF, "led status: %d", status); 106fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 107fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data = ov534_reg_read(udev, 0x21); 108fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data |= 0x80; 109fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_reg_write(udev, 0x21, data); 110fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 111fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data = ov534_reg_read(udev, 0x23); 112fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite if (status) 113fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data |= 0x80; 114fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite else 115fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data &= ~(0x80); 116fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 117fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_reg_write(udev, 0x23, data); 118fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 119fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 120fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int sccb_check_status(struct usb_device *udev) 121fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 1229e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite u8 data; 123fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite int i; 124fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 125fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite for (i = 0; i < 5; i++) { 126fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data = ov534_reg_read(udev, OV534_REG_STATUS); 127fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 1289e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite switch (data) { 129fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite case 0x00: 130fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 1; 131fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite case 0x04: 132fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 133fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite case 0x03: 134fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite break; 135fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite default: 136fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5\n", 137fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data, i + 1); 138fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite } 139fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite } 140fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 141fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 142fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 1439e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospitestatic void sccb_reg_write(struct usb_device *udev, u16 reg, u8 val) 144fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 1459e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val); 146fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_reg_write(udev, OV534_REG_SUBADDR, reg); 147fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_reg_write(udev, OV534_REG_WRITE, val); 148fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_WRITE_3); 149fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 150fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite if (!sccb_check_status(udev)) 151fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_ERR, "sccb_reg_write failed"); 152fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 153fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 15447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Parisstatic const __u8 ov534_reg_initdata[][2] = { 15547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe7, 0x3a }, 15647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 15747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */ 15847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 15947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc2, 0x0c }, 16047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x88, 0xf8 }, 16147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc3, 0x69 }, 16247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x89, 0xff }, 16347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x76, 0x03 }, 16447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x92, 0x01 }, 16547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x93, 0x18 }, 16647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x94, 0x10 }, 16747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x95, 0x10 }, 16847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe2, 0x00 }, 16947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe7, 0x3e }, 17047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 17147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x96, 0x00 }, 17247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 17347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x20 }, 17447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x20 }, 17547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x20 }, 17647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x0a }, 17747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x3f }, 17847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x4a }, 17947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x20 }, 18047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x15 }, 18147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x0b }, 18247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 18347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8e, 0x40 }, 18447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x1f, 0x81 }, 18547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x34, 0x05 }, 18647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe3, 0x04 }, 18747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x88, 0x00 }, 18847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x89, 0x00 }, 18947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x76, 0x00 }, 19047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe7, 0x2e }, 19147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x31, 0xf9 }, 19247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x25, 0x42 }, 19347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x21, 0xf0 }, 19447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 19547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x1c, 0x00 }, 19647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x1d, 0x40 }, 1970f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ 1980f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris { 0x1d, 0x00 }, /* payload size */ 1995ea9c4def8154a5be836dd31cbd97f49fd34ea8fJim Paris { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ 2005ea9c4def8154a5be836dd31cbd97f49fd34ea8fJim Paris { 0x1d, 0x58 }, /* frame size */ 2015ea9c4def8154a5be836dd31cbd97f49fd34ea8fJim Paris { 0x1d, 0x00 }, /* frame size */ 20247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 203c06eb61941459b1981817fb675d0104ac0cd6df8Jim Paris { 0x1c, 0x0a }, 204c06eb61941459b1981817fb675d0104ac0cd6df8Jim Paris { 0x1d, 0x08 }, /* turn on UVC header */ 205c06eb61941459b1981817fb675d0104ac0cd6df8Jim Paris { 0x1d, 0x0e }, /* .. */ 206c06eb61941459b1981817fb675d0104ac0cd6df8Jim Paris 20747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8d, 0x1c }, 20847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8e, 0x80 }, 20947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe5, 0x04 }, 21047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 21147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc0, 0x50 }, 21247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc1, 0x3c }, 21347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc2, 0x0c }, 21447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris}; 215fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 21647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Parisstatic const __u8 ov772x_reg_initdata[][2] = { 21747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x12, 0x80 }, 21847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x11, 0x01 }, 21947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 22047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x3d, 0x03 }, 22147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x17, 0x26 }, 22247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x18, 0xa0 }, 22347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x19, 0x07 }, 22447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x1a, 0xf0 }, 22547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x32, 0x00 }, 22647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x29, 0xa0 }, 22747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x2c, 0xf0 }, 22847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x65, 0x20 }, 22947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x11, 0x01 }, 23047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x42, 0x7f }, 23147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x63, 0xe0 }, 23247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x64, 0xff }, 23347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x66, 0x00 }, 23447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x13, 0xf0 }, 23547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0d, 0x41 }, 23647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0f, 0xc5 }, 23747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x14, 0x11 }, 23847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 23947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x22, 0x7f }, 24047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x23, 0x03 }, 24147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x24, 0x40 }, 24247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x25, 0x30 }, 24347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x26, 0xa1 }, 24447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x2a, 0x00 }, 24547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x2b, 0x00 }, 24647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x6b, 0xaa }, 24747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x13, 0xff }, 24847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 24947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x90, 0x05 }, 25047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x91, 0x01 }, 25147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x92, 0x03 }, 25247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x93, 0x00 }, 25347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x94, 0x60 }, 25447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x95, 0x3c }, 25547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x96, 0x24 }, 25647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x1e }, 25747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x98, 0x62 }, 25847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x99, 0x80 }, 25947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x9a, 0x1e }, 26047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x9b, 0x08 }, 26147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x9c, 0x20 }, 26247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x9e, 0x81 }, 26347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 26447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xa6, 0x04 }, 26547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x7e, 0x0c }, 26647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x7f, 0x16 }, 26747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x80, 0x2a }, 26847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x81, 0x4e }, 26947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x82, 0x61 }, 27047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x83, 0x6f }, 27147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x84, 0x7b }, 27247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x85, 0x86 }, 27347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x86, 0x8e }, 27447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x87, 0x97 }, 27547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x88, 0xa4 }, 27647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x89, 0xaf }, 27747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8a, 0xc5 }, 27847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8b, 0xd7 }, 27947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8c, 0xe8 }, 28047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8d, 0x20 }, 28147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 28247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0c, 0x90 }, 28347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 28447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x2b, 0x00 }, 28547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x22, 0x7f }, 28647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x23, 0x03 }, 28747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x11, 0x01 }, 28847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0c, 0xd0 }, 28947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x64, 0xff }, 29047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0d, 0x41 }, 29147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 29247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x14, 0x41 }, 29347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0e, 0xcd }, 29447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xac, 0xbf }, 29547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8e, 0x00 }, 29647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0c, 0xd0 } 29747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris}; 298fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 299fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 30047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris/* setup method */ 30147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Parisstatic void ov534_setup(struct usb_device *udev) 30247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris{ 30347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris int i; 304fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 30547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris /* Initialize bridge chip */ 30647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++) 30747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris ov534_reg_write(udev, ov534_reg_initdata[i][0], 30847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris ov534_reg_initdata[i][1]); 309fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 310fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_set_led(udev, 1); 311fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 31247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris /* Initialize sensor */ 31347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++) 31447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris sccb_reg_write(udev, ov772x_reg_initdata[i][0], 31547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris ov772x_reg_initdata[i][1]); 316fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 317fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_reg_write(udev, 0xe0, 0x09); 318fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_set_led(udev, 0); 319fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 320fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 321fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* this function is called at probe time */ 322fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int sd_config(struct gspca_dev *gspca_dev, 323fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite const struct usb_device_id *id) 324fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 325fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite struct cam *cam; 326fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 327fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite cam = &gspca_dev->cam; 328fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 329fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite cam->epaddr = 0x01; 330fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite cam->cam_mode = vga_mode; 331fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite cam->nmodes = ARRAY_SIZE(vga_mode); 332fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 3330f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris cam->bulk_size = 16384; 334fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite cam->bulk_nurbs = 2; 335fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 336fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 337fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 338fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 339fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* this function is called at probe and resume time */ 340fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int sd_init(struct gspca_dev *gspca_dev) 341fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 3423adba442246a81aad29cf99ef55500379b7a3669Antonio Ospite int fr; 343fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 3443adba442246a81aad29cf99ef55500379b7a3669Antonio Ospite ov534_setup(gspca_dev->dev); 345fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 3463adba442246a81aad29cf99ef55500379b7a3669Antonio Ospite fr = frame_rate; 347fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 3483adba442246a81aad29cf99ef55500379b7a3669Antonio Ospite switch (fr) { 349fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite case 50: 350fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite sccb_reg_write(gspca_dev->dev, 0x11, 0x01); 351fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); 35247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); 353fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite break; 354fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite case 40: 355fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite sccb_reg_write(gspca_dev->dev, 0x11, 0x02); 356fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1); 35747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); 358fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite break; 3593adba442246a81aad29cf99ef55500379b7a3669Antonio Ospite/* case 30: */ 360fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite default: 3613adba442246a81aad29cf99ef55500379b7a3669Antonio Ospite fr = 30; 362fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite sccb_reg_write(gspca_dev->dev, 0x11, 0x04); 363fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite sccb_reg_write(gspca_dev->dev, 0x0d, 0x81); 36447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); 365fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite break; 366fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite case 15: 367fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite sccb_reg_write(gspca_dev->dev, 0x11, 0x03); 368fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); 36947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); 370fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite break; 3713adba442246a81aad29cf99ef55500379b7a3669Antonio Ospite } 3723adba442246a81aad29cf99ef55500379b7a3669Antonio Ospite 3733adba442246a81aad29cf99ef55500379b7a3669Antonio Ospite PDEBUG(D_PROBE, "frame_rate: %d", fr); 374fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 375fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 376fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 377fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 378fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int sd_start(struct gspca_dev *gspca_dev) 379fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 380fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite /* start streaming data */ 381fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_set_led(gspca_dev->dev, 1); 382fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_reg_write(gspca_dev->dev, 0xe0, 0x00); 383fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 384fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 385fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 386fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 387fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic void sd_stopN(struct gspca_dev *gspca_dev) 388fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 389fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite /* stop streaming data */ 390fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_reg_write(gspca_dev->dev, 0xe0, 0x09); 391fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ov534_set_led(gspca_dev->dev, 0); 392fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 393fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 394fb139224aea3b56237542690516eb9d6d671b135Jim Paris/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 395fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_EOH (1 << 7) 396fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_ERR (1 << 6) 397fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_STI (1 << 5) 398fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_RES (1 << 4) 399fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_SCR (1 << 3) 400fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_PTS (1 << 2) 401fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_EOF (1 << 1) 402fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_FID (1 << 0) 403fb139224aea3b56237542690516eb9d6d671b135Jim Paris 404fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, 405fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite __u8 *data, int len) 406fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 4078c252050146fc6f54e9bf5ef8276b25f3dd67a1cJean-Francois Moine struct sd *sd = (struct sd *) gspca_dev; 408fb139224aea3b56237542690516eb9d6d671b135Jim Paris __u32 this_pts; 409fb139224aea3b56237542690516eb9d6d671b135Jim Paris int this_fid; 4100f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris int remaining_len = len; 4110f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris __u8 *next_data = data; 4120f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris 4130f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Parisscan_next: 4140f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris if (remaining_len <= 0) 4150f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris return; 4160f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris 4170f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris data = next_data; 4180f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris len = min(remaining_len, 2048); 4190f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris remaining_len -= len; 4200f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris next_data += len; 421fb139224aea3b56237542690516eb9d6d671b135Jim Paris 422fb139224aea3b56237542690516eb9d6d671b135Jim Paris /* Payloads are prefixed with a the UVC-style header. We 423fb139224aea3b56237542690516eb9d6d671b135Jim Paris consider a frame to start when the FID toggles, or the PTS 424fb139224aea3b56237542690516eb9d6d671b135Jim Paris changes. A frame ends when EOF is set, and we've received 425fb139224aea3b56237542690516eb9d6d671b135Jim Paris the correct number of bytes. */ 426fb139224aea3b56237542690516eb9d6d671b135Jim Paris 427fb139224aea3b56237542690516eb9d6d671b135Jim Paris /* Verify UVC header. Header length is always 12 */ 428fb139224aea3b56237542690516eb9d6d671b135Jim Paris if (data[0] != 12 || len < 12) { 429fb139224aea3b56237542690516eb9d6d671b135Jim Paris PDEBUG(D_PACK, "bad header"); 430fb139224aea3b56237542690516eb9d6d671b135Jim Paris goto discard; 431fb139224aea3b56237542690516eb9d6d671b135Jim Paris } 432fb139224aea3b56237542690516eb9d6d671b135Jim Paris 433fb139224aea3b56237542690516eb9d6d671b135Jim Paris /* Check errors */ 434fb139224aea3b56237542690516eb9d6d671b135Jim Paris if (data[1] & UVC_STREAM_ERR) { 435fb139224aea3b56237542690516eb9d6d671b135Jim Paris PDEBUG(D_PACK, "payload error"); 436fb139224aea3b56237542690516eb9d6d671b135Jim Paris goto discard; 437fb139224aea3b56237542690516eb9d6d671b135Jim Paris } 438fb139224aea3b56237542690516eb9d6d671b135Jim Paris 439fb139224aea3b56237542690516eb9d6d671b135Jim Paris /* Extract PTS and FID */ 440fb139224aea3b56237542690516eb9d6d671b135Jim Paris if (!(data[1] & UVC_STREAM_PTS)) { 441fb139224aea3b56237542690516eb9d6d671b135Jim Paris PDEBUG(D_PACK, "PTS not present"); 442fb139224aea3b56237542690516eb9d6d671b135Jim Paris goto discard; 443fb139224aea3b56237542690516eb9d6d671b135Jim Paris } 444fb139224aea3b56237542690516eb9d6d671b135Jim Paris this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2]; 445fb139224aea3b56237542690516eb9d6d671b135Jim Paris this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0; 446fb139224aea3b56237542690516eb9d6d671b135Jim Paris 447fb139224aea3b56237542690516eb9d6d671b135Jim Paris /* If PTS or FID has changed, start a new frame. */ 4488c252050146fc6f54e9bf5ef8276b25f3dd67a1cJean-Francois Moine if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 449fb139224aea3b56237542690516eb9d6d671b135Jim Paris gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); 4508c252050146fc6f54e9bf5ef8276b25f3dd67a1cJean-Francois Moine sd->last_pts = this_pts; 4518c252050146fc6f54e9bf5ef8276b25f3dd67a1cJean-Francois Moine sd->last_fid = this_fid; 452fb139224aea3b56237542690516eb9d6d671b135Jim Paris } 453fb139224aea3b56237542690516eb9d6d671b135Jim Paris 454fb139224aea3b56237542690516eb9d6d671b135Jim Paris /* Add the data from this payload */ 455fb139224aea3b56237542690516eb9d6d671b135Jim Paris gspca_frame_add(gspca_dev, INTER_PACKET, frame, 456fb139224aea3b56237542690516eb9d6d671b135Jim Paris data + 12, len - 12); 457fb139224aea3b56237542690516eb9d6d671b135Jim Paris 458fb139224aea3b56237542690516eb9d6d671b135Jim Paris /* If this packet is marked as EOF, end the frame */ 459fb139224aea3b56237542690516eb9d6d671b135Jim Paris if (data[1] & UVC_STREAM_EOF) { 4608c252050146fc6f54e9bf5ef8276b25f3dd67a1cJean-Francois Moine sd->last_pts = 0; 461fb139224aea3b56237542690516eb9d6d671b135Jim Paris 462fb139224aea3b56237542690516eb9d6d671b135Jim Paris if ((frame->data_end - frame->data) != 463fb139224aea3b56237542690516eb9d6d671b135Jim Paris (gspca_dev->width * gspca_dev->height * 2)) { 464fb139224aea3b56237542690516eb9d6d671b135Jim Paris PDEBUG(D_PACK, "short frame"); 465fb139224aea3b56237542690516eb9d6d671b135Jim Paris goto discard; 466fb139224aea3b56237542690516eb9d6d671b135Jim Paris } 467fb139224aea3b56237542690516eb9d6d671b135Jim Paris 468fb139224aea3b56237542690516eb9d6d671b135Jim Paris gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0); 469fb139224aea3b56237542690516eb9d6d671b135Jim Paris } 470fb139224aea3b56237542690516eb9d6d671b135Jim Paris 4710f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris /* Done this payload */ 4720f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris goto scan_next; 473fb139224aea3b56237542690516eb9d6d671b135Jim Paris 474fb139224aea3b56237542690516eb9d6d671b135Jim Parisdiscard: 475fb139224aea3b56237542690516eb9d6d671b135Jim Paris /* Discard data until a new frame starts. */ 476fb139224aea3b56237542690516eb9d6d671b135Jim Paris gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); 4770f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris goto scan_next; 478fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 479fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 480fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* sub-driver description */ 481fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic const struct sd_desc sd_desc = { 482fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .name = MODULE_NAME, 483fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .ctrls = sd_ctrls, 484fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .nctrls = ARRAY_SIZE(sd_ctrls), 485fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .config = sd_config, 486fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .init = sd_init, 487fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .start = sd_start, 488fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .stopN = sd_stopN, 489fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .pkt_scan = sd_pkt_scan, 490fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 491fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 492fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* -- module initialisation -- */ 493fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic const __devinitdata struct usb_device_id device_table[] = { 494fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */ 495fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */ 496fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */ 497fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite {} 498fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 499fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 500fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio OspiteMODULE_DEVICE_TABLE(usb, device_table); 501fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 502fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* -- device connect -- */ 503fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 504fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 505fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 506fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite THIS_MODULE); 507fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 508fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 509fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic struct usb_driver sd_driver = { 510fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .name = MODULE_NAME, 511fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .id_table = device_table, 512fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .probe = sd_probe, 513fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .disconnect = gspca_disconnect, 514fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#ifdef CONFIG_PM 515fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .suspend = gspca_suspend, 516fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .resume = gspca_resume, 517fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#endif 518fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 519fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 520fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* -- module insert / remove -- */ 521fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int __init sd_mod_init(void) 522fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 523fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite if (usb_register(&sd_driver) < 0) 524fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return -1; 525fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_PROBE, "registered"); 526fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 527fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 528fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 529fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic void __exit sd_mod_exit(void) 530fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 531fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite usb_deregister(&sd_driver); 532fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_PROBE, "deregistered"); 533fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 534fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 535fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitemodule_init(sd_mod_init); 536fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitemodule_exit(sd_mod_exit); 537fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 538fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitemodule_param(frame_rate, int, 0644); 539fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio OspiteMODULE_PARM_DESC(frame_rate, "Frame rate (15, 30, 40, 50)"); 540