From fbb4c6d20f29f2b10daad31cc6238d91f93d70d4 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sat, 22 Nov 2008 05:23:39 -0300 Subject: V4L/DVB (9712): gspca:Subdriver ov534 added. The OmniVision OV534 is the USB bridge chip used in Sony Playstation EYE, it is found also in other webcams like Hercules Blog Webcam and Hercules Dualpix HD. This driver is the port to gspca of a prototype driver by Mark Ferrell based on vivi. The original code to initialize the camera and start the capture is from Jim Paris on ps2dev.org, here integrated with the analysis of the USB communications taken by the windows driver. Signed-off-by: Antonio Ospite Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 505 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 505 insertions(+) create mode 100644 drivers/media/video/gspca/ov534.c (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c new file mode 100644 index 00000000000..a574be09bd4 --- /dev/null +++ b/drivers/media/video/gspca/ov534.c @@ -0,0 +1,505 @@ +/* + * ov534/ov772x gspca driver + * Copyright (C) 2008 Antonio Ospite + * + * Based on a prototype written by Mark Ferrell + * USB protocol reverse engineered by Jim Paris + * https://jim.sh/svn/jim/devl/playstation/ps3/eye/test/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define MODULE_NAME "ov534" + +#include "gspca.h" + +#define OV534_REG_ADDRESS 0xf1 /* ? */ +#define OV534_REG_SUBADDR 0xf2 +#define OV534_REG_WRITE 0xf3 +#define OV534_REG_READ 0xf4 +#define OV534_REG_OPERATION 0xf5 +#define OV534_REG_STATUS 0xf6 + +#define OV534_OP_WRITE_3 0x37 +#define OV534_OP_WRITE_2 0x33 +#define OV534_OP_READ_2 0xf9 + +#define CTRL_TIMEOUT 500 + +MODULE_AUTHOR("Antonio Ospite "); +MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); +MODULE_LICENSE("GPL"); + +/* global parameters */ +static int frame_rate; + +/* specific webcam descriptor */ +struct sd { + struct gspca_dev gspca_dev; /* !! must be the first item */ + __u8 frame_rate; +}; + +/* V4L2 controls supported by the driver */ +static struct ctrl sd_ctrls[] = { +}; + +static struct v4l2_pix_format vga_mode[] = { + {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, + .bytesperline = 640 * 2, + .sizeimage = 640 * 480 * 2, + .colorspace = V4L2_COLORSPACE_JPEG, + .priv = 0}, +}; + +static void ov534_reg_write(struct usb_device *udev, u16 reg, u16 val) +{ + u16 data = val; + int ret; + + PDEBUG(D_USBO, "reg=0x%04x, val=0%04x", reg, val); + ret = usb_control_msg(udev, + usb_sndctrlpipe(udev, 0), + 0x1, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x0, reg, &data, 1, CTRL_TIMEOUT); + if (ret < 0) + PDEBUG(D_ERR, "write failed"); +} + +static u16 ov534_reg_read(struct usb_device *udev, u16 reg) +{ + u16 data; + int ret; + + ret = usb_control_msg(udev, + usb_rcvctrlpipe(udev, 0), + 0x1, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0x0, reg, &data, 1, CTRL_TIMEOUT); + PDEBUG(D_USBI, "reg=0x%04x, data=0x%04x", reg, data); + if (ret < 0) + PDEBUG(D_ERR, "read failed"); + return data; +} + +static void ov534_reg_verify_write(struct usb_device *udev, u16 reg, u16 val) +{ + u16 data; + + ov534_reg_write(udev, reg, val); + data = ov534_reg_read(udev, reg); + if (data != val) { + PDEBUG(D_ERR | D_USBO, + "unexpected result from read: 0x%04x != 0x%04x", val, + data); + } +} + +/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. + * (direction and output)? */ +static void ov534_set_led(struct usb_device *udev, int status) +{ + u16 data; + + PDEBUG(D_CONF, "led status: %d", status); + + data = ov534_reg_read(udev, 0x21); + data |= 0x80; + ov534_reg_write(udev, 0x21, data); + + data = ov534_reg_read(udev, 0x23); + if (status) + data |= 0x80; + else + data &= ~(0x80); + + ov534_reg_write(udev, 0x23, data); +} + +static int sccb_check_status(struct usb_device *udev) +{ + u16 data; + int i; + + for (i = 0; i < 5; i++) { + data = ov534_reg_read(udev, OV534_REG_STATUS); + + switch (data & 0xFF) { + case 0x00: + return 1; + case 0x04: + return 0; + case 0x03: + break; + default: + PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5\n", + data, i + 1); + } + } + return 0; +} + +static void sccb_reg_write(struct usb_device *udev, u16 reg, u16 val) +{ + PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%04x", reg, val); + ov534_reg_write(udev, OV534_REG_SUBADDR, reg); + ov534_reg_write(udev, OV534_REG_WRITE, val); + ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_WRITE_3); + + if (!sccb_check_status(udev)) + PDEBUG(D_ERR, "sccb_reg_write failed"); +} + +/* setup method */ +static void ov534_setup(struct usb_device *udev) +{ + ov534_reg_verify_write(udev, 0xe7, 0x3a); + + ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60); + ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60); + ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60); + ov534_reg_write(udev, OV534_REG_ADDRESS, 0x42); + + ov534_reg_verify_write(udev, 0xc2, 0x0c); + ov534_reg_verify_write(udev, 0x88, 0xf8); + ov534_reg_verify_write(udev, 0xc3, 0x69); + ov534_reg_verify_write(udev, 0x89, 0xff); + ov534_reg_verify_write(udev, 0x76, 0x03); + ov534_reg_verify_write(udev, 0x92, 0x01); + ov534_reg_verify_write(udev, 0x93, 0x18); + ov534_reg_verify_write(udev, 0x94, 0x10); + ov534_reg_verify_write(udev, 0x95, 0x10); + ov534_reg_verify_write(udev, 0xe2, 0x00); + ov534_reg_verify_write(udev, 0xe7, 0x3e); + + ov534_reg_write(udev, 0x1c, 0x0a); + ov534_reg_write(udev, 0x1d, 0x22); + ov534_reg_write(udev, 0x1d, 0x06); + + ov534_reg_verify_write(udev, 0x96, 0x00); + + ov534_reg_write(udev, 0x97, 0x20); + ov534_reg_write(udev, 0x97, 0x20); + ov534_reg_write(udev, 0x97, 0x20); + ov534_reg_write(udev, 0x97, 0x0a); + ov534_reg_write(udev, 0x97, 0x3f); + ov534_reg_write(udev, 0x97, 0x4a); + ov534_reg_write(udev, 0x97, 0x20); + ov534_reg_write(udev, 0x97, 0x15); + ov534_reg_write(udev, 0x97, 0x0b); + + ov534_reg_verify_write(udev, 0x8e, 0x40); + ov534_reg_verify_write(udev, 0x1f, 0x81); + ov534_reg_verify_write(udev, 0x34, 0x05); + ov534_reg_verify_write(udev, 0xe3, 0x04); + ov534_reg_verify_write(udev, 0x88, 0x00); + ov534_reg_verify_write(udev, 0x89, 0x00); + ov534_reg_verify_write(udev, 0x76, 0x00); + ov534_reg_verify_write(udev, 0xe7, 0x2e); + ov534_reg_verify_write(udev, 0x31, 0xf9); + ov534_reg_verify_write(udev, 0x25, 0x42); + ov534_reg_verify_write(udev, 0x21, 0xf0); + + ov534_reg_write(udev, 0x1c, 0x00); + ov534_reg_write(udev, 0x1d, 0x40); + ov534_reg_write(udev, 0x1d, 0x02); + ov534_reg_write(udev, 0x1d, 0x00); + ov534_reg_write(udev, 0x1d, 0x02); + ov534_reg_write(udev, 0x1d, 0x57); + ov534_reg_write(udev, 0x1d, 0xff); + + ov534_reg_verify_write(udev, 0x8d, 0x1c); + ov534_reg_verify_write(udev, 0x8e, 0x80); + ov534_reg_verify_write(udev, 0xe5, 0x04); + + ov534_set_led(udev, 1); + + sccb_reg_write(udev, 0x12, 0x80); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x11, 0x01); + + ov534_set_led(udev, 0); + + sccb_reg_write(udev, 0x3d, 0x03); + sccb_reg_write(udev, 0x17, 0x26); + sccb_reg_write(udev, 0x18, 0xa0); + sccb_reg_write(udev, 0x19, 0x07); + sccb_reg_write(udev, 0x1a, 0xf0); + sccb_reg_write(udev, 0x32, 0x00); + sccb_reg_write(udev, 0x29, 0xa0); + sccb_reg_write(udev, 0x2c, 0xf0); + sccb_reg_write(udev, 0x65, 0x20); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x42, 0x7f); + sccb_reg_write(udev, 0x63, 0xe0); + sccb_reg_write(udev, 0x64, 0xff); + sccb_reg_write(udev, 0x66, 0x00); + sccb_reg_write(udev, 0x13, 0xf0); + sccb_reg_write(udev, 0x0d, 0x41); + sccb_reg_write(udev, 0x0f, 0xc5); + sccb_reg_write(udev, 0x14, 0x11); + + ov534_set_led(udev, 1); + + sccb_reg_write(udev, 0x22, 0x7f); + sccb_reg_write(udev, 0x23, 0x03); + sccb_reg_write(udev, 0x24, 0x40); + sccb_reg_write(udev, 0x25, 0x30); + sccb_reg_write(udev, 0x26, 0xa1); + sccb_reg_write(udev, 0x2a, 0x00); + sccb_reg_write(udev, 0x2b, 0x00); + sccb_reg_write(udev, 0x6b, 0xaa); + sccb_reg_write(udev, 0x13, 0xff); + + ov534_set_led(udev, 0); + + sccb_reg_write(udev, 0x90, 0x05); + sccb_reg_write(udev, 0x91, 0x01); + sccb_reg_write(udev, 0x92, 0x03); + sccb_reg_write(udev, 0x93, 0x00); + sccb_reg_write(udev, 0x94, 0x60); + sccb_reg_write(udev, 0x95, 0x3c); + sccb_reg_write(udev, 0x96, 0x24); + sccb_reg_write(udev, 0x97, 0x1e); + sccb_reg_write(udev, 0x98, 0x62); + sccb_reg_write(udev, 0x99, 0x80); + sccb_reg_write(udev, 0x9a, 0x1e); + sccb_reg_write(udev, 0x9b, 0x08); + sccb_reg_write(udev, 0x9c, 0x20); + sccb_reg_write(udev, 0x9e, 0x81); + + ov534_set_led(udev, 1); + + sccb_reg_write(udev, 0xa6, 0x04); + sccb_reg_write(udev, 0x7e, 0x0c); + sccb_reg_write(udev, 0x7f, 0x16); + sccb_reg_write(udev, 0x80, 0x2a); + sccb_reg_write(udev, 0x81, 0x4e); + sccb_reg_write(udev, 0x82, 0x61); + sccb_reg_write(udev, 0x83, 0x6f); + sccb_reg_write(udev, 0x84, 0x7b); + sccb_reg_write(udev, 0x85, 0x86); + sccb_reg_write(udev, 0x86, 0x8e); + sccb_reg_write(udev, 0x87, 0x97); + sccb_reg_write(udev, 0x88, 0xa4); + sccb_reg_write(udev, 0x89, 0xaf); + sccb_reg_write(udev, 0x8a, 0xc5); + sccb_reg_write(udev, 0x8b, 0xd7); + sccb_reg_write(udev, 0x8c, 0xe8); + sccb_reg_write(udev, 0x8d, 0x20); + + sccb_reg_write(udev, 0x0c, 0x90); + + ov534_reg_verify_write(udev, 0xc0, 0x50); + ov534_reg_verify_write(udev, 0xc1, 0x3c); + ov534_reg_verify_write(udev, 0xc2, 0x0c); + + ov534_set_led(udev, 1); + + sccb_reg_write(udev, 0x2b, 0x00); + sccb_reg_write(udev, 0x22, 0x7f); + sccb_reg_write(udev, 0x23, 0x03); + sccb_reg_write(udev, 0x11, 0x01); + sccb_reg_write(udev, 0x0c, 0xd0); + sccb_reg_write(udev, 0x64, 0xff); + sccb_reg_write(udev, 0x0d, 0x41); + + sccb_reg_write(udev, 0x14, 0x41); + sccb_reg_write(udev, 0x0e, 0xcd); + sccb_reg_write(udev, 0xac, 0xbf); + sccb_reg_write(udev, 0x8e, 0x00); + sccb_reg_write(udev, 0x0c, 0xd0); + + ov534_reg_write(udev, 0xe0, 0x09); + ov534_set_led(udev, 0); +} + +/* this function is called at probe time */ +static int sd_config(struct gspca_dev *gspca_dev, + const struct usb_device_id *id) +{ + struct cam *cam; + + cam = &gspca_dev->cam; + + cam->epaddr = 0x01; + cam->cam_mode = vga_mode; + cam->nmodes = ARRAY_SIZE(vga_mode); + + cam->bulk_size = vga_mode[0].sizeimage; + cam->bulk_nurbs = 2; + + PDEBUG(D_PROBE, "bulk_size = %d", cam->bulk_size); + + return 0; +} + +/* this function is called at probe and resume time */ +static int sd_init(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *)gspca_dev; + ov534_setup(gspca_dev->dev); + + if (frame_rate > 0) + sd->frame_rate = frame_rate; + + PDEBUG(D_PROBE, "frame_rate = %d", sd->frame_rate); + + switch (sd->frame_rate) { + case 50: + sccb_reg_write(gspca_dev->dev, 0x11, 0x01); + sccb_check_status(gspca_dev->dev); + sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); + sccb_check_status(gspca_dev->dev); + ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02); + break; + case 40: + sccb_reg_write(gspca_dev->dev, 0x11, 0x02); + sccb_check_status(gspca_dev->dev); + sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1); + sccb_check_status(gspca_dev->dev); + ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04); + break; + case 30: + default: + sccb_reg_write(gspca_dev->dev, 0x11, 0x04); + sccb_check_status(gspca_dev->dev); + sccb_reg_write(gspca_dev->dev, 0x0d, 0x81); + sccb_check_status(gspca_dev->dev); + ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02); + break; + case 15: + sccb_reg_write(gspca_dev->dev, 0x11, 0x03); + sccb_check_status(gspca_dev->dev); + sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); + sccb_check_status(gspca_dev->dev); + ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04); + break; + }; + + return 0; +} + +static int sd_start(struct gspca_dev *gspca_dev) +{ + PDEBUG(D_PROBE, "width = %d, height = %d", + gspca_dev->width, gspca_dev->height); + + gspca_dev->cam.bulk_size = gspca_dev->width * gspca_dev->height * 2; + + /* start streaming data */ + ov534_set_led(gspca_dev->dev, 1); + ov534_reg_write(gspca_dev->dev, 0xe0, 0x00); + + return 0; +} + +static void sd_stopN(struct gspca_dev *gspca_dev) +{ + /* stop streaming data */ + ov534_reg_write(gspca_dev->dev, 0xe0, 0x09); + ov534_set_led(gspca_dev->dev, 0); +} + +static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, + __u8 *data, int len) +{ + /* + * The current camera setup doesn't stream the last pixel, so we set it + * to a dummy value + */ + __u8 last_pixel[4] = { 0, 0, 0, 0 }; + int framesize = gspca_dev->cam.bulk_size; + + if (len == framesize - 4) { + frame = + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); + frame = + gspca_frame_add(gspca_dev, LAST_PACKET, frame, last_pixel, + 4); + } else + PDEBUG(D_PACK, "packet len = %d, framesize = %d", len, + framesize); +} + +/* sub-driver description */ +static const struct sd_desc sd_desc = { + .name = MODULE_NAME, + .ctrls = sd_ctrls, + .nctrls = ARRAY_SIZE(sd_ctrls), + .config = sd_config, + .init = sd_init, + .start = sd_start, + .stopN = sd_stopN, + .pkt_scan = sd_pkt_scan, +}; + +/* -- module initialisation -- */ +static const __devinitdata struct usb_device_id device_table[] = { + {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */ + {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */ + {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */ + {} +}; + +MODULE_DEVICE_TABLE(usb, device_table); + +/* -- device connect -- */ +static int sd_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd), + THIS_MODULE); +} + +static struct usb_driver sd_driver = { + .name = MODULE_NAME, + .id_table = device_table, + .probe = sd_probe, + .disconnect = gspca_disconnect, +#ifdef CONFIG_PM + .suspend = gspca_suspend, + .resume = gspca_resume, +#endif +}; + +/* -- module insert / remove -- */ +static int __init sd_mod_init(void) +{ + if (usb_register(&sd_driver) < 0) + return -1; + PDEBUG(D_PROBE, "registered"); + return 0; +} + +static void __exit sd_mod_exit(void) +{ + usb_deregister(&sd_driver); + PDEBUG(D_PROBE, "deregistered"); +} + +module_init(sd_mod_init); +module_exit(sd_mod_exit); + +module_param(frame_rate, int, 0644); +MODULE_PARM_DESC(frame_rate, "Frame rate (15, 30, 40, 50)"); -- cgit v1.2.3 From 3adba442246a81aad29cf99ef55500379b7a3669 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 3 Dec 2008 14:01:54 -0300 Subject: V4L/DVB (9855): gspca: Simplify frame rate setting and debug in ov534. Signed-off-by: Antonio Ospite Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index a574be09bd4..b26faae8d75 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -48,7 +48,6 @@ static int frame_rate; /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ - __u8 frame_rate; }; /* V4L2 controls supported by the driver */ @@ -358,45 +357,38 @@ static int sd_config(struct gspca_dev *gspca_dev, /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - struct sd *sd = (struct sd *)gspca_dev; - ov534_setup(gspca_dev->dev); + int fr; - if (frame_rate > 0) - sd->frame_rate = frame_rate; + ov534_setup(gspca_dev->dev); - PDEBUG(D_PROBE, "frame_rate = %d", sd->frame_rate); + fr = frame_rate; - switch (sd->frame_rate) { + switch (fr) { case 50: sccb_reg_write(gspca_dev->dev, 0x11, 0x01); - sccb_check_status(gspca_dev->dev); sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); - sccb_check_status(gspca_dev->dev); ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02); break; case 40: sccb_reg_write(gspca_dev->dev, 0x11, 0x02); - sccb_check_status(gspca_dev->dev); sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1); - sccb_check_status(gspca_dev->dev); ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04); break; - case 30: +/* case 30: */ default: + fr = 30; sccb_reg_write(gspca_dev->dev, 0x11, 0x04); - sccb_check_status(gspca_dev->dev); sccb_reg_write(gspca_dev->dev, 0x0d, 0x81); - sccb_check_status(gspca_dev->dev); ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02); break; case 15: sccb_reg_write(gspca_dev->dev, 0x11, 0x03); - sccb_check_status(gspca_dev->dev); sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); - sccb_check_status(gspca_dev->dev); ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04); break; - }; + } + + PDEBUG(D_PROBE, "frame_rate: %d", fr); return 0; } -- cgit v1.2.3 From 9e1e7b068debea80c3ffbde264d0389b8137b589 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 3 Dec 2008 14:10:01 -0300 Subject: V4L/DVB (9856): gspca: Use u8 values for USB control messages in ov534. Signed-off-by: Antonio Ospite Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index b26faae8d75..530f0b71216 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -62,12 +62,12 @@ static struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; -static void ov534_reg_write(struct usb_device *udev, u16 reg, u16 val) +static void ov534_reg_write(struct usb_device *udev, u16 reg, u8 val) { - u16 data = val; + u8 data = val; int ret; - PDEBUG(D_USBO, "reg=0x%04x, val=0%04x", reg, val); + PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val); ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x1, @@ -77,9 +77,9 @@ static void ov534_reg_write(struct usb_device *udev, u16 reg, u16 val) PDEBUG(D_ERR, "write failed"); } -static u16 ov534_reg_read(struct usb_device *udev, u16 reg) +static u8 ov534_reg_read(struct usb_device *udev, u16 reg) { - u16 data; + u8 data; int ret; ret = usb_control_msg(udev, @@ -87,21 +87,21 @@ static u16 ov534_reg_read(struct usb_device *udev, u16 reg) 0x1, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 0x0, reg, &data, 1, CTRL_TIMEOUT); - PDEBUG(D_USBI, "reg=0x%04x, data=0x%04x", reg, data); + PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, data); if (ret < 0) PDEBUG(D_ERR, "read failed"); return data; } -static void ov534_reg_verify_write(struct usb_device *udev, u16 reg, u16 val) +static void ov534_reg_verify_write(struct usb_device *udev, u16 reg, u8 val) { - u16 data; + u8 data; ov534_reg_write(udev, reg, val); data = ov534_reg_read(udev, reg); if (data != val) { PDEBUG(D_ERR | D_USBO, - "unexpected result from read: 0x%04x != 0x%04x", val, + "unexpected result from read: 0x%02x != 0x%02x", val, data); } } @@ -110,7 +110,7 @@ static void ov534_reg_verify_write(struct usb_device *udev, u16 reg, u16 val) * (direction and output)? */ static void ov534_set_led(struct usb_device *udev, int status) { - u16 data; + u8 data; PDEBUG(D_CONF, "led status: %d", status); @@ -129,13 +129,13 @@ static void ov534_set_led(struct usb_device *udev, int status) static int sccb_check_status(struct usb_device *udev) { - u16 data; + u8 data; int i; for (i = 0; i < 5; i++) { data = ov534_reg_read(udev, OV534_REG_STATUS); - switch (data & 0xFF) { + switch (data) { case 0x00: return 1; case 0x04: @@ -150,9 +150,9 @@ static int sccb_check_status(struct usb_device *udev) return 0; } -static void sccb_reg_write(struct usb_device *udev, u16 reg, u16 val) +static void sccb_reg_write(struct usb_device *udev, u16 reg, u8 val) { - PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%04x", reg, val); + PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val); ov534_reg_write(udev, OV534_REG_SUBADDR, reg); ov534_reg_write(udev, OV534_REG_WRITE, val); ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_WRITE_3); -- cgit v1.2.3 From 442a43f50fac8ce13f1b43ca7c5f54af6f91c65e Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Wed, 3 Dec 2008 16:21:08 -0300 Subject: V4L/DVB (9857): gspca: Use smaller chunks for urb buffer in ov534. Signed-off-by: Antonio Ospite Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 46 +++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 16 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 530f0b71216..a1c31bc53a3 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -346,7 +346,14 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - cam->bulk_size = vga_mode[0].sizeimage; + /* + * On some architectures we need contiguous memory for urb buffers, and + * in low memory situation 'sizeimage' can be too much. + * 16kiB chunks should be available even when we are low in memory. + * TODO: CHECK this description: is the problem arch-dependent or more + * general? + */ + cam->bulk_size = 16 * 1024; cam->bulk_nurbs = 2; PDEBUG(D_PROBE, "bulk_size = %d", cam->bulk_size); @@ -395,15 +402,19 @@ static int sd_init(struct gspca_dev *gspca_dev) static int sd_start(struct gspca_dev *gspca_dev) { - PDEBUG(D_PROBE, "width = %d, height = %d", - gspca_dev->width, gspca_dev->height); - - gspca_dev->cam.bulk_size = gspca_dev->width * gspca_dev->height * 2; + struct gspca_frame *frame; /* start streaming data */ ov534_set_led(gspca_dev->dev, 1); ov534_reg_write(gspca_dev->dev, 0xe0, 0x00); + frame = gspca_get_i_frame(gspca_dev); + if (frame == NULL) { + PDEBUG(D_ERR, "NULL frame!"); + return -1; + } + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, gspca_dev->usb_buf, 0); + return 0; } @@ -421,18 +432,21 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, * The current camera setup doesn't stream the last pixel, so we set it * to a dummy value */ - __u8 last_pixel[4] = { 0, 0, 0, 0 }; - int framesize = gspca_dev->cam.bulk_size; - - if (len == framesize - 4) { - frame = - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, len); - frame = - gspca_frame_add(gspca_dev, LAST_PACKET, frame, last_pixel, - 4); + __u8 last[4] = { 0, 0, 0, 0 }; + int framesize = frame->v4l2_buf.length; + + PDEBUG(D_PACK, ""); + PDEBUG(D_PACK, "** packet len = %d, framesize = %d", len, framesize); + PDEBUG(D_PACK, "** frame->data_end - frame->data + len = %d", + frame->data_end - frame->data + len); + + if (frame->data_end - frame->data + len == framesize - 4) { + PDEBUG(D_PACK, " end of frame!"); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, last, 4); + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); } else - PDEBUG(D_PACK, "packet len = %d, framesize = %d", len, - framesize); + gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); } /* sub-driver description */ -- cgit v1.2.3 From 47dfd21fbf4ba303b5fdfad6f4e110e57990803c Mon Sep 17 00:00:00 2001 From: Jim Paris Date: Thu, 4 Dec 2008 04:28:27 -0300 Subject: V4L/DVB (9858): gspca - ov534: Initialization cleanup. Signed-off-by: Jim Paris Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 337 ++++++++++++++++++-------------------- 1 file changed, 159 insertions(+), 178 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index a1c31bc53a3..ee08e30e23c 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -93,19 +93,6 @@ static u8 ov534_reg_read(struct usb_device *udev, u16 reg) return data; } -static void ov534_reg_verify_write(struct usb_device *udev, u16 reg, u8 val) -{ - u8 data; - - ov534_reg_write(udev, reg, val); - data = ov534_reg_read(udev, reg); - if (data != val) { - PDEBUG(D_ERR | D_USBO, - "unexpected result from read: 0x%02x != 0x%02x", val, - data); - } -} - /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. * (direction and output)? */ static void ov534_set_led(struct usb_device *udev, int status) @@ -161,174 +148,168 @@ static void sccb_reg_write(struct usb_device *udev, u16 reg, u8 val) PDEBUG(D_ERR, "sccb_reg_write failed"); } -/* setup method */ -static void ov534_setup(struct usb_device *udev) -{ - ov534_reg_verify_write(udev, 0xe7, 0x3a); - - ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60); - ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60); - ov534_reg_write(udev, OV534_REG_ADDRESS, 0x60); - ov534_reg_write(udev, OV534_REG_ADDRESS, 0x42); - - ov534_reg_verify_write(udev, 0xc2, 0x0c); - ov534_reg_verify_write(udev, 0x88, 0xf8); - ov534_reg_verify_write(udev, 0xc3, 0x69); - ov534_reg_verify_write(udev, 0x89, 0xff); - ov534_reg_verify_write(udev, 0x76, 0x03); - ov534_reg_verify_write(udev, 0x92, 0x01); - ov534_reg_verify_write(udev, 0x93, 0x18); - ov534_reg_verify_write(udev, 0x94, 0x10); - ov534_reg_verify_write(udev, 0x95, 0x10); - ov534_reg_verify_write(udev, 0xe2, 0x00); - ov534_reg_verify_write(udev, 0xe7, 0x3e); - - ov534_reg_write(udev, 0x1c, 0x0a); - ov534_reg_write(udev, 0x1d, 0x22); - ov534_reg_write(udev, 0x1d, 0x06); - - ov534_reg_verify_write(udev, 0x96, 0x00); - - ov534_reg_write(udev, 0x97, 0x20); - ov534_reg_write(udev, 0x97, 0x20); - ov534_reg_write(udev, 0x97, 0x20); - ov534_reg_write(udev, 0x97, 0x0a); - ov534_reg_write(udev, 0x97, 0x3f); - ov534_reg_write(udev, 0x97, 0x4a); - ov534_reg_write(udev, 0x97, 0x20); - ov534_reg_write(udev, 0x97, 0x15); - ov534_reg_write(udev, 0x97, 0x0b); - - ov534_reg_verify_write(udev, 0x8e, 0x40); - ov534_reg_verify_write(udev, 0x1f, 0x81); - ov534_reg_verify_write(udev, 0x34, 0x05); - ov534_reg_verify_write(udev, 0xe3, 0x04); - ov534_reg_verify_write(udev, 0x88, 0x00); - ov534_reg_verify_write(udev, 0x89, 0x00); - ov534_reg_verify_write(udev, 0x76, 0x00); - ov534_reg_verify_write(udev, 0xe7, 0x2e); - ov534_reg_verify_write(udev, 0x31, 0xf9); - ov534_reg_verify_write(udev, 0x25, 0x42); - ov534_reg_verify_write(udev, 0x21, 0xf0); - - ov534_reg_write(udev, 0x1c, 0x00); - ov534_reg_write(udev, 0x1d, 0x40); - ov534_reg_write(udev, 0x1d, 0x02); - ov534_reg_write(udev, 0x1d, 0x00); - ov534_reg_write(udev, 0x1d, 0x02); - ov534_reg_write(udev, 0x1d, 0x57); - ov534_reg_write(udev, 0x1d, 0xff); - - ov534_reg_verify_write(udev, 0x8d, 0x1c); - ov534_reg_verify_write(udev, 0x8e, 0x80); - ov534_reg_verify_write(udev, 0xe5, 0x04); - - ov534_set_led(udev, 1); - - sccb_reg_write(udev, 0x12, 0x80); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x11, 0x01); - - ov534_set_led(udev, 0); - - sccb_reg_write(udev, 0x3d, 0x03); - sccb_reg_write(udev, 0x17, 0x26); - sccb_reg_write(udev, 0x18, 0xa0); - sccb_reg_write(udev, 0x19, 0x07); - sccb_reg_write(udev, 0x1a, 0xf0); - sccb_reg_write(udev, 0x32, 0x00); - sccb_reg_write(udev, 0x29, 0xa0); - sccb_reg_write(udev, 0x2c, 0xf0); - sccb_reg_write(udev, 0x65, 0x20); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x42, 0x7f); - sccb_reg_write(udev, 0x63, 0xe0); - sccb_reg_write(udev, 0x64, 0xff); - sccb_reg_write(udev, 0x66, 0x00); - sccb_reg_write(udev, 0x13, 0xf0); - sccb_reg_write(udev, 0x0d, 0x41); - sccb_reg_write(udev, 0x0f, 0xc5); - sccb_reg_write(udev, 0x14, 0x11); - - ov534_set_led(udev, 1); - - sccb_reg_write(udev, 0x22, 0x7f); - sccb_reg_write(udev, 0x23, 0x03); - sccb_reg_write(udev, 0x24, 0x40); - sccb_reg_write(udev, 0x25, 0x30); - sccb_reg_write(udev, 0x26, 0xa1); - sccb_reg_write(udev, 0x2a, 0x00); - sccb_reg_write(udev, 0x2b, 0x00); - sccb_reg_write(udev, 0x6b, 0xaa); - sccb_reg_write(udev, 0x13, 0xff); +static const __u8 ov534_reg_initdata[][2] = { + { 0xe7, 0x3a }, + + { OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */ + + { 0xc2, 0x0c }, + { 0x88, 0xf8 }, + { 0xc3, 0x69 }, + { 0x89, 0xff }, + { 0x76, 0x03 }, + { 0x92, 0x01 }, + { 0x93, 0x18 }, + { 0x94, 0x10 }, + { 0x95, 0x10 }, + { 0xe2, 0x00 }, + { 0xe7, 0x3e }, + + { 0x1c, 0x0a }, + { 0x1d, 0x22 }, + { 0x1d, 0x06 }, + + { 0x96, 0x00 }, + + { 0x97, 0x20 }, + { 0x97, 0x20 }, + { 0x97, 0x20 }, + { 0x97, 0x0a }, + { 0x97, 0x3f }, + { 0x97, 0x4a }, + { 0x97, 0x20 }, + { 0x97, 0x15 }, + { 0x97, 0x0b }, + + { 0x8e, 0x40 }, + { 0x1f, 0x81 }, + { 0x34, 0x05 }, + { 0xe3, 0x04 }, + { 0x88, 0x00 }, + { 0x89, 0x00 }, + { 0x76, 0x00 }, + { 0xe7, 0x2e }, + { 0x31, 0xf9 }, + { 0x25, 0x42 }, + { 0x21, 0xf0 }, + + { 0x1c, 0x00 }, + { 0x1d, 0x40 }, + { 0x1d, 0x02 }, + { 0x1d, 0x00 }, + { 0x1d, 0x02 }, + { 0x1d, 0x57 }, + { 0x1d, 0xff }, + + { 0x8d, 0x1c }, + { 0x8e, 0x80 }, + { 0xe5, 0x04 }, + + { 0xc0, 0x50 }, + { 0xc1, 0x3c }, + { 0xc2, 0x0c }, +}; - ov534_set_led(udev, 0); +static const __u8 ov772x_reg_initdata[][2] = { + { 0x12, 0x80 }, + { 0x11, 0x01 }, + + { 0x3d, 0x03 }, + { 0x17, 0x26 }, + { 0x18, 0xa0 }, + { 0x19, 0x07 }, + { 0x1a, 0xf0 }, + { 0x32, 0x00 }, + { 0x29, 0xa0 }, + { 0x2c, 0xf0 }, + { 0x65, 0x20 }, + { 0x11, 0x01 }, + { 0x42, 0x7f }, + { 0x63, 0xe0 }, + { 0x64, 0xff }, + { 0x66, 0x00 }, + { 0x13, 0xf0 }, + { 0x0d, 0x41 }, + { 0x0f, 0xc5 }, + { 0x14, 0x11 }, + + { 0x22, 0x7f }, + { 0x23, 0x03 }, + { 0x24, 0x40 }, + { 0x25, 0x30 }, + { 0x26, 0xa1 }, + { 0x2a, 0x00 }, + { 0x2b, 0x00 }, + { 0x6b, 0xaa }, + { 0x13, 0xff }, + + { 0x90, 0x05 }, + { 0x91, 0x01 }, + { 0x92, 0x03 }, + { 0x93, 0x00 }, + { 0x94, 0x60 }, + { 0x95, 0x3c }, + { 0x96, 0x24 }, + { 0x97, 0x1e }, + { 0x98, 0x62 }, + { 0x99, 0x80 }, + { 0x9a, 0x1e }, + { 0x9b, 0x08 }, + { 0x9c, 0x20 }, + { 0x9e, 0x81 }, + + { 0xa6, 0x04 }, + { 0x7e, 0x0c }, + { 0x7f, 0x16 }, + { 0x80, 0x2a }, + { 0x81, 0x4e }, + { 0x82, 0x61 }, + { 0x83, 0x6f }, + { 0x84, 0x7b }, + { 0x85, 0x86 }, + { 0x86, 0x8e }, + { 0x87, 0x97 }, + { 0x88, 0xa4 }, + { 0x89, 0xaf }, + { 0x8a, 0xc5 }, + { 0x8b, 0xd7 }, + { 0x8c, 0xe8 }, + { 0x8d, 0x20 }, + + { 0x0c, 0x90 }, + + { 0x2b, 0x00 }, + { 0x22, 0x7f }, + { 0x23, 0x03 }, + { 0x11, 0x01 }, + { 0x0c, 0xd0 }, + { 0x64, 0xff }, + { 0x0d, 0x41 }, + + { 0x14, 0x41 }, + { 0x0e, 0xcd }, + { 0xac, 0xbf }, + { 0x8e, 0x00 }, + { 0x0c, 0xd0 } +}; - sccb_reg_write(udev, 0x90, 0x05); - sccb_reg_write(udev, 0x91, 0x01); - sccb_reg_write(udev, 0x92, 0x03); - sccb_reg_write(udev, 0x93, 0x00); - sccb_reg_write(udev, 0x94, 0x60); - sccb_reg_write(udev, 0x95, 0x3c); - sccb_reg_write(udev, 0x96, 0x24); - sccb_reg_write(udev, 0x97, 0x1e); - sccb_reg_write(udev, 0x98, 0x62); - sccb_reg_write(udev, 0x99, 0x80); - sccb_reg_write(udev, 0x9a, 0x1e); - sccb_reg_write(udev, 0x9b, 0x08); - sccb_reg_write(udev, 0x9c, 0x20); - sccb_reg_write(udev, 0x9e, 0x81); - ov534_set_led(udev, 1); +/* setup method */ +static void ov534_setup(struct usb_device *udev) +{ + int i; - sccb_reg_write(udev, 0xa6, 0x04); - sccb_reg_write(udev, 0x7e, 0x0c); - sccb_reg_write(udev, 0x7f, 0x16); - sccb_reg_write(udev, 0x80, 0x2a); - sccb_reg_write(udev, 0x81, 0x4e); - sccb_reg_write(udev, 0x82, 0x61); - sccb_reg_write(udev, 0x83, 0x6f); - sccb_reg_write(udev, 0x84, 0x7b); - sccb_reg_write(udev, 0x85, 0x86); - sccb_reg_write(udev, 0x86, 0x8e); - sccb_reg_write(udev, 0x87, 0x97); - sccb_reg_write(udev, 0x88, 0xa4); - sccb_reg_write(udev, 0x89, 0xaf); - sccb_reg_write(udev, 0x8a, 0xc5); - sccb_reg_write(udev, 0x8b, 0xd7); - sccb_reg_write(udev, 0x8c, 0xe8); - sccb_reg_write(udev, 0x8d, 0x20); - - sccb_reg_write(udev, 0x0c, 0x90); - - ov534_reg_verify_write(udev, 0xc0, 0x50); - ov534_reg_verify_write(udev, 0xc1, 0x3c); - ov534_reg_verify_write(udev, 0xc2, 0x0c); + /* Initialize bridge chip */ + for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++) + ov534_reg_write(udev, ov534_reg_initdata[i][0], + ov534_reg_initdata[i][1]); ov534_set_led(udev, 1); - sccb_reg_write(udev, 0x2b, 0x00); - sccb_reg_write(udev, 0x22, 0x7f); - sccb_reg_write(udev, 0x23, 0x03); - sccb_reg_write(udev, 0x11, 0x01); - sccb_reg_write(udev, 0x0c, 0xd0); - sccb_reg_write(udev, 0x64, 0xff); - sccb_reg_write(udev, 0x0d, 0x41); - - sccb_reg_write(udev, 0x14, 0x41); - sccb_reg_write(udev, 0x0e, 0xcd); - sccb_reg_write(udev, 0xac, 0xbf); - sccb_reg_write(udev, 0x8e, 0x00); - sccb_reg_write(udev, 0x0c, 0xd0); + /* Initialize sensor */ + for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++) + sccb_reg_write(udev, ov772x_reg_initdata[i][0], + ov772x_reg_initdata[i][1]); ov534_reg_write(udev, 0xe0, 0x09); ov534_set_led(udev, 0); @@ -374,24 +355,24 @@ static int sd_init(struct gspca_dev *gspca_dev) case 50: sccb_reg_write(gspca_dev->dev, 0x11, 0x01); sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); - ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02); + ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); break; case 40: sccb_reg_write(gspca_dev->dev, 0x11, 0x02); sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1); - ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04); + ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); break; /* case 30: */ default: fr = 30; sccb_reg_write(gspca_dev->dev, 0x11, 0x04); sccb_reg_write(gspca_dev->dev, 0x0d, 0x81); - ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x02); + ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); break; case 15: sccb_reg_write(gspca_dev->dev, 0x11, 0x03); sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); - ov534_reg_verify_write(gspca_dev->dev, 0xe5, 0x04); + ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); break; } -- cgit v1.2.3 From 5ea9c4def8154a5be836dd31cbd97f49fd34ea8f Mon Sep 17 00:00:00 2001 From: Jim Paris Date: Thu, 4 Dec 2008 04:36:14 -0300 Subject: V4L/DVB (9859): gspca - ov534: Fix frame size so we don't miss the last pixel. The frame size is too small, so we lose the last YUYV pixel. Fix the setup and remove the last_pixel hack. Signed-off-by: Jim Paris Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index ee08e30e23c..79bb6241d27 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -197,9 +197,9 @@ static const __u8 ov534_reg_initdata[][2] = { { 0x1d, 0x40 }, { 0x1d, 0x02 }, { 0x1d, 0x00 }, - { 0x1d, 0x02 }, - { 0x1d, 0x57 }, - { 0x1d, 0xff }, + { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ + { 0x1d, 0x58 }, /* frame size */ + { 0x1d, 0x00 }, /* frame size */ { 0x8d, 0x1c }, { 0x8e, 0x80 }, @@ -409,25 +409,15 @@ static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, __u8 *data, int len) { - /* - * The current camera setup doesn't stream the last pixel, so we set it - * to a dummy value - */ - __u8 last[4] = { 0, 0, 0, 0 }; int framesize = frame->v4l2_buf.length; - PDEBUG(D_PACK, ""); - PDEBUG(D_PACK, "** packet len = %d, framesize = %d", len, framesize); - PDEBUG(D_PACK, "** frame->data_end - frame->data + len = %d", - frame->data_end - frame->data + len); - - if (frame->data_end - frame->data + len == framesize - 4) { - PDEBUG(D_PACK, " end of frame!"); - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, last, 4); - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0); + if (len == framesize) { + frame = gspca_frame_add(gspca_dev, FIRST_PACKET, frame, + data, len); + frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); } else - gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len); + PDEBUG(D_PACK, "packet len = %d, framesize = %d", len, + framesize); } /* sub-driver description */ -- cgit v1.2.3 From fb139224aea3b56237542690516eb9d6d671b135 Mon Sep 17 00:00:00 2001 From: Jim Paris Date: Thu, 4 Dec 2008 04:52:40 -0300 Subject: V4L/DVB (9860): gspca - ov534: Frame transfer improvements. The indirect registers at 0x1c/0x1d control frame settings. If we leave the values at 0x0a and 0x0b at their reset-time defaults, frame data from the camera matches the UVC payload format. This lets us better reassemble the data into frames and know when data was lost. This also lets us relax the bulk_size requirement from 600K to 2K, which should help systems on with limited RAM (like the PS3). Signed-off-by: Jim Paris Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 103 ++++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 32 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 79bb6241d27..e02c8f70f81 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -165,10 +165,6 @@ static const __u8 ov534_reg_initdata[][2] = { { 0xe2, 0x00 }, { 0xe7, 0x3e }, - { 0x1c, 0x0a }, - { 0x1d, 0x22 }, - { 0x1d, 0x06 }, - { 0x96, 0x00 }, { 0x97, 0x20 }, @@ -327,18 +323,9 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - /* - * On some architectures we need contiguous memory for urb buffers, and - * in low memory situation 'sizeimage' can be too much. - * 16kiB chunks should be available even when we are low in memory. - * TODO: CHECK this description: is the problem arch-dependent or more - * general? - */ - cam->bulk_size = 16 * 1024; + cam->bulk_size = 2048; cam->bulk_nurbs = 2; - PDEBUG(D_PROBE, "bulk_size = %d", cam->bulk_size); - return 0; } @@ -383,19 +370,10 @@ static int sd_init(struct gspca_dev *gspca_dev) static int sd_start(struct gspca_dev *gspca_dev) { - struct gspca_frame *frame; - /* start streaming data */ ov534_set_led(gspca_dev->dev, 1); ov534_reg_write(gspca_dev->dev, 0xe0, 0x00); - frame = gspca_get_i_frame(gspca_dev); - if (frame == NULL) { - PDEBUG(D_ERR, "NULL frame!"); - return -1; - } - gspca_frame_add(gspca_dev, FIRST_PACKET, frame, gspca_dev->usb_buf, 0); - return 0; } @@ -406,18 +384,79 @@ static void sd_stopN(struct gspca_dev *gspca_dev) ov534_set_led(gspca_dev->dev, 0); } +/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ +#define UVC_STREAM_EOH (1 << 7) +#define UVC_STREAM_ERR (1 << 6) +#define UVC_STREAM_STI (1 << 5) +#define UVC_STREAM_RES (1 << 4) +#define UVC_STREAM_SCR (1 << 3) +#define UVC_STREAM_PTS (1 << 2) +#define UVC_STREAM_EOF (1 << 1) +#define UVC_STREAM_FID (1 << 0) + static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, __u8 *data, int len) { - int framesize = frame->v4l2_buf.length; - - if (len == framesize) { - frame = gspca_frame_add(gspca_dev, FIRST_PACKET, frame, - data, len); - frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0); - } else - PDEBUG(D_PACK, "packet len = %d, framesize = %d", len, - framesize); + static __u32 last_pts; + __u32 this_pts; + static int last_fid; + int this_fid; + + /* Payloads are prefixed with a the UVC-style header. We + consider a frame to start when the FID toggles, or the PTS + changes. A frame ends when EOF is set, and we've received + the correct number of bytes. */ + + /* Verify UVC header. Header length is always 12 */ + if (data[0] != 12 || len < 12) { + PDEBUG(D_PACK, "bad header"); + goto discard; + } + + /* Check errors */ + if (data[1] & UVC_STREAM_ERR) { + PDEBUG(D_PACK, "payload error"); + goto discard; + } + + /* Extract PTS and FID */ + if (!(data[1] & UVC_STREAM_PTS)) { + PDEBUG(D_PACK, "PTS not present"); + goto discard; + } + this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2]; + this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0; + + /* If PTS or FID has changed, start a new frame. */ + if (this_pts != last_pts || this_fid != last_fid) { + gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); + last_pts = this_pts; + last_fid = this_fid; + } + + /* Add the data from this payload */ + gspca_frame_add(gspca_dev, INTER_PACKET, frame, + data + 12, len - 12); + + /* If this packet is marked as EOF, end the frame */ + if (data[1] & UVC_STREAM_EOF) { + last_pts = 0; + + if ((frame->data_end - frame->data) != + (gspca_dev->width * gspca_dev->height * 2)) { + PDEBUG(D_PACK, "short frame"); + goto discard; + } + + gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0); + } + + /* Done */ + return; + +discard: + /* Discard data until a new frame starts. */ + gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); } /* sub-driver description */ -- cgit v1.2.3 From 8c252050146fc6f54e9bf5ef8276b25f3dd67a1c Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Thu, 4 Dec 2008 05:06:08 -0300 Subject: V4L/DVB (9861): gspca - ov534: Accept many simultaneous webcams. This patch moves the last fid and pts from static to the sd structure. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index e02c8f70f81..28a7982792b 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -48,6 +48,8 @@ static int frame_rate; /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ + __u32 last_fid; + __u32 last_pts; }; /* V4L2 controls supported by the driver */ @@ -397,9 +399,8 @@ static void sd_stopN(struct gspca_dev *gspca_dev) static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, __u8 *data, int len) { - static __u32 last_pts; + struct sd *sd = (struct sd *) gspca_dev; __u32 this_pts; - static int last_fid; int this_fid; /* Payloads are prefixed with a the UVC-style header. We @@ -428,10 +429,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0; /* If PTS or FID has changed, start a new frame. */ - if (this_pts != last_pts || this_fid != last_fid) { + if (this_pts != sd->last_pts || this_fid != sd->last_fid) { gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0); - last_pts = this_pts; - last_fid = this_fid; + sd->last_pts = this_pts; + sd->last_fid = this_fid; } /* Add the data from this payload */ @@ -440,7 +441,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, /* If this packet is marked as EOF, end the frame */ if (data[1] & UVC_STREAM_EOF) { - last_pts = 0; + sd->last_pts = 0; if ((frame->data_end - frame->data) != (gspca_dev->width * gspca_dev->height * 2)) { -- cgit v1.2.3 From 0f7a50b29dd9c8603d5ce15c11fd1a1d731e1a6d Mon Sep 17 00:00:00 2001 From: Jim Paris Date: Wed, 10 Dec 2008 05:45:14 -0300 Subject: V4L/DVB (9873): gspca - ov534: Improve payload handling. Frame data in bulk transfers is separated into 2048-byte payloads. Each payload has its own header. Signed-off-by: Jim Paris Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 28a7982792b..74bb7962e11 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -1,6 +1,7 @@ /* * ov534/ov772x gspca driver * Copyright (C) 2008 Antonio Ospite + * Copyright (C) 2008 Jim Paris * * Based on a prototype written by Mark Ferrell * USB protocol reverse engineered by Jim Paris @@ -193,8 +194,8 @@ static const __u8 ov534_reg_initdata[][2] = { { 0x1c, 0x00 }, { 0x1d, 0x40 }, - { 0x1d, 0x02 }, - { 0x1d, 0x00 }, + { 0x1d, 0x02 }, /* payload size 0x0200 * 4 = 2048 bytes */ + { 0x1d, 0x00 }, /* payload size */ { 0x1d, 0x02 }, /* frame size 0x025800 * 4 = 614400 */ { 0x1d, 0x58 }, /* frame size */ { 0x1d, 0x00 }, /* frame size */ @@ -325,7 +326,7 @@ static int sd_config(struct gspca_dev *gspca_dev, cam->cam_mode = vga_mode; cam->nmodes = ARRAY_SIZE(vga_mode); - cam->bulk_size = 2048; + cam->bulk_size = 16384; cam->bulk_nurbs = 2; return 0; @@ -402,6 +403,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, struct sd *sd = (struct sd *) gspca_dev; __u32 this_pts; int this_fid; + int remaining_len = len; + __u8 *next_data = data; + +scan_next: + if (remaining_len <= 0) + return; + + data = next_data; + len = min(remaining_len, 2048); + remaining_len -= len; + next_data += len; /* Payloads are prefixed with a the UVC-style header. We consider a frame to start when the FID toggles, or the PTS @@ -452,12 +464,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame, gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0); } - /* Done */ - return; + /* Done this payload */ + goto scan_next; discard: /* Discard data until a new frame starts. */ gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0); + goto scan_next; } /* sub-driver description */ -- cgit v1.2.3 From c06eb61941459b1981817fb675d0104ac0cd6df8 Mon Sep 17 00:00:00 2001 From: Jim Paris Date: Wed, 10 Dec 2008 05:47:44 -0300 Subject: V4L/DVB (9874): gspca - ov534: Explicitly initialize frame format. Set frame format registers 0x0a and 0x0b to explicit values rather than relying on reset-time defaults. Signed-off-by: Jim Paris Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 74bb7962e11..66a7bd2f676 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -200,6 +200,10 @@ static const __u8 ov534_reg_initdata[][2] = { { 0x1d, 0x58 }, /* frame size */ { 0x1d, 0x00 }, /* frame size */ + { 0x1c, 0x0a }, + { 0x1d, 0x08 }, /* turn on UVC header */ + { 0x1d, 0x0e }, /* .. */ + { 0x8d, 0x1c }, { 0x8e, 0x80 }, { 0xe5, 0x04 }, -- cgit v1.2.3 From 11d9f25da89523d19dba3608d51a86af2954fc0d Mon Sep 17 00:00:00 2001 From: Jim Paris Date: Wed, 10 Dec 2008 06:06:20 -0300 Subject: V4L/DVB (9877): gspca - ov534: Add framerate support. Add support for getting and setting framerate via v4l2 controls, rather than setting a fixed value at module insertion. Signed-off-by: Jim Paris Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 115 ++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 37 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 66a7bd2f676..cd5c302d699 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -43,14 +43,12 @@ MODULE_AUTHOR("Antonio Ospite "); MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); MODULE_LICENSE("GPL"); -/* global parameters */ -static int frame_rate; - /* specific webcam descriptor */ struct sd { struct gspca_dev gspca_dev; /* !! must be the first item */ __u32 last_fid; __u32 last_pts; + int frame_rate; }; /* V4L2 controls supported by the driver */ @@ -296,6 +294,40 @@ static const __u8 ov772x_reg_initdata[][2] = { { 0x0c, 0xd0 } }; +/* set framerate */ +static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) +{ + struct sd *sd = (struct sd *) gspca_dev; + int fr = sd->frame_rate; + + switch (fr) { + case 50: + sccb_reg_write(gspca_dev->dev, 0x11, 0x01); + sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); + ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); + break; + case 40: + sccb_reg_write(gspca_dev->dev, 0x11, 0x02); + sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1); + ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); + break; +/* case 30: */ + default: + fr = 30; + sccb_reg_write(gspca_dev->dev, 0x11, 0x04); + sccb_reg_write(gspca_dev->dev, 0x0d, 0x81); + ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); + break; + case 15: + sccb_reg_write(gspca_dev->dev, 0x11, 0x03); + sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); + ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); + break; + } + + sd->frame_rate = fr; + PDEBUG(D_PROBE, "frame_rate: %d", fr); +} /* setup method */ static void ov534_setup(struct usb_device *udev) @@ -339,38 +371,8 @@ static int sd_config(struct gspca_dev *gspca_dev, /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - int fr; - ov534_setup(gspca_dev->dev); - - fr = frame_rate; - - switch (fr) { - case 50: - sccb_reg_write(gspca_dev->dev, 0x11, 0x01); - sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); - ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); - break; - case 40: - sccb_reg_write(gspca_dev->dev, 0x11, 0x02); - sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1); - ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); - break; -/* case 30: */ - default: - fr = 30; - sccb_reg_write(gspca_dev->dev, 0x11, 0x04); - sccb_reg_write(gspca_dev->dev, 0x0d, 0x81); - ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); - break; - case 15: - sccb_reg_write(gspca_dev->dev, 0x11, 0x03); - sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); - ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); - break; - } - - PDEBUG(D_PROBE, "frame_rate: %d", fr); + ov534_set_frame_rate(gspca_dev); return 0; } @@ -477,6 +479,46 @@ discard: goto scan_next; } +/* get stream parameters (framerate) */ +int sd_get_streamparm(struct gspca_dev *gspca_dev, + struct v4l2_streamparm *parm) +{ + struct v4l2_captureparm *cp = &parm->parm.capture; + struct v4l2_fract *tpf = &cp->timeperframe; + struct sd *sd = (struct sd *) gspca_dev; + + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + cp->capability |= V4L2_CAP_TIMEPERFRAME; + tpf->numerator = 1; + tpf->denominator = sd->frame_rate; + + return 0; +} + +/* set stream parameters (framerate) */ +int sd_set_streamparm(struct gspca_dev *gspca_dev, + struct v4l2_streamparm *parm) +{ + struct v4l2_captureparm *cp = &parm->parm.capture; + struct v4l2_fract *tpf = &cp->timeperframe; + struct sd *sd = (struct sd *) gspca_dev; + + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + /* Set requested framerate */ + sd->frame_rate = tpf->denominator / tpf->numerator; + ov534_set_frame_rate(gspca_dev); + + /* Return the actual framerate */ + tpf->numerator = 1; + tpf->denominator = sd->frame_rate; + + return 0; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -487,6 +529,8 @@ static const struct sd_desc sd_desc = { .start = sd_start, .stopN = sd_stopN, .pkt_scan = sd_pkt_scan, + .get_streamparm = sd_get_streamparm, + .set_streamparm = sd_set_streamparm, }; /* -- module initialisation -- */ @@ -534,6 +578,3 @@ static void __exit sd_mod_exit(void) module_init(sd_mod_init); module_exit(sd_mod_exit); - -module_param(frame_rate, int, 0644); -MODULE_PARM_DESC(frame_rate, "Frame rate (15, 30, 40, 50)"); -- cgit v1.2.3 From 15e3209a30c1b4dd52e937388fb3969d06dc33ec Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 14 Dec 2008 05:41:56 -0300 Subject: V4L/DVB (9882): gspca - ov534: Fix typo. Signed-off-by: Antonio Ospite Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index cd5c302d699..edcd92557c8 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -421,7 +421,7 @@ scan_next: remaining_len -= len; next_data += len; - /* Payloads are prefixed with a the UVC-style header. We + /* Payloads are prefixed with a UVC-style header. We consider a frame to start when the FID toggles, or the PTS changes. A frame ends when EOF is set, and we've received the correct number of bytes. */ -- cgit v1.2.3 From e6e483782772994fe42ef9e8b5b4d6f6376b3d45 Mon Sep 17 00:00:00 2001 From: Antonio Ospite Date: Sun, 14 Dec 2008 05:48:07 -0300 Subject: V4L/DVB (9883): gspca - ov534: Show sensor ID. The original version of sccb_read_reg() is from Jim Paris. NOTE: as it is now reading sensor ID won't work for sensors on different i2c slave address. Signed-off-by: Antonio Ospite Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index edcd92557c8..ad97b0be5f3 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -149,6 +149,20 @@ static void sccb_reg_write(struct usb_device *udev, u16 reg, u8 val) PDEBUG(D_ERR, "sccb_reg_write failed"); } +static u8 sccb_reg_read(struct usb_device *udev, u16 reg) +{ + ov534_reg_write(udev, OV534_REG_SUBADDR, reg); + ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_WRITE_2); + if (!sccb_check_status(udev)) + PDEBUG(D_ERR, "sccb_reg_read failed 1"); + + ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_READ_2); + if (!sccb_check_status(udev)) + PDEBUG(D_ERR, "sccb_reg_read failed 2"); + + return ov534_reg_read(udev, OV534_REG_READ); +} + static const __u8 ov534_reg_initdata[][2] = { { 0xe7, 0x3a }, @@ -339,6 +353,9 @@ static void ov534_setup(struct usb_device *udev) ov534_reg_write(udev, ov534_reg_initdata[i][0], ov534_reg_initdata[i][1]); + PDEBUG(D_PROBE, "sensor is ov%02x%02x", + sccb_reg_read(udev, 0x0a), sccb_reg_read(udev, 0x0b)); + ov534_set_led(udev, 1); /* Initialize sensor */ -- cgit v1.2.3 From 1dc87b6e2fb29777f921c733d78df7eea31e6cc8 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 14 Dec 2008 05:50:24 -0300 Subject: V4L/DVB (9884): gspca - ov534: Fix a warning when compilation without GSPCA_DEBUG. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index ad97b0be5f3..7332947cb2c 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -149,6 +149,7 @@ static void sccb_reg_write(struct usb_device *udev, u16 reg, u8 val) PDEBUG(D_ERR, "sccb_reg_write failed"); } +#ifdef GSPCA_DEBUG static u8 sccb_reg_read(struct usb_device *udev, u16 reg) { ov534_reg_write(udev, OV534_REG_SUBADDR, reg); @@ -162,6 +163,7 @@ static u8 sccb_reg_read(struct usb_device *udev, u16 reg) return ov534_reg_read(udev, OV534_REG_READ); } +#endif static const __u8 ov534_reg_initdata[][2] = { { 0xe7, 0x3a }, -- cgit v1.2.3 From 5c1a15a149504496b25ee3f681893cbe1647ba39 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 21 Dec 2008 15:02:54 -0300 Subject: V4L/DVB (9995): gspca - ov534 and m5602: Set static some functions/variables. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 7332947cb2c..0eeb417d462 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -499,8 +499,8 @@ discard: } /* get stream parameters (framerate) */ -int sd_get_streamparm(struct gspca_dev *gspca_dev, - struct v4l2_streamparm *parm) +static int sd_get_streamparm(struct gspca_dev *gspca_dev, + struct v4l2_streamparm *parm) { struct v4l2_captureparm *cp = &parm->parm.capture; struct v4l2_fract *tpf = &cp->timeperframe; @@ -517,8 +517,8 @@ int sd_get_streamparm(struct gspca_dev *gspca_dev, } /* set stream parameters (framerate) */ -int sd_set_streamparm(struct gspca_dev *gspca_dev, - struct v4l2_streamparm *parm) +static int sd_set_streamparm(struct gspca_dev *gspca_dev, + struct v4l2_streamparm *parm) { struct v4l2_captureparm *cp = &parm->parm.capture; struct v4l2_fract *tpf = &cp->timeperframe; -- cgit v1.2.3 From f367b85d9a0bda04c31c5c5598dba758efc6658e Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Sun, 28 Dec 2008 06:51:37 -0300 Subject: V4L/DVB (10045): gspca - ov534: Remove empty line in trace. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 0eeb417d462..d5c74d65ce8 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -131,7 +131,7 @@ static int sccb_check_status(struct usb_device *udev) case 0x03: break; default: - PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5\n", + PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5", data, i + 1); } } -- cgit v1.2.3 From 15f64864e392612b230bc71d84e4537b80c607b1 Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 29 Dec 2008 06:19:43 -0300 Subject: V4L/DVB (10046): gspca - ov534: Use the gspca usb buf for usb control messages. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 104 +++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 51 deletions(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index d5c74d65ce8..406f6bc12d9 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -63,65 +63,66 @@ static struct v4l2_pix_format vga_mode[] = { .priv = 0}, }; -static void ov534_reg_write(struct usb_device *udev, u16 reg, u8 val) +static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) { - u8 data = val; + struct usb_device *udev = gspca_dev->dev; int ret; PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val); + gspca_dev->usb_buf[0] = val; ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x1, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0, reg, &data, 1, CTRL_TIMEOUT); + 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); if (ret < 0) PDEBUG(D_ERR, "write failed"); } -static u8 ov534_reg_read(struct usb_device *udev, u16 reg) +static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg) { - u8 data; + struct usb_device *udev = gspca_dev->dev; int ret; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x1, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0, reg, &data, 1, CTRL_TIMEOUT); - PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, data); + 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT); + PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]); if (ret < 0) PDEBUG(D_ERR, "read failed"); - return data; + return gspca_dev->usb_buf[0]; } /* Two bits control LED: 0x21 bit 7 and 0x23 bit 7. * (direction and output)? */ -static void ov534_set_led(struct usb_device *udev, int status) +static void ov534_set_led(struct gspca_dev *gspca_dev, int status) { u8 data; PDEBUG(D_CONF, "led status: %d", status); - data = ov534_reg_read(udev, 0x21); + data = ov534_reg_read(gspca_dev, 0x21); data |= 0x80; - ov534_reg_write(udev, 0x21, data); + ov534_reg_write(gspca_dev, 0x21, data); - data = ov534_reg_read(udev, 0x23); + data = ov534_reg_read(gspca_dev, 0x23); if (status) data |= 0x80; else data &= ~(0x80); - ov534_reg_write(udev, 0x23, data); + ov534_reg_write(gspca_dev, 0x23, data); } -static int sccb_check_status(struct usb_device *udev) +static int sccb_check_status(struct gspca_dev *gspca_dev) { u8 data; int i; for (i = 0; i < 5; i++) { - data = ov534_reg_read(udev, OV534_REG_STATUS); + data = ov534_reg_read(gspca_dev, OV534_REG_STATUS); switch (data) { case 0x00: @@ -138,30 +139,30 @@ static int sccb_check_status(struct usb_device *udev) return 0; } -static void sccb_reg_write(struct usb_device *udev, u16 reg, u8 val) +static void sccb_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val) { PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val); - ov534_reg_write(udev, OV534_REG_SUBADDR, reg); - ov534_reg_write(udev, OV534_REG_WRITE, val); - ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_WRITE_3); + ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); + ov534_reg_write(gspca_dev, OV534_REG_WRITE, val); + ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3); - if (!sccb_check_status(udev)) + if (!sccb_check_status(gspca_dev)) PDEBUG(D_ERR, "sccb_reg_write failed"); } #ifdef GSPCA_DEBUG -static u8 sccb_reg_read(struct usb_device *udev, u16 reg) +static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg) { - ov534_reg_write(udev, OV534_REG_SUBADDR, reg); - ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_WRITE_2); - if (!sccb_check_status(udev)) + ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg); + ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2); + if (!sccb_check_status(gspca_dev)) PDEBUG(D_ERR, "sccb_reg_read failed 1"); - ov534_reg_write(udev, OV534_REG_OPERATION, OV534_OP_READ_2); - if (!sccb_check_status(udev)) + ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2); + if (!sccb_check_status(gspca_dev)) PDEBUG(D_ERR, "sccb_reg_read failed 2"); - return ov534_reg_read(udev, OV534_REG_READ); + return ov534_reg_read(gspca_dev, OV534_REG_READ); } #endif @@ -318,26 +319,26 @@ static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) switch (fr) { case 50: - sccb_reg_write(gspca_dev->dev, 0x11, 0x01); - sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); - ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); + sccb_reg_write(gspca_dev, 0x11, 0x01); + sccb_reg_write(gspca_dev, 0x0d, 0x41); + ov534_reg_write(gspca_dev, 0xe5, 0x02); break; case 40: - sccb_reg_write(gspca_dev->dev, 0x11, 0x02); - sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1); - ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); + sccb_reg_write(gspca_dev, 0x11, 0x02); + sccb_reg_write(gspca_dev, 0x0d, 0xc1); + ov534_reg_write(gspca_dev, 0xe5, 0x04); break; /* case 30: */ default: fr = 30; - sccb_reg_write(gspca_dev->dev, 0x11, 0x04); - sccb_reg_write(gspca_dev->dev, 0x0d, 0x81); - ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); + sccb_reg_write(gspca_dev, 0x11, 0x04); + sccb_reg_write(gspca_dev, 0x0d, 0x81); + ov534_reg_write(gspca_dev, 0xe5, 0x02); break; case 15: - sccb_reg_write(gspca_dev->dev, 0x11, 0x03); - sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); - ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); + sccb_reg_write(gspca_dev, 0x11, 0x03); + sccb_reg_write(gspca_dev, 0x0d, 0x41); + ov534_reg_write(gspca_dev, 0xe5, 0x04); break; } @@ -346,27 +347,28 @@ static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) } /* setup method */ -static void ov534_setup(struct usb_device *udev) +static void ov534_setup(struct gspca_dev *gspca_dev) { int i; /* Initialize bridge chip */ for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++) - ov534_reg_write(udev, ov534_reg_initdata[i][0], + ov534_reg_write(gspca_dev, ov534_reg_initdata[i][0], ov534_reg_initdata[i][1]); PDEBUG(D_PROBE, "sensor is ov%02x%02x", - sccb_reg_read(udev, 0x0a), sccb_reg_read(udev, 0x0b)); + sccb_reg_read(gspca_dev, 0x0a), + sccb_reg_read(gspca_dev, 0x0b)); - ov534_set_led(udev, 1); + ov534_set_led(gspca_dev, 1); /* Initialize sensor */ for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++) - sccb_reg_write(udev, ov772x_reg_initdata[i][0], + sccb_reg_write(gspca_dev, ov772x_reg_initdata[i][0], ov772x_reg_initdata[i][1]); - ov534_reg_write(udev, 0xe0, 0x09); - ov534_set_led(udev, 0); + ov534_reg_write(gspca_dev, 0xe0, 0x09); + ov534_set_led(gspca_dev, 0); } /* this function is called at probe time */ @@ -390,7 +392,7 @@ static int sd_config(struct gspca_dev *gspca_dev, /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - ov534_setup(gspca_dev->dev); + ov534_setup(gspca_dev); ov534_set_frame_rate(gspca_dev); return 0; @@ -399,8 +401,8 @@ static int sd_init(struct gspca_dev *gspca_dev) static int sd_start(struct gspca_dev *gspca_dev) { /* start streaming data */ - ov534_set_led(gspca_dev->dev, 1); - ov534_reg_write(gspca_dev->dev, 0xe0, 0x00); + ov534_set_led(gspca_dev, 1); + ov534_reg_write(gspca_dev, 0xe0, 0x00); return 0; } @@ -408,8 +410,8 @@ static int sd_start(struct gspca_dev *gspca_dev) static void sd_stopN(struct gspca_dev *gspca_dev) { /* stop streaming data */ - ov534_reg_write(gspca_dev->dev, 0xe0, 0x09); - ov534_set_led(gspca_dev->dev, 0); + ov534_reg_write(gspca_dev, 0xe0, 0x09); + ov534_set_led(gspca_dev, 0); } /* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */ -- cgit v1.2.3 From cc611b8aef7a8a9a2e614f1bdf3e2b8f066c8c8d Mon Sep 17 00:00:00 2001 From: Jean-Francois Moine Date: Mon, 29 Dec 2008 07:49:41 -0300 Subject: V4L/DVB (10049): gspca - many subdrivers: Set 'const' the pixel format table. Signed-off-by: Jean-Francois Moine Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/gspca/ov534.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/media/video/gspca/ov534.c') diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 406f6bc12d9..3bf15e40169 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c @@ -55,7 +55,7 @@ struct sd { static struct ctrl sd_ctrls[] = { }; -static struct v4l2_pix_format vga_mode[] = { +static const struct v4l2_pix_format vga_mode[] = { {640, 480, V4L2_PIX_FMT_YUYV, V4L2_FIELD_NONE, .bytesperline = 640 * 2, .sizeimage = 640 * 480 * 2, -- cgit v1.2.3