V4L/DVB (8829): gspca: Have a clean kmalloc-ated buffer for USB exchanges.
The USB buffer may be used for DMA and there may be a caching problem if the buffer is part of the device structure. Thanks to Alan Stern. Signed-off-by: Jean-Francois Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
91de65ac00
commit
8295d99ee5
|
@ -124,7 +124,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
|
||||||
struct usb_device *dev = gspca_dev->dev;
|
struct usb_device *dev = gspca_dev->dev;
|
||||||
|
|
||||||
#ifdef GSPCA_DEBUG
|
#ifdef GSPCA_DEBUG
|
||||||
if (len > sizeof gspca_dev->usb_buf) {
|
if (len > USB_BUF_SZ) {
|
||||||
err("reg_r: buffer overflow");
|
err("reg_r: buffer overflow");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -164,7 +164,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
|
||||||
struct usb_device *dev = gspca_dev->dev;
|
struct usb_device *dev = gspca_dev->dev;
|
||||||
|
|
||||||
#ifdef GSPCA_DEBUG
|
#ifdef GSPCA_DEBUG
|
||||||
if (len > sizeof gspca_dev->usb_buf) {
|
if (len > USB_BUF_SZ) {
|
||||||
err("reg_w: buffer overflow");
|
err("reg_w: buffer overflow");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,7 +235,7 @@ static void reg_r(struct gspca_dev *gspca_dev,
|
||||||
struct usb_device *dev = gspca_dev->dev;
|
struct usb_device *dev = gspca_dev->dev;
|
||||||
|
|
||||||
#ifdef GSPCA_DEBUG
|
#ifdef GSPCA_DEBUG
|
||||||
if (len > sizeof gspca_dev->usb_buf) {
|
if (len > USB_BUF_SZ) {
|
||||||
err("reg_r: buffer overflow");
|
err("reg_r: buffer overflow");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
|
||||||
struct usb_device *dev = gspca_dev->dev;
|
struct usb_device *dev = gspca_dev->dev;
|
||||||
|
|
||||||
#ifdef GSPCA_DEBUG
|
#ifdef GSPCA_DEBUG
|
||||||
if (len > sizeof gspca_dev->usb_buf) {
|
if (len > USB_BUF_SZ) {
|
||||||
err("reg_w: buffer overflow");
|
err("reg_w: buffer overflow");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1731,6 +1731,12 @@ int gspca_dev_probe(struct usb_interface *intf,
|
||||||
err("couldn't kzalloc gspca struct");
|
err("couldn't kzalloc gspca struct");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
gspca_dev->usb_buf = kmalloc(USB_BUF_SZ, GFP_KERNEL);
|
||||||
|
if (!gspca_dev->usb_buf) {
|
||||||
|
err("out of memory");
|
||||||
|
ret = -EIO;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
gspca_dev->dev = dev;
|
gspca_dev->dev = dev;
|
||||||
gspca_dev->iface = interface->bInterfaceNumber;
|
gspca_dev->iface = interface->bInterfaceNumber;
|
||||||
gspca_dev->nbalt = intf->num_altsetting;
|
gspca_dev->nbalt = intf->num_altsetting;
|
||||||
|
@ -1774,6 +1780,7 @@ int gspca_dev_probe(struct usb_interface *intf,
|
||||||
PDEBUG(D_PROBE, "probe ok");
|
PDEBUG(D_PROBE, "probe ok");
|
||||||
return 0;
|
return 0;
|
||||||
out:
|
out:
|
||||||
|
kfree(gspca_dev->usb_buf);
|
||||||
kfree(gspca_dev);
|
kfree(gspca_dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1806,6 +1813,7 @@ void gspca_disconnect(struct usb_interface *intf)
|
||||||
/* We don't want people trying to open up the device */
|
/* We don't want people trying to open up the device */
|
||||||
video_unregister_device(&gspca_dev->vdev);
|
video_unregister_device(&gspca_dev->vdev);
|
||||||
/* Free the memory */
|
/* Free the memory */
|
||||||
|
kfree(gspca_dev->usb_buf);
|
||||||
kfree(gspca_dev);
|
kfree(gspca_dev);
|
||||||
PDEBUG(D_PROBE, "disconnect complete");
|
PDEBUG(D_PROBE, "disconnect complete");
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,7 +127,8 @@ struct gspca_dev {
|
||||||
const struct sd_desc *sd_desc; /* subdriver description */
|
const struct sd_desc *sd_desc; /* subdriver description */
|
||||||
unsigned ctrl_dis; /* disabled controls (bit map) */
|
unsigned ctrl_dis; /* disabled controls (bit map) */
|
||||||
|
|
||||||
__u8 usb_buf[8]; /* buffer for USB exchanges */
|
#define USB_BUF_SZ 64
|
||||||
|
__u8 *usb_buf; /* buffer for USB exchanges */
|
||||||
struct urb *urb[MAX_NURBS];
|
struct urb *urb[MAX_NURBS];
|
||||||
|
|
||||||
__u8 *frbuf; /* buffer for nframes */
|
__u8 *frbuf; /* buffer for nframes */
|
||||||
|
|
|
@ -100,22 +100,6 @@ static int reg_w(struct gspca_dev *gspca_dev,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int reg_w_buf(struct gspca_dev *gspca_dev,
|
|
||||||
__u16 index, __u8 *buf, int len)
|
|
||||||
{
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = usb_control_msg(gspca_dev->dev,
|
|
||||||
usb_sndbulkpipe(gspca_dev->dev, 4),
|
|
||||||
0x12,
|
|
||||||
0xc8, /* ?? */
|
|
||||||
0, /* value */
|
|
||||||
index, buf, len, 500);
|
|
||||||
if (rc < 0)
|
|
||||||
PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bulk_w(struct gspca_dev *gspca_dev,
|
static void bulk_w(struct gspca_dev *gspca_dev,
|
||||||
__u16 *pch,
|
__u16 *pch,
|
||||||
__u16 Address)
|
__u16 Address)
|
||||||
|
@ -175,7 +159,6 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
||||||
/*
|
/*
|
||||||
Initialize the MR97113 chip register
|
Initialize the MR97113 chip register
|
||||||
*/
|
*/
|
||||||
data = kmalloc(16, GFP_KERNEL);
|
|
||||||
data[0] = 0x00; /* address */
|
data[0] = 0x00; /* address */
|
||||||
data[1] = 0x0c | 0x01; /* reg 0 */
|
data[1] = 0x0c | 0x01; /* reg 0 */
|
||||||
data[2] = 0x01; /* reg 1 */
|
data[2] = 0x01; /* reg 1 */
|
||||||
|
@ -195,12 +178,10 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
||||||
data[10] = 0x5d; /* reg 9, I2C device address
|
data[10] = 0x5d; /* reg 9, I2C device address
|
||||||
* [for PAS5101 (0x40)] [for MI (0x5d)] */
|
* [for PAS5101 (0x40)] [for MI (0x5d)] */
|
||||||
|
|
||||||
err_code = reg_w_buf(gspca_dev, data[0], data, 11);
|
err_code = reg_w(gspca_dev, data[0], 11);
|
||||||
kfree(data);
|
|
||||||
if (err_code < 0)
|
if (err_code < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
data = gspca_dev->usb_buf;
|
|
||||||
data[0] = 0x23; /* address */
|
data[0] = 0x23; /* address */
|
||||||
data[1] = 0x09; /* reg 35, append frame header */
|
data[1] = 0x09; /* reg 35, append frame header */
|
||||||
|
|
||||||
|
|
|
@ -410,7 +410,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
|
||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
#ifdef GSPCA_DEBUG
|
#ifdef GSPCA_DEBUG
|
||||||
if (len > sizeof gspca_dev->usb_buf) {
|
if (len > USB_BUF_SZ) {
|
||||||
PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
|
PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -426,26 +426,6 @@ static void reg_w(struct gspca_dev *gspca_dev,
|
||||||
500);
|
500);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reg_w_big(struct gspca_dev *gspca_dev,
|
|
||||||
__u16 value,
|
|
||||||
const __u8 *buffer,
|
|
||||||
int len)
|
|
||||||
{
|
|
||||||
__u8 *tmpbuf;
|
|
||||||
|
|
||||||
tmpbuf = kmalloc(len, GFP_KERNEL);
|
|
||||||
memcpy(tmpbuf, buffer, len);
|
|
||||||
usb_control_msg(gspca_dev->dev,
|
|
||||||
usb_sndctrlpipe(gspca_dev->dev, 0),
|
|
||||||
0x08, /* request */
|
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
|
|
||||||
value,
|
|
||||||
0, /* index */
|
|
||||||
tmpbuf, len,
|
|
||||||
500);
|
|
||||||
kfree(tmpbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
|
static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
|
||||||
{
|
{
|
||||||
int retry = 60;
|
int retry = 60;
|
||||||
|
@ -886,7 +866,7 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
||||||
/* reg 0x17 SensorClk enable inv Clk 0x60 */
|
/* reg 0x17 SensorClk enable inv Clk 0x60 */
|
||||||
reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
|
reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
|
||||||
/* Set the registers from the template */
|
/* Set the registers from the template */
|
||||||
reg_w_big(gspca_dev, 0x01, sn9c10x, l);
|
reg_w(gspca_dev, 0x01, sn9c10x, l);
|
||||||
switch (sd->sensor) {
|
switch (sd->sensor) {
|
||||||
case SENSOR_HV7131R:
|
case SENSOR_HV7131R:
|
||||||
i2c_w_vector(gspca_dev, hv7131_sensor_init,
|
i2c_w_vector(gspca_dev, hv7131_sensor_init,
|
||||||
|
|
|
@ -613,10 +613,16 @@ static const __u8 qtable4[] = {
|
||||||
0x29, 0x29, 0x29, 0x29
|
0x29, 0x29, 0x29, 0x29
|
||||||
};
|
};
|
||||||
|
|
||||||
/* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */
|
/* read <len> bytes to gspca_dev->usb_buf */
|
||||||
static void reg_r(struct gspca_dev *gspca_dev,
|
static void reg_r(struct gspca_dev *gspca_dev,
|
||||||
__u16 value, int len)
|
__u16 value, int len)
|
||||||
{
|
{
|
||||||
|
#ifdef GSPCA_DEBUG
|
||||||
|
if (len > USB_BUF_SZ) {
|
||||||
|
err("reg_r: buffer overflow");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
usb_control_msg(gspca_dev->dev,
|
usb_control_msg(gspca_dev->dev,
|
||||||
usb_rcvctrlpipe(gspca_dev->dev, 0),
|
usb_rcvctrlpipe(gspca_dev->dev, 0),
|
||||||
0,
|
0,
|
||||||
|
@ -649,29 +655,20 @@ static void reg_w(struct gspca_dev *gspca_dev,
|
||||||
{
|
{
|
||||||
PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
|
PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
|
||||||
value, buffer[0], buffer[1]);
|
value, buffer[0], buffer[1]);
|
||||||
if (len <= sizeof gspca_dev->usb_buf) {
|
#ifdef GSPCA_DEBUG
|
||||||
memcpy(gspca_dev->usb_buf, buffer, len);
|
if (len > USB_BUF_SZ) {
|
||||||
usb_control_msg(gspca_dev->dev,
|
err("reg_w: buffer overflow");
|
||||||
usb_sndctrlpipe(gspca_dev->dev, 0),
|
return;
|
||||||
0x08,
|
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
|
|
||||||
value, 0,
|
|
||||||
gspca_dev->usb_buf, len,
|
|
||||||
500);
|
|
||||||
} else {
|
|
||||||
__u8 *tmpbuf;
|
|
||||||
|
|
||||||
tmpbuf = kmalloc(len, GFP_KERNEL);
|
|
||||||
memcpy(tmpbuf, buffer, len);
|
|
||||||
usb_control_msg(gspca_dev->dev,
|
|
||||||
usb_sndctrlpipe(gspca_dev->dev, 0),
|
|
||||||
0x08,
|
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
|
|
||||||
value, 0,
|
|
||||||
tmpbuf, len,
|
|
||||||
500);
|
|
||||||
kfree(tmpbuf);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
memcpy(gspca_dev->usb_buf, buffer, len);
|
||||||
|
usb_control_msg(gspca_dev->dev,
|
||||||
|
usb_sndctrlpipe(gspca_dev->dev, 0),
|
||||||
|
0x08,
|
||||||
|
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
|
||||||
|
value, 0,
|
||||||
|
gspca_dev->usb_buf, len,
|
||||||
|
500);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* I2C write 1 byte */
|
/* I2C write 1 byte */
|
||||||
|
|
|
@ -449,31 +449,47 @@ static const __u8 qtable_spca504_default[2][64] = {
|
||||||
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
|
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
|
||||||
};
|
};
|
||||||
|
|
||||||
static void reg_r(struct usb_device *dev,
|
/* read <len> bytes to gspca_dev->usb_buf */
|
||||||
__u16 req,
|
static void reg_r(struct gspca_dev *gspca_dev,
|
||||||
__u16 index,
|
__u16 req,
|
||||||
__u8 *buffer, __u16 length)
|
__u16 index,
|
||||||
|
__u16 len)
|
||||||
{
|
{
|
||||||
usb_control_msg(dev,
|
#ifdef GSPCA_DEBUG
|
||||||
usb_rcvctrlpipe(dev, 0),
|
if (len > USB_BUF_SZ) {
|
||||||
|
err("reg_r: buffer overflow");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
usb_control_msg(gspca_dev->dev,
|
||||||
|
usb_rcvctrlpipe(gspca_dev->dev, 0),
|
||||||
req,
|
req,
|
||||||
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
0, /* value */
|
0, /* value */
|
||||||
index, buffer, length,
|
index,
|
||||||
|
len ? gspca_dev->usb_buf : NULL, len,
|
||||||
500);
|
500);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reg_w(struct usb_device *dev,
|
/* write <len> bytes from gspca_dev->usb_buf */
|
||||||
__u16 req,
|
static void reg_w(struct gspca_dev *gspca_dev,
|
||||||
__u16 value,
|
__u16 req,
|
||||||
__u16 index,
|
__u16 value,
|
||||||
__u8 *buffer, __u16 length)
|
__u16 index,
|
||||||
|
__u16 len)
|
||||||
{
|
{
|
||||||
usb_control_msg(dev,
|
#ifdef GSPCA_DEBUG
|
||||||
usb_sndctrlpipe(dev, 0),
|
if (len > USB_BUF_SZ) {
|
||||||
|
err("reg_w: buffer overflow");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
usb_control_msg(gspca_dev->dev,
|
||||||
|
usb_sndctrlpipe(gspca_dev->dev, 0),
|
||||||
req,
|
req,
|
||||||
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
|
||||||
value, index, buffer, length,
|
value, index,
|
||||||
|
len ? gspca_dev->usb_buf : NULL, len,
|
||||||
500);
|
500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,7 +650,7 @@ static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
|
||||||
int count = 10;
|
int count = 10;
|
||||||
|
|
||||||
while (--count > 0) {
|
while (--count > 0) {
|
||||||
reg_r(gspca_dev->dev, 0x21, 0, gspca_dev->usb_buf, 1);
|
reg_r(gspca_dev, 0x21, 0, 1);
|
||||||
if ((gspca_dev->usb_buf[0] & 0x01) == 0)
|
if ((gspca_dev->usb_buf[0] & 0x01) == 0)
|
||||||
break;
|
break;
|
||||||
msleep(10);
|
msleep(10);
|
||||||
|
@ -644,15 +660,14 @@ static int spca504B_PollingDataReady(struct gspca_dev *gspca_dev)
|
||||||
|
|
||||||
static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
|
static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct usb_device *dev = gspca_dev->dev;
|
|
||||||
int count = 50;
|
int count = 50;
|
||||||
|
|
||||||
while (--count > 0) {
|
while (--count > 0) {
|
||||||
reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
|
reg_r(gspca_dev, 0x21, 1, 1);
|
||||||
if (gspca_dev->usb_buf[0] != 0) {
|
if (gspca_dev->usb_buf[0] != 0) {
|
||||||
gspca_dev->usb_buf[0] = 0;
|
gspca_dev->usb_buf[0] = 0;
|
||||||
reg_w(dev, 0x21, 0, 1, gspca_dev->usb_buf, 1);
|
reg_w(gspca_dev, 0x21, 0, 1, 1);
|
||||||
reg_r(dev, 0x21, 1, gspca_dev->usb_buf, 1);
|
reg_r(gspca_dev, 0x21, 1, 1);
|
||||||
spca504B_PollingDataReady(gspca_dev);
|
spca504B_PollingDataReady(gspca_dev);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -662,16 +677,14 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
|
||||||
|
|
||||||
static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
|
static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct usb_device *dev = gspca_dev->dev;
|
|
||||||
__u8 *data;
|
__u8 *data;
|
||||||
|
|
||||||
data = kmalloc(64, GFP_KERNEL);
|
data = gspca_dev->usb_buf;
|
||||||
reg_r(dev, 0x20, 0, data, 5);
|
reg_r(gspca_dev, 0x20, 0, 5);
|
||||||
PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
|
PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
|
||||||
data[0], data[1], data[2], data[3], data[4]);
|
data[0], data[1], data[2], data[3], data[4]);
|
||||||
reg_r(dev, 0x23, 0, data, 64);
|
reg_r(gspca_dev, 0x23, 0, 64);
|
||||||
reg_r(dev, 0x23, 1, data, 64);
|
reg_r(gspca_dev, 0x23, 1, 64);
|
||||||
kfree(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
|
static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
|
||||||
|
@ -686,21 +699,21 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
|
||||||
Type = 0;
|
Type = 0;
|
||||||
switch (sd->bridge) {
|
switch (sd->bridge) {
|
||||||
case BRIDGE_SPCA533:
|
case BRIDGE_SPCA533:
|
||||||
reg_w(dev, 0x31, 0, 0, NULL, 0);
|
reg_w(gspca_dev, 0x31, 0, 0, 0);
|
||||||
spca504B_WaitCmdStatus(gspca_dev);
|
spca504B_WaitCmdStatus(gspca_dev);
|
||||||
rc = spca504B_PollingDataReady(gspca_dev);
|
rc = spca504B_PollingDataReady(gspca_dev);
|
||||||
spca50x_GetFirmware(gspca_dev);
|
spca50x_GetFirmware(gspca_dev);
|
||||||
gspca_dev->usb_buf[0] = 2; /* type */
|
gspca_dev->usb_buf[0] = 2; /* type */
|
||||||
reg_w(dev, 0x24, 0, 8, gspca_dev->usb_buf, 1);
|
reg_w(gspca_dev, 0x24, 0, 8, 1);
|
||||||
reg_r(dev, 0x24, 8, gspca_dev->usb_buf, 1);
|
reg_r(gspca_dev, 0x24, 8, 1);
|
||||||
|
|
||||||
gspca_dev->usb_buf[0] = Size;
|
gspca_dev->usb_buf[0] = Size;
|
||||||
reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
|
reg_w(gspca_dev, 0x25, 0, 4, 1);
|
||||||
reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */
|
reg_r(gspca_dev, 0x25, 4, 1); /* size */
|
||||||
rc = spca504B_PollingDataReady(gspca_dev);
|
rc = spca504B_PollingDataReady(gspca_dev);
|
||||||
|
|
||||||
/* Init the cam width height with some values get on init ? */
|
/* Init the cam width height with some values get on init ? */
|
||||||
reg_w(dev, 0x31, 0, 4, NULL, 0);
|
reg_w(gspca_dev, 0x31, 0, 4, 0);
|
||||||
spca504B_WaitCmdStatus(gspca_dev);
|
spca504B_WaitCmdStatus(gspca_dev);
|
||||||
rc = spca504B_PollingDataReady(gspca_dev);
|
rc = spca504B_PollingDataReady(gspca_dev);
|
||||||
break;
|
break;
|
||||||
|
@ -708,12 +721,12 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
|
||||||
/* case BRIDGE_SPCA504B: */
|
/* case BRIDGE_SPCA504B: */
|
||||||
/* case BRIDGE_SPCA536: */
|
/* case BRIDGE_SPCA536: */
|
||||||
gspca_dev->usb_buf[0] = Size;
|
gspca_dev->usb_buf[0] = Size;
|
||||||
reg_w(dev, 0x25, 0, 4, gspca_dev->usb_buf, 1);
|
reg_w(gspca_dev, 0x25, 0, 4, 1);
|
||||||
reg_r(dev, 0x25, 4, gspca_dev->usb_buf, 1); /* size */
|
reg_r(gspca_dev, 0x25, 4, 1); /* size */
|
||||||
Type = 6;
|
Type = 6;
|
||||||
gspca_dev->usb_buf[0] = Type;
|
gspca_dev->usb_buf[0] = Type;
|
||||||
reg_w(dev, 0x27, 0, 0, gspca_dev->usb_buf, 1);
|
reg_w(gspca_dev, 0x27, 0, 0, 1);
|
||||||
reg_r(dev, 0x27, 0, gspca_dev->usb_buf, 1); /* type */
|
reg_r(gspca_dev, 0x27, 0, 1); /* type */
|
||||||
rc = spca504B_PollingDataReady(gspca_dev);
|
rc = spca504B_PollingDataReady(gspca_dev);
|
||||||
break;
|
break;
|
||||||
case BRIDGE_SPCA504:
|
case BRIDGE_SPCA504:
|
||||||
|
@ -752,18 +765,15 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev)
|
||||||
|
|
||||||
static void spca504B_setQtable(struct gspca_dev *gspca_dev)
|
static void spca504B_setQtable(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct usb_device *dev = gspca_dev->dev;
|
|
||||||
|
|
||||||
gspca_dev->usb_buf[0] = 3;
|
gspca_dev->usb_buf[0] = 3;
|
||||||
reg_w(dev, 0x26, 0, 0, gspca_dev->usb_buf, 1);
|
reg_w(gspca_dev, 0x26, 0, 0, 1);
|
||||||
reg_r(dev, 0x26, 0, gspca_dev->usb_buf, 1);
|
reg_r(gspca_dev, 0x26, 0, 1);
|
||||||
spca504B_PollingDataReady(gspca_dev);
|
spca504B_PollingDataReady(gspca_dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
|
static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
struct usb_device *dev = gspca_dev->dev;
|
|
||||||
int pollreg = 1;
|
int pollreg = 1;
|
||||||
|
|
||||||
switch (sd->bridge) {
|
switch (sd->bridge) {
|
||||||
|
@ -774,20 +784,20 @@ static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
|
||||||
default:
|
default:
|
||||||
/* case BRIDGE_SPCA533: */
|
/* case BRIDGE_SPCA533: */
|
||||||
/* case BRIDGE_SPCA504B: */
|
/* case BRIDGE_SPCA504B: */
|
||||||
reg_w(dev, 0, 0, 0x21a7, NULL, 0); /* brightness */
|
reg_w(gspca_dev, 0, 0, 0x21a7, 0); /* brightness */
|
||||||
reg_w(dev, 0, 0x20, 0x21a8, NULL, 0); /* contrast */
|
reg_w(gspca_dev, 0, 0x20, 0x21a8, 0); /* contrast */
|
||||||
reg_w(dev, 0, 0, 0x21ad, NULL, 0); /* hue */
|
reg_w(gspca_dev, 0, 0, 0x21ad, 0); /* hue */
|
||||||
reg_w(dev, 0, 1, 0x21ac, NULL, 0); /* sat/hue */
|
reg_w(gspca_dev, 0, 1, 0x21ac, 0); /* sat/hue */
|
||||||
reg_w(dev, 0, 0x20, 0x21ae, NULL, 0); /* saturation */
|
reg_w(gspca_dev, 0, 0x20, 0x21ae, 0); /* saturation */
|
||||||
reg_w(dev, 0, 0, 0x21a3, NULL, 0); /* gamma */
|
reg_w(gspca_dev, 0, 0, 0x21a3, 0); /* gamma */
|
||||||
break;
|
break;
|
||||||
case BRIDGE_SPCA536:
|
case BRIDGE_SPCA536:
|
||||||
reg_w(dev, 0, 0, 0x20f0, NULL, 0);
|
reg_w(gspca_dev, 0, 0, 0x20f0, 0);
|
||||||
reg_w(dev, 0, 0x21, 0x20f1, NULL, 0);
|
reg_w(gspca_dev, 0, 0x21, 0x20f1, 0);
|
||||||
reg_w(dev, 0, 0x40, 0x20f5, NULL, 0);
|
reg_w(gspca_dev, 0, 0x40, 0x20f5, 0);
|
||||||
reg_w(dev, 0, 1, 0x20f4, NULL, 0);
|
reg_w(gspca_dev, 0, 1, 0x20f4, 0);
|
||||||
reg_w(dev, 0, 0x40, 0x20f6, NULL, 0);
|
reg_w(gspca_dev, 0, 0x40, 0x20f6, 0);
|
||||||
reg_w(dev, 0, 0, 0x2089, NULL, 0);
|
reg_w(gspca_dev, 0, 0, 0x2089, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (pollreg)
|
if (pollreg)
|
||||||
|
@ -799,7 +809,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
||||||
const struct usb_device_id *id)
|
const struct usb_device_id *id)
|
||||||
{
|
{
|
||||||
struct sd *sd = (struct sd *) gspca_dev;
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
struct usb_device *dev = gspca_dev->dev;
|
|
||||||
struct cam *cam;
|
struct cam *cam;
|
||||||
|
|
||||||
cam = &gspca_dev->cam;
|
cam = &gspca_dev->cam;
|
||||||
|
@ -811,7 +820,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
||||||
if (sd->subtype == AiptekMiniPenCam13) {
|
if (sd->subtype == AiptekMiniPenCam13) {
|
||||||
/* try to get the firmware as some cam answer 2.0.1.2.2
|
/* try to get the firmware as some cam answer 2.0.1.2.2
|
||||||
* and should be a spca504b then overwrite that setting */
|
* and should be a spca504b then overwrite that setting */
|
||||||
reg_r(dev, 0x20, 0, gspca_dev->usb_buf, 1);
|
reg_r(gspca_dev, 0x20, 0, 1);
|
||||||
switch (gspca_dev->usb_buf[0]) {
|
switch (gspca_dev->usb_buf[0]) {
|
||||||
case 1:
|
case 1:
|
||||||
break; /* (right bridge/subtype) */
|
break; /* (right bridge/subtype) */
|
||||||
|
@ -860,12 +869,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
||||||
|
|
||||||
switch (sd->bridge) {
|
switch (sd->bridge) {
|
||||||
case BRIDGE_SPCA504B:
|
case BRIDGE_SPCA504B:
|
||||||
reg_w(dev, 0x1d, 0, 0, NULL, 0);
|
reg_w(gspca_dev, 0x1d, 0, 0, 0);
|
||||||
reg_w(dev, 0, 1, 0x2306, NULL, 0);
|
reg_w(gspca_dev, 0, 1, 0x2306, 0);
|
||||||
reg_w(dev, 0, 0, 0x0d04, NULL, 0);
|
reg_w(gspca_dev, 0, 0, 0x0d04, 0);
|
||||||
reg_w(dev, 0, 0, 0x2000, NULL, 0);
|
reg_w(gspca_dev, 0, 0, 0x2000, 0);
|
||||||
reg_w(dev, 0, 0x13, 0x2301, NULL, 0);
|
reg_w(gspca_dev, 0, 0x13, 0x2301, 0);
|
||||||
reg_w(dev, 0, 0, 0x2306, NULL, 0);
|
reg_w(gspca_dev, 0, 0, 0x2306, 0);
|
||||||
/* fall thru */
|
/* fall thru */
|
||||||
case BRIDGE_SPCA533:
|
case BRIDGE_SPCA533:
|
||||||
rc = spca504B_PollingDataReady(gspca_dev);
|
rc = spca504B_PollingDataReady(gspca_dev);
|
||||||
|
@ -873,12 +882,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
|
||||||
break;
|
break;
|
||||||
case BRIDGE_SPCA536:
|
case BRIDGE_SPCA536:
|
||||||
spca50x_GetFirmware(gspca_dev);
|
spca50x_GetFirmware(gspca_dev);
|
||||||
reg_r(dev, 0x00, 0x5002, gspca_dev->usb_buf, 1);
|
reg_r(gspca_dev, 0x00, 0x5002, 1);
|
||||||
gspca_dev->usb_buf[0] = 0;
|
gspca_dev->usb_buf[0] = 0;
|
||||||
reg_w(dev, 0x24, 0, 0, gspca_dev->usb_buf, 1);
|
reg_w(gspca_dev, 0x24, 0, 0, 1);
|
||||||
reg_r(dev, 0x24, 0, gspca_dev->usb_buf, 1);
|
reg_r(gspca_dev, 0x24, 0, 1);
|
||||||
rc = spca504B_PollingDataReady(gspca_dev);
|
rc = spca504B_PollingDataReady(gspca_dev);
|
||||||
reg_w(dev, 0x34, 0, 0, NULL, 0);
|
reg_w(gspca_dev, 0x34, 0, 0, 0);
|
||||||
spca504B_WaitCmdStatus(gspca_dev);
|
spca504B_WaitCmdStatus(gspca_dev);
|
||||||
break;
|
break;
|
||||||
case BRIDGE_SPCA504C: /* pccam600 */
|
case BRIDGE_SPCA504C: /* pccam600 */
|
||||||
|
@ -971,12 +980,12 @@ static void sd_start(struct gspca_dev *gspca_dev)
|
||||||
/* case BRIDGE_SPCA536: */
|
/* case BRIDGE_SPCA536: */
|
||||||
if (sd->subtype == MegapixV4 ||
|
if (sd->subtype == MegapixV4 ||
|
||||||
sd->subtype == LogitechClickSmart820) {
|
sd->subtype == LogitechClickSmart820) {
|
||||||
reg_w(dev, 0xf0, 0, 0, NULL, 0);
|
reg_w(gspca_dev, 0xf0, 0, 0, 0);
|
||||||
spca504B_WaitCmdStatus(gspca_dev);
|
spca504B_WaitCmdStatus(gspca_dev);
|
||||||
reg_r(dev, 0xf0, 4, NULL, 0);
|
reg_r(gspca_dev, 0xf0, 4, 0);
|
||||||
spca504B_WaitCmdStatus(gspca_dev);
|
spca504B_WaitCmdStatus(gspca_dev);
|
||||||
} else {
|
} else {
|
||||||
reg_w(dev, 0x31, 0, 4, NULL, 0);
|
reg_w(gspca_dev, 0x31, 0, 4, 0);
|
||||||
spca504B_WaitCmdStatus(gspca_dev);
|
spca504B_WaitCmdStatus(gspca_dev);
|
||||||
rc = spca504B_PollingDataReady(gspca_dev);
|
rc = spca504B_PollingDataReady(gspca_dev);
|
||||||
}
|
}
|
||||||
|
@ -1045,7 +1054,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
|
||||||
/* case BRIDGE_SPCA533: */
|
/* case BRIDGE_SPCA533: */
|
||||||
/* case BRIDGE_SPCA536: */
|
/* case BRIDGE_SPCA536: */
|
||||||
/* case BRIDGE_SPCA504B: */
|
/* case BRIDGE_SPCA504B: */
|
||||||
reg_w(dev, 0x31, 0, 0, NULL, 0);
|
reg_w(gspca_dev, 0x31, 0, 0, 0);
|
||||||
spca504B_WaitCmdStatus(gspca_dev);
|
spca504B_WaitCmdStatus(gspca_dev);
|
||||||
spca504B_PollingDataReady(gspca_dev);
|
spca504B_PollingDataReady(gspca_dev);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -391,7 +391,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
|
||||||
NULL, 0, 500);
|
NULL, 0, 500);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (len <= sizeof gspca_dev->usb_buf) {
|
if (len <= USB_BUF_SZ) {
|
||||||
memcpy(gspca_dev->usb_buf, buffer, len);
|
memcpy(gspca_dev->usb_buf, buffer, len);
|
||||||
usb_control_msg(gspca_dev->dev,
|
usb_control_msg(gspca_dev->dev,
|
||||||
usb_sndctrlpipe(gspca_dev->dev, 0),
|
usb_sndctrlpipe(gspca_dev->dev, 0),
|
||||||
|
|
Loading…
Reference in New Issue