ov534.c revision 84fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebf
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/* specific webcam descriptor */ 47fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestruct sd { 48fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite struct gspca_dev gspca_dev; /* !! must be the first item */ 498c252050146fc6f54e9bf5ef8276b25f3dd67a1cJean-Francois Moine __u32 last_pts; 5084fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine u16 last_fid; 5184fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine u8 frame_rate; 52fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 53fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 54fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* V4L2 controls supported by the driver */ 55fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic struct ctrl sd_ctrls[] = { 56fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 57fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 58cc611b8aef7a8a9a2e614f1bdf3e2b8f066c8c8dJean-Francois Moinestatic const struct v4l2_pix_format vga_mode[] = { 59fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, 60fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .bytesperline = 640 * 2, 61fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .sizeimage = 640 * 480 * 2, 62fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .colorspace = V4L2_COLORSPACE_JPEG, 63fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .priv = 0}, 64fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 65fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 6615f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moinestatic void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) 67fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 6815f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine struct usb_device *udev = gspca_dev->dev; 69fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite int ret; 70fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 719e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val); 7215f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine gspca_dev->usb_buf[0] = val; 73fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ret = usb_control_msg(udev, 74fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite usb_sndctrlpipe(udev, 0), 75fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 0x1, 76fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 7715f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); 78fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite if (ret < 0) 79fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_ERR, "write failed"); 80fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 81fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 8215f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moinestatic u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) 83fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 8415f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine struct usb_device *udev = gspca_dev->dev; 85fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite int ret; 86fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 87fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite ret = usb_control_msg(udev, 88fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite usb_rcvctrlpipe(udev, 0), 89fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 0x1, 90fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 9115f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); 9215f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]); 93fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite if (ret < 0) 94fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_ERR, "read failed"); 9515f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine return gspca_dev->usb_buf[0]; 96fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 97fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 98fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. 99fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite * (direction and output)? */ 10015f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moinestatic void ov534_set_led(struct gspca_dev *gspca_dev, int status) 101fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 1029e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite u8 data; 103fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 104fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_CONF, "led status: %d", status); 105fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 10615f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine data = ov534_reg_read(gspca_dev, 0x21); 107fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data |= 0x80; 10815f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, 0x21, data); 109fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 11015f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine data = ov534_reg_read(gspca_dev, 0x23); 111fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite if (status) 112fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data |= 0x80; 113fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite else 114fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data &= ~(0x80); 115fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 11615f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, 0x23, data); 117fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 118fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 11915f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moinestatic int sccb_check_status(struct gspca_dev *gspca_dev) 120fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 1219e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite u8 data; 122fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite int i; 123fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 124fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite for (i = 0; i < 5; i++) { 12515f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); 126fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 1279e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite switch (data) { 128fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite case 0x00: 129fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 1; 130fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite case 0x04: 131fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 132fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite case 0x03: 133fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite break; 134fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite default: 135f367b85d9a0bda04c31c5c5598dba758efc6658eJean-Francois Moine PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5", 136fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite data, i + 1); 137fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite } 138fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite } 139fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 140fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 141fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 14215f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moinestatic void sccb_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) 143fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 1449e1e7b068debea80c3ffbde264d0389b8137b589Antonio Ospite PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val); 14515f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); 14615f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, OV534_REG_WRITE, val); 14715f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); 148fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 14915f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine if (!sccb_check_status(gspca_dev)) 150fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_ERR, "sccb_reg_write failed"); 151fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 152fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 1531dc87b6e2fb29777f921c733d78df7eea31e6cc8Jean-Francois Moine#ifdef GSPCA_DEBUG 15415f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moinestatic u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg) 155e6e483782772994fe42ef9e8b5b4d6f6376b3d45Antonio Ospite{ 15615f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); 15715f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); 15815f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine if (!sccb_check_status(gspca_dev)) 159e6e483782772994fe42ef9e8b5b4d6f6376b3d45Antonio Ospite PDEBUG(D_ERR, "sccb_reg_read failed 1"); 160e6e483782772994fe42ef9e8b5b4d6f6376b3d45Antonio Ospite 16115f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); 16215f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine if (!sccb_check_status(gspca_dev)) 163e6e483782772994fe42ef9e8b5b4d6f6376b3d45Antonio Ospite PDEBUG(D_ERR, "sccb_reg_read failed 2"); 164e6e483782772994fe42ef9e8b5b4d6f6376b3d45Antonio Ospite 16515f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine return ov534_reg_read(gspca_dev, OV534_REG_READ); 166e6e483782772994fe42ef9e8b5b4d6f6376b3d45Antonio Ospite} 1671dc87b6e2fb29777f921c733d78df7eea31e6cc8Jean-Francois Moine#endif 168e6e483782772994fe42ef9e8b5b4d6f6376b3d45Antonio Ospite 16947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Parisstatic const __u8 ov534_reg_initdata[][2] = { 17047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe7, 0x3a }, 17147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 17247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */ 17347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 17447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc2, 0x0c }, 17547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x88, 0xf8 }, 17647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc3, 0x69 }, 17747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x89, 0xff }, 17847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x76, 0x03 }, 17947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x92, 0x01 }, 18047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x93, 0x18 }, 18147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x94, 0x10 }, 18247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x95, 0x10 }, 18347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe2, 0x00 }, 18447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe7, 0x3e }, 18547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 18647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x96, 0x00 }, 18747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 18847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x20 }, 18947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x20 }, 19047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x20 }, 19147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x0a }, 19247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x3f }, 19347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x4a }, 19447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x20 }, 19547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x15 }, 19647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x0b }, 19747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 19847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8e, 0x40 }, 19947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x1f, 0x81 }, 20047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x34, 0x05 }, 20147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe3, 0x04 }, 20247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x88, 0x00 }, 20347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x89, 0x00 }, 20447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x76, 0x00 }, 20547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe7, 0x2e }, 20647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x31, 0xf9 }, 20747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x25, 0x42 }, 20847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x21, 0xf0 }, 20947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 21047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x1c, 0x00 }, 21147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x1d, 0x40 }, 2120f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ 2130f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris { 0x1d, 0x00 }, /* payload size */ 2145ea9c4def8154a5be836dd31cbd97f49fd34ea8fJim Paris { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ 2155ea9c4def8154a5be836dd31cbd97f49fd34ea8fJim Paris { 0x1d, 0x58 }, /* frame size */ 2165ea9c4def8154a5be836dd31cbd97f49fd34ea8fJim Paris { 0x1d, 0x00 }, /* frame size */ 21747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 218c06eb61941459b1981817fb675d0104ac0cd6df8Jim Paris { 0x1c, 0x0a }, 219c06eb61941459b1981817fb675d0104ac0cd6df8Jim Paris { 0x1d, 0x08 }, /* turn on UVC header */ 220c06eb61941459b1981817fb675d0104ac0cd6df8Jim Paris { 0x1d, 0x0e }, /* .. */ 221c06eb61941459b1981817fb675d0104ac0cd6df8Jim Paris 22247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8d, 0x1c }, 22347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8e, 0x80 }, 22447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xe5, 0x04 }, 22547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 22647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc0, 0x50 }, 22747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc1, 0x3c }, 22847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xc2, 0x0c }, 22947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris}; 230fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 23147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Parisstatic const __u8 ov772x_reg_initdata[][2] = { 23247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x12, 0x80 }, 23347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x11, 0x01 }, 23447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 23547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x3d, 0x03 }, 23647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x17, 0x26 }, 23747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x18, 0xa0 }, 23847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x19, 0x07 }, 23947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x1a, 0xf0 }, 24047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x32, 0x00 }, 24147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x29, 0xa0 }, 24247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x2c, 0xf0 }, 24347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x65, 0x20 }, 24447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x11, 0x01 }, 24547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x42, 0x7f }, 24647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x63, 0xe0 }, 24747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x64, 0xff }, 24847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x66, 0x00 }, 24947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x13, 0xf0 }, 25047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0d, 0x41 }, 25147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0f, 0xc5 }, 25247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x14, 0x11 }, 25347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 25447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x22, 0x7f }, 25547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x23, 0x03 }, 25647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x24, 0x40 }, 25747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x25, 0x30 }, 25847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x26, 0xa1 }, 25947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x2a, 0x00 }, 26047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x2b, 0x00 }, 26147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x6b, 0xaa }, 26247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x13, 0xff }, 26347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 26447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x90, 0x05 }, 26547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x91, 0x01 }, 26647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x92, 0x03 }, 26747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x93, 0x00 }, 26847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x94, 0x60 }, 26947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x95, 0x3c }, 27047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x96, 0x24 }, 27147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x97, 0x1e }, 27247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x98, 0x62 }, 27347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x99, 0x80 }, 27447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x9a, 0x1e }, 27547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x9b, 0x08 }, 27647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x9c, 0x20 }, 27747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x9e, 0x81 }, 27847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 27947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xa6, 0x04 }, 28047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x7e, 0x0c }, 28147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x7f, 0x16 }, 28247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x80, 0x2a }, 28347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x81, 0x4e }, 28447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x82, 0x61 }, 28547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x83, 0x6f }, 28647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x84, 0x7b }, 28747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x85, 0x86 }, 28847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x86, 0x8e }, 28947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x87, 0x97 }, 29047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x88, 0xa4 }, 29147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x89, 0xaf }, 29247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8a, 0xc5 }, 29347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8b, 0xd7 }, 29447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8c, 0xe8 }, 29547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8d, 0x20 }, 29647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 29747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0c, 0x90 }, 29847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 29947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x2b, 0x00 }, 30047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x22, 0x7f }, 30147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x23, 0x03 }, 30247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x11, 0x01 }, 30347dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0c, 0xd0 }, 30447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x64, 0xff }, 30547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0d, 0x41 }, 30647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris 30747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x14, 0x41 }, 30847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0e, 0xcd }, 30947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0xac, 0xbf }, 31047dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x8e, 0x00 }, 31147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris { 0x0c, 0xd0 } 31247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris}; 313fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 31411d9f25da89523d19dba3608d51a86af2954fc0dJim Paris/* set framerate */ 31511d9f25da89523d19dba3608d51a86af2954fc0dJim Parisstatic void ov534_set_frame_rate(struct gspca_dev *gspca_dev) 31611d9f25da89523d19dba3608d51a86af2954fc0dJim Paris{ 31711d9f25da89523d19dba3608d51a86af2954fc0dJim Paris struct sd *sd = (struct sd *) gspca_dev; 31811d9f25da89523d19dba3608d51a86af2954fc0dJim Paris int fr = sd->frame_rate; 31911d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 32011d9f25da89523d19dba3608d51a86af2954fc0dJim Paris switch (fr) { 32111d9f25da89523d19dba3608d51a86af2954fc0dJim Paris case 50: 32215f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_write(gspca_dev, 0x11, 0x01); 32315f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_write(gspca_dev, 0x0d, 0x41); 32415f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, 0xe5, 0x02); 32511d9f25da89523d19dba3608d51a86af2954fc0dJim Paris break; 32611d9f25da89523d19dba3608d51a86af2954fc0dJim Paris case 40: 32715f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_write(gspca_dev, 0x11, 0x02); 32815f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_write(gspca_dev, 0x0d, 0xc1); 32915f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, 0xe5, 0x04); 33011d9f25da89523d19dba3608d51a86af2954fc0dJim Paris break; 33111d9f25da89523d19dba3608d51a86af2954fc0dJim Paris/* case 30: */ 33211d9f25da89523d19dba3608d51a86af2954fc0dJim Paris default: 33311d9f25da89523d19dba3608d51a86af2954fc0dJim Paris fr = 30; 33415f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_write(gspca_dev, 0x11, 0x04); 33515f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_write(gspca_dev, 0x0d, 0x81); 33615f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, 0xe5, 0x02); 33711d9f25da89523d19dba3608d51a86af2954fc0dJim Paris break; 33811d9f25da89523d19dba3608d51a86af2954fc0dJim Paris case 15: 33915f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_write(gspca_dev, 0x11, 0x03); 34015f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_write(gspca_dev, 0x0d, 0x41); 34115f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, 0xe5, 0x04); 34211d9f25da89523d19dba3608d51a86af2954fc0dJim Paris break; 34311d9f25da89523d19dba3608d51a86af2954fc0dJim Paris } 34411d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 34511d9f25da89523d19dba3608d51a86af2954fc0dJim Paris sd->frame_rate = fr; 34611d9f25da89523d19dba3608d51a86af2954fc0dJim Paris PDEBUG(D_PROBE, "frame_rate: %d", fr); 34711d9f25da89523d19dba3608d51a86af2954fc0dJim Paris} 348fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 34947dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris/* setup method */ 35015f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moinestatic void ov534_setup(struct gspca_dev *gspca_dev) 35147dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris{ 35247dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris int i; 353fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 35447dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris /* Initialize bridge chip */ 35547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++) 35615f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, ov534_reg_initdata[i][0], 35747dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris ov534_reg_initdata[i][1]); 358fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 359e6e483782772994fe42ef9e8b5b4d6f6376b3d45Antonio Ospite PDEBUG(D_PROBE, "sensor is ov%02x%02x", 36015f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_read(gspca_dev, 0x0a), 36115f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_read(gspca_dev, 0x0b)); 362e6e483782772994fe42ef9e8b5b4d6f6376b3d45Antonio Ospite 36315f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_set_led(gspca_dev, 1); 364fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 36547dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris /* Initialize sensor */ 36647dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++) 36715f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine sccb_reg_write(gspca_dev, ov772x_reg_initdata[i][0], 36847dfd21fbf4ba303b5fdfad6f4e110e57990803cJim Paris ov772x_reg_initdata[i][1]); 369fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 37015f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, 0xe0, 0x09); 37115f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_set_led(gspca_dev, 0); 372fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 373fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 374fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* this function is called at probe time */ 375fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int sd_config(struct gspca_dev *gspca_dev, 376fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite const struct usb_device_id *id) 377fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 378fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite struct cam *cam; 379fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 380fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite cam = &gspca_dev->cam; 381fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 382fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite cam->cam_mode = vga_mode; 383fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite cam->nmodes = ARRAY_SIZE(vga_mode); 384fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 3850f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris cam->bulk_size = 16384; 386fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite cam->bulk_nurbs = 2; 387fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 388fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 389fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 390fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 391fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* this function is called at probe and resume time */ 392fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int sd_init(struct gspca_dev *gspca_dev) 393fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 39415f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_setup(gspca_dev); 39511d9f25da89523d19dba3608d51a86af2954fc0dJim Paris ov534_set_frame_rate(gspca_dev); 396fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 397fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 398fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 399fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 400fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int sd_start(struct gspca_dev *gspca_dev) 401fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 402fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite /* start streaming data */ 40315f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_set_led(gspca_dev, 1); 40415f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, 0xe0, 0x00); 405fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 406fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 407fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 408fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 409fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic void sd_stopN(struct gspca_dev *gspca_dev) 410fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 411fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite /* stop streaming data */ 41215f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_reg_write(gspca_dev, 0xe0, 0x09); 41315f64864e392612b230bc71d84e4537b80c607b1Jean-Francois Moine ov534_set_led(gspca_dev, 0); 414fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 415fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 416fb139224aea3b56237542690516eb9d6d671b135Jim Paris/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ 417fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_EOH (1 << 7) 418fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_ERR (1 << 6) 419fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_STI (1 << 5) 420fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_RES (1 << 4) 421fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_SCR (1 << 3) 422fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_PTS (1 << 2) 423fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_EOF (1 << 1) 424fb139224aea3b56237542690516eb9d6d671b135Jim Paris#define UVC_STREAM_FID (1 << 0) 425fb139224aea3b56237542690516eb9d6d671b135Jim Paris 426fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, 427fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite __u8 *data, int len) 428fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 4298c252050146fc6f54e9bf5ef8276b25f3dd67a1cJean-Francois Moine struct sd *sd = (struct sd *) gspca_dev; 430fb139224aea3b56237542690516eb9d6d671b135Jim Paris __u32 this_pts; 43184fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine u16 this_fid; 4320f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris int remaining_len = len; 4330f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6dJim Paris 43484fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine do { 43584fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine len = min(remaining_len, 2040); /*fixme: was 2048*/ 436fb139224aea3b56237542690516eb9d6d671b135Jim Paris 43784fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine /* Payloads are prefixed with a UVC-style header. We 43884fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine consider a frame to start when the FID toggles, or the PTS 43984fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine changes. A frame ends when EOF is set, and we've received 44084fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine the correct number of bytes. */ 441fb139224aea3b56237542690516eb9d6d671b135Jim Paris 44284fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine /* Verify UVC header. Header length is always 12 */ 44384fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine if (data[0] != 12 || len < 12) { 44484fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine PDEBUG(D_PACK, "bad header"); 44584fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine goto discard; 44684fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine } 447fb139224aea3b56237542690516eb9d6d671b135Jim Paris 44884fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine /* Check errors */ 44984fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine if (data[1] & UVC_STREAM_ERR) { 45084fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine PDEBUG(D_PACK, "payload error"); 45184fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine goto discard; 45284fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine } 453fb139224aea3b56237542690516eb9d6d671b135Jim Paris 45484fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine /* Extract PTS and FID */ 45584fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine if (!(data[1] & UVC_STREAM_PTS)) { 45684fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine PDEBUG(D_PACK, "PTS not present"); 457fb139224aea3b56237542690516eb9d6d671b135Jim Paris goto discard; 458fb139224aea3b56237542690516eb9d6d671b135Jim Paris } 45984fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine this_pts = (data[5] << 24) | (data[4] << 16) 46084fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine | (data[3] << 8) | data[2]; 46184fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0; 462fb139224aea3b56237542690516eb9d6d671b135Jim Paris 46384fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine /* If PTS or FID has changed, start a new frame. */ 46484fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine if (this_pts != sd->last_pts || this_fid != sd->last_fid) { 46584fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine gspca_frame_add(gspca_dev, FIRST_PACKET, frame, 4663481c19854cdb1de1842c6ea6d558006ac0b3b7dJean-Francois Moine NULL, 0); 46784fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine sd->last_pts = this_pts; 46884fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine sd->last_fid = this_fid; 46984fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine } 47084fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine 47184fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine /* Add the data from this payload */ 47284fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine gspca_frame_add(gspca_dev, INTER_PACKET, frame, 47384fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine data + 12, len - 12); 47484fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine 47584fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine /* If this packet is marked as EOF, end the frame */ 47684fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine if (data[1] & UVC_STREAM_EOF) { 47784fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine sd->last_pts = 0; 47884fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine 47984fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine if (frame->data_end - frame->data != 48084fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine gspca_dev->width * gspca_dev->height * 2) { 48184fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine PDEBUG(D_PACK, "short frame"); 48284fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine goto discard; 48384fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine } 48484fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine 48584fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, 48684fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine NULL, 0); 4873481c19854cdb1de1842c6ea6d558006ac0b3b7dJean-Francois Moine } 488fb139224aea3b56237542690516eb9d6d671b135Jim Paris 48984fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine /* Done this payload */ 49084fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine goto scan_next; 491fb139224aea3b56237542690516eb9d6d671b135Jim Paris 492fb139224aea3b56237542690516eb9d6d671b135Jim Parisdiscard: 49384fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine /* Discard data until a new frame starts. */ 49484fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); 49584fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine 49684fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moinescan_next: 49784fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine remaining_len -= len; 49884fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine data += len; 49984fbdf87ab8eaa4eaefb317a7eb437cd4d3d0ebfJean-Francois Moine } while (remaining_len > 0); 500fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 501fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 50211d9f25da89523d19dba3608d51a86af2954fc0dJim Paris/* get stream parameters (framerate) */ 5035c1a15a149504496b25ee3f681893cbe1647ba39Jean-Francois Moinestatic int sd_get_streamparm(struct gspca_dev *gspca_dev, 5045c1a15a149504496b25ee3f681893cbe1647ba39Jean-Francois Moine struct v4l2_streamparm *parm) 50511d9f25da89523d19dba3608d51a86af2954fc0dJim Paris{ 50611d9f25da89523d19dba3608d51a86af2954fc0dJim Paris struct v4l2_captureparm *cp = &parm->parm.capture; 50711d9f25da89523d19dba3608d51a86af2954fc0dJim Paris struct v4l2_fract *tpf = &cp->timeperframe; 50811d9f25da89523d19dba3608d51a86af2954fc0dJim Paris struct sd *sd = (struct sd *) gspca_dev; 50911d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 51011d9f25da89523d19dba3608d51a86af2954fc0dJim Paris if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 51111d9f25da89523d19dba3608d51a86af2954fc0dJim Paris return -EINVAL; 51211d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 51311d9f25da89523d19dba3608d51a86af2954fc0dJim Paris cp->capability |= V4L2_CAP_TIMEPERFRAME; 51411d9f25da89523d19dba3608d51a86af2954fc0dJim Paris tpf->numerator = 1; 51511d9f25da89523d19dba3608d51a86af2954fc0dJim Paris tpf->denominator = sd->frame_rate; 51611d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 51711d9f25da89523d19dba3608d51a86af2954fc0dJim Paris return 0; 51811d9f25da89523d19dba3608d51a86af2954fc0dJim Paris} 51911d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 52011d9f25da89523d19dba3608d51a86af2954fc0dJim Paris/* set stream parameters (framerate) */ 5215c1a15a149504496b25ee3f681893cbe1647ba39Jean-Francois Moinestatic int sd_set_streamparm(struct gspca_dev *gspca_dev, 5225c1a15a149504496b25ee3f681893cbe1647ba39Jean-Francois Moine struct v4l2_streamparm *parm) 52311d9f25da89523d19dba3608d51a86af2954fc0dJim Paris{ 52411d9f25da89523d19dba3608d51a86af2954fc0dJim Paris struct v4l2_captureparm *cp = &parm->parm.capture; 52511d9f25da89523d19dba3608d51a86af2954fc0dJim Paris struct v4l2_fract *tpf = &cp->timeperframe; 52611d9f25da89523d19dba3608d51a86af2954fc0dJim Paris struct sd *sd = (struct sd *) gspca_dev; 52711d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 52811d9f25da89523d19dba3608d51a86af2954fc0dJim Paris if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 52911d9f25da89523d19dba3608d51a86af2954fc0dJim Paris return -EINVAL; 53011d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 53111d9f25da89523d19dba3608d51a86af2954fc0dJim Paris /* Set requested framerate */ 53211d9f25da89523d19dba3608d51a86af2954fc0dJim Paris sd->frame_rate = tpf->denominator / tpf->numerator; 53311d9f25da89523d19dba3608d51a86af2954fc0dJim Paris ov534_set_frame_rate(gspca_dev); 53411d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 53511d9f25da89523d19dba3608d51a86af2954fc0dJim Paris /* Return the actual framerate */ 53611d9f25da89523d19dba3608d51a86af2954fc0dJim Paris tpf->numerator = 1; 53711d9f25da89523d19dba3608d51a86af2954fc0dJim Paris tpf->denominator = sd->frame_rate; 53811d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 53911d9f25da89523d19dba3608d51a86af2954fc0dJim Paris return 0; 54011d9f25da89523d19dba3608d51a86af2954fc0dJim Paris} 54111d9f25da89523d19dba3608d51a86af2954fc0dJim Paris 542fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* sub-driver description */ 543fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic const struct sd_desc sd_desc = { 544fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .name = MODULE_NAME, 545fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .ctrls = sd_ctrls, 546fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .nctrls = ARRAY_SIZE(sd_ctrls), 547fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .config = sd_config, 548fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .init = sd_init, 549fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .start = sd_start, 550fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .stopN = sd_stopN, 551fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .pkt_scan = sd_pkt_scan, 55211d9f25da89523d19dba3608d51a86af2954fc0dJim Paris .get_streamparm = sd_get_streamparm, 55311d9f25da89523d19dba3608d51a86af2954fc0dJim Paris .set_streamparm = sd_set_streamparm, 554fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 555fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 556fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* -- module initialisation -- */ 557fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic const __devinitdata struct usb_device_id device_table[] = { 558fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */ 559fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite {} 560fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 561fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 562fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio OspiteMODULE_DEVICE_TABLE(usb, device_table); 563fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 564fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* -- device connect -- */ 565fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) 566fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 567fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), 568fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite THIS_MODULE); 569fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 570fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 571fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic struct usb_driver sd_driver = { 572fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .name = MODULE_NAME, 573fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .id_table = device_table, 574fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .probe = sd_probe, 575fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .disconnect = gspca_disconnect, 576fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#ifdef CONFIG_PM 577fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .suspend = gspca_suspend, 578fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite .resume = gspca_resume, 579fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite#endif 580fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite}; 581fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 582fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite/* -- module insert / remove -- */ 583fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic int __init sd_mod_init(void) 584fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 585f69e9529ed96ff917096d0b7b3015c8d8ea5750dAlexey Klimov int ret; 586f69e9529ed96ff917096d0b7b3015c8d8ea5750dAlexey Klimov ret = usb_register(&sd_driver); 587f69e9529ed96ff917096d0b7b3015c8d8ea5750dAlexey Klimov if (ret < 0) 588e6b148490f5e9ebb90ecb4a8de930be1b8936a16Alexey Klimov return ret; 589fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_PROBE, "registered"); 590fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite return 0; 591fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 592fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 593fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitestatic void __exit sd_mod_exit(void) 594fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite{ 595fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite usb_deregister(&sd_driver); 596fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite PDEBUG(D_PROBE, "deregistered"); 597fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite} 598fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospite 599fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitemodule_init(sd_mod_init); 600fbb4c6d20f29f2b10daad31cc6238d91f93d70d4Antonio Ospitemodule_exit(sd_mod_exit); 601