Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@penguin.transmeta.com>2002-02-20 20:26:30 -0800
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-02-20 20:26:30 -0800
commita2dad09d3c809794ec68ed2d1299c03785260cbf (patch)
tree7ea13ac3f4a631689a620deac5592537fdc63419
parentd46f8df66db42edc8f487f2f6ad302567d853264 (diff)
parentf7df36d699eb0722429552df33626354d1196c28 (diff)
Merge bk://linuxusb.bkbits.net/linus-2.5
into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
-rw-r--r--drivers/usb/hcd/Config.help1
-rw-r--r--drivers/usb/hub.c53
-rw-r--r--drivers/usb/ov511.c2750
-rw-r--r--drivers/usb/ov511.h231
-rw-r--r--drivers/usb/uhci.c227
-rw-r--r--drivers/usb/uhci.h60
-rw-r--r--drivers/usb/usb-ohci.c13
-rw-r--r--drivers/usb/usb-uhci.c10
-rw-r--r--drivers/usb/vicam.c2
9 files changed, 1733 insertions, 1614 deletions
diff --git a/drivers/usb/hcd/Config.help b/drivers/usb/hcd/Config.help
index c25152b48718..3412fb5d1874 100644
--- a/drivers/usb/hcd/Config.help
+++ b/drivers/usb/hcd/Config.help
@@ -21,7 +21,6 @@ CONFIG_USB_EHCI_HCD
The module will be called ehci-hcd.o. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>.
-OHCI (most USB hosts except VIA, Intel PIIX) support
CONFIG_USB_OHCI_HCD
The Open Host Controller Interface (OHCI) is a standard for accessing
USB 1.1 host controller hardware. It does more in hardware than Intel's
diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c
index bc89ba970163..91bdb6345587 100644
--- a/drivers/usb/hub.c
+++ b/drivers/usb/hub.c
@@ -644,6 +644,49 @@ void usb_hub_port_disable(struct usb_device *hub, int port)
port + 1, hub->devpath, ret);
}
+/* USB 2.0 spec, 7.1.7.3 / fig 7-29:
+ *
+ * Between connect detection and reset signaling there must be a delay
+ * of 100ms at least for debounce and power-settling. The corresponding
+ * timer shall restart whenever the downstream port detects a disconnect.
+ *
+ * Apparently there are some bluetooth and irda-dongles and a number
+ * of low-speed devices which require longer delays of about 200-400ms.
+ * Not covered by the spec - but easy to deal with.
+ *
+ * This implementation uses 400ms minimum debounce timeout and checks
+ * every 10ms for transient disconnects to restart the delay.
+ */
+
+#define HUB_DEBOUNCE_TIMEOUT 400
+#define HUB_DEBOUNCE_STEP 10
+
+/* return: -1 on error, 0 on success, 1 on disconnect. */
+static int usb_hub_port_debounce(struct usb_device *hub, int port)
+{
+ int ret;
+ unsigned delay_time;
+ u16 portchange, portstatus;
+
+ for (delay_time = 0; delay_time < HUB_DEBOUNCE_TIMEOUT; /* empty */ ) {
+
+ /* wait debounce step increment */
+ wait_ms(HUB_DEBOUNCE_STEP);
+
+ ret = usb_hub_port_status(hub, port, &portstatus, &portchange);
+ if (ret < 0)
+ return -1;
+
+ if ((portchange & USB_PORT_STAT_C_CONNECTION)) {
+ usb_clear_port_feature(hub, port+1, USB_PORT_FEAT_C_CONNECTION);
+ delay_time = 0;
+ }
+ else
+ delay_time += HUB_DEBOUNCE_STEP;
+ }
+ return ((portstatus&USB_PORT_STAT_CONNECTION)) ? 0 : 1;
+}
+
static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
u16 portstatus, u16 portchange)
{
@@ -671,12 +714,16 @@ static void usb_hub_port_connect_change(struct usb_hub *hubstate, int port,
return;
}
+ if (usb_hub_port_debounce(hub, port)) {
+ err("connect-debounce failed, port %d disabled", port+1);
+ usb_hub_port_disable(hub, port);
+ return;
+ }
+
/* Some low speed devices have problems with the quick delay, so */
/* be a bit pessimistic with those devices. RHbug #23670 */
- if (portstatus & USB_PORT_STAT_LOW_SPEED) {
- wait_ms(400);
+ if (portstatus & USB_PORT_STAT_LOW_SPEED)
delay = HUB_LONG_RESET_TIME;
- }
down(&usb_address0_sem);
diff --git a/drivers/usb/ov511.c b/drivers/usb/ov511.c
index 0957c2b8246b..e74388fd64f0 100644
--- a/drivers/usb/ov511.c
+++ b/drivers/usb/ov511.c
@@ -58,7 +58,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.48a for Linux 2.4"
+#define DRIVER_VERSION "v1.49 for Linux 2.5"
#define EMAIL "mmcclell@bigfoot.com"
#define DRIVER_AUTHOR "Mark McClelland <mmcclell@bigfoot.com> & Bret Wallach \
& Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
@@ -309,7 +309,7 @@ static int ov51x_check_snapshot(struct usb_ov511 *);
static inline int sensor_get_picture(struct usb_ov511 *,
struct video_picture *);
static int sensor_get_exposure(struct usb_ov511 *, unsigned char *);
-static int ov511_control_ioctl(struct inode *, struct file *, unsigned int,
+static int ov51x_control_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
/**********************************************************************
@@ -332,6 +332,7 @@ static struct cam_list clist[] = {
{ 100, "Lifeview RoboCam" },
{ 102, "AverMedia InterCam Elite" },
{ 112, "MediaForte MV300" }, /* or OV7110 evaluation kit */
+ { 192, "Webeye 2000B" },
{ -1, NULL }
};
@@ -373,6 +374,10 @@ static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE;
static unsigned char yQuanTable518[] = OV518_YQUANTABLE;
static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE;
+/**********************************************************************
+ * Memory management
+ **********************************************************************/
+
/* Here we want the physical address of the memory.
* This is used when initializing the contents of the
* area and marking the pages as reserved.
@@ -451,7 +456,7 @@ static struct proc_dir_entry *ov511_proc_entry = NULL;
extern struct proc_dir_entry *video_proc_entry;
static struct file_operations ov511_control_fops = {
- ioctl: ov511_control_ioctl,
+ ioctl: ov51x_control_ioctl,
};
#define YES_NO(x) ((x) ? "yes" : "no")
@@ -463,29 +468,29 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
{
char *out = page;
int i, j, len;
- struct usb_ov511 *ov511 = data;
+ struct usb_ov511 *ov = data;
struct video_picture p;
unsigned char exp;
- if (!ov511 || !ov511->dev)
+ if (!ov || !ov->dev)
return -ENODEV;
- sensor_get_picture(ov511, &p);
- sensor_get_exposure(ov511, &exp);
+ sensor_get_picture(ov, &p);
+ sensor_get_exposure(ov, &exp);
/* IMPORTANT: This output MUST be kept under PAGE_SIZE
* or we need to get more sophisticated. */
out += sprintf(out, "driver_version : %s\n", DRIVER_VERSION);
- out += sprintf(out, "custom_id : %d\n", ov511->customid);
- out += sprintf(out, "model : %s\n", ov511->desc ?
- clist[ov511->desc].description : "unknown");
- out += sprintf(out, "streaming : %s\n", YES_NO(ov511->streaming));
- out += sprintf(out, "grabbing : %s\n", YES_NO(ov511->grabbing));
- out += sprintf(out, "compress : %s\n", YES_NO(ov511->compress));
- out += sprintf(out, "subcapture : %s\n", YES_NO(ov511->sub_flag));
+ out += sprintf(out, "custom_id : %d\n", ov->customid);
+ out += sprintf(out, "model : %s\n", ov->desc ?
+ clist[ov->desc].description : "unknown");
+ out += sprintf(out, "streaming : %s\n", YES_NO(ov->streaming));
+ out += sprintf(out, "grabbing : %s\n", YES_NO(ov->grabbing));
+ out += sprintf(out, "compress : %s\n", YES_NO(ov->compress));
+ out += sprintf(out, "subcapture : %s\n", YES_NO(ov->sub_flag));
out += sprintf(out, "sub_size : %d %d %d %d\n",
- ov511->subx, ov511->suby, ov511->subw, ov511->subh);
+ ov->subx, ov->suby, ov->subw, ov->subh);
out += sprintf(out, "data_format : %s\n",
force_rgb ? "RGB" : "BGR");
out += sprintf(out, "brightness : %d\n", p.brightness >> 8);
@@ -497,12 +502,12 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
for (i = 0; i < OV511_NUMFRAMES; i++) {
out += sprintf(out, "frame : %d\n", i);
out += sprintf(out, " depth : %d\n",
- ov511->frame[i].depth);
+ ov->frame[i].depth);
out += sprintf(out, " size : %d %d\n",
- ov511->frame[i].width, ov511->frame[i].height);
+ ov->frame[i].width, ov->frame[i].height);
out += sprintf(out, " format : ");
for (j = 0; plist[j].num >= 0; j++) {
- if (plist[j].num == ov511->frame[i].format) {
+ if (plist[j].num == ov->frame[i].format) {
out += sprintf(out, "%s\n", plist[j].name);
break;
}
@@ -510,29 +515,28 @@ ov511_read_proc_info(char *page, char **start, off_t off, int count, int *eof,
if (plist[j].num < 0)
out += sprintf(out, "unknown\n");
out += sprintf(out, " data_buffer : 0x%p\n",
- ov511->frame[i].data);
+ ov->frame[i].data);
}
- out += sprintf(out, "snap_enabled : %s\n",
- YES_NO(ov511->snap_enabled));
+ out += sprintf(out, "snap_enabled : %s\n", YES_NO(ov->snap_enabled));
out += sprintf(out, "bridge : %s\n",
- ov511->bridge == BRG_OV511 ? "OV511" :
- ov511->bridge == BRG_OV511PLUS ? "OV511+" :
- ov511->bridge == BRG_OV518 ? "OV518" :
- ov511->bridge == BRG_OV518PLUS ? "OV518+" :
+ ov->bridge == BRG_OV511 ? "OV511" :
+ ov->bridge == BRG_OV511PLUS ? "OV511+" :
+ ov->bridge == BRG_OV518 ? "OV518" :
+ ov->bridge == BRG_OV518PLUS ? "OV518+" :
"unknown");
out += sprintf(out, "sensor : %s\n",
- ov511->sensor == SEN_OV6620 ? "OV6620" :
- ov511->sensor == SEN_OV6630 ? "OV6630" :
- ov511->sensor == SEN_OV7610 ? "OV7610" :
- ov511->sensor == SEN_OV7620 ? "OV7620" :
- ov511->sensor == SEN_OV7620AE ? "OV7620AE" :
- ov511->sensor == SEN_OV8600 ? "OV8600" :
- ov511->sensor == SEN_KS0127 ? "KS0127" :
- ov511->sensor == SEN_KS0127B ? "KS0127B" :
- ov511->sensor == SEN_SAA7111A ? "SAA7111A" :
+ ov->sensor == SEN_OV6620 ? "OV6620" :
+ ov->sensor == SEN_OV6630 ? "OV6630" :
+ ov->sensor == SEN_OV7610 ? "OV7610" :
+ ov->sensor == SEN_OV7620 ? "OV7620" :
+ ov->sensor == SEN_OV7620AE ? "OV7620AE" :
+ ov->sensor == SEN_OV8600 ? "OV8600" :
+ ov->sensor == SEN_KS0127 ? "KS0127" :
+ ov->sensor == SEN_KS0127B ? "KS0127B" :
+ ov->sensor == SEN_SAA7111A ? "SAA7111A" :
"unknown");
- out += sprintf(out, "packet_size : %d\n", ov511->packet_size);
- out += sprintf(out, "framebuffer : 0x%p\n", ov511->fbuf);
+ out += sprintf(out, "packet_size : %d\n", ov->packet_size);
+ out += sprintf(out, "framebuffer : 0x%p\n", ov->fbuf);
len = out - page;
len -= off;
@@ -565,16 +569,16 @@ ov511_read_proc_button(char *page, char **start, off_t off, int count, int *eof,
{
char *out = page;
int len, status;
- struct usb_ov511 *ov511 = data;
+ struct usb_ov511 *ov = data;
- if (!ov511 || !ov511->dev)
+ if (!ov || !ov->dev)
return -ENODEV;
- status = ov51x_check_snapshot(ov511);
+ status = ov51x_check_snapshot(ov);
out += sprintf(out, "%d", status);
if (status)
- ov51x_clear_snapshot(ov511);
+ ov51x_clear_snapshot(ov);
len = out - page;
len -= off;
@@ -716,18 +720,22 @@ proc_ov511_destroy(void)
*
**********************************************************************/
+/* Write an OV51x register */
static int
-ov511_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
+reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
{
int rc;
PDEBUG(5, "0x%02X:0x%02X", reg, value);
- rc = usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
+ down(&ov->cbuf_lock);
+ ov->cbuf[0] = value;
+ rc = usb_control_msg(ov->dev,
+ usb_sndctrlpipe(ov->dev, 0),
2 /* REG_IO */,
USB_TYPE_CLASS | USB_RECIP_DEVICE,
- 0, (__u16)reg, &value, 1, HZ);
+ 0, (__u16)reg, &ov->cbuf[0], 1, HZ);
+ up(&ov->cbuf_lock);
if (rc < 0)
err("reg write: error %d", rc);
@@ -735,45 +743,48 @@ ov511_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
return rc;
}
+/* Read from an OV51x register */
/* returns: negative is error, pos or zero is data */
static int
-ov511_reg_read(struct usb_device *dev, unsigned char reg)
+reg_r(struct usb_ov511 *ov, unsigned char reg)
{
int rc;
- unsigned char buffer[1];
- rc = usb_control_msg(dev,
- usb_rcvctrlpipe(dev, 0),
+ down(&ov->cbuf_lock);
+ rc = usb_control_msg(ov->dev,
+ usb_rcvctrlpipe(ov->dev, 0),
2 /* REG_IO */,
USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE,
- 0, (__u16)reg, buffer, 1, HZ);
+ 0, (__u16)reg, &ov->cbuf[0], 1, HZ);
- PDEBUG(5, "0x%02X:0x%02X", reg, buffer[0]);
+ PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]);
- if (rc < 0) {
+ if (rc < 0)
err("reg read: error %d", rc);
- return rc;
- } else {
- return buffer[0];
- }
+ else
+ rc = ov->cbuf[0];
+
+ up(&ov->cbuf_lock);
+
+ return rc;
}
/*
- * Writes bits at positions specified by mask to a reg. Bits that are in
+ * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
* the same position as 1's in "mask" are cleared and set to "value". Bits
* that are in the same position as 0's in "mask" are preserved, regardless
* of their respective state in "value".
*/
static int
-ov511_reg_write_mask(struct usb_device *dev,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
+reg_w_mask(struct usb_ov511 *ov,
+ unsigned char reg,
+ unsigned char value,
+ unsigned char mask)
{
int ret;
unsigned char oldval, newval;
- ret = ov511_reg_read(dev, reg);
+ ret = reg_r(ov, reg);
if (ret < 0)
return ret;
@@ -782,31 +793,30 @@ ov511_reg_write_mask(struct usb_device *dev,
value &= mask; /* Enforce mask on value */
newval = oldval | value; /* Set the desired bits */
- return (ov511_reg_write(dev, reg, newval));
+ return (reg_w(ov, reg, newval));
}
-/* Writes multiple (n) values to a single register. Only valid with certain
- * registers (0x30 and 0xc4 - 0xce). Used for writing 16 and 24-bit values. */
+/*
+ * Writes multiple (n) byte value to a single register. Only valid with certain
+ * registers (0x30 and 0xc4 - 0xce).
+ */
static int
-ov518_reg_write_multi(struct usb_device *dev,
- unsigned char reg,
- unsigned char *values,
- int n)
+ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
{
int rc;
- PDEBUG(5, "0x%02X:[multiple], n=%d", reg, n); // FIXME
+ PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n);
- if (values == NULL) {
- err("reg write multiple: NULL buffer");
- return -EINVAL;
- }
+ down(&ov->cbuf_lock);
+
+ *((u32 *)ov->cbuf) = __cpu_to_le32(val);
- rc = usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
+ rc = usb_control_msg(ov->dev,
+ usb_sndctrlpipe(ov->dev, 0),
2 /* REG_IO */,
USB_TYPE_CLASS | USB_RECIP_DEVICE,
- 0, (__u16)reg, values, n, HZ);
+ 0, (__u16)reg, ov->cbuf, n, HZ);
+ up(&ov->cbuf_lock);
if (rc < 0)
err("reg write multiple: error %d", rc);
@@ -815,12 +825,12 @@ ov518_reg_write_multi(struct usb_device *dev,
}
static int
-ov511_upload_quan_tables(struct usb_device *dev)
+ov511_upload_quan_tables(struct usb_ov511 *ov)
{
unsigned char *pYTable = yQuanTable511;
unsigned char *pUVTable = uvQuanTable511;
unsigned char val0, val1;
- int i, rc, reg = OV511_OMNICE_Y_LUT_BEGIN;
+ int i, rc, reg = R511_COMP_LUT_BEGIN;
PDEBUG(4, "Uploading quantization tables");
@@ -833,7 +843,7 @@ ov511_upload_quan_tables(struct usb_device *dev)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = ov511_reg_write(dev, reg, val0);
+ rc = reg_w(ov, reg, val0);
if (rc < 0)
return rc;
}
@@ -845,8 +855,7 @@ ov511_upload_quan_tables(struct usb_device *dev)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = ov511_reg_write(dev, reg + OV511_QUANTABLESIZE / 2,
- val0);
+ rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0);
if (rc < 0)
return rc;
}
@@ -859,12 +868,12 @@ ov511_upload_quan_tables(struct usb_device *dev)
/* OV518 quantization tables are 8x4 (instead of 8x8) */
static int
-ov518_upload_quan_tables(struct usb_device *dev)
+ov518_upload_quan_tables(struct usb_ov511 *ov)
{
unsigned char *pYTable = yQuanTable518;
unsigned char *pUVTable = uvQuanTable518;
unsigned char val0, val1;
- int i, rc, reg = OV511_OMNICE_Y_LUT_BEGIN;
+ int i, rc, reg = R511_COMP_LUT_BEGIN;
PDEBUG(4, "Uploading quantization tables");
@@ -877,7 +886,7 @@ ov518_upload_quan_tables(struct usb_device *dev)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = ov511_reg_write(dev, reg, val0);
+ rc = reg_w(ov, reg, val0);
if (rc < 0)
return rc;
}
@@ -889,8 +898,7 @@ ov518_upload_quan_tables(struct usb_device *dev)
val0 &= 0x0f;
val1 &= 0x0f;
val0 |= val1 << 4;
- rc = ov511_reg_write(dev, reg + OV518_QUANTABLESIZE / 2,
- val0);
+ rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0);
if (rc < 0)
return rc;
}
@@ -901,13 +909,39 @@ ov518_upload_quan_tables(struct usb_device *dev)
return 0;
}
+static int
+ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type)
+{
+ int rc;
+
+ /* Setting bit 0 not allowed on 518/518Plus */
+ if (ov->bclass == BCL_OV518)
+ reset_type &= 0xfe;
+
+ PDEBUG(4, "Reset: type=0x%X", reset_type);
+
+ rc = reg_w(ov, R51x_SYS_RESET, reset_type);
+ rc = reg_w(ov, R51x_SYS_RESET, 0);
+
+ if (rc < 0)
+ err("reset: command failed");
+
+ return rc;
+}
+
+/**********************************************************************
+ *
+ * I2C (sensor) I/O
+ *
+ **********************************************************************/
+
/* NOTE: Do not call this function directly!
* The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from ov51x_i2c_write(). Note that this function
+ * This is normally only called from i2c_w(). Note that this function
* always succeeds regardless of whether the sensor is present and working.
*/
static int
-ov518_i2c_write_internal(struct usb_device *dev,
+ov518_i2c_write_internal(struct usb_ov511 *ov,
unsigned char reg,
unsigned char value)
{
@@ -916,15 +950,15 @@ ov518_i2c_write_internal(struct usb_device *dev,
PDEBUG(5, "0x%02X:0x%02X", reg, value);
/* Select camera register */
- rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE, reg);
+ rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
if (rc < 0) goto error;
/* Write "value" to I2C data port of OV511 */
- rc = ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);
+ rc = reg_w(ov, R51x_I2C_DATA, value);
if (rc < 0) goto error;
/* Initiate 3-byte write cycle */
- rc = ov511_reg_write(dev, OV518_REG_I2C_CONTROL, 0x01);
+ rc = reg_w(ov, R518_I2C_CTL, 0x01);
if (rc < 0) goto error;
return 0;
@@ -936,7 +970,7 @@ error:
/* NOTE: Do not call this function directly! */
static int
-ov511_i2c_write_internal(struct usb_device *dev,
+ov511_i2c_write_internal(struct usb_ov511 *ov,
unsigned char reg,
unsigned char value)
{
@@ -947,19 +981,18 @@ ov511_i2c_write_internal(struct usb_device *dev,
/* Three byte write cycle */
for (retries = OV511_I2C_RETRIES; ; ) {
/* Select camera register */
- rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE,
- reg);
+ rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
if (rc < 0) goto error;
/* Write "value" to I2C data port of OV511 */
- rc = ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);
+ rc = reg_w(ov, R51x_I2C_DATA, value);
if (rc < 0) goto error;
/* Initiate 3-byte write cycle */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x01);
+ rc = reg_w(ov, R511_I2C_CTL, 0x01);
if (rc < 0) goto error;
- do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+ do rc = reg_r(ov, R511_I2C_CTL);
while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
if (rc < 0) goto error;
@@ -967,7 +1000,7 @@ ov511_i2c_write_internal(struct usb_device *dev,
break;
#if 0
/* I2C abort */
- ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+ reg_w(ov, R511_I2C_CTL, 0x10);
#endif
if (--retries < 0) {
err("i2c write retries exhausted");
@@ -985,27 +1018,27 @@ error:
/* NOTE: Do not call this function directly!
* The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from ov51x_i2c_read(). Note that this function
+ * This is normally only called from i2c_r(). Note that this function
* always succeeds regardless of whether the sensor is present and working.
*/
static int
-ov518_i2c_read_internal(struct usb_device *dev, unsigned char reg)
+ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
{
int rc, value;
/* Select camera register */
- rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE, reg);
+ rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
if (rc < 0) goto error;
/* Initiate 2-byte write cycle */
- rc = ov511_reg_write(dev, OV518_REG_I2C_CONTROL, 0x03);
+ rc = reg_w(ov, R518_I2C_CTL, 0x03);
if (rc < 0) goto error;
/* Initiate 2-byte read cycle */
- rc = ov511_reg_write(dev, OV518_REG_I2C_CONTROL, 0x05);
+ rc = reg_w(ov, R518_I2C_CTL, 0x05);
if (rc < 0) goto error;
- value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
+ value = reg_r(ov, R51x_I2C_DATA);
PDEBUG(5, "0x%02X:0x%02X", reg, value);
@@ -1019,22 +1052,21 @@ error:
/* NOTE: Do not call this function directly!
* returns: negative is error, pos or zero is data */
static int
-ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
+ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
{
int rc, value, retries;
/* Two byte write cycle */
for (retries = OV511_I2C_RETRIES; ; ) {
/* Select camera register */
- rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE,
- reg);
+ rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
if (rc < 0) goto error;
/* Initiate 2-byte write cycle */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x03);
+ rc = reg_w(ov, R511_I2C_CTL, 0x03);
if (rc < 0) goto error;
- do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+ do rc = reg_r(ov, R511_I2C_CTL);
while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
if (rc < 0) goto error;
@@ -1042,7 +1074,7 @@ ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
break;
/* I2C abort */
- ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+ reg_w(ov, R511_I2C_CTL, 0x10);
if (--retries < 0) {
err("i2c write retries exhausted");
@@ -1054,10 +1086,10 @@ ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
/* Two byte read cycle */
for (retries = OV511_I2C_RETRIES; ; ) {
/* Initiate 2-byte read cycle */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
+ rc = reg_w(ov, R511_I2C_CTL, 0x05);
if (rc < 0) goto error;
- do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
+ do rc = reg_r(ov, R511_I2C_CTL);
while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
if (rc < 0) goto error;
@@ -1065,7 +1097,7 @@ ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
break;
/* I2C abort */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
+ rc = reg_w(ov, R511_I2C_CTL, 0x10);
if (rc < 0) goto error;
if (--retries < 0) {
@@ -1075,12 +1107,12 @@ ov511_i2c_read_internal(struct usb_device *dev, unsigned char reg)
}
}
- value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
+ value = reg_r(ov, R51x_I2C_DATA);
PDEBUG(5, "0x%02X:0x%02X", reg, value);
- /* This is needed to make ov51x_i2c_write() work */
- rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
+ /* This is needed to make i2c_w() work */
+ rc = reg_w(ov, R511_I2C_CTL, 0x05);
if (rc < 0)
goto error;
@@ -1093,48 +1125,42 @@ error:
/* returns: negative is error, pos or zero is data */
static int
-ov51x_i2c_read(struct usb_ov511 *ov511, unsigned char reg)
+i2c_r(struct usb_ov511 *ov, unsigned char reg)
{
int rc;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- rc = ov518_i2c_read_internal(dev, reg);
+ if (ov->bclass == BCL_OV518)
+ rc = ov518_i2c_read_internal(ov, reg);
else
- rc = ov511_i2c_read_internal(dev, reg);
+ rc = ov511_i2c_read_internal(ov, reg);
- up(&ov511->i2c_lock);
+ up(&ov->i2c_lock);
return rc;
}
static int
-ov51x_i2c_write(struct usb_ov511 *ov511,
- unsigned char reg,
- unsigned char value)
+i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
{
int rc;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- rc = ov518_i2c_write_internal(dev, reg, value);
+ if (ov->bclass == BCL_OV518)
+ rc = ov518_i2c_write_internal(ov, reg, value);
else
- rc = ov511_i2c_write_internal(dev, reg, value);
+ rc = ov511_i2c_write_internal(ov, reg, value);
- up(&ov511->i2c_lock);
+ up(&ov->i2c_lock);
return rc;
}
/* Do not call this function directly! */
static int
-ov51x_i2c_write_mask_internal(struct usb_device *dev,
+ov51x_i2c_write_mask_internal(struct usb_ov511 *ov,
unsigned char reg,
unsigned char value,
unsigned char mask)
@@ -1145,11 +1171,10 @@ ov51x_i2c_write_mask_internal(struct usb_device *dev,
if (mask == 0xff) {
newval = value;
} else {
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- rc = ov518_i2c_read_internal(dev, reg);
+ if (ov->bclass == BCL_OV518)
+ rc = ov518_i2c_read_internal(ov, reg);
else
- rc = ov511_i2c_read_internal(dev, reg);
+ rc = ov511_i2c_read_internal(ov, reg);
if (rc < 0)
return rc;
@@ -1159,11 +1184,10 @@ ov51x_i2c_write_mask_internal(struct usb_device *dev,
newval = oldval | value; /* Set the desired bits */
}
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- return (ov518_i2c_write_internal(dev, reg, newval));
+ if (ov->bclass == BCL_OV518)
+ return (ov518_i2c_write_internal(ov, reg, newval));
else
- return (ov511_i2c_write_internal(dev, reg, newval));
+ return (ov511_i2c_write_internal(ov, reg, newval));
}
/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
@@ -1172,126 +1196,138 @@ ov51x_i2c_write_mask_internal(struct usb_device *dev,
* of their respective state in "value".
*/
static int
-ov51x_i2c_write_mask(struct usb_ov511 *ov511,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
+i2c_w_mask(struct usb_ov511 *ov,
+ unsigned char reg,
+ unsigned char value,
+ unsigned char mask)
{
int rc;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
- rc = ov51x_i2c_write_mask_internal(dev, reg, value, mask);
- up(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
+ rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
+ up(&ov->i2c_lock);
return rc;
}
/* Write to a specific I2C slave ID and register, using the specified mask */
static int
-ov51x_i2c_write_slave(struct usb_ov511 *ov511,
- unsigned char slave,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
+i2c_w_slave(struct usb_ov511 *ov,
+ unsigned char slave,
+ unsigned char reg,
+ unsigned char value,
+ unsigned char mask)
{
int rc = 0;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
/* Set new slave IDs */
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+ if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
rc = -EIO;
goto out;
}
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+ if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
rc = -EIO;
goto out;
}
- rc = ov51x_i2c_write_mask_internal(dev, reg, value, mask);
+ rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
/* Don't bail out yet if error; IDs must be restored */
/* Restore primary IDs */
- slave = ov511->primary_i2c_slave;
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+ slave = ov->primary_i2c_slave;
+ if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
rc = -EIO;
goto out;
}
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+ if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
rc = -EIO;
goto out;
}
out:
- up(&ov511->i2c_lock);
+ up(&ov->i2c_lock);
return rc;
}
/* Read from a specific I2C slave ID and register */
static int
-ov51x_i2c_read_slave(struct usb_ov511 *ov511,
- unsigned char slave,
- unsigned char reg)
+i2c_r_slave(struct usb_ov511 *ov,
+ unsigned char slave,
+ unsigned char reg)
{
int rc;
- struct usb_device *dev = ov511->dev;
- down(&ov511->i2c_lock);
+ down(&ov->i2c_lock);
/* Set new slave IDs */
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+ if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
rc = -EIO;
goto out;
}
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+ if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
rc = -EIO;
goto out;
}
- if (dev->descriptor.idProduct == PROD_OV518 ||
- dev->descriptor.idProduct == PROD_OV518PLUS)
- rc = ov518_i2c_read_internal(dev, reg);
+ if (ov->bclass == BCL_OV518)
+ rc = ov518_i2c_read_internal(ov, reg);
else
- rc = ov511_i2c_read_internal(dev, reg);
+ rc = ov511_i2c_read_internal(ov, reg);
/* Don't bail out yet if error; IDs must be restored */
/* Restore primary IDs */
- slave = ov511->primary_i2c_slave;
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, slave) < 0) {
+ slave = ov->primary_i2c_slave;
+ if (reg_w(ov, R51x_I2C_W_SID, slave) < 0) {
rc = -EIO;
goto out;
}
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, slave + 1) < 0) {
+ if (reg_w(ov, R51x_I2C_R_SID, slave + 1) < 0) {
rc = -EIO;
goto out;
}
out:
- up(&ov511->i2c_lock);
+ up(&ov->i2c_lock);
return rc;
}
+/* Sets I2C read and write slave IDs. Returns <0 for error */
+static int
+ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
+{
+ down(&ov->i2c_lock);
+
+ if (reg_w(ov, R51x_I2C_W_SID, sid) < 0)
+ return -EIO;
+
+ if (reg_w(ov, R51x_I2C_R_SID, sid + 1) < 0)
+ return -EIO;
+
+ if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
+ return -EIO;
+
+ up(&ov->i2c_lock);
+
+ return 0;
+}
+
static int
-ov511_write_regvals(struct usb_ov511 *ov511,
- struct ov511_regvals * pRegvals)
+write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals)
{
int rc;
- struct usb_device *dev = ov511->dev;
while (pRegvals->bus != OV511_DONE_BUS) {
if (pRegvals->bus == OV511_REG_BUS) {
- if ((rc = ov511_reg_write(dev, pRegvals->reg,
- pRegvals->val)) < 0)
+ if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0)
goto error;
} else if (pRegvals->bus == OV511_I2C_BUS) {
- if ((rc = ov51x_i2c_write(ov511, pRegvals->reg,
- pRegvals->val)) < 0)
+ if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0)
goto error;
} else {
err("Bad regval array");
@@ -1309,57 +1345,60 @@ error:
#ifdef OV511_DEBUG
static void
-ov511_dump_i2c_range(struct usb_ov511 *ov511, int reg1, int regn)
+dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn)
{
int i;
int rc;
+
for (i = reg1; i <= regn; i++) {
- rc = ov51x_i2c_read(ov511, i);
+ rc = i2c_r(ov, i);
info("OV7610[0x%X] = 0x%X", i, rc);
}
}
static void
-ov51x_dump_i2c_regs(struct usb_ov511 *ov511)
+dump_i2c_regs(struct usb_ov511 *ov)
{
info("I2C REGS");
- ov511_dump_i2c_range(ov511, 0x00, 0x7C);
+ dump_i2c_range(ov, 0x00, 0x7C);
}
static void
-ov511_dump_reg_range(struct usb_device *dev, int reg1, int regn)
+dump_reg_range(struct usb_ov511 *ov, int reg1, int regn)
{
int i;
int rc;
+
for (i = reg1; i <= regn; i++) {
- rc = ov511_reg_read(dev, i);
- info("OV511[0x%X] = 0x%X", i, rc);
+ rc = reg_r(ov, i);
+ info("OV511[0x%X] = 0x%X", i, rc);
}
}
+/* FIXME: Should there be an OV518 version of this? */
static void
-ov511_dump_regs(struct usb_device *dev)
+ov511_dump_regs(struct usb_ov511 *ov)
{
info("CAMERA INTERFACE REGS");
- ov511_dump_reg_range(dev, 0x10, 0x1f);
+ dump_reg_range(ov, 0x10, 0x1f);
info("DRAM INTERFACE REGS");
- ov511_dump_reg_range(dev, 0x20, 0x23);
+ dump_reg_range(ov, 0x20, 0x23);
info("ISO FIFO REGS");
- ov511_dump_reg_range(dev, 0x30, 0x31);
+ dump_reg_range(ov, 0x30, 0x31);
info("PIO REGS");
- ov511_dump_reg_range(dev, 0x38, 0x39);
- ov511_dump_reg_range(dev, 0x3e, 0x3e);
+ dump_reg_range(ov, 0x38, 0x39);
+ dump_reg_range(ov, 0x3e, 0x3e);
info("I2C REGS");
- ov511_dump_reg_range(dev, 0x40, 0x49);
+ dump_reg_range(ov, 0x40, 0x49);
info("SYSTEM CONTROL REGS");
- ov511_dump_reg_range(dev, 0x50, 0x55);
- ov511_dump_reg_range(dev, 0x5e, 0x5f);
+ dump_reg_range(ov, 0x50, 0x55);
+ dump_reg_range(ov, 0x5e, 0x5f);
info("OmniCE REGS");
- ov511_dump_reg_range(dev, 0x70, 0x79);
+ dump_reg_range(ov, 0x70, 0x79);
/* NOTE: Quantization tables are not readable. You will get the value
* in reg. 0x79 for every table register */
- ov511_dump_reg_range(dev, 0x80, 0x9f);
- ov511_dump_reg_range(dev, 0xa0, 0xbf);
+ dump_reg_range(ov, 0x80, 0x9f);
+ dump_reg_range(ov, 0xa0, 0xbf);
}
#endif
@@ -1372,7 +1411,7 @@ ov511_dump_regs(struct usb_device *dev)
/* For as-yet unimplemented I2C interface */
static void
-call_i2c_clients(struct usb_ov511 *ov511, unsigned int cmd,
+call_i2c_clients(struct usb_ov511 *ov, unsigned int cmd,
void *arg)
{
/* Do nothing */
@@ -1380,59 +1419,33 @@ call_i2c_clients(struct usb_ov511 *ov511, unsigned int cmd,
/*****************************************************************************/
-static int
-ov511_reset(struct usb_ov511 *ov511, unsigned char reset_type)
-{
- int rc;
-
- /* Setting bit 0 not allowed on 518/518Plus */
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- reset_type &= 0xfe;
-
- PDEBUG(4, "Reset: type=0x%X", reset_type);
-
- rc = ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, reset_type);
- rc = ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, 0);
-
- if (rc < 0)
- err("reset: command failed");
-
- return rc;
-}
-
/* Temporarily stops OV511 from functioning. Must do this before changing
* registers while the camera is streaming */
static inline int
-ov511_stop(struct usb_ov511 *ov511)
+ov51x_stop(struct usb_ov511 *ov)
{
PDEBUG(4, "stopping");
- ov511->stopped = 1;
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- return (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET,
- 0x3a));
+ ov->stopped = 1;
+ if (ov->bclass == BCL_OV518)
+ return (reg_w(ov, R51x_SYS_RESET, 0x3a));
else
- return (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET,
- 0x3d));
+ return (reg_w(ov, R51x_SYS_RESET, 0x3d));
}
/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
* actually stopped (for performance). */
static inline int
-ov511_restart(struct usb_ov511 *ov511)
+ov51x_restart(struct usb_ov511 *ov)
{
- if (ov511->stopped) {
+ if (ov->stopped) {
PDEBUG(4, "restarting");
- ov511->stopped = 0;
+ ov->stopped = 0;
/* Reinitialize the stream */
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- ov511_reg_write(ov511->dev, 0x2f, 0x80);
+ if (ov->bclass == BCL_OV518)
+ reg_w(ov, 0x2f, 0x80);
- return (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET,
- 0x00));
+ return (reg_w(ov, R51x_SYS_RESET, 0x00));
}
return 0;
@@ -1440,14 +1453,13 @@ ov511_restart(struct usb_ov511 *ov511)
/* Resets the hardware snapshot button */
static void
-ov51x_clear_snapshot(struct usb_ov511 *ov511)
+ov51x_clear_snapshot(struct usb_ov511 *ov)
{
- if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS) {
- ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
- ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x03);
- ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ if (ov->bclass == BCL_OV511) {
+ reg_w(ov, R51x_SYS_SNAP, 0x01);
+ reg_w(ov, R51x_SYS_SNAP, 0x03);
+ reg_w(ov, R51x_SYS_SNAP, 0x01);
+ } else if (ov->bclass == BCL_OV518) {
warn("snapshot reset not supported yet on OV518(+)");
} else {
err("clear snap: invalid bridge type");
@@ -1458,19 +1470,18 @@ ov51x_clear_snapshot(struct usb_ov511 *ov511)
/* Checks the status of the snapshot button. Returns 1 if it was pressed since
* it was last cleared, and zero in all other cases (including errors) */
static int
-ov51x_check_snapshot(struct usb_ov511 *ov511)
+ov51x_check_snapshot(struct usb_ov511 *ov)
{
int ret, status = 0;
- if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS) {
- ret = ov511_reg_read(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT);
+ if (ov->bclass == BCL_OV511) {
+ ret = reg_r(ov, R51x_SYS_SNAP);
if (ret < 0) {
err("Error checking snspshot status (%d)", ret);
} else if (ret & 0x08) {
status = 1;
}
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ } else if (ov->bclass == BCL_OV518) {
warn("snapshot check not supported yet on OV518(+)");
} else {
err("check snap: invalid bridge type");
@@ -1479,53 +1490,33 @@ ov51x_check_snapshot(struct usb_ov511 *ov511)
return status;
}
-/* Sets I2C read and write slave IDs. Returns <0 for error */
-static int
-ov51x_set_slave_ids(struct usb_ov511 *ov511,
- unsigned char write_id,
- unsigned char read_id)
-{
- struct usb_device *dev = ov511->dev;
-
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE, write_id) < 0)
- return -EIO;
-
- if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ, read_id) < 0)
- return -EIO;
-
- if (ov511_reset(ov511, OV511_RESET_NOREGS) < 0)
- return -EIO;
-
- return 0;
-}
-
/* This does an initial reset of an OmniVision sensor and ensures that I2C
* is synchronized. Returns <0 for failure.
*/
static int
-ov51x_init_ov_sensor(struct usb_ov511 *ov511)
+init_ov_sensor(struct usb_ov511 *ov)
{
int i, success;
/* Reset the sensor */
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) return -EIO;
+ if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO;
/* Wait for it to initialize */
schedule_timeout (1 + 150 * HZ / 1000);
for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
- if ((ov51x_i2c_read(ov511, OV7610_REG_ID_HIGH) == 0x7F) &&
- (ov51x_i2c_read(ov511, OV7610_REG_ID_LOW) == 0xA2)) {
+ if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
+ (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
success = 1;
continue;
}
/* Reset the sensor */
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) return -EIO;
+ if (i2c_w(ov, 0x12, 0x80) < 0) return -EIO;
/* Wait for it to initialize */
schedule_timeout(1 + 150 * HZ / 1000);
/* Dummy read to sync I2C */
- if (ov51x_i2c_read(ov511, 0x00) < 0) return -EIO;
+ if (i2c_r(ov, 0x00) < 0) return -EIO;
}
if (!success)
@@ -1537,16 +1528,16 @@ ov51x_init_ov_sensor(struct usb_ov511 *ov511)
}
static int
-ov511_set_packet_size(struct usb_ov511 *ov511, int size)
+ov51x_set_packet_size(struct usb_ov511 *ov, int size)
{
int alt, mult;
- if (ov511_stop(ov511) < 0)
+ if (ov51x_stop(ov) < 0)
return -EIO;
mult = size >> 5;
- if (ov511->bridge == BRG_OV511) {
+ if (ov->bridge == BRG_OV511) {
if (size == 0) alt = OV511_ALT_SIZE_0;
else if (size == 257) alt = OV511_ALT_SIZE_257;
else if (size == 513) alt = OV511_ALT_SIZE_513;
@@ -1556,7 +1547,7 @@ ov511_set_packet_size(struct usb_ov511 *ov511, int size)
err("Set packet size: invalid size (%d)", size);
return -EINVAL;
}
- } else if (ov511->bridge == BRG_OV511PLUS) {
+ } else if (ov->bridge == BRG_OV511PLUS) {
if (size == 0) alt = OV511PLUS_ALT_SIZE_0;
else if (size == 33) alt = OV511PLUS_ALT_SIZE_33;
else if (size == 129) alt = OV511PLUS_ALT_SIZE_129;
@@ -1569,8 +1560,7 @@ ov511_set_packet_size(struct usb_ov511 *ov511, int size)
err("Set packet size: invalid size (%d)", size);
return -EINVAL;
}
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ } else if (ov->bclass == BCL_OV518) {
if (size == 0) alt = OV518_ALT_SIZE_0;
else if (size == 128) alt = OV518_ALT_SIZE_128;
else if (size == 256) alt = OV518_ALT_SIZE_256;
@@ -1591,32 +1581,30 @@ ov511_set_packet_size(struct usb_ov511 *ov511, int size)
PDEBUG(3, "set packet size: %d, mult=%d, alt=%d", size, mult, alt);
// FIXME: Don't know how to do this on OV518 yet
- if (ov511->bridge != BRG_OV518 &&
- ov511->bridge != BRG_OV518PLUS) {
- if (ov511_reg_write(ov511->dev, OV511_REG_FIFO_PACKET_SIZE,
+ if (ov->bclass == BCL_OV511) {
+ if (reg_w(ov, R51x_FIFO_PSIZE,
mult) < 0) {
return -EIO;
}
}
- if (usb_set_interface(ov511->dev, ov511->iface, alt) < 0) {
+ if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
err("Set packet size: set interface error");
return -EBUSY;
}
/* Initialize the stream */
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- if (ov511_reg_write(ov511->dev, 0x2f, 0x80) < 0)
+ if (ov->bclass == BCL_OV518)
+ if (reg_w(ov, 0x2f, 0x80) < 0)
return -EIO;
// FIXME - Should we only reset the FIFO?
- if (ov511_reset(ov511, OV511_RESET_NOREGS) < 0)
+ if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
return -EIO;
- ov511->packet_size = size;
+ ov->packet_size = size;
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return 0;
@@ -1624,51 +1612,49 @@ ov511_set_packet_size(struct usb_ov511 *ov511, int size)
/* Upload compression params and quantization tables. Returns 0 for success. */
static int
-ov511_init_compression(struct usb_ov511 *ov511)
+ov511_init_compression(struct usb_ov511 *ov)
{
- struct usb_device *dev = ov511->dev;
int rc = 0;
- if (!ov511->compress_inited) {
+ if (!ov->compress_inited) {
- ov511_reg_write(dev, 0x70, phy);
- ov511_reg_write(dev, 0x71, phuv);
- ov511_reg_write(dev, 0x72, pvy);
- ov511_reg_write(dev, 0x73, pvuv);
- ov511_reg_write(dev, 0x74, qhy);
- ov511_reg_write(dev, 0x75, qhuv);
- ov511_reg_write(dev, 0x76, qvy);
- ov511_reg_write(dev, 0x77, qvuv);
+ reg_w(ov, 0x70, phy);
+ reg_w(ov, 0x71, phuv);
+ reg_w(ov, 0x72, pvy);
+ reg_w(ov, 0x73, pvuv);
+ reg_w(ov, 0x74, qhy);
+ reg_w(ov, 0x75, qhuv);
+ reg_w(ov, 0x76, qvy);
+ reg_w(ov, 0x77, qvuv);
- if (ov511_upload_quan_tables(dev) < 0) {
+ if (ov511_upload_quan_tables(ov) < 0) {
err("Error uploading quantization tables");
rc = -EIO;
goto out;
}
}
- ov511->compress_inited = 1;
+ ov->compress_inited = 1;
out:
return rc;
}
/* Upload compression params and quantization tables. Returns 0 for success. */
static int
-ov518_init_compression(struct usb_ov511 *ov511)
+ov518_init_compression(struct usb_ov511 *ov)
{
- struct usb_device *dev = ov511->dev;
int rc = 0;
- if (!ov511->compress_inited) {
+ if (!ov->compress_inited) {
- if (ov518_upload_quan_tables(dev) < 0) {
+ if (ov518_upload_quan_tables(ov) < 0) {
err("Error uploading quantization tables");
rc = -EIO;
goto out;
}
}
- ov511->compress_inited = 1;
+ ov->compress_inited = 1;
out:
return rc;
}
@@ -1677,22 +1663,22 @@ out:
/* Sets sensor's contrast setting to "val" */
static int
-sensor_set_contrast(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_contrast(struct usb_ov511 *ov, unsigned short val)
{
int rc;
PDEBUG(3, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
{
- rc = ov51x_i2c_write(ov511, OV7610_REG_CNT, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_CNT, val >> 8);
if (rc < 0)
goto out;
break;
@@ -1705,14 +1691,14 @@ sensor_set_contrast(struct usb_ov511 *ov511, unsigned short val)
};
/* Use Y gamma control instead. Bit 0 enables it. */
- rc = ov51x_i2c_write(ov511, 0x64, ctab[val>>12]);
+ rc = i2c_w(ov, 0x64, ctab[val>>12]);
if (rc < 0)
goto out;
break;
}
case SEN_SAA7111A:
{
- rc = ov51x_i2c_write(ov511, 0x0b, val >> 9);
+ rc = i2c_w(ov, 0x0b, val >> 9);
if (rc < 0)
goto out;
break;
@@ -1726,9 +1712,9 @@ sensor_set_contrast(struct usb_ov511 *ov511, unsigned short val)
}
rc = 0; /* Success */
- ov511->contrast = val;
+ ov->contrast = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -1736,15 +1722,15 @@ out:
/* Gets sensor's contrast setting */
static int
-sensor_get_contrast(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_read(ov511, OV7610_REG_CNT);
+ rc = i2c_r(ov, OV7610_REG_CNT);
if (rc < 0)
return rc;
else
@@ -1752,14 +1738,14 @@ sensor_get_contrast(struct usb_ov511 *ov511, unsigned short *val)
break;
case SEN_OV7620:
/* Use Y gamma reg instead. Bit 0 is the enable bit. */
- rc = ov51x_i2c_read(ov511, 0x64);
+ rc = i2c_r(ov, 0x64);
if (rc < 0)
return rc;
else
*val = (rc & 0xfe) << 8;
break;
case SEN_SAA7111A:
- *val = ov511->contrast;
+ *val = ov->contrast;
break;
default:
PDEBUG(3, "Unsupported with this sensor");
@@ -1767,7 +1753,7 @@ sensor_get_contrast(struct usb_ov511 *ov511, unsigned short *val)
}
PDEBUG(3, "%d", *val);
- ov511->contrast = *val;
+ ov->contrast = *val;
return 0;
}
@@ -1776,35 +1762,35 @@ sensor_get_contrast(struct usb_ov511 *ov511, unsigned short *val)
/* Sets sensor's brightness setting to "val" */
static int
-sensor_set_brightness(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_brightness(struct usb_ov511 *ov, unsigned short val)
{
int rc;
PDEBUG(4, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_write(ov511, OV7610_REG_BRT, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
if (rc < 0)
goto out;
break;
case SEN_OV7620:
/* 7620 doesn't like manual changes when in auto mode */
- if (!ov511->auto_brt) {
- rc = ov51x_i2c_write(ov511, OV7610_REG_BRT, val >> 8);
+ if (!ov->auto_brt) {
+ rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
if (rc < 0)
goto out;
}
break;
case SEN_SAA7111A:
- rc = ov51x_i2c_write(ov511, 0x0a, val >> 8);
+ rc = i2c_w(ov, 0x0a, val >> 8);
if (rc < 0)
goto out;
break;
@@ -1815,9 +1801,9 @@ sensor_set_brightness(struct usb_ov511 *ov511, unsigned short val)
}
rc = 0; /* Success */
- ov511->brightness = val;
+ ov->brightness = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -1825,24 +1811,24 @@ out:
/* Gets sensor's brightness setting */
static int
-sensor_get_brightness(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
case SEN_OV7620:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_read(ov511, OV7610_REG_BRT);
+ rc = i2c_r(ov, OV7610_REG_BRT);
if (rc < 0)
return rc;
else
*val = rc << 8;
break;
case SEN_SAA7111A:
- *val = ov511->brightness;
+ *val = ov->brightness;
break;
default:
PDEBUG(3, "Unsupported with this sensor");
@@ -1850,7 +1836,7 @@ sensor_get_brightness(struct usb_ov511 *ov511, unsigned short *val)
}
PDEBUG(3, "%d", *val);
- ov511->brightness = *val;
+ ov->brightness = *val;
return 0;
}
@@ -1859,36 +1845,36 @@ sensor_get_brightness(struct usb_ov511 *ov511, unsigned short *val)
/* Sets sensor's saturation (color intensity) setting to "val" */
static int
-sensor_set_saturation(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_saturation(struct usb_ov511 *ov, unsigned short val)
{
int rc;
PDEBUG(3, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_write(ov511, OV7610_REG_SAT, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
if (rc < 0)
goto out;
break;
case SEN_OV7620:
// /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
-// rc = ov511_i2c_write(ov511->dev, 0x62, (val >> 9) & 0x7e);
+// rc = ov_i2c_write(ov->dev, 0x62, (val >> 9) & 0x7e);
// if (rc < 0)
// goto out;
- rc = ov51x_i2c_write(ov511, OV7610_REG_SAT, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
if (rc < 0)
goto out;
break;
case SEN_SAA7111A:
- rc = ov51x_i2c_write(ov511, 0x0c, val >> 9);
+ rc = i2c_w(ov, 0x0c, val >> 9);
if (rc < 0)
goto out;
break;
@@ -1899,9 +1885,9 @@ sensor_set_saturation(struct usb_ov511 *ov511, unsigned short val)
}
rc = 0; /* Success */
- ov511->colour = val;
+ ov->colour = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -1909,16 +1895,16 @@ out:
/* Gets sensor's saturation (color intensity) setting */
static int
-sensor_get_saturation(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_read(ov511, OV7610_REG_SAT);
+ rc = i2c_r(ov, OV7610_REG_SAT);
if (rc < 0)
return rc;
else
@@ -1926,19 +1912,19 @@ sensor_get_saturation(struct usb_ov511 *ov511, unsigned short *val)
break;
case SEN_OV7620:
// /* Use UV gamma reg instead. Bits 0 & 7 are reserved. */
-// rc = ov51x_i2c_read(ov511, 0x62);
+// rc = i2c_r(ov, 0x62);
// if (rc < 0)
// return rc;
// else
// *val = (rc & 0x7e) << 9;
- rc = ov51x_i2c_read(ov511, OV7610_REG_SAT);
+ rc = i2c_r(ov, OV7610_REG_SAT);
if (rc < 0)
return rc;
else
*val = rc << 8;
break;
case SEN_SAA7111A:
- *val = ov511->colour;
+ *val = ov->colour;
break;
default:
PDEBUG(3, "Unsupported with this sensor");
@@ -1946,7 +1932,7 @@ sensor_get_saturation(struct usb_ov511 *ov511, unsigned short *val)
}
PDEBUG(3, "%d", *val);
- ov511->colour = *val;
+ ov->colour = *val;
return 0;
}
@@ -1955,44 +1941,42 @@ sensor_get_saturation(struct usb_ov511 *ov511, unsigned short *val)
/* Sets sensor's hue (red/blue balance) setting to "val" */
static int
-sensor_set_hue(struct usb_ov511 *ov511, unsigned short val)
+sensor_set_hue(struct usb_ov511 *ov, unsigned short val)
{
int rc;
PDEBUG(3, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_write(ov511, OV7610_REG_RED, 0xFF - (val >> 8));
+ rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8));
if (rc < 0)
goto out;
- rc = ov51x_i2c_write(ov511, OV7610_REG_BLUE, val >> 8);
+ rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8);
if (rc < 0)
goto out;
break;
case SEN_OV7620:
// Hue control is causing problems. I will enable it once it's fixed.
#if 0
- rc = ov51x_i2c_write(ov511, 0x7a,
- (unsigned char)(val >> 8) + 0xb);
+ rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb);
if (rc < 0)
goto out;
- rc = ov51x_i2c_write(ov511, 0x79,
- (unsigned char)(val >> 8) + 0xb);
+ rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb);
if (rc < 0)
goto out;
#endif
break;
case SEN_SAA7111A:
- rc = ov51x_i2c_write(ov511, 0x0d, (val + 32768) >> 8);
+ rc = i2c_w(ov, 0x0d, (val + 32768) >> 8);
if (rc < 0)
goto out;
break;
@@ -2003,9 +1987,9 @@ sensor_set_hue(struct usb_ov511 *ov511, unsigned short val)
}
rc = 0; /* Success */
- ov511->hue = val;
+ ov->hue = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -2013,29 +1997,29 @@ out:
/* Gets sensor's hue (red/blue balance) setting */
static int
-sensor_get_hue(struct usb_ov511 *ov511, unsigned short *val)
+sensor_get_hue(struct usb_ov511 *ov, unsigned short *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
- rc = ov51x_i2c_read(ov511, OV7610_REG_BLUE);
+ rc = i2c_r(ov, OV7610_REG_BLUE);
if (rc < 0)
return rc;
else
*val = rc << 8;
break;
case SEN_OV7620:
- rc = ov51x_i2c_read(ov511, 0x7a);
+ rc = i2c_r(ov, 0x7a);
if (rc < 0)
return rc;
else
*val = rc << 8;
break;
case SEN_SAA7111A:
- *val = ov511->hue;
+ *val = ov->hue;
break;
default:
PDEBUG(3, "Unsupported with this sensor");
@@ -2043,7 +2027,7 @@ sensor_get_hue(struct usb_ov511 *ov511, unsigned short *val)
}
PDEBUG(3, "%d", *val);
- ov511->hue = *val;
+ ov->hue = *val;
return 0;
}
@@ -2051,30 +2035,30 @@ sensor_get_hue(struct usb_ov511 *ov511, unsigned short *val)
/* -------------------------------------------------------------------------- */
static inline int
-sensor_set_picture(struct usb_ov511 *ov511, struct video_picture *p)
+sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p)
{
int rc;
PDEBUG(4, "sensor_set_picture");
- ov511->whiteness = p->whiteness;
+ ov->whiteness = p->whiteness;
/* Don't return error if a setting is unsupported, or rest of settings
* will not be performed */
- rc = sensor_set_contrast(ov511, p->contrast);
+ rc = sensor_set_contrast(ov, p->contrast);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_brightness(ov511, p->brightness);
+ rc = sensor_set_brightness(ov, p->brightness);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_saturation(ov511, p->colour);
+ rc = sensor_set_saturation(ov, p->colour);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_hue(ov511, p->hue);
+ rc = sensor_set_hue(ov, p->hue);
if (FATAL_ERROR(rc))
return rc;
@@ -2082,7 +2066,7 @@ sensor_set_picture(struct usb_ov511 *ov511, struct video_picture *p)
}
static inline int
-sensor_get_picture(struct usb_ov511 *ov511, struct video_picture *p)
+sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p)
{
int rc;
@@ -2091,27 +2075,27 @@ sensor_get_picture(struct usb_ov511 *ov511, struct video_picture *p)
/* Don't return error if a setting is unsupported, or rest of settings
* will not be performed */
- rc = sensor_get_contrast(ov511, &(p->contrast));
+ rc = sensor_get_contrast(ov, &(p->contrast));
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_get_brightness(ov511, &(p->brightness));
+ rc = sensor_get_brightness(ov, &(p->brightness));
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_get_saturation(ov511, &(p->colour));
+ rc = sensor_get_saturation(ov, &(p->colour));
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_get_hue(ov511, &(p->hue));
+ rc = sensor_get_hue(ov, &(p->hue));
if (FATAL_ERROR(rc))
return rc;
p->whiteness = 105 << 8;
/* Can we get these from frame[0]? -claudio? */
- p->depth = ov511->frame[0].depth;
- p->palette = ov511->frame[0].format;
+ p->depth = ov->frame[0].depth;
+ p->palette = ov->frame[0].format;
return 0;
}
@@ -2120,24 +2104,24 @@ sensor_get_picture(struct usb_ov511 *ov511, struct video_picture *p)
/* Sets current exposure for sensor. This only has an effect if auto-exposure
* is off */
static inline int
-sensor_set_exposure(struct usb_ov511 *ov511, unsigned char val)
+sensor_set_exposure(struct usb_ov511 *ov, unsigned char val)
{
int rc;
PDEBUG(3, "%d", val);
- if (ov511->stop_during_set)
- if (ov511_stop(ov511) < 0)
+ if (ov->stop_during_set)
+ if (ov51x_stop(ov) < 0)
return -EIO;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV6620:
case SEN_OV6630:
case SEN_OV7610:
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
- rc = ov51x_i2c_write(ov511, 0x10, val);
+ rc = i2c_w(ov, 0x10, val);
if (rc < 0)
goto out;
@@ -2153,9 +2137,9 @@ sensor_set_exposure(struct usb_ov511 *ov511, unsigned char val)
}
rc = 0; /* Success */
- ov511->exposure = val;
+ ov->exposure = val;
out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -2164,18 +2148,18 @@ out:
/* Gets current exposure level from sensor, regardless of whether it is under
* manual control. */
static int
-sensor_get_exposure(struct usb_ov511 *ov511, unsigned char *val)
+sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val)
{
int rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV6620:
case SEN_OV6630:
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
- rc = ov51x_i2c_read(ov511, 0x10);
+ rc = i2c_r(ov, 0x10);
if (rc < 0)
return rc;
else
@@ -2193,24 +2177,22 @@ sensor_get_exposure(struct usb_ov511 *ov511, unsigned char *val)
}
PDEBUG(3, "%d", *val);
- ov511->exposure = *val;
+ ov->exposure = *val;
return 0;
}
/* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */
static inline void
-ov51x_led_control(struct usb_ov511 *ov511, int enable)
+ov51x_led_control(struct usb_ov511 *ov, int enable)
{
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- if (ov511->bridge == BRG_OV511PLUS)
- ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_LED_CTL,
- enable ? 1 : 0);
- else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- ov511_reg_write_mask(ov511->dev, OV518_REG_GPIO_OUT,
- enable ? 0x02 : 0x00, 0x02);
+ if (ov->bridge == BRG_OV511PLUS)
+ reg_w(ov, R511_SYS_LED_CTL, enable ? 1 : 0);
+ else if (ov->bclass == BCL_OV518)
+ reg_w_mask(ov, R518_GPIO_OUT, enable ? 0x02 : 0x00, 0x02);
+
return;
}
@@ -2224,7 +2206,7 @@ ov51x_led_control(struct usb_ov511 *ov511, int enable)
* Returns: 0 for success
*/
static int
-sensor_set_light_freq(struct usb_ov511 *ov511, int freq)
+sensor_set_light_freq(struct usb_ov511 *ov, int freq)
{
int sixty;
@@ -2239,24 +2221,24 @@ sensor_set_light_freq(struct usb_ov511 *ov511, int freq)
return -EINVAL;
}
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
- ov51x_i2c_write_mask(ov511, 0x2a, sixty?0x00:0x80, 0x80);
- ov51x_i2c_write(ov511, 0x2b, sixty?0x00:0xac);
- ov51x_i2c_write_mask(ov511, 0x13, 0x10, 0x10);
- ov51x_i2c_write_mask(ov511, 0x13, 0x00, 0x10);
+ i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
+ i2c_w(ov, 0x2b, sixty?0x00:0xac);
+ i2c_w_mask(ov, 0x13, 0x10, 0x10);
+ i2c_w_mask(ov, 0x13, 0x00, 0x10);
break;
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
- ov51x_i2c_write_mask(ov511, 0x2a, sixty?0x00:0x80, 0x80);
- ov51x_i2c_write(ov511, 0x2b, sixty?0x00:0xac);
- ov51x_i2c_write_mask(ov511, 0x76, 0x01, 0x01);
+ i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
+ i2c_w(ov, 0x2b, sixty?0x00:0xac);
+ i2c_w_mask(ov, 0x76, 0x01, 0x01);
break;
case SEN_OV6620:
case SEN_OV6630:
- ov51x_i2c_write(ov511, 0x2b, sixty?0xa8:0x28);
- ov51x_i2c_write(ov511, 0x2a, sixty?0x84:0xa4);
+ i2c_w(ov, 0x2b, sixty?0xa8:0x28);
+ i2c_w(ov, 0x2a, sixty?0x84:0xa4);
break;
case SEN_KS0127:
case SEN_KS0127B:
@@ -2268,7 +2250,7 @@ sensor_set_light_freq(struct usb_ov511 *ov511, int freq)
return -EINVAL;
}
- ov511->lightfreq = freq;
+ ov->lightfreq = freq;
return 0;
}
@@ -2283,23 +2265,23 @@ sensor_set_light_freq(struct usb_ov511 *ov511, int freq)
* Returns: 0 for success
*/
static inline int
-sensor_set_banding_filter(struct usb_ov511 *ov511, int enable)
+sensor_set_banding_filter(struct usb_ov511 *ov, int enable)
{
int rc;
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- if (ov511->sensor == SEN_KS0127 || ov511->sensor == SEN_KS0127B
- || ov511->sensor == SEN_SAA7111A) {
+ if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
+ || ov->sensor == SEN_SAA7111A) {
PDEBUG(5, "Unsupported with this sensor");
return -EPERM;
}
- rc = ov51x_i2c_write_mask(ov511, 0x2d, enable?0x04:0x00, 0x04);
+ rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04);
if (rc < 0)
return rc;
- ov511->bandfilt = enable;
+ ov->bandfilt = enable;
return 0;
}
@@ -2311,23 +2293,23 @@ sensor_set_banding_filter(struct usb_ov511 *ov511, int enable)
* Returns: 0 for success
*/
static inline int
-sensor_set_auto_brightness(struct usb_ov511 *ov511, int enable)
+sensor_set_auto_brightness(struct usb_ov511 *ov, int enable)
{
int rc;
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- if (ov511->sensor == SEN_KS0127 || ov511->sensor == SEN_KS0127B
- || ov511->sensor == SEN_SAA7111A) {
+ if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
+ || ov->sensor == SEN_SAA7111A) {
PDEBUG(5, "Unsupported with this sensor");
return -EPERM;
}
- rc = ov51x_i2c_write_mask(ov511, 0x2d, enable?0x10:0x00, 0x10);
+ rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10);
if (rc < 0)
return rc;
- ov511->auto_brt = enable;
+ ov->auto_brt = enable;
return 0;
}
@@ -2339,22 +2321,22 @@ sensor_set_auto_brightness(struct usb_ov511 *ov511, int enable)
* Returns: 0 for success
*/
static inline int
-sensor_set_auto_exposure(struct usb_ov511 *ov511, int enable)
+sensor_set_auto_exposure(struct usb_ov511 *ov, int enable)
{
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
- ov51x_i2c_write_mask(ov511, 0x29, enable?0x00:0x80, 0x80);
+ i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80);
break;
case SEN_OV6620:
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
- ov51x_i2c_write_mask(ov511, 0x13, enable?0x01:0x00, 0x01);
+ i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01);
break;
case SEN_OV6630:
- ov51x_i2c_write_mask(ov511, 0x28, enable?0x00:0x10, 0x10);
+ i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10);
break;
case SEN_KS0127:
case SEN_KS0127B:
@@ -2366,7 +2348,7 @@ sensor_set_auto_exposure(struct usb_ov511 *ov511, int enable)
return -EINVAL;
}
- ov511->auto_exp = enable;
+ ov->auto_exp = enable;
return 0;
}
@@ -2379,27 +2361,27 @@ sensor_set_auto_exposure(struct usb_ov511 *ov511, int enable)
* Returns: 0 for success
*/
static int
-sensor_set_backlight(struct usb_ov511 *ov511, int enable)
+sensor_set_backlight(struct usb_ov511 *ov, int enable)
{
PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7620:
case SEN_OV8600:
- ov51x_i2c_write_mask(ov511, 0x68, enable?0xe0:0xc0, 0xe0);
- ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08);
- ov51x_i2c_write_mask(ov511, 0x28, enable?0x02:0x00, 0x02);
+ i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0);
+ i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
+ i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
break;
case SEN_OV6620:
- ov51x_i2c_write_mask(ov511, 0x4e, enable?0xe0:0xc0, 0xe0);
- ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08);
- ov51x_i2c_write_mask(ov511, 0x0e, enable?0x80:0x00, 0x80);
+ i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0);
+ i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
+ i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80);
break;
case SEN_OV6630:
- ov51x_i2c_write_mask(ov511, 0x4e, enable?0x80:0x60, 0xe0);
- ov51x_i2c_write_mask(ov511, 0x29, enable?0x08:0x00, 0x08);
- ov51x_i2c_write_mask(ov511, 0x28, enable?0x02:0x00, 0x02);
+ i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0);
+ i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
+ i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
break;
case SEN_OV7610:
case SEN_OV7620AE:
@@ -2413,7 +2395,7 @@ sensor_set_backlight(struct usb_ov511 *ov511, int enable)
return -EINVAL;
}
- ov511->backlight = enable;
+ ov->backlight = enable;
return 0;
}
@@ -2422,7 +2404,7 @@ sensor_set_backlight(struct usb_ov511 *ov511, int enable)
* planar or not), or zero for unsupported format.
*/
static inline int
-ov511_get_depth(int palette)
+get_depth(int palette)
{
switch (palette) {
case VIDEO_PALETTE_GREY: return 8;
@@ -2445,55 +2427,55 @@ get_frame_length(struct ov511_frame *frame)
return 0;
else
return ((frame->width * frame->height
- * ov511_get_depth(frame->format)) >> 3);
+ * get_depth(frame->format)) >> 3);
}
static int
-mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
+mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
int mode, int sub_flag, int qvga)
{
int clock;
/******** Mode (VGA/QVGA) and sensor specific regs ********/
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
- ov51x_i2c_write(ov511, 0x14, qvga?0x24:0x04);
+ i2c_w(ov, 0x14, qvga?0x24:0x04);
// FIXME: Does this improve the image quality or frame rate?
#if 0
- ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20);
- ov51x_i2c_write(ov511, 0x24, 0x10);
- ov51x_i2c_write(ov511, 0x25, qvga?0x40:0x8a);
- ov51x_i2c_write(ov511, 0x2f, qvga?0x30:0xb0);
- ov51x_i2c_write(ov511, 0x35, qvga?0x1c:0x9c);
+ i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
+ i2c_w(ov, 0x24, 0x10);
+ i2c_w(ov, 0x25, qvga?0x40:0x8a);
+ i2c_w(ov, 0x2f, qvga?0x30:0xb0);
+ i2c_w(ov, 0x35, qvga?0x1c:0x9c);
#endif
break;
case SEN_OV7620:
-// ov51x_i2c_write(ov511, 0x2b, 0x00);
- ov51x_i2c_write(ov511, 0x14, qvga?0xa4:0x84);
- ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20);
- ov51x_i2c_write(ov511, 0x24, qvga?0x20:0x3a);
- ov51x_i2c_write(ov511, 0x25, qvga?0x30:0x60);
- ov51x_i2c_write_mask(ov511, 0x2d, qvga?0x40:0x00, 0x40);
- ov51x_i2c_write_mask(ov511, 0x67, qvga?0xf0:0x90, 0xf0);
- ov51x_i2c_write_mask(ov511, 0x74, qvga?0x20:0x00, 0x20);
+// i2c_w(ov, 0x2b, 0x00);
+ i2c_w(ov, 0x14, qvga?0xa4:0x84);
+ i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
+ i2c_w(ov, 0x24, qvga?0x20:0x3a);
+ i2c_w(ov, 0x25, qvga?0x30:0x60);
+ i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
+ i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0);
+ i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
break;
case SEN_OV7620AE:
-// ov51x_i2c_write(ov511, 0x2b, 0x00);
- ov51x_i2c_write(ov511, 0x14, qvga?0xa4:0x84);
+// i2c_w(ov, 0x2b, 0x00);
+ i2c_w(ov, 0x14, qvga?0xa4:0x84);
// FIXME: Enable this once 7620AE uses 7620 initial settings
#if 0
- ov51x_i2c_write_mask(ov511, 0x28, qvga?0x00:0x20, 0x20);
- ov51x_i2c_write(ov511, 0x24, qvga?0x20:0x3a);
- ov51x_i2c_write(ov511, 0x25, qvga?0x30:0x60);
- ov51x_i2c_write_mask(ov511, 0x2d, qvga?0x40:0x00, 0x40);
- ov51x_i2c_write_mask(ov511, 0x67, qvga?0xb0:0x90, 0xf0);
- ov51x_i2c_write_mask(ov511, 0x74, qvga?0x20:0x00, 0x20);
+ i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
+ i2c_w(ov, 0x24, qvga?0x20:0x3a);
+ i2c_w(ov, 0x25, qvga?0x30:0x60);
+ i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
+ i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0);
+ i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
#endif
break;
case SEN_OV6620:
case SEN_OV6630:
- ov51x_i2c_write(ov511, 0x14, qvga?0x24:0x04);
+ i2c_w(ov, 0x14, qvga?0x24:0x04);
/* No special settings yet */
break;
default:
@@ -2504,19 +2486,17 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
/******** Palette-specific regs ********/
if (mode == VIDEO_PALETTE_GREY) {
- if (ov511->sensor == SEN_OV7610
- || ov511->sensor == SEN_OV7620AE) {
+ if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV7620AE) {
/* these aren't valid on the OV6620/OV7620/6630? */
- ov51x_i2c_write_mask(ov511, 0x0e, 0x40, 0x40);
+ i2c_w_mask(ov, 0x0e, 0x40, 0x40);
}
- ov51x_i2c_write_mask(ov511, 0x13, 0x20, 0x20);
+ i2c_w_mask(ov, 0x13, 0x20, 0x20);
} else {
- if (ov511->sensor == SEN_OV7610
- || ov511->sensor == SEN_OV7620AE) {
+ if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV7620AE) {
/* not valid on the OV6620/OV7620/6630? */
- ov51x_i2c_write_mask(ov511, 0x0e, 0x00, 0x40);
+ i2c_w_mask(ov, 0x0e, 0x00, 0x40);
}
- ov51x_i2c_write_mask(ov511, 0x13, 0x00, 0x20);
+ i2c_w_mask(ov, 0x13, 0x00, 0x20);
}
/******** Clock programming ********/
@@ -2525,13 +2505,13 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
/* The OV6620 needs special handling. This prevents the
* severe banding that normally occurs */
- if (ov511->sensor == SEN_OV6620 || ov511->sensor == SEN_OV6630)
+ if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
{
/* Clock down */
- ov51x_i2c_write(ov511, 0x2a, 0x04);
+ i2c_w(ov, 0x2a, 0x04);
- if (ov511->compress) {
+ if (ov->compress) {
// clock = 0; /* This ensures the highest frame rate */
clock = 3;
} else if (clockdiv == -1) { /* If user didn't override it */
@@ -2542,21 +2522,21 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
PDEBUG(4, "Setting clock divisor to %d", clock);
- ov51x_i2c_write(ov511, 0x11, clock);
+ i2c_w(ov, 0x11, clock);
- ov51x_i2c_write(ov511, 0x2a, 0x84);
+ i2c_w(ov, 0x2a, 0x84);
/* This next setting is critical. It seems to improve
* the gain or the contrast. The "reserved" bits seem
* to have some effect in this case. */
- ov51x_i2c_write(ov511, 0x2d, 0x85);
+ i2c_w(ov, 0x2d, 0x85);
}
else
{
- if (ov511->compress) {
+ if (ov->compress) {
clock = 1; /* This ensures the highest frame rate */
} else if (clockdiv == -1) { /* If user didn't override it */
/* Calculate and set the clock divisor */
- clock = ((sub_flag ? ov511->subw * ov511->subh
+ clock = ((sub_flag ? ov->subw * ov->subh
: width * height)
* (mode == VIDEO_PALETTE_GREY ? 2 : 3) / 2)
/ 66000;
@@ -2566,45 +2546,44 @@ mode_init_ov_sensor_regs(struct usb_ov511 *ov511, int width, int height,
PDEBUG(4, "Setting clock divisor to %d", clock);
- ov51x_i2c_write(ov511, 0x11, clock);
+ i2c_w(ov, 0x11, clock);
}
/******** Special Features ********/
if (framedrop >= 0)
- ov51x_i2c_write(ov511, 0x16, framedrop);
+ i2c_w(ov, 0x16, framedrop);
/* We only have code to convert GBR -> RGB24 */
if ((mode == VIDEO_PALETTE_RGB24) && sensor_gbr)
- ov51x_i2c_write_mask(ov511, 0x12, 0x08, 0x08);
+ i2c_w_mask(ov, 0x12, 0x08, 0x08);
else
- ov51x_i2c_write_mask(ov511, 0x12, 0x00, 0x08);
+ i2c_w_mask(ov, 0x12, 0x00, 0x08);
/* Test Pattern */
- ov51x_i2c_write_mask(ov511, 0x12, (testpat?0x02:0x00), 0x02);
+ i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02);
/* Auto white balance */
// if (awb)
- ov51x_i2c_write_mask(ov511, 0x12, 0x04, 0x04);
+ i2c_w_mask(ov, 0x12, 0x04, 0x04);
// else
-// ov51x_i2c_write_mask(ov511, 0x12, 0x00, 0x04);
+// i2c_w_mask(ov, 0x12, 0x00, 0x04);
- // This will go away as soon as ov511_mode_init_sensor_regs()
+ // This will go away as soon as ov51x_mode_init_sensor_regs()
// is fully tested.
/* 7620/6620/6630? don't have register 0x35, so play it safe */
- if (ov511->sensor == SEN_OV7610 ||
- ov511->sensor == SEN_OV7620AE) {
+ if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV7620AE) {
if (width == 640 && height == 480)
- ov51x_i2c_write(ov511, 0x35, 0x9e);
+ i2c_w(ov, 0x35, 0x9e);
else
- ov51x_i2c_write(ov511, 0x35, 0x1e);
+ i2c_w(ov, 0x35, 0x1e);
}
return 0;
}
static int
-set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
+set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode,
int sub_flag)
{
int ret;
@@ -2613,7 +2592,7 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
/* The different sensor ICs handle setting up of window differently.
* IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!!! */
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620AE:
hwsbase = 0x38;
@@ -2637,9 +2616,9 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
return -EINVAL;
}
- if (ov511->sensor == SEN_OV6620 || ov511->sensor == SEN_OV6630) {
+ if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) {
if (width > 176 && height > 144) { /* CIF */
- ret = mode_init_ov_sensor_regs(ov511, width, height,
+ ret = mode_init_ov_sensor_regs(ov, width, height,
mode, sub_flag, 0);
if (ret < 0)
return ret;
@@ -2651,7 +2630,7 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
err("Illegal dimensions");
return -EINVAL;
} else { /* QCIF */
- ret = mode_init_ov_sensor_regs(ov511, width, height,
+ ret = mode_init_ov_sensor_regs(ov, width, height,
mode, sub_flag, 1);
if (ret < 0)
return ret;
@@ -2660,7 +2639,7 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
}
} else {
if (width > 320 && height > 240) { /* VGA */
- ret = mode_init_ov_sensor_regs(ov511, width, height,
+ ret = mode_init_ov_sensor_regs(ov, width, height,
mode, sub_flag, 0);
if (ret < 0)
return ret;
@@ -2672,7 +2651,7 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
err("Illegal dimensions");
return -EINVAL;
} else { /* QVGA */
- ret = mode_init_ov_sensor_regs(ov511, width, height,
+ ret = mode_init_ov_sensor_regs(ov, width, height,
mode, sub_flag, 1);
if (ret < 0)
return ret;
@@ -2688,24 +2667,20 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
/* FIXME! - This needs to be changed to support 160x120 and 6620!!! */
if (sub_flag) {
- ov51x_i2c_write(ov511, 0x17, hwsbase+(ov511->subx>>hwscale));
- ov51x_i2c_write(ov511, 0x18,
- hwebase+((ov511->subx+ov511->subw)>>hwscale));
- ov51x_i2c_write(ov511, 0x19, vwsbase+(ov511->suby>>vwscale));
- ov51x_i2c_write(ov511, 0x1a,
- vwebase+((ov511->suby+ov511->subh)>>vwscale));
+ i2c_w(ov, 0x17, hwsbase+(ov->subx>>hwscale));
+ i2c_w(ov, 0x18, hwebase+((ov->subx+ov->subw)>>hwscale));
+ i2c_w(ov, 0x19, vwsbase+(ov->suby>>vwscale));
+ i2c_w(ov, 0x1a, vwebase+((ov->suby+ov->subh)>>vwscale));
} else {
- ov51x_i2c_write(ov511, 0x17, hwsbase + hoffset);
- ov51x_i2c_write(ov511, 0x18,
- hwebase + hoffset + (hwsize>>hwscale));
- ov51x_i2c_write(ov511, 0x19, vwsbase + voffset);
- ov51x_i2c_write(ov511, 0x1a,
- vwebase + voffset + (vwsize>>vwscale));
+ i2c_w(ov, 0x17, hwsbase + hoffset);
+ i2c_w(ov, 0x18, hwebase + hoffset + (hwsize>>hwscale));
+ i2c_w(ov, 0x19, vwsbase + voffset);
+ i2c_w(ov, 0x1a, vwebase + voffset + (vwsize>>vwscale));
}
#ifdef OV511_DEBUG
if (dump_sensor)
- ov51x_dump_i2c_regs(ov511);
+ dump_i2c_regs(ov);
#endif
return 0;
@@ -2716,18 +2691,14 @@ set_ov_sensor_window(struct usb_ov511 *ov511, int width, int height, int mode,
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
static int
-ov511_mode_init_regs(struct usb_ov511 *ov511,
+ov511_mode_init_regs(struct usb_ov511 *ov,
int width, int height, int mode, int sub_flag)
{
int lncnt, pxcnt, rc = 0;
- struct usb_device *dev = ov511->dev;
-
- if (!ov511 || !dev)
- return -EFAULT;
if (sub_flag) {
- width = ov511->subw;
- height = ov511->subh;
+ width = ov->subw;
+ height = ov->subh;
}
PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
@@ -2735,7 +2706,7 @@ ov511_mode_init_regs(struct usb_ov511 *ov511,
// FIXME: This should be moved to a 7111a-specific function once
// subcapture is dealt with properly
- if (ov511->sensor == SEN_SAA7111A) {
+ if (ov->sensor == SEN_SAA7111A) {
if (width == 320 && height == 240) {
/* No need to do anything special */
} else if (width == 640 && height == 480) {
@@ -2754,26 +2725,22 @@ ov511_mode_init_regs(struct usb_ov511 *ov511,
return -EINVAL;
}
- if (width < ov511->minwidth || height < ov511->minheight) {
+ if (width < ov->minwidth || height < ov->minheight) {
err("Requested dimensions are too small");
return -EINVAL;
}
- if (ov511_stop(ov511) < 0)
+ if (ov51x_stop(ov) < 0)
return -EIO;
if (mode == VIDEO_PALETTE_GREY) {
- ov511_reg_write(dev, 0x16, 0x00);
-
- /* For snapshot */
- ov511_reg_write(dev, 0x1e, 0x00);
- ov511_reg_write(dev, 0x1f, 0x01);
+ reg_w(ov, R511_CAM_UV_EN, 0x00);
+ reg_w(ov, R511_SNAP_UV_EN, 0x00);
+ reg_w(ov, R511_SNAP_OPTS, 0x01);
} else {
- ov511_reg_write(dev, 0x16, 0x01);
-
- /* For snapshot */
- ov511_reg_write(dev, 0x1e, 0x01);
- ov511_reg_write(dev, 0x1f, 0x03);
+ reg_w(ov, R511_CAM_UV_EN, 0x01);
+ reg_w(ov, R511_SNAP_UV_EN, 0x01);
+ reg_w(ov, R511_SNAP_OPTS, 0x03);
}
/* Here I'm assuming that snapshot size == image size.
@@ -2782,25 +2749,28 @@ ov511_mode_init_regs(struct usb_ov511 *ov511,
pxcnt = (width >> 3) - 1;
lncnt = (height >> 3) - 1;
- ov511_reg_write(dev, 0x12, pxcnt);
- ov511_reg_write(dev, 0x13, lncnt);
- ov511_reg_write(dev, 0x14, 0x00);
- ov511_reg_write(dev, 0x15, 0x00);
- ov511_reg_write(dev, 0x18, 0x03); /* YUV420, low pass filer on */
+ reg_w(ov, R511_CAM_PXCNT, pxcnt);
+ reg_w(ov, R511_CAM_LNCNT, lncnt);
+ reg_w(ov, R511_CAM_PXDIV, 0x00);
+ reg_w(ov, R511_CAM_LNDIV, 0x00);
+
+ /* YUV420, low pass filer on */
+ reg_w(ov, R511_CAM_OPTS, 0x03);
/* Snapshot additions */
- ov511_reg_write(dev, 0x1a, pxcnt);
- ov511_reg_write(dev, 0x1b, lncnt);
- ov511_reg_write(dev, 0x1c, 0x00);
- ov511_reg_write(dev, 0x1d, 0x00);
+ reg_w(ov, R511_SNAP_PXCNT, pxcnt);
+ reg_w(ov, R511_SNAP_LNCNT, lncnt);
+ reg_w(ov, R511_SNAP_PXDIV, 0x00);
+ reg_w(ov, R511_SNAP_LNDIV, 0x00);
- if (ov511->compress) {
- ov511_reg_write(dev, 0x78, 0x07); // Turn on Y & UV compression
- ov511_reg_write(dev, 0x79, 0x03); // Enable LUTs
- ov511_reset(ov511, OV511_RESET_OMNICE);
+ if (ov->compress) {
+ /* Enable Y and UV quantization and compression */
+ reg_w(ov, R511_COMP_EN, 0x07);
+ reg_w(ov, R511_COMP_LUT_EN, 0x03);
+ ov51x_reset(ov, OV511_RESET_OMNICE);
}
//out:
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
return rc;
@@ -2824,17 +2794,15 @@ static struct mode_list_518 mlist518[] = {
* Do not put any sensor-specific code in here (including I2C I/O functions)
*/
static int
-ov518_mode_init_regs(struct usb_ov511 *ov511,
+ov518_mode_init_regs(struct usb_ov511 *ov,
int width, int height, int mode, int sub_flag)
{
int i;
- struct usb_device *dev = ov511->dev;
- unsigned char b[3]; /* Multiple-value reg buffer */
PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
width, height, mode, sub_flag);
- if (ov511_stop(ov511) < 0)
+ if (ov51x_stop(ov) < 0)
return -EIO;
for (i = 0; mlist518[i].width; i++) {
@@ -2852,113 +2820,94 @@ ov518_mode_init_regs(struct usb_ov511 *ov511,
// pxcnt = sub_flag ? (ov511->subw >> 3) - 1 : mlist[i].pxcnt;
// lncnt = sub_flag ? (ov511->subh >> 3) - 1 : mlist[i].lncnt;
//
-// ov511_reg_write(dev, 0x12, pxcnt);
-// ov511_reg_write(dev, 0x13, lncnt);
+// reg_w(ov511, 0x12, pxcnt);
+// reg_w(ov511, 0x13, lncnt);
/******** Set the mode ********/
/* Mode independent regs */
- ov511_reg_write(dev, 0x2b, 0x00);
- ov511_reg_write(dev, 0x2d, 0x00);
- ov511_reg_write(dev, 0x3b, 0x00);
- ov511_reg_write(dev, 0x3d, 0x00);
+ reg_w(ov, 0x2b, 0x00);
+ reg_w(ov, 0x2d, 0x00);
+ reg_w(ov, 0x3b, 0x00);
+ reg_w(ov, 0x3d, 0x00);
/* Mode dependent regs. Regs 38 - 3e are always the same as
* regs 28 - 2e */
- ov511_reg_write_mask(dev, 0x28, mlist518[i].reg28
+ reg_w_mask(ov, 0x28, mlist518[i].reg28
| (mode == VIDEO_PALETTE_GREY) ? 0x80:0x00, 0x8f);
- ov511_reg_write(dev, 0x29, mlist518[i].reg29);
- ov511_reg_write(dev, 0x2a, mlist518[i].reg2a);
- ov511_reg_write(dev, 0x2c, mlist518[i].reg2c);
- ov511_reg_write(dev, 0x2e, mlist518[i].reg2e);
- ov511_reg_write_mask(dev, 0x38, mlist518[i].reg28
+ reg_w(ov, 0x29, mlist518[i].reg29);
+ reg_w(ov, 0x2a, mlist518[i].reg2a);
+ reg_w(ov, 0x2c, mlist518[i].reg2c);
+ reg_w(ov, 0x2e, mlist518[i].reg2e);
+ reg_w_mask(ov, 0x38, mlist518[i].reg28
| (mode == VIDEO_PALETTE_GREY) ? 0x80:0x00, 0x8f);
- ov511_reg_write(dev, 0x39, mlist518[i].reg29);
- ov511_reg_write(dev, 0x3a, mlist518[i].reg2a);
- ov511_reg_write(dev, 0x3c, mlist518[i].reg2c);
- ov511_reg_write(dev, 0x3e, mlist518[i].reg2e);
- ov511_reg_write(dev, 0x24, mlist518[i].reg24);
- ov511_reg_write(dev, 0x25, mlist518[i].reg25);
+ reg_w(ov, 0x39, mlist518[i].reg29);
+ reg_w(ov, 0x3a, mlist518[i].reg2a);
+ reg_w(ov, 0x3c, mlist518[i].reg2c);
+ reg_w(ov, 0x3e, mlist518[i].reg2e);
+ reg_w(ov, 0x24, mlist518[i].reg24);
+ reg_w(ov, 0x25, mlist518[i].reg25);
/* Windows driver does this here; who knows why */
- ov511_reg_write(dev, 0x2f, 0x80);
+ reg_w(ov, 0x2f, 0x80);
/******** Set the framerate (to 15 FPS) ********/
/* Mode independent, but framerate dependent, regs */
/* These are for 15 FPS only */
- ov511_reg_write(dev, 0x51, 0x08);
- ov511_reg_write(dev, 0x22, 0x18);
- ov511_reg_write(dev, 0x23, 0xff);
- ov511_reg_write(dev, 0x71, 0x19); /* Compression-related? */
+ reg_w(ov, 0x51, 0x08);
+ reg_w(ov, 0x22, 0x18);
+ reg_w(ov, 0x23, 0xff);
+ reg_w(ov, 0x71, 0x19); /* Compression-related? */
// FIXME: Sensor-specific
/* Bit 5 is what matters here. Of course, it is "reserved" */
- ov51x_i2c_write(ov511, 0x54, 0x23);
+ i2c_w(ov, 0x54, 0x23);
- ov511_reg_write(dev, 0x2f, 0x80);
+ reg_w(ov, 0x2f, 0x80);
/* Mode dependent regs */
if ((width == 352 && height == 288) ||
(width == 320 && height == 240)) {
- b[0]=0x80; b[1]=0x02;
- ov518_reg_write_multi(dev, 0x30, b, 2);
- b[0]=0x90; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc4, b, 2);
- b[0]=0xf4; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc6, b, 2);
- b[0]=0xf4; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc7, b, 2);
- b[0]=0x8e; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xc8, b, 2);
- b[0]=0x1a; b[1]=0x00; b[2]=0x02;
- ov518_reg_write_multi(dev, 0xca, b, 3);
- b[0]=0x14; b[1]=0x02;
- ov518_reg_write_multi(dev, 0xcb, b, 2);
- b[0]=0xd0; b[1]=0x07;
- ov518_reg_write_multi(dev, 0xcc, b, 2);
- b[0]=0x20; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xcd, b, 2);
- b[0]=0x60; b[1]=0x02;
- ov518_reg_write_multi(dev, 0xce, b, 2);
-
+ /* 640 (280h) byte iso packets */
+ ov518_reg_w32(ov, 0x30, 640, 2); /* 280h */
+ ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */
+ ov518_reg_w32(ov, 0xc6, 500, 2); /* 1f4h */
+ ov518_reg_w32(ov, 0xc7, 500, 2); /* 1f4h */
+ ov518_reg_w32(ov, 0xc8, 142, 2); /* 8eh */
+ ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */
+ ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */
+ ov518_reg_w32(ov, 0xcc, 2000, 2); /* 7d0h */
+ ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */
+ ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */
} else if ((width == 176 && height == 144) ||
(width == 160 && height == 120)) {
- b[0]=0x80; b[1]=0x01;
- ov518_reg_write_multi(dev, 0x30, b, 2);
- b[0]=0xc8; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xc4, b, 2);
- b[0]=0x40; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc6, b, 2);
- b[0]=0x40; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xc7, b, 2);
- b[0]=0x60; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xc8, b, 2);
- b[0]=0x0f; b[1]=0x33; b[2]=0x01;
- ov518_reg_write_multi(dev, 0xca, b, 3);
- b[0]=0x40; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xcb, b, 2);
- b[0]=0xec; b[1]=0x04;
- ov518_reg_write_multi(dev, 0xcc, b, 2);
- b[0]=0x13; b[1]=0x00;
- ov518_reg_write_multi(dev, 0xcd, b, 2);
- b[0]=0x6d; b[1]=0x01;
- ov518_reg_write_multi(dev, 0xce, b, 2);
+ /* 384 (180h) byte iso packets */
+ ov518_reg_w32(ov, 0x30, 384, 2); /* 180h */
+ ov518_reg_w32(ov, 0xc4, 200, 2); /* c8h */
+ ov518_reg_w32(ov, 0xc6, 320, 2); /* 140h */
+ ov518_reg_w32(ov, 0xc7, 320, 2); /* 140h */
+ ov518_reg_w32(ov, 0xc8, 96, 2); /* 60h */
+ ov518_reg_w32(ov, 0xca, 78607, 3); /* 1330fh */
+ ov518_reg_w32(ov, 0xcb, 320, 2); /* 140h */
+ ov518_reg_w32(ov, 0xcc, 1260, 2); /* 4ech */
+ ov518_reg_w32(ov, 0xcd, 19, 2); /* 13h */
+ ov518_reg_w32(ov, 0xce, 365, 2); /* 16dh */
} else {
/* Can't happen, since we already handled this case */
err("ov518_mode_init_regs(): **** logic error ****");
}
- ov511_reg_write(dev, 0x2f, 0x80);
+ reg_w(ov, 0x2f, 0x80);
break;
}
- if (ov511_restart(ov511) < 0)
+ if (ov51x_restart(ov) < 0)
return -EIO;
/* Reset it just for good measure */
- if (ov511_reset(ov511, OV511_RESET_NOREGS) < 0)
+ if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
return -EIO;
if (mlist518[i].width == 0) {
@@ -2971,29 +2920,31 @@ ov518_mode_init_regs(struct usb_ov511 *ov511,
/* This is a wrapper around the OV511, OV518, and sensor specific functions */
static int
-mode_init_regs(struct usb_ov511 *ov511,
+mode_init_regs(struct usb_ov511 *ov,
int width, int height, int mode, int sub_flag)
{
int rc = 0;
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
- rc = ov518_mode_init_regs(ov511, width, height, mode, sub_flag);
+ if (!ov || !ov->dev)
+ return -EFAULT;
+
+ if (ov->bclass == BCL_OV518) {
+ rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag);
} else {
- rc = ov511_mode_init_regs(ov511, width, height, mode, sub_flag);
+ rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag);
}
if (FATAL_ERROR(rc))
return rc;
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_OV7610:
case SEN_OV7620:
case SEN_OV7620AE:
case SEN_OV8600:
case SEN_OV6620:
case SEN_OV6630:
- rc = set_ov_sensor_window(ov511, width, height, mode, sub_flag);
+ rc = set_ov_sensor_window(ov, width, height, mode, sub_flag);
break;
case SEN_KS0127:
case SEN_KS0127B:
@@ -3001,10 +2952,10 @@ mode_init_regs(struct usb_ov511 *ov511,
rc = -EINVAL;
break;
case SEN_SAA7111A:
-// rc = mode_init_saa_sensor_regs(ov511, width, height, mode,
+// rc = mode_init_saa_sensor_regs(ov, width, height, mode,
// sub_flag);
- PDEBUG(1, "SAA status = 0X%x", ov51x_i2c_read(ov511, 0x1f));
+ PDEBUG(1, "SAA status = 0X%x", i2c_r(ov, 0x1f));
break;
default:
err("Unknown sensor");
@@ -3015,25 +2966,25 @@ mode_init_regs(struct usb_ov511 *ov511,
return rc;
/* Sensor-independent settings */
- rc = sensor_set_auto_brightness(ov511, ov511->auto_brt);
+ rc = sensor_set_auto_brightness(ov, ov->auto_brt);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_auto_exposure(ov511, ov511->auto_exp);
+ rc = sensor_set_auto_exposure(ov, ov->auto_exp);
if (FATAL_ERROR(rc))
return rc;
- rc = sensor_set_banding_filter(ov511, bandingfilter);
+ rc = sensor_set_banding_filter(ov, bandingfilter);
if (FATAL_ERROR(rc))
return rc;
- if (ov511->lightfreq) {
- rc = sensor_set_light_freq(ov511, lightfreq);
+ if (ov->lightfreq) {
+ rc = sensor_set_light_freq(ov, lightfreq);
if (FATAL_ERROR(rc))
return rc;
}
- rc = sensor_set_backlight(ov511, ov511->backlight);
+ rc = sensor_set_backlight(ov, ov->backlight);
if (FATAL_ERROR(rc))
return rc;
@@ -3044,28 +2995,28 @@ mode_init_regs(struct usb_ov511 *ov511,
* useful for apps that use read() and do not set these.
*/
static int
-ov51x_set_default_params(struct usb_ov511 *ov511)
+ov51x_set_default_params(struct usb_ov511 *ov)
{
int i;
- PDEBUG(3, "%dx%d, RGB24", ov511->maxwidth, ov511->maxheight);
+ PDEBUG(3, "%dx%d, RGB24", ov->maxwidth, ov->maxheight);
/* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used
* (using read() instead). */
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].width = ov511->maxwidth;
- ov511->frame[i].height = ov511->maxheight;
- ov511->frame[i].bytes_read = 0;
+ ov->frame[i].width = ov->maxwidth;
+ ov->frame[i].height = ov->maxheight;
+ ov->frame[i].bytes_read = 0;
if (force_palette)
- ov511->frame[i].format = force_palette;
+ ov->frame[i].format = force_palette;
else
- ov511->frame[i].format = VIDEO_PALETTE_RGB24;
- ov511->frame[i].depth = ov511_get_depth(ov511->frame[i].format);
+ ov->frame[i].format = VIDEO_PALETTE_RGB24;
+ ov->frame[i].depth = get_depth(ov->frame[i].format);
}
/* Initialize to max width/height, RGB24 */
- if (mode_init_regs(ov511, ov511->maxwidth, ov511->maxheight,
- ov511->frame[0].format, 0) < 0)
+ if (mode_init_regs(ov, ov->maxwidth, ov->maxheight,
+ ov->frame[0].format, 0) < 0)
return -EINVAL;
return 0;
@@ -3079,18 +3030,17 @@ ov51x_set_default_params(struct usb_ov511 *ov511)
/* Set analog input port of decoder */
static int
-decoder_set_input(struct usb_ov511 *ov511, int input)
+decoder_set_input(struct usb_ov511 *ov, int input)
{
PDEBUG(4, "port %d", input);
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_SAA7111A:
{
/* Select mode */
- ov51x_i2c_write_mask(ov511, 0x02, input, 0x07);
+ i2c_w_mask(ov, 0x02, input, 0x07);
/* Bypass chrominance trap for modes 4..7 */
- ov51x_i2c_write_mask(ov511, 0x09,
- (input > 3) ? 0x80:0x00, 0x80);
+ i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80);
break;
}
default:
@@ -3102,9 +3052,9 @@ decoder_set_input(struct usb_ov511 *ov511, int input)
/* Get ASCII name of video input */
static int
-decoder_get_input_name(struct usb_ov511 *ov511, int input, char *name)
+decoder_get_input_name(struct usb_ov511 *ov, int input, char *name)
{
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_SAA7111A:
{
if (input < 0 || input > 7)
@@ -3125,11 +3075,11 @@ decoder_get_input_name(struct usb_ov511 *ov511, int input, char *name)
/* Set norm (NTSC, PAL, SECAM, AUTO) */
static int
-decoder_set_norm(struct usb_ov511 *ov511, int norm)
+decoder_set_norm(struct usb_ov511 *ov, int norm)
{
PDEBUG(4, "%d", norm);
- switch (ov511->sensor) {
+ switch (ov->sensor) {
case SEN_SAA7111A:
{
int reg_8, reg_e;
@@ -3150,8 +3100,8 @@ decoder_set_norm(struct usb_ov511 *ov511, int norm)
return -EINVAL;
}
- ov51x_i2c_write_mask(ov511, 0x08, reg_8, 0xc0);
- ov51x_i2c_write_mask(ov511, 0x0e, reg_e, 0x70);
+ i2c_w_mask(ov, 0x08, reg_8, 0xc0);
+ i2c_w_mask(ov, 0x0e, reg_e, 0x70);
break;
}
default:
@@ -3198,8 +3148,8 @@ decoder_set_norm(struct usb_ov511 *ov511, int norm)
#define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))
static inline void
-ov511_move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v,
- int rowPixels, unsigned char * rgb, int bits)
+move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v,
+ int rowPixels, unsigned char * rgb, int bits)
{
const int rvScale = 91881;
const int guScale = -22553;
@@ -3269,10 +3219,10 @@ ov511_move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v,
**********************************************************************/
/* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the
- * array at pOut is specified by w.
+ * image at pOut is specified by w.
*/
static inline void
-ov511_make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
+make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
{
unsigned char *pOut1 = pOut;
int x, y;
@@ -3310,7 +3260,7 @@ yuv400raw_to_yuv400p(struct ov511_frame *frame,
for (y = 0; y < frame->rawheight - 1; y += 8) {
pOut = pOutLine;
for (x = 0; x < frame->rawwidth - 1; x += 8) {
- ov511_make_8x8(pIn, pOut, frame->rawwidth);
+ make_8x8(pIn, pOut, frame->rawwidth);
pIn += 64;
pOut += 8;
}
@@ -3369,8 +3319,8 @@ yuv420raw_to_yuv420p(struct ov511_frame *frame,
for (y = 0; y < frame->rawheight - 1; y += 16) {
pOut = pOutLine;
for (x = 0; x < frame->rawwidth - 1; x += 16) {
- ov511_make_8x8(pIn, pOut, w);
- ov511_make_8x8(pIn + 64, pOut + a/4, w);
+ make_8x8(pIn, pOut, w);
+ make_8x8(pIn + 64, pOut + a/4, w);
pIn += 384;
pOut += 8;
}
@@ -3384,7 +3334,7 @@ yuv420raw_to_yuv420p(struct ov511_frame *frame,
for (y = 0; y < frame->rawheight - 1; y += 8) {
pOut = pOutLine;
for (x = 0; x < frame->rawwidth - 1; x += 8) {
- ov511_make_8x8(pIn, pOut, frame->rawwidth);
+ make_8x8(pIn, pOut, frame->rawwidth);
pIn += 64;
pOut += 8;
if ((++k) > 3) {
@@ -3441,17 +3391,17 @@ fixFrameRGBoffset(struct ov511_frame *frame)
*
**********************************************************************/
-/* Chooses a decompression module, locks it, and sets ov511->decomp_ops
+/* Chooses a decompression module, locks it, and sets ov->decomp_ops
* accordingly. Returns -ENXIO if decompressor is not available, otherwise
* returns 0 if no other error.
*/
static int
-ov51x_request_decompressor(struct usb_ov511 *ov511)
+request_decompressor(struct usb_ov511 *ov)
{
- if (!ov511)
+ if (!ov)
return -ENODEV;
- if (ov511->decomp_ops) {
+ if (ov->decomp_ops) {
err("ERROR: Decompressor already requested!");
return -EINVAL;
}
@@ -3459,24 +3409,23 @@ ov51x_request_decompressor(struct usb_ov511 *ov511)
lock_kernel();
/* Try to get MMX, and fall back on no-MMX if necessary */
- if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS) {
+ if (ov->bclass == BCL_OV511) {
if (ov511_mmx_decomp_ops) {
PDEBUG(3, "Using OV511 MMX decompressor");
- ov511->decomp_ops = ov511_mmx_decomp_ops;
+ ov->decomp_ops = ov511_mmx_decomp_ops;
} else if (ov511_decomp_ops) {
PDEBUG(3, "Using OV511 decompressor");
- ov511->decomp_ops = ov511_decomp_ops;
+ ov->decomp_ops = ov511_decomp_ops;
} else {
err("No decompressor available");
}
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ } else if (ov->bclass == BCL_OV518) {
if (ov518_mmx_decomp_ops) {
PDEBUG(3, "Using OV518 MMX decompressor");
- ov511->decomp_ops = ov518_mmx_decomp_ops;
+ ov->decomp_ops = ov518_mmx_decomp_ops;
} else if (ov518_decomp_ops) {
PDEBUG(3, "Using OV518 decompressor");
- ov511->decomp_ops = ov518_decomp_ops;
+ ov->decomp_ops = ov518_decomp_ops;
} else {
err("No decompressor available");
}
@@ -3484,13 +3433,13 @@ ov51x_request_decompressor(struct usb_ov511 *ov511)
err("Unknown bridge");
}
- if (ov511->decomp_ops) {
- if (!ov511->decomp_ops->decomp_lock) {
- ov511->decomp_ops = NULL;
+ if (ov->decomp_ops) {
+ if (!ov->decomp_ops->decomp_lock) {
+ ov->decomp_ops = NULL;
unlock_kernel();
return -ENOSYS;
}
- ov511->decomp_ops->decomp_lock();
+ ov->decomp_ops->decomp_lock();
unlock_kernel();
return 0;
} else {
@@ -3499,25 +3448,25 @@ ov51x_request_decompressor(struct usb_ov511 *ov511)
}
}
-/* Unlocks decompression module and nulls ov511->decomp_ops. Safe to call even
- * if ov511->decomp_ops is NULL.
+/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even
+ * if ov->decomp_ops is NULL.
*/
static void
-ov51x_release_decompressor(struct usb_ov511 *ov511)
+release_decompressor(struct usb_ov511 *ov)
{
int released = 0; /* Did we actually do anything? */
- if (!ov511)
+ if (!ov)
return;
lock_kernel();
- if (ov511->decomp_ops && ov511->decomp_ops->decomp_unlock) {
- ov511->decomp_ops->decomp_unlock();
+ if (ov->decomp_ops && ov->decomp_ops->decomp_unlock) {
+ ov->decomp_ops->decomp_unlock();
released = 1;
}
- ov511->decomp_ops = NULL;
+ ov->decomp_ops = NULL;
unlock_kernel();
@@ -3526,26 +3475,26 @@ ov51x_release_decompressor(struct usb_ov511 *ov511)
}
static void
-ov51x_decompress(struct usb_ov511 *ov511, struct ov511_frame *frame,
- unsigned char *pIn0, unsigned char *pOut0)
+decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
+ unsigned char *pIn0, unsigned char *pOut0)
{
- if (!ov511->decomp_ops)
- if (ov51x_request_decompressor(ov511))
+ if (!ov->decomp_ops)
+ if (request_decompressor(ov))
return;
PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd);
if (frame->format == VIDEO_PALETTE_GREY
- && ov511->decomp_ops->decomp_400) {
- int ret = ov511->decomp_ops->decomp_400(
+ && ov->decomp_ops->decomp_400) {
+ int ret = ov->decomp_ops->decomp_400(
pIn0,
pOut0,
frame->rawwidth,
frame->rawheight,
frame->bytes_recvd);
PDEBUG(4, "DEBUG: decomp_400 returned %d", ret);
- } else if (ov511->decomp_ops->decomp_420) {
- int ret = ov511->decomp_ops->decomp_420(
+ } else if (ov->decomp_ops->decomp_420) {
+ int ret = ov->decomp_ops->decomp_420(
pIn0,
pOut0,
frame->rawwidth,
@@ -3585,8 +3534,8 @@ yuv420p_to_rgb(struct ov511_frame *frame,
u = (*pU++) - 128;
v = (*pV++) - 128;
- ov511_move_420_block(y00, y01, y10, y11, u, v,
- frame->width, pOut, bits);
+ move_420_block(y00, y01, y10, y11, u, v,
+ frame->width, pOut, bits);
pY += 2;
pOut += 2 * bytes;
@@ -3741,11 +3690,11 @@ deinterlace(struct ov511_frame *frame, int rawformat,
* 4. Fix the RGB offset, if necessary
*/
static void
-ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
+ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
{
if (dumppix) {
memset(frame->data, 0,
- MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight));
+ MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd);
memmove(frame->data, frame->rawdata, frame->bytes_recvd);
return;
@@ -3754,9 +3703,9 @@ ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
/* YUV400 must be handled separately */
if (frame->format == VIDEO_PALETTE_GREY) {
/* Deinterlace frame, if necessary */
- if (ov511->sensor == SEN_SAA7111A && frame->rawheight == 480) {
+ if (ov->sensor == SEN_SAA7111A && frame->rawheight == 480) {
if (frame->compressed)
- ov51x_decompress(ov511, frame, frame->rawdata,
+ decompress(ov, frame, frame->rawdata,
frame->tempdata);
else
yuv400raw_to_yuv400p(frame, frame->rawdata,
@@ -3766,7 +3715,7 @@ ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
frame->data);
} else {
if (frame->compressed)
- ov51x_decompress(ov511, frame, frame->rawdata,
+ decompress(ov, frame, frame->rawdata,
frame->data);
else
yuv400raw_to_yuv400p(frame, frame->rawdata,
@@ -3778,12 +3727,12 @@ ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
/* Process frame->data to frame->rawdata */
if (frame->compressed)
- ov51x_decompress(ov511, frame, frame->rawdata, frame->tempdata);
+ decompress(ov, frame, frame->rawdata, frame->tempdata);
else
yuv420raw_to_yuv420p(frame, frame->rawdata, frame->tempdata);
/* Deinterlace frame, if necessary */
- if (ov511->sensor == SEN_SAA7111A && frame->rawheight == 480) {
+ if (ov->sensor == SEN_SAA7111A && frame->rawheight == 480) {
memmove(frame->rawdata, frame->tempdata,
MAX_RAW_DATA_SIZE(frame->width, frame->height));
deinterlace(frame, RAWFMT_YUV420, frame->rawdata,
@@ -3837,7 +3786,7 @@ ov511_postprocess(struct usb_ov511 *ov511, struct ov511_frame *frame)
**********************************************************************/
static int
-ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
+ov511_move_data(struct usb_ov511 *ov, struct urb *urb)
{
unsigned char *cdata;
int data_size, num, offset, i, totlen = 0;
@@ -3847,7 +3796,7 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
PDEBUG(5, "Moving %d packets", urb->number_of_packets);
- data_size = ov511->packet_size - 1;
+ data_size = ov->packet_size - 1;
for (i = 0; i < urb->number_of_packets; i++) {
int n = urb->iso_frame_desc[i].actual_length;
@@ -3858,15 +3807,15 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
- aPackNum[i] = n ? cdata[ov511->packet_size - 1] : -1;
+ aPackNum[i] = n ? cdata[ov->packet_size - 1] : -1;
- if (!n || ov511->curframe == -1)
+ if (!n || ov->curframe == -1)
continue;
if (st)
PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);
- frame = &ov511->frame[ov511->curframe];
+ frame = &ov->frame[ov->curframe];
/* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
* byte non-zero. The EOF packet has image width/height in the
@@ -3884,7 +3833,7 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
if (printph) {
info("packet header (%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x",
- cdata[ov511->packet_size - 1],
+ cdata[ov->packet_size - 1],
cdata[0], cdata[1], cdata[2], cdata[3], cdata[4], cdata[5],
cdata[6], cdata[7], cdata[8], cdata[9], cdata[10], cdata[11]);
}
@@ -3898,7 +3847,7 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
/* Frame end */
if (cdata[8] & 0x80) {
ts = (struct timeval *)(frame->data
- + MAX_FRAME_SIZE(ov511->maxwidth, ov511->maxheight));
+ + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
do_gettimeofday(ts);
/* Get the actual frame size from the EOF header */
@@ -3906,21 +3855,21 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
frame->rawheight = ((int)(cdata[10]) + 1) * 8;
PDEBUG(4, "Frame end, curframe = %d, packnum=%d, hw=%d, vw=%d, recvd=%d",
- ov511->curframe,
- (int)(cdata[ov511->packet_size - 1]),
+ ov->curframe,
+ (int)(cdata[ov->packet_size - 1]),
frame->rawwidth,
frame->rawheight,
frame->bytes_recvd);
/* Validate the header data */
- RESTRICT_TO_RANGE(frame->rawwidth, ov511->minwidth, ov511->maxwidth);
- RESTRICT_TO_RANGE(frame->rawheight, ov511->minheight, ov511->maxheight);
+ RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
+ RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
/* Don't allow byte count to exceed buffer size */
RESTRICT_TO_RANGE(frame->bytes_recvd,
8,
- MAX_RAW_DATA_SIZE(ov511->maxwidth,
- ov511->maxheight));
+ MAX_RAW_DATA_SIZE(ov->maxwidth,
+ ov->maxheight));
if (frame->scanstate == STATE_LINES) {
int iFrameNext;
@@ -3934,20 +3883,20 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
/* If next frame is ready or grabbing,
* point to it */
- iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
- if (ov511->frame[iFrameNext].grabstate == FRAME_READY
- || ov511->frame[iFrameNext].grabstate == FRAME_GRABBING) {
- ov511->curframe = iFrameNext;
- ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
+ iFrameNext = (ov->curframe + 1) % OV511_NUMFRAMES;
+ if (ov->frame[iFrameNext].grabstate == FRAME_READY
+ || ov->frame[iFrameNext].grabstate == FRAME_GRABBING) {
+ ov->curframe = iFrameNext;
+ ov->frame[iFrameNext].scanstate = STATE_SCANNING;
} else {
if (frame->grabstate == FRAME_DONE) {
PDEBUG(4, "Frame done! congratulations");
} else {
PDEBUG(4, "Frame not ready? state = %d",
- ov511->frame[iFrameNext].grabstate);
+ ov->frame[iFrameNext].grabstate);
}
- ov511->curframe = -1;
+ ov->curframe = -1;
}
} else {
PDEBUG(5, "Frame done, but not scanning");
@@ -3957,7 +3906,7 @@ ov511_move_data(struct usb_ov511 *ov511, struct urb *urb)
*/
} else {
/* Frame start */
- PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);
+ PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
/* Check to see if it's a snapshot frame */
/* FIXME?? Should the snapshot reset go here? Performance? */
@@ -4006,24 +3955,24 @@ check_middle:
/* Dump all data exactly as received */
if (dumppix == 2) {
frame->bytes_recvd += n - 1;
- if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight))
+ if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight))
memmove(frame->rawdata + frame->bytes_recvd - (n - 1),
&cdata[0], n - 1);
else
PDEBUG(3, "Raw data buffer overrun!! (%d)",
frame->bytes_recvd
- - MAX_RAW_DATA_SIZE(ov511->maxwidth,
- ov511->maxheight));
+ - MAX_RAW_DATA_SIZE(ov->maxwidth,
+ ov->maxheight));
} else if (!frame->compressed && !remove_zeros) {
frame->bytes_recvd += num;
- if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight))
+ if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight))
memmove(frame->rawdata + frame->bytes_recvd - num,
&cdata[offset], num);
else
PDEBUG(3, "Raw data buffer overrun!! (%d)",
frame->bytes_recvd
- - MAX_RAW_DATA_SIZE(ov511->maxwidth,
- ov511->maxheight));
+ - MAX_RAW_DATA_SIZE(ov->maxwidth,
+ ov->maxheight));
} else { /* Remove all-zero FIFO lines (aligned 32-byte blocks) */
int b, in = 0, allzero, copied=0;
if (offset) {
@@ -4046,7 +3995,7 @@ check_middle:
/* Don't copy it */
} else {
if (frame->bytes_recvd + copied + 32
- <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight)) {
+ <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight)) {
memmove(frame->rawdata + frame->bytes_recvd + copied,
&cdata[in], 32);
copied += 32;
@@ -4070,7 +4019,7 @@ check_middle:
}
static int
-ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
+ov518_move_data(struct usb_ov511 *ov, struct urb *urb)
{
unsigned char *cdata;
int i, data_size, totlen = 0;
@@ -4080,7 +4029,7 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
PDEBUG(5, "Moving %d packets", urb->number_of_packets);
/* OV518(+) has no packet numbering */
- data_size = ov511->packet_size;
+ data_size = ov->packet_size;
for (i = 0; i < urb->number_of_packets; i++) {
int n = urb->iso_frame_desc[i].actual_length;
@@ -4096,7 +4045,7 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
continue;
}
- if (ov511->curframe == -1) {
+ if (ov->curframe == -1) {
PDEBUG(4, "No frame currently active");
continue;
}
@@ -4104,21 +4053,7 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
if (st)
PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);
- frame = &ov511->frame[ov511->curframe];
-
-#if 0
- {
- int d;
- /* Print all data */
- for (d = 0; d <= data_size - 16; d += 16) {
- info("%4x: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", d,
- cdata[d], cdata[d+1], cdata[d+2], cdata[d+3],
- cdata[d+4], cdata[d+5], cdata[d+6], cdata[d+7],
- cdata[d+8], cdata[d+9], cdata[d+10], cdata[d+11],
- cdata[d+12], cdata[d+13], cdata[d+14], cdata[d+15]);
- }
- }
-#endif
+ frame = &ov->frame[ov->curframe];
if (printph) {
info("packet header: %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x",
@@ -4136,7 +4071,7 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
goto eof;
} else { //scanstate == STATE_SCANNING
/* Frame start */
- PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);
+ PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
goto sof;
}
} else {
@@ -4145,11 +4080,11 @@ ov518_move_data(struct usb_ov511 *ov511, struct urb *urb)
eof:
ts = (struct timeval *)(frame->data
- + MAX_FRAME_SIZE(ov511->maxwidth, ov511->maxheight));
+ + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
do_gettimeofday(ts);
PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d",
- ov511->curframe,
+ ov->curframe,
(int)(cdata[9]), (int)(cdata[10]), frame->bytes_recvd);
// FIXME: Since we don't know the header formats yet,
@@ -4158,13 +4093,13 @@ eof:
frame->rawheight = frame->height;
/* Validate the header data */
- RESTRICT_TO_RANGE(frame->rawwidth, ov511->minwidth, ov511->maxwidth);
- RESTRICT_TO_RANGE(frame->rawheight, ov511->minheight, ov511->maxheight);
+ RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
+ RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
/* Don't allow byte count to exceed buffer size */
RESTRICT_TO_RANGE(frame->bytes_recvd,
8,
- MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight));
+ MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight));
if (frame->scanstate == STATE_LINES) {
int iFrameNext;
@@ -4178,21 +4113,21 @@ eof:
/* If next frame is ready or grabbing,
* point to it */
- iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
- if (ov511->frame[iFrameNext].grabstate == FRAME_READY
- || ov511->frame[iFrameNext].grabstate == FRAME_GRABBING) {
- ov511->curframe = iFrameNext;
- ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
- frame = &ov511->frame[iFrameNext];
+ iFrameNext = (ov->curframe + 1) % OV511_NUMFRAMES;
+ if (ov->frame[iFrameNext].grabstate == FRAME_READY
+ || ov->frame[iFrameNext].grabstate == FRAME_GRABBING) {
+ ov->curframe = iFrameNext;
+ ov->frame[iFrameNext].scanstate = STATE_SCANNING;
+ frame = &ov->frame[iFrameNext];
} else {
if (frame->grabstate == FRAME_DONE) {
PDEBUG(4, "Frame done! congratulations");
} else {
PDEBUG(4, "Frame not ready? state = %d",
- ov511->frame[iFrameNext].grabstate);
+ ov->frame[iFrameNext].grabstate);
}
- ov511->curframe = -1;
+ ov->curframe = -1;
PDEBUG(4, "SOF dropped (no active frame)");
continue; /* Nowhere to store this frame */
}
@@ -4225,31 +4160,26 @@ check_middle:
/* Dump all data exactly as received */
if (dumppix == 2) {
frame->bytes_recvd += n;
- if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight))
+ if (frame->bytes_recvd <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight))
memmove(frame->rawdata + frame->bytes_recvd - n,
&cdata[0], n);
else
PDEBUG(3, "Raw data buffer overrun!! (%d)",
frame->bytes_recvd
- - MAX_RAW_DATA_SIZE(ov511->maxwidth,
- ov511->maxheight));
+ - MAX_RAW_DATA_SIZE(ov->maxwidth,
+ ov->maxheight));
} else {
/* All incoming data are divided into 8-byte segments. If the
* segment contains all zero bytes, it must be skipped. These
* zero-segments allow the OV518 to mainain a constant data rate
* regardless of the effectiveness of the compression. Segments
* are aligned relative to the beginning of each isochronous
- * packet. The first segment is a header.
+ * packet. The first segment is a header (the decompressor
+ * skips it later).
*/
int b, in = 0, allzero, copied=0;
-// Decompressor expects the header
-#if 0
- if (frame->bytes_recvd == 0)
- in += 8; /* Skip header */
-#endif
-
while (in < n) {
allzero = 1;
for (b = 0; b < 8; b++) {
@@ -4263,7 +4193,7 @@ check_middle:
/* Don't copy it */
} else {
if (frame->bytes_recvd + copied + 8
- <= MAX_RAW_DATA_SIZE(ov511->maxwidth, ov511->maxheight)) {
+ <= MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight)) {
memmove(frame->rawdata + frame->bytes_recvd + copied,
&cdata[in], 8);
copied += 8;
@@ -4281,43 +4211,41 @@ check_middle:
}
static void
-ov511_isoc_irq(struct urb *urb)
+ov51x_isoc_irq(struct urb *urb)
{
int len;
- struct usb_ov511 *ov511;
+ struct usb_ov511 *ov;
if (!urb->context) {
PDEBUG(4, "no context");
return;
}
- ov511 = (struct usb_ov511 *) urb->context;
+ ov = (struct usb_ov511 *) urb->context;
- if (!ov511->dev || !ov511->user) {
+ if (!ov || !ov->dev || !ov->user) {
PDEBUG(4, "no device, or not open");
return;
}
- if (!ov511->streaming) {
+ if (!ov->streaming) {
PDEBUG(4, "hmmm... not streaming, but got interrupt");
return;
}
/* Copy the data received into our frame buffer */
- if (ov511->curframe >= 0) {
- if (ov511->bridge == BRG_OV511 ||
- ov511->bridge == BRG_OV511PLUS)
- len = ov511_move_data(ov511, urb);
- else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- len = ov518_move_data(ov511, urb);
+ if (ov->curframe >= 0) {
+ if (ov->bclass == BCL_OV511)
+ len = ov511_move_data(ov, urb);
+ else if (ov->bclass == BCL_OV518)
+ len = ov518_move_data(ov, urb);
else
- err("Unknown bridge device (%d)", ov511->bridge);
- } else if (waitqueue_active(&ov511->wq)) {
- wake_up_interruptible(&ov511->wq);
+ err("Unknown bridge device (%d)", ov->bridge);
+ } else if (waitqueue_active(&ov->wq)) {
+ wake_up_interruptible(&ov->wq);
}
- urb->dev = ov511->dev;
+ urb->dev = ov->dev;
return;
}
@@ -4329,16 +4257,16 @@ ov511_isoc_irq(struct urb *urb)
***************************************************************************/
static int
-ov511_init_isoc(struct usb_ov511 *ov511)
+ov51x_init_isoc(struct usb_ov511 *ov)
{
struct urb *urb;
int fx, err, n, size;
PDEBUG(3, "*** Initializing capture ***");
- ov511->curframe = -1;
+ ov->curframe = -1;
- if (ov511->bridge == BRG_OV511) {
+ if (ov->bridge == BRG_OV511) {
if (cams == 1) size = 993;
else if (cams == 2) size = 513;
else if (cams == 3 || cams == 4) size = 257;
@@ -4346,7 +4274,7 @@ ov511_init_isoc(struct usb_ov511 *ov511)
err("\"cams\" parameter too high!");
return -1;
}
- } else if (ov511->bridge == BRG_OV511PLUS) {
+ } else if (ov->bridge == BRG_OV511PLUS) {
if (cams == 1) size = 961;
else if (cams == 2) size = 513;
else if (cams == 3 || cams == 4) size = 257;
@@ -4356,8 +4284,7 @@ ov511_init_isoc(struct usb_ov511 *ov511)
err("\"cams\" parameter too high!");
return -1;
}
- } else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
+ } else if (ov->bclass == BCL_OV518) {
if (cams == 1) size = 896;
else if (cams == 2) size = 512;
else if (cams == 3 || cams == 4) size = 256;
@@ -4373,14 +4300,13 @@ ov511_init_isoc(struct usb_ov511 *ov511)
if (packetsize == -1) {
// FIXME: OV518 is hardcoded to 15 FPS (alternate 5) for now
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- ov511_set_packet_size(ov511, 640);
+ if (ov->bclass == BCL_OV518)
+ ov51x_set_packet_size(ov, 640);
else
- ov511_set_packet_size(ov511, size);
+ ov51x_set_packet_size(ov, size);
} else {
info("Forcing packet size to %d", packetsize);
- ov511_set_packet_size(ov511, packetsize);
+ ov51x_set_packet_size(ov, packetsize);
}
for (n = 0; n < OV511_NUMSBUF; n++) {
@@ -4390,32 +4316,30 @@ ov511_init_isoc(struct usb_ov511 *ov511)
err("init isoc: usb_alloc_urb ret. NULL");
return -ENOMEM;
}
- ov511->sbuf[n].urb = urb;
- urb->dev = ov511->dev;
- urb->context = ov511;
- urb->pipe = usb_rcvisocpipe(ov511->dev, OV511_ENDPOINT_ADDRESS);
+ ov->sbuf[n].urb = urb;
+ urb->dev = ov->dev;
+ urb->context = ov;
+ urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS);
urb->transfer_flags = USB_ISO_ASAP;
- urb->transfer_buffer = ov511->sbuf[n].data;
- urb->complete = ov511_isoc_irq;
+ urb->transfer_buffer = ov->sbuf[n].data;
+ urb->complete = ov51x_isoc_irq;
urb->number_of_packets = FRAMES_PER_DESC;
- urb->transfer_buffer_length =
- ov511->packet_size * FRAMES_PER_DESC;
+ urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC;
for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
- urb->iso_frame_desc[fx].offset =
- ov511->packet_size * fx;
- urb->iso_frame_desc[fx].length = ov511->packet_size;
+ urb->iso_frame_desc[fx].offset = ov->packet_size * fx;
+ urb->iso_frame_desc[fx].length = ov->packet_size;
}
}
- ov511->streaming = 1;
+ ov->streaming = 1;
- ov511->sbuf[OV511_NUMSBUF - 1].urb->next = ov511->sbuf[0].urb;
+ ov->sbuf[OV511_NUMSBUF - 1].urb->next = ov->sbuf[0].urb;
for (n = 0; n < OV511_NUMSBUF - 1; n++)
- ov511->sbuf[n].urb->next = ov511->sbuf[n+1].urb;
+ ov->sbuf[n].urb->next = ov->sbuf[n+1].urb;
for (n = 0; n < OV511_NUMSBUF; n++) {
- ov511->sbuf[n].urb->dev = ov511->dev;
- err = usb_submit_urb(ov511->sbuf[n].urb, GFP_KERNEL);
+ ov->sbuf[n].urb->dev = ov->dev;
+ err = usb_submit_urb(ov->sbuf[n].urb, GFP_KERNEL);
if (err)
err("init isoc: usb_submit_urb(%d) ret %d", n, err);
}
@@ -4424,51 +4348,51 @@ ov511_init_isoc(struct usb_ov511 *ov511)
}
static void
-ov511_stop_isoc(struct usb_ov511 *ov511)
+ov51x_stop_isoc(struct usb_ov511 *ov)
{
int n;
- if (!ov511->streaming || !ov511->dev)
+ if (!ov->streaming || !ov->dev)
return;
PDEBUG(3, "*** Stopping capture ***");
- ov511_set_packet_size(ov511, 0);
+ ov51x_set_packet_size(ov, 0);
- ov511->streaming = 0;
+ ov->streaming = 0;
/* Unschedule all of the iso td's */
for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
- if (ov511->sbuf[n].urb) {
- ov511->sbuf[n].urb->next = NULL;
- usb_unlink_urb(ov511->sbuf[n].urb);
- usb_free_urb(ov511->sbuf[n].urb);
- ov511->sbuf[n].urb = NULL;
+ if (ov->sbuf[n].urb) {
+ ov->sbuf[n].urb->next = NULL;
+ usb_unlink_urb(ov->sbuf[n].urb);
+ usb_free_urb(ov->sbuf[n].urb);
+ ov->sbuf[n].urb = NULL;
}
}
}
static int
-ov511_new_frame(struct usb_ov511 *ov511, int framenum)
+ov51x_new_frame(struct usb_ov511 *ov, int framenum)
{
struct ov511_frame *frame;
int newnum;
- PDEBUG(4, "ov511->curframe = %d, framenum = %d", ov511->curframe,
- framenum);
- if (!ov511->dev)
+ PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum);
+
+ if (!ov->dev)
return -1;
/* If we're not grabbing a frame right now and the other frame is */
/* ready to be grabbed into, then use it instead */
- if (ov511->curframe == -1) {
+ if (ov->curframe == -1) {
newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES;
- if (ov511->frame[newnum].grabstate == FRAME_READY)
+ if (ov->frame[newnum].grabstate == FRAME_READY)
framenum = newnum;
} else
return 0;
- frame = &ov511->frame[framenum];
+ frame = &ov->frame[framenum];
PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum,
frame->width, frame->height);
@@ -4477,16 +4401,16 @@ ov511_new_frame(struct usb_ov511 *ov511, int framenum)
frame->scanstate = STATE_SCANNING;
frame->snapshot = 0;
- ov511->curframe = framenum;
+ ov->curframe = framenum;
/* Make sure it's not too big */
- if (frame->width > ov511->maxwidth)
- frame->width = ov511->maxwidth;
+ if (frame->width > ov->maxwidth)
+ frame->width = ov->maxwidth;
frame->width &= ~7L; /* Multiple of 8 */
- if (frame->height > ov511->maxheight)
- frame->height = ov511->maxheight;
+ if (frame->height > ov->maxheight)
+ frame->height = ov->maxheight;
frame->height &= ~3L; /* Multiple of 4 */
@@ -4498,84 +4422,86 @@ ov511_new_frame(struct usb_ov511 *ov511, int framenum)
* Buffer management
*
***************************************************************************/
+
static int
-ov511_alloc(struct usb_ov511 *ov511)
+ov51x_alloc(struct usb_ov511 *ov)
{
int i;
- int w = ov511->maxwidth;
- int h = ov511->maxheight;
+ const int w = ov->maxwidth;
+ const int h = ov->maxheight;
+ const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h);
+ const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h);
PDEBUG(4, "entered");
- down(&ov511->buf_lock);
+ down(&ov->buf_lock);
- if (ov511->buf_state == BUF_PEND_DEALLOC) {
- ov511->buf_state = BUF_ALLOCATED;
- del_timer(&ov511->buf_timer);
+ if (ov->buf_state == BUF_PEND_DEALLOC) {
+ ov->buf_state = BUF_ALLOCATED;
+ del_timer(&ov->buf_timer);
}
- if (ov511->buf_state == BUF_ALLOCATED)
+ if (ov->buf_state == BUF_ALLOCATED)
goto out;
- ov511->fbuf = rvmalloc(OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
- if (!ov511->fbuf)
+ ov->fbuf = rvmalloc(data_bufsize);
+ if (!ov->fbuf)
goto error;
- ov511->rawfbuf = vmalloc(OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
- if (!ov511->rawfbuf) {
- rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
- ov511->fbuf = NULL;
+ ov->rawfbuf = vmalloc(raw_bufsize);
+ if (!ov->rawfbuf) {
+ rvfree(ov->fbuf, data_bufsize);
+ ov->fbuf = NULL;
goto error;
}
- memset(ov511->rawfbuf, 0, OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
+ memset(ov->rawfbuf, 0, raw_bufsize);
- ov511->tempfbuf = vmalloc(OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
- if (!ov511->tempfbuf) {
- vfree(ov511->rawfbuf);
- ov511->rawfbuf = NULL;
- rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
- ov511->fbuf = NULL;
+ ov->tempfbuf = vmalloc(raw_bufsize);
+ if (!ov->tempfbuf) {
+ vfree(ov->rawfbuf);
+ ov->rawfbuf = NULL;
+ rvfree(ov->fbuf, data_bufsize);
+ ov->fbuf = NULL;
goto error;
}
- memset(ov511->tempfbuf, 0, OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h));
+ memset(ov->tempfbuf, 0, raw_bufsize);
for (i = 0; i < OV511_NUMSBUF; i++) {
- ov511->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
+ ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL);
- if (!ov511->sbuf[i].data) {
+ if (!ov->sbuf[i].data) {
while (--i) {
- kfree(ov511->sbuf[i].data);
- ov511->sbuf[i].data = NULL;
+ kfree(ov->sbuf[i].data);
+ ov->sbuf[i].data = NULL;
}
- vfree(ov511->tempfbuf);
- ov511->tempfbuf = NULL;
- vfree(ov511->rawfbuf);
- ov511->rawfbuf = NULL;
- rvfree(ov511->fbuf,
- OV511_NUMFRAMES * MAX_DATA_SIZE(w, h));
- ov511->fbuf = NULL;
+ vfree(ov->tempfbuf);
+ ov->tempfbuf = NULL;
+ vfree(ov->rawfbuf);
+ ov->rawfbuf = NULL;
+ rvfree(ov->fbuf, data_bufsize);
+ ov->fbuf = NULL;
goto error;
}
- PDEBUG(4, "sbuf[%d] @ %p", i, ov511->sbuf[i].data);
+ PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data);
}
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].data = ov511->fbuf + i * MAX_DATA_SIZE(w, h);
- ov511->frame[i].rawdata = ov511->rawfbuf
+ ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h);
+ ov->frame[i].rawdata = ov->rawfbuf
+ i * MAX_RAW_DATA_SIZE(w, h);
- ov511->frame[i].tempdata = ov511->tempfbuf
+ ov->frame[i].tempdata = ov->tempfbuf
+ i * MAX_RAW_DATA_SIZE(w, h);
- PDEBUG(4, "frame[%d] @ %p", i, ov511->frame[i].data);
+ PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data);
}
- ov511->buf_state = BUF_ALLOCATED;
+ ov->buf_state = BUF_ALLOCATED;
out:
- up(&ov511->buf_lock);
+ up(&ov->buf_lock);
PDEBUG(4, "leaving");
return 0;
error:
- ov511->buf_state = BUF_NOT_ALLOCATED;
- up(&ov511->buf_lock);
+ ov->buf_state = BUF_NOT_ALLOCATED;
+ up(&ov->buf_lock);
PDEBUG(4, "errored");
return -ENOMEM;
}
@@ -4586,206 +4512,211 @@ error:
* them if you explicitly free them somewhere else!
*/
static void
-ov511_do_dealloc(struct usb_ov511 *ov511)
+ov51x_do_dealloc(struct usb_ov511 *ov)
{
int i;
PDEBUG(4, "entered");
- if (ov511->fbuf) {
- rvfree(ov511->fbuf, OV511_NUMFRAMES
- * MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight));
- ov511->fbuf = NULL;
+ if (ov->fbuf) {
+ rvfree(ov->fbuf, OV511_NUMFRAMES
+ * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
+ ov->fbuf = NULL;
}
- if (ov511->rawfbuf) {
- vfree(ov511->rawfbuf);
- ov511->rawfbuf = NULL;
+ if (ov->rawfbuf) {
+ vfree(ov->rawfbuf);
+ ov->rawfbuf = NULL;
}
- if (ov511->tempfbuf) {
- vfree(ov511->tempfbuf);
- ov511->tempfbuf = NULL;
+ if (ov->tempfbuf) {
+ vfree(ov->tempfbuf);
+ ov->tempfbuf = NULL;
}
for (i = 0; i < OV511_NUMSBUF; i++) {
- if (ov511->sbuf[i].data) {
- kfree(ov511->sbuf[i].data);
- ov511->sbuf[i].data = NULL;
+ if (ov->sbuf[i].data) {
+ kfree(ov->sbuf[i].data);
+ ov->sbuf[i].data = NULL;
}
}
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].data = NULL;
- ov511->frame[i].rawdata = NULL;
- ov511->frame[i].tempdata = NULL;
+ ov->frame[i].data = NULL;
+ ov->frame[i].rawdata = NULL;
+ ov->frame[i].tempdata = NULL;
}
PDEBUG(4, "buffer memory deallocated");
- ov511->buf_state = BUF_NOT_ALLOCATED;
+ ov->buf_state = BUF_NOT_ALLOCATED;
PDEBUG(4, "leaving");
}
static void
-ov511_buf_callback(unsigned long data)
+ov51x_buf_callback(unsigned long data)
{
- struct usb_ov511 *ov511 = (struct usb_ov511 *)data;
+ struct usb_ov511 *ov = (struct usb_ov511 *)data;
PDEBUG(4, "entered");
- down(&ov511->buf_lock);
+ down(&ov->buf_lock);
- if (ov511->buf_state == BUF_PEND_DEALLOC)
- ov511_do_dealloc(ov511);
+ if (ov->buf_state == BUF_PEND_DEALLOC)
+ ov51x_do_dealloc(ov);
- up(&ov511->buf_lock);
+ up(&ov->buf_lock);
PDEBUG(4, "leaving");
}
static void
-ov511_dealloc(struct usb_ov511 *ov511, int now)
+ov51x_dealloc(struct usb_ov511 *ov, int now)
{
- struct timer_list *bt = &(ov511->buf_timer);
+ struct timer_list *bt = &(ov->buf_timer);
PDEBUG(4, "entered");
- down(&ov511->buf_lock);
+ down(&ov->buf_lock);
PDEBUG(4, "deallocating buffer memory %s", now ? "now" : "later");
- if (ov511->buf_state == BUF_PEND_DEALLOC) {
- ov511->buf_state = BUF_ALLOCATED;
+ if (ov->buf_state == BUF_PEND_DEALLOC) {
+ ov->buf_state = BUF_ALLOCATED;
del_timer(bt);
}
if (now)
- ov511_do_dealloc(ov511);
+ ov51x_do_dealloc(ov);
else {
- ov511->buf_state = BUF_PEND_DEALLOC;
+ ov->buf_state = BUF_PEND_DEALLOC;
init_timer(bt);
- bt->function = ov511_buf_callback;
- bt->data = (unsigned long)ov511;
+ bt->function = ov51x_buf_callback;
+ bt->data = (unsigned long)ov;
bt->expires = jiffies + buf_timeout * HZ;
add_timer(bt);
}
- up(&ov511->buf_lock);
+ up(&ov->buf_lock);
PDEBUG(4, "leaving");
}
/****************************************************************************
*
- * V4L API
+ * V4L 1 API
*
***************************************************************************/
static int
-ov511_open(struct video_device *vdev, int flags)
+ov51x_v4l1_open(struct video_device *vdev, int flags)
{
- struct usb_ov511 *ov511 = vdev->priv;
+ struct usb_ov511 *ov = vdev->priv;
int err, i;
PDEBUG(4, "opening");
- down(&ov511->lock);
+ down(&ov->lock);
err = -EBUSY;
- if (ov511->user)
+ if (ov->user)
goto out;
err = -ENOMEM;
- if (ov511_alloc(ov511))
+ if (ov51x_alloc(ov))
goto out;
- ov511->sub_flag = 0;
+ ov->sub_flag = 0;
/* In case app doesn't set them... */
- if (ov51x_set_default_params(ov511) < 0)
+ if (ov51x_set_default_params(ov) < 0)
goto out;
/* Make sure frames are reset */
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].grabstate = FRAME_UNUSED;
- ov511->frame[i].bytes_read = 0;
+ ov->frame[i].grabstate = FRAME_UNUSED;
+ ov->frame[i].bytes_read = 0;
}
/* If compression is on, make sure now that a
* decompressor can be loaded */
- if (ov511->compress && !ov511->decomp_ops) {
- err = ov51x_request_decompressor(ov511);
- if (err)
+ if (ov->compress && !ov->decomp_ops) {
+ err = request_decompressor(ov);
+ if (err && !dumppix)
goto out;
}
- err = ov511_init_isoc(ov511);
+ err = ov51x_init_isoc(ov);
if (err) {
- ov511_dealloc(ov511, 0);
+ ov51x_dealloc(ov, 0);
goto out;
}
- ov511->user++;
+ ov->user++;
- if (ov511->led_policy == LED_AUTO)
- ov51x_led_control(ov511, 1);
+ if (ov->led_policy == LED_AUTO)
+ ov51x_led_control(ov, 1);
out:
- up(&ov511->lock);
-
+ up(&ov->lock);
return err;
}
static void
-ov511_close(struct video_device *dev)
+ov51x_v4l1_close(struct video_device *vdev)
{
- struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
+ struct usb_ov511 *ov = vdev->priv;
PDEBUG(4, "ov511_close");
- down(&ov511->lock);
+ down(&ov->lock);
- ov511->user--;
- ov511_stop_isoc(ov511);
+ ov->user--;
+ ov51x_stop_isoc(ov);
- ov51x_release_decompressor(ov511);
+ release_decompressor(ov);
- if (ov511->led_policy == LED_AUTO)
- ov51x_led_control(ov511, 0);
+ if (ov->led_policy == LED_AUTO)
+ ov51x_led_control(ov, 0);
- if (ov511->dev)
- ov511_dealloc(ov511, 0);
+ if (ov->dev)
+ ov51x_dealloc(ov, 0);
- up(&ov511->lock);
+ up(&ov->lock);
/* Device unplugged while open. Only a minimum of unregistration is done
* here; the disconnect callback already did the rest. */
- if (!ov511->dev) {
- ov511_dealloc(ov511, 1);
- video_unregister_device(&ov511->vdev);
- kfree(ov511);
- ov511 = NULL;
+ if (!ov->dev) {
+ down(&ov->cbuf_lock);
+ kfree(ov->cbuf);
+ ov->cbuf = NULL;
+ up(&ov->cbuf_lock);
+
+ ov51x_dealloc(ov, 1);
+ video_unregister_device(&ov->vdev);
+ kfree(ov);
+ ov = NULL;
}
}
static int
-ov511_init_done(struct video_device *vdev)
+ov51x_v4l1_init_done(struct video_device *vdev)
{
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
- create_proc_ov511_cam((struct usb_ov511 *)vdev);
+ create_proc_ov511_cam(vdev->priv);
#endif
return 0;
}
static long
-ov511_write(struct video_device *vdev, const char *buf,
- unsigned long count, int noblock)
+ov51x_v4l1_write(struct video_device *vdev, const char *buf,
+ unsigned long count, int noblock)
{
return -EINVAL;
}
/* Do not call this function directly! */
static int
-ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
+ov51x_v4l1_ioctl_internal(struct video_device *vdev, unsigned int cmd,
+ void *arg)
{
- struct usb_ov511 *ov511 = (struct usb_ov511 *)vdev;
+ struct usb_ov511 *ov = vdev->priv;
PDEBUG(5, "IOCtl: 0x%X", cmd);
- if (!ov511->dev)
+ if (!ov->dev)
return -EIO;
switch (cmd) {
@@ -4797,20 +4728,20 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
memset(&b, 0, sizeof(b));
sprintf(b.name, "%s USB Camera",
- ov511->bridge == BRG_OV511 ? "OV511" :
- ov511->bridge == BRG_OV511PLUS ? "OV511+" :
- ov511->bridge == BRG_OV518 ? "OV518" :
- ov511->bridge == BRG_OV518PLUS ? "OV518+" :
+ ov->bridge == BRG_OV511 ? "OV511" :
+ ov->bridge == BRG_OV511PLUS ? "OV511+" :
+ ov->bridge == BRG_OV518 ? "OV518" :
+ ov->bridge == BRG_OV518PLUS ? "OV518+" :
"unknown");
b.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
- if (ov511->has_tuner)
+ if (ov->has_tuner)
b.type |= VID_TYPE_TUNER;
- b.channels = ov511->num_inputs;
- b.audios = ov511->has_audio_proc ? 1:0;
- b.maxwidth = ov511->maxwidth;
- b.maxheight = ov511->maxheight;
- b.minwidth = ov511->minwidth;
- b.minheight = ov511->minheight;
+ b.channels = ov->num_inputs;
+ b.audios = ov->has_audio_proc ? 1:0;
+ b.maxwidth = ov->maxwidth;
+ b.maxheight = ov->maxheight;
+ b.minwidth = ov->minwidth;
+ b.minheight = ov->minheight;
if (copy_to_user(arg, &b, sizeof(b)))
return -EFAULT;
@@ -4826,18 +4757,18 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
if (copy_from_user(&v, arg, sizeof(v)))
return -EFAULT;
- if ((unsigned)(v.channel) >= ov511->num_inputs) {
+ if ((unsigned)(v.channel) >= ov->num_inputs) {
err("Invalid channel (%d)", v.channel);
return -EINVAL;
}
- v.norm = ov511->norm;
- v.type = (ov511->has_tuner) ? VIDEO_TYPE_TV : VIDEO_TYPE_CAMERA;
- v.flags = (ov511->has_tuner) ? VIDEO_VC_TUNER : 0;
- v.flags |= (ov511->has_audio_proc) ? VIDEO_VC_AUDIO : 0;
-// v.flags |= (ov511->has_decoder) ? VIDEO_VC_NORM : 0;
- v.tuners = (ov511->has_tuner) ? 1:0;
- decoder_get_input_name(ov511, v.channel, v.name);
+ v.norm = ov->norm;
+ v.type = (ov->has_tuner) ? VIDEO_TYPE_TV : VIDEO_TYPE_CAMERA;
+ v.flags = (ov->has_tuner) ? VIDEO_VC_TUNER : 0;
+ v.flags |= (ov->has_audio_proc) ? VIDEO_VC_AUDIO : 0;
+// v.flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0;
+ v.tuners = (ov->has_tuner) ? 1:0;
+ decoder_get_input_name(ov, v.channel, v.name);
if (copy_to_user(arg, &v, sizeof(v)))
return -EFAULT;
@@ -4855,7 +4786,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EFAULT;
/* Make sure it's not a camera */
- if (!ov511->has_decoder) {
+ if (!ov->has_decoder) {
if (v.channel == 0)
return 0;
else
@@ -4870,16 +4801,16 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
}
- if ((unsigned)(v.channel) >= ov511->num_inputs) {
+ if ((unsigned)(v.channel) >= ov->num_inputs) {
err("Invalid channel (%d)", v.channel);
return -EINVAL;
}
- err = decoder_set_input(ov511, v.channel);
+ err = decoder_set_input(ov, v.channel);
if (err)
return err;
- err = decoder_set_norm(ov511, v.norm);
+ err = decoder_set_norm(ov, v.norm);
if (err)
return err;
@@ -4893,7 +4824,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
memset(&p, 0, sizeof(p));
- if (sensor_get_picture(ov511, &p))
+ if (sensor_get_picture(ov, &p))
return -EIO;
if (copy_to_user(arg, &p, sizeof(p)))
@@ -4911,10 +4842,10 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
if (copy_from_user(&p, arg, sizeof(p)))
return -EFAULT;
- if (!ov511_get_depth(p.palette))
+ if (!get_depth(p.palette))
return -EINVAL;
- if (sensor_set_picture(ov511, &p))
+ if (sensor_set_picture(ov, &p))
return -EIO;
if (force_palette && p.palette != force_palette) {
@@ -4923,23 +4854,22 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
}
// FIXME: Format should be independent of frames
- if (p.palette != ov511->frame[0].format) {
+ if (p.palette != ov->frame[0].format) {
PDEBUG(4, "Detected format change");
/* If we're collecting previous frame wait
before changing modes */
- interruptible_sleep_on(&ov511->wq);
+ interruptible_sleep_on(&ov->wq);
if (signal_pending(current)) return -EINTR;
- mode_init_regs(ov511, ov511->frame[0].width,
- ov511->frame[0].height, p.palette,
- ov511->sub_flag);
+ mode_init_regs(ov, ov->frame[0].width,
+ ov->frame[0].height, p.palette, ov->sub_flag);
}
PDEBUG(4, "Setting depth=%d, palette=%d", p.depth, p.palette);
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].depth = p.depth;
- ov511->frame[i].format = p.palette;
+ ov->frame[i].depth = p.depth;
+ ov->frame[i].format = p.palette;
}
return 0;
@@ -4952,7 +4882,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
if (copy_from_user(&vf, arg, sizeof(vf)))
return -EFAULT;
- ov511->sub_flag = vf;
+ ov->sub_flag = vf;
return 0;
}
case VIDIOCSCAPTURE:
@@ -4980,10 +4910,10 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
if (vc.height == 0)
vc.height = 16;
- ov511->subx = vc.x;
- ov511->suby = vc.y;
- ov511->subw = vc.width;
- ov511->subh = vc.height;
+ ov->subx = vc.x;
+ ov->suby = vc.y;
+ ov->subw = vc.width;
+ ov->subh = vc.height;
return 0;
}
@@ -5003,25 +4933,25 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
if (vw.clipcount)
return -EINVAL;
- if (vw.height != ov511->maxheight)
+ if (vw.height != ov->maxheight)
return -EINVAL;
- if (vw.width != ov511->maxwidth)
+ if (vw.width != ov->maxwidth)
return -EINVAL;
#endif
/* If we're collecting previous frame wait
before changing modes */
- interruptible_sleep_on(&ov511->wq);
+ interruptible_sleep_on(&ov->wq);
if (signal_pending(current)) return -EINTR;
- result = mode_init_regs(ov511, vw.width, vw.height,
- ov511->frame[0].format, ov511->sub_flag);
+ result = mode_init_regs(ov, vw.width, vw.height,
+ ov->frame[0].format, ov->sub_flag);
if (result < 0)
return result;
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].width = vw.width;
- ov511->frame[i].height = vw.height;
+ ov->frame[i].width = vw.width;
+ ov->frame[i].height = vw.height;
}
return 0;
@@ -5033,8 +4963,8 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
memset(&vw, 0, sizeof(vw));
vw.x = 0; /* FIXME */
vw.y = 0;
- vw.width = ov511->frame[0].width;
- vw.height = ov511->frame[0].height;
+ vw.width = ov->frame[0].width;
+ vw.height = ov->frame[0].height;
vw.flags = 30;
PDEBUG(4, "VIDIOCGWIN: %dx%d", vw.width, vw.height);
@@ -5053,13 +4983,13 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
memset(&vm, 0, sizeof(vm));
vm.size = OV511_NUMFRAMES
- * MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight);
+ * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
vm.frames = OV511_NUMFRAMES;
vm.offsets[0] = 0;
for (i = 1; i < OV511_NUMFRAMES; i++) {
vm.offsets[i] = vm.offsets[i-1]
- + MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight);
+ + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
}
if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
@@ -5079,7 +5009,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
PDEBUG(4, "frame: %d, size: %dx%d, format: %d",
vm.frame, vm.width, vm.height, vm.format);
- depth = ov511_get_depth(vm.format);
+ depth = get_depth(vm.format);
if (!depth) {
err("VIDIOCMCAPTURE: invalid format (%d)", vm.format);
return -EINVAL;
@@ -5090,13 +5020,13 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
}
- if (vm.width > ov511->maxwidth
- || vm.height > ov511->maxheight) {
+ if (vm.width > ov->maxwidth
+ || vm.height > ov->maxheight) {
err("VIDIOCMCAPTURE: requested dimensions too big");
return -EINVAL;
}
- if (ov511->frame[vm.frame].grabstate == FRAME_GRABBING) {
+ if (ov->frame[vm.frame].grabstate == FRAME_GRABBING) {
PDEBUG(4, "VIDIOCMCAPTURE: already grabbing");
return -EBUSY;
}
@@ -5106,38 +5036,38 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
}
- if ((ov511->frame[vm.frame].width != vm.width) ||
- (ov511->frame[vm.frame].height != vm.height) ||
- (ov511->frame[vm.frame].format != vm.format) ||
- (ov511->frame[vm.frame].sub_flag != ov511->sub_flag) ||
- (ov511->frame[vm.frame].depth != depth)) {
+ if ((ov->frame[vm.frame].width != vm.width) ||
+ (ov->frame[vm.frame].height != vm.height) ||
+ (ov->frame[vm.frame].format != vm.format) ||
+ (ov->frame[vm.frame].sub_flag != ov->sub_flag) ||
+ (ov->frame[vm.frame].depth != depth)) {
PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters");
/* If we're collecting previous frame wait
before changing modes */
- interruptible_sleep_on(&ov511->wq);
+ interruptible_sleep_on(&ov->wq);
if (signal_pending(current)) return -EINTR;
- ret = mode_init_regs(ov511, vm.width, vm.height,
- vm.format, ov511->sub_flag);
+ ret = mode_init_regs(ov, vm.width, vm.height,
+ vm.format, ov->sub_flag);
#if 0
if (ret < 0) {
PDEBUG(1, "Got error while initializing regs ");
return ret;
}
#endif
- ov511->frame[vm.frame].width = vm.width;
- ov511->frame[vm.frame].height = vm.height;
- ov511->frame[vm.frame].format = vm.format;
- ov511->frame[vm.frame].sub_flag = ov511->sub_flag;
- ov511->frame[vm.frame].depth = depth;
+ ov->frame[vm.frame].width = vm.width;
+ ov->frame[vm.frame].height = vm.height;
+ ov->frame[vm.frame].format = vm.format;
+ ov->frame[vm.frame].sub_flag = ov->sub_flag;
+ ov->frame[vm.frame].depth = depth;
}
/* Mark it as ready */
- ov511->frame[vm.frame].grabstate = FRAME_READY;
+ ov->frame[vm.frame].grabstate = FRAME_READY;
PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", vm.frame);
- return ov511_new_frame(ov511, vm.frame);
+ return ov51x_new_frame(ov, vm.frame);
}
case VIDIOCSYNC:
{
@@ -5152,7 +5082,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
return -EINVAL;
}
- frame = &ov511->frame[fnum];
+ frame = &ov->frame[fnum];
PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum,
frame->grabstate);
@@ -5164,7 +5094,7 @@ ov511_ioctl_internal(struct video_device *vdev, unsigned int cmd, void *arg)
case FRAME_GRABBING:
case FRAME_ERROR:
redo:
- if (!ov511->dev)
+ if (!ov->dev)
return -EIO;
rc = wait_event_interruptible(frame->wq,
@@ -5177,15 +5107,15 @@ redo:
if (frame->grabstate == FRAME_ERROR) {
int ret;
- if ((ret = ov511_new_frame(ov511, fnum)) < 0)
+ if ((ret = ov51x_new_frame(ov, fnum)) < 0)
return ret;
goto redo;
}
/* Fall through */
case FRAME_DONE:
- if (ov511->snap_enabled && !frame->snapshot) {
+ if (ov->snap_enabled && !frame->snapshot) {
int ret;
- if ((ret = ov511_new_frame(ov511, fnum)) < 0)
+ if ((ret = ov51x_new_frame(ov, fnum)) < 0)
return ret;
goto redo;
}
@@ -5194,13 +5124,13 @@ redo:
/* Reset the hardware snapshot button */
/* FIXME - Is this the best place for this? */
- if ((ov511->snap_enabled) && (frame->snapshot)) {
+ if ((ov->snap_enabled) && (frame->snapshot)) {
frame->snapshot = 0;
- ov51x_clear_snapshot(ov511);
+ ov51x_clear_snapshot(ov);
}
/* Decompression, format conversion, etc... */
- ov511_postprocess(ov511, frame);
+ ov51x_postprocess(ov, frame);
break;
} /* end switch */
@@ -5229,7 +5159,7 @@ redo:
memset(&vu, 0, sizeof(vu));
- vu.video = ov511->vdev.minor; /* Video minor */
+ vu.video = ov->vdev.minor; /* Video minor */
vu.vbi = VIDEO_NO_UNIT; /* VBI minor */
vu.radio = VIDEO_NO_UNIT; /* Radio minor */
vu.audio = VIDEO_NO_UNIT; /* Audio minor */
@@ -5249,7 +5179,7 @@ redo:
if (copy_from_user(&v, arg, sizeof(v)))
return -EFAULT;
- if (!ov511->has_tuner || v.tuner) // Only tuner 0
+ if (!ov->has_tuner || v.tuner) // Only tuner 0
return -EINVAL;
strcpy(v.name, "Television");
@@ -5263,7 +5193,7 @@ redo:
v.mode = 0; /* FIXME: Not sure what this is yet */
v.signal = 0xFFFF; /* unknown */
- call_i2c_clients(ov511, cmd, &v);
+ call_i2c_clients(ov, cmd, &v);
if (copy_to_user(arg, &v, sizeof(v)))
return -EFAULT;
@@ -5281,7 +5211,7 @@ redo:
return -EFAULT;
/* Only no or one tuner for now */
- if (!ov511->has_tuner || v.tuner)
+ if (!ov->has_tuner || v.tuner)
return -EINVAL;
/* and it only has certain valid modes */
@@ -5290,21 +5220,21 @@ redo:
v.mode != VIDEO_MODE_SECAM) return -EOPNOTSUPP;
/* Is this right/necessary? */
- err = decoder_set_norm(ov511, v.mode);
+ err = decoder_set_norm(ov, v.mode);
if (err)
return err;
- call_i2c_clients(ov511, cmd, &v);
+ call_i2c_clients(ov, cmd, &v);
return 0;
}
case VIDIOCGFREQ:
{
- unsigned long v = ov511->freq;
+ unsigned long v = ov->freq;
PDEBUG(4, "VIDIOCGFREQ");
- if (!ov511->has_tuner)
+ if (!ov->has_tuner)
return -EINVAL;
#if 0
/* FIXME: this is necessary for testing */
@@ -5319,7 +5249,7 @@ redo:
{
unsigned long v;
- if (!ov511->has_tuner)
+ if (!ov->has_tuner)
return -EINVAL;
if (copy_from_user(&v, arg, sizeof(v)))
@@ -5327,8 +5257,8 @@ redo:
PDEBUG(4, "VIDIOCSFREQ: %lx", v);
- ov511->freq = v;
- call_i2c_clients(ov511, cmd, &v);
+ ov->freq = v;
+ call_i2c_clients(ov, cmd, &v);
return 0;
}
@@ -5347,29 +5277,29 @@ redo:
}
static int
-ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
+ov51x_v4l1_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
{
int rc;
- struct usb_ov511 *ov511 = vdev->priv;
+ struct usb_ov511 *ov = vdev->priv;
- if (down_interruptible(&ov511->lock))
+ if (down_interruptible(&ov->lock))
return -EINTR;
- rc = ov511_ioctl_internal(vdev, cmd, arg);
+ rc = ov51x_v4l1_ioctl_internal(vdev, cmd, arg);
- up(&ov511->lock);
+ up(&ov->lock);
return rc;
}
static inline long
-ov511_read(struct video_device *vdev, char *buf, unsigned long count,
- int noblock)
+ov51x_v4l1_read(struct video_device *vdev, char *buf, unsigned long count,
+ int noblock)
{
- struct usb_ov511 *ov511 = vdev->priv;
+ struct usb_ov511 *ov = vdev->priv;
int i, rc = 0, frmx = -1;
struct ov511_frame *frame;
- if (down_interruptible(&ov511->lock))
+ if (down_interruptible(&ov->lock))
return -EINTR;
PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
@@ -5379,16 +5309,16 @@ ov511_read(struct video_device *vdev, char *buf, unsigned long count,
goto error;
}
- if (!ov511->dev) {
+ if (!ov->dev) {
rc = -EIO;
goto error;
}
// FIXME: Only supports two frames
/* See if a frame is completed, then use it. */
- if (ov511->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */
+ if (ov->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */
frmx = 0;
- else if (ov511->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
+ else if (ov->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
frmx = 1;
/* If nonblocking we return immediately */
@@ -5400,24 +5330,24 @@ ov511_read(struct video_device *vdev, char *buf, unsigned long count,
/* If no FRAME_DONE, look for a FRAME_GRABBING state. */
/* See if a frame is in process (grabbing), then use it. */
if (frmx == -1) {
- if (ov511->frame[0].grabstate == FRAME_GRABBING)
+ if (ov->frame[0].grabstate == FRAME_GRABBING)
frmx = 0;
- else if (ov511->frame[1].grabstate == FRAME_GRABBING)
+ else if (ov->frame[1].grabstate == FRAME_GRABBING)
frmx = 1;
}
/* If no frame is active, start one. */
if (frmx == -1) {
- if ((rc = ov511_new_frame(ov511, frmx = 0))) {
- err("read: ov511_new_frame error");
+ if ((rc = ov51x_new_frame(ov, frmx = 0))) {
+ err("read: ov51x_new_frame error");
goto error;
}
}
- frame = &ov511->frame[frmx];
+ frame = &ov->frame[frmx];
restart:
- if (!ov511->dev) {
+ if (!ov->dev) {
rc = -EIO;
goto error;
}
@@ -5436,9 +5366,9 @@ restart:
if (frame->grabstate == FRAME_ERROR) {
frame->bytes_read = 0;
- err("** ick! ** Errored frame %d", ov511->curframe);
- if (ov511_new_frame(ov511, frmx)) {
- err("read: ov511_new_frame error");
+ err("** ick! ** Errored frame %d", ov->curframe);
+ if (ov51x_new_frame(ov, frmx)) {
+ err("read: ov51x_new_frame error");
goto error;
}
goto restart;
@@ -5446,25 +5376,25 @@ restart:
/* Repeat until we get a snapshot frame */
- if (ov511->snap_enabled)
+ if (ov->snap_enabled)
PDEBUG(4, "Waiting snapshot frame");
- if (ov511->snap_enabled && !frame->snapshot) {
+ if (ov->snap_enabled && !frame->snapshot) {
frame->bytes_read = 0;
- if ((rc = ov511_new_frame(ov511, frmx))) {
- err("read: ov511_new_frame error");
+ if ((rc = ov51x_new_frame(ov, frmx))) {
+ err("read: ov51x_new_frame error");
goto error;
}
goto restart;
}
/* Clear the snapshot */
- if (ov511->snap_enabled && frame->snapshot) {
+ if (ov->snap_enabled && frame->snapshot) {
frame->snapshot = 0;
- ov51x_clear_snapshot(ov511);
+ ov51x_clear_snapshot(ov);
}
/* Decompression, format conversion, etc... */
- ov511_postprocess(ov511, frame);
+ ov51x_postprocess(ov, frame);
PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx,
frame->bytes_read,
@@ -5496,48 +5426,49 @@ restart:
// FIXME: Only supports two frames
/* Mark it as available to be used again. */
- ov511->frame[frmx].grabstate = FRAME_UNUSED;
- if ((rc = ov511_new_frame(ov511, !frmx))) {
- err("ov511_new_frame returned error");
+ ov->frame[frmx].grabstate = FRAME_UNUSED;
+ if ((rc = ov51x_new_frame(ov, !frmx))) {
+ err("ov51x_new_frame returned error");
goto error;
}
}
PDEBUG(4, "read finished, returning %ld (sweet)", count);
- up(&ov511->lock);
+ up(&ov->lock);
return count;
error:
- up(&ov511->lock);
+ up(&ov->lock);
return rc;
}
static int
-ov511_mmap(struct vm_area_struct *vma, struct video_device *vdev, const char *adr, unsigned long size)
+ov51x_v4l1_mmap(struct vm_area_struct *vma, struct video_device *vdev,
+ const char *adr, unsigned long size)
{
- struct usb_ov511 *ov511 = vdev->priv;
+ struct usb_ov511 *ov = vdev->priv;
unsigned long start = (unsigned long)adr;
unsigned long page, pos;
- if (ov511->dev == NULL)
+ if (ov->dev == NULL)
return -EIO;
PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
if (size > (((OV511_NUMFRAMES
- * MAX_DATA_SIZE(ov511->maxwidth, ov511->maxheight)
+ * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
+ PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
return -EINVAL;
- if (down_interruptible(&ov511->lock))
+ if (down_interruptible(&ov->lock))
return -EINTR;
- pos = (unsigned long)ov511->fbuf;
+ pos = (unsigned long)ov->fbuf;
while (size > 0) {
page = kvirt_to_pa(pos);
if (remap_page_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
- up(&ov511->lock);
+ up(&ov->lock);
return -EAGAIN;
}
start += PAGE_SIZE;
@@ -5548,31 +5479,31 @@ ov511_mmap(struct vm_area_struct *vma, struct video_device *vdev, const char *ad
size = 0;
}
- up(&ov511->lock);
+ up(&ov->lock);
return 0;
}
-static struct video_device ov511_template = {
+static struct video_device vdev_template = {
owner: THIS_MODULE,
name: "OV511 USB Camera",
type: VID_TYPE_CAPTURE,
hardware: VID_HARDWARE_OV511,
- open: ov511_open,
- close: ov511_close,
- read: ov511_read,
- write: ov511_write,
- ioctl: ov511_ioctl,
- mmap: ov511_mmap,
- initialize: ov511_init_done,
+ open: ov51x_v4l1_open,
+ close: ov51x_v4l1_close,
+ read: ov51x_v4l1_read,
+ write: ov51x_v4l1_write,
+ ioctl: ov51x_v4l1_ioctl,
+ mmap: ov51x_v4l1_mmap,
+ initialize: ov51x_v4l1_init_done,
};
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
static int
-ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+ov51x_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long ularg)
{
struct proc_dir_entry *pde;
- struct usb_ov511 *ov511;
+ struct usb_ov511 *ov;
void *arg = (void *) ularg;
int rc;
@@ -5580,11 +5511,11 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (!pde)
return -ENOENT;
- ov511 = (struct usb_ov511 *) pde->data;
- if (!ov511)
+ ov = (struct usb_ov511 *) pde->data;
+ if (!ov)
return -ENODEV;
- if (!ov511->dev)
+ if (!ov->dev)
return -EIO;
/* Should we pass through standard V4L IOCTLs? */
@@ -5609,19 +5540,19 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (opt.optnum) {
case OV511_USOPT_BRIGHT:
- rc = sensor_get_brightness(ov511, &(opt.val));
+ rc = sensor_get_brightness(ov, &(opt.val));
if (rc) return rc;
break;
case OV511_USOPT_SAT:
- rc = sensor_get_saturation(ov511, &(opt.val));
+ rc = sensor_get_saturation(ov, &(opt.val));
if (rc) return rc;
break;
case OV511_USOPT_HUE:
- rc = sensor_get_hue(ov511, &(opt.val));
+ rc = sensor_get_hue(ov, &(opt.val));
if (rc) return rc;
break;
case OV511_USOPT_CONTRAST:
- rc = sensor_get_contrast(ov511, &(opt.val));
+ rc = sensor_get_contrast(ov, &(opt.val));
if (rc) return rc;
break;
default:
@@ -5643,19 +5574,19 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (opt.optnum) {
case OV511_USOPT_BRIGHT:
- rc = sensor_set_brightness(ov511, opt.val);
+ rc = sensor_set_brightness(ov, opt.val);
if (rc) return rc;
break;
case OV511_USOPT_SAT:
- rc = sensor_set_saturation(ov511, opt.val);
+ rc = sensor_set_saturation(ov, opt.val);
if (rc) return rc;
break;
case OV511_USOPT_HUE:
- rc = sensor_set_hue(ov511, opt.val);
+ rc = sensor_set_hue(ov, opt.val);
if (rc) return rc;
break;
case OV511_USOPT_CONTRAST:
- rc = sensor_set_contrast(ov511, opt.val);
+ rc = sensor_set_contrast(ov, opt.val);
if (rc) return rc;
break;
default:
@@ -5674,19 +5605,19 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (opt.optnum) {
case OV511_UIOPT_POWER_FREQ:
- opt.val = ov511->lightfreq;
+ opt.val = ov->lightfreq;
break;
case OV511_UIOPT_BFILTER:
- opt.val = ov511->bandfilt;
+ opt.val = ov->bandfilt;
break;
case OV511_UIOPT_LED:
- opt.val = ov511->led_policy;
+ opt.val = ov->led_policy;
break;
case OV511_UIOPT_DEBUG:
opt.val = debug;
break;
case OV511_UIOPT_COMPRESS:
- opt.val = ov511->compress;
+ opt.val = ov->compress;
break;
default:
err("Invalid get int option number");
@@ -5707,20 +5638,20 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
switch (opt.optnum) {
case OV511_UIOPT_POWER_FREQ:
- rc = sensor_set_light_freq(ov511, opt.val);
+ rc = sensor_set_light_freq(ov, opt.val);
if (rc) return rc;
break;
case OV511_UIOPT_BFILTER:
- rc = sensor_set_banding_filter(ov511, opt.val);
+ rc = sensor_set_banding_filter(ov, opt.val);
if (rc) return rc;
break;
case OV511_UIOPT_LED:
if (opt.val <= 2) {
- ov511->led_policy = opt.val;
- if (ov511->led_policy == LED_OFF)
- ov51x_led_control(ov511, 0);
- else if (ov511->led_policy == LED_ON)
- ov51x_led_control(ov511, 1);
+ ov->led_policy = opt.val;
+ if (ov->led_policy == LED_OFF)
+ ov51x_led_control(ov, 0);
+ else if (ov->led_policy == LED_ON)
+ ov51x_led_control(ov, 1);
} else {
return -EINVAL;
}
@@ -5732,14 +5663,12 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
return -EINVAL;
break;
case OV511_UIOPT_COMPRESS:
- ov511->compress = opt.val;
- if (ov511->compress) {
- if (ov511->bridge == BRG_OV511 ||
- ov511->bridge == BRG_OV511PLUS)
- ov511_init_compression(ov511);
- else if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS)
- ov518_init_compression(ov511);
+ ov->compress = opt.val;
+ if (ov->compress) {
+ if (ov->bclass == BCL_OV511)
+ ov511_init_compression(ov);
+ else if (ov->bclass == BCL_OV518)
+ ov518_init_compression(ov);
}
break;
default:
@@ -5756,7 +5685,7 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (copy_from_user(&w, arg, sizeof(w)))
return -EFAULT;
- return ov51x_i2c_write_slave(ov511, w.slave, w.reg, w.value,
+ return i2c_w_slave(ov, w.slave, w.reg, w.value,
w.mask);
}
case OV511IOC_RI2C:
@@ -5766,7 +5695,7 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (copy_from_user(&r, arg, sizeof(r)))
return -EFAULT;
- rc = ov51x_i2c_read_slave(ov511, r.slave, r.reg);
+ rc = i2c_r_slave(ov, r.slave, r.reg);
if (rc < 0)
return rc;
@@ -5795,7 +5724,7 @@ ov511_control_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
* the same register settings as the OV7610, since they are very similar.
*/
static int
-ov7xx0_configure(struct usb_ov511 *ov511)
+ov7xx0_configure(struct usb_ov511 *ov)
{
int i, success;
int rc;
@@ -5912,16 +5841,15 @@ ov7xx0_configure(struct usb_ov511 *ov511)
PDEBUG(4, "starting configuration");
/* This looks redundant, but is necessary for WebCam 3 */
- ov511->primary_i2c_slave = OV7xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV7xx0_I2C_WRITE_ID,
- OV7xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV7xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
return -1;
- if (ov51x_init_ov_sensor(ov511) >= 0) {
+ if (init_ov_sensor(ov) >= 0) {
PDEBUG(1, "OV7xx0 sensor initalized (method 1)");
} else {
/* Reset the 76xx */
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) return -1;
+ if (i2c_w(ov, 0x12, 0x80) < 0) return -1;
/* Wait for it to initialize */
schedule_timeout(1 + 150 * HZ / 1000);
@@ -5929,10 +5857,8 @@ ov7xx0_configure(struct usb_ov511 *ov511)
i = 0;
success = 0;
while (i <= i2c_detect_tries) {
- if ((ov51x_i2c_read(ov511,
- OV7610_REG_ID_HIGH) == 0x7F) &&
- (ov51x_i2c_read(ov511,
- OV7610_REG_ID_LOW) == 0xA2)) {
+ if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
+ (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
success = 1;
break;
} else {
@@ -5956,17 +5882,17 @@ ov7xx0_configure(struct usb_ov511 *ov511)
}
/* Detect sensor (sub)type */
- rc = ov51x_i2c_read(ov511, OV7610_REG_COM_I);
+ rc = i2c_r(ov, OV7610_REG_COM_I);
if (rc < 0) {
err("Error detecting sensor type");
return -1;
} else if ((rc & 3) == 3) {
info("Sensor is an OV7610");
- ov511->sensor = SEN_OV7610;
+ ov->sensor = SEN_OV7610;
} else if ((rc & 3) == 1) {
/* I don't know what's different about the 76BE yet */
- if (ov51x_i2c_read(ov511, 0x15) & 1)
+ if (i2c_r(ov, 0x15) & 1)
info("Sensor is an OV7620AE");
else
info("Sensor is an OV76BE");
@@ -5974,48 +5900,48 @@ ov7xx0_configure(struct usb_ov511 *ov511)
/* OV511+ will return all zero isoc data unless we
* configure the sensor as a 7620. Someone needs to
* find the exact reg. setting that causes this. */
- if (ov511->bridge == BRG_OV511PLUS) {
+ if (ov->bridge == BRG_OV511PLUS) {
info("Enabling 511+/7620AE workaround");
- ov511->sensor = SEN_OV7620;
+ ov->sensor = SEN_OV7620;
} else {
- ov511->sensor = SEN_OV7620AE;
+ ov->sensor = SEN_OV7620AE;
}
} else if ((rc & 3) == 0) {
info("Sensor is an OV7620");
- ov511->sensor = SEN_OV7620;
+ ov->sensor = SEN_OV7620;
} else {
err("Unknown image sensor version: %d", rc & 3);
return -1;
}
- if (ov511->sensor == SEN_OV7620) {
+ if (ov->sensor == SEN_OV7620) {
PDEBUG(4, "Writing 7620 registers");
- if (ov511_write_regvals(ov511, aRegvalsNorm7620))
+ if (write_regvals(ov, aRegvalsNorm7620))
return -1;
} else {
PDEBUG(4, "Writing 7610 registers");
- if (ov511_write_regvals(ov511, aRegvalsNorm7610))
+ if (write_regvals(ov, aRegvalsNorm7610))
return -1;
}
/* Set sensor-specific vars */
- ov511->maxwidth = 640;
- ov511->maxheight = 480;
- ov511->minwidth = 64;
- ov511->minheight = 48;
+ ov->maxwidth = 640;
+ ov->maxheight = 480;
+ ov->minwidth = 64;
+ ov->minheight = 48;
// FIXME: These do not match the actual settings yet
- ov511->brightness = 0x80 << 8;
- ov511->contrast = 0x80 << 8;
- ov511->colour = 0x80 << 8;
- ov511->hue = 0x80 << 8;
+ ov->brightness = 0x80 << 8;
+ ov->contrast = 0x80 << 8;
+ ov->colour = 0x80 << 8;
+ ov->hue = 0x80 << 8;
return 0;
}
/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
static int
-ov6xx0_configure(struct usb_ov511 *ov511)
+ov6xx0_configure(struct usb_ov511 *ov)
{
int rc;
@@ -6141,7 +6067,7 @@ ov6xx0_configure(struct usb_ov511 *ov511)
PDEBUG(4, "starting sensor configuration");
- if (ov51x_init_ov_sensor(ov511) < 0) {
+ if (init_ov_sensor(ov) < 0) {
err("Failed to read sensor ID. You might not have an OV6xx0,");
err("or it may be not responding. Report this to " EMAIL);
return -1;
@@ -6150,50 +6076,44 @@ ov6xx0_configure(struct usb_ov511 *ov511)
}
/* Detect sensor (sub)type */
- rc = ov51x_i2c_read(ov511, OV7610_REG_COM_I);
+ rc = i2c_r(ov, OV7610_REG_COM_I);
if (rc < 0) {
err("Error detecting sensor type");
return -1;
} else if ((rc & 3) == 0) {
info("Sensor is an OV6630");
- ov511->sensor = SEN_OV6630;
+ ov->sensor = SEN_OV6630;
} else if ((rc & 3) == 1) {
info("Sensor is an OV6620");
- ov511->sensor = SEN_OV6620;
+ ov->sensor = SEN_OV6620;
} else if ((rc & 3) == 2) {
info("Sensor is an OV6630AE");
- ov511->sensor = SEN_OV6630;
+ ov->sensor = SEN_OV6630;
} else if ((rc & 3) == 3) {
info("Sensor is an OV6630AF");
- ov511->sensor = SEN_OV6630;
+ ov->sensor = SEN_OV6630;
}
/* Set sensor-specific vars */
- if (ov511->sensor == SEN_OV6620) {
- ov511->maxwidth = 352;
- ov511->maxheight = 288;
- } else {
- /* 352x288 not working with OV518 yet */
- ov511->maxwidth = 320;
- ov511->maxheight = 240;
- }
- ov511->minwidth = 64;
- ov511->minheight = 48;
+ ov->maxwidth = 352;
+ ov->maxheight = 288;
+ ov->minwidth = 64;
+ ov->minheight = 48;
// FIXME: These do not match the actual settings yet
- ov511->brightness = 0x80 << 8;
- ov511->contrast = 0x80 << 8;
- ov511->colour = 0x80 << 8;
- ov511->hue = 0x80 << 8;
+ ov->brightness = 0x80 << 8;
+ ov->contrast = 0x80 << 8;
+ ov->colour = 0x80 << 8;
+ ov->hue = 0x80 << 8;
- if (ov511->sensor == SEN_OV6620) {
+ if (ov->sensor == SEN_OV6620) {
PDEBUG(4, "Writing 6x20 registers");
- if (ov511_write_regvals(ov511, aRegvalsNorm6x20))
+ if (write_regvals(ov, aRegvalsNorm6x20))
return -1;
} else {
PDEBUG(4, "Writing 6x30 registers");
- if (ov511_write_regvals(ov511, aRegvalsNorm6x30))
+ if (write_regvals(ov, aRegvalsNorm6x30))
return -1;
}
@@ -6202,13 +6122,13 @@ ov6xx0_configure(struct usb_ov511 *ov511)
/* This initializes the KS0127 and KS0127B video decoders. */
static int
-ks0127_configure(struct usb_ov511 *ov511)
+ks0127_configure(struct usb_ov511 *ov)
{
int rc;
// FIXME: I don't know how to sync or reset it yet
#if 0
- if (ov51x_init_ks_sensor(ov511) < 0) {
+ if (ov51x_init_ks_sensor(ov) < 0) {
err("Failed to initialize the KS0127");
return -1;
} else {
@@ -6217,21 +6137,21 @@ ks0127_configure(struct usb_ov511 *ov511)
#endif
/* Detect decoder subtype */
- rc = ov51x_i2c_read(ov511, 0x00);
+ rc = i2c_r(ov, 0x00);
if (rc < 0) {
err("Error detecting sensor type");
return -1;
} else if (rc & 0x08) {
- rc = ov51x_i2c_read(ov511, 0x3d);
+ rc = i2c_r(ov, 0x3d);
if (rc < 0) {
err("Error detecting sensor type");
return -1;
} else if ((rc & 0x0f) == 0) {
info("Sensor is a KS0127");
- ov511->sensor = SEN_KS0127;
+ ov->sensor = SEN_KS0127;
} else if ((rc & 0x0f) == 9) {
info("Sensor is a KS0127B Rev. A");
- ov511->sensor = SEN_KS0127B;
+ ov->sensor = SEN_KS0127B;
}
} else {
err("Error: Sensor is an unsupported KS0122");
@@ -6239,16 +6159,16 @@ ks0127_configure(struct usb_ov511 *ov511)
}
/* Set sensor-specific vars */
- ov511->maxwidth = 640;
- ov511->maxheight = 480;
- ov511->minwidth = 64;
- ov511->minheight = 48;
+ ov->maxwidth = 640;
+ ov->maxheight = 480;
+ ov->minwidth = 64;
+ ov->minheight = 48;
// FIXME: These do not match the actual settings yet
- ov511->brightness = 0x80 << 8;
- ov511->contrast = 0x80 << 8;
- ov511->colour = 0x80 << 8;
- ov511->hue = 0x80 << 8;
+ ov->brightness = 0x80 << 8;
+ ov->contrast = 0x80 << 8;
+ ov->colour = 0x80 << 8;
+ ov->hue = 0x80 << 8;
/* This device is not supported yet. Bail out now... */
err("This sensor is not supported yet.");
@@ -6261,7 +6181,6 @@ ks0127_configure(struct usb_ov511 *ov511)
static int
saa7111a_configure(struct usb_ov511 *ov511)
{
- struct usb_device *dev = ov511->dev;
int rc;
/* Since there is no register reset command, all registers must be
@@ -6296,7 +6215,7 @@ saa7111a_configure(struct usb_ov511 *ov511)
// FIXME: I don't know how to sync or reset it yet
#if 0
- if (ov51x_init_saa_sensor(ov511) < 0) {
+ if (ov51x_init_saa_sensor(ov) < 0) {
err("Failed to initialize the SAA7111A");
return -1;
} else {
@@ -6323,12 +6242,12 @@ saa7111a_configure(struct usb_ov511 *ov511)
ov511->hue = 32768;
PDEBUG(4, "Writing SAA7111A registers");
- if (ov511_write_regvals(ov511, aRegvalsNormSAA7111A))
+ if (write_regvals(ov511, aRegvalsNormSAA7111A))
return -1;
/* Detect version of decoder. This must be done after writing the
* initial regs or the decoder will lock up. */
- rc = ov51x_i2c_read(ov511, 0x00);
+ rc = i2c_r(ov511, 0x00);
if (rc < 0) {
err("Error detecting sensor version");
@@ -6341,8 +6260,8 @@ saa7111a_configure(struct usb_ov511 *ov511)
// FIXME: Fix this for OV518(+)
/* Latch to negative edge of clock. Otherwise, we get incorrect
* colors and jitter in the digital signal. */
- if (ov511->bridge == BRG_OV511 || ov511->bridge == BRG_OV511PLUS)
- ov511_reg_write(dev, 0x11, 0x00);
+ if (ov511->bclass == BCL_OV511)
+ reg_w(ov511, 0x11, 0x00);
else
warn("SAA7111A not yet supported with OV518/OV518+");
@@ -6351,144 +6270,138 @@ saa7111a_configure(struct usb_ov511 *ov511)
/* This initializes the OV511/OV511+ and the sensor */
static int
-ov511_configure(struct usb_ov511 *ov511)
+ov511_configure(struct usb_ov511 *ov)
{
- struct usb_device *dev = ov511->dev;
int i;
static struct ov511_regvals aRegvalsInit511[] = {
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3f },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3d },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x3f },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x3d },
{ OV511_DONE_BUS, 0x0, 0x00},
};
static struct ov511_regvals aRegvalsNorm511[] = {
- { OV511_REG_BUS, OV511_REG_DRAM_ENABLE_FLOW_CONTROL, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x03 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
- { OV511_REG_BUS, OV511_REG_FIFO_BITMASK, 0x1f },
- { OV511_REG_BUS, OV511_OMNICE_ENABLE, 0x00 },
- { OV511_REG_BUS, OV511_OMNICE_LUT_ENABLE, 0x03 },
+ { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x03 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
+ { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f },
+ { OV511_REG_BUS, R511_COMP_EN, 0x00 },
+ { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
{ OV511_DONE_BUS, 0x0, 0x00 },
};
static struct ov511_regvals aRegvalsNorm511Plus[] = {
- { OV511_REG_BUS, OV511_REG_DRAM_ENABLE_FLOW_CONTROL, 0xff },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x03 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x01 },
- { OV511_REG_BUS, OV511_REG_FIFO_BITMASK, 0xff },
- { OV511_REG_BUS, OV511_OMNICE_ENABLE, 0x00 },
- { OV511_REG_BUS, OV511_OMNICE_LUT_ENABLE, 0x03 },
+ { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x03 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 },
+ { OV511_REG_BUS, R511_FIFO_OPTS, 0xff },
+ { OV511_REG_BUS, R511_COMP_EN, 0x00 },
+ { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
{ OV511_DONE_BUS, 0x0, 0x00 },
};
PDEBUG(4, "");
- ov511->customid = ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID);
- if (ov511->customid < 0) {
+ ov->customid = reg_r(ov, R511_SYS_CUST_ID);
+ if (ov->customid < 0) {
err("Unable to read camera bridge registers");
goto error;
}
- ov511->desc = -1;
- PDEBUG (1, "CustomID = %d", ov511->customid);
+ ov->desc = -1;
+ PDEBUG (1, "CustomID = %d", ov->customid);
for (i = 0; clist[i].id >= 0; i++) {
- if (ov511->customid == clist[i].id) {
+ if (ov->customid == clist[i].id) {
info("model: %s", clist[i].description);
- ov511->desc = i;
+ ov->desc = i;
break;
}
}
if (clist[i].id == -1) {
- err("Camera type (%d) not recognized", ov511->customid);
+ err("Camera type (%d) not recognized", ov->customid);
err("Please notify " EMAIL " of the name,");
err("manufacturer, model, and this number of your camera.");
err("Also include the output of the detection process.");
}
if (clist[i].id == 6) { /* USB Life TV (NTSC) */
- ov511->tuner_type = 8; /* Temic 4036FY5 3X 1981 */
+ ov->tuner_type = 8; /* Temic 4036FY5 3X 1981 */
}
- if (ov511_write_regvals(ov511, aRegvalsInit511)) goto error;
+ if (write_regvals(ov, aRegvalsInit511)) goto error;
- if (ov511->led_policy == LED_OFF || ov511->led_policy == LED_AUTO)
- ov51x_led_control(ov511, 0);
+ if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
+ ov51x_led_control(ov, 0);
/* The OV511+ has undocumented bits in the flow control register.
* Setting it to 0xff fixes the corruption with moving objects. */
- if (ov511->bridge == BRG_OV511) {
- if (ov511_write_regvals(ov511, aRegvalsNorm511)) goto error;
- } else if (ov511->bridge == BRG_OV511PLUS) {
- if (ov511_write_regvals(ov511, aRegvalsNorm511Plus)) goto error;
+ if (ov->bridge == BRG_OV511) {
+ if (write_regvals(ov, aRegvalsNorm511)) goto error;
+ } else if (ov->bridge == BRG_OV511PLUS) {
+ if (write_regvals(ov, aRegvalsNorm511Plus)) goto error;
} else {
err("Invalid bridge");
}
- if (ov511_init_compression(ov511)) goto error;
+ if (ov511_init_compression(ov)) goto error;
- ov511_set_packet_size(ov511, 0);
+ ov51x_set_packet_size(ov, 0);
- ov511->snap_enabled = snapshot;
+ ov->snap_enabled = snapshot;
/* Test for 7xx0 */
PDEBUG(3, "Testing for 0V7xx0");
- ov511->primary_i2c_slave = OV7xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV7xx0_I2C_WRITE_ID,
- OV7xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV7xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
goto error;
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) {
+ if (i2c_w(ov, 0x12, 0x80) < 0) {
/* Test for 6xx0 */
PDEBUG(3, "Testing for 0V6xx0");
- ov511->primary_i2c_slave = OV6xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV6xx0_I2C_WRITE_ID,
- OV6xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV6xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
goto error;
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) {
+ if (i2c_w(ov, 0x12, 0x80) < 0) {
/* Test for 8xx0 */
PDEBUG(3, "Testing for 0V8xx0");
- ov511->primary_i2c_slave = OV8xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV8xx0_I2C_WRITE_ID,
- OV8xx0_I2C_READ_ID))
+ ov->primary_i2c_slave = OV8xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV8xx0_SID))
goto error;
- if (ov51x_i2c_write(ov511, 0x12, 0x80) < 0) {
+ if (i2c_w(ov, 0x12, 0x80) < 0) {
/* Test for SAA7111A */
PDEBUG(3, "Testing for SAA7111A");
- ov511->primary_i2c_slave = SAA7111A_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, SAA7111A_I2C_WRITE_ID,
- SAA7111A_I2C_READ_ID))
+ ov->primary_i2c_slave = SAA7111A_SID;
+ if (ov51x_set_slave_ids(ov, SAA7111A_SID))
goto error;
- if (ov51x_i2c_write(ov511, 0x0d, 0x00) < 0) {
+ if (i2c_w(ov, 0x0d, 0x00) < 0) {
/* Test for KS0127 */
PDEBUG(3, "Testing for KS0127");
- ov511->primary_i2c_slave = KS0127_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, KS0127_I2C_WRITE_ID,
- KS0127_I2C_READ_ID))
+ ov->primary_i2c_slave = KS0127_SID;
+ if (ov51x_set_slave_ids(ov, KS0127_SID))
goto error;
- if (ov51x_i2c_write(ov511, 0x10, 0x00) < 0) {
+ if (i2c_w(ov, 0x10, 0x00) < 0) {
err("Can't determine sensor slave IDs");
goto error;
} else {
- if(ks0127_configure(ov511) < 0) {
+ if (ks0127_configure(ov) < 0) {
err("Failed to configure KS0127");
goto error;
}
}
} else {
- if(saa7111a_configure(ov511) < 0) {
+ if (saa7111a_configure(ov) < 0) {
err("Failed to configure SAA7111A");
goto error;
}
@@ -6498,13 +6411,13 @@ ov511_configure(struct usb_ov511 *ov511)
goto error;
}
} else {
- if(ov6xx0_configure(ov511) < 0) {
+ if (ov6xx0_configure(ov) < 0) {
err("Failed to configure OV6xx0");
goto error;
}
}
} else {
- if(ov7xx0_configure(ov511) < 0) {
+ if (ov7xx0_configure(ov) < 0) {
err("Failed to configure OV7xx0");
goto error;
}
@@ -6520,96 +6433,90 @@ error:
/* This initializes the OV518/OV518+ and the sensor */
static int
-ov518_configure(struct usb_ov511 *ov511)
+ov518_configure(struct usb_ov511 *ov)
{
- struct usb_device *dev = ov511->dev;
-
static struct ov511_regvals aRegvalsInit518[] = {
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x40 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0xe1 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3e },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0xe1 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x00 },
- { OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0xe1 },
- { OV511_REG_BUS, 0x46, 0x00 },
- { OV511_REG_BUS, 0x5d, 0x03 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x40 },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
+ { OV511_REG_BUS, R51x_SYS_RESET, 0x00 },
+ { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
+ { OV511_REG_BUS, 0x46, 0x00 },
+ { OV511_REG_BUS, 0x5d, 0x03 },
{ OV511_DONE_BUS, 0x0, 0x00},
};
/* New values, based on Windows driver. Since what they do is not
* known yet, this may be incorrect. */
static struct ov511_regvals aRegvalsNorm518[] = {
- { OV511_REG_BUS, 0x52, 0x02 }, /* Reset snapshot */
- { OV511_REG_BUS, 0x52, 0x01 }, /* Enable snapshot */
- { OV511_REG_BUS, 0x31, 0x0f },
- { OV511_REG_BUS, 0x5d, 0x03 },
- { OV511_REG_BUS, 0x24, 0x9f },
- { OV511_REG_BUS, 0x25, 0x90 },
- { OV511_REG_BUS, 0x20, 0x00 }, /* Was 0x08 */
- { OV511_REG_BUS, 0x51, 0x04 },
- { OV511_REG_BUS, 0x71, 0x19 },
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */
+ { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */
+ { OV511_REG_BUS, 0x31, 0x0f },
+ { OV511_REG_BUS, 0x5d, 0x03 },
+ { OV511_REG_BUS, 0x24, 0x9f },
+ { OV511_REG_BUS, 0x25, 0x90 },
+ { OV511_REG_BUS, 0x20, 0x00 }, /* Was 0x08 */
+ { OV511_REG_BUS, 0x51, 0x04 },
+ { OV511_REG_BUS, 0x71, 0x19 },
{ OV511_DONE_BUS, 0x0, 0x00 },
};
PDEBUG(4, "");
/* First 5 bits of custom ID reg are a revision ID on OV518 */
- info("Device revision %d",
- 0x1F & ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID));
+ info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID));
- if (ov511_write_regvals(ov511, aRegvalsInit518)) goto error;
+ if (write_regvals(ov, aRegvalsInit518)) goto error;
/* Set LED GPIO pin to output mode */
- if (ov511_reg_write_mask(dev, 0x57,0x00, 0x02) < 0) goto error;
+ if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0) goto error;
/* LED is off by default with OV518; have to explicitly turn it on */
- if (ov511->led_policy == LED_OFF || ov511->led_policy == LED_AUTO)
- ov51x_led_control(ov511, 0);
+ if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
+ ov51x_led_control(ov, 0);
else
- ov51x_led_control(ov511, 1);
+ ov51x_led_control(ov, 1);
/* Don't require compression if dumppix is enabled; otherwise it's
* required. OV518 has no uncompressed mode, to save RAM. */
- if (!dumppix && !ov511->compress) {
- ov511->compress = 1;
+ if (!dumppix && !ov->compress) {
+ ov->compress = 1;
warn("Compression required with OV518...enabling");
}
- if (ov511_write_regvals(ov511, aRegvalsNorm518)) goto error;
+ if (write_regvals(ov, aRegvalsNorm518)) goto error;
- if (ov511_reg_write(dev, 0x2f,0x80) < 0) goto error;
+ if (reg_w(ov, 0x2f, 0x80) < 0) goto error;
- if (ov518_init_compression(ov511)) goto error;
+ if (ov518_init_compression(ov)) goto error;
- ov511_set_packet_size(ov511, 0);
+ ov51x_set_packet_size(ov, 0);
- ov511->snap_enabled = snapshot;
+ ov->snap_enabled = snapshot;
/* Test for 76xx */
- ov511->primary_i2c_slave = OV7xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV7xx0_I2C_WRITE_ID,
- OV7xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV7xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
goto error;
/* The OV518 must be more aggressive about sensor detection since
* I2C write will never fail if the sensor is not present. We have
* to try to initialize the sensor to detect its presence */
- if (ov51x_init_ov_sensor(ov511) < 0) {
+ if (init_ov_sensor(ov) < 0) {
/* Test for 6xx0 */
- ov511->primary_i2c_slave = OV6xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV6xx0_I2C_WRITE_ID,
- OV6xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV6xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
goto error;
- if (ov51x_init_ov_sensor(ov511) < 0) {
+ if (init_ov_sensor(ov) < 0) {
/* Test for 8xx0 */
- ov511->primary_i2c_slave = OV8xx0_I2C_WRITE_ID;
- if (ov51x_set_slave_ids(ov511, OV8xx0_I2C_WRITE_ID,
- OV8xx0_I2C_READ_ID) < 0)
+ ov->primary_i2c_slave = OV8xx0_SID;
+ if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
goto error;
- if (ov51x_init_ov_sensor(ov511) < 0) {
+ if (init_ov_sensor(ov) < 0) {
err("Can't determine sensor slave IDs");
goto error;
} else {
@@ -6617,21 +6524,25 @@ ov518_configure(struct usb_ov511 *ov511)
goto error;
}
} else {
- if (ov6xx0_configure(ov511) < 0) {
+ if (ov6xx0_configure(ov) < 0) {
err("Failed to configure OV6xx0");
goto error;
}
}
} else {
- if (ov7xx0_configure(ov511) < 0) {
+ if (ov7xx0_configure(ov) < 0) {
err("Failed to configure OV7xx0");
goto error;
}
}
+ // FIXME: Sizes > 320x240 are not working yet
+ ov->maxwidth = 320;
+ ov->maxheight = 240;
+
// The OV518 cannot go as low as the sensor can
- ov511->minwidth = 160;
- ov511->minheight = 120;
+ ov->minwidth = 160;
+ ov->minheight = 120;
return 0;
@@ -6648,12 +6559,13 @@ error:
*
***************************************************************************/
+/* 2.2.x compatibility */
static void *
ov51x_probe(struct usb_device *dev, unsigned int ifnum,
const struct usb_device_id *id)
{
struct usb_interface_descriptor *interface;
- struct usb_ov511 *ov511;
+ struct usb_ov511 *ov;
int i;
int registered = 0;
@@ -6671,57 +6583,54 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
if (interface->bInterfaceSubClass != 0x00)
return NULL;
- /* Since code below may sleep, we use this as a lock */
- MOD_INC_USE_COUNT;
-
- if ((ov511 = kmalloc(sizeof(*ov511), GFP_KERNEL)) == NULL) {
- err("couldn't kmalloc ov511 struct");
- goto error_unlock;
+ if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
+ err("couldn't kmalloc ov struct");
+ goto error_out;
}
- memset(ov511, 0, sizeof(*ov511));
+ memset(ov, 0, sizeof(*ov));
- ov511->dev = dev;
- ov511->iface = interface->bInterfaceNumber;
- ov511->led_policy = led;
- ov511->compress = compress;
- ov511->lightfreq = lightfreq;
- ov511->num_inputs = 1; /* Video decoder init functs. change this */
- ov511->stop_during_set = !fastset;
- ov511->tuner_type = tuner;
- ov511->backlight = backlight;
+ ov->dev = dev;
+ ov->iface = interface->bInterfaceNumber;
+ ov->led_policy = led;
+ ov->compress = compress;
+ ov->lightfreq = lightfreq;
+ ov->num_inputs = 1; /* Video decoder init functs. change this */
+ ov->stop_during_set = !fastset;
+ ov->tuner_type = tuner;
+ ov->backlight = backlight;
- ov511->auto_brt = autobright;
- ov511->auto_gain = autogain;
- ov511->auto_exp = autoexp;
+ ov->auto_brt = autobright;
+ ov->auto_gain = autogain;
+ ov->auto_exp = autoexp;
switch (dev->descriptor.idProduct) {
case PROD_OV511:
info("USB OV511 camera found");
- ov511->bridge = BRG_OV511;
- ov511->bclass = BCL_OV511;
+ ov->bridge = BRG_OV511;
+ ov->bclass = BCL_OV511;
break;
case PROD_OV511PLUS:
info("USB OV511+ camera found");
- ov511->bridge = BRG_OV511PLUS;
- ov511->bclass = BCL_OV511;
+ ov->bridge = BRG_OV511PLUS;
+ ov->bclass = BCL_OV511;
break;
case PROD_OV518:
info("USB OV518 camera found");
- ov511->bridge = BRG_OV518;
- ov511->bclass = BCL_OV518;
+ ov->bridge = BRG_OV518;
+ ov->bclass = BCL_OV518;
break;
case PROD_OV518PLUS:
info("USB OV518+ camera found");
- ov511->bridge = BRG_OV518PLUS;
- ov511->bclass = BCL_OV518;
+ ov->bridge = BRG_OV518PLUS;
+ ov->bclass = BCL_OV518;
break;
case PROD_ME2CAM:
if (dev->descriptor.idVendor != VEND_MATTEL)
goto error;
info("Intel Play Me2Cam (OV511+) found");
- ov511->bridge = BRG_OV511PLUS;
- ov511->bclass = BCL_OV511;
+ ov->bridge = BRG_OV511PLUS;
+ ov->bclass = BCL_OV511;
break;
default:
err("Unknown product ID 0x%x", dev->descriptor.idProduct);
@@ -6733,47 +6642,53 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
if (force_rgb)
info("data format set to RGB");
- init_waitqueue_head(&ov511->wq);
+ init_waitqueue_head(&ov->wq);
+
+ init_MUTEX(&ov->lock); /* to 1 == available */
+ init_MUTEX(&ov->buf_lock);
+ init_MUTEX(&ov->param_lock);
+ init_MUTEX(&ov->i2c_lock);
+ init_MUTEX(&ov->cbuf_lock);
- init_MUTEX(&ov511->lock); /* to 1 == available */
- init_MUTEX(&ov511->buf_lock);
- init_MUTEX(&ov511->param_lock);
- init_MUTEX(&ov511->i2c_lock);
- ov511->buf_state = BUF_NOT_ALLOCATED;
+ ov->buf_state = BUF_NOT_ALLOCATED;
- if (ov511->bridge == BRG_OV518 ||
- ov511->bridge == BRG_OV518PLUS) {
- if (ov518_configure(ov511) < 0)
+ /* Must be kmalloc()'ed, for DMA accessibility */
+ ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL);
+ if (!ov->cbuf)
+ goto error;
+
+ if (ov->bclass == BCL_OV518) {
+ if (ov518_configure(ov) < 0)
goto error;
} else {
- if (ov511_configure(ov511) < 0)
+ if (ov511_configure(ov) < 0)
goto error;
}
for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov511->frame[i].framenum = i;
- init_waitqueue_head(&ov511->frame[i].wq);
+ ov->frame[i].framenum = i;
+ init_waitqueue_head(&ov->frame[i].wq);
}
/* Unnecessary? (This is done on open(). Need to make sure variables
* are properly initialized without this before removing it, though). */
- if (ov51x_set_default_params(ov511) < 0)
+ if (ov51x_set_default_params(ov) < 0)
goto error;
#ifdef OV511_DEBUG
if (dump_bridge)
- ov511_dump_regs(dev);
+ ov511_dump_regs(ov);
#endif
- memcpy(&ov511->vdev, &ov511_template, sizeof(ov511_template));
- ov511->vdev.priv = ov511;
+ memcpy(&ov->vdev, &vdev_template, sizeof(vdev_template));
+ ov->vdev.priv = ov;
for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) {
/* Minor 0 cannot be specified; assume user wants autodetect */
if (unit_video[i] == 0)
break;
- if (video_register_device(&ov511->vdev, VFL_TYPE_GRABBER,
+ if (video_register_device(&ov->vdev, VFL_TYPE_GRABBER,
unit_video[i]) >= 0) {
registered = 1;
break;
@@ -6782,35 +6697,40 @@ ov51x_probe(struct usb_device *dev, unsigned int ifnum,
/* Use the next available one */
if (!registered &&
- video_register_device(&ov511->vdev, VFL_TYPE_GRABBER, -1) < 0) {
+ video_register_device(&ov->vdev, VFL_TYPE_GRABBER, -1) < 0) {
err("video_register_device failed");
goto error;
}
- info("Device registered on minor %d", ov511->vdev.minor);
+ info("Device registered on minor %d", ov->vdev.minor);
- MOD_DEC_USE_COUNT;
- return ov511;
+ return ov;
error:
err("Camera initialization failed");
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
/* Safe to call even if entry doesn't exist */
- destroy_proc_ov511_cam(ov511);
+ destroy_proc_ov511_cam(ov);
#endif
+ if (ov->cbuf) {
+ down(&ov->cbuf_lock);
+ kfree(ov->cbuf);
+ ov->cbuf = NULL;
+ up(&ov->cbuf_lock);
+ }
+
usb_driver_release_interface(&ov511_driver,
- &dev->actconfig->interface[ov511->iface]);
+ &dev->actconfig->interface[ov->iface]);
error_dealloc:
- if (ov511) {
- kfree(ov511);
- ov511 = NULL;
+ if (ov) {
+ kfree(ov);
+ ov = NULL;
}
-error_unlock:
- MOD_DEC_USE_COUNT;
+error_out:
return NULL;
}
@@ -6818,62 +6738,64 @@ error_unlock:
static void
ov51x_disconnect(struct usb_device *dev, void *ptr)
{
- struct usb_ov511 *ov511 = (struct usb_ov511 *) ptr;
+ struct usb_ov511 *ov = (struct usb_ov511 *) ptr;
int n;
- MOD_INC_USE_COUNT;
-
PDEBUG(3, "");
/* We don't want people trying to open up the device */
- if (!ov511->user)
- video_unregister_device(&ov511->vdev);
+ if (!ov->user)
+ video_unregister_device(&ov->vdev);
else
PDEBUG(3, "Device open...deferring video_unregister_device");
for (n = 0; n < OV511_NUMFRAMES; n++)
- ov511->frame[n].grabstate = FRAME_ERROR;
+ ov->frame[n].grabstate = FRAME_ERROR;
- ov511->curframe = -1;
+ ov->curframe = -1;
/* This will cause the process to request another frame */
for (n = 0; n < OV511_NUMFRAMES; n++)
- if (waitqueue_active(&ov511->frame[n].wq))
- wake_up_interruptible(&ov511->frame[n].wq);
- if (waitqueue_active(&ov511->wq))
- wake_up_interruptible(&ov511->wq);
+ if (waitqueue_active(&ov->frame[n].wq))
+ wake_up_interruptible(&ov->frame[n].wq);
+ if (waitqueue_active(&ov->wq))
+ wake_up_interruptible(&ov->wq);
- ov511->streaming = 0;
+ ov->streaming = 0;
/* Unschedule all of the iso td's */
for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
- if (ov511->sbuf[n].urb) {
- ov511->sbuf[n].urb->next = NULL;
- usb_unlink_urb(ov511->sbuf[n].urb);
- usb_free_urb(ov511->sbuf[n].urb);
- ov511->sbuf[n].urb = NULL;
+ if (ov->sbuf[n].urb) {
+ ov->sbuf[n].urb->next = NULL;
+ usb_unlink_urb(ov->sbuf[n].urb);
+ usb_free_urb(ov->sbuf[n].urb);
+ ov->sbuf[n].urb = NULL;
}
}
#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
- destroy_proc_ov511_cam(ov511);
+ destroy_proc_ov511_cam(ov);
#endif
usb_driver_release_interface(&ov511_driver,
- &ov511->dev->actconfig->interface[ov511->iface]);
- ov511->dev = NULL;
+ &ov->dev->actconfig->interface[ov->iface]);
+ ov->dev = NULL;
/* Free the memory */
- if (ov511 && !ov511->user) {
- ov511_dealloc(ov511, 1);
- kfree(ov511);
- ov511 = NULL;
- }
+ if (ov && !ov->user) {
+ down(&ov->cbuf_lock);
+ kfree(ov->cbuf);
+ ov->cbuf = NULL;
+ up(&ov->cbuf_lock);
- MOD_DEC_USE_COUNT;
+ ov51x_dealloc(ov, 1);
+ kfree(ov);
+ ov = NULL;
+ }
}
static struct usb_driver ov511_driver = {
+ owner: THIS_MODULE,
name: "ov511",
id_table: device_table,
probe: ov51x_probe,
diff --git a/drivers/usb/ov511.h b/drivers/usb/ov511.h
index 0bdf18885253..4e6a9fa6a262 100644
--- a/drivers/usb/ov511.h
+++ b/drivers/usb/ov511.h
@@ -9,11 +9,11 @@
#define OV511_DEBUG /* Turn on debug messages */
#ifdef OV511_DEBUG
-# define PDEBUG(level, fmt, args...) \
-if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
- ## args)
+ #define PDEBUG(level, fmt, args...) \
+ if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt,\
+ __LINE__ , ## args)
#else
-# define PDEBUG(level, fmt, args...) do {} while(0)
+ #define PDEBUG(level, fmt, args...) do {} while(0)
#endif
/* This macro restricts an int variable to an inclusive range */
@@ -36,98 +36,105 @@ if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
#define VEND_MATTEL 0x0813
#define PROD_ME2CAM 0x0002
+/* --------------------------------- */
+/* OV51x REGISTER MNEMONICS */
+/* --------------------------------- */
+
/* Camera interface register numbers */
-#define OV511_REG_CAMERA_DELAY_MODE 0x10
-#define OV511_REG_CAMERA_EDGE_MODE 0x11
-#define OV511_REG_CAMERA_CLAMPED_PIXEL_NUM 0x12
-#define OV511_REG_CAMERA_CLAMPED_LINE_NUM 0x13
-#define OV511_REG_CAMERA_PIXEL_DIVISOR 0x14
-#define OV511_REG_CAMERA_LINE_DIVISOR 0x15
-#define OV511_REG_CAMERA_DATA_INPUT_SELECT 0x16
-#define OV511_REG_CAMERA_RESERVED_LINE_MODE 0x17
-#define OV511_REG_CAMERA_BITMASK 0x18
+#define R511_CAM_DELAY 0x10
+#define R511_CAM_EDGE 0x11
+#define R511_CAM_PXCNT 0x12
+#define R511_CAM_LNCNT 0x13
+#define R511_CAM_PXDIV 0x14
+#define R511_CAM_LNDIV 0x15
+#define R511_CAM_UV_EN 0x16
+#define R511_CAM_LINE_MODE 0x17
+#define R511_CAM_OPTS 0x18
/* Snapshot mode camera interface register numbers */
-#define OV511_REG_SNAP_CAPTURED_FRAME 0x19
-#define OV511_REG_SNAP_CLAMPED_PIXEL_NUM 0x1A
-#define OV511_REG_SNAP_CLAMPED_LINE_NUM 0x1B
-#define OV511_REG_SNAP_PIXEL_DIVISOR 0x1C
-#define OV511_REG_SNAP_LINE_DIVISOR 0x1D
-#define OV511_REG_SNAP_DATA_INPUT_SELECT 0x1E
-#define OV511_REG_SNAP_BITMASK 0x1F
+#define R511_SNAP_FRAME 0x19
+#define R511_SNAP_PXCNT 0x1A
+#define R511_SNAP_LNCNT 0x1B
+#define R511_SNAP_PXDIV 0x1C
+#define R511_SNAP_LNDIV 0x1D
+#define R511_SNAP_UV_EN 0x1E
+#define R511_SNAP_OPTS 0x1F
/* DRAM register numbers */
-#define OV511_REG_DRAM_ENABLE_FLOW_CONTROL 0x20
-#define OV511_REG_DRAM_READ_CYCLE_PREDICT 0x21
-#define OV511_REG_DRAM_MANUAL_READ_CYCLE 0x22
-#define OV511_REG_DRAM_REFRESH_COUNTER 0x23
+#define R511_DRAM_FLOW_CTL 0x20
+#define R511_DRAM_ARCP 0x21
+#define R511_DRAM_MRC 0x22
+#define R511_DRAM_RFC 0x23
/* ISO FIFO register numbers */
-#define OV511_REG_FIFO_PACKET_SIZE 0x30
-#define OV511_REG_FIFO_BITMASK 0x31
-
-/* PIO register numbers */
-#define OV511_REG_PIO_BITMASK 0x38
-#define OV511_REG_PIO_DATA_PORT 0x39
-#define OV511_REG_PIO_BIST 0x3E
-
-/* I2C register numbers */
-#define OV511_REG_I2C_CONTROL 0x40
-#define OV518_REG_I2C_CONTROL 0x47 /* OV518(+) only */
-#define OV511_REG_I2C_SLAVE_ID_WRITE 0x41
-#define OV511_REG_I2C_SUB_ADDRESS_3_BYTE 0x42
-#define OV511_REG_I2C_SUB_ADDRESS_2_BYTE 0x43
-#define OV511_REG_I2C_SLAVE_ID_READ 0x44
-#define OV511_REG_I2C_DATA_PORT 0x45
-#define OV511_REG_I2C_CLOCK_PRESCALER 0x46
-#define OV511_REG_I2C_TIME_OUT_COUNTER 0x47
-
-/* I2C snapshot register numbers */
-#define OV511_REG_I2C_SNAP_SUB_ADDRESS 0x48
-#define OV511_REG_I2C_SNAP_DATA_PORT 0x49
-
-/* System control register numbers */
-#define OV511_REG_SYSTEM_RESET 0x50
-#define OV511_RESET_UDC 0x01
-#define OV511_RESET_I2C 0x02
-#define OV511_RESET_FIFO 0x04
-#define OV511_RESET_OMNICE 0x08
-#define OV511_RESET_DRAM_INTF 0x10
-#define OV511_RESET_CAMERA_INTF 0x20
-#define OV511_RESET_OV511 0x40
-#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
-#define OV511_RESET_ALL 0x7F
-#define OV511_REG_SYSTEM_CLOCK_DIVISOR 0x51
-#define OV511_REG_SYSTEM_SNAPSHOT 0x52
-#define OV511_REG_SYSTEM_INIT 0x53
-#define OV511_REG_SYSTEM_PWR_CLK 0x54 /* OV511+/OV518(+) only */
-#define OV511_REG_SYSTEM_LED_CTL 0x55 /* OV511+ only */
-#define OV518_REG_GPIO_IN 0x55 /* OV518(+) only */
-#define OV518_REG_GPIO_OUT 0x56 /* OV518(+) only */
-#define OV518_REG_GPIO_CTL 0x57 /* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_IN 0x58 /* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_CLEAR 0x59 /* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_POLARITY 0x5a /* OV518(+) only */
-#define OV518_REG_GPIO_PULSE_EN 0x5b /* OV518(+) only */
-#define OV518_REG_GPIO_RESET 0x5c /* OV518(+) only */
-#define OV511_REG_SYSTEM_USER_DEFINED 0x5E
-#define OV511_REG_SYSTEM_CUSTOM_ID 0x5F
-
-/* OmniCE register numbers */
-#define OV511_OMNICE_PREDICTION_HORIZ_Y 0x70
-#define OV511_OMNICE_PREDICTION_HORIZ_UV 0x71
-#define OV511_OMNICE_PREDICTION_VERT_Y 0x72
-#define OV511_OMNICE_PREDICTION_VERT_UV 0x73
-#define OV511_OMNICE_QUANTIZATION_HORIZ_Y 0x74
-#define OV511_OMNICE_QUANTIZATION_HORIZ_UV 0x75
-#define OV511_OMNICE_QUANTIZATION_VERT_Y 0x76
-#define OV511_OMNICE_QUANTIZATION_VERT_UV 0x77
-#define OV511_OMNICE_ENABLE 0x78
-#define OV511_OMNICE_LUT_ENABLE 0x79
-#define OV511_OMNICE_Y_LUT_BEGIN 0x80
-#define OV511_OMNICE_Y_LUT_END 0x9F
-#define OV511_OMNICE_UV_LUT_BEGIN 0xA0
-#define OV511_OMNICE_UV_LUT_END 0xBF
+#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
+#define R511_FIFO_OPTS 0x31
+
+/* Parallel IO register numbers */
+#define R511_PIO_OPTS 0x38
+#define R511_PIO_DATA 0x39
+#define R511_PIO_BIST 0x3E
+#define R518_GPIO_IN 0x55 /* OV518(+) only */
+#define R518_GPIO_OUT 0x56 /* OV518(+) only */
+#define R518_GPIO_CTL 0x57 /* OV518(+) only */
+#define R518_GPIO_PULSE_IN 0x58 /* OV518(+) only */
+#define R518_GPIO_PULSE_CLEAR 0x59 /* OV518(+) only */
+#define R518_GPIO_PULSE_POL 0x5a /* OV518(+) only */
+#define R518_GPIO_PULSE_EN 0x5b /* OV518(+) only */
+#define R518_GPIO_RESET 0x5c /* OV518(+) only */
+
+/* I2C registers */
+#define R511_I2C_CTL 0x40
+#define R518_I2C_CTL 0x47 /* OV518(+) only */
+#define R51x_I2C_W_SID 0x41
+#define R51x_I2C_SADDR_3 0x42
+#define R51x_I2C_SADDR_2 0x43
+#define R51x_I2C_R_SID 0x44
+#define R51x_I2C_DATA 0x45
+#define R51x_I2C_CLOCK 0x46
+#define R51x_I2C_TIMEOUT 0x47
+
+/* I2C snapshot registers */
+#define R511_SI2C_SADDR_3 0x48
+#define R511_SI2C_DATA 0x49
+
+/* System control registers */
+#define R51x_SYS_RESET 0x50
+ /* Reset type definitions */
+#define OV511_RESET_UDC 0x01
+#define OV511_RESET_I2C 0x02
+#define OV511_RESET_FIFO 0x04
+#define OV511_RESET_OMNICE 0x08
+#define OV511_RESET_DRAM 0x10
+#define OV511_RESET_CAM_INT 0x20
+#define OV511_RESET_OV511 0x40
+#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
+#define OV511_RESET_ALL 0x7F
+
+#define R511_SYS_CLOCK_DIV 0x51
+#define R51x_SYS_SNAP 0x52
+#define R51x_SYS_INIT 0x53
+#define R511_SYS_PWR_CLK 0x54 /* OV511+/OV518(+) only */
+#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
+#define R511_SYS_USER 0x5E
+#define R511_SYS_CUST_ID 0x5F
+
+/* OmniCE (compression) registers */
+#define R511_COMP_PHY 0x70
+#define R511_COMP_PHUV 0x71
+#define R511_COMP_PVY 0x72
+#define R511_COMP_PVUV 0x73
+#define R511_COMP_QHY 0x74
+#define R511_COMP_QHUV 0x75
+#define R511_COMP_QVY 0x76
+#define R511_COMP_QVUV 0x77
+#define R511_COMP_EN 0x78
+#define R511_COMP_LUT_EN 0x79
+#define R511_COMP_LUT_BEGIN 0x80
+
+/* --------------------------------- */
+/* ALTERNATE NUMBERS */
+/* --------------------------------- */
/* Alternate numbers for various max packet sizes (OV511 only) */
#define OV511_ALT_SIZE_992 0
@@ -159,6 +166,10 @@ if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
#define OV518_ALT_SIZE_768 6
#define OV518_ALT_SIZE_896 7
+/* --------------------------------- */
+/* OV7610 REGISTER MNEMONICS */
+/* --------------------------------- */
+
/* OV7610 registers */
#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
#define OV7610_REG_BLUE 0x01 /* blue channel balance */
@@ -210,26 +221,27 @@ if (debug >= (level)) info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , \
/* 36-37 reserved */
#define OV7610_REG_COM_K 0x38 /* misc registers */
+/* --------------------------------- */
+/* I2C ADDRESSES */
+/* --------------------------------- */
+
+#define OV7xx0_SID 0x42
+#define OV6xx0_SID 0xC0
+#define OV8xx0_SID 0xA0
+#define KS0127_SID 0xD8
+#define SAA7111A_SID 0x48
+
+/* --------------------------------- */
+/* MISCELLANEOUS DEFINES */
+/* --------------------------------- */
+
+#define I2C_CLOCK_PRESCALER 0x03
+
#define FRAMES_PER_DESC 10 /* FIXME - What should this be? */
-#define FRAME_SIZE_PER_DESC 993 /* FIXME - Deprecated */
#define MAX_FRAME_SIZE_PER_DESC 993 /* For statically allocated stuff */
#define PIXELS_PER_SEG 256 /* Pixels per segment */
-#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
-
-/* I2C addresses */
-#define OV7xx0_I2C_WRITE_ID 0x42
-#define OV7xx0_I2C_READ_ID 0x43
-#define OV6xx0_I2C_WRITE_ID 0xC0
-#define OV6xx0_I2C_READ_ID 0xC1
-#define OV8xx0_I2C_WRITE_ID 0xA0
-#define OV8xx0_I2C_READ_ID 0xA1
-#define KS0127_I2C_WRITE_ID 0xD8
-#define KS0127_I2C_READ_ID 0xD9
-#define SAA7111A_I2C_WRITE_ID 0x48
-#define SAA7111A_I2C_READ_ID 0x49
-
-#define OV511_I2C_CLOCK_PRESCALER 0x03
+#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
/* Bridge types */
enum {
@@ -429,11 +441,14 @@ struct ov51x_decomp_ops {
#define OV511_NUMFRAMES 2
#if OV511_NUMFRAMES > VIDEO_MAX_FRAME
-#error "OV511_NUMFRAMES is too high"
+ #error "OV511_NUMFRAMES is too high"
#endif
#define OV511_NUMSBUF 2
+/* Control transfers use up to 4 bytes */
+#define OV511_CBUF_SIZE 4
+
struct usb_ov511 {
struct video_device vdev;
@@ -535,6 +550,10 @@ struct usb_ov511 {
/* I2C interface to kernel */
struct semaphore i2c_lock; /* Protect I2C controller regs */
unsigned char primary_i2c_slave; /* I2C write id of sensor */
+
+ /* Control transaction stuff */
+ unsigned char *cbuf; /* Buffer for payload */
+ struct semaphore cbuf_lock;
};
struct cam_list {
diff --git a/drivers/usb/uhci.c b/drivers/usb/uhci.c
index ec02802c4889..368f2158065b 100644
--- a/drivers/usb/uhci.c
+++ b/drivers/usb/uhci.c
@@ -4,7 +4,7 @@
* Maintainer: Johannes Erdfelt <johannes@erdfelt.com>
*
* (C) Copyright 1999 Linus Torvalds
- * (C) Copyright 1999-2001 Johannes Erdfelt, johannes@erdfelt.com
+ * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com
* (C) Copyright 1999 Randy Dunlap
* (C) Copyright 1999 Georg Acher, acher@in.tum.de
* (C) Copyright 1999 Deti Fliegl, deti@fliegl.de
@@ -240,10 +240,10 @@ static void uhci_remove_td(struct uhci *uhci, struct uhci_td *td)
unsigned long flags;
/* If it's not inserted, don't remove it */
+ spin_lock_irqsave(&uhci->frame_list_lock, flags);
if (td->frame == -1 && list_empty(&td->fl_list))
- return;
+ goto out;
- spin_lock_irqsave(&uhci->frame_list_lock, flags);
if (td->frame != -1 && uhci->fl->frame_cpu[td->frame] == td) {
if (list_empty(&td->fl_list)) {
uhci->fl->frame[td->frame] = td->link;
@@ -268,6 +268,7 @@ static void uhci_remove_td(struct uhci *uhci, struct uhci_td *td)
list_del_init(&td->fl_list);
td->frame = -1;
+out:
spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
}
@@ -358,6 +359,9 @@ static void uhci_free_qh(struct uhci *uhci, struct uhci_qh *qh)
pci_pool_free(uhci->qh_pool, qh, qh->dma_handle);
}
+/*
+ * MUST be called with uhci->frame_list_lock acquired
+ */
static void _uhci_insert_qh(struct uhci *uhci, struct uhci_qh *skelqh, struct urb *urb)
{
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
@@ -417,11 +421,10 @@ static void uhci_remove_qh(struct uhci *uhci, struct urb *urb)
return;
/* Only go through the hoops if it's actually linked in */
+ spin_lock_irqsave(&uhci->frame_list_lock, flags);
if (!list_empty(&qh->list)) {
qh->urbp = NULL;
- spin_lock_irqsave(&uhci->frame_list_lock, flags);
-
pqh = list_entry(qh->list.prev, struct uhci_qh, list);
if (pqh->urbp) {
@@ -444,9 +447,8 @@ static void uhci_remove_qh(struct uhci *uhci, struct urb *urb)
qh->element = qh->link = UHCI_PTR_TERM;
list_del_init(&qh->list);
-
- spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
}
+ spin_unlock_irqrestore(&uhci->frame_list_lock, flags);
spin_lock_irqsave(&uhci->qh_remove_list_lock, flags);
@@ -658,6 +660,9 @@ static struct urb_priv *uhci_alloc_urb_priv(struct uhci *uhci, struct urb *urb)
return urbp;
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td)
{
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
@@ -667,6 +672,9 @@ static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td)
list_add_tail(&td->list, &urbp->td_list);
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static void uhci_remove_td_from_urb(struct uhci_td *td)
{
if (list_empty(&td->list))
@@ -677,22 +685,22 @@ static void uhci_remove_td_from_urb(struct uhci_td *td)
td->urb = NULL;
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static void uhci_destroy_urb_priv(struct urb *urb)
{
struct list_head *head, *tmp;
struct urb_priv *urbp;
struct uhci *uhci;
- unsigned long flags;
-
- spin_lock_irqsave(&urb->lock, flags);
urbp = (struct urb_priv *)urb->hcpriv;
if (!urbp)
- goto out;
+ return;
if (!urbp->dev || !urbp->dev->bus || !urbp->dev->bus->hcpriv) {
warn("uhci_destroy_urb_priv: urb %p belongs to disconnected device or bus?", urb);
- goto out;
+ return;
}
if (!list_empty(&urb->urb_list))
@@ -715,20 +723,21 @@ static void uhci_destroy_urb_priv(struct urb *urb)
uhci_free_td(uhci, td);
}
- if (urbp->setup_packet_dma_handle)
+ if (urbp->setup_packet_dma_handle) {
pci_unmap_single(uhci->dev, urbp->setup_packet_dma_handle,
sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE);
+ urbp->setup_packet_dma_handle = 0;
+ }
- if (urbp->transfer_buffer_dma_handle)
+ if (urbp->transfer_buffer_dma_handle) {
pci_unmap_single(uhci->dev, urbp->transfer_buffer_dma_handle,
urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+ urbp->transfer_buffer_dma_handle = 0;
+ }
urb->hcpriv = NULL;
kmem_cache_free(uhci_up_cachep, urbp);
-
-out:
- spin_unlock_irqrestore(&urb->lock, flags);
}
static void uhci_inc_fsbr(struct uhci *uhci, struct urb *urb)
@@ -872,7 +881,7 @@ static int uhci_submit_control(struct urb *urb)
* It's IN if the pipe is an output pipe or we're not expecting
* data back.
*/
- destination &= ~TD_PID;
+ destination &= ~TD_TOKEN_PID_MASK;
if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length)
destination |= USB_PID_IN;
else
@@ -1312,9 +1321,7 @@ static int isochronous_find_limits(struct urb *urb, unsigned int *start, unsigne
struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
struct list_head *tmp, *head;
int ret = 0;
- unsigned long flags;
- spin_lock_irqsave(&uhci->urb_list_lock, flags);
head = &uhci->urb_list;
tmp = head->next;
while (tmp != head) {
@@ -1337,8 +1344,6 @@ static int isochronous_find_limits(struct urb *urb, unsigned int *start, unsigne
} else
ret = -1; /* no previous urb found */
- spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
-
return ret;
}
@@ -1446,34 +1451,30 @@ static int uhci_result_isochronous(struct urb *urb)
return ret;
}
+/*
+ * MUST be called with uhci->urb_list_lock acquired
+ */
static struct urb *uhci_find_urb_ep(struct uhci *uhci, struct urb *urb)
{
struct list_head *tmp, *head;
- unsigned long flags;
- struct urb *u = NULL;
/* We don't match Isoc transfers since they are special */
if (usb_pipeisoc(urb->pipe))
return NULL;
- spin_lock_irqsave(&uhci->urb_list_lock, flags);
head = &uhci->urb_list;
tmp = head->next;
while (tmp != head) {
- u = list_entry(tmp, struct urb, urb_list);
+ struct urb *u = list_entry(tmp, struct urb, urb_list);
tmp = tmp->next;
if (u->dev == urb->dev && u->pipe == urb->pipe &&
u->status == -EINPROGRESS)
- goto out;
+ return u;
}
- u = NULL;
-
-out:
- spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
- return u;
+ return NULL;
}
static int uhci_submit_urb(struct urb *urb, int mem_flags)
@@ -1492,19 +1493,25 @@ static int uhci_submit_urb(struct urb *urb, int mem_flags)
return -ENODEV;
}
+ /* increment the reference count of the urb, as we now also control it */
+ urb = usb_get_urb(urb);
+
uhci = (struct uhci *)urb->dev->bus->hcpriv;
INIT_LIST_HEAD(&urb->urb_list);
usb_inc_dev_use(urb->dev);
- spin_lock_irqsave(&urb->lock, flags);
+ spin_lock_irqsave(&uhci->urb_list_lock, flags);
+ spin_lock(&urb->lock);
if (urb->status == -EINPROGRESS || urb->status == -ECONNRESET ||
urb->status == -ECONNABORTED) {
dbg("uhci_submit_urb: urb not available to submit (status = %d)", urb->status);
/* Since we can have problems on the out path */
- spin_unlock_irqrestore(&urb->lock, flags);
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
usb_dec_dev_use(urb->dev);
+ usb_put_urb(urb);
return ret;
}
@@ -1572,18 +1579,21 @@ static int uhci_submit_urb(struct urb *urb, int mem_flags)
out:
urb->status = ret;
- spin_unlock_irqrestore(&urb->lock, flags);
-
if (ret == -EINPROGRESS) {
- spin_lock_irqsave(&uhci->urb_list_lock, flags);
/* We use _tail to make find_urb_ep more efficient */
list_add_tail(&urb->urb_list, &uhci->urb_list);
+
+ spin_unlock(&urb->lock);
spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
return 0;
}
uhci_unlink_generic(uhci, urb);
+
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
uhci_call_completion(urb);
return ret;
@@ -1592,7 +1602,7 @@ out:
/*
* Return the result of a transfer
*
- * Must be called with urb_list_lock acquired
+ * MUST be called with urb_list_lock acquired
*/
static void uhci_transfer_result(struct uhci *uhci, struct urb *urb)
{
@@ -1631,10 +1641,10 @@ static void uhci_transfer_result(struct uhci *uhci, struct urb *urb)
urbp->status = ret;
- spin_unlock_irqrestore(&urb->lock, flags);
-
- if (ret == -EINPROGRESS)
+ if (ret == -EINPROGRESS) {
+ spin_unlock_irqrestore(&urb->lock, flags);
return;
+ }
switch (usb_pipetype(urb->pipe)) {
case PIPE_CONTROL:
@@ -1664,15 +1674,22 @@ static void uhci_transfer_result(struct uhci *uhci, struct urb *urb)
usb_pipetype(urb->pipe), urb);
}
+ /* Remove it from uhci->urb_list */
list_del_init(&urb->urb_list);
uhci_add_complete(urb);
+
+ spin_unlock_irqrestore(&urb->lock, flags);
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static void uhci_unlink_generic(struct uhci *uhci, struct urb *urb)
{
struct list_head *head, *tmp;
struct urb_priv *urbp = urb->hcpriv;
+ int prevactive = 1;
/* We can get called when urbp allocation fails, so check */
if (!urbp)
@@ -1680,6 +1697,19 @@ static void uhci_unlink_generic(struct uhci *uhci, struct urb *urb)
uhci_dec_fsbr(uhci, urb); /* Safe since it checks */
+ /*
+ * Now we need to find out what the last successful toggle was
+ * so we can update the local data toggle for the next transfer
+ *
+ * There's 3 way's the last successful completed TD is found:
+ *
+ * 1) The TD is NOT active and the actual length < expected length
+ * 2) The TD is NOT active and it's the last TD in the chain
+ * 3) The TD is active and the previous TD is NOT active
+ *
+ * Control and Isochronous ignore the toggle, so this is safe
+ * for all types
+ */
head = &urbp->td_list;
tmp = head->next;
while (tmp != head) {
@@ -1687,15 +1717,18 @@ static void uhci_unlink_generic(struct uhci *uhci, struct urb *urb)
tmp = tmp->next;
- /* Control and Isochronous ignore the toggle, so this */
- /* is safe for all types */
- if ((!(td->status & TD_CTRL_ACTIVE) &&
- (uhci_actual_length(td->status) < uhci_expected_length(td->info)) ||
- tmp == head)) {
+ if (!(td->status & TD_CTRL_ACTIVE) &&
+ (uhci_actual_length(td->status) < uhci_expected_length(td->info) ||
+ tmp == head))
usb_settoggle(urb->dev, uhci_endpoint(td->info),
uhci_packetout(td->info),
uhci_toggle(td->info) ^ 1);
- }
+ else if ((td->status & TD_CTRL_ACTIVE) && !prevactive)
+ usb_settoggle(urb->dev, uhci_endpoint(td->info),
+ uhci_packetout(td->info),
+ uhci_toggle(td->info));
+
+ prevactive = td->status & TD_CTRL_ACTIVE;
}
uhci_delete_queued_urb(uhci, urb);
@@ -1718,6 +1751,9 @@ static int uhci_unlink_urb(struct urb *urb)
uhci = (struct uhci *)urb->dev->bus->hcpriv;
+ spin_lock_irqsave(&uhci->urb_list_lock, flags);
+ spin_lock(&urb->lock);
+
/* Release bandwidth for Interrupt or Isoc. transfers */
/* Spinlock needed ? */
if (urb->bandwidth) {
@@ -1733,35 +1769,41 @@ static int uhci_unlink_urb(struct urb *urb)
}
}
- if (urb->status != -EINPROGRESS)
+ if (urb->status != -EINPROGRESS) {
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
return 0;
+ }
- spin_lock_irqsave(&uhci->urb_list_lock, flags);
list_del_init(&urb->urb_list);
- spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
uhci_unlink_generic(uhci, urb);
/* Short circuit the virtual root hub */
if (urb->dev == uhci->rh.dev) {
rh_unlink_urb(urb);
+
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
uhci_call_completion(urb);
} else {
if (urb->transfer_flags & USB_ASYNC_UNLINK) {
- /* urb_list is available now since we called */
- /* uhci_unlink_generic already */
-
urbp->status = urb->status = -ECONNABORTED;
- spin_lock_irqsave(&uhci->urb_remove_list_lock, flags);
+ spin_lock(&uhci->urb_remove_list_lock);
- /* Check to see if the remove list is empty */
+ /* If we're the first, set the next interrupt bit */
if (list_empty(&uhci->urb_remove_list))
uhci_set_next_interrupt(uhci);
list_add(&urb->urb_list, &uhci->urb_remove_list);
- spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
+ spin_unlock(&uhci->urb_remove_list_lock);
+
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
} else {
urb->status = -ENOENT;
@@ -1774,6 +1816,9 @@ static int uhci_unlink_urb(struct urb *urb)
} else
schedule_timeout(1+1*HZ/1000);
+ spin_unlock(&urb->lock);
+ spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
+
uhci_call_completion(urb);
}
}
@@ -1907,12 +1952,14 @@ static __u8 root_hub_hub_des[] =
/* prepare Interrupt pipe transaction data; HUB INTERRUPT ENDPOINT */
static int rh_send_irq(struct urb *urb)
{
- int i, len = 1;
struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
+ struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
unsigned int io_addr = uhci->io_addr;
+ unsigned long flags;
+ int i, len = 1;
__u16 data = 0;
- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
+ spin_lock_irqsave(&urb->lock, flags);
for (i = 0; i < uhci->rh.numports; i++) {
data |= ((inw(io_addr + USBPORTSC1 + i * 2) & 0xa) > 0 ? (1 << (i + 1)) : 0);
len = (i + 1) / 8 + 1;
@@ -1922,6 +1969,8 @@ static int rh_send_irq(struct urb *urb)
urb->actual_length = len;
urbp->status = 0;
+ spin_unlock_irqrestore(&urb->lock, flags);
+
if ((data > 0) && (uhci->rh.send != 0)) {
dbg("root-hub INT complete: port1: %x port2: %x data: %x",
inw(io_addr + USBPORTSC1), inw(io_addr + USBPORTSC2), data);
@@ -1948,7 +1997,6 @@ static void rh_int_timer_do(unsigned long ptr)
spin_lock_irqsave(&uhci->urb_list_lock, flags);
head = &uhci->urb_list;
-
tmp = head->next;
while (tmp != head) {
struct urb *u = list_entry(tmp, struct urb, urb_list);
@@ -1956,6 +2004,8 @@ static void rh_int_timer_do(unsigned long ptr)
tmp = tmp->next;
+ spin_lock(&urb->lock);
+
/* Check if the FSBR timed out */
if (urbp->fsbr && !urbp->fsbr_timeout && time_after_eq(jiffies, urbp->fsbrtime + IDLE_TIMEOUT))
uhci_fsbr_timeout(uhci, u);
@@ -1965,6 +2015,8 @@ static void rh_int_timer_do(unsigned long ptr)
list_del(&u->urb_list);
list_add_tail(&u->urb_list, &list);
}
+
+ spin_unlock(&urb->lock);
}
spin_unlock_irqrestore(&uhci->urb_list_lock, flags);
@@ -2198,6 +2250,9 @@ static int rh_submit_urb(struct urb *urb)
return stat;
}
+/*
+ * MUST be called with urb->lock acquired
+ */
static int rh_unlink_urb(struct urb *urb)
{
struct uhci *uhci = (struct uhci *)urb->dev->bus->hcpriv;
@@ -2233,16 +2288,25 @@ static void uhci_free_pending_qhs(struct uhci *uhci)
static void uhci_call_completion(struct urb *urb)
{
- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
+ struct urb_priv *urbp;
struct usb_device *dev = urb->dev;
struct uhci *uhci = (struct uhci *)dev->bus->hcpriv;
int is_ring = 0, killed, resubmit_interrupt, status;
struct urb *nurb;
+ unsigned long flags;
+
+ spin_lock_irqsave(&urb->lock, flags);
+
+ urbp = (struct urb_priv *)urb->hcpriv;
+ if (!urbp || !urb->dev) {
+ spin_unlock_irqrestore(&urb->lock, flags);
+ return;
+ }
killed = (urb->status == -ENOENT || urb->status == -ECONNABORTED ||
urb->status == -ECONNRESET);
resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT &&
- urb->interval && !killed);
+ urb->interval);
nurb = urb->next;
if (nurb && !killed) {
@@ -2267,14 +2331,6 @@ static void uhci_call_completion(struct urb *urb)
is_ring = (nurb == urb);
}
- status = urbp->status;
- if (!resubmit_interrupt)
- /* We don't need urb_priv anymore */
- uhci_destroy_urb_priv(urb);
-
- if (!killed)
- urb->status = status;
-
if (urbp->transfer_buffer_dma_handle)
pci_dma_sync_single(uhci->dev, urbp->transfer_buffer_dma_handle,
urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
@@ -2284,11 +2340,28 @@ static void uhci_call_completion(struct urb *urb)
pci_dma_sync_single(uhci->dev, urbp->setup_packet_dma_handle,
sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE);
+ status = urbp->status;
+ if (!resubmit_interrupt || killed)
+ /* We don't need urb_priv anymore */
+ uhci_destroy_urb_priv(urb);
+
+ if (!killed)
+ urb->status = status;
+
urb->dev = NULL;
- if (urb->complete)
+ spin_unlock_irqrestore(&urb->lock, flags);
+
+ if (urb->complete) {
urb->complete(urb);
- if (resubmit_interrupt) {
+ /* Recheck the status. The completion handler may have */
+ /* unlinked the resubmitting interrupt URB */
+ killed = (urb->status == -ENOENT ||
+ urb->status == -ECONNABORTED ||
+ urb->status == -ECONNRESET);
+ }
+
+ if (resubmit_interrupt && !killed) {
urb->dev = dev;
uhci_reset_interrupt(urb);
} else {
@@ -2299,6 +2372,7 @@ static void uhci_call_completion(struct urb *urb)
/* We decrement the usage count after we're done */
/* with everything */
usb_dec_dev_use(dev);
+ usb_put_urb(urb);
}
}
}
@@ -2315,11 +2389,14 @@ static void uhci_finish_completion(struct uhci *uhci)
struct urb_priv *urbp = list_entry(tmp, struct urb_priv, complete_list);
struct urb *urb = urbp->urb;
- tmp = tmp->next;
-
list_del_init(&urbp->complete_list);
+ spin_unlock_irqrestore(&uhci->complete_list_lock, flags);
uhci_call_completion(urb);
+
+ spin_lock_irqsave(&uhci->complete_list_lock, flags);
+ head = &uhci->complete_list;
+ tmp = head->next;
}
spin_unlock_irqrestore(&uhci->complete_list_lock, flags);
}
@@ -2341,7 +2418,8 @@ static void uhci_remove_pending_qhs(struct uhci *uhci)
list_del_init(&urb->urb_list);
urbp->status = urb->status = -ECONNRESET;
- uhci_call_completion(urb);
+
+ uhci_add_complete(urb);
}
spin_unlock_irqrestore(&uhci->urb_remove_list_lock, flags);
}
@@ -3074,3 +3152,4 @@ module_exit(uhci_hcd_cleanup);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
+
diff --git a/drivers/usb/uhci.h b/drivers/usb/uhci.h
index c2b17f6705a1..2a7e94535ec3 100644
--- a/drivers/usb/uhci.h
+++ b/drivers/usb/uhci.h
@@ -121,15 +121,16 @@ struct uhci_qh {
* for TD <info>: (a.k.a. Token)
*/
#define TD_TOKEN_TOGGLE 19
-#define TD_PID 0xFF
+#define TD_TOKEN_PID_MASK 0xFF
+#define TD_TOKEN_EXPLEN_MASK 0x7FF /* expected length, encoded as n - 1 */
#define uhci_maxlen(token) ((token) >> 21)
-#define uhci_expected_length(info) (((info >> 21) + 1) & TD_CTRL_ACTLEN_MASK) /* 1-based */
+#define uhci_expected_length(info) (((info >> 21) + 1) & TD_TOKEN_EXPLEN_MASK) /* 1-based */
#define uhci_toggle(token) (((token) >> TD_TOKEN_TOGGLE) & 1)
#define uhci_endpoint(token) (((token) >> 15) & 0xf)
#define uhci_devaddr(token) (((token) >> 8) & 0x7f)
#define uhci_devep(token) (((token) >> 8) & 0x7ff)
-#define uhci_packetid(token) ((token) & 0xff)
+#define uhci_packetid(token) ((token) & TD_TOKEN_PID_MASK)
#define uhci_packetout(token) (uhci_packetid(token) != USB_PID_IN)
#define uhci_packetin(token) (uhci_packetid(token) == USB_PID_IN)
@@ -163,7 +164,7 @@ struct uhci_td {
struct list_head list; /* P: urb->lock */
int frame;
- struct list_head fl_list; /* P: frame_list_lock */
+ struct list_head fl_list; /* P: uhci->frame_list_lock */
} __attribute__((aligned(16)));
/*
@@ -306,21 +307,25 @@ struct uhci {
struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QH's */
spinlock_t frame_list_lock;
- struct uhci_frame_list *fl; /* Frame list */
+ struct uhci_frame_list *fl; /* P: uhci->frame_list_lock */
int fsbr; /* Full speed bandwidth reclamation */
int is_suspended;
+ /* Main list of URB's currently controlled by this HC */
+ spinlock_t urb_list_lock;
+ struct list_head urb_list; /* P: uhci->urb_list_lock */
+
+ /* List of QH's that are done, but waiting to be unlinked (race) */
spinlock_t qh_remove_list_lock;
- struct list_head qh_remove_list;
+ struct list_head qh_remove_list; /* P: uhci->qh_remove_list_lock */
+ /* List of asynchronously unlinked URB's */
spinlock_t urb_remove_list_lock;
- struct list_head urb_remove_list;
-
- spinlock_t urb_list_lock;
- struct list_head urb_list;
+ struct list_head urb_remove_list; /* P: uhci->urb_remove_list_lock */
+ /* List of URB's awaiting completion callback */
spinlock_t complete_list_lock;
- struct list_head complete_list;
+ struct list_head complete_list; /* P: uhci->complete_list_lock */
struct virt_root_hub rh; /* private data of the virtual root hub */
};
@@ -333,7 +338,7 @@ struct urb_priv {
dma_addr_t transfer_buffer_dma_handle;
struct uhci_qh *qh; /* QH for this URB */
- struct list_head td_list;
+ struct list_head td_list; /* P: urb->lock */
int fsbr : 1; /* URB turned on FSBR */
int fsbr_timeout : 1; /* URB timed out on FSBR */
@@ -345,12 +350,37 @@ struct urb_priv {
int status; /* Final status */
unsigned long inserttime; /* In jiffies */
- unsigned long fsbrtime; /* In jiffies */
+ unsigned long fsbrtime; /* In jiffies */
- struct list_head queue_list;
- struct list_head complete_list;
+ struct list_head queue_list; /* P: uhci->frame_list_lock */
+ struct list_head complete_list; /* P: uhci->complete_list_lock */
};
+/*
+ * Locking in uhci.c
+ *
+ * spinlocks are used extensively to protect the many lists and data
+ * structures we have. It's not that pretty, but it's necessary. We
+ * need to be done with all of the locks (except complete_list_lock) when
+ * we call urb->complete. I've tried to make it simple enough so I don't
+ * have to spend hours racking my brain trying to figure out if the
+ * locking is safe.
+ *
+ * Here's the safe locking order to prevent deadlocks:
+ *
+ * #1 uhci->urb_list_lock
+ * #2 urb->lock
+ * #3 uhci->urb_remove_list_lock, uhci->frame_list_lock,
+ * uhci->qh_remove_list_lock
+ * #4 uhci->complete_list_lock
+ *
+ * If you're going to grab 2 or more locks at once, ALWAYS grab the lock
+ * at the lowest level FIRST and NEVER grab locks at the same level at the
+ * same time.
+ *
+ * So, if you need uhci->urb_list_lock, grab it before you grab urb->lock
+ */
+
/* -------------------------------------------------------------------------
Virtual Root HUB
------------------------------------------------------------------------- */
diff --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c
index 28ef71243cd8..32a17a937c70 100644
--- a/drivers/usb/usb-ohci.c
+++ b/drivers/usb/usb-ohci.c
@@ -205,6 +205,7 @@ static void urb_rm_priv_locked (struct urb * urb)
urb_free_priv ((struct ohci *)urb->dev->bus->hcpriv, urb_priv);
usb_dec_dev_use (urb->dev);
urb->dev = NULL;
+ usb_put_urb (urb);
}
}
@@ -553,6 +554,9 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
// if(usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)))
// return -EPIPE;
+ /* increment the reference count of the urb, as we now also control it */
+ urb = usb_get_urb (urb);
+
usb_inc_dev_use (urb->dev);
ohci = (ohci_t *) urb->dev->bus->hcpriv;
@@ -568,12 +572,14 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
* such as powering down ports */
if (ohci->disabled) {
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -ESHUTDOWN;
}
/* every endpoint has a ed, locate and fill it */
if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1, mem_flags))) {
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -ENOMEM;
}
@@ -595,6 +601,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
size = urb->number_of_packets;
if (size <= 0) {
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -EINVAL;
}
for (i = 0; i < urb->number_of_packets; i++) {
@@ -615,6 +622,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *), mem_flags);
if (!urb_priv) {
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -ENOMEM;
}
memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *));
@@ -632,6 +640,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
urb_free_priv (ohci, urb_priv);
spin_unlock_irqrestore (&usb_ed_lock, flags);
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -ENOMEM;
}
}
@@ -640,6 +649,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
urb_free_priv (ohci, urb_priv);
spin_unlock_irqrestore (&usb_ed_lock, flags);
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return -EINVAL;
}
@@ -662,6 +672,7 @@ static int sohci_submit_urb (struct urb * urb, int mem_flags)
urb_free_priv (ohci, urb_priv);
spin_unlock_irqrestore (&usb_ed_lock, flags);
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
return bustime;
}
usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc (urb->pipe));
@@ -2100,6 +2111,7 @@ static int rh_submit_urb (struct urb * urb)
urb->dev = NULL;
if (urb->complete)
urb->complete (urb);
+ usb_put_urb (urb);
return 0;
}
@@ -2123,6 +2135,7 @@ static int rh_unlink_urb (struct urb * urb)
urb->complete (urb);
} else
urb->status = -ENOENT;
+ usb_put_urb (urb);
}
return 0;
}
diff --git a/drivers/usb/usb-uhci.c b/drivers/usb/usb-uhci.c
index 2f38a19857de..00346153dbab 100644
--- a/drivers/usb/usb-uhci.c
+++ b/drivers/usb/usb-uhci.c
@@ -1217,6 +1217,7 @@ _static int uhci_unlink_urb_sync (uhci_t *s, struct urb *urb)
urb->complete ((struct urb *) urb);
}
usb_dec_dev_use (usb_dev);
+ usb_put_urb (urb);
}
else
spin_unlock_irqrestore (&s->urb_list_lock, flags);
@@ -1305,7 +1306,7 @@ _static void uhci_cleanup_unlink(uhci_t *s, int force)
#else
kfree (urb_priv);
#endif
-
+ usb_put_urb (urb);
}
}
}
@@ -1650,6 +1651,9 @@ _static int uhci_submit_urb (struct urb *urb, int mem_flags)
return -EINVAL;
}
+ /* increment the reference count of the urb, as we now also control it */
+ urb = usb_get_urb (urb);
+
usb_inc_dev_use (urb->dev);
spin_lock_irqsave (&s->urb_list_lock, flags);
@@ -1665,6 +1669,7 @@ _static int uhci_submit_urb (struct urb *urb, int mem_flags)
(!(urb->transfer_flags & USB_QUEUE_BULK) || !(queued_urb->transfer_flags & USB_QUEUE_BULK)))) {
spin_unlock_irqrestore (&s->urb_list_lock, flags);
usb_dec_dev_use (urb->dev);
+ usb_put_urb (urb);
err("ENXIO %08x, flags %x, urb %p, burb %p",urb->pipe,urb->transfer_flags,urb,queued_urb);
return -ENXIO; // urb already queued
}
@@ -1678,6 +1683,7 @@ _static int uhci_submit_urb (struct urb *urb, int mem_flags)
if (!urb_priv) {
usb_dec_dev_use (urb->dev);
spin_unlock_irqrestore (&s->urb_list_lock, flags);
+ usb_put_urb (urb);
return -ENOMEM;
}
@@ -1766,6 +1772,7 @@ _static int uhci_submit_urb (struct urb *urb, int mem_flags)
#else
kfree (urb_priv);
#endif
+ usb_put_urb (urb);
return ret;
}
@@ -2730,6 +2737,7 @@ _static int process_urb (uhci_t *s, struct list_head *p)
}
usb_dec_dev_use (usb_dev);
+ usb_put_urb (urb);
}
}
diff --git a/drivers/usb/vicam.c b/drivers/usb/vicam.c
index c74b653c2e52..916c808f2086 100644
--- a/drivers/usb/vicam.c
+++ b/drivers/usb/vicam.c
@@ -40,6 +40,8 @@
#include <linux/errno.h>
#include <linux/poll.h>
#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/module.h>