aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/Kconfig144
-rw-r--r--drivers/media/video/gspca/conex.c3
-rw-r--r--drivers/media/video/gspca/finepix.c8
-rw-r--r--drivers/media/video/gspca/gspca.c56
-rw-r--r--drivers/media/video/gspca/gspca.h6
-rw-r--r--drivers/media/video/gspca/pac7311.c3
-rw-r--r--drivers/media/video/gspca/spca501.c3
-rw-r--r--drivers/media/video/gspca/spca505.c4
-rw-r--r--drivers/media/video/gspca/spca561.c3
-rw-r--r--drivers/media/video/gspca/vc032x.c3
-rw-r--r--drivers/media/video/gspca/zc3xx.c15
11 files changed, 142 insertions, 106 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 4d0817471c9..6b557c057fa 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -3,16 +3,16 @@ menuconfig USB_GSPCA
depends on VIDEO_V4L2
default m
---help---
- Say Y here if you want to enable selecting webcams based
- on the GSPCA framework.
+ Say Y here if you want to enable selecting webcams based
+ on the GSPCA framework.
- See <file:Documentation/video4linux/gspca.txt> for more info.
+ See <file:Documentation/video4linux/gspca.txt> for more info.
- This driver uses the Video For Linux API. You must say Y or M to
- "Video For Linux" to use this driver.
+ This driver uses the Video For Linux API. You must say Y or M to
+ "Video For Linux" to use this driver.
- To compile this driver as modules, choose M here: the
- modules will be called gspca_main.
+ To compile this driver as modules, choose M here: the
+ modules will be called gspca_main.
if USB_GSPCA && VIDEO_V4L2
@@ -23,190 +23,190 @@ config USB_GSPCA_CONEX
tristate "Conexant Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the Conexant chip.
+ Say Y here if you want support for cameras based on the Conexant chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_conex.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_conex.
config USB_GSPCA_ETOMS
tristate "Etoms USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the Etoms chip.
+ Say Y here if you want support for cameras based on the Etoms chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_etoms.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_etoms.
config USB_GSPCA_FINEPIX
tristate "Fujifilm FinePix USB V4L2 driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the FinePix chip.
+ Say Y here if you want support for cameras based on the FinePix chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_finepix.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_finepix.
config USB_GSPCA_MARS
tristate "Mars USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the Mars chip.
+ Say Y here if you want support for cameras based on the Mars chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_mars.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_mars.
config USB_GSPCA_OV519
tristate "OV519 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the OV519 chip.
+ Say Y here if you want support for cameras based on the OV519 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_ov519.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_ov519.
config USB_GSPCA_PAC207
tristate "Pixart PAC207 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the PAC207 chip.
+ Say Y here if you want support for cameras based on the PAC207 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_pac207.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_pac207.
config USB_GSPCA_PAC7311
tristate "Pixart PAC7311 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the PAC7311 chip.
+ Say Y here if you want support for cameras based on the PAC7311 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_pac7311.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_pac7311.
config USB_GSPCA_SONIXB
tristate "SN9C102 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the SONIXB chip.
+ Say Y here if you want support for cameras based on the SONIXB chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_sonixb.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sonixb.
config USB_GSPCA_SONIXJ
tristate "SONIX JPEG USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the SONIXJ chip.
+ Say Y here if you want support for cameras based on the SONIXJ chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_sonixj
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sonixj
config USB_GSPCA_SPCA500
tristate "SPCA500 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the SPCA500 chip.
+ Say Y here if you want support for cameras based on the SPCA500 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca500.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_spca500.
config USB_GSPCA_SPCA501
tristate "SPCA501 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the SPCA501 chip.
+ Say Y here if you want support for cameras based on the SPCA501 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca501.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_spca501.
config USB_GSPCA_SPCA505
tristate "SPCA505 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the SPCA505 chip.
+ Say Y here if you want support for cameras based on the SPCA505 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca505.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_spca505.
config USB_GSPCA_SPCA506
tristate "SPCA506 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the SPCA506 chip.
+ Say Y here if you want support for cameras based on the SPCA506 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca506.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_spca506.
config USB_GSPCA_SPCA508
tristate "SPCA508 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the SPCA508 chip.
+ Say Y here if you want support for cameras based on the SPCA508 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca508.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_spca508.
config USB_GSPCA_SPCA561
tristate "SPCA561 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the SPCA561 chip.
+ Say Y here if you want support for cameras based on the SPCA561 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca561.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_spca561.
config USB_GSPCA_STK014
tristate "Syntek DV4000 (STK014) USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the STK014 chip.
+ Say Y here if you want support for cameras based on the STK014 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_stk014.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_stk014.
config USB_GSPCA_SUNPLUS
tristate "SUNPLUS USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the Sunplus
- SPCA504(abc) SPCA533 SPCA536 chips.
+ Say Y here if you want support for cameras based on the Sunplus
+ SPCA504(abc) SPCA533 SPCA536 chips.
- To compile this driver as a module, choose M here: the
- module will be called gspca_spca5xx.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_spca5xx.
config USB_GSPCA_T613
tristate "T613 (JPEG Compliance) USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the T613 chip.
+ Say Y here if you want support for cameras based on the T613 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_t613.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_t613.
config USB_GSPCA_TV8532
tristate "TV8532 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the TV8531 chip.
+ Say Y here if you want support for cameras based on the TV8531 chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_tv8532.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_tv8532.
config USB_GSPCA_VC032X
tristate "VC032X USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the VC032X chip.
+ Say Y here if you want support for cameras based on the VC032X chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_vc032x.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_vc032x.
config USB_GSPCA_ZC3XX
- tristate "VC3xx USB Camera Driver"
+ tristate "ZC3XX USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
help
- Say Y here if you want support for cameras based on the ZC3XX chip.
+ Say Y here if you want support for cameras based on the ZC3XX chip.
- To compile this driver as a module, choose M here: the
- module will be called gspca_zc3xx.
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_zc3xx.
endif
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index a9d51ba7c57..de28354ea5b 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -846,10 +846,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0;
}
+/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
int retry = 50;
+ if (!gspca_dev->present)
+ return;
reg_w_val(gspca_dev, 0x0000, 0x00);
reg_r(gspca_dev, 0x0002, 1);
reg_w_val(gspca_dev, 0x0053, 0x00);
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index 65d3cbfe6b2..607942fd797 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -276,6 +276,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
/* Stop the state machine */
if (dev->state != FPIX_NOP)
wait_for_completion(&dev->can_close);
+}
+
+/* called on streamoff with alt 0 and disconnect */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
usb_free_urb(dev->control_urb);
dev->control_urb = NULL;
@@ -385,6 +391,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
error:
/* Free the ressources */
sd_stopN(gspca_dev);
+ sd_stop0(gspca_dev);
return ret;
}
@@ -425,6 +432,7 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
};
/* -- device connect -- */
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index e48fbfc8ad0..748a87e82e4 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -646,15 +646,14 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev)
{
gspca_dev->streaming = 0;
atomic_set(&gspca_dev->nevent, 0);
- if (gspca_dev->present) {
- if (gspca_dev->sd_desc->stopN)
- gspca_dev->sd_desc->stopN(gspca_dev);
- destroy_urbs(gspca_dev);
- gspca_set_alt0(gspca_dev);
- if (gspca_dev->sd_desc->stop0)
- gspca_dev->sd_desc->stop0(gspca_dev);
- PDEBUG(D_STREAM, "stream off OK");
- }
+ if (gspca_dev->present
+ && gspca_dev->sd_desc->stopN)
+ gspca_dev->sd_desc->stopN(gspca_dev);
+ destroy_urbs(gspca_dev);
+ gspca_set_alt0(gspca_dev);
+ if (gspca_dev->sd_desc->stop0)
+ gspca_dev->sd_desc->stop0(gspca_dev);
+ PDEBUG(D_STREAM, "stream off OK");
}
static void gspca_set_default_mode(struct gspca_dev *gspca_dev)
@@ -863,7 +862,7 @@ static int dev_open(struct inode *inode, struct file *file)
int ret;
PDEBUG(D_STREAM, "%s open", current->comm);
- gspca_dev = (struct gspca_dev *) video_devdata(file);
+ gspca_dev = video_drvdata(file);
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
if (!gspca_dev->present) {
@@ -875,6 +874,13 @@ static int dev_open(struct inode *inode, struct file *file)
ret = -EBUSY;
goto out;
}
+
+ /* protect the subdriver against rmmod */
+ if (!try_module_get(gspca_dev->module)) {
+ ret = -ENODEV;
+ goto out;
+ }
+
gspca_dev->users++;
/* one more user */
@@ -884,10 +890,10 @@ static int dev_open(struct inode *inode, struct file *file)
#ifdef GSPCA_DEBUG
/* activate the v4l2 debug */
if (gspca_debug & D_V4L2)
- gspca_dev->vdev.debug |= V4L2_DEBUG_IOCTL
+ gspca_dev->vdev->debug |= V4L2_DEBUG_IOCTL
| V4L2_DEBUG_IOCTL_ARG;
else
- gspca_dev->vdev.debug &= ~(V4L2_DEBUG_IOCTL
+ gspca_dev->vdev->debug &= ~(V4L2_DEBUG_IOCTL
| V4L2_DEBUG_IOCTL_ARG);
#endif
ret = 0;
@@ -921,6 +927,7 @@ static int dev_close(struct inode *inode, struct file *file)
gspca_dev->memory = GSPCA_MEMORY_NO;
}
file->private_data = NULL;
+ module_put(gspca_dev->module);
mutex_unlock(&gspca_dev->queue_lock);
PDEBUG(D_STREAM, "close done");
@@ -1748,11 +1755,6 @@ out:
return ret;
}
-static void dev_release(struct video_device *vfd)
-{
- /* nothing */
-}
-
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.open = dev_open,
@@ -1800,7 +1802,7 @@ static struct video_device gspca_template = {
.name = "gspca main driver",
.fops = &dev_fops,
.ioctl_ops = &dev_ioctl_ops,
- .release = dev_release, /* mandatory */
+ .release = video_device_release,
.minor = -1,
};
@@ -1869,17 +1871,18 @@ int gspca_dev_probe(struct usb_interface *intf,
init_waitqueue_head(&gspca_dev->wq);
/* init video stuff */
- memcpy(&gspca_dev->vdev, &gspca_template, sizeof gspca_template);
- gspca_dev->vdev.parent = &dev->dev;
- memcpy(&gspca_dev->fops, &dev_fops, sizeof gspca_dev->fops);
- gspca_dev->vdev.fops = &gspca_dev->fops;
- gspca_dev->fops.owner = module; /* module protection */
+ gspca_dev->vdev = video_device_alloc();
+ memcpy(gspca_dev->vdev, &gspca_template, sizeof gspca_template);
+ gspca_dev->vdev->parent = &dev->dev;
+ gspca_dev->module = module;
gspca_dev->present = 1;
- ret = video_register_device(&gspca_dev->vdev,
+ video_set_drvdata(gspca_dev->vdev, gspca_dev);
+ ret = video_register_device(gspca_dev->vdev,
VFL_TYPE_GRABBER,
video_nr);
if (ret < 0) {
err("video_register_device err %d", ret);
+ video_device_release(gspca_dev->vdev);
goto out;
}
@@ -1887,7 +1890,8 @@ int gspca_dev_probe(struct usb_interface *intf,
PDEBUG(D_PROBE, "probe ok");
return 0;
out:
- kref_put(&gspca_dev->kref, gspca_delete);
+ kfree(gspca_dev->usb_buf);
+ kfree(gspca_dev);
return ret;
}
EXPORT_SYMBOL(gspca_dev_probe);
@@ -1905,7 +1909,7 @@ void gspca_disconnect(struct usb_interface *intf)
usb_set_intfdata(intf, NULL);
/* We don't want people trying to open up the device */
- video_unregister_device(&gspca_dev->vdev);
+ video_unregister_device(gspca_dev->vdev);
gspca_dev->present = 0;
gspca_dev->streaming = 0;
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 1d9dc90b479..d25e8d69373 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -97,7 +97,7 @@ struct sd_desc {
cam_pkt_op pkt_scan;
/* optional operations */
cam_v_op stopN; /* called on stream off - main alt */
- cam_v_op stop0; /* called on stream off - alt 0 */
+ cam_v_op stop0; /* called on stream off & disconnect - alt 0 */
cam_v_op dq_callback; /* called when a frame has been dequeued */
cam_jpg_op get_jcomp;
cam_jpg_op set_jcomp;
@@ -120,8 +120,8 @@ struct gspca_frame {
};
struct gspca_dev {
- struct video_device vdev; /* !! must be the first item */
- struct file_operations fops;
+ struct video_device *vdev;
+ struct module *module; /* subdriver handling the device */
struct usb_device *dev;
struct kref kref;
struct file *capt_file; /* file doing video capture */
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index e5ff9a6199e..fbd45e235d9 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -749,10 +749,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x78, 0x44); /* Bit_0=start stream, Bit_6=LED */
}
+/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ if (!gspca_dev->present)
+ return;
if (sd->sensor == SENSOR_PAC7302) {
reg_w(gspca_dev, 0xff, 0x01);
reg_w(gspca_dev, 0x78, 0x40);
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index b742f260c7c..e29954c1c38 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -2022,8 +2022,11 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x01, 0x00);
}
+/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
+ if (!gspca_dev->present)
+ return;
reg_write(gspca_dev->dev, SPCA501_REG_CTLRL, 0x05, 0x00);
}
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index b345749213c..895b9fe4018 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -742,8 +742,12 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, 0x02, 0x00, 0x00);
}
+/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
+ if (!gspca_dev->present)
+ return;
+
/* This maybe reset or power control */
reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 020a03c466c..c3de4e44123 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -766,10 +766,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
}
}
+/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ if (!gspca_dev->present)
+ return;
if (sd->chip_revision == Rev012A) {
reg_w_val(gspca_dev->dev, 0x8118, 0x29);
reg_w_val(gspca_dev->dev, 0x8114, 0x08);
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index be46d923254..17af353ddd1 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -1633,10 +1633,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w(dev, 0xa0, 0x09, 0xb003);
}
+/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
+ if (!gspca_dev->present)
+ return;
reg_w(dev, 0x89, 0xffff, 0xffff);
}
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index d0a4451dc46..0befacf4985 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -2266,7 +2266,7 @@ static const struct usb_action hdcs2020b_NoFliker[] = {
{}
};
-static const struct usb_action hv7131bxx_Initial[] = {
+static const struct usb_action hv7131bxx_Initial[] = { /* 320x240 */
{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x10, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -2290,7 +2290,7 @@ static const struct usb_action hv7131bxx_Initial[] = {
{0xaa, 0x14, 0x0001},
{0xaa, 0x15, 0x00e8},
{0xaa, 0x16, 0x0002},
- {0xaa, 0x17, 0x0086},
+ {0xaa, 0x17, 0x0086}, /* 00,17,88,aa */
{0xaa, 0x31, 0x0038},
{0xaa, 0x32, 0x0038},
{0xaa, 0x33, 0x0038},
@@ -2309,7 +2309,7 @@ static const struct usb_action hv7131bxx_Initial[] = {
{0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
{0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
{0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xaa, 0x02, 0x0080}, /* {0xaa, 0x02, 0x0090}; */
+ {0xaa, 0x02, 0x0090}, /* 00,02,80,aa */
{0xa1, 0x01, 0x0002},
{0xa0, 0x00, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x02, ZC3XX_R090_I2CCOMMAND},
@@ -2374,7 +2374,7 @@ static const struct usb_action hv7131bxx_Initial[] = {
{}
};
-static const struct usb_action hv7131bxx_InitialScale[] = {
+static const struct usb_action hv7131bxx_InitialScale[] = { /* 640x480*/
{0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x00, ZC3XX_R010_CMOSSENSORSELECT},
@@ -6388,6 +6388,8 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/*fixme: is it really write to 011d and 018d for all other sensors? */
brightness = sd->brightness;
reg_w(gspca_dev->dev, brightness, 0x011d);
+ if (sd->sensor == SENSOR_HV7131B)
+ return;
if (brightness < 0x70)
brightness += 0x10;
else
@@ -6529,6 +6531,7 @@ static void setquality(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_GC0305:
+ case SENSOR_HV7131B:
case SENSOR_OV7620:
case SENSOR_PO2030:
return;
@@ -7209,7 +7212,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
zc3_init = init_tb[(int) sd->sensor][mode];
switch (sd->sensor) {
- case SENSOR_HV7131B:
case SENSOR_HV7131C:
zcxx_probeSensor(gspca_dev);
break;
@@ -7334,10 +7336,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
return 0;
}
+/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ if (!gspca_dev->present)
+ return;
send_unknown(gspca_dev->dev, sd->sensor);
}