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/Kconfig27
-rw-r--r--drivers/media/video/gspca/Makefile102
-rw-r--r--drivers/media/video/gspca/conex.c63
-rw-r--r--drivers/media/video/gspca/etoms.c36
-rw-r--r--drivers/media/video/gspca/finepix.c433
-rw-r--r--drivers/media/video/gspca/gspca.c166
-rw-r--r--drivers/media/video/gspca/gspca.h14
-rw-r--r--drivers/media/video/gspca/jpeg.h263
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c7
-rw-r--r--drivers/media/video/gspca/mars.c506
-rw-r--r--drivers/media/video/gspca/mr97310a.c362
-rw-r--r--drivers/media/video/gspca/ov519.c7
-rw-r--r--drivers/media/video/gspca/ov534.c820
-rw-r--r--drivers/media/video/gspca/pac207.c8
-rw-r--r--drivers/media/video/gspca/pac7311.c7
-rw-r--r--drivers/media/video/gspca/sonixb.c7
-rw-r--r--drivers/media/video/gspca/sonixj.c951
-rw-r--r--drivers/media/video/gspca/spca500.c99
-rw-r--r--drivers/media/video/gspca/spca501.c22
-rw-r--r--drivers/media/video/gspca/spca505.c525
-rw-r--r--drivers/media/video/gspca/spca506.c57
-rw-r--r--drivers/media/video/gspca/spca508.c128
-rw-r--r--drivers/media/video/gspca/spca561.c192
-rw-r--r--drivers/media/video/gspca/sq905.c456
-rw-r--r--drivers/media/video/gspca/sq905c.c328
-rw-r--r--drivers/media/video/gspca/stk014.c72
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c7
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c76
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h65
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c147
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h130
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h8
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c123
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h58
-rw-r--r--drivers/media/video/gspca/sunplus.c124
-rw-r--r--drivers/media/video/gspca/t613.c564
-rw-r--r--drivers/media/video/gspca/tv8532.c483
-rw-r--r--drivers/media/video/gspca/vc032x.c1591
-rw-r--r--drivers/media/video/gspca/zc3xx.c884
39 files changed, 6308 insertions, 3610 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index ee6a691dff2..578dc4ffc96 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -56,6 +56,15 @@ config USB_GSPCA_MARS
To compile this driver as a module, choose M here: the
module will be called gspca_mars.
+config USB_GSPCA_MR97310A
+ tristate "Mars-Semi MR97310A USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the MR97310A chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_mr97310a.
+
config USB_GSPCA_OV519
tristate "OV519 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
@@ -167,6 +176,24 @@ config USB_GSPCA_SPCA561
To compile this driver as a module, choose M here: the
module will be called gspca_spca561.
+config USB_GSPCA_SQ905
+ tristate "SQ Technologies SQ905 based USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the SQ905 chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sq905.
+
+config USB_GSPCA_SQ905C
+ tristate "SQ Technologies SQ905C based USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the SQ905C chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sq905c.
+
config USB_GSPCA_STK014
tristate "Syntek DV4000 (STK014) USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index bd8d9ee4050..8a6643e8eb9 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -1,50 +1,56 @@
-obj-$(CONFIG_USB_GSPCA) += gspca_main.o
-obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
-obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
-obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
-obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
-obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
-obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
-obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
-obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
-obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
-obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
-obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
-obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
-obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
-obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
-obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
-obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
-obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
-obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
-obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
-obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
-obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
-obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
+obj-$(CONFIG_USB_GSPCA) += gspca_main.o
+obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
+obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
+obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
+obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
+obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
+obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
+obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
+obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
+obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
+obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
+obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
+obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
+obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
+obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
+obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
+obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
+obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
+obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o
+obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o
+obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
+obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
+obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
+obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
+obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
+obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
-gspca_main-objs := gspca.o
-gspca_conex-objs := conex.o
-gspca_etoms-objs := etoms.o
-gspca_finepix-objs := finepix.o
-gspca_mars-objs := mars.o
-gspca_ov519-objs := ov519.o
-gspca_ov534-objs := ov534.o
-gspca_pac207-objs := pac207.o
-gspca_pac7311-objs := pac7311.o
-gspca_sonixb-objs := sonixb.o
-gspca_sonixj-objs := sonixj.o
-gspca_spca500-objs := spca500.o
-gspca_spca501-objs := spca501.o
-gspca_spca505-objs := spca505.o
-gspca_spca506-objs := spca506.o
-gspca_spca508-objs := spca508.o
-gspca_spca561-objs := spca561.o
-gspca_stk014-objs := stk014.o
-gspca_sunplus-objs := sunplus.o
-gspca_t613-objs := t613.o
-gspca_tv8532-objs := tv8532.o
-gspca_vc032x-objs := vc032x.o
-gspca_zc3xx-objs := zc3xx.o
+gspca_main-objs := gspca.o
+gspca_conex-objs := conex.o
+gspca_etoms-objs := etoms.o
+gspca_finepix-objs := finepix.o
+gspca_mars-objs := mars.o
+gspca_mr97310a-objs := mr97310a.o
+gspca_ov519-objs := ov519.o
+gspca_ov534-objs := ov534.o
+gspca_pac207-objs := pac207.o
+gspca_pac7311-objs := pac7311.o
+gspca_sonixb-objs := sonixb.o
+gspca_sonixj-objs := sonixj.o
+gspca_spca500-objs := spca500.o
+gspca_spca501-objs := spca501.o
+gspca_spca505-objs := spca505.o
+gspca_spca506-objs := spca506.o
+gspca_spca508-objs := spca508.o
+gspca_spca561-objs := spca561.o
+gspca_sq905-objs := sq905.o
+gspca_sq905c-objs := sq905c.o
+gspca_stk014-objs := stk014.o
+gspca_sunplus-objs := sunplus.o
+gspca_t613-objs := t613.o
+gspca_tv8532-objs := tv8532.o
+gspca_vc032x-objs := vc032x.o
+gspca_zc3xx-objs := zc3xx.o
-obj-$(CONFIG_USB_M5602) += m5602/
-obj-$(CONFIG_USB_STV06XX) += stv06xx/
+obj-$(CONFIG_USB_M5602) += m5602/
+obj-$(CONFIG_USB_STV06XX) += stv06xx/
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 1753f5bb354..219cfa6fb87 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -36,8 +36,12 @@ struct sd {
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
+ u8 quality;
+#define QUALITY_MIN 30
+#define QUALITY_MAX 60
+#define QUALITY_DEF 40
- unsigned char qindex;
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -815,14 +819,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
- sd->qindex = 0; /* set the quantization */
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -839,6 +842,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
cx11646_initsize(gspca_dev);
cx11646_fw(gspca_dev);
cx_sensor(gspca_dev);
@@ -849,8 +860,11 @@ static int sd_start(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;
int retry = 50;
+ kfree(sd->jpeg_hdr);
+
if (!gspca_dev->present)
return;
reg_w_val(gspca_dev, 0x0000, 0x00);
@@ -876,6 +890,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
if (data[0] == 0xff && data[1] == 0xd8) {
/* start of frame */
@@ -883,9 +899,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data, 0);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
data += 2;
len -= 2;
}
@@ -988,6 +1003,34 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -998,6 +1041,8 @@ static struct sd_desc sd_desc = {
.start = sd_start,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1029,8 +1074,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index f3cd8ff5cc9..2c20d06a03e 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -472,19 +472,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_w_val(gspca_dev, ET_O_RED + i, brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- int brightness = 0;
-
- for (i = 0; i < 4; i++) {
- reg_r(gspca_dev, ET_O_RED + i, 1);
- brightness += gspca_dev->usb_buf[0];
- }
- sd->brightness = brightness >> 3;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -495,19 +482,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, ET_G_RED, RGBG, 6);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- int contrast = 0;
-
- for (i = 0; i < 4; i++) {
- reg_r(gspca_dev, ET_G_RED + i, 1);
- contrast += gspca_dev->usb_buf[0];
- }
- sd->contrast = contrast >> 2;
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -658,7 +632,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 1;
sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAS106) {
cam->cam_mode = sif_mode;
@@ -821,7 +794,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -840,7 +812,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -859,7 +830,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -928,8 +898,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index afc8b2dd307..00e6863ed66 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -27,7 +27,7 @@ MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");
MODULE_LICENSE("GPL");
/* Default timeout, in ms */
-#define FPIX_TIMEOUT (HZ / 10)
+#define FPIX_TIMEOUT 250
/* Maximum transfer size to use. The windows driver reads by chunks of
* 0x2000 bytes, so do the same. Note: reading more seems to work
@@ -38,38 +38,15 @@ MODULE_LICENSE("GPL");
struct usb_fpix {
struct gspca_dev gspca_dev; /* !! must be the first item */
- /*
- * USB stuff
- */
- struct usb_ctrlrequest ctrlreq;
- struct urb *control_urb;
- struct timer_list bulk_timer;
-
- enum {
- FPIX_NOP, /* inactive, else streaming */
- FPIX_RESET, /* must reset */
- FPIX_REQ_FRAME, /* requesting a frame */
- FPIX_READ_FRAME, /* reading frame */
- } state;
-
- /*
- * Driver stuff
- */
- struct delayed_work wqe;
- struct completion can_close;
- int streaming;
+ struct work_struct work_struct;
+ struct workqueue_struct *work_thread;
};
/* Delay after which claim the next frame. If the delay is too small,
* the camera will return old frames. On the 4800Z, 20ms is bad, 25ms
- * will fail every 4 or 5 frames, but 30ms is perfect. */
-#define NEXT_FRAME_DELAY (((HZ * 30) + 999) / 1000)
-
-#define dev_new_state(new_state) { \
- PDEBUG(D_STREAM, "new state from %d to %d at %s:%d", \
- dev->state, new_state, __func__, __LINE__); \
- dev->state = new_state; \
-}
+ * will fail every 4 or 5 frames, but 30ms is perfect. On the A210,
+ * 30ms is bad while 35ms is perfect. */
+#define NEXT_FRAME_DELAY 35
/* These cameras only support 320x200. */
static const struct v4l2_pix_format fpix_mode[1] = {
@@ -80,316 +57,183 @@ static const struct v4l2_pix_format fpix_mode[1] = {
.priv = 0}
};
-/* Reads part of a frame */
-static void read_frame_part(struct usb_fpix *dev)
+/* send a command to the webcam */
+static int command(struct gspca_dev *gspca_dev,
+ int order) /* 0: reset, 1: frame request */
{
- int ret;
+ static u8 order_values[2][12] = {
+ {0xc6, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0}, /* reset */
+ {0xd3, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0}, /* fr req */
+ };
- PDEBUG(D_STREAM, "read_frame_part");
-
- /* Reads part of a frame */
- ret = usb_submit_urb(dev->gspca_dev.urb[0], GFP_ATOMIC);
- if (ret) {
- dev_new_state(FPIX_RESET);
- schedule_delayed_work(&dev->wqe, 1);
- PDEBUG(D_STREAM, "usb_submit_urb failed with %d",
- ret);
- } else {
- /* Sometimes we never get a callback, so use a timer.
- * Is this masking a bug somewhere else? */
- dev->bulk_timer.expires = jiffies + msecs_to_jiffies(150);
- add_timer(&dev->bulk_timer);
- }
+ memcpy(gspca_dev->usb_buf, order_values[order], 12);
+ return usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_GET_STATUS,
+ USB_DIR_OUT | USB_TYPE_CLASS |
+ USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
+ 12, FPIX_TIMEOUT);
}
-/* Callback for URBs. */
-static void urb_callback(struct urb *urb)
+/* workqueue */
+static void dostream(struct work_struct *work)
{
- struct gspca_dev *gspca_dev = urb->context;
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- PDEBUG(D_PACK,
- "enter urb_callback - status=%d, length=%d",
- urb->status, urb->actual_length);
-
- if (dev->state == FPIX_READ_FRAME)
- del_timer(&dev->bulk_timer);
-
- if (urb->status != 0) {
- /* We kill a stuck urb every 50 frames on average, so don't
- * display a log message for that. */
- if (urb->status != -ECONNRESET)
- PDEBUG(D_STREAM, "bad URB status %d", urb->status);
- dev_new_state(FPIX_RESET);
- schedule_delayed_work(&dev->wqe, 1);
- }
-
- switch (dev->state) {
- case FPIX_REQ_FRAME:
- dev_new_state(FPIX_READ_FRAME);
- read_frame_part(dev);
- break;
-
- case FPIX_READ_FRAME: {
- unsigned char *data = urb->transfer_buffer;
- struct gspca_frame *frame;
-
- frame = gspca_get_i_frame(&dev->gspca_dev);
- if (frame == NULL)
- gspca_dev->last_packet_type = DISCARD_PACKET;
- if (urb->actual_length < FPIX_MAX_TRANSFER ||
- (data[urb->actual_length-2] == 0xff &&
- data[urb->actual_length-1] == 0xd9)) {
-
- /* If the result is less than what was asked
- * for, then it's the end of the
- * frame. Sometime the jpeg is not complete,
- * but there's nothing we can do. We also end
- * here if the the jpeg ends right at the end
- * of the frame. */
- if (frame)
- gspca_frame_add(gspca_dev, LAST_PACKET,
- frame,
- data, urb->actual_length);
- dev_new_state(FPIX_REQ_FRAME);
- schedule_delayed_work(&dev->wqe, NEXT_FRAME_DELAY);
- } else {
+ struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct);
+ struct gspca_dev *gspca_dev = &dev->gspca_dev;
+ struct urb *urb = gspca_dev->urb[0];
+ u8 *data = urb->transfer_buffer;
+ struct gspca_frame *frame;
+ int ret = 0;
+ int len;
+
+ /* synchronize with the main driver */
+ mutex_lock(&gspca_dev->usb_lock);
+ mutex_unlock(&gspca_dev->usb_lock);
+ PDEBUG(D_STREAM, "dostream started");
+
+ /* loop reading a frame */
+again:
+ while (gspca_dev->present && gspca_dev->streaming) {
+
+ /* request a frame */
+ mutex_lock(&gspca_dev->usb_lock);
+ ret = command(gspca_dev, 1);
+ mutex_unlock(&gspca_dev->usb_lock);
+ if (ret < 0)
+ break;
+ if (!gspca_dev->present || !gspca_dev->streaming)
+ break;
+
+ /* the frame comes in parts */
+ for (;;) {
+ ret = usb_bulk_msg(gspca_dev->dev,
+ urb->pipe,
+ data,
+ FPIX_MAX_TRANSFER,
+ &len, FPIX_TIMEOUT);
+ if (ret < 0) {
+ /* Most of the time we get a timeout
+ * error. Just restart. */
+ goto again;
+ }
+ if (!gspca_dev->present || !gspca_dev->streaming)
+ goto out;
+ frame = gspca_get_i_frame(&dev->gspca_dev);
+ if (frame == NULL)
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+
+ if (len < FPIX_MAX_TRANSFER ||
+ (data[len - 2] == 0xff &&
+ data[len - 1] == 0xd9)) {
+
+ /* If the result is less than what was asked
+ * for, then it's the end of the
+ * frame. Sometimes the jpeg is not complete,
+ * but there's nothing we can do. We also end
+ * here if the the jpeg ends right at the end
+ * of the frame. */
+ if (frame)
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame,
+ data, len);
+ break;
+ }
/* got a partial image */
if (frame)
gspca_frame_add(gspca_dev,
gspca_dev->last_packet_type
- == LAST_PACKET
+ == LAST_PACKET
? FIRST_PACKET : INTER_PACKET,
- frame,
- data, urb->actual_length);
- read_frame_part(dev);
+ frame, data, len);
}
- break;
- }
-
- case FPIX_NOP:
- case FPIX_RESET:
- PDEBUG(D_STREAM, "invalid state %d", dev->state);
- break;
- }
-}
-/* Request a new frame */
-static void request_frame(struct usb_fpix *dev)
-{
- int ret;
- struct gspca_dev *gspca_dev = &dev->gspca_dev;
-
- /* Setup command packet */
- memset(gspca_dev->usb_buf, 0, 12);
- gspca_dev->usb_buf[0] = 0xd3;
- gspca_dev->usb_buf[7] = 0x01;
-
- /* Request a frame */
- dev->ctrlreq.bRequestType =
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- dev->ctrlreq.bRequest = USB_REQ_GET_STATUS;
- dev->ctrlreq.wValue = 0;
- dev->ctrlreq.wIndex = 0;
- dev->ctrlreq.wLength = cpu_to_le16(12);
-
- usb_fill_control_urb(dev->control_urb,
- gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- (unsigned char *) &dev->ctrlreq,
- gspca_dev->usb_buf,
- 12, urb_callback, gspca_dev);
-
- ret = usb_submit_urb(dev->control_urb, GFP_ATOMIC);
- if (ret) {
- dev_new_state(FPIX_RESET);
- schedule_delayed_work(&dev->wqe, 1);
- PDEBUG(D_STREAM, "usb_submit_urb failed with %d", ret);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* State machine. */
-static void fpix_sm(struct work_struct *work)
-{
- struct usb_fpix *dev = container_of(work, struct usb_fpix, wqe.work);
-
- PDEBUG(D_STREAM, "fpix_sm state %d", dev->state);
-
- /* verify that the device wasn't unplugged */
- if (!dev->gspca_dev.present) {
- PDEBUG(D_STREAM, "device is gone");
- dev_new_state(FPIX_NOP);
- complete(&dev->can_close);
- return;
- }
-
- if (!dev->streaming) {
- PDEBUG(D_STREAM, "stopping state machine");
- dev_new_state(FPIX_NOP);
- complete(&dev->can_close);
- return;
+ /* We must wait before trying reading the next
+ * frame. If we don't, or if the delay is too short,
+ * the camera will disconnect. */
+ msleep(NEXT_FRAME_DELAY);
}
- switch (dev->state) {
- case FPIX_RESET:
- dev_new_state(FPIX_REQ_FRAME);
- schedule_delayed_work(&dev->wqe, HZ / 10);
- break;
-
- case FPIX_REQ_FRAME:
- /* get an image */
- request_frame(dev);
- break;
-
- case FPIX_NOP:
- case FPIX_READ_FRAME:
- PDEBUG(D_STREAM, "invalid state %d", dev->state);
- break;
- }
+out:
+ PDEBUG(D_STREAM, "dostream stopped");
}
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
+ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
struct cam *cam = &gspca_dev->cam;
cam->cam_mode = fpix_mode;
cam->nmodes = 1;
- cam->epaddr = 0x01; /* todo: correct for all cams? */
cam->bulk_size = FPIX_MAX_TRANSFER;
-/* gspca_dev->nbalt = 1; * use bulk transfer */
- return 0;
-}
-
-/* Stop streaming and free the ressources allocated by sd_start. */
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- dev->streaming = 0;
-
- /* 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;
-}
-
-/* Kill an URB that hasn't completed. */
-static void timeout_kill(unsigned long data)
-{
- struct urb *urb = (struct urb *) data;
+ INIT_WORK(&dev->work_struct, dostream);
- usb_unlink_urb(urb);
+ return 0;
}
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- INIT_DELAYED_WORK(&dev->wqe, fpix_sm);
-
- init_timer(&dev->bulk_timer);
- dev->bulk_timer.function = timeout_kill;
-
return 0;
}
+/* start the camera */
static int sd_start(struct gspca_dev *gspca_dev)
{
struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
- int ret;
- int size_ret;
+ int ret, len;
/* Init the device */
- memset(gspca_dev->usb_buf, 0, 12);
- gspca_dev->usb_buf[0] = 0xc6;
- gspca_dev->usb_buf[8] = 0x20;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_STATUS,
- USB_DIR_OUT | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
- 12, FPIX_TIMEOUT);
-
- if (ret != 12) {
- PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
- ret = -EIO;
- goto error;
+ ret = command(gspca_dev, 0);
+ if (ret < 0) {
+ PDEBUG(D_STREAM, "init failed %d", ret);
+ return ret;
}
/* Read the result of the command. Ignore the result, for it
* varies with the device. */
ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev,
- gspca_dev->cam.epaddr),
- gspca_dev->usb_buf, FPIX_MAX_TRANSFER, &size_ret,
+ gspca_dev->urb[0]->pipe,
+ gspca_dev->urb[0]->transfer_buffer,
+ FPIX_MAX_TRANSFER, &len,
FPIX_TIMEOUT);
- if (ret != 0) {
- PDEBUG(D_STREAM, "usb_bulk_msg failed (%d)", ret);
- ret = -EIO;
- goto error;
+ if (ret < 0) {
+ PDEBUG(D_STREAM, "usb_bulk_msg failed %d", ret);
+ return ret;
}
/* Request a frame, but don't read it */
- memset(gspca_dev->usb_buf, 0, 12);
- gspca_dev->usb_buf[0] = 0xd3;
- gspca_dev->usb_buf[7] = 0x01;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_STATUS,
- USB_DIR_OUT | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
- 12, FPIX_TIMEOUT);
- if (ret != 12) {
- PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
- ret = -EIO;
- goto error;
+ ret = command(gspca_dev, 1);
+ if (ret < 0) {
+ PDEBUG(D_STREAM, "frame request failed %d", ret);
+ return ret;
}
/* Again, reset bulk in endpoint */
- usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
-
- /* Allocate a control URB */
- dev->control_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->control_urb) {
- PDEBUG(D_STREAM, "No free urbs available");
- ret = -EIO;
- goto error;
- }
-
- /* Various initializations. */
- init_completion(&dev->can_close);
- dev->bulk_timer.data = (unsigned long)dev->gspca_dev.urb[0];
- dev->gspca_dev.urb[0]->complete = urb_callback;
- dev->streaming = 1;
+ usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
- /* Schedule a frame request. */
- dev_new_state(FPIX_REQ_FRAME);
- schedule_delayed_work(&dev->wqe, 1);
+ /* Start the workqueue function to do the streaming */
+ dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+ queue_work(dev->work_thread, &dev->work_struct);
return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-error:
- /* Free the ressources */
- sd_stopN(gspca_dev);
- sd_stop0(gspca_dev);
- return ret;
+ /* wait for the work queue to terminate */
+ mutex_unlock(&gspca_dev->usb_lock);
+ destroy_workqueue(dev->work_thread);
+ mutex_lock(&gspca_dev->usb_lock);
+ dev->work_thread = NULL;
}
/* Table of supported USB devices */
@@ -424,12 +268,11 @@ MODULE_DEVICE_TABLE(usb, device_table);
/* sub-driver description */
static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
+ .name = MODULE_NAME,
.config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
+ .init = sd_init,
+ .start = sd_start,
+ .stop0 = sd_stop0,
};
/* -- device connect -- */
@@ -443,24 +286,28 @@ static int sd_probe(struct usb_interface *intf,
}
static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
.disconnect = gspca_disconnect,
#ifdef CONFIG_PM
.suspend = gspca_suspend,
- .resume = gspca_resume,
+ .resume = gspca_resume,
#endif
};
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
+
static void __exit sd_mod_exit(void)
{
usb_deregister(&sd_driver);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 65e4901f4db..a75c1ca2db4 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -38,15 +38,16 @@
#include "gspca.h"
/* global values */
-#define DEF_NURBS 2 /* default number of URBs */
+#define DEF_NURBS 3 /* default number of URBs */
+#if DEF_NURBS > MAX_NURBS
+#error "DEF_NURBS too big"
+#endif
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0)
-
-static int video_nr = -1;
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0)
#ifdef GSPCA_DEBUG
int gspca_debug = D_ERR | D_PROBE;
@@ -126,16 +127,18 @@ static void fill_frame(struct gspca_dev *gspca_dev,
struct urb *urb)
{
struct gspca_frame *frame;
- __u8 *data; /* address of data in the iso message */
+ u8 *data; /* address of data in the iso message */
int i, len, st;
cam_pkt_op pkt_scan;
if (urb->status != 0) {
+ if (urb->status == -ESHUTDOWN)
+ return; /* disconnection */
#ifdef CONFIG_PM
if (!gspca_dev->frozen)
#endif
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- return; /* disconnection ? */
+ return;
}
pkt_scan = gspca_dev->sd_desc->pkt_scan;
for (i = 0; i < urb->number_of_packets; i++) {
@@ -166,7 +169,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
/* let the packet be analyzed by the subdriver */
PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
i, urb->iso_frame_desc[i].offset, len);
- data = (__u8 *) urb->transfer_buffer
+ data = (u8 *) urb->transfer_buffer
+ urb->iso_frame_desc[i].offset;
pkt_scan(gspca_dev, frame, data, len);
}
@@ -182,8 +185,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
*
* Analyse each packet and call the subdriver for copy to the frame buffer.
*/
-static void isoc_irq(struct urb *urb
-)
+static void isoc_irq(struct urb *urb)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
@@ -196,8 +198,7 @@ static void isoc_irq(struct urb *urb
/*
* bulk message interrupt from the USB device
*/
-static void bulk_irq(struct urb *urb
-)
+static void bulk_irq(struct urb *urb)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
struct gspca_frame *frame;
@@ -209,6 +210,8 @@ static void bulk_irq(struct urb *urb
switch (urb->status) {
case 0:
break;
+ case -ESHUTDOWN:
+ return; /* disconnection */
case -ECONNRESET:
urb->status = 0;
break;
@@ -217,7 +220,7 @@ static void bulk_irq(struct urb *urb
if (!gspca_dev->frozen)
#endif
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- return; /* disconnection ? */
+ return;
}
/* check the availability of the frame buffer */
@@ -322,6 +325,7 @@ static int gspca_is_compressed(__u32 format)
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_SPCA561:
case V4L2_PIX_FMT_PAC207:
+ case V4L2_PIX_FMT_MR97310A:
return 1;
}
return 0;
@@ -422,10 +426,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
if (urb == NULL)
break;
- BUG_ON(!gspca_dev->dev);
gspca_dev->urb[i] = NULL;
- if (!gspca_dev->present)
- usb_kill_urb(urb);
+ usb_kill_urb(urb);
if (urb->transfer_buffer != NULL)
usb_buffer_free(gspca_dev->dev,
urb->transfer_buffer_length,
@@ -439,22 +441,16 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
* look for an input transfer endpoint in an alternate setting
*/
static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
- __u8 epaddr,
__u8 xfer)
{
struct usb_host_endpoint *ep;
int i, attr;
- epaddr |= USB_DIR_IN;
for (i = 0; i < alt->desc.bNumEndpoints; i++) {
ep = &alt->endpoint[i];
- if (ep->desc.bEndpointAddress == epaddr) {
- attr = ep->desc.bmAttributes
- & USB_ENDPOINT_XFERTYPE_MASK;
- if (attr == xfer)
- return ep;
- break;
- }
+ attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ if (attr == xfer)
+ return ep;
}
return NULL;
}
@@ -478,23 +474,23 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
i = gspca_dev->alt; /* previous alt setting */
/* try isoc */
- while (--i > 0) { /* alt 0 is unusable */
+ while (--i >= 0) {
ep = alt_xfer(&intf->altsetting[i],
- gspca_dev->cam.epaddr,
USB_ENDPOINT_XFER_ISOC);
if (ep)
break;
}
- /* if no isoc, try bulk */
+ /* if no isoc, try bulk (alt 0 only) */
if (ep == NULL) {
ep = alt_xfer(&intf->altsetting[0],
- gspca_dev->cam.epaddr,
USB_ENDPOINT_XFER_BULK);
if (ep == NULL) {
err("no transfer endpoint found");
return NULL;
}
+ i = 0;
+ gspca_dev->bulk = 1;
}
PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
i, ep->desc.bEndpointAddress);
@@ -521,7 +517,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
/* calculate the packet size and the number of packets */
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- if (gspca_dev->alt != 0) { /* isoc */
+ if (!gspca_dev->bulk) { /* isoc */
/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
@@ -601,6 +597,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
+
/* set the higher alternate setting and
* loop until urb submit succeeds */
gspca_dev->alt = gspca_dev->nbalt;
@@ -616,10 +617,9 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
goto out;
/* clear the bulk endpoint */
- if (gspca_dev->alt == 0) /* if bulk transfer */
+ if (gspca_dev->bulk)
usb_clear_halt(gspca_dev->dev,
- usb_rcvintpipe(gspca_dev->dev,
- gspca_dev->cam.epaddr));
+ gspca_dev->urb[0]->pipe);
/* start the cam */
ret = gspca_dev->sd_desc->start(gspca_dev);
@@ -630,7 +630,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
gspca_dev->streaming = 1;
/* some bulk transfers are started by the subdriver */
- if (gspca_dev->alt == 0 && gspca_dev->cam.bulk_nurbs == 0)
+ if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0)
break;
/* submit the URBs */
@@ -671,11 +671,14 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
static void gspca_stream_off(struct gspca_dev *gspca_dev)
{
gspca_dev->streaming = 0;
- 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->present) {
+ if (gspca_dev->sd_desc->stopN)
+ gspca_dev->sd_desc->stopN(gspca_dev);
+ destroy_urbs(gspca_dev);
+ gspca_set_alt0(gspca_dev);
+ }
+
+ /* always call stop0 to free the subdriver's resources */
if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
PDEBUG(D_STREAM, "stream off OK");
@@ -762,7 +765,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
fmtdesc->pixelformat = fmt_tb[index];
if (gspca_is_compressed(fmt_tb[index]))
fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
- fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;
fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;
fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;
@@ -957,8 +959,15 @@ static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
struct gspca_dev *gspca_dev = priv;
+ int ret;
- memset(cap, 0, sizeof *cap);
+ /* protect the access to the usb device */
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+ return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
if (gspca_dev->dev->product != NULL) {
strncpy(cap->card, gspca_dev->dev->product,
@@ -969,13 +978,15 @@ static int vidioc_querycap(struct file *file, void *priv,
le16_to_cpu(gspca_dev->dev->descriptor.idVendor),
le16_to_cpu(gspca_dev->dev->descriptor.idProduct));
}
- strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
- sizeof cap->bus_info);
+ usb_make_path(gspca_dev->dev, cap->bus_info, sizeof(cap->bus_info));
cap->version = DRIVER_VERSION_NUMBER;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
| V4L2_CAP_READWRITE;
- return 0;
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->usb_lock);
+ return ret;
}
static int vidioc_queryctrl(struct file *file, void *priv,
@@ -1038,7 +1049,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = ctrls->set(gspca_dev, ctrl->value);
+ if (gspca_dev->present)
+ ret = ctrls->set(gspca_dev, ctrl->value);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1062,7 +1076,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = ctrls->get(gspca_dev, &ctrl->value);
+ if (gspca_dev->present)
+ ret = ctrls->get(gspca_dev, &ctrl->value);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1081,7 +1098,6 @@ static int vidioc_s_audio(struct file *file, void *priv,
static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *audio)
{
- memset(audio, 0, sizeof *audio);
strcpy(audio->name, "Microphone");
return 0;
}
@@ -1115,7 +1131,6 @@ static int vidioc_enum_input(struct file *file, void *priv,
if (input->index != 0)
return -EINVAL;
- memset(input, 0, sizeof *input);
input->type = V4L2_INPUT_TYPE_CAMERA;
strncpy(input->name, gspca_dev->sd_desc->name,
sizeof input->name);
@@ -1224,10 +1239,7 @@ static int vidioc_streamon(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
- if (!gspca_dev->present) {
- ret = -ENODEV;
- goto out;
- }
+
if (gspca_dev->nframes == 0
|| !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {
ret = -EINVAL;
@@ -1295,7 +1307,10 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1310,7 +1325,10 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1320,8 +1338,6 @@ static int vidioc_g_parm(struct file *filp, void *priv,
{
struct gspca_dev *gspca_dev = priv;
- memset(parm, 0, sizeof *parm);
- parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
parm->parm.capture.readbuffers = gspca_dev->nbufread;
if (gspca_dev->sd_desc->get_streamparm) {
@@ -1329,7 +1345,11 @@ static int vidioc_g_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->get_streamparm(gspca_dev,
+ parm);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1354,7 +1374,11 @@ static int vidioc_s_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->set_streamparm(gspca_dev,
+ parm);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1382,7 +1406,6 @@ static int vidiocgmbuf(struct file *file, void *priv,
{
struct v4l2_format fmt;
- memset(&fmt, 0, sizeof fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
i = gspca_dev->cam.nmodes - 1; /* highest mode */
fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width;
@@ -1528,7 +1551,8 @@ static int frame_wait(struct gspca_dev *gspca_dev,
if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->sd_desc->dq_callback(gspca_dev);
+ if (gspca_dev->present)
+ gspca_dev->sd_desc->dq_callback(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
return j;
@@ -1550,6 +1574,9 @@ static int vidioc_dqbuf(struct file *file, void *priv,
if (v4l2_buf->memory != gspca_dev->memory)
return -EINVAL;
+ if (!gspca_dev->present)
+ return -ENODEV;
+
/* if not streaming, be sure the application will not loop forever */
if (!(file->f_flags & O_NONBLOCK)
&& !gspca_dev->streaming && gspca_dev->users == 1)
@@ -1700,8 +1727,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
PDEBUG(D_FRAM, "poll");
poll_wait(file, &gspca_dev->wq, wait);
- if (!gspca_dev->present)
- return POLLERR;
/* if reqbufs is not done, the user would use read() */
if (gspca_dev->nframes == 0) {
@@ -1714,10 +1739,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0)
return POLLERR;
- if (!gspca_dev->present) {
- ret = POLLERR;
- goto out;
- }
/* check the next incoming buffer */
i = gspca_dev->fr_o;
@@ -1726,8 +1747,9 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
ret = POLLIN | POLLRDNORM; /* something to read */
else
ret = 0;
-out:
mutex_unlock(&gspca_dev->queue_lock);
+ if (!gspca_dev->present)
+ return POLLHUP;
return ret;
}
@@ -1925,7 +1947,7 @@ int gspca_dev_probe(struct usb_interface *intf,
gspca_dev->present = 1;
ret = video_register_device(&gspca_dev->vdev,
VFL_TYPE_GRABBER,
- video_nr);
+ -1);
if (ret < 0) {
err("video_register_device err %d", ret);
goto out;
@@ -1953,10 +1975,16 @@ void gspca_disconnect(struct usb_interface *intf)
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->present = 0;
- mutex_unlock(&gspca_dev->usb_lock);
- destroy_urbs(gspca_dev);
+ if (gspca_dev->streaming) {
+ destroy_urbs(gspca_dev);
+ wake_up_interruptible(&gspca_dev->wq);
+ }
+
+ /* the device is freed at exit of this function */
gspca_dev->dev = NULL;
+ mutex_unlock(&gspca_dev->usb_lock);
+
usb_set_intfdata(intf, NULL);
/* release the device */
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index c90af9cb1e0..e4d4cf6ce05 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -33,19 +33,13 @@ extern int gspca_debug;
#endif
#undef err
#define err(fmt, args...) \
- do {\
- printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args)
#undef info
#define info(fmt, args...) \
- do {\
- printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args)
#undef warn
#define warn(fmt, args...) \
- do {\
- printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args)
#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
/* image transfers */
@@ -62,7 +56,6 @@ struct cam {
* - cannot be > MAX_NURBS
* - when 0 and bulk_size != 0 means
* 1 URB and submit done by subdriver */
- __u8 epaddr;
};
struct gspca_dev;
@@ -174,6 +167,7 @@ struct gspca_dev {
__u8 iface; /* USB interface number */
__u8 alt; /* USB alternate setting */
__u8 nbalt; /* number of USB alternate settings */
+ u8 bulk; /* image transfer by 0:isoc / 1:bulk */
};
int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h
index d823b47bd4e..de63c36806c 100644
--- a/drivers/media/video/gspca/jpeg.h
+++ b/drivers/media/video/gspca/jpeg.h
@@ -24,171 +24,39 @@
*
*/
-/* start of jpeg frame + quantization table */
-static const unsigned char quant[][0x88] = {
-/* index 0 - Q40*/
- {
+/*
+ * generation options
+ * CONEX_CAM Conexant if present
+ */
+
+/* JPEG header */
+static const u8 jpeg_head[] = {
0xff, 0xd8, /* jpeg */
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0, /* quantization table part 1 */
- 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50,
- 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64,
- 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101,
- 109,
- 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115,
- 126, 129, 124,
-1, /* quantization table part 2 */
- 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124},
-/* index 1 - Q50 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40,
- 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51,
- 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87,
- 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101,
- 103, 99,
-1,
- 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99},
-/* index 2 Q60 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32,
- 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41,
- 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70,
- 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79,
-1,
- 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79},
-/* index 3 - Q70 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24,
- 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31,
- 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52,
- 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59,
-1,
- 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59},
-/* index 4 - Q80 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16,
- 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20,
- 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35,
- 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40,
-1,
- 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40},
-/* index 5 - Q85 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12,
- 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15,
- 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26,
- 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30,
-1,
- 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
-/* index 6 - 86 */
-{
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04,
- 0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B,
- 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A,
- 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E,
- 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13,
- 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18,
- 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20,
- 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C,
-1,
- 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07,
- 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- },
-/* index 7 - 88 */
-{
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03,
- 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A,
- 0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09,
- 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C,
- 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10,
- 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15,
- 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B,
- 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18,
-1,
- 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06,
- 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-},
-/* index 8 - ?? */
-{
- 0xff, 0xd8,
+
+/* quantization table quality 50% */
0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05,
- 0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06,
- 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09,
- 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B,
- 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E,
- 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C,
+#define JPEG_QT0_OFFSET 7
+ 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
+ 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
+ 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
+ 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
+ 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
+ 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
+ 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
+ 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
1,
- 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03,
- 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C
-}
-};
+#define JPEG_QT1_OFFSET 72
+ 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
+ 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-/* huffman table + start of SOF0 */
-static unsigned char huffman[] = {
+/* huffman table */
0xff, 0xc4, 0x01, 0xa2,
0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -244,58 +112,57 @@ static unsigned char huffman[] = {
0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
#ifdef CONEX_CAM
/* the Conexant frames start with SOF0 */
+#define JPEG_HDR_SZ 556
#else
0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */
0x08, /* data precision */
-#endif
-};
-
-#ifndef CONEX_CAM
-/* variable part:
- * 0x01, 0xe0, height
- * 0x02, 0x80, width
- * 0x03, component number
- * 0x01,
- * 0x21, samples Y
- */
-
-/* end of header */
-static unsigned char eoh[] = {
+#define JPEG_HEIGHT_OFFSET 561
+ 0x01, 0xe0, /* height */
+ 0x02, 0x80, /* width */
+ 0x03, /* component number */
+ 0x01,
+ 0x21, /* samples Y */
0x00, /* quant Y */
0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */
0x03, 0x11, 0x01,
0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */
0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
-};
+#define JPEG_HDR_SZ 589
#endif
+};
-/* -- output the JPEG header -- */
-static void jpeg_put_header(struct gspca_dev *gspca_dev,
- struct gspca_frame *frame,
- int qindex,
- int samplesY)
+/* define the JPEG header */
+static void jpeg_define(u8 *jpeg_hdr,
+ int height,
+ int width,
+ int samplesY)
{
+ memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
#ifndef CONEX_CAM
- unsigned char tmpbuf[8];
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height & 0xff;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width & 0xff;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
#endif
+}
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
- (unsigned char *) quant[qindex], sizeof quant[0]);
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- (unsigned char *) huffman, sizeof huffman);
-#ifndef CONEX_CAM
- tmpbuf[0] = gspca_dev->height >> 8;
- tmpbuf[1] = gspca_dev->height & 0xff;
- tmpbuf[2] = gspca_dev->width >> 8;
- tmpbuf[3] = gspca_dev->width & 0xff;
- tmpbuf[4] = 0x03; /* component number */
- tmpbuf[5] = 0x01; /* first component */
- tmpbuf[6] = samplesY;
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- tmpbuf, 7);
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- eoh, sizeof eoh);
-#endif
+/* set the JPEG quality */
+static void jpeg_set_qual(u8 *jpeg_hdr,
+ int quality)
+{
+ int i, sc;
+
+ if (quality < 50)
+ sc = 5000 / quality;
+ else
+ sc = 200 - quality * 2;
+ for (i = 0; i < 64; i++) {
+ jpeg_hdr[JPEG_QT0_OFFSET + i] =
+ (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
+ jpeg_hdr[JPEG_QT1_OFFSET + i] =
+ (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
+ }
}
#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index ed906fe3128..b35e4838a6e 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -332,7 +332,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
int err;
cam = &gspca_dev->cam;
- cam->epaddr = M5602_ISOC_ENDPOINT_ADDR;
sd->desc = &sd_desc;
if (dump_bridge)
@@ -374,8 +373,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init mod_m5602_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 3d2090e67a6..75e8d14e4ac 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -32,17 +32,91 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- char qindex;
+ u8 brightness;
+ u8 colors;
+ u8 gamma;
+ u8 sharpness;
+ u8 quality;
+#define QUALITY_MIN 40
+#define QUALITY_MAX 70
+#define QUALITY_DEF 50
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+
static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 30,
+ .step = 1,
+#define BRIGHTNESS_DEF 15
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 1,
+ .maximum = 255,
+ .step = 1,
+#define COLOR_DEF 200
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+ {
+ {
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+#define GAMMA_DEF 1
+ .default_value = GAMMA_DEF,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
+ {
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sharpness",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+#define SHARPNESS_DEF 1
+ .default_value = SHARPNESS_DEF,
+ },
+ .set = sd_setsharpness,
+ .get = sd_getsharpness,
+ },
};
static const struct v4l2_pix_format vga_mode[] = {
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 589,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv = 2},
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -52,65 +126,45 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 1},
};
-/* MI Register table //elvis */
-enum {
- REG_HW_MI_0,
- REG_HW_MI_1,
- REG_HW_MI_2,
- REG_HW_MI_3,
- REG_HW_MI_4,
- REG_HW_MI_5,
- REG_HW_MI_6,
- REG_HW_MI_7,
- REG_HW_MI_9 = 0x09,
- REG_HW_MI_B = 0x0B,
- REG_HW_MI_C,
- REG_HW_MI_D,
- REG_HW_MI_1E = 0x1E,
- REG_HW_MI_20 = 0x20,
- REG_HW_MI_2B = 0x2B,
- REG_HW_MI_2C,
- REG_HW_MI_2D,
- REG_HW_MI_2E,
- REG_HW_MI_35 = 0x35,
- REG_HW_MI_5F = 0x5f,
- REG_HW_MI_60,
- REG_HW_MI_61,
- REG_HW_MI_62,
- REG_HW_MI_63,
- REG_HW_MI_64,
- REG_HW_MI_F1 = 0xf1,
- ATTR_TOTAL_MI_REG = 0xf2
+static const __u8 mi_data[0x20] = {
+/* 01 02 03 04 05 06 07 08 */
+ 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00,
+/* 09 0a 0b 0c 0d 0e 0f 10 */
+ 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01,
+/* 11 12 13 14 15 16 17 18 */
+ 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02,
+/* 19 1a 1b 1c 1d 1e 1f 20 */
+ 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00
};
-/* the bytes to write are in gspca_dev->usb_buf */
+/* write <len> bytes from gspca_dev->usb_buf */
static int reg_w(struct gspca_dev *gspca_dev,
- __u16 index, int len)
+ int len)
{
- int rc;
-
- rc = usb_control_msg(gspca_dev->dev,
- usb_sndbulkpipe(gspca_dev->dev, 4),
- 0x12,
- 0xc8, /* ?? */
- 0, /* value */
- index, gspca_dev->usb_buf, len, 500);
- if (rc < 0)
- PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
- return rc;
+ int alen, ret;
+
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ gspca_dev->usb_buf,
+ len,
+ &alen,
+ 500); /* timeout in milliseconds */
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d",
+ gspca_dev->usb_buf[0], ret);
+ return ret;
}
-static void bulk_w(struct gspca_dev *gspca_dev,
- __u16 *pch,
- __u16 Address)
+static void mi_w(struct gspca_dev *gspca_dev,
+ u8 addr,
+ u8 value)
{
gspca_dev->usb_buf[0] = 0x1f;
gspca_dev->usb_buf[1] = 0; /* control byte */
- gspca_dev->usb_buf[2] = Address;
- gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */
- gspca_dev->usb_buf[4] = *pch; /* low byte */
+ gspca_dev->usb_buf[2] = addr;
+ gspca_dev->usb_buf[3] = value;
- reg_w(gspca_dev, Address, 5);
+ reg_w(gspca_dev, 4);
}
/* this function is called at probe time */
@@ -121,10 +175,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
- sd->qindex = 1; /* set the quantization table */
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->colors = COLOR_DEF;
+ sd->gamma = GAMMA_DEF;
+ sd->sharpness = SHARPNESS_DEF;
+ sd->quality = QUALITY_DEF;
+ gspca_dev->nbalt = 9; /* use the altsetting 08 */
return 0;
}
@@ -136,24 +194,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int err_code;
- __u8 *data;
- __u16 *MI_buf;
- int h_size, v_size;
- int intpipe;
-
- PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
- err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8);
- if (err_code < 0) {
- PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
- return err_code;
- }
+ u8 *data;
+ int i;
+
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
data = gspca_dev->usb_buf;
+
data[0] = 0x01; /* address */
data[1] = 0x01;
-
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
@@ -163,30 +219,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
data[0] = 0x00; /* address */
data[1] = 0x0c | 0x01; /* reg 0 */
data[2] = 0x01; /* reg 1 */
- h_size = gspca_dev->width;
- v_size = gspca_dev->height;
- data[3] = h_size / 8; /* h_size , reg 2 */
- data[4] = v_size / 8; /* v_size , reg 3 */
+ data[3] = gspca_dev->width / 8; /* h_size , reg 2 */
+ data[4] = gspca_dev->height / 8; /* v_size , reg 3 */
data[5] = 0x30; /* reg 4, MI, PAS5101 :
* 0x30 for 24mhz , 0x28 for 12mhz */
- data[6] = 4; /* reg 5, H start */
- data[7] = 0xc0; /* reg 6, gamma 1.5 */
- data[8] = 3; /* reg 7, V start */
+ data[6] = 0x02; /* reg 5, H start - was 0x04 */
+ data[7] = sd->gamma * 0x40; /* reg 0x06: gamma */
+ data[8] = 0x01; /* reg 7, V start - was 0x03 */
/* if (h_size == 320 ) */
/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
/* else */
data[9] = 0x52; /* reg 8, 24MHz, no scale down */
- data[10] = 0x5d; /* reg 9, I2C device address
- * [for PAS5101 (0x40)] [for MI (0x5d)] */
+/*jfm: from win trace*/
+ data[10] = 0x18;
- err_code = reg_w(gspca_dev, data[0], 11);
+ err_code = reg_w(gspca_dev, 11);
if (err_code < 0)
return err_code;
data[0] = 0x23; /* address */
data[1] = 0x09; /* reg 35, append frame header */
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
@@ -197,137 +251,57 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* else */
data[1] = 50; /* 50 reg 60, pc-cam frame size
* (unit: 4KB) 200KB */
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
- if (0) { /* fixed dark-gain */
- data[1] = 0; /* reg 94, Y Gain (1.75) */
- data[2] = 0; /* reg 95, UV Gain (1.75) */
- data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable
- * auto dark-gain */
- data[4] = 0; /* reg 97, set fixed dark level */
- data[5] = 0; /* reg 98, don't care */
- } else { /* auto dark-gain */
- data[1] = 0; /* reg 94, Y Gain (auto) */
- data[2] = 0; /* reg 95, UV Gain (1.75) */
- data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable
- * auto dark-gain */
- switch (gspca_dev->width) {
-/* case 1280: */
-/* data[4] = 154;
- * reg 97, %3 shadow point (unit: 256 pixel) */
-/* data[5] = 51;
- * reg 98, %1 highlight point
- * (uint: 256 pixel) */
-/* break; */
- default:
-/* case 640: */
- data[4] = 36; /* reg 97, %3 shadow point
- * (unit: 256 pixel) */
- data[5] = 12; /* reg 98, %1 highlight point
- * (uint: 256 pixel) */
- break;
- case 320:
- data[4] = 9; /* reg 97, %3 shadow point
- * (unit: 256 pixel) */
- data[5] = 3; /* reg 98, %1 highlight point
- * (uint: 256 pixel) */
- break;
- }
- }
/* auto dark-gain */
data[0] = 0x5e; /* address */
-
- err_code = reg_w(gspca_dev, data[0], 6);
+ data[1] = 0; /* reg 94, Y Gain (auto) */
+/*jfm: from win trace*/
+ /* reg 0x5f/0x60 (LE) = saturation */
+ /* h (60): xxxx x100
+ * l (5f): xxxx x000 */
+ data[2] = sd->colors << 3;
+ data[3] = ((sd->colors >> 2) & 0xf8) | 0x04;
+ data[4] = sd->brightness; /* reg 0x61 = brightness */
+ data[5] = 0x00;
+
+ err_code = reg_w(gspca_dev, 6);
if (err_code < 0)
return err_code;
data[0] = 0x67;
- data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */
- err_code = reg_w(gspca_dev, data[0], 2);
+/*jfm: from win trace*/
+ data[1] = sd->sharpness * 4 + 3;
+ data[2] = 0x14;
+ err_code = reg_w(gspca_dev, 3);
if (err_code < 0)
return err_code;
- /*
- * initialize the value of MI sensor...
- */
- MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL);
- MI_buf[REG_HW_MI_1] = 0x000a;
- MI_buf[REG_HW_MI_2] = 0x000c;
- MI_buf[REG_HW_MI_3] = 0x0405;
- MI_buf[REG_HW_MI_4] = 0x0507;
- /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */
- MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */
- MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */
- /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */
- MI_buf[REG_HW_MI_7] = 0x0002;
- /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */
- /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */
- MI_buf[REG_HW_MI_9] = 0x0374;
- MI_buf[REG_HW_MI_B] = 0x0000;
- MI_buf[REG_HW_MI_C] = 0x0000;
- MI_buf[REG_HW_MI_D] = 0x0000;
- MI_buf[REG_HW_MI_1E] = 0x8000;
-/* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */
- MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */
- MI_buf[REG_HW_MI_2B] = 0x0008;
-/* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */
- MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */
- MI_buf[REG_HW_MI_2D] = 0x0008;
- MI_buf[REG_HW_MI_2E] = 0x0008;
- MI_buf[REG_HW_MI_35] = 0x0051;
- MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */
- MI_buf[REG_HW_MI_60] = 0x0000;
- MI_buf[REG_HW_MI_61] = 0x0000;
- MI_buf[REG_HW_MI_62] = 0x0498;
- MI_buf[REG_HW_MI_63] = 0x0000;
- MI_buf[REG_HW_MI_64] = 0x0000;
- MI_buf[REG_HW_MI_F1] = 0x0001;
- /* changing while setting up the different value of dx/dy */
-
- if (gspca_dev->width != 1280) {
- MI_buf[0x01] = 0x010a;
- MI_buf[0x02] = 0x014c;
- MI_buf[0x03] = 0x01e5;
- MI_buf[0x04] = 0x0287;
- }
- MI_buf[0x20] = 0x1104;
-
- bulk_w(gspca_dev, MI_buf + 1, 1);
- bulk_w(gspca_dev, MI_buf + 2, 2);
- bulk_w(gspca_dev, MI_buf + 3, 3);
- bulk_w(gspca_dev, MI_buf + 4, 4);
- bulk_w(gspca_dev, MI_buf + 5, 5);
- bulk_w(gspca_dev, MI_buf + 6, 6);
- bulk_w(gspca_dev, MI_buf + 7, 7);
- bulk_w(gspca_dev, MI_buf + 9, 9);
- bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b);
- bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c);
- bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d);
- bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e);
- bulk_w(gspca_dev, MI_buf + 0x20, 0x20);
- bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b);
- bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c);
- bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d);
- bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e);
- bulk_w(gspca_dev, MI_buf + 0x35, 0x35);
- bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f);
- bulk_w(gspca_dev, MI_buf + 0x60, 0x60);
- bulk_w(gspca_dev, MI_buf + 0x61, 0x61);
- bulk_w(gspca_dev, MI_buf + 0x62, 0x62);
- bulk_w(gspca_dev, MI_buf + 0x63, 0x63);
- bulk_w(gspca_dev, MI_buf + 0x64, 0x64);
- bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1);
- kfree(MI_buf);
-
- intpipe = usb_sndintpipe(gspca_dev->dev, 0);
- err_code = usb_clear_halt(gspca_dev->dev, intpipe);
+ data[0] = 0x69;
+ data[1] = 0x2f;
+ data[2] = 0x28;
+ data[3] = 0x42;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x63;
+ data[1] = 0x07;
+ err_code = reg_w(gspca_dev, 2);
+/*jfm: win trace - many writes here to reg 0x64*/
+ if (err_code < 0)
+ return err_code;
+
+ /* initialize the MI sensor */
+ for (i = 0; i < sizeof mi_data; i++)
+ mi_w(gspca_dev, i + 1, mi_data[i]);
data[0] = 0x00;
data[1] = 0x4d; /* ISOC transfering enable... */
- reg_w(gspca_dev, data[0], 2);
- return err_code;
+ reg_w(gspca_dev, 2);
+ return 0;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -336,11 +310,18 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0] = 1;
gspca_dev->usb_buf[1] = 0;
- result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2);
+ result = reg_w(gspca_dev, 2);
if (result < 0)
PDEBUG(D_ERR, "Camera Stop failed");
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -363,16 +344,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|| data[5 + p] == 0x65
|| data[5 + p] == 0x66
|| data[5 + p] == 0x67) {
- PDEBUG(D_PACK, "sof offset: %d leng: %d",
+ PDEBUG(D_PACK, "sof offset: %d len: %d",
p, len);
frame = gspca_frame_add(gspca_dev, LAST_PACKET,
- frame, data, 0);
+ frame, data, p);
/* put the JPEG header */
- jpeg_put_header(gspca_dev, frame,
- sd->qindex, 0x21);
- data += 16;
- len -= 16;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
+ data += p + 16;
+ len -= p + 16;
break;
}
}
@@ -380,6 +361,121 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x61;
+ gspca_dev->usb_buf[1] = val;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming) {
+
+ /* see sd_start */
+ gspca_dev->usb_buf[0] = 0x5f;
+ gspca_dev->usb_buf[1] = sd->colors << 3;
+ gspca_dev->usb_buf[2] = ((sd->colors >> 2) & 0xf8) | 0x04;
+ reg_w(gspca_dev, 3);
+ }
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x06;
+ gspca_dev->usb_buf[1] = val * 0x40;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gamma;
+ return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->sharpness = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x67;
+ gspca_dev->usb_buf[1] = val * 4 + 3;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->sharpness;
+ return 0;
+}
+
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -389,7 +485,10 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -421,8 +520,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
new file mode 100644
index 00000000000..2a901a4a6f0
--- /dev/null
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -0,0 +1,362 @@
+/*
+ * Mars MR97310A library
+ *
+ * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "mr97310a"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>");
+MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+ u8 sof_read;
+};
+
+/* V4L2 controls supported by the driver */
+static struct ctrl sd_ctrls[] = {
+};
+
+static const struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 4},
+ {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 3},
+ {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+/* the bytes to write are in gspca_dev->usb_buf */
+static int reg_w(struct gspca_dev *gspca_dev, int len)
+{
+ int rc;
+
+ rc = usb_bulk_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ gspca_dev->usb_buf, len, NULL, 500);
+ if (rc < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d",
+ gspca_dev->usb_buf[0], rc);
+ return rc;
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam;
+
+ cam = &gspca_dev->cam;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = ARRAY_SIZE(vga_mode);
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ return 0;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 *data = gspca_dev->usb_buf;
+ int err_code;
+
+ sd->sof_read = 0;
+
+ /* Note: register descriptions guessed from MR97113A driver */
+
+ data[0] = 0x01;
+ data[1] = 0x01;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x00;
+ data[1] = 0x0d;
+ data[2] = 0x01;
+ data[5] = 0x2b;
+ data[7] = 0x00;
+ data[9] = 0x50; /* reg 8, no scale down */
+ data[10] = 0xc0;
+
+ switch (gspca_dev->width) {
+ case 160:
+ data[9] |= 0x0c; /* reg 8, 4:1 scale down */
+ /* fall thru */
+ case 320:
+ data[9] |= 0x04; /* reg 8, 2:1 scale down */
+ /* fall thru */
+ case 640:
+ default:
+ data[3] = 0x50; /* reg 2, H size */
+ data[4] = 0x78; /* reg 3, V size */
+ data[6] = 0x04; /* reg 5, H start */
+ data[8] = 0x03; /* reg 7, V start */
+ break;
+
+ case 176:
+ data[9] |= 0x04; /* reg 8, 2:1 scale down */
+ /* fall thru */
+ case 352:
+ data[3] = 0x2c; /* reg 2, H size */
+ data[4] = 0x48; /* reg 3, V size */
+ data[6] = 0x94; /* reg 5, H start */
+ data[8] = 0x63; /* reg 7, V start */
+ break;
+ }
+
+ err_code = reg_w(gspca_dev, 11);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x0a;
+ data[1] = 0x80;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x14;
+ data[1] = 0x0a;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1b;
+ data[1] = 0x00;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x15;
+ data[1] = 0x16;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x16;
+ data[1] = 0x10;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x17;
+ data[1] = 0x3a;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x18;
+ data[1] = 0x68;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x02;
+ data[3] = 0x06;
+ data[4] = 0x59;
+ data[5] = 0x0c;
+ data[6] = 0x16;
+ data[7] = 0x00;
+ data[8] = 0x07;
+ data[9] = 0x00;
+ data[10] = 0x01;
+ err_code = reg_w(gspca_dev, 11);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x0a;
+ data[3] = 0x00;
+ data[4] = 0x01;
+ data[5] = 0x00;
+ data[6] = 0x00;
+ data[7] = 0x01;
+ data[8] = 0x00;
+ data[9] = 0x0a;
+ err_code = reg_w(gspca_dev, 10);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x12;
+ data[3] = 0x00;
+ data[4] = 0x63;
+ data[5] = 0x00;
+ data[6] = 0x70;
+ data[7] = 0x00;
+ data[8] = 0x00;
+ err_code = reg_w(gspca_dev, 9);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x00;
+ data[1] = 0x4d; /* ISOC transfering enable... */
+ err_code = reg_w(gspca_dev, 2);
+ return err_code;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ int result;
+
+ gspca_dev->usb_buf[0] = 1;
+ gspca_dev->usb_buf[1] = 0;
+ result = reg_w(gspca_dev, 2);
+ if (result < 0)
+ PDEBUG(D_ERR, "Camera Stop failed");
+}
+
+/* Include pac common sof detection functions */
+#include "pac_common.h"
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ unsigned char *sof;
+
+ sof = pac_find_sof(gspca_dev, data, len);
+ if (sof) {
+ int n;
+
+ /* finish decoding current frame */
+ n = sof - data;
+ if (n > sizeof pac_sof_marker)
+ n -= sizeof pac_sof_marker;
+ else
+ n = 0;
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, n);
+ /* Start next frame. */
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ pac_sof_marker, sizeof pac_sof_marker);
+ len -= sof - data;
+ data = sof;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x08ca, 0x0111)},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index ee232956c81..1fff37b7989 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1360,7 +1360,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = OV511_ENDPOINT_ADDRESS;
if (!sd->sif) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -2177,8 +2176,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 3bf15e40169..19e0bc60de1 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,7 +1,8 @@
/*
- * ov534/ov772x gspca driver
+ * ov534 gspca driver
* Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
* Copyright (C) 2008 Jim Paris <jim@jtan.com>
+ * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
*
* Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
* USB protocol reverse engineered by Jim Paris <jim@jtan.com>
@@ -26,7 +27,7 @@
#include "gspca.h"
-#define OV534_REG_ADDRESS 0xf1 /* ? */
+#define OV534_REG_ADDRESS 0xf1 /* sensor address */
#define OV534_REG_SUBADDR 0xf2
#define OV534_REG_WRITE 0xf3
#define OV534_REG_READ 0xf4
@@ -46,9 +47,13 @@ MODULE_LICENSE("GPL");
/* specific webcam descriptor */
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- __u32 last_fid;
__u32 last_pts;
- int frame_rate;
+ u16 last_fid;
+ u8 frame_rate;
+
+ u8 sensor;
+#define SENSOR_OV772X 0
+#define SENSOR_OV965X 1
};
/* V4L2 controls supported by the driver */
@@ -63,114 +68,7 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 0},
};
-static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
- gspca_dev->usb_buf[0] = val;
- ret = usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
- 0x1,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- if (ret < 0)
- PDEBUG(D_ERR, "write failed");
-}
-
-static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- ret = usb_control_msg(udev,
- usb_rcvctrlpipe(udev, 0),
- 0x1,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
- if (ret < 0)
- PDEBUG(D_ERR, "read failed");
- return gspca_dev->usb_buf[0];
-}
-
-/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
- * (direction and output)? */
-static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
-{
- u8 data;
-
- PDEBUG(D_CONF, "led status: %d", status);
-
- data = ov534_reg_read(gspca_dev, 0x21);
- data |= 0x80;
- ov534_reg_write(gspca_dev, 0x21, data);
-
- data = ov534_reg_read(gspca_dev, 0x23);
- if (status)
- data |= 0x80;
- else
- data &= ~(0x80);
-
- ov534_reg_write(gspca_dev, 0x23, data);
-}
-
-static int sccb_check_status(struct gspca_dev *gspca_dev)
-{
- u8 data;
- int i;
-
- for (i = 0; i < 5; i++) {
- data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
-
- switch (data) {
- case 0x00:
- return 1;
- case 0x04:
- return 0;
- case 0x03:
- break;
- default:
- PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
- data, i + 1);
- }
- }
- return 0;
-}
-
-static void sccb_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
- PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val);
- ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
- ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
-
- if (!sccb_check_status(gspca_dev))
- PDEBUG(D_ERR, "sccb_reg_write failed");
-}
-
-#ifdef GSPCA_DEBUG
-static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
- ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
- if (!sccb_check_status(gspca_dev))
- PDEBUG(D_ERR, "sccb_reg_read failed 1");
-
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
- if (!sccb_check_status(gspca_dev))
- PDEBUG(D_ERR, "sccb_reg_read failed 2");
-
- return ov534_reg_read(gspca_dev, OV534_REG_READ);
-}
-#endif
-
-static const __u8 ov534_reg_initdata[][2] = {
- { 0xe7, 0x3a },
-
- { OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */
-
+static const u8 bridge_init_ov722x[][2] = {
{ 0xc2, 0x0c },
{ 0x88, 0xf8 },
{ 0xc3, 0x69 },
@@ -228,7 +126,7 @@ static const __u8 ov534_reg_initdata[][2] = {
{ 0xc2, 0x0c },
};
-static const __u8 ov772x_reg_initdata[][2] = {
+static const u8 sensor_init_ov722x[][2] = {
{ 0x12, 0x80 },
{ 0x11, 0x01 },
@@ -311,6 +209,456 @@ static const __u8 ov772x_reg_initdata[][2] = {
{ 0x0c, 0xd0 }
};
+static const u8 bridge_init_ov965x[][2] = {
+ {0x88, 0xf8},
+ {0x89, 0xff},
+ {0x76, 0x03},
+ {0x92, 0x03},
+ {0x95, 0x10},
+ {0xe2, 0x00},
+ {0xe7, 0x3e},
+ {0x8d, 0x1c},
+ {0x8e, 0x00},
+ {0x8f, 0x00},
+ {0x1f, 0x00},
+ {0xc3, 0xf9},
+ {0x89, 0xff},
+ {0x88, 0xf8},
+ {0x76, 0x03},
+ {0x92, 0x01},
+ {0x93, 0x18},
+ {0x1c, 0x0a},
+ {0x1d, 0x48},
+ {0xc0, 0x50},
+ {0xc1, 0x3c},
+ {0x34, 0x05},
+ {0xc2, 0x0c},
+ {0xc3, 0xf9},
+ {0x34, 0x05},
+ {0xe7, 0x2e},
+ {0x31, 0xf9},
+ {0x35, 0x02},
+ {0xd9, 0x10},
+ {0x25, 0x42},
+ {0x94, 0x11},
+};
+
+static const u8 sensor_init_ov965x[][2] = {
+ {0x12, 0x80}, /* com7 - reset */
+ {0x00, 0x00}, /* gain */
+ {0x01, 0x80}, /* blue */
+ {0x02, 0x80}, /* red */
+ {0x03, 0x1b}, /* vref */
+ {0x04, 0x03}, /* com1 - exposure low bits */
+ {0x0b, 0x57}, /* ver */
+ {0x0e, 0x61}, /* com5 */
+ {0x0f, 0x42}, /* com6 */
+ {0x11, 0x00}, /* clkrc */
+ {0x12, 0x02}, /* com7 */
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+ {0x14, 0x28}, /* com9 */
+ {0x16, 0x24}, /* rsvd16 */
+ {0x17, 0x1d}, /* hstart*/
+ {0x18, 0xbd}, /* hstop */
+ {0x19, 0x01}, /* vstrt */
+ {0x1a, 0x81}, /* vstop*/
+ {0x1e, 0x04}, /* mvfp */
+ {0x24, 0x3c}, /* aew */
+ {0x25, 0x36}, /* aeb */
+ {0x26, 0x71}, /* vpt */
+ {0x27, 0x08}, /* bbias */
+ {0x28, 0x08}, /* gbbias */
+ {0x29, 0x15}, /* gr com */
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0x2c, 0x08}, /* rbias */
+ {0x32, 0xff}, /* href */
+ {0x33, 0x00}, /* chlf */
+ {0x34, 0x3f}, /* arblm */
+ {0x35, 0x00}, /* rsvd35 */
+ {0x36, 0xf8}, /* rsvd36 */
+ {0x38, 0x72}, /* acom38 */
+ {0x39, 0x57}, /* ofon */
+ {0x3a, 0x80}, /* tslb */
+ {0x3b, 0xc4},
+ {0x3d, 0x99}, /* com13 */
+ {0x3f, 0xc1},
+ {0x40, 0xc0}, /* com15 */
+ {0x41, 0x40}, /* com16 */
+ {0x42, 0xc0},
+ {0x43, 0x0a},
+ {0x44, 0xf0},
+ {0x45, 0x46},
+ {0x46, 0x62},
+ {0x47, 0x2a},
+ {0x48, 0x3c},
+ {0x4a, 0xfc},
+ {0x4b, 0xfc},
+ {0x4c, 0x7f},
+ {0x4d, 0x7f},
+ {0x4e, 0x7f},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0x59, 0x85},
+ {0x5a, 0xa9},
+ {0x5b, 0x64},
+ {0x5c, 0x84},
+ {0x5d, 0x53},
+ {0x5e, 0x0e},
+ {0x5f, 0xf0},
+ {0x60, 0xf0},
+ {0x61, 0xf0},
+ {0x62, 0x00}, /* lcc1 */
+ {0x63, 0x00}, /* lcc2 */
+ {0x64, 0x02}, /* lcc3 */
+ {0x65, 0x16}, /* lcc4 */
+ {0x66, 0x01}, /* lcc5 */
+ {0x69, 0x02}, /* hv */
+ {0x6b, 0x5a}, /* dbvl */
+ {0x6c, 0x04},
+ {0x6d, 0x55},
+ {0x6e, 0x00},
+ {0x6f, 0x9d},
+ {0x70, 0x21},
+ {0x71, 0x78},
+ {0x72, 0x00},
+ {0x73, 0x01},
+ {0x74, 0x3a},
+ {0x75, 0x35},
+ {0x76, 0x01},
+ {0x77, 0x02},
+ {0x7a, 0x12},
+ {0x7b, 0x08},
+ {0x7c, 0x16},
+ {0x7d, 0x30},
+ {0x7e, 0x5e},
+ {0x7f, 0x72},
+ {0x80, 0x82},
+ {0x81, 0x8e},
+ {0x82, 0x9a},
+ {0x83, 0xa4},
+ {0x84, 0xac},
+ {0x85, 0xb8},
+ {0x86, 0xc3},
+ {0x87, 0xd6},
+ {0x88, 0xe6},
+ {0x89, 0xf2},
+ {0x8a, 0x03},
+ {0x8c, 0x89},
+ {0x14, 0x28}, /* com9 */
+ {0x90, 0x7d},
+ {0x91, 0x7b},
+ {0x9d, 0x03},
+ {0x9e, 0x04},
+ {0x9f, 0x7a},
+ {0xa0, 0x79},
+ {0xa1, 0x40}, /* aechm */
+ {0xa4, 0x50},
+ {0xa5, 0x68}, /* com26 */
+ {0xa6, 0x4a},
+ {0xa8, 0xc1}, /* acoma8 */
+ {0xa9, 0xef}, /* acoma9 */
+ {0xaa, 0x92},
+ {0xab, 0x04},
+ {0xac, 0x80},
+ {0xad, 0x80},
+ {0xae, 0x80},
+ {0xaf, 0x80},
+ {0xb2, 0xf2},
+ {0xb3, 0x20},
+ {0xb4, 0x20},
+ {0xb5, 0x00},
+ {0xb6, 0xaf},
+ {0xbb, 0xae},
+ {0xbc, 0x7f},
+ {0xdb, 0x7f},
+ {0xbe, 0x7f},
+ {0xbf, 0x7f},
+ {0xc0, 0xe2},
+ {0xc1, 0xc0},
+ {0xc2, 0x01},
+ {0xc3, 0x4e},
+ {0xc6, 0x85},
+ {0xc7, 0x80},
+ {0xc9, 0xe0},
+ {0xca, 0xe8},
+ {0xcb, 0xf0},
+ {0xcc, 0xd8},
+ {0xcd, 0xf1},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0xff, 0x41}, /* read 41, write ff 00 */
+ {0x41, 0x40}, /* com16 */
+ {0xc5, 0x03},
+ {0x6a, 0x02},
+
+ {0x12, 0x62}, /* com7 - VGA + CIF */
+ {0x36, 0xfa}, /* rsvd36 */
+ {0x69, 0x0a}, /* hv */
+ {0x8c, 0x89}, /* com22 */
+ {0x14, 0x28}, /* com9 */
+ {0x3e, 0x0c},
+ {0x41, 0x40}, /* com16 */
+ {0x72, 0x00},
+ {0x73, 0x00},
+ {0x74, 0x3a},
+ {0x75, 0x35},
+ {0x76, 0x01},
+ {0xc7, 0x80},
+ {0x03, 0x12}, /* vref */
+ {0x17, 0x16}, /* hstart */
+ {0x18, 0x02}, /* hstop */
+ {0x19, 0x01}, /* vstrt */
+ {0x1a, 0x3d}, /* vstop */
+ {0x32, 0xff}, /* href */
+ {0xc0, 0xaa},
+};
+
+static const u8 bridge_init_ov965x_2[][2] = {
+ {0x94, 0xaa},
+ {0xf1, 0x60},
+ {0xe5, 0x04},
+ {0xc0, 0x50},
+ {0xc1, 0x3c},
+ {0x8c, 0x00},
+ {0x8d, 0x1c},
+ {0x34, 0x05},
+
+ {0xc2, 0x0c},
+ {0xc3, 0xf9},
+ {0xda, 0x01},
+ {0x50, 0x00},
+ {0x51, 0xa0},
+ {0x52, 0x3c},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x57, 0x00},
+ {0x5c, 0x00},
+ {0x5a, 0xa0},
+ {0x5b, 0x78},
+ {0x35, 0x02},
+ {0xd9, 0x10},
+ {0x94, 0x11},
+};
+
+static const u8 sensor_init_ov965x_2[][2] = {
+ {0x3b, 0xc4},
+ {0x1e, 0x04}, /* mvfp */
+ {0x13, 0xe0}, /* com8 */
+ {0x00, 0x00}, /* gain */
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+ {0x11, 0x03}, /* clkrc */
+ {0x6b, 0x5a}, /* dblv */
+ {0x6a, 0x05},
+ {0xc5, 0x07},
+ {0xa2, 0x4b},
+ {0xa3, 0x3e},
+ {0x2d, 0x00},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc0},
+ {0x2d, 0x00},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc1},
+ {0x3f, 0x01},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc1},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0xff, 0x41}, /* read 41, write ff 00 */
+ {0x41, 0x40}, /* com16 */
+ {0x56, 0x40},
+ {0x55, 0x8f},
+ {0x10, 0x25}, /* aech - exposure high bits */
+ {0xff, 0x13}, /* read 13, write ff 00 */
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+};
+
+static const u8 bridge_start_ov965x[][2] = {
+ {0xc2, 0x4c},
+ {0xc3, 0xf9},
+ {0x50, 0x00},
+ {0x51, 0xa0},
+ {0x52, 0x78},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x57, 0x00},
+ {0x5c, 0x00},
+ {0x5a, 0x28},
+ {0x5b, 0x1e},
+ {0x35, 0x00},
+ {0xd9, 0x21},
+ {0x94, 0x11},
+};
+
+static const u8 sensor_start_ov965x[][2] = {
+ {0x3b, 0xe4},
+ {0x1e, 0x04}, /* mvfp */
+ {0x13, 0xe0}, /* com8 */
+ {0x00, 0x00},
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+ {0x11, 0x01}, /* clkrc */
+ {0x6b, 0x5a}, /* dblv */
+ {0x6a, 0x02},
+ {0xc5, 0x03},
+ {0xa2, 0x96},
+ {0xa3, 0x7d},
+ {0xff, 0x13}, /* read 13, write ff 00 */
+ {0x13, 0xe7},
+ {0x3a, 0x80},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc1},
+};
+
+
+static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int ret;
+
+ PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
+ gspca_dev->usb_buf[0] = val;
+ ret = usb_control_msg(udev,
+ usb_sndctrlpipe(udev, 0),
+ 0x01,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
+ if (ret < 0)
+ PDEBUG(D_ERR, "write failed");
+}
+
+static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int ret;
+
+ ret = usb_control_msg(udev,
+ usb_rcvctrlpipe(udev, 0),
+ 0x01,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
+ PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
+ if (ret < 0)
+ PDEBUG(D_ERR, "read failed");
+ return gspca_dev->usb_buf[0];
+}
+
+/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
+ * (direction and output)? */
+static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
+{
+ u8 data;
+
+ PDEBUG(D_CONF, "led status: %d", status);
+
+ data = ov534_reg_read(gspca_dev, 0x21);
+ data |= 0x80;
+ ov534_reg_write(gspca_dev, 0x21, data);
+
+ data = ov534_reg_read(gspca_dev, 0x23);
+ if (status)
+ data |= 0x80;
+ else
+ data &= ~0x80;
+
+ ov534_reg_write(gspca_dev, 0x23, data);
+
+ if (!status) {
+ data = ov534_reg_read(gspca_dev, 0x21);
+ data &= ~0x80;
+ ov534_reg_write(gspca_dev, 0x21, data);
+ }
+}
+
+static int sccb_check_status(struct gspca_dev *gspca_dev)
+{
+ u8 data;
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
+
+ switch (data) {
+ case 0x00:
+ return 1;
+ case 0x04:
+ return 0;
+ case 0x03:
+ break;
+ default:
+ PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
+ data, i + 1);
+ }
+ }
+ return 0;
+}
+
+static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
+{
+ PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val);
+ ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
+ ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
+ ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
+
+ if (!sccb_check_status(gspca_dev))
+ PDEBUG(D_ERR, "sccb_reg_write failed");
+}
+
+static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
+{
+ ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
+ ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
+ if (!sccb_check_status(gspca_dev))
+ PDEBUG(D_ERR, "sccb_reg_read failed 1");
+
+ ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
+ if (!sccb_check_status(gspca_dev))
+ PDEBUG(D_ERR, "sccb_reg_read failed 2");
+
+ return ov534_reg_read(gspca_dev, OV534_REG_READ);
+}
+
+/* output a bridge sequence (reg - val) */
+static void reg_w_array(struct gspca_dev *gspca_dev,
+ const u8 (*data)[2], int len)
+{
+ while (--len >= 0) {
+ ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]);
+ data++;
+ }
+}
+
+/* output a sensor sequence (reg - val) */
+static void sccb_w_array(struct gspca_dev *gspca_dev,
+ const u8 (*data)[2], int len)
+{
+ while (--len >= 0) {
+ if ((*data)[0] != 0xff) {
+ sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]);
+ } else {
+ sccb_reg_read(gspca_dev, (*data)[1]);
+ sccb_reg_write(gspca_dev, 0xff, 0x00);
+ }
+ data++;
+ }
+}
+
/* set framerate */
static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
{
@@ -346,40 +694,17 @@ static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
PDEBUG(D_PROBE, "frame_rate: %d", fr);
}
-/* setup method */
-static void ov534_setup(struct gspca_dev *gspca_dev)
-{
- int i;
-
- /* Initialize bridge chip */
- for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++)
- ov534_reg_write(gspca_dev, ov534_reg_initdata[i][0],
- ov534_reg_initdata[i][1]);
-
- PDEBUG(D_PROBE, "sensor is ov%02x%02x",
- sccb_reg_read(gspca_dev, 0x0a),
- sccb_reg_read(gspca_dev, 0x0b));
-
- ov534_set_led(gspca_dev, 1);
-
- /* Initialize sensor */
- for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++)
- sccb_reg_write(gspca_dev, ov772x_reg_initdata[i][0],
- ov772x_reg_initdata[i][1]);
-
- ov534_reg_write(gspca_dev, 0xe0, 0x09);
- ov534_set_led(gspca_dev, 0);
-}
-
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
+ struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
+ sd->sensor = id->driver_info;
+
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -392,26 +717,102 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- ov534_setup(gspca_dev);
- ov534_set_frame_rate(gspca_dev);
+ struct sd *sd = (struct sd *) gspca_dev;
+ u16 sensor_id;
+ static const u8 sensor_addr[2] = {
+ 0x42, /* 0 SENSOR_OV772X */
+ 0x60, /* 1 SENSOR_OV965X */
+ };
+
+ /* reset bridge */
+ ov534_reg_write(gspca_dev, 0xe7, 0x3a);
+ ov534_reg_write(gspca_dev, 0xe0, 0x08);
+ msleep(100);
+
+ /* initialize the sensor address */
+ ov534_reg_write(gspca_dev, OV534_REG_ADDRESS,
+ sensor_addr[sd->sensor]);
+
+ /* reset sensor */
+ sccb_reg_write(gspca_dev, 0x12, 0x80);
+ msleep(10);
+
+ /* probe the sensor */
+ sccb_reg_read(gspca_dev, 0x0a);
+ sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
+ sccb_reg_read(gspca_dev, 0x0b);
+ sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
+ PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
+
+ /* initialize */
+ switch (sd->sensor) {
+ case SENSOR_OV772X:
+ reg_w_array(gspca_dev, bridge_init_ov722x,
+ ARRAY_SIZE(bridge_init_ov722x));
+ ov534_set_led(gspca_dev, 1);
+ sccb_w_array(gspca_dev, sensor_init_ov722x,
+ ARRAY_SIZE(sensor_init_ov722x));
+ ov534_reg_write(gspca_dev, 0xe0, 0x09);
+ ov534_set_led(gspca_dev, 0);
+ ov534_set_frame_rate(gspca_dev);
+ break;
+ default:
+/* case SENSOR_OV965X: */
+ reg_w_array(gspca_dev, bridge_init_ov965x,
+ ARRAY_SIZE(bridge_init_ov965x));
+ sccb_w_array(gspca_dev, sensor_init_ov965x,
+ ARRAY_SIZE(sensor_init_ov965x));
+ reg_w_array(gspca_dev, bridge_init_ov965x_2,
+ ARRAY_SIZE(bridge_init_ov965x_2));
+ sccb_w_array(gspca_dev, sensor_init_ov965x_2,
+ ARRAY_SIZE(sensor_init_ov965x_2));
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ ov534_reg_write(gspca_dev, 0xe0, 0x01);
+ ov534_set_led(gspca_dev, 0);
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ }
return 0;
}
static int sd_start(struct gspca_dev *gspca_dev)
{
- /* start streaming data */
- ov534_set_led(gspca_dev, 1);
- ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ struct sd *sd = (struct sd *) gspca_dev;
+ switch (sd->sensor) {
+ case SENSOR_OV772X:
+ ov534_set_led(gspca_dev, 1);
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ break;
+ default:
+/* case SENSOR_OV965X: */
+ reg_w_array(gspca_dev, bridge_start_ov965x,
+ ARRAY_SIZE(bridge_start_ov965x));
+ sccb_w_array(gspca_dev, sensor_start_ov965x,
+ ARRAY_SIZE(sensor_start_ov965x));
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ ov534_set_led(gspca_dev, 1);
+/*fixme: other sensor start omitted*/
+ }
return 0;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- /* stop streaming data */
- ov534_reg_write(gspca_dev, 0xe0, 0x09);
- ov534_set_led(gspca_dev, 0);
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->sensor) {
+ case SENSOR_OV772X:
+ ov534_reg_write(gspca_dev, 0xe0, 0x09);
+ ov534_set_led(gspca_dev, 0);
+ break;
+ default:
+/* case SENSOR_OV965X: */
+ ov534_reg_write(gspca_dev, 0xe0, 0x01);
+ ov534_set_led(gspca_dev, 0);
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ break;
+ }
}
/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -429,75 +830,75 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
{
struct sd *sd = (struct sd *) gspca_dev;
__u32 this_pts;
- int this_fid;
+ u16 this_fid;
int remaining_len = len;
- __u8 *next_data = data;
-scan_next:
- if (remaining_len <= 0)
- return;
-
- data = next_data;
- len = min(remaining_len, 2048);
- remaining_len -= len;
- next_data += len;
-
- /* Payloads are prefixed with a UVC-style header. We
- consider a frame to start when the FID toggles, or the PTS
- changes. A frame ends when EOF is set, and we've received
- the correct number of bytes. */
-
- /* Verify UVC header. Header length is always 12 */
- if (data[0] != 12 || len < 12) {
- PDEBUG(D_PACK, "bad header");
- goto discard;
- }
-
- /* Check errors */
- if (data[1] & UVC_STREAM_ERR) {
- PDEBUG(D_PACK, "payload error");
- goto discard;
- }
+ do {
+ len = min(remaining_len, 2040); /*fixme: was 2048*/
- /* Extract PTS and FID */
- if (!(data[1] & UVC_STREAM_PTS)) {
- PDEBUG(D_PACK, "PTS not present");
- goto discard;
- }
- this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2];
- this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
-
- /* If PTS or FID has changed, start a new frame. */
- if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
- sd->last_pts = this_pts;
- sd->last_fid = this_fid;
- }
+ /* Payloads are prefixed with a UVC-style header. We
+ consider a frame to start when the FID toggles, or the PTS
+ changes. A frame ends when EOF is set, and we've received
+ the correct number of bytes. */
- /* Add the data from this payload */
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- data + 12, len - 12);
+ /* Verify UVC header. Header length is always 12 */
+ if (data[0] != 12 || len < 12) {
+ PDEBUG(D_PACK, "bad header");
+ goto discard;
+ }
- /* If this packet is marked as EOF, end the frame */
- if (data[1] & UVC_STREAM_EOF) {
- sd->last_pts = 0;
+ /* Check errors */
+ if (data[1] & UVC_STREAM_ERR) {
+ PDEBUG(D_PACK, "payload error");
+ goto discard;
+ }
- if ((frame->data_end - frame->data) !=
- (gspca_dev->width * gspca_dev->height * 2)) {
- PDEBUG(D_PACK, "short frame");
+ /* Extract PTS and FID */
+ if (!(data[1] & UVC_STREAM_PTS)) {
+ PDEBUG(D_PACK, "PTS not present");
goto discard;
}
+ this_pts = (data[5] << 24) | (data[4] << 16)
+ | (data[3] << 8) | data[2];
+ this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
+
+ /* If PTS or FID has changed, start a new frame. */
+ if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ NULL, 0);
+ sd->last_pts = this_pts;
+ sd->last_fid = this_fid;
+ }
- gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0);
- }
+ /* Add the data from this payload */
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ data + 12, len - 12);
- /* Done this payload */
- goto scan_next;
+ /* If this packet is marked as EOF, end the frame */
+ if (data[1] & UVC_STREAM_EOF) {
+ sd->last_pts = 0;
+
+ if (frame->data_end - frame->data !=
+ gspca_dev->width * gspca_dev->height * 2) {
+ PDEBUG(D_PACK, "short frame");
+ goto discard;
+ }
+
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ NULL, 0);
+ }
+
+ /* Done this payload */
+ goto scan_next;
discard:
- /* Discard data until a new frame starts. */
- gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
- goto scan_next;
+ /* Discard data until a new frame starts. */
+ gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
+
+scan_next:
+ remaining_len -= len;
+ data += len;
+ } while (remaining_len > 0);
}
/* get stream parameters (framerate) */
@@ -556,9 +957,8 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */
- {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */
- {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */
+ {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
+ {USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
{}
};
@@ -585,8 +985,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index c90ac852bac..95a97ab684c 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -256,7 +256,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
cam = &gspca_dev->cam;
- cam->epaddr = 0x05;
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
@@ -536,6 +535,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2470)},
{USB_DEVICE(0x093a, 0x2471)},
{USB_DEVICE(0x093a, 0x2472)},
+ {USB_DEVICE(0x093a, 0x2474)},
{USB_DEVICE(0x093a, 0x2476)},
{USB_DEVICE(0x145f, 0x013a)},
{USB_DEVICE(0x2001, 0xf115)},
@@ -565,8 +565,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index a9c95cba710..e1e3a3a5048 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -498,7 +498,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x05;
sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAC7302) {
@@ -1097,8 +1096,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index b3e4e0677b6..153d0a91d4b 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -870,7 +870,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
if (!(sensor_data[sd->sensor].flags & F_SIF)) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1272,8 +1271,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 3373b8d9d2a..c72e19d3ac3 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -35,36 +35,47 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
atomic_t avg_lum;
- unsigned int exposure;
-
- __u16 brightness;
- __u8 contrast;
- __u8 colors;
- __u8 autogain;
- __u8 blue;
- __u8 red;
- __u8 vflip; /* ov7630 only */
- __u8 infrared; /* mi0360 only */
-
- __s8 ag_cnt;
+ u32 exposure;
+
+ u16 brightness;
+ u8 contrast;
+ u8 colors;
+ u8 autogain;
+ u8 blue;
+ u8 red;
+ u8 gamma;
+ u8 vflip; /* ov7630/ov7648 only */
+ u8 infrared; /* mt9v111 only */
+ u8 quality; /* image quality */
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
+ u8 jpegqual; /* webcam quality */
+
+ u8 reg18;
+
+ s8 ag_cnt;
#define AG_CNT_START 13
- __u8 qindex;
- __u8 bridge;
+ u8 bridge;
#define BRIDGE_SN9C102P 0
#define BRIDGE_SN9C105 1
#define BRIDGE_SN9C110 2
#define BRIDGE_SN9C120 3
#define BRIDGE_SN9C325 4
- __u8 sensor; /* Type of image sensor chip */
+ u8 sensor; /* Type of image sensor chip */
#define SENSOR_HV7131R 0
#define SENSOR_MI0360 1
#define SENSOR_MO4000 2
-#define SENSOR_OM6802 3
-#define SENSOR_OV7630 4
-#define SENSOR_OV7648 5
-#define SENSOR_OV7660 6
- __u8 i2c_base;
+#define SENSOR_MT9V111 3
+#define SENSOR_OM6802 4
+#define SENSOR_OV7630 5
+#define SENSOR_OV7648 6
+#define SENSOR_OV7660 7
+#define SENSOR_SP80708 8
+ u8 i2c_base;
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -78,6 +89,8 @@ static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -158,6 +171,20 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setred_balance,
.get = sd_getred_balance,
},
+ {
+ {
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 0,
+ .maximum = 40,
+ .step = 1,
+#define GAMMA_DEF 20
+ .default_value = GAMMA_DEF,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
#define AUTOGAIN_IDX 5
{
{
@@ -173,7 +200,7 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setautogain,
.get = sd_getautogain,
},
-/* ov7630 only */
+/* ov7630/ov7648 only */
#define VFLIP_IDX 6
{
{
@@ -183,13 +210,13 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
-#define VFLIP_DEF 1
+#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */
.default_value = VFLIP_DEF,
},
.set = sd_setvflip,
.get = sd_getvflip,
},
-/* mi0360 only */
+/* mt9v111 only */
#define INFRARED_IDX 7
{
{
@@ -211,18 +238,22 @@ static struct ctrl sd_ctrls[] = {
static __u32 ctrl_dis[] = {
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_HV7131R 0 */
- (1 << VFLIP_IDX),
+ (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_MI0360 1 */
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_MO4000 2 */
+ (1 << VFLIP_IDX),
+ /* SENSOR_MT9V111 3 */
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OM6802 3 */
+ /* SENSOR_OM6802 4 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
- /* SENSOR_OV7630 4 */
+ /* SENSOR_OV7630 5 */
+ (1 << INFRARED_IDX),
+ /* SENSOR_OV7648 6 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OV7648 5 */
+ /* SENSOR_OV7660 7 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OV7660 6 */
+ /* SENSOR_SP80708 8 */
};
static const struct v4l2_pix_format vga_mode[] = {
@@ -243,196 +274,228 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 0},
};
-/*Data from sn9c102p+hv71331r */
-static const __u8 sn_hv7131[] = {
+/*Data from sn9c102p+hv7131r */
+static const u8 sn_hv7131[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0a, 0x00, 0x00, 0x00
};
-static const __u8 sn_mi0360[] = {
+static const u8 sn_mi0360[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x06, 0x00, 0x00, 0x00
};
-static const __u8 sn_mo4000[] = {
+static const u8 sn_mo4000[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
+ 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x08, 0x00, 0x00, 0x00
};
-static const __u8 sn_om6802[] = {
+static const u8 sn_mt9v111[0x1c] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
+ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
+/* reg8 reg9 rega regb regc regd rege regf */
+ 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
+ 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
+/* reg18 reg19 reg1a reg1b */
+ 0x06, 0x00, 0x00, 0x00
+};
+
+static const u8 sn_om6802[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
- 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
- 0xf7
+/* reg18 reg19 reg1a reg1b */
+ 0x05, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7630[] = {
+static const u8 sn_ov7630[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0b, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7648[] = {
+static const u8 sn_ov7648[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0b, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7660[] = {
+static const u8 sn_ov7660[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg18 reg19 reg1a reg1b */
+ 0x07, 0x00, 0x00, 0x00
+};
+
+static const u8 sn_sp80708[0x1c] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
+ 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
+/* reg8 reg9 rega regb regc regd rege regf */
+ 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
+ 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
+/* reg18 reg19 reg1a reg1b */
+ 0x07, 0x00, 0x00, 0x00
};
/* sequence specific to the sensors - !! index = SENSOR_xxx */
-static const __u8 *sn_tb[] = {
+static const u8 *sn_tb[] = {
sn_hv7131,
sn_mi0360,
sn_mo4000,
+ sn_mt9v111,
sn_om6802,
sn_ov7630,
sn_ov7648,
- sn_ov7660
+ sn_ov7660,
+ sn_sp80708
};
-static const __u8 gamma_def[] = {
+/* default gamma table */
+static const u8 gamma_def[17] = {
0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
};
+/* gamma for sensors HV7131R and MT9V111 */
+static const u8 gamma_spec_1[17] = {
+ 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
+ 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
+};
+/* gamma for sensor SP80708 */
+static const u8 gamma_spec_2[17] = {
+ 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
+ 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
+};
/* color matrix and offsets */
-static const __u8 reg84[] = {
+static const u8 reg84[] = {
0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
0x00, 0x00, 0x00 /* YUV offsets */
};
-static const __u8 hv7131r_sensor_init[][8] = {
- {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
- {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
- {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
- {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
- {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
- {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
- {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
- {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
+static const u8 hv7131r_sensor_init[][8] = {
+ {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
+ {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
+/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
+ {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
+/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
+ {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
+ {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
+ {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
+ {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
+ {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
{}
};
-static const __u8 mi0360_sensor_init[][8] = {
- {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
- {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
- {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
- {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
- {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
- {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
- {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
- {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
- {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
-
- {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
- {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
-
- {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
- {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
-
- {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
- {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
-/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
-/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
- {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
- {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
+static const u8 mi0360_sensor_init[][8] = {
+ {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
+ {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
+ {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
+ {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
+ {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
+ {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
+ {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
+ {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
+ {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
+
+ {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
+ {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
+
+ {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
+ {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
+
+ {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
+ {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
+/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
+/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
+ {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
+ {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
{}
};
-static const __u8 mo4000_sensor_init[][8] = {
+static const u8 mo4000_sensor_init[][8] = {
{0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -455,7 +518,49 @@ static const __u8 mo4000_sensor_init[][8] = {
{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
{}
};
-static __u8 om6802_sensor_init[][8] = {
+static const u8 mt9v111_sensor_init[][8] = {
+ {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
+ /* delay 20 ms */
+ {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
+ {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
+ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
+ {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
+ {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
+ {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
+ {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
+ {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
+ {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
+ {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
+ {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ /*******/
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
+ {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
+ {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
+ /*******/
+ {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
+ {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
+ {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
+ {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
+ {}
+};
+static const u8 om6802_sensor_init[][8] = {
{0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
{0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
@@ -489,7 +594,7 @@ static __u8 om6802_sensor_init[][8] = {
/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
{}
};
-static const __u8 ov7630_sensor_init[][8] = {
+static const u8 ov7630_sensor_init[][8] = {
{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
/* win: delay 20ms */
@@ -543,7 +648,7 @@ static const __u8 ov7630_sensor_init[][8] = {
{}
};
-static const __u8 ov7648_sensor_init[][8] = {
+static const u8 ov7648_sensor_init[][8] = {
{0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -572,7 +677,8 @@ static const __u8 ov7648_sensor_init[][8] = {
{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
/*...*/
/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
+/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
+ * set by setvflip */
{0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
@@ -589,7 +695,7 @@ static const __u8 ov7648_sensor_init[][8] = {
{}
};
-static const __u8 ov7660_sensor_init[][8] = {
+static const u8 ov7660_sensor_init[][8] = {
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
/* (delay 20ms) */
{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
@@ -678,28 +784,92 @@ static const __u8 ov7660_sensor_init[][8] = {
{}
};
-static const __u8 qtable4[] = {
- 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
- 0x06, 0x08, 0x0A, 0x11,
- 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
- 0x19, 0x19, 0x17, 0x15,
- 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
- 0x21, 0x2E, 0x21, 0x23,
- 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
- 0x25, 0x29, 0x2C, 0x29,
- 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
- 0x17, 0x1B, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29
+static const u8 sp80708_sensor_init[][8] = {
+ {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
+ /********/
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
+ {}
};
/* read <len> bytes to gspca_dev->usb_buf */
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) {
@@ -718,10 +888,10 @@ static void reg_r(struct gspca_dev *gspca_dev,
}
static void reg_w1(struct gspca_dev *gspca_dev,
- __u16 value,
- __u8 data)
+ u16 value,
+ u8 data)
{
- PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
+ PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
gspca_dev->usb_buf[0] = data;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -733,11 +903,11 @@ static void reg_w1(struct gspca_dev *gspca_dev,
500);
}
static void reg_w(struct gspca_dev *gspca_dev,
- __u16 value,
- const __u8 *buffer,
+ u16 value,
+ const u8 *buffer,
int len)
{
- PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
+ PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
value, buffer[0], buffer[1]);
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
@@ -756,7 +926,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
}
/* I2C write 1 byte */
-static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
+static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -781,7 +951,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
/* I2C write 8 bytes */
static void i2c_w8(struct gspca_dev *gspca_dev,
- const __u8 *buffer)
+ const u8 *buffer)
{
memcpy(gspca_dev->usb_buf, buffer, 8);
usb_control_msg(gspca_dev->dev,
@@ -795,10 +965,10 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
}
/* read 5 bytes in gspca_dev->usb_buf */
-static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
+static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 mode[8];
+ u8 mode[8];
mode[0] = 0x81 | 0x10;
mode[1] = sd->i2c_base;
@@ -817,7 +987,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
reg_r(gspca_dev, 0x0a, 5);
}
-static int probesensor(struct gspca_dev *gspca_dev)
+static int hv7131r_probe(struct gspca_dev *gspca_dev)
{
i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
msleep(10);
@@ -839,16 +1009,66 @@ static int probesensor(struct gspca_dev *gspca_dev)
return -ENODEV;
}
+static void mi0360_probe(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, j;
+ u16 val = 0;
+ static const u8 probe_tb[][4][8] = {
+ { /* mi0360 */
+ {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
+ },
+ { /* mt9v111 */
+ {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {}
+ },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
+ reg_w1(gspca_dev, 0x17, 0x62);
+ reg_w1(gspca_dev, 0x01, 0x08);
+ for (j = 0; j < 3; j++)
+ i2c_w8(gspca_dev, probe_tb[i][j]);
+ msleep(2);
+ reg_r(gspca_dev, 0x0a, 5);
+ val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
+ if (probe_tb[i][3][0] != 0)
+ i2c_w8(gspca_dev, probe_tb[i][3]);
+ reg_w1(gspca_dev, 0x01, 0x29);
+ reg_w1(gspca_dev, 0x17, 0x42);
+ if (val != 0xffff)
+ break;
+ }
+ switch (val) {
+ case 0x823a:
+ PDEBUG(D_PROBE, "Sensor mt9v111");
+ sd->sensor = SENSOR_MT9V111;
+ sd->i2c_base = 0x5c;
+ break;
+ case 0x8243:
+ PDEBUG(D_PROBE, "Sensor mi0360");
+ break;
+ default:
+ PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
+ break;
+ }
+}
+
static int configure_gpio(struct gspca_dev *gspca_dev,
- const __u8 *sn9c1xx)
+ const u8 *sn9c1xx)
{
struct sd *sd = (struct sd *) gspca_dev;
- const __u8 *reg9a;
- static const __u8 reg9a_def[] =
+ const u8 *reg9a;
+ static const u8 reg9a_def[] =
{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
- static const __u8 reg9a_sn9c325[] =
+ static const u8 reg9a_sn9c325[] =
{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
- static const __u8 regd4[] = {0x60, 0x00, 0x00};
+ static const u8 regd4[] = {0x60, 0x00, 0x00};
reg_w1(gspca_dev, 0xf1, 0x00);
reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -872,6 +1092,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg_w1(gspca_dev, 0x01, 0x61);
+ reg_w1(gspca_dev, 0x17, 0x61);
+ reg_w1(gspca_dev, 0x01, 0x60);
+ reg_w1(gspca_dev, 0x01, 0x40);
+ break;
case SENSOR_OM6802:
reg_w1(gspca_dev, 0x02, 0x71);
reg_w1(gspca_dev, 0x01, 0x42);
@@ -900,12 +1126,20 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
break;
}
/* fall thru */
+ case SENSOR_SP80708:
+ reg_w1(gspca_dev, 0x01, 0x63);
+ reg_w1(gspca_dev, 0x17, 0x20);
+ reg_w1(gspca_dev, 0x01, 0x62);
+ reg_w1(gspca_dev, 0x01, 0x42);
+ mdelay(100);
+ reg_w1(gspca_dev, 0x02, 0x62);
+ break;
default:
reg_w1(gspca_dev, 0x01, 0x43);
reg_w1(gspca_dev, 0x17, 0x61);
reg_w1(gspca_dev, 0x01, 0x42);
if (sd->sensor == SENSOR_HV7131R) {
- if (probesensor(gspca_dev) < 0)
+ if (hv7131r_probe(gspca_dev) < 0)
return -ENODEV;
}
break;
@@ -916,7 +1150,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
{
int i = 0;
- static const __u8 SetSensorClk[] = /* 0x08 Mclk */
+ static const u8 SetSensorClk[] = /* 0x08 Mclk */
{ 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
while (hv7131r_sensor_init[i][0]) {
@@ -946,6 +1180,19 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
}
}
+static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
+ i++;
+ msleep(20);
+ while (mt9v111_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
+ i++;
+ }
+}
+
static void om6802_InitSensor(struct gspca_dev *gspca_dev)
{
int i = 0;
@@ -1010,6 +1257,19 @@ static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
}
}
+static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
+ i++;
+ msleep(20);
+ while (sp80708_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, sp80708_sensor_init[i]);
+ i++;
+ }
+}
+
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
@@ -1018,7 +1278,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1026,16 +1285,21 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info >> 8;
sd->i2c_base = id->driver_info;
- sd->qindex = 4; /* set the quantization table */
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
sd->blue = BLUE_BALANCE_DEF;
sd->red = RED_BALANCE_DEF;
+ sd->gamma = GAMMA_DEF;
sd->autogain = AUTOGAIN_DEF;
sd->ag_cnt = -1;
- sd->vflip = VFLIP_DEF;
+ if (sd->sensor != SENSOR_OV7630)
+ sd->vflip = 0;
+ else
+ sd->vflip = 1;
sd->infrared = INFRARED_DEF;
+ sd->quality = QUALITY_DEF;
+ sd->jpegqual = 80;
gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
return 0;
@@ -1045,8 +1309,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
static int sd_init(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 regGpio[] = { 0x29, 0x74 };
- __u8 regF1;
+ u8 regGpio[] = { 0x29, 0x74 };
+ u8 regF1;
/* setup a selector by bridge */
reg_w1(gspca_dev, 0xf1, 0x01);
@@ -1064,11 +1328,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
case BRIDGE_SN9C105:
if (regF1 != 0x11)
return -ENODEV;
+ if (sd->sensor == SENSOR_MI0360)
+ mi0360_probe(gspca_dev);
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
case BRIDGE_SN9C120:
if (regF1 != 0x12)
return -ENODEV;
+ if (sd->sensor == SENSOR_MI0360)
+ mi0360_probe(gspca_dev);
regGpio[1] = 0x70;
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
@@ -1086,20 +1354,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
return 0;
}
-static unsigned int setexposure(struct gspca_dev *gspca_dev,
- unsigned int expo)
+static u32 setexposure(struct gspca_dev *gspca_dev,
+ u32 expo)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 doit[] = /* update sensor */
- { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
- static const __u8 sensorgo[] = /* sensor on */
- { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
- static const __u8 gainMo[] =
- { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
switch (sd->sensor) {
case SENSOR_HV7131R: {
- __u8 Expodoit[] =
+ u8 Expodoit[] =
{ 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
Expodoit[3] = expo >> 16;
@@ -1109,8 +1371,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
break;
}
case SENSOR_MI0360: {
- __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
+ u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
{ 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
+ static const u8 doit[] = /* update sensor */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
+ static const u8 sensorgo[] = /* sensor on */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
if (expo > 0x0635)
expo = 0x0635;
@@ -1124,10 +1390,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
break;
}
case SENSOR_MO4000: {
- __u8 expoMof[] =
+ u8 expoMof[] =
{ 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
- __u8 expoMo10[] =
+ u8 expoMo10[] =
{ 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
+ static const u8 gainMo[] =
+ { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
if (expo > 0x1fff)
expo = 0x1fff;
@@ -1139,14 +1407,27 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
| ((expo & 0x0003) << 4);
i2c_w8(gspca_dev, expoMo10);
i2c_w8(gspca_dev, gainMo);
- PDEBUG(D_CONF, "set exposure %d",
+ PDEBUG(D_FRAM, "set exposure %d",
((expoMo10[3] & 0x07) << 10)
| (expoMof[3] << 2)
| ((expoMo10[3] & 0x30) >> 4));
break;
}
+ case SENSOR_MT9V111: {
+ u8 expo_c1[] =
+ { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
+
+ if (expo > 0x0280)
+ expo = 0x0280;
+ else if (expo < 0x0040)
+ expo = 0x0040;
+ expo_c1[3] = expo >> 8;
+ expo_c1[4] = expo;
+ i2c_w8(gspca_dev, expo_c1);
+ break;
+ }
case SENSOR_OM6802: {
- __u8 gainOm[] =
+ u8 gainOm[] =
{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
if (expo > 0x03ff)
@@ -1156,7 +1437,7 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
gainOm[3] = expo >> 2;
i2c_w8(gspca_dev, gainOm);
reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
- PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
+ PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
break;
}
}
@@ -1167,7 +1448,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int expo;
- __u8 k2;
+ u8 k2;
k2 = ((int) sd->brightness - 0x8000) >> 10;
switch (sd->sensor) {
@@ -1184,6 +1465,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
expo = sd->brightness >> 4;
sd->exposure = setexposure(gspca_dev, expo);
break;
+ case SENSOR_MT9V111:
+ expo = sd->brightness >> 8;
+ sd->exposure = setexposure(gspca_dev, expo);
+ break;
case SENSOR_OM6802:
expo = sd->brightness >> 6;
sd->exposure = setexposure(gspca_dev, expo);
@@ -1191,14 +1476,15 @@ static void setbrightness(struct gspca_dev *gspca_dev)
break;
}
- reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
+ if (sd->sensor != SENSOR_MT9V111)
+ reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
}
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 k2;
- __u8 contrast[6];
+ u8 k2;
+ u8 contrast[6];
k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
contrast[0] = (k2 + 1) / 2; /* red */
@@ -1214,8 +1500,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i, v;
- __u8 reg8a[12]; /* U & V gains */
- static __s16 uv[6] = { /* same as reg84 in signed decimal */
+ u8 reg8a[12]; /* U & V gains */
+ static s16 uv[6] = { /* same as reg84 in signed decimal */
-24, -38, 64, /* UR UG UB */
62, -51, -9 /* VR VG VB */
};
@@ -1236,22 +1522,75 @@ static void setredblue(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x06, sd->blue);
}
+static void setgamma(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ u8 gamma[17];
+ const u8 *gamma_base;
+ static const u8 delta[17] = {
+ 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
+ 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
+ };
+
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ case SENSOR_MT9V111:
+ gamma_base = gamma_spec_1;
+ break;
+ case SENSOR_SP80708:
+ gamma_base = gamma_spec_2;
+ break;
+ default:
+ gamma_base = gamma_def;
+ break;
+ }
+
+ for (i = 0; i < sizeof gamma; i++)
+ gamma[i] = gamma_base[i]
+ + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
+ reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
+}
+
static void setautogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
return;
+ switch (sd->sensor) {
+ case SENSOR_OV7630:
+ case SENSOR_OV7648: {
+ u8 comb;
+
+ if (sd->sensor == SENSOR_OV7630)
+ comb = 0xc0;
+ else
+ comb = 0xa0;
+ if (sd->autogain)
+ comb |= 0x02;
+ i2c_w1(&sd->gspca_dev, 0x13, comb);
+ return;
+ }
+ }
if (sd->autogain)
sd->ag_cnt = AG_CNT_START;
else
sd->ag_cnt = -1;
}
+/* ov7630/ov7648 only */
static void setvflip(struct sd *sd)
{
- i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
- sd->vflip ? 0x82 : 0x02);
+ u8 comn;
+
+ if (sd->sensor == SENSOR_OV7630)
+ comn = 0x02;
+ else
+ comn = 0x06;
+ if (sd->vflip)
+ comn |= 0x80;
+ i2c_w1(&sd->gspca_dev, 0x75, comn);
}
static void setinfrared(struct sd *sd)
@@ -1262,20 +1601,63 @@ static void setinfrared(struct sd *sd)
sd->infrared ? 0x66 : 0x64);
}
+static void setjpegqual(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, sc;
+
+ if (sd->jpegqual < 50)
+ sc = 5000 / sd->jpegqual;
+ else
+ sc = 200 - sd->jpegqual * 2;
+#if USB_BUF_SZ < 64
+#error "No room enough in usb_buf for quantization table"
+#endif
+ for (i = 0; i < 64; i++)
+ gspca_dev->usb_buf[i] =
+ (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x0100, 0,
+ gspca_dev->usb_buf, 64,
+ 500);
+ for (i = 0; i < 64; i++)
+ gspca_dev->usb_buf[i] =
+ (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x0140, 0,
+ gspca_dev->usb_buf, 64,
+ 500);
+
+ sd->reg18 ^= 0x40;
+ reg_w1(gspca_dev, 0x18, sd->reg18);
+}
+
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
- __u8 reg1, reg17, reg18;
- const __u8 *sn9c1xx;
+ u8 reg1, reg17;
+ const u8 *sn9c1xx;
int mode;
- static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
- static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
- static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
- static const __u8 CE_ov76xx[] =
+ static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
+ static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
+ static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
+ static const u8 CE_ov76xx[] =
{ 0x32, 0xdd, 0x32, 0xdd };
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
sn9c1xx = sn_tb[(int) sd->sensor];
configure_gpio(gspca_dev, sn9c1xx);
@@ -1292,6 +1674,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0xc9, 0x3c);
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg17 = 0xe0;
+ break;
case SENSOR_OV7630:
reg17 = 0xe2;
break;
@@ -1315,14 +1700,24 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
- reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
+
+ setgamma(gspca_dev);
+
for (i = 0; i < 8; i++)
reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg_w1(gspca_dev, 0x9a, 0x07);
+ reg_w1(gspca_dev, 0x99, 0x59);
+ break;
case SENSOR_OV7648:
reg_w1(gspca_dev, 0x9a, 0x0a);
reg_w1(gspca_dev, 0x99, 0x60);
break;
+ case SENSOR_SP80708:
+ reg_w1(gspca_dev, 0x9a, 0x05);
+ reg_w1(gspca_dev, 0x99, 0x59);
+ break;
case SENSOR_OV7660:
if (sd->bridge == BRIDGE_SN9C120) {
reg_w1(gspca_dev, 0x9a, 0x05);
@@ -1358,6 +1753,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* reg1 = 0x06; * 640 clk 24Mz (done) */
}
break;
+ case SENSOR_MT9V111:
+ mt9v111_InitSensor(gspca_dev);
+ if (mode) {
+ reg1 = 0x04; /* 320 clk 48Mhz */
+ } else {
+/* reg1 = 0x06; * 640 clk 24Mz (done) */
+ reg17 = 0xc2;
+ }
+ break;
case SENSOR_OM6802:
om6802_InitSensor(gspca_dev);
reg17 = 0x64; /* 640 MCKSIZE */
@@ -1373,8 +1777,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg17 = 0x21;
/* reg1 = 0x42; * 42 - 46? */
break;
- default:
-/* case SENSOR_OV7660: */
+ case SENSOR_OV7660:
ov7660_InitSensor(gspca_dev);
if (sd->bridge == BRIDGE_SN9C120) {
if (mode) { /* 320x240 - 160x120 */
@@ -1387,6 +1790,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
* inverse power down */
}
break;
+ default:
+/* case SENSOR_SP80708: */
+ sp80708_InitSensor(gspca_dev);
+ if (mode) {
+/*?? reg1 = 0x04; * 320 clk 48Mhz */
+ } else {
+ reg1 = 0x46; /* 640 clk 48Mz */
+ reg17 = 0xa2;
+ }
+ break;
}
reg_w(gspca_dev, 0xc0, C0, 6);
reg_w(gspca_dev, 0xca, CA, 4);
@@ -1403,20 +1816,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
/* here change size mode 0 -> VGA; 1 -> CIF */
- reg18 = sn9c1xx[0x18] | (mode << 4);
- reg_w1(gspca_dev, 0x18, reg18 | 0x40);
-
- reg_w(gspca_dev, 0x100, qtable4, 0x40);
- reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
-
- reg_w1(gspca_dev, 0x18, reg18);
+ sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
+ reg_w1(gspca_dev, 0x18, sd->reg18);
+ setjpegqual(gspca_dev);
reg_w1(gspca_dev, 0x17, reg17);
reg_w1(gspca_dev, 0x01, reg1);
switch (sd->sensor) {
- case SENSOR_MI0360:
- setinfrared(sd);
- break;
case SENSOR_OV7630:
setvflip(sd);
break;
@@ -1430,14 +1836,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 stophv7131[] =
+ static const u8 stophv7131[] =
{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
- static const __u8 stopmi0360[] =
+ static const u8 stopmi0360[] =
{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
- static const __u8 stopov7648[] =
+ static const u8 stopov7648[] =
{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
- __u8 data;
- const __u8 *sn9c1xx;
+ u8 data;
+ const u8 *sn9c1xx;
data = 0x0b;
switch (sd->sensor) {
@@ -1452,6 +1858,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
case SENSOR_OV7648:
i2c_w8(gspca_dev, stopov7648);
/* fall thru */
+ case SENSOR_MT9V111:
case SENSOR_OV7630:
data = 0x29;
break;
@@ -1468,13 +1875,20 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0xf1, 0x00);
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void do_autogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int delta;
int expotimes;
- __u8 luma_mean = 130;
- __u8 luma_delta = 20;
+ u8 luma_mean = 130;
+ u8 luma_delta = 20;
/* Thanks S., without your advice, autobright should not work :) */
if (sd->ag_cnt < 0)
@@ -1499,6 +1913,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
default:
/* case SENSOR_MO4000: */
/* case SENSOR_MI0360: */
+/* case SENSOR_MT9V111: */
/* case SENSOR_OM6802: */
expotimes = sd->exposure;
expotimes += (luma_mean - delta) >> 6;
@@ -1516,7 +1931,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
/* This function is run at interrupt level. */
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1550,7 +1965,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
if (gspca_dev->last_packet_type == LAST_PACKET) {
/* put the JPEG 422 header */
- jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
}
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
@@ -1645,6 +2061,24 @@ static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming)
+ setgamma(gspca_dev);
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gamma;
+ return 0;
+}
+
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1699,6 +2133,34 @@ static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1708,8 +2170,11 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.dq_callback = do_autogain,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1724,9 +2189,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
#endif
{USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
{USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
-#endif
{USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
@@ -1764,10 +2227,10 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
+#endif
{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
-#endif
- {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
+ {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1794,8 +2257,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
info("registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 942f04cd44d..6f38fa6d86b 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -38,8 +38,11 @@ struct sd {
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
+ u8 quality;
+#define QUALITY_MIN 70
+#define QUALITY_MAX 95
+#define QUALITY_DEF 85
- char qindex;
char subtype;
#define AgfaCl20 0
#define AiptekPocketDV 1
@@ -56,6 +59,8 @@ struct sd {
#define Optimedia 12
#define PalmPixDC85 13
#define ToptroIndus 14
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -629,7 +634,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
sd->subtype = id->driver_info;
if (sd->subtype != LogitechClickSmart310) {
cam->cam_mode = vga_mode;
@@ -638,10 +642,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
- sd->qindex = 5;
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -667,6 +671,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
__u8 Data;
__u8 xmult, ymult;
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
if (sd->subtype == LogitechClickSmart310) {
xmult = 0x16;
ymult = 0x12;
@@ -713,7 +723,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
write_vector(gspca_dev, spca500_visual_defaults);
spca500_setmode(gspca_dev, xmult, ymult);
/* enable drop packet */
- reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ if (err < 0)
PDEBUG(D_ERR, "failed to enable drop packet");
reg_w(gspca_dev, 0x00, 0x8880, 3);
err = spca50x_setup_qtable(gspca_dev,
@@ -881,6 +892,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0]);
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -901,7 +919,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
data += SPCA500_OFFSET_DATA;
len -= SPCA500_OFFSET_DATA;
@@ -937,16 +956,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
(__u8) (sd->brightness - 128));
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
- if (ret >= 0)
- sd->brightness = ret + 128;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -954,16 +963,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
- if (ret >= 0)
- sd->contrast = ret;
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -971,16 +970,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
- if (ret >= 0)
- sd->colors = ret;
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -995,7 +984,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1014,7 +1002,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -1033,11 +1020,38 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1047,7 +1061,10 @@ static struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1093,8 +1110,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 82e3e3e2ada..d48b27c648c 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1883,10 +1883,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1897,10 +1893,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
sd->contrast & 0xff);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1908,10 +1900,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
-}
-
static void setblue_balance(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1934,7 +1922,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
sd->subtype = id->driver_info;
@@ -2084,7 +2071,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -2103,7 +2089,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -2122,7 +2107,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -2211,8 +2195,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 2a33a29010e..2acec58b1b9 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -31,9 +31,9 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- unsigned char brightness;
+ u8 brightness;
- char subtype;
+ u8 subtype;
#define IntelPCCameraPro 0
#define Nxultra 1
};
@@ -43,7 +43,6 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
@@ -52,7 +51,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 255,
.step = 1,
- .default_value = 127,
+#define BRIGHTNESS_DEF 127
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
@@ -64,12 +64,12 @@ static const struct v4l2_pix_format vga_mode[] = {
.bytesperline = 160,
.sizeimage = 160 * 120 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 5},
+ .priv = 4},
{176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
.bytesperline = 176,
.sizeimage = 176 * 144 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 4},
+ .priv = 3},
{320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 3 / 2,
@@ -93,6 +93,7 @@ static const struct v4l2_pix_format vga_mode[] = {
#define SPCA50X_USB_CTRL 0x00 /* spca505 */
#define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */
+
#define SPCA50X_REG_GLOBAL 0x03 /* spca505 */
#define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */
#define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */
@@ -101,230 +102,230 @@ static const struct v4l2_pix_format vga_mode[] = {
#define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */
#define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */
+/* Image format and compression control */
+#define SPCA50X_REG_COMPRESS 0x04
+
/*
* Data to initialize a SPCA505. Common to the CCD and external modes
*/
-static const __u16 spca505_init_data[][3] = {
- /* line bmRequest,value,index */
- /* 1819 */
+static const u8 spca505_init_data[][3] = {
+ /* bmRequest,value,index */
{SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3},
/* Sensor reset */
- /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
- /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
+ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
+ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
/* Block USB reset */
- /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL,
- SPCA50X_GLOBAL_MISC0},
+ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0},
- /* 1831 */ {0x5, 0x01, 0x10},
+ {0x05, 0x01, 0x10},
/* Maybe power down some stuff */
- /* 1834 */ {0x5, 0x0f, 0x11},
+ {0x05, 0x0f, 0x11},
/* Setup internal CCD ? */
- /* 1837 */ {0x6, 0x10, 0x08},
- /* 1840 */ {0x6, 0x00, 0x09},
- /* 1843 */ {0x6, 0x00, 0x0a},
- /* 1846 */ {0x6, 0x00, 0x0b},
- /* 1849 */ {0x6, 0x10, 0x0c},
- /* 1852 */ {0x6, 0x00, 0x0d},
- /* 1855 */ {0x6, 0x00, 0x0e},
- /* 1858 */ {0x6, 0x00, 0x0f},
- /* 1861 */ {0x6, 0x10, 0x10},
- /* 1864 */ {0x6, 0x02, 0x11},
- /* 1867 */ {0x6, 0x00, 0x12},
- /* 1870 */ {0x6, 0x04, 0x13},
- /* 1873 */ {0x6, 0x02, 0x14},
- /* 1876 */ {0x6, 0x8a, 0x51},
- /* 1879 */ {0x6, 0x40, 0x52},
- /* 1882 */ {0x6, 0xb6, 0x53},
- /* 1885 */ {0x6, 0x3d, 0x54},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
{}
};
/*
* Data to initialize the camera using the internal CCD
*/
-static const __u16 spca505_open_data_ccd[][3] = {
- /* line bmRequest,value,index */
+static const u8 spca505_open_data_ccd[][3] = {
+ /* bmRequest,value,index */
/* Internal CCD data set */
- /* 1891 */ {0x3, 0x04, 0x01},
+ {0x03, 0x04, 0x01},
/* This could be a reset */
- /* 1894 */ {0x3, 0x00, 0x01},
+ {0x03, 0x00, 0x01},
/* Setup compression and image registers. 0x6 and 0x7 seem to be
related to H&V hold, and are resolution mode specific */
- /* 1897 */ {0x4, 0x10, 0x01},
+ {0x04, 0x10, 0x01},
/* DIFF(0x50), was (0x10) */
- /* 1900 */ {0x4, 0x00, 0x04},
- /* 1903 */ {0x4, 0x00, 0x05},
- /* 1906 */ {0x4, 0x20, 0x06},
- /* 1909 */ {0x4, 0x20, 0x07},
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x20, 0x06},
+ {0x04, 0x20, 0x07},
- /* 1912 */ {0x8, 0x0a, 0x00},
+ {0x08, 0x0a, 0x00},
/* DIFF (0x4a), was (0xa) */
- /* 1915 */ {0x5, 0x00, 0x10},
- /* 1918 */ {0x5, 0x00, 0x11},
- /* 1921 */ {0x5, 0x00, 0x00},
+ {0x05, 0x00, 0x10},
+ {0x05, 0x00, 0x11},
+ {0x05, 0x00, 0x00},
/* DIFF not written */
- /* 1924 */ {0x5, 0x00, 0x01},
+ {0x05, 0x00, 0x01},
/* DIFF not written */
- /* 1927 */ {0x5, 0x00, 0x02},
+ {0x05, 0x00, 0x02},
/* DIFF not written */
- /* 1930 */ {0x5, 0x00, 0x03},
+ {0x05, 0x00, 0x03},
/* DIFF not written */
- /* 1933 */ {0x5, 0x00, 0x04},
+ {0x05, 0x00, 0x04},
/* DIFF not written */
- /* 1936 */ {0x5, 0x80, 0x05},
+ {0x05, 0x80, 0x05},
/* DIFF not written */
- /* 1939 */ {0x5, 0xe0, 0x06},
+ {0x05, 0xe0, 0x06},
/* DIFF not written */
- /* 1942 */ {0x5, 0x20, 0x07},
+ {0x05, 0x20, 0x07},
/* DIFF not written */
- /* 1945 */ {0x5, 0xa0, 0x08},
+ {0x05, 0xa0, 0x08},
/* DIFF not written */
- /* 1948 */ {0x5, 0x0, 0x12},
+ {0x05, 0x0, 0x12},
/* DIFF not written */
- /* 1951 */ {0x5, 0x02, 0x0f},
+ {0x05, 0x02, 0x0f},
/* DIFF not written */
- /* 1954 */ {0x5, 0x10, 0x46},
+ {0x05, 0x10, 0x46},
/* DIFF not written */
- /* 1957 */ {0x5, 0x8, 0x4a},
+ {0x05, 0x8, 0x4a},
/* DIFF not written */
- /* 1960 */ {0x3, 0x08, 0x03},
+ {0x03, 0x08, 0x03},
/* DIFF (0x3,0x28,0x3) */
- /* 1963 */ {0x3, 0x08, 0x01},
- /* 1966 */ {0x3, 0x0c, 0x03},
+ {0x03, 0x08, 0x01},
+ {0x03, 0x0c, 0x03},
/* DIFF not written */
- /* 1969 */ {0x3, 0x21, 0x00},
+ {0x03, 0x21, 0x00},
/* DIFF (0x39) */
/* Extra block copied from init to hopefully ensure CCD is in a sane state */
- /* 1837 */ {0x6, 0x10, 0x08},
- /* 1840 */ {0x6, 0x00, 0x09},
- /* 1843 */ {0x6, 0x00, 0x0a},
- /* 1846 */ {0x6, 0x00, 0x0b},
- /* 1849 */ {0x6, 0x10, 0x0c},
- /* 1852 */ {0x6, 0x00, 0x0d},
- /* 1855 */ {0x6, 0x00, 0x0e},
- /* 1858 */ {0x6, 0x00, 0x0f},
- /* 1861 */ {0x6, 0x10, 0x10},
- /* 1864 */ {0x6, 0x02, 0x11},
- /* 1867 */ {0x6, 0x00, 0x12},
- /* 1870 */ {0x6, 0x04, 0x13},
- /* 1873 */ {0x6, 0x02, 0x14},
- /* 1876 */ {0x6, 0x8a, 0x51},
- /* 1879 */ {0x6, 0x40, 0x52},
- /* 1882 */ {0x6, 0xb6, 0x53},
- /* 1885 */ {0x6, 0x3d, 0x54},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
/* End of extra block */
- /* 1972 */ {0x6, 0x3f, 0x1},
+ {0x06, 0x3f, 0x1},
/* Block skipped */
- /* 1975 */ {0x6, 0x10, 0x02},
- /* 1978 */ {0x6, 0x64, 0x07},
- /* 1981 */ {0x6, 0x10, 0x08},
- /* 1984 */ {0x6, 0x00, 0x09},
- /* 1987 */ {0x6, 0x00, 0x0a},
- /* 1990 */ {0x6, 0x00, 0x0b},
- /* 1993 */ {0x6, 0x10, 0x0c},
- /* 1996 */ {0x6, 0x00, 0x0d},
- /* 1999 */ {0x6, 0x00, 0x0e},
- /* 2002 */ {0x6, 0x00, 0x0f},
- /* 2005 */ {0x6, 0x10, 0x10},
- /* 2008 */ {0x6, 0x02, 0x11},
- /* 2011 */ {0x6, 0x00, 0x12},
- /* 2014 */ {0x6, 0x04, 0x13},
- /* 2017 */ {0x6, 0x02, 0x14},
- /* 2020 */ {0x6, 0x8a, 0x51},
- /* 2023 */ {0x6, 0x40, 0x52},
- /* 2026 */ {0x6, 0xb6, 0x53},
- /* 2029 */ {0x6, 0x3d, 0x54},
- /* 2032 */ {0x6, 0x60, 0x57},
- /* 2035 */ {0x6, 0x20, 0x58},
- /* 2038 */ {0x6, 0x15, 0x59},
- /* 2041 */ {0x6, 0x05, 0x5a},
-
- /* 2044 */ {0x5, 0x01, 0xc0},
- /* 2047 */ {0x5, 0x10, 0xcb},
- /* 2050 */ {0x5, 0x80, 0xc1},
+ {0x06, 0x10, 0x02},
+ {0x06, 0x64, 0x07},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
+ {0x06, 0x60, 0x57},
+ {0x06, 0x20, 0x58},
+ {0x06, 0x15, 0x59},
+ {0x06, 0x05, 0x5a},
+
+ {0x05, 0x01, 0xc0},
+ {0x05, 0x10, 0xcb},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2053 */ {0x5, 0x0, 0xc2},
+ {0x05, 0x0, 0xc2},
/* 4 was 0 */
- /* 2056 */ {0x5, 0x00, 0xca},
- /* 2059 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2062 */ {0x5, 0x04, 0xc2},
- /* 2065 */ {0x5, 0x00, 0xca},
- /* 2068 */ {0x5, 0x0, 0xc1},
+ {0x05, 0x04, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x0, 0xc1},
/* */
- /* 2071 */ {0x5, 0x00, 0xc2},
- /* 2074 */ {0x5, 0x00, 0xca},
- /* 2077 */ {0x5, 0x40, 0xc1},
+ {0x05, 0x00, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x40, 0xc1},
/* */
- /* 2080 */ {0x5, 0x17, 0xc2},
- /* 2083 */ {0x5, 0x00, 0xca},
- /* 2086 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x17, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2089 */ {0x5, 0x06, 0xc2},
- /* 2092 */ {0x5, 0x00, 0xca},
- /* 2095 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x06, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2098 */ {0x5, 0x04, 0xc2},
- /* 2101 */ {0x5, 0x00, 0xca},
+ {0x05, 0x04, 0xc2},
+ {0x05, 0x00, 0xca},
- /* 2104 */ {0x3, 0x4c, 0x3},
- /* 2107 */ {0x3, 0x18, 0x1},
+ {0x03, 0x4c, 0x3},
+ {0x03, 0x18, 0x1},
- /* 2110 */ {0x6, 0x70, 0x51},
- /* 2113 */ {0x6, 0xbe, 0x53},
- /* 2116 */ {0x6, 0x71, 0x57},
- /* 2119 */ {0x6, 0x20, 0x58},
- /* 2122 */ {0x6, 0x05, 0x59},
- /* 2125 */ {0x6, 0x15, 0x5a},
+ {0x06, 0x70, 0x51},
+ {0x06, 0xbe, 0x53},
+ {0x06, 0x71, 0x57},
+ {0x06, 0x20, 0x58},
+ {0x06, 0x05, 0x59},
+ {0x06, 0x15, 0x5a},
- /* 2128 */ {0x4, 0x00, 0x08},
+ {0x04, 0x00, 0x08},
/* Compress = OFF (0x1 to turn on) */
- /* 2131 */ {0x4, 0x12, 0x09},
- /* 2134 */ {0x4, 0x21, 0x0a},
- /* 2137 */ {0x4, 0x10, 0x0b},
- /* 2140 */ {0x4, 0x21, 0x0c},
- /* 2143 */ {0x4, 0x05, 0x00},
+ {0x04, 0x12, 0x09},
+ {0x04, 0x21, 0x0a},
+ {0x04, 0x10, 0x0b},
+ {0x04, 0x21, 0x0c},
+ {0x04, 0x05, 0x00},
/* was 5 (Image Type ? ) */
- /* 2146 */ {0x4, 0x00, 0x01},
-
- /* 2149 */ {0x6, 0x3f, 0x01},
-
- /* 2152 */ {0x4, 0x00, 0x04},
- /* 2155 */ {0x4, 0x00, 0x05},
- /* 2158 */ {0x4, 0x40, 0x06},
- /* 2161 */ {0x4, 0x40, 0x07},
-
- /* 2164 */ {0x6, 0x1c, 0x17},
- /* 2167 */ {0x6, 0xe2, 0x19},
- /* 2170 */ {0x6, 0x1c, 0x1b},
- /* 2173 */ {0x6, 0xe2, 0x1d},
- /* 2176 */ {0x6, 0xaa, 0x1f},
- /* 2179 */ {0x6, 0x70, 0x20},
-
- /* 2182 */ {0x5, 0x01, 0x10},
- /* 2185 */ {0x5, 0x00, 0x11},
- /* 2188 */ {0x5, 0x01, 0x00},
- /* 2191 */ {0x5, 0x05, 0x01},
- /* 2194 */ {0x5, 0x00, 0xc1},
+ {0x04, 0x00, 0x01},
+
+ {0x06, 0x3f, 0x01},
+
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x40, 0x06},
+ {0x04, 0x40, 0x07},
+
+ {0x06, 0x1c, 0x17},
+ {0x06, 0xe2, 0x19},
+ {0x06, 0x1c, 0x1b},
+ {0x06, 0xe2, 0x1d},
+ {0x06, 0xaa, 0x1f},
+ {0x06, 0x70, 0x20},
+
+ {0x05, 0x01, 0x10},
+ {0x05, 0x00, 0x11},
+ {0x05, 0x01, 0x00},
+ {0x05, 0x05, 0x01},
+ {0x05, 0x00, 0xc1},
/* */
- /* 2197 */ {0x5, 0x00, 0xc2},
- /* 2200 */ {0x5, 0x00, 0xca},
+ {0x05, 0x00, 0xc2},
+ {0x05, 0x00, 0xca},
- /* 2203 */ {0x6, 0x70, 0x51},
- /* 2206 */ {0x6, 0xbe, 0x53},
+ {0x06, 0x70, 0x51},
+ {0x06, 0xbe, 0x53},
{}
};
/*
- Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
+ * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
* SPCA505b chip based cameras initialization data
- *
*/
/* jfm */
#define initial_brightness 0x7f /* 0x0(white)-0xff(black) */
@@ -332,7 +333,7 @@ static const __u16 spca505_open_data_ccd[][3] = {
/*
* Data to initialize a SPCA505. Common to the CCD and external modes
*/
-static const __u16 spca505b_init_data[][3] = {
+static const u8 spca505b_init_data[][3] = {
/* start */
{0x02, 0x00, 0x00}, /* init */
{0x02, 0x00, 0x01},
@@ -396,7 +397,7 @@ static const __u16 spca505b_init_data[][3] = {
/*
* Data to initialize the camera using the internal CCD
*/
-static const __u16 spca505b_open_data_ccd[][3] = {
+static const u8 spca505b_open_data_ccd[][3] = {
/* {0x02,0x00,0x00}, */
{0x03, 0x04, 0x01}, /* rst */
@@ -426,7 +427,7 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x05, 0x00, 0x12},
{0x05, 0x6f, 0x00},
{0x05, initial_brightness >> 6, 0x00},
- {0x05, initial_brightness << 2, 0x01},
+ {0x05, (initial_brightness << 2) & 0xff, 0x01},
{0x05, 0x00, 0x02},
{0x05, 0x01, 0x03},
{0x05, 0x00, 0x04},
@@ -436,7 +437,7 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x05, 0xa0, 0x08},
{0x05, 0x00, 0x12},
{0x05, 0x02, 0x0f},
- {0x05, 128, 0x14}, /* max exposure off (0=on) */
+ {0x05, 0x80, 0x14}, /* max exposure off (0=on) */
{0x05, 0x01, 0xb0},
{0x05, 0x01, 0xbf},
{0x03, 0x02, 0x06},
@@ -560,26 +561,26 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x06, 0x32, 0x20},
{0x05, initial_brightness >> 6, 0x00},
- {0x05, initial_brightness << 2, 0x01},
+ {0x05, (initial_brightness << 2) & 0xff, 0x01},
{0x05, 0x06, 0xc1},
{0x05, 0x58, 0xc2},
- {0x05, 0x0, 0xca},
- {0x05, 0x0, 0x11},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x00, 0x11},
{}
};
static int reg_write(struct usb_device *dev,
- __u16 reg, __u16 index, __u16 value)
+ u16 req, u16 index, u16 value)
{
int ret;
ret = usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
- reg,
+ req,
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
- PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x",
- reg, index, value, ret);
+ PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
+ req, index, value, ret);
if (ret < 0)
PDEBUG(D_ERR, "reg write: error %d", ret);
return ret;
@@ -587,42 +588,34 @@ static int reg_write(struct usb_device *dev,
/* returns: negative is error, pos or zero is data */
static int reg_read(struct gspca_dev *gspca_dev,
- __u16 reg, /* bRequest */
- __u16 index, /* wIndex */
- __u16 length) /* wLength (1 or 2 only) */
+ u16 req, /* bRequest */
+ u16 index) /* wIndex */
{
int ret;
- gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
- reg,
+ req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- (__u16) 0, /* value */
- (__u16) index,
- gspca_dev->usb_buf, length,
+ 0, /* value */
+ index,
+ gspca_dev->usb_buf, 2,
500); /* timeout */
- if (ret < 0) {
- PDEBUG(D_ERR, "reg_read err %d", ret);
- return -1;
- }
+ if (ret < 0)
+ return ret;
return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
}
static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
+ const u8 data[][3])
{
struct usb_device *dev = gspca_dev->dev;
int ret, i = 0;
- while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
+ while (data[i][0] != 0) {
ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
- if (ret < 0) {
- PDEBUG(D_ERR,
- "Register write failed for 0x%x,0x%x,0x%x",
- data[i][0], data[i][1], data[i][2]);
+ if (ret < 0)
return ret;
- }
i++;
}
return 0;
@@ -636,14 +629,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
sd->subtype = id->driver_info;
if (sd->subtype != IntelPCCameraPro)
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ cam->nmodes = ARRAY_SIZE(vga_mode);
else /* no 640x480 for IntelPCCameraPro */
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1;
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
+ sd->brightness = BRIGHTNESS_DEF;
if (sd->subtype == Nxultra) {
if (write_vector(gspca_dev, spca505b_init_data))
@@ -658,81 +650,71 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
+ return 0;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
struct sd *sd = (struct sd *) gspca_dev;
- int ret;
+ u8 brightness = sd->brightness;
+
+ reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6);
+ reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2);
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int ret, mode;
+ static u8 mode_tb[][3] = {
+ /* r00 r06 r07 */
+ {0x00, 0x10, 0x10}, /* 640x480 */
+ {0x01, 0x1a, 0x1a}, /* 352x288 */
+ {0x02, 0x1c, 0x1d}, /* 320x240 */
+ {0x04, 0x34, 0x34}, /* 176x144 */
+ {0x05, 0x40, 0x40} /* 160x120 */
+ };
- PDEBUG(D_STREAM, "Initializing SPCA505");
if (sd->subtype == Nxultra)
write_vector(gspca_dev, spca505b_open_data_ccd);
else
write_vector(gspca_dev, spca505_open_data_ccd);
- ret = reg_read(gspca_dev, 6, 0x16, 2);
+ ret = reg_read(gspca_dev, 0x06, 0x16);
if (ret < 0) {
- PDEBUG(D_ERR|D_STREAM,
- "register read failed for after vector read err = %d",
+ PDEBUG(D_ERR|D_CONF,
+ "register read failed err: %d",
ret);
- return -EIO;
+ return ret;
}
- PDEBUG(D_STREAM,
- "After vector read returns : 0x%x should be 0x0101",
- ret & 0xffff);
-
- ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a);
- if (ret < 0) {
- PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d",
- ret);
- return -EIO;
+ if (ret != 0x0101) {
+ PDEBUG(D_ERR|D_CONF,
+ "After vector read returns 0x%04x should be 0x0101",
+ ret);
}
- reg_write(gspca_dev->dev, 5, 0xc2, 18);
- return 0;
-}
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
+ ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a);
+ if (ret < 0)
+ return ret;
+ reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12);
/* necessary because without it we can see stream
* only once after loading module */
/* stopping usb registers Tomasz change */
- reg_write(dev, 0x02, 0x0, 0x0);
- switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- case 0:
- reg_write(dev, 0x04, 0x00, 0x00);
- reg_write(dev, 0x04, 0x06, 0x10);
- reg_write(dev, 0x04, 0x07, 0x10);
- break;
- case 1:
- reg_write(dev, 0x04, 0x00, 0x01);
- reg_write(dev, 0x04, 0x06, 0x1a);
- reg_write(dev, 0x04, 0x07, 0x1a);
- break;
- case 2:
- reg_write(dev, 0x04, 0x00, 0x02);
- reg_write(dev, 0x04, 0x06, 0x1c);
- reg_write(dev, 0x04, 0x07, 0x1d);
- break;
- case 4:
- reg_write(dev, 0x04, 0x00, 0x04);
- reg_write(dev, 0x04, 0x06, 0x34);
- reg_write(dev, 0x04, 0x07, 0x34);
- break;
- default:
-/* case 5: */
- reg_write(dev, 0x04, 0x00, 0x05);
- reg_write(dev, 0x04, 0x06, 0x40);
- reg_write(dev, 0x04, 0x07, 0x40);
- break;
- }
-/* Enable ISO packet machine - should we do this here or in ISOC init ? */
+ reg_write(dev, 0x02, 0x00, 0x00);
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]);
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]);
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]);
+
ret = reg_write(dev, SPCA50X_REG_USB,
SPCA50X_USB_CTRL,
SPCA50X_CUSB_ENABLE);
-/* reg_write(dev, 0x5, 0x0, 0x0); */
-/* reg_write(dev, 0x5, 0x0, 0x1); */
-/* reg_write(dev, 0x5, 0x11, 0x2); */
+ setbrightness(gspca_dev);
+
return ret;
}
@@ -750,15 +732,15 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
/* This maybe reset or power control */
reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
- reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
- reg_write(gspca_dev->dev, 0x03, 0x00, 0x1);
- reg_write(gspca_dev->dev, 0x05, 0x10, 0x1);
- reg_write(gspca_dev->dev, 0x05, 0x11, 0xf);
+ reg_write(gspca_dev->dev, 0x03, 0x01, 0x00);
+ reg_write(gspca_dev->dev, 0x03, 0x00, 0x01);
+ reg_write(gspca_dev->dev, 0x05, 0x10, 0x01);
+ reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f);
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
switch (data[0]) {
@@ -771,7 +753,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data, len);
break;
case 0xff: /* drop */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
break;
default:
data += 1;
@@ -782,24 +763,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
}
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- __u8 brightness = sd->brightness;
- reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6);
- reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2);
-
-}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = 255
- - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2)
- + (reg_read(gspca_dev, 5, 0x0, 1) << 6));
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -814,7 +777,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -863,8 +825,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 96e2512e062..3a0c893f942 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -193,24 +193,6 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
}
}
-static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg)
-{
- int retry = 60;
-
- reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
- reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
- reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002);
- while (--retry) {
- reg_r(gspca_dev, 0x07, 0x0003, 2);
- if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
- break;
- }
- if (retry == 0)
- return -1;
- reg_r(gspca_dev, 0x07, 0x0000, 1);
- return gspca_dev->usb_buf[0];
-}
-
static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
__u16 norme,
__u16 channel)
@@ -303,7 +285,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
@@ -596,13 +577,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright);
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -612,13 +586,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast);
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -628,13 +595,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation);
-}
-
static void sethue(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -644,13 +604,6 @@ static void sethue(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void gethue(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue);
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -665,7 +618,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -684,7 +636,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -703,7 +654,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -722,7 +672,6 @@ static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- gethue(gspca_dev);
*val = sd->hue;
return 0;
}
@@ -772,8 +721,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index be5d740a315..adacf843766 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -101,8 +101,7 @@ static const struct v4l2_pix_format sif_mode[] = {
* Initialization data: this is the first set-up data written to the
* device (before the open data).
*/
-static const __u16 spca508_init_data[][3] =
-#define IGN(x) /* nothing */
+static const u16 spca508_init_data[][2] =
{
/* line URB value, index */
/* 44274 1804 */ {0x0000, 0x870b},
@@ -589,11 +588,10 @@ static const __u16 spca508_init_data[][3] =
{}
};
-
/*
* Initialization data for Intel EasyPC Camera CS110
*/
-static const __u16 spca508cs110_init_data[][3] = {
+static const u16 spca508cs110_init_data[][2] = {
{0x0000, 0x870b}, /* Reset CTL3 */
{0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
{0x0000, 0x8111}, /* Normal operation on reset */
@@ -677,7 +675,7 @@ static const __u16 spca508cs110_init_data[][3] = {
{}
};
-static const __u16 spca508_sightcam_init_data[][3] = {
+static const u16 spca508_sightcam_init_data[][2] = {
/* This line seems to setup the frame/canvas */
/*368 */ {0x000f, 0x8402},
@@ -760,7 +758,7 @@ static const __u16 spca508_sightcam_init_data[][3] = {
{}
};
-static const __u16 spca508_sightcam2_init_data[][3] = {
+static const u16 spca508_sightcam2_init_data[][2] = {
/* 35 */ {0x0020, 0x8112},
/* 36 */ {0x000f, 0x8402},
@@ -1107,7 +1105,7 @@ static const __u16 spca508_sightcam2_init_data[][3] = {
/*
* Initialization data for Creative Webcam Vista
*/
-static const __u16 spca508_vista_init_data[][3] = {
+static const u16 spca508_vista_init_data[][2] = {
{0x0008, 0x8200}, /* Clear register */
{0x0000, 0x870b}, /* Reset CTL3 */
{0x0020, 0x8112}, /* Video Drop packet enable */
@@ -1309,18 +1307,18 @@ static const __u16 spca508_vista_init_data[][3] = {
{0x0050, 0x8703},
{0x0002, 0x8704}, /* External input CKIx1 */
- {0x0001, 0x870C}, /* Select CKOx2 output */
- {0x009A, 0x8600}, /* Line memory Read Counter (L) */
+ {0x0001, 0x870c}, /* Select CKOx2 output */
+ {0x009a, 0x8600}, /* Line memory Read Counter (L) */
{0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
{0x0023, 0x8601},
{0x0010, 0x8602},
- {0x000A, 0x8603},
+ {0x000a, 0x8603},
{0x009A, 0x8600},
- {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */
- {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */
- {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */
- {0x0048, 0x865E}, /* Vertical valid lines window (L) */
- {0x0000, 0x865F},
+ {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
+ {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */
+ {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */
+ {0x0048, 0x865e}, /* Vertical valid lines window (L) */
+ {0x0000, 0x865f},
{0x0006, 0x8660},
/* Enable nibble data input, select nibble input order */
@@ -1328,63 +1326,63 @@ static const __u16 spca508_vista_init_data[][3] = {
{0x0013, 0x8608}, /* A11 Coeficients for color correction */
{0x0028, 0x8609},
/* Note: these values are confirmed at the end of array */
- {0x0005, 0x860A}, /* ... */
- {0x0025, 0x860B},
- {0x00E1, 0x860C},
- {0x00FA, 0x860D},
- {0x00F4, 0x860E},
- {0x00E8, 0x860F},
+ {0x0005, 0x860a}, /* ... */
+ {0x0025, 0x860b},
+ {0x00e1, 0x860c},
+ {0x00fa, 0x860D},
+ {0x00f4, 0x860e},
+ {0x00e8, 0x860f},
{0x0025, 0x8610}, /* A33 Coef. */
- {0x00FC, 0x8611}, /* White balance offset: R */
+ {0x00fc, 0x8611}, /* White balance offset: R */
{0x0001, 0x8612}, /* White balance offset: Gr */
- {0x00FE, 0x8613}, /* White balance offset: B */
+ {0x00fe, 0x8613}, /* White balance offset: B */
{0x0000, 0x8614}, /* White balance offset: Gb */
{0x0064, 0x8651}, /* R gain for white balance (L) */
{0x0040, 0x8652}, /* Gr gain for white balance (L) */
{0x0066, 0x8653}, /* B gain for white balance (L) */
{0x0040, 0x8654}, /* Gb gain for white balance (L) */
- {0x0001, 0x863F}, /* Enable fixed gamma correction */
+ {0x0001, 0x863f}, /* Enable fixed gamma correction */
- {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */
+ {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */
/* UV division: UV no change, Enable New edge enhancement */
{0x0018, 0x8657}, /* Edge gain high threshold */
{0x0020, 0x8658}, /* Edge gain low threshold */
{0x000A, 0x8659}, /* Edge bandwidth high threshold */
- {0x0005, 0x865A}, /* Edge bandwidth low threshold */
+ {0x0005, 0x865a}, /* Edge bandwidth low threshold */
{0x0064, 0x8607}, /* UV filter enable */
{0x0016, 0x8660},
- {0x0000, 0x86B0}, /* Bad pixels compensation address */
- {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */
- {0x0000, 0x86B2},
- {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */
- {0x0000, 0x86B4},
-
- {0x0001, 0x86B0},
- {0x00F5, 0x86B1},
- {0x0000, 0x86B2},
- {0x00C6, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0002, 0x86B0},
- {0x001C, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D7, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0003, 0x86B0},
- {0x001C, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D8, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0004, 0x86B0},
- {0x001D, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D8, 0x86B3},
- {0x0000, 0x86B4},
- {0x001E, 0x8660},
+ {0x0000, 0x86b0}, /* Bad pixels compensation address */
+ {0x00dc, 0x86b1}, /* X coord for bad pixels compensation (L) */
+ {0x0000, 0x86b2},
+ {0x0009, 0x86b3}, /* Y coord for bad pixels compensation (L) */
+ {0x0000, 0x86b4},
+
+ {0x0001, 0x86b0},
+ {0x00f5, 0x86b1},
+ {0x0000, 0x86b2},
+ {0x00c6, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0002, 0x86b0},
+ {0x001c, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d7, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0003, 0x86b0},
+ {0x001c, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d8, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0004, 0x86b0},
+ {0x001d, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d8, 0x86b3},
+ {0x0000, 0x86b4},
+ {0x001e, 0x8660},
/* READ { 0, 0x0000, 0x8608 } ->
0000: 13 */
@@ -1449,7 +1447,7 @@ static int reg_read(struct gspca_dev *gspca_dev,
}
static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
+ const u16 data[][2])
{
struct usb_device *dev = gspca_dev->dev;
int ret, i = 0;
@@ -1487,7 +1485,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
@@ -1593,13 +1590,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, 0x8654, brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = reg_read(gspca_dev, 0x8651);
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1614,7 +1604,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1666,8 +1655,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 3c9288019e9..c99c5e34e21 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -141,38 +141,38 @@ static const struct v4l2_pix_format sif_072a_mode[] = {
#define SPCA561_OFFSET_WIN1GBAVE 14
#define SPCA561_OFFSET_FREQ 15
#define SPCA561_OFFSET_VSYNC 16
-#define SPCA561_OFFSET_DATA 1
#define SPCA561_INDEX_I2C_BASE 0x8800
#define SPCA561_SNAPBIT 0x20
#define SPCA561_SNAPCTRL 0x40
-static const __u16 rev72a_init_data1[][2] = {
+static const u16 rev72a_reset[][2] = {
{0x0000, 0x8114}, /* Software GPIO output data */
{0x0001, 0x8114}, /* Software GPIO output data */
{0x0000, 0x8112}, /* Some kind of reset */
+ {}
+};
+static const __u16 rev72a_init_data1[][2] = {
{0x0003, 0x8701}, /* PCLK clock delay adjustment */
{0x0001, 0x8703}, /* HSYNC from cmos inverted */
{0x0011, 0x8118}, /* Enable and conf sensor */
{0x0001, 0x8118}, /* Conf sensor */
{0x0092, 0x8804}, /* I know nothing about these */
{0x0010, 0x8802}, /* 0x88xx registers, so I won't */
- {0x000d, 0x8805}, /* sensor default setting */
{}
};
-static const __u16 rev72a_init_sensor1[][2] = {
- /* ms-win values */
- {0x0001, 0x0018}, /* 0x01 <- 0x0d */
- {0x0002, 0x0065}, /* 0x02 <- 0x18 */
- {0x0004, 0x0121}, /* 0x04 <- 0x0165 */
- {0x0005, 0x00aa}, /* 0x05 <- 0x21 */
- {0x0007, 0x0004}, /* 0x07 <- 0xaa */
- {0x0020, 0x1502}, /* 0x20 <- 0x1504 */
- {0x0039, 0x0010}, /* 0x39 <- 0x02 */
- {0x0035, 0x0049}, /* 0x35 <- 0x10 */
- {0x0009, 0x100b}, /* 0x09 <- 0x1049 */
- {0x0028, 0x000f}, /* 0x28 <- 0x0b */
- {0x003b, 0x003c}, /* 0x3b <- 0x0f */
- {0x003c, 0x0000}, /* 0x3c <- 0x00 */
+static const u16 rev72a_init_sensor1[][2] = {
+ {0x0001, 0x000d},
+ {0x0002, 0x0018},
+ {0x0004, 0x0165},
+ {0x0005, 0x0021},
+ {0x0007, 0x00aa},
+ {0x0020, 0x1504},
+ {0x0039, 0x0002},
+ {0x0035, 0x0010},
+ {0x0009, 0x1049},
+ {0x0028, 0x000b},
+ {0x003b, 0x000f},
+ {0x003c, 0x0000},
{}
};
static const __u16 rev72a_init_data2[][2] = {
@@ -190,15 +190,10 @@ static const __u16 rev72a_init_data2[][2] = {
{0x0002, 0x8201}, /* Output address for r/w serial EEPROM */
{0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
{0x0001, 0x8200}, /* OprMode to be executed by hardware */
- {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */
- {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
- {0x0001, 0x8200}, /* OprMode to be executed by hardware */
- {0x0010, 0x8660}, /* Compensation memory stuff */
- {0x0018, 0x8660}, /* Compensation memory stuff */
-
- {0x0004, 0x8611}, /* R offset for white balance */
- {0x0004, 0x8612}, /* Gr offset for white balance */
- {0x0007, 0x8613}, /* B offset for white balance */
+/* from ms-win */
+ {0x0000, 0x8611}, /* R offset for white balance */
+ {0x00fd, 0x8612}, /* Gr offset for white balance */
+ {0x0003, 0x8613}, /* B offset for white balance */
{0x0000, 0x8614}, /* Gb offset for white balance */
/* from ms-win */
{0x0035, 0x8651}, /* R gain for white balance */
@@ -206,8 +201,8 @@ static const __u16 rev72a_init_data2[][2] = {
{0x005f, 0x8653}, /* B gain for white balance */
{0x0040, 0x8654}, /* Gb gain for white balance */
{0x0002, 0x8502}, /* Maximum average bit rate stuff */
-
{0x0011, 0x8802},
+
{0x0087, 0x8700}, /* Set master clock (96Mhz????) */
{0x0081, 0x8702}, /* Master clock output enable */
@@ -218,104 +213,15 @@ static const __u16 rev72a_init_data2[][2] = {
{0x0003, 0x865c}, /* Vertical offset for valid lines */
{}
};
-static const __u16 rev72a_init_sensor2[][2] = {
- /* ms-win values */
- {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */
- {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */
- {0x0005, 0x002f}, /* 0x05 <- 0x2f */
- {0x0006, 0x0000}, /* 0x06 <- 0 */
- {0x000a, 0x0002}, /* 0x0a <- 2 */
- {0x0009, 0x1061}, /* 0x09 <- 0x1061 */
- {0x0035, 0x0014}, /* 0x35 <- 0x14 */
- {}
-};
-static const __u16 rev72a_init_data3[][2] = {
- {0x0030, 0x8112}, /* ISO and drop packet enable */
-/*fixme: should stop here*/
- {0x0000, 0x8112}, /* Some kind of reset ???? */
- {0x0009, 0x8118}, /* Enable sensor and set standby */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0001, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8112}, /* Some kind of reset ??? */
- {0x0003, 0x8701},
- {0x0001, 0x8703},
- {0x0011, 0x8118},
- {0x0001, 0x8118},
- /***************/
- {0x0092, 0x8804},
- {0x0010, 0x8802},
- {0x000d, 0x8805},
- {0x0001, 0x8801},
- {0x0000, 0x8800},
- {0x0018, 0x8805},
- {0x0002, 0x8801},
- {0x0000, 0x8800},
- {0x0065, 0x8805},
- {0x0004, 0x8801},
- {0x0001, 0x8800},
- {0x0021, 0x8805},
- {0x0005, 0x8801},
- {0x0000, 0x8800},
- {0x00aa, 0x8805},
- {0x0007, 0x8801}, /* mode 0xaa */
- {0x0000, 0x8800},
- {0x0004, 0x8805},
- {0x0020, 0x8801},
- {0x0015, 0x8800}, /* mode 0x0415 */
- {0x0002, 0x8805},
- {0x0039, 0x8801},
- {0x0000, 0x8800},
- {0x0010, 0x8805},
- {0x0035, 0x8801},
- {0x0000, 0x8800},
- {0x0049, 0x8805},
- {0x0009, 0x8801},
- {0x0010, 0x8800},
- {0x000b, 0x8805},
- {0x0028, 0x8801},
- {0x0000, 0x8800},
- {0x000f, 0x8805},
- {0x003b, 0x8801},
- {0x0000, 0x8800},
- {0x0000, 0x8805},
- {0x003c, 0x8801},
- {0x0000, 0x8800},
- {0x0002, 0x8502},
- {0x0039, 0x8801},
- {0x0000, 0x8805},
- {0x0000, 0x8800},
-
- {0x0087, 0x8700}, /* overwrite by start */
- {0x0081, 0x8702},
- {0x0000, 0x8500},
-/* {0x0010, 0x8500}, -- Previous line was this */
- {0x0002, 0x865b},
- {0x0003, 0x865c},
- /***************/
- {0x0003, 0x8801}, /* 0x121-> 289 */
- {0x0021, 0x8805},
- {0x0001, 0x8800},
- {0x0004, 0x8801}, /* 0x165 -> 357 */
- {0x0065, 0x8805},
- {0x0001, 0x8800},
- {0x0005, 0x8801}, /* 0x2f //blanking control colonne */
- {0x002f, 0x8805},
- {0x0000, 0x8800},
- {0x0006, 0x8801}, /* 0x00 //blanking mode row */
- {0x0000, 0x8805},
- {0x0000, 0x8800},
- {0x000a, 0x8801}, /* 0x01 //0x02 */
- {0x0001, 0x8805},
- {0x0000, 0x8800},
- {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock
+static const u16 rev72a_init_sensor2[][2] = {
+ {0x0003, 0x0121},
+ {0x0004, 0x0165},
+ {0x0005, 0x002f}, /* blanking control column */
+ {0x0006, 0x0000}, /* blanking mode row*/
+ {0x000a, 0x0002},
+ {0x0009, 0x1061}, /* setexposure times && pixel clock
* 0001 0 | 000 0110 0001 */
- {0x0061, 0x8805}, /* 61 31 */
- {0x0008, 0x8800}, /* 08 */
- {0x0035, 0x8801}, /* 0x14 - set gain general */
- {0x001f, 0x8805}, /* 0x14 */
- {0x0000, 0x8800},
- {0x000e, 0x8112}, /* white balance - was 30 */
+ {0x0035, 0x0014},
{}
};
@@ -460,6 +366,7 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
reg_r(gspca_dev, 0x8803, 1);
if (!gspca_dev->usb_buf[0])
return;
+ msleep(10);
} while (--retry);
}
@@ -479,6 +386,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
reg_r(gspca_dev, 0x8805, 1);
return ((int) value << 8) | gspca_dev->usb_buf[0];
}
+ msleep(10);
} while (--retry);
return -1;
}
@@ -541,7 +449,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
sd->chip_revision = id->driver_info;
@@ -572,11 +479,13 @@ static int sd_init_12a(struct gspca_dev *gspca_dev)
static int sd_init_72a(struct gspca_dev *gspca_dev)
{
PDEBUG(D_STREAM, "Chip revision: 072a");
+ write_vector(gspca_dev, rev72a_reset);
+ msleep(200);
write_vector(gspca_dev, rev72a_init_data1);
write_sensor_72a(gspca_dev, rev72a_init_sensor1);
write_vector(gspca_dev, rev72a_init_data2);
write_sensor_72a(gspca_dev, rev72a_init_sensor2);
- write_vector(gspca_dev, rev72a_init_data3);
+ reg_w_val(gspca_dev->dev, 0x8112, 0x30);
return 0;
}
@@ -731,11 +640,18 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
int Clck;
int mode;
+ write_vector(gspca_dev, rev72a_reset);
+ msleep(200);
+ write_vector(gspca_dev, rev72a_init_data1);
+ write_sensor_72a(gspca_dev, rev72a_init_sensor1);
+
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
switch (mode) {
default:
-/* case 0:
- case 1: */
+ case 0:
+ Clck = 0x27; /* ms-win 0x87 */
+ break;
+ case 1:
Clck = 0x25;
break;
case 2:
@@ -745,13 +661,14 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
Clck = 0x21;
break;
}
- reg_w_val(dev, 0x8500, mode); /* mode */
reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
- reg_w_val(dev, 0x8112, 0x10 | 0x20);
+ reg_w_val(dev, 0x8702, 0x81);
+ reg_w_val(dev, 0x8500, mode); /* mode */
+ write_sensor_72a(gspca_dev, rev72a_init_sensor2);
setcontrast(gspca_dev);
/* setbrightness(gspca_dev); * fixme: bad values */
- setwhite(gspca_dev);
setautogain(gspca_dev);
+ reg_w_val(dev, 0x8112, 0x10 | 0x20);
return 0;
}
@@ -867,12 +784,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
- switch (data[0]) { /* sequence number */
+ len--;
+ switch (*data++) { /* sequence number */
case 0: /* start of frame */
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
- data += SPCA561_OFFSET_DATA;
- len -= SPCA561_OFFSET_DATA;
if (data[1] & 0x10) {
/* compressed bayer */
gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -893,8 +809,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
case 0xff: /* drop (empty mpackets) */
return;
}
- data++;
- len--;
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
@@ -1197,8 +1111,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
new file mode 100644
index 00000000000..04e3ae57a2e
--- /dev/null
+++ b/drivers/media/video/gspca/sq905.c
@@ -0,0 +1,456 @@
+/*
+ * SQ905 subdriver
+ *
+ * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * History and Acknowledgments
+ *
+ * The original Linux driver for SQ905 based cameras was written by
+ * Marcell Lengyel and furter developed by many other contributers
+ * and is available from http://sourceforge.net/projects/sqcam/
+ *
+ * This driver takes advantage of the reverse engineering work done for
+ * that driver and for libgphoto2 but shares no code with them.
+ *
+ * This driver has used as a base the finepix driver and other gspca
+ * based drivers and may still contain code fragments taken from those
+ * drivers.
+ */
+
+#define MODULE_NAME "sq905"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, "
+ "Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define SQ905_CMD_TIMEOUT 500
+#define SQ905_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define SQ905_MAX_TRANSFER 0x8000
+#define FRAME_HEADER_LEN 64
+
+/* The known modes, or registers. These go in the "value" slot. */
+
+/* 00 is "none" obviously */
+
+#define SQ905_BULK_READ 0x03 /* precedes any bulk read */
+#define SQ905_COMMAND 0x06 /* precedes the command codes below */
+#define SQ905_PING 0x07 /* when reading an "idling" command */
+#define SQ905_READ_DONE 0xc0 /* ack bulk read completed */
+
+/* Any non-zero value in the bottom 2 bits of the 2nd byte of
+ * the ID appears to indicate the camera can do 640*480. If the
+ * LSB of that byte is set the image is just upside down, otherwise
+ * it is rotated 180 degrees. */
+#define SQ905_HIRES_MASK 0x00000300
+#define SQ905_ORIENTATION_MASK 0x00000100
+
+/* Some command codes. These go in the "index" slot. */
+
+#define SQ905_ID 0xf0 /* asks for model string */
+#define SQ905_CONFIG 0x20 /* gets photo alloc. table, not used here */
+#define SQ905_DATA 0x30 /* accesses photo data, not used here */
+#define SQ905_CLEAR 0xa0 /* clear everything */
+#define SQ905_CAPTURE_LOW 0x60 /* Starts capture at 160x120 */
+#define SQ905_CAPTURE_MED 0x61 /* Starts capture at 320x240 */
+#define SQ905_CAPTURE_HIGH 0x62 /* Starts capture at 640x480 (some cams only) */
+/* note that the capture command also controls the output dimensions */
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ /*
+ * Driver stuff
+ */
+ struct work_struct work_struct;
+ struct workqueue_struct *work_thread;
+};
+
+static struct v4l2_pix_format sq905_mode[] = {
+ { 160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+ { 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+ { 640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0}
+};
+
+/*
+ * Send a command to the camera.
+ */
+static int sq905_command(struct gspca_dev *gspca_dev, u16 index)
+{
+ int ret;
+
+ gspca_dev->usb_buf[0] = '\0';
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_COMMAND, index, gspca_dev->usb_buf, 1,
+ SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_PING, 0, gspca_dev->usb_buf, 1,
+ SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed 2 (%d)",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Acknowledge the end of a frame - see warning on sq905_command.
+ */
+static int sq905_ack_frame(struct gspca_dev *gspca_dev)
+{
+ int ret;
+
+ gspca_dev->usb_buf[0] = '\0';
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1,
+ SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * request and read a block of data - see warning on sq905_command.
+ */
+static int
+sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size)
+{
+ int ret;
+ int act_len;
+
+ gspca_dev->usb_buf[0] = '\0';
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_BULK_READ, size, gspca_dev->usb_buf,
+ 1, SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
+ return ret;
+ }
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+ data, size, &act_len, SQ905_DATA_TIMEOUT);
+
+ /* successful, it returns 0, otherwise negative */
+ if (ret < 0 || act_len != size) {
+ PDEBUG(D_ERR, "bulk read fail (%d) len %d/%d",
+ ret, act_len, size);
+ return -EIO;
+ }
+ return 0;
+}
+
+/* This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use the camera's USB interface we take the gspca
+ * usb_lock when performing USB operations. In practice the only thing we need
+ * to protect against is the usb_set_interface call that gspca makes during
+ * stream_off as the camera doesn't provide any controls that the user could try
+ * to change.
+ */
+static void sq905_dostream(struct work_struct *work)
+{
+ struct sd *dev = container_of(work, struct sd, work_struct);
+ struct gspca_dev *gspca_dev = &dev->gspca_dev;
+ struct gspca_frame *frame;
+ int bytes_left; /* bytes remaining in current frame. */
+ int data_len; /* size to use for the next read. */
+ int header_read; /* true if we have already read the frame header. */
+ int discarding; /* true if we failed to get space for frame. */
+ int packet_type;
+ int frame_sz;
+ int ret;
+ u8 *data;
+ u8 *buffer;
+
+ buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
+ mutex_lock(&gspca_dev->usb_lock);
+ if (!buffer) {
+ PDEBUG(D_ERR, "Couldn't allocate USB buffer");
+ goto quit_stream;
+ }
+
+ frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage
+ + FRAME_HEADER_LEN;
+
+ while (gspca_dev->present && gspca_dev->streaming) {
+ /* Need a short delay to ensure streaming flag was set by
+ * gspca and to make sure gspca can grab the mutex. */
+ mutex_unlock(&gspca_dev->usb_lock);
+ msleep(1);
+
+ /* request some data and then read it until we have
+ * a complete frame. */
+ bytes_left = frame_sz;
+ header_read = 0;
+ discarding = 0;
+
+ while (bytes_left > 0) {
+ data_len = bytes_left > SQ905_MAX_TRANSFER ?
+ SQ905_MAX_TRANSFER : bytes_left;
+ mutex_lock(&gspca_dev->usb_lock);
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = sq905_read_data(gspca_dev, buffer, data_len);
+ if (ret < 0)
+ goto quit_stream;
+ mutex_unlock(&gspca_dev->usb_lock);
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for frame",
+ data_len, bytes_left);
+ bytes_left -= data_len;
+ data = buffer;
+ if (!header_read) {
+ packet_type = FIRST_PACKET;
+ /* The first 64 bytes of each frame are
+ * a header full of FF 00 bytes */
+ data += FRAME_HEADER_LEN;
+ data_len -= FRAME_HEADER_LEN;
+ header_read = 1;
+ } else if (bytes_left == 0) {
+ packet_type = LAST_PACKET;
+ } else {
+ packet_type = INTER_PACKET;
+ }
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding) {
+ frame = gspca_frame_add(gspca_dev, packet_type,
+ frame, data, data_len);
+ /* If entire frame fits in one packet we still
+ need to add a LAST_PACKET */
+ if (packet_type == FIRST_PACKET &&
+ bytes_left == 0)
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame, data, 0);
+ } else {
+ discarding = 1;
+ }
+ }
+ /* acknowledge the frame */
+ mutex_lock(&gspca_dev->usb_lock);
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = sq905_ack_frame(gspca_dev);
+ if (ret < 0)
+ goto quit_stream;
+ }
+quit_stream:
+ /* the usb_lock is already acquired */
+ if (gspca_dev->present)
+ sq905_command(gspca_dev, SQ905_CLEAR);
+ mutex_unlock(&gspca_dev->usb_lock);
+ kfree(buffer);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam = &gspca_dev->cam;
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ /* We don't use the buffer gspca allocates so make it small. */
+ cam->bulk_size = 64;
+
+ INIT_WORK(&dev->work_struct, sq905_dostream);
+
+ return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ /* wait for the work queue to terminate */
+ mutex_unlock(&gspca_dev->usb_lock);
+ /* This waits for sq905_dostream to finish */
+ destroy_workqueue(dev->work_thread);
+ dev->work_thread = NULL;
+ mutex_lock(&gspca_dev->usb_lock);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ u32 ident;
+ int ret;
+
+ /* connect to the camera and read
+ * the model ID and process that and put it away.
+ */
+ ret = sq905_command(gspca_dev, SQ905_CLEAR);
+ if (ret < 0)
+ return ret;
+ ret = sq905_command(gspca_dev, SQ905_ID);
+ if (ret < 0)
+ return ret;
+ ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4);
+ if (ret < 0)
+ return ret;
+ /* usb_buf is allocated with kmalloc so is aligned.
+ * Camera model number is the right way round if we assume this
+ * reverse engineered ID is supposed to be big endian. */
+ ident = be32_to_cpup((__be32 *)gspca_dev->usb_buf);
+ ret = sq905_command(gspca_dev, SQ905_CLEAR);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident);
+ gspca_dev->cam.cam_mode = sq905_mode;
+ gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode);
+ if (!(ident & SQ905_HIRES_MASK))
+ gspca_dev->cam.nmodes--;
+ return 0;
+}
+
+/* Set up for getting frames. */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+ int ret;
+
+ /* "Open the shutter" and set size, to start capture */
+ switch (gspca_dev->curr_mode) {
+ default:
+/* case 2: */
+ PDEBUG(D_STREAM, "Start streaming at high resolution");
+ ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH);
+ break;
+ case 1:
+ PDEBUG(D_STREAM, "Start streaming at medium resolution");
+ ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED);
+ break;
+ case 0:
+ PDEBUG(D_STREAM, "Start streaming at low resolution");
+ ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW);
+ }
+
+ if (ret < 0) {
+ PDEBUG(D_ERR, "Start streaming command failed");
+ return ret;
+ }
+ /* Start the workqueue function to do the streaming */
+ dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+ queue_work(dev->work_thread, &dev->work_struct);
+
+ return 0;
+}
+
+/* Table of supported USB devices */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x2770, 0x9120)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stop0 = sd_stop0,
+};
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id,
+ &sd_desc,
+ sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
new file mode 100644
index 00000000000..0bcb74a1b14
--- /dev/null
+++ b/drivers/media/video/gspca/sq905c.c
@@ -0,0 +1,328 @@
+/*
+ * SQ905C subdriver
+ *
+ * Copyright (C) 2009 Theodore Kilgore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ *
+ * This driver uses work done in
+ * libgphoto2/camlibs/digigr8, Copyright (C) Theodore Kilgore.
+ *
+ * This driver has also used as a base the sq905c driver
+ * and may contain code fragments from it.
+ */
+
+#define MODULE_NAME "sq905c"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/SQ905C USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define SQ905C_CMD_TIMEOUT 500
+#define SQ905C_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define SQ905C_MAX_TRANSFER 0x8000
+
+#define FRAME_HEADER_LEN 0x50
+
+/* Commands. These go in the "value" slot. */
+#define SQ905C_CLEAR 0xa0 /* clear everything */
+#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */
+#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */
+#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */
+
+/* For capture, this must go in the "index" slot. */
+#define SQ905C_CAPTURE_INDEX 0x110f
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+ const struct v4l2_pix_format *cap_mode;
+ /* Driver stuff */
+ struct work_struct work_struct;
+ struct workqueue_struct *work_thread;
+};
+
+/*
+ * Most of these cameras will do 640x480 and 320x240. 160x120 works
+ * in theory but gives very poor output. Therefore, not supported.
+ * The 0x2770:0x9050 cameras have max resolution of 320x240.
+ */
+static struct v4l2_pix_format sq905c_mode[] = {
+ { 320, 240, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+ { 640, 480, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0}
+};
+
+/* Send a command to the camera. */
+static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index)
+{
+ int ret;
+
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ command, index, NULL, 0,
+ SQ905C_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use the camera's USB interface the gspca usb_lock is
+ * used when performing the one USB control operation inside the workqueue,
+ * which tells the camera to close the stream. In practice the only thing
+ * which needs to be protected against is the usb_set_interface call that
+ * gspca makes during stream_off. Otherwise the camera doesn't provide any
+ * controls that the user could try to change.
+ */
+static void sq905c_dostream(struct work_struct *work)
+{
+ struct sd *dev = container_of(work, struct sd, work_struct);
+ struct gspca_dev *gspca_dev = &dev->gspca_dev;
+ struct gspca_frame *frame;
+ int bytes_left; /* bytes remaining in current frame. */
+ int data_len; /* size to use for the next read. */
+ int act_len;
+ int discarding = 0; /* true if we failed to get space for frame. */
+ int packet_type;
+ int ret;
+ u8 *buffer;
+
+ buffer = kmalloc(SQ905C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
+ if (!buffer) {
+ PDEBUG(D_ERR, "Couldn't allocate USB buffer");
+ goto quit_stream;
+ }
+
+ while (gspca_dev->present && gspca_dev->streaming) {
+ if (!gspca_dev->present)
+ goto quit_stream;
+ /* Request the header, which tells the size to download */
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+ buffer, FRAME_HEADER_LEN, &act_len,
+ SQ905C_DATA_TIMEOUT);
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for header",
+ act_len, FRAME_HEADER_LEN);
+ if (ret < 0 || act_len < FRAME_HEADER_LEN)
+ goto quit_stream;
+ /* size is read from 4 bytes starting 0x40, little endian */
+ bytes_left = buffer[0x40]|(buffer[0x41]<<8)|(buffer[0x42]<<16)
+ |(buffer[0x43]<<24);
+ PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
+ /* We keep the header. It has other information, too. */
+ packet_type = FIRST_PACKET;
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding) {
+ gspca_frame_add(gspca_dev, packet_type,
+ frame, buffer, FRAME_HEADER_LEN);
+ } else
+ discarding = 1;
+ while (bytes_left > 0) {
+ data_len = bytes_left > SQ905C_MAX_TRANSFER ?
+ SQ905C_MAX_TRANSFER : bytes_left;
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+ buffer, data_len, &act_len,
+ SQ905C_DATA_TIMEOUT);
+ if (ret < 0 || act_len < data_len)
+ goto quit_stream;
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for frame",
+ data_len, bytes_left);
+ bytes_left -= data_len;
+ if (bytes_left == 0)
+ packet_type = LAST_PACKET;
+ else
+ packet_type = INTER_PACKET;
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding)
+ gspca_frame_add(gspca_dev, packet_type,
+ frame, buffer, data_len);
+ else
+ discarding = 1;
+ }
+ }
+quit_stream:
+ mutex_lock(&gspca_dev->usb_lock);
+ if (gspca_dev->present)
+ sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
+ mutex_unlock(&gspca_dev->usb_lock);
+ kfree(buffer);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam = &gspca_dev->cam;
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ PDEBUG(D_PROBE,
+ "SQ9050 camera detected"
+ " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ cam->cam_mode = sq905c_mode;
+ cam->nmodes = 2;
+ if (id->idProduct == 0x9050)
+ cam->nmodes = 1;
+ /* We don't use the buffer gspca allocates so make it small. */
+ cam->bulk_size = 32;
+ INIT_WORK(&dev->work_struct, sq905c_dostream);
+ return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ /* wait for the work queue to terminate */
+ mutex_unlock(&gspca_dev->usb_lock);
+ /* This waits for sq905c_dostream to finish */
+ destroy_workqueue(dev->work_thread);
+ dev->work_thread = NULL;
+ mutex_lock(&gspca_dev->usb_lock);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ int ret;
+
+ /* connect to the camera and reset it. */
+ ret = sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
+ return ret;
+}
+
+/* Set up for getting frames. */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+ int ret;
+
+ dev->cap_mode = gspca_dev->cam.cam_mode;
+ /* "Open the shutter" and set size, to start capture */
+ switch (gspca_dev->width) {
+ case 640:
+ PDEBUG(D_STREAM, "Start streaming at high resolution");
+ dev->cap_mode++;
+ ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_HI,
+ SQ905C_CAPTURE_INDEX);
+ break;
+ default: /* 320 */
+ PDEBUG(D_STREAM, "Start streaming at medium resolution");
+ ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_MED,
+ SQ905C_CAPTURE_INDEX);
+ }
+
+ if (ret < 0) {
+ PDEBUG(D_ERR, "Start streaming command failed");
+ return ret;
+ }
+ /* Start the workqueue function to do the streaming */
+ dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+ queue_work(dev->work_thread, &dev->work_struct);
+
+ return 0;
+}
+
+/* Table of supported USB devices */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x2770, 0x905c)},
+ {USB_DEVICE(0x2770, 0x9050)},
+ {USB_DEVICE(0x2770, 0x913d)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stop0 = sd_stop0,
+};
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id,
+ &sd_desc,
+ sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 60de9af87fb..f25be20cf1a 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -35,10 +35,13 @@ struct sd {
unsigned char contrast;
unsigned char colors;
unsigned char lightfreq;
-};
+ u8 quality;
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
-/* global parameters */
-static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */
+ u8 *jpeg_hdr;
+};
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -180,7 +183,7 @@ static int rcv_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x63b, 0);
reg_w(gspca_dev, 0x630, 5);
ret = usb_bulk_msg(dev,
- usb_rcvbulkpipe(dev, 5),
+ usb_rcvbulkpipe(dev, 0x05),
gspca_dev->usb_buf,
4, /* length */
&alen,
@@ -294,15 +297,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
- cam->epaddr = 0x02;
gspca_dev->cam.cam_mode = vga_mode;
gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
sd->lightfreq = FREQ_DEF;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -326,8 +328,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int ret, value;
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
/* work on alternate 1 */
usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
@@ -399,11 +408,19 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
PDEBUG(D_STREAM, "camera stopped");
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
+ struct sd *sd = (struct sd *) gspca_dev;
static unsigned char ffd9[] = {0xff, 0xd9};
/* a frame starts with:
@@ -420,7 +437,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG 411 header */
- jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
/* beginning of the frame */
#define STKHDRSZ 12
@@ -520,6 +538,34 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
return -EINVAL;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -529,8 +575,11 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.querymenu = sd_querymenu,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -562,8 +611,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
info("registered");
return 0;
}
@@ -575,6 +626,3 @@ static void __exit sd_mod_exit(void)
module_init(sd_mod_init);
module_exit(sd_mod_exit);
-
-module_param_named(quant, sd_quant, int, 0644);
-MODULE_PARM_DESC(quant, "Quantization index (0..8)");
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 13a021e3cbb..9dff2e65b11 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -429,7 +429,6 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Configuring camera");
cam = &gspca_dev->cam;
- cam->epaddr = STV_ISOC_ENDPOINT_ADDR;
sd->desc = sd_desc;
gspca_dev->sd_desc = &sd->desc;
@@ -501,8 +500,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index 14335a9e4bb..b1690381420 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -30,6 +30,66 @@
#include "stv06xx_hdcs.h"
+static const struct ctrl hdcs1x00_ctrl[] = {
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x00,
+ .maximum = 0xffff,
+ .step = 0x1,
+ .default_value = HDCS_DEFAULT_EXPOSURE,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = hdcs_set_exposure,
+ .get = hdcs_get_exposure
+ }, {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = HDCS_DEFAULT_GAIN,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = hdcs_set_gain,
+ .get = hdcs_get_gain
+ }
+};
+
+static struct v4l2_pix_format hdcs1x00_mode[] = {
+ {
+ HDCS_1X00_DEF_WIDTH,
+ HDCS_1X00_DEF_HEIGHT,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
+ .bytesperline = HDCS_1X00_DEF_WIDTH,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1
+ }
+};
+
+static const struct ctrl hdcs1020_ctrl[] = {};
+
+static struct v4l2_pix_format hdcs1020_mode[] = {
+ {
+ HDCS_1020_DEF_WIDTH,
+ HDCS_1020_DEF_HEIGHT,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
+ .bytesperline = HDCS_1020_DEF_WIDTH,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1
+ }
+};
+
enum hdcs_power_state {
HDCS_STATE_SLEEP,
HDCS_STATE_IDLE,
@@ -353,10 +413,10 @@ static int hdcs_probe_1x00(struct sd *sd)
info("HDCS-1000/1100 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes;
- sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls;
- sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls;
+ sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
+ sd->desc.ctrls = hdcs1x00_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl);
hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
if (!hdcs)
@@ -412,10 +472,10 @@ static int hdcs_probe_1020(struct sd *sd)
info("HDCS-1020 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes;
- sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls;
- sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls;
+ sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
+ sd->desc.ctrls = hdcs1020_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl);
hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
if (!hdcs)
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index 9c7279a4cd8..412f06cf3d5 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -152,53 +152,6 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
.stop = hdcs_stop,
.disconnect = hdcs_disconnect,
.dump = hdcs_dump,
-
- .nctrls = 2,
- .ctrls = {
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xffff,
- .step = 0x1,
- .default_value = HDCS_DEFAULT_EXPOSURE,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = hdcs_set_exposure,
- .get = hdcs_get_exposure
- },
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = HDCS_DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = hdcs_set_gain,
- .get = hdcs_get_gain
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- HDCS_1X00_DEF_WIDTH,
- HDCS_1X00_DEF_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
- .bytesperline = HDCS_1X00_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
@@ -207,29 +160,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
.i2c_addr = (0x55 << 1),
.i2c_len = 1,
- .nctrls = 0,
- .ctrls = {},
-
.init = hdcs_init,
.probe = hdcs_probe_1020,
.start = hdcs_start,
.stop = hdcs_stop,
.dump = hdcs_dump,
-
- .nmodes = 1,
- .modes = {
- {
- HDCS_1020_DEF_WIDTH,
- HDCS_1020_DEF_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
- .bytesperline = HDCS_1020_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
static const u16 stv_bridge_init[][2] = {
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index d0a0f859645..285221e6b39 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -46,6 +46,132 @@
#include "stv06xx_pb0100.h"
+static const struct ctrl pb0100_ctrl[] = {
+#define GAIN_IDX 0
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 128
+ },
+ .set = pb0100_set_gain,
+ .get = pb0100_get_gain
+ },
+#define RED_BALANCE_IDX 1
+ {
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Red Balance",
+ .minimum = -255,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = pb0100_set_red_balance,
+ .get = pb0100_get_red_balance
+ },
+#define BLUE_BALANCE_IDX 2
+ {
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Blue Balance",
+ .minimum = -255,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = pb0100_set_blue_balance,
+ .get = pb0100_get_blue_balance
+ },
+#define EXPOSURE_IDX 3
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Exposure",
+ .minimum = 0,
+ .maximum = 511,
+ .step = 1,
+ .default_value = 12
+ },
+ .set = pb0100_set_exposure,
+ .get = pb0100_get_exposure
+ },
+#define AUTOGAIN_IDX 4
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Automatic Gain and Exposure",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = pb0100_set_autogain,
+ .get = pb0100_get_autogain
+ },
+#define AUTOGAIN_TARGET_IDX 5
+ {
+ {
+ .id = V4L2_CTRL_CLASS_USER + 0x1000,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Automatic Gain Target",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 128
+ },
+ .set = pb0100_set_autogain_target,
+ .get = pb0100_get_autogain_target
+ },
+#define NATURAL_IDX 6
+ {
+ {
+ .id = V4L2_CTRL_CLASS_USER + 0x1001,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Natural Light Source",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = pb0100_set_natural,
+ .get = pb0100_get_natural
+ }
+};
+
+static struct v4l2_pix_format pb0100_mode[] = {
+/* low res / subsample modes disabled as they are only half res horizontal,
+ halving the vertical resolution does not seem to work */
+ {
+ 320,
+ 240,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 320 * 240,
+ .bytesperline = 320,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = PB0100_CROP_TO_VGA
+ },
+ {
+ 352,
+ 288,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 352 * 288,
+ .bytesperline = 352,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
static int pb0100_probe(struct sd *sd)
{
u16 sensor;
@@ -59,20 +185,19 @@ static int pb0100_probe(struct sd *sd)
if ((sensor >> 8) == 0x64) {
sensor_settings = kmalloc(
- stv06xx_sensor_pb0100.nctrls * sizeof(s32),
+ ARRAY_SIZE(pb0100_ctrl) * sizeof(s32),
GFP_KERNEL);
if (!sensor_settings)
return -ENOMEM;
info("Photobit pb0100 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes;
- sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls;
- sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls;
- for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++)
- sensor_settings[i] = stv06xx_sensor_pb0100.
- ctrls[i].qctrl.default_value;
+ sd->gspca_dev.cam.cam_mode = pb0100_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
+ sd->desc.ctrls = pb0100_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl);
+ for (i = 0; i < sd->desc.nctrls; i++)
+ sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value;
sd->sensor_priv = sensor_settings;
return 0;
@@ -143,6 +268,12 @@ out:
return (err < 0) ? err : 0;
}
+static void pb0100_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
/* FIXME: Sort the init commands out and put them into tables,
this is only for getting the camera to work */
/* FIXME: No error handling for now,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
index 5ea21a1154c..4de4fa5ebc5 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
@@ -114,6 +114,7 @@ static int pb0100_start(struct sd *sd);
static int pb0100_init(struct sd *sd);
static int pb0100_stop(struct sd *sd);
static int pb0100_dump(struct sd *sd);
+static void pb0100_disconnect(struct sd *sd);
/* V4L2 controls supported by the driver */
static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -137,139 +138,12 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
.i2c_addr = 0xba,
.i2c_len = 2,
- .nctrls = 7,
- .ctrls = {
-#define GAIN_IDX 0
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 128
- },
- .set = pb0100_set_gain,
- .get = pb0100_get_gain
- },
-#define RED_BALANCE_IDX 1
- {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = -255,
- .maximum = 255,
- .step = 1,
- .default_value = 0
- },
- .set = pb0100_set_red_balance,
- .get = pb0100_get_red_balance
- },
-#define BLUE_BALANCE_IDX 2
- {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = -255,
- .maximum = 255,
- .step = 1,
- .default_value = 0
- },
- .set = pb0100_set_blue_balance,
- .get = pb0100_get_blue_balance
- },
-#define EXPOSURE_IDX 3
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 0,
- .maximum = 511,
- .step = 1,
- .default_value = 12
- },
- .set = pb0100_set_exposure,
- .get = pb0100_get_exposure
- },
-#define AUTOGAIN_IDX 4
- {
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Automatic Gain and Exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = pb0100_set_autogain,
- .get = pb0100_get_autogain
- },
-#define AUTOGAIN_TARGET_IDX 5
- {
- {
- .id = V4L2_CTRL_CLASS_USER + 0x1000,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Automatic Gain Target",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 128
- },
- .set = pb0100_set_autogain_target,
- .get = pb0100_get_autogain_target
- },
-#define NATURAL_IDX 6
- {
- {
- .id = V4L2_CTRL_CLASS_USER + 0x1001,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Natural Light Source",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = pb0100_set_natural,
- .get = pb0100_get_natural
- },
- },
-
.init = pb0100_init,
.probe = pb0100_probe,
.start = pb0100_start,
.stop = pb0100_stop,
.dump = pb0100_dump,
-
- .nmodes = 2,
- .modes = {
-/* low res / subsample modes disabled as they are only half res horizontal,
- halving the vertical resolution does not seem to work */
- {
- 320,
- 240,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 320 * 240,
- .bytesperline = 320,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = PB0100_CROP_TO_VGA
- },
- {
- 352,
- 288,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 352 * 288,
- .bytesperline = 352,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
- }
+ .disconnect = pb0100_disconnect,
};
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
index c726dacefa1..e88c42f7d2f 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -41,8 +41,6 @@ extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00;
extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
-#define STV06XX_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
-
struct stv06xx_sensor {
/* Defines the name of a sensor */
char name[32];
@@ -81,12 +79,6 @@ struct stv06xx_sensor {
/* Instructs the sensor to dump all its contents */
int (*dump)(struct sd *sd);
-
- int nctrls;
- struct ctrl ctrls[STV06XX_MAX_CTRLS];
-
- char nmodes;
- struct v4l2_pix_format modes[];
};
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index 1ca91f2a6de..69c77c932fc 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -29,26 +29,92 @@
#include "stv06xx_vv6410.h"
+static struct v4l2_pix_format vv6410_mode[] = {
+ {
+ 356,
+ 292,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 356 * 292,
+ .bytesperline = 356,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
+static const struct ctrl vv6410_ctrl[] = {
+#define HFLIP_IDX 0
+ {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_hflip,
+ .get = vv6410_get_hflip
+ },
+#define VFLIP_IDX 1
+ {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_vflip,
+ .get = vv6410_get_vflip
+ },
+#define GAIN_IDX 2
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "analog gain",
+ .minimum = 0,
+ .maximum = 15,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_analog_gain,
+ .get = vv6410_get_analog_gain
+ }
+};
+
static int vv6410_probe(struct sd *sd)
{
u16 data;
- int err;
+ int err, i;
+ s32 *sensor_settings;
err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data);
-
if (err < 0)
return -ENODEV;
if (data == 0x19) {
info("vv6410 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_vv6410.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_vv6410.nmodes;
- sd->desc.ctrls = stv06xx_sensor_vv6410.ctrls;
- sd->desc.nctrls = stv06xx_sensor_vv6410.nctrls;
+ sensor_settings = kmalloc(ARRAY_SIZE(vv6410_ctrl) * sizeof(s32),
+ GFP_KERNEL);
+ if (!sensor_settings)
+ return -ENOMEM;
+
+ sd->gspca_dev.cam.cam_mode = vv6410_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode);
+ sd->desc.ctrls = vv6410_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl);
+
+ for (i = 0; i < sd->desc.nctrls; i++)
+ sensor_settings[i] = vv6410_ctrl[i].qctrl.default_value;
+ sd->sensor_priv = sensor_settings;
return 0;
}
-
return -ENODEV;
}
@@ -80,6 +146,12 @@ static int vv6410_init(struct sd *sd)
return (err < 0) ? err : 0;
}
+static void vv6410_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
static int vv6410_start(struct sd *sd)
{
int err;
@@ -156,17 +228,13 @@ static int vv6410_dump(struct sd *sd)
static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
- *val = (i2c_data & VV6410_HFLIP) ? 1 : 0;
-
+ *val = sensor_settings[HFLIP_IDX];
PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -174,6 +242,9 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[HFLIP_IDX] = val;
err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
if (err < 0)
return err;
@@ -191,17 +262,13 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
- *val = (i2c_data & VV6410_VFLIP) ? 1 : 0;
-
+ *val = sensor_settings[VFLIP_IDX];
PDEBUG(D_V4L2, "Read vertical flip %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -209,6 +276,9 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[VFLIP_IDX] = val;
err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
if (err < 0)
return err;
@@ -226,24 +296,23 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data);
-
- *val = i2c_data & 0xf;
+ *val = sensor_settings[GAIN_IDX];
PDEBUG(D_V4L2, "Read analog gain %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ sensor_settings[GAIN_IDX] = val;
PDEBUG(D_V4L2, "Set analog gain to %d", val);
err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 3ff8c4ea336..95ac55891bd 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -178,6 +178,7 @@ static int vv6410_start(struct sd *sd);
static int vv6410_init(struct sd *sd);
static int vv6410_stop(struct sd *sd);
static int vv6410_dump(struct sd *sd);
+static void vv6410_disconnect(struct sd *sd);
/* V4L2 controls supported by the driver */
static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -197,62 +198,7 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
.start = vv6410_start,
.stop = vv6410_stop,
.dump = vv6410_dump,
-
- .nctrls = 3,
- .ctrls = {
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_hflip,
- .get = vv6410_get_hflip
- }, {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_vflip,
- .get = vv6410_get_vflip
- }, {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "analog gain",
- .minimum = 0,
- .maximum = 15,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_analog_gain,
- .get = vv6410_get_analog_gain
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- 356,
- 292,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 356 * 292,
- .bytesperline = 356,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
- }
+ .disconnect = vv6410_disconnect,
};
/* If NULL, only single value to write, stored in len */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 6d904d5e4c7..c2b8c10c075 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -39,8 +39,11 @@ struct sd {
unsigned char contrast;
unsigned char colors;
unsigned char autogain;
+ u8 quality;
+#define QUALITY_MIN 70
+#define QUALITY_MAX 95
+#define QUALITY_DEF 85
- char qindex;
char bridge;
#define BRIDGE_SPCA504 0
#define BRIDGE_SPCA504B 1
@@ -52,6 +55,8 @@ struct sd {
#define LogitechClickSmart420 2
#define LogitechClickSmart820 3
#define MegapixV4 4
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -812,7 +817,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
sd->bridge = id->driver_info >> 8;
sd->subtype = id->driver_info;
@@ -850,10 +854,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
break;
}
- sd->qindex = 5; /* set the quantization table */
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -970,6 +974,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
__u8 i;
__u8 info[6];
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
if (sd->bridge == BRIDGE_SPCA504B)
spca504B_setQtable(gspca_dev);
spca504B_SetSizeType(gspca_dev);
@@ -1079,6 +1089,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
}
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -1155,9 +1172,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
}
/* add 0x00 after 0xff */
@@ -1198,26 +1214,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
}
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u16 brightness = 0;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
- break;
- case BRIDGE_SPCA536:
- brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
- break;
- }
- sd->brightness = ((brightness & 0xff) - 128) % 255;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1237,24 +1233,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
}
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
- break;
- case BRIDGE_SPCA536:
- sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
- break;
- }
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1274,24 +1252,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
}
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
- break;
- case BRIDGE_SPCA536:
- sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
- break;
- }
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1306,7 +1266,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1325,7 +1284,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -1344,7 +1302,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -1365,6 +1322,34 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1374,7 +1359,10 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1465,8 +1453,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 6ee111a3cbd..f63e37e2e4f 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -37,20 +37,21 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- unsigned char brightness;
- unsigned char contrast;
- unsigned char colors;
- unsigned char autogain;
- unsigned char gamma;
- unsigned char sharpness;
- unsigned char freq;
- unsigned char whitebalance;
- unsigned char mirror;
- unsigned char effect;
-
- __u8 sensor;
-#define SENSOR_TAS5130A 0
-#define SENSOR_OM6802 1
+ u8 brightness;
+ u8 contrast;
+ u8 colors;
+ u8 autogain;
+ u8 gamma;
+ u8 sharpness;
+ u8 freq;
+ u8 whitebalance;
+ u8 mirror;
+ u8 effect;
+
+ u8 sensor;
+#define SENSOR_OM6802 0
+#define SENSOR_OTHER 1
+#define SENSOR_TAS5130A 2
};
/* V4L2 controls supported by the driver */
@@ -78,7 +79,6 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
@@ -87,12 +87,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 14,
.step = 1,
- .default_value = 8,
+#define BRIGHTNESS_DEF 8
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
},
-#define SD_CONTRAST 1
{
{
.id = V4L2_CID_CONTRAST,
@@ -101,12 +101,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0x0d,
.step = 1,
- .default_value = 0x07,
+#define CONTRAST_DEF 0x07
+ .default_value = CONTRAST_DEF,
},
.set = sd_setcontrast,
.get = sd_getcontrast,
},
-#define SD_COLOR 2
{
{
.id = V4L2_CID_SATURATION,
@@ -115,7 +115,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0x0f,
.step = 1,
- .default_value = 0x05,
+#define COLORS_DEF 0x05
+ .default_value = COLORS_DEF,
},
.set = sd_setcolors,
.get = sd_getcolors,
@@ -135,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setgamma,
.get = sd_getgamma,
},
-#define SD_AUTOGAIN 4
{
{
.id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
@@ -146,12 +146,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0x01,
+#define AUTOGAIN_DEF 0x01
+ .default_value = AUTOGAIN_DEF,
},
.set = sd_setlowlight,
.get = sd_getlowlight,
},
-#define SD_MIRROR 5
{
{
.id = V4L2_CID_HFLIP,
@@ -160,12 +160,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0,
+#define MIRROR_DEF 0
+ .default_value = MIRROR_DEF,
},
.set = sd_setflip,
.get = sd_getflip
},
-#define SD_LIGHTFREQ 6
{
{
.id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -174,12 +174,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 1, /* 1 -> 0x50, 2->0x60 */
.maximum = 2,
.step = 1,
- .default_value = 1,
+#define FREQ_DEF 1
+ .default_value = FREQ_DEF,
},
.set = sd_setfreq,
.get = sd_getfreq},
-#define SD_WHITE_BALANCE 7
{
{
.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
@@ -188,12 +188,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0,
+#define WHITE_BALANCE_DEF 0
+ .default_value = WHITE_BALANCE_DEF,
},
.set = sd_setwhitebalance,
.get = sd_getwhitebalance
},
-#define SD_SHARPNESS 8 /* (aka definition on win) */
{
{
.id = V4L2_CID_SHARPNESS,
@@ -202,12 +202,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 15,
.step = 1,
- .default_value = 0x06,
+#define SHARPNESS_DEF 0x06
+ .default_value = SHARPNESS_DEF,
},
.set = sd_setsharpness,
.get = sd_getsharpness,
},
-#define SD_EFFECTS 9
{
{
.id = V4L2_CID_EFFECTS,
@@ -216,7 +216,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 4,
.step = 1,
- .default_value = 0,
+#define EFFECTS_DEF 0
+ .default_value = EFFECTS_DEF,
},
.set = sd_seteffect,
.get = sd_geteffect
@@ -263,28 +264,50 @@ static const struct v4l2_pix_format vga_mode_t16[] = {
/* sensor specific data */
struct additional_sensor_data {
- const __u8 data1[20];
- const __u8 data2[18];
- const __u8 data3[18];
- const __u8 data4[4];
- const __u8 data5[6];
- const __u8 stream[4];
+ const u8 data1[10];
+ const u8 data2[9];
+ const u8 data3[9];
+ const u8 data4[4];
+ const u8 data5[6];
+ const u8 stream[4];
};
-const static struct additional_sensor_data sensor_data[] = {
+static const struct additional_sensor_data sensor_data[] = {
+ { /* OM6802 */
+ .data1 =
+ {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
+ 0xb3, 0xfc},
+ .data2 =
+ {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
+ 0xff},
+ .data4 = /*Freq (50/60Hz). Splitted for test purpose */
+ {0x66, 0xca, 0xa8, 0xf0},
+ .data5 = /* this could be removed later */
+ {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x78},
+ },
+ { /* OTHER */
+ .data1 =
+ {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
+ 0xe8, 0xfc},
+ .data2 =
+ {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
+ 0xd9},
+ .data4 =
+ {0x66, 0x00, 0xa8, 0xa8},
+ .data5 =
+ {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x00},
+ },
{ /* TAS5130A */
.data1 =
- {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
- 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
- 0xd8, 0xc8, 0xd9, 0xfc},
+ {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
+ 0xc8, 0xfc},
.data2 =
- {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
- 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
- 0xe8, 0xe0},
- .data3 =
- {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
- 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
- 0xcf, 0xe0},
+ {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
+ 0xe0},
.data4 = /* Freq (50/60Hz). Splitted for test purpose */
{0x66, 0x00, 0xa8, 0xe8},
.data5 =
@@ -292,32 +315,12 @@ const static struct additional_sensor_data sensor_data[] = {
.stream =
{0x0b, 0x04, 0x0a, 0x40},
},
- { /* OM6802 */
- .data1 =
- {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
- 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
- 0xd8, 0xb3, 0xd9, 0xfc},
- .data2 =
- {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
- 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
- 0xe8, 0xff},
- .data3 =
- {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
- 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
- 0xcf, 0xff},
- .data4 = /*Freq (50/60Hz). Splitted for test purpose */
- {0x66, 0xca, 0xa8, 0xf0 },
- .data5 = /* this could be removed later */
- {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
- .stream =
- {0x0b, 0x04, 0x0a, 0x78},
- }
};
#define MAX_EFFECTS 7
/* easily done by soft, this table could be removed,
* i keep it here just in case */
-static const __u8 effects_table[MAX_EFFECTS][6] = {
+static const u8 effects_table[MAX_EFFECTS][6] = {
{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
@@ -327,90 +330,58 @@ static const __u8 effects_table[MAX_EFFECTS][6] = {
{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
};
-static const __u8 gamma_table[GAMMA_MAX][34] = {
- {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */
- 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
- 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
- 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */
- 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
- 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
- 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */
- 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
- 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
- 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */
- 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
- 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
- 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */
- 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
- 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
- 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */
- 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
- 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
- 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */
- 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
- 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
- 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */
- 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
- 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
- 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */
- 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
- 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
- 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */
- 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
- 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
- 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */
- 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
- 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
- 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */
- 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
- 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
- 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */
- 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
- 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
- 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */
- 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
- 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
- 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */
- 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
- 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
- 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */
- 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
- 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
- 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
- 0xa0, 0xff}
+static const u8 gamma_table[GAMMA_MAX][17] = {
+ {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */
+ 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
+ 0xff},
+ {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
+ 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
+ 0xff},
+ {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
+ 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
+ 0xff},
+ {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
+ 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+ 0xff},
+ {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
+ 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
+ 0xff},
+ {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
+ 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
+ 0xff},
+ {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
+ 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
+ 0xff},
+ {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
+ 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
+ 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
+ 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
+ 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
+ 0xff},
+ {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B, /* 11 */
+ 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+ 0xff},
+ {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
+ 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
+ 0xff},
+ {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
+ 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
+ 0xff},
+ {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
+ 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
+ 0xff},
+ {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
+ 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
+ 0xff}
};
-static const __u8 tas5130a_sensor_init[][8] = {
+static const u8 tas5130a_sensor_init[][8] = {
{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
@@ -418,11 +389,11 @@ static const __u8 tas5130a_sensor_init[][8] = {
{},
};
-static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
+static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
/* read 1 byte */
-static int reg_r(struct gspca_dev *gspca_dev,
- __u16 index)
+static u8 reg_r(struct gspca_dev *gspca_dev,
+ u16 index)
{
usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -435,7 +406,7 @@ static int reg_r(struct gspca_dev *gspca_dev,
}
static void reg_w(struct gspca_dev *gspca_dev,
- __u16 index)
+ u16 index)
{
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -446,7 +417,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
}
static void reg_w_buf(struct gspca_dev *gspca_dev,
- const __u8 *buffer, __u16 len)
+ const u8 *buffer, u16 len)
{
if (len <= USB_BUF_SZ) {
memcpy(gspca_dev->usb_buf, buffer, len);
@@ -457,7 +428,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
0x01, 0,
gspca_dev->usb_buf, len, 500);
} else {
- __u8 *tmpbuf;
+ u8 *tmpbuf;
tmpbuf = kmalloc(len, GFP_KERNEL);
memcpy(tmpbuf, buffer, len);
@@ -471,14 +442,41 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
}
}
+/* write values to consecutive registers */
+static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
+ u8 reg,
+ const u8 *buffer, u16 len)
+{
+ int i;
+ u8 *p, *tmpbuf;
+
+ if (len * 2 <= USB_BUF_SZ)
+ p = tmpbuf = gspca_dev->usb_buf;
+ else
+ p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
+ i = len;
+ while (--i >= 0) {
+ *p++ = reg++;
+ *p++ = *buffer++;
+ }
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x01, 0,
+ tmpbuf, len * 2, 500);
+ if (len * 2 > USB_BUF_SZ)
+ kfree(tmpbuf);
+}
+
/* Reported as OM6802*/
static void om6802_sensor_init(struct gspca_dev *gspca_dev)
{
int i;
- const __u8 *p;
- __u8 byte;
- __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
- static const __u8 sensor_init[] = {
+ const u8 *p;
+ u8 byte;
+ u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
+ static const u8 sensor_init[] = {
0xdf, 0x6d,
0xdd, 0x18,
0x5a, 0xe0,
@@ -497,7 +495,7 @@ static void om6802_sensor_init(struct gspca_dev *gspca_dev)
};
reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
- msleep(5);
+ msleep(100);
i = 4;
while (--i > 0) {
byte = reg_r(gspca_dev, 0x0060);
@@ -538,20 +536,20 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode_t16;
cam->nmodes = ARRAY_SIZE(vga_mode_t16);
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
- sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
- sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLORS_DEF;
sd->gamma = GAMMA_DEF;
- sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
- sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
- sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
- sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
- sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
+ sd->autogain = AUTOGAIN_DEF;
+ sd->mirror = MIRROR_DEF;
+ sd->freq = FREQ_DEF;
+ sd->whitebalance = WHITE_BALANCE_DEF;
+ sd->sharpness = SHARPNESS_DEF;
+ sd->effect = EFFECTS_DEF;
return 0;
}
@@ -559,7 +557,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int brightness;
- __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
+ u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
brightness = sd->brightness;
if (brightness < 7) {
@@ -576,7 +574,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int contrast = sd->contrast;
- __u16 reg_to_write;
+ u16 reg_to_write;
if (contrast < 7)
reg_to_write = 0x8ea9 - contrast * 0x200;
@@ -589,7 +587,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
+ u16 reg_to_write;
reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
reg_w(gspca_dev, reg_to_write);
@@ -600,14 +598,15 @@ static void setgamma(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
- reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+ reg_w_ixbuf(gspca_dev, 0x90,
+ gamma_table[sd->gamma], sizeof gamma_table[0]);
}
static void setwhitebalance(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 white_balance[8] =
+ u8 white_balance[8] =
{0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
if (sd->whitebalance)
@@ -619,7 +618,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev)
static void setsharpness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
+ u16 reg_to_write;
reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
@@ -635,18 +634,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
* to see the initial parameters.*/
struct sd *sd = (struct sd *) gspca_dev;
int i;
- __u8 byte, test_byte;
-
- static const __u8 read_indexs[] =
- { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
- 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
- static const __u8 n1[] =
+ u16 sensor_id;
+ u8 test_byte = 0;
+ u16 reg80, reg8e;
+
+ static const u8 read_indexs[] =
+ { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
+ 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
+ static const u8 n1[] =
{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
- static const __u8 n2[] =
+ static const u8 n2[] =
{0x08, 0x00};
- static const __u8 n3[] =
+ static const u8 n3[6] =
{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
- static const __u8 n4[] =
+ static const u8 n3_other[6] =
+ {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00};
+ static const u8 n4[] =
{0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
@@ -656,40 +659,61 @@ static int sd_init(struct gspca_dev *gspca_dev)
0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
- static const __u8 nset9[4] =
- { 0x0b, 0x04, 0x0a, 0x78 };
- static const __u8 nset8[6] =
+ static const u8 n4_other[] =
+ {0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
+ 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
+ 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
+ 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
+ 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
+ 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
+ 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
+ 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00};
+ static const u8 nset8[6] =
{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
-
- byte = reg_r(gspca_dev, 0x06);
- test_byte = reg_r(gspca_dev, 0x07);
- if (byte == 0x08 && test_byte == 0x07) {
- PDEBUG(D_CONF, "sensor om6802");
- sd->sensor = SENSOR_OM6802;
- } else if (byte == 0x08 && test_byte == 0x01) {
- PDEBUG(D_CONF, "sensor tas5130a");
- sd->sensor = SENSOR_TAS5130A;
- } else {
- PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
+ static const u8 nset8_other[6] =
+ { 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 };
+ static const u8 nset9[4] =
+ { 0x0b, 0x04, 0x0a, 0x78 };
+ static const u8 nset9_other[4] =
+ { 0x0b, 0x04, 0x0a, 0x00 };
+
+ sensor_id = (reg_r(gspca_dev, 0x06) << 8)
+ | reg_r(gspca_dev, 0x07);
+ switch (sensor_id & 0xff0f) {
+ case 0x0801:
+ PDEBUG(D_PROBE, "sensor tas5130a");
sd->sensor = SENSOR_TAS5130A;
+ break;
+ case 0x0803:
+ PDEBUG(D_PROBE, "sensor 'other'");
+ sd->sensor = SENSOR_OTHER;
+ break;
+ case 0x0807:
+ PDEBUG(D_PROBE, "sensor om6802");
+ sd->sensor = SENSOR_OM6802;
+ break;
+ default:
+ PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id);
+ return -EINVAL;
}
- reg_w_buf(gspca_dev, n1, sizeof n1);
- test_byte = 0;
- i = 5;
- while (--i >= 0) {
- reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
- test_byte = reg_r(gspca_dev, 0x0063);
- msleep(100);
- if (test_byte == 0x17)
- break; /* OK */
- }
- if (i < 0) {
- err("Bad sensor reset %02x", test_byte);
-/* return -EIO; */
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, n1, sizeof n1);
+ i = 5;
+ while (--i >= 0) {
+ reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
+ test_byte = reg_r(gspca_dev, 0x0063);
+ msleep(100);
+ if (test_byte == 0x17)
+ break; /* OK */
+ }
+ if (i < 0) {
+ err("Bad sensor reset %02x", test_byte);
+/* return -EIO; */
/*fixme: test - continue */
+ }
+ reg_w_buf(gspca_dev, n2, sizeof n2);
}
- reg_w_buf(gspca_dev, n2, sizeof n2);
i = 0;
while (read_indexs[i] != 0x00) {
@@ -699,21 +723,31 @@ static int sd_init(struct gspca_dev *gspca_dev)
i++;
}
- reg_w_buf(gspca_dev, n3, sizeof n3);
- reg_w_buf(gspca_dev, n4, sizeof n4);
- reg_r(gspca_dev, 0x0080);
- reg_w(gspca_dev, 0x2c80);
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, n3, sizeof n3);
+ reg_w_buf(gspca_dev, n4, sizeof n4);
+ reg_r(gspca_dev, 0x0080);
+ reg_w(gspca_dev, 0x2c80);
+ reg80 = 0x3880;
+ reg8e = 0x338e;
+ } else {
+ reg_w_buf(gspca_dev, n3_other, sizeof n3_other);
+ reg_w_buf(gspca_dev, n4_other, sizeof n4_other);
+ sd->gamma = 5;
+ reg80 = 0xac80;
+ reg8e = 0xb88e;
+ }
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
sizeof sensor_data[sd->sensor].data1);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
- sizeof sensor_data[sd->sensor].data3);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
sizeof sensor_data[sd->sensor].data2);
- reg_w(gspca_dev, 0x3880);
- reg_w(gspca_dev, 0x3880);
- reg_w(gspca_dev, 0x338e);
+ reg_w(gspca_dev, reg80);
+ reg_w(gspca_dev, reg80);
+ reg_w(gspca_dev, reg8e);
setbrightness(gspca_dev);
setcontrast(gspca_dev);
@@ -730,16 +764,20 @@ static int sd_init(struct gspca_dev *gspca_dev)
sizeof sensor_data[sd->sensor].data4);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
sizeof sensor_data[sd->sensor].data5);
- reg_w_buf(gspca_dev, nset8, sizeof nset8);
- reg_w_buf(gspca_dev, nset9, sizeof nset9);
-
- reg_w(gspca_dev, 0x2880);
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, nset8, sizeof nset8);
+ reg_w_buf(gspca_dev, nset9, sizeof nset9);
+ reg_w(gspca_dev, 0x2880);
+ } else {
+ reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other);
+ reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other);
+ }
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
sizeof sensor_data[sd->sensor].data1);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
- sizeof sensor_data[sd->sensor].data3);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
sizeof sensor_data[sd->sensor].data2);
return 0;
@@ -748,7 +786,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
static void setflip(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 flipcmd[8] =
+ u8 flipcmd[8] =
{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
if (sd->mirror)
@@ -778,7 +816,7 @@ static void seteffect(struct gspca_dev *gspca_dev)
static void setlightfreq(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
+ u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
if (sd->freq == 2) /* 60hz */
freq[1] = 0x00;
@@ -791,22 +829,22 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
static void poll_sensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 poll1[] =
+ static const u8 poll1[] =
{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
0x60, 0x14};
- static const __u8 poll2[] =
+ static const u8 poll2[] =
{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
- static const __u8 poll3[] =
+ static const u8 poll3[] =
{0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
- static const __u8 poll4[] =
+ static const u8 poll4[] =
{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
0xc2, 0x80, 0xc3, 0x10};
- if (sd->sensor != SENSOR_TAS5130A) {
+ if (sd->sensor == SENSOR_OM6802) {
PDEBUG(D_STREAM, "[Sensor requires polling]");
reg_w_buf(gspca_dev, poll1, sizeof poll1);
reg_w_buf(gspca_dev, poll2, sizeof poll2);
@@ -819,13 +857,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i, mode;
- __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
- static const __u8 t3[] =
- { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
- 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
+ u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
+ static const u8 t3[] =
+ { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
switch (mode) {
+ case 0: /* 640x480 (0x00) */
+ break;
case 1: /* 352x288 */
t2[1] = 0x40;
break;
@@ -835,14 +874,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
case 3: /* 176x144 */
t2[1] = 0x50;
break;
- case 4: /* 160x120 */
+ default:
+/* case 4: * 160x120 */
t2[1] = 0x20;
break;
- default: /* 640x480 (0x00) */
- break;
}
- if (sd->sensor == SENSOR_TAS5130A) {
+ switch (sd->sensor) {
+ case SENSOR_OM6802:
+ om6802_sensor_init(gspca_dev);
+ break;
+ case SENSOR_OTHER:
+ break;
+ default:
+/* case SENSOR_TAS5130A: */
i = 0;
while (tas5130a_sensor_init[i][0] != 0) {
reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
@@ -854,14 +899,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
sizeof tas5130a_sensor_init[0]);
reg_w(gspca_dev, 0x3c80);
- } else {
- om6802_sensor_init(gspca_dev);
+ break;
}
reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
sizeof sensor_data[sd->sensor].data4);
reg_r(gspca_dev, 0x0012);
reg_w_buf(gspca_dev, t2, sizeof t2);
- reg_w_buf(gspca_dev, t3, sizeof t3);
+ reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
reg_w(gspca_dev, 0x0013);
msleep(15);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
@@ -885,16 +929,18 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
msleep(20);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
sizeof sensor_data[sd->sensor].stream);
- msleep(20);
- reg_w(gspca_dev, 0x0309);
+ if (sd->sensor != SENSOR_OTHER) {
+ msleep(20);
+ reg_w(gspca_dev, 0x0309);
+ }
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
- static __u8 ffd9[] = { 0xff, 0xd9 };
+ static u8 ffd9[] = { 0xff, 0xd9 };
if (data[0] == 0x5a) {
/* Control Packet, after this came the header again,
@@ -1172,8 +1218,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 94163cceb28..9f243d7e311 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -31,7 +31,6 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
__u16 brightness;
- __u16 contrast;
__u8 packet;
};
@@ -39,38 +38,22 @@ struct sd {
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Brightness",
.minimum = 1,
- .maximum = 0x2ff,
+ .maximum = 0x15f, /* = 352 - 1 */
.step = 1,
- .default_value = 0x18f,
+#define BRIGHTNESS_DEF 0x14c
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
},
-#define SD_CONTRAST 1
- {
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 0xffff,
- .step = 1,
- .default_value = 0x7fff,
- },
- .set = sd_setcontrast,
- .get = sd_getcontrast,
- },
};
static const struct v4l2_pix_format sif_mode[] = {
@@ -86,78 +69,64 @@ static const struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};
-/*
- * Initialization data: this is the first set-up data written to the
- * device (before the open data).
- */
-#define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */
-#define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */
-#define TESTLINE 0x81 /* reg 0x29 -> 0x81 */
-#define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */
-#define TESTPTL 0x14 /* reg 0x2D -> 0x14 */
-#define TESTPTH 0x01 /* reg 0x2E -> 0x01 */
-#define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */
-#define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */
-#define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */
-#define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */
-#define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */
-#define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */
-#define EXPOL 0x8f /* reg 0x1c -> 0x8f */
-#define EXPOH 0x01 /* reg 0x1d -> 0x01 */
-#define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */
-#define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */
-#define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */
-#define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */
-#define TV8532_CMD_UPDATE 0x84
-
-#define TV8532_EEprom_Add 0x03
-#define TV8532_EEprom_DataL 0x04
-#define TV8532_EEprom_DataM 0x05
-#define TV8532_EEprom_DataH 0x06
-#define TV8532_EEprom_TableLength 0x07
-#define TV8532_EEprom_Write 0x08
-#define TV8532_PART_CTRL 0x00
-#define TV8532_CTRL 0x01
-#define TV8532_CMD_EEprom_Open 0x30
-#define TV8532_CMD_EEprom_Close 0x29
-#define TV8532_UDP_UPDATE 0x31
-#define TV8532_GPIO 0x39
-#define TV8532_GPIO_OE 0x3B
-#define TV8532_REQ_RegWrite 0x02
-#define TV8532_REQ_RegRead 0x03
-
-#define TV8532_ADWIDTH_L 0x0C
-#define TV8532_ADWIDTH_H 0x0D
-#define TV8532_ADHEIGHT_L 0x0E
-#define TV8532_ADHEIGHT_H 0x0F
-#define TV8532_EXPOSURE 0x1C
-#define TV8532_QUANT_COMP 0x28
-#define TV8532_MODE_PACKET 0x29
-#define TV8532_SETCLK 0x2C
-#define TV8532_POINT_L 0x2D
-#define TV8532_POINT_H 0x2E
-#define TV8532_POINTB_L 0x2F
-#define TV8532_POINTB_H 0x30
-#define TV8532_BUDGET_L 0x2A
-#define TV8532_BUDGET_H 0x2B
-#define TV8532_VID_L 0x34
-#define TV8532_VID_H 0x35
-#define TV8532_PID_L 0x36
-#define TV8532_PID_H 0x37
-#define TV8532_DeviceID 0x83
-#define TV8532_AD_SLOPE 0x91
-#define TV8532_AD_BITCTRL 0x94
-#define TV8532_AD_COLBEGIN_L 0x10
-#define TV8532_AD_COLBEGIN_H 0x11
-#define TV8532_AD_ROWBEGIN_L 0x14
-#define TV8532_AD_ROWBEGIN_H 0x15
-
-static const __u32 tv_8532_eeprom_data[] = {
-/* add dataL dataM dataH */
- 0x00010001, 0x01018011, 0x02050014, 0x0305001c,
- 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b,
- 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9,
- 0x0c0509f1, 0
+/* TV-8532A (ICM532A) registers (LE) */
+#define R00_PART_CONTROL 0x00
+#define LATENT_CHANGE 0x80
+#define EXPO_CHANGE 0x04
+#define R01_TIMING_CONTROL_LOW 0x01
+#define CMD_EEprom_Open 0x30
+#define CMD_EEprom_Close 0x29
+#define R03_TABLE_ADDR 0x03
+#define R04_WTRAM_DATA_L 0x04
+#define R05_WTRAM_DATA_M 0x05
+#define R06_WTRAM_DATA_H 0x06
+#define R07_TABLE_LEN 0x07
+#define R08_RAM_WRITE_ACTION 0x08
+#define R0C_AD_WIDTHL 0x0c
+#define R0D_AD_WIDTHH 0x0d
+#define R0E_AD_HEIGHTL 0x0e
+#define R0F_AD_HEIGHTH 0x0f
+#define R10_AD_COL_BEGINL 0x10
+#define R11_AD_COL_BEGINH 0x11
+#define MIRROR 0x04 /* [10] */
+#define R14_AD_ROW_BEGINL 0x14
+#define R15_AD_ROWBEGINH 0x15
+#define R1C_AD_EXPOSE_TIMEL 0x1c
+#define R28_QUANT 0x28
+#define R29_LINE 0x29
+#define R2C_POLARITY 0x2c
+#define R2D_POINT 0x2d
+#define R2E_POINTH 0x2e
+#define R2F_POINTB 0x2f
+#define R30_POINTBH 0x30
+#define R31_UPD 0x31
+#define R2A_HIGH_BUDGET 0x2a
+#define R2B_LOW_BUDGET 0x2b
+#define R34_VID 0x34
+#define R35_VIDH 0x35
+#define R36_PID 0x36
+#define R37_PIDH 0x37
+#define R39_Test1 0x39 /* GPIO */
+#define R3B_Test3 0x3B /* GPIO */
+#define R83_AD_IDH 0x83
+#define R91_AD_SLOPEREG 0x91
+#define R94_AD_BITCONTROL 0x94
+
+static const u8 eeprom_data[][3] = {
+/* dataH dataM dataL */
+ {0x01, 0x00, 0x01},
+ {0x01, 0x80, 0x11},
+ {0x05, 0x00, 0x14},
+ {0x05, 0x00, 0x1c},
+ {0x0d, 0x00, 0x1e},
+ {0x05, 0x00, 0x1f},
+ {0x05, 0x05, 0x19},
+ {0x05, 0x01, 0x1b},
+ {0x05, 0x09, 0x1e},
+ {0x0d, 0x89, 0x2e},
+ {0x05, 0x89, 0x2f},
+ {0x05, 0x0d, 0xd9},
+ {0x05, 0x09, 0xf1},
};
static int reg_r(struct gspca_dev *gspca_dev,
@@ -165,7 +134,7 @@ static int reg_r(struct gspca_dev *gspca_dev,
{
usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegRead,
+ 0x03,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 1,
@@ -174,27 +143,27 @@ static int reg_r(struct gspca_dev *gspca_dev,
}
/* write 1 byte */
-static void reg_w_1(struct gspca_dev *gspca_dev,
+static void reg_w1(struct gspca_dev *gspca_dev,
__u16 index, __u8 value)
{
gspca_dev->usb_buf[0] = value;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegWrite,
+ 0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 1, 500);
}
/* write 2 bytes */
-static void reg_w_2(struct gspca_dev *gspca_dev,
- __u16 index, __u8 val1, __u8 val2)
+static void reg_w2(struct gspca_dev *gspca_dev,
+ u16 index, u16 value)
{
- gspca_dev->usb_buf[0] = val1;
- gspca_dev->usb_buf[1] = val2;
+ gspca_dev->usb_buf[0] = value;
+ gspca_dev->usb_buf[1] = value >> 8;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegWrite,
+ 0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 2, 500);
@@ -202,32 +171,18 @@ static void reg_w_2(struct gspca_dev *gspca_dev,
static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev)
{
- int i = 0;
- __u8 reg, data0, data1, data2;
-
- reg_w_1(gspca_dev, TV8532_GPIO, 0xb0);
- reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open);
-/* msleep(1); */
- while (tv_8532_eeprom_data[i]) {
- reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24;
- reg_w_1(gspca_dev, TV8532_EEprom_Add, reg);
- /* msleep(1); */
- data0 = (tv_8532_eeprom_data[i] & 0x000000ff);
- reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0);
- /* msleep(1); */
- data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8;
- reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1);
- /* msleep(1); */
- data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16;
- reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2);
- /* msleep(1); */
- reg_w_1(gspca_dev, TV8532_EEprom_Write, 0);
- /* msleep(10); */
- i++;
+ int i;
+
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Open);
+ for (i = 0; i < ARRAY_SIZE(eeprom_data); i++) {
+ reg_w1(gspca_dev, R03_TABLE_ADDR, i);
+ reg_w1(gspca_dev, R04_WTRAM_DATA_L, eeprom_data[i][2]);
+ reg_w1(gspca_dev, R05_WTRAM_DATA_M, eeprom_data[i][1]);
+ reg_w1(gspca_dev, R06_WTRAM_DATA_H, eeprom_data[i][0]);
+ reg_w1(gspca_dev, R08_RAM_WRITE_ACTION, 0);
}
- reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i);
-/* msleep(1); */
- reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close);
+ reg_w1(gspca_dev, R07_TABLE_LEN, i);
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
msleep(10);
}
@@ -238,79 +193,76 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- tv_8532WriteEEprom(gspca_dev);
-
cam = &gspca_dev->cam;
- cam->epaddr = 1;
cam->cam_mode = sif_mode;
- cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+ cam->nmodes = ARRAY_SIZE(sif_mode);
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
- sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->brightness = BRIGHTNESS_DEF;
return 0;
}
static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev)
{
- __u8 data;
-
- data = reg_r(gspca_dev, 0x0001);
- PDEBUG(D_USBI, "register 0x01-> %x", data);
- data = reg_r(gspca_dev, 0x0002);
- PDEBUG(D_USBI, "register 0x02-> %x", data);
- reg_r(gspca_dev, TV8532_ADWIDTH_L);
- reg_r(gspca_dev, TV8532_ADWIDTH_H);
- reg_r(gspca_dev, TV8532_QUANT_COMP);
- reg_r(gspca_dev, TV8532_MODE_PACKET);
- reg_r(gspca_dev, TV8532_SETCLK);
- reg_r(gspca_dev, TV8532_POINT_L);
- reg_r(gspca_dev, TV8532_POINT_H);
- reg_r(gspca_dev, TV8532_POINTB_L);
- reg_r(gspca_dev, TV8532_POINTB_H);
- reg_r(gspca_dev, TV8532_BUDGET_L);
- reg_r(gspca_dev, TV8532_BUDGET_H);
- reg_r(gspca_dev, TV8532_VID_L);
- reg_r(gspca_dev, TV8532_VID_H);
- reg_r(gspca_dev, TV8532_PID_L);
- reg_r(gspca_dev, TV8532_PID_H);
- reg_r(gspca_dev, TV8532_DeviceID);
- reg_r(gspca_dev, TV8532_AD_COLBEGIN_L);
- reg_r(gspca_dev, TV8532_AD_COLBEGIN_H);
- reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L);
- reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H);
+ int i;
+ static u8 reg_tb[] = {
+ R0C_AD_WIDTHL,
+ R0D_AD_WIDTHH,
+ R28_QUANT,
+ R29_LINE,
+ R2C_POLARITY,
+ R2D_POINT,
+ R2E_POINTH,
+ R2F_POINTB,
+ R30_POINTBH,
+ R2A_HIGH_BUDGET,
+ R2B_LOW_BUDGET,
+ R34_VID,
+ R35_VIDH,
+ R36_PID,
+ R37_PIDH,
+ R83_AD_IDH,
+ R10_AD_COL_BEGINL,
+ R11_AD_COL_BEGINH,
+ R14_AD_ROW_BEGINL,
+ R15_AD_ROWBEGINH,
+ 0
+ };
+
+ i = 0;
+ do {
+ reg_r(gspca_dev, reg_tb[i]);
+ i++;
+ } while (reg_tb[i] != 0);
}
static void tv_8532_setReg(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
- ADCBEGINL); /* 0x10 */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
- ADCBEGINH); /* also digital gain */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
-
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a);
+ reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+ /* begin active line */
+ reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+ /* mirror and digital gain */
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* = 0x84 */
+
+ reg_w1(gspca_dev, R3B_Test3, 0x0a); /* Test0Sel = 10 */
/******************************************************/
- reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */
- reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */
- reg_w_2(gspca_dev, TV8532_EXPOSURE,
- EXPOL, EXPOH); /* 350d 0x014c; 1c */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
- ADCBEGINL); /* 0x10 */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
- ADCBEGINH); /* also digital gain */
- reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L,
- ADRBEGINL); /* 0x14 */
-
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */
-
- reg_w_1(gspca_dev, TV8532_CTRL,
- TV8532_CMD_EEprom_Close); /* 0x01 */
-
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90);
+ reg_w1(gspca_dev, R0F_AD_HEIGHTH, 0x01);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+ reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+ /* begin active line */
+ reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+ /* mirror and digital gain */
+ reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02);
+
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* = 0x84 */
}
static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
@@ -319,54 +271,55 @@ static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
/* strange polling from tgc */
for (i = 0; i < 10; i++) {
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+ reg_w1(gspca_dev, R00_PART_CONTROL,
+ LATENT_CHANGE | EXPO_CHANGE);
+ reg_w1(gspca_dev, R31_UPD, 0x01);
}
}
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ tv_8532WriteEEprom(gspca_dev);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
+ * slope rate 2 */
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
tv_8532ReadRegisters(gspca_dev);
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
- reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL,
- ADHEIGHH); /* 401d 0x0169; 0e */
- reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL,
- EXPOH); /* 350d 0x014c; 1c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+ reg_w1(gspca_dev, R3B_Test3, 0x0b);
+ reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+ reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8);
+ reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
/*******************************************************************/
- reg_w_1(gspca_dev, TV8532_QUANT_COMP,
- TESTCOMP); /* 0x72 compressed mode 0x28 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R28_QUANT, 0x90);
+ /* no compress - fixed Q - quant 0 */
+ reg_w1(gspca_dev, R29_LINE, 0x81);
+ /* 0x84; // CIF | 4 packet 0x29 */
/************************************************/
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_POINT_L,
- TESTPTL); /* 0x38; 0x2d */
- reg_w_1(gspca_dev, TV8532_POINT_H,
- TESTPTH); /* 0x04; 0x2e */
- reg_w_1(gspca_dev, TV8532_POINTB_L,
- TESTPTBL); /* 0x04; 0x2f */
- reg_w_1(gspca_dev, TV8532_POINTB_H,
- TESTPTBH); /* 0x04; 0x30 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+ /* 0x48; //0x08; 0x2c */
+ reg_w1(gspca_dev, R2D_POINT, 0x14);
+ /* 0x38; 0x2d */
+ reg_w1(gspca_dev, R2E_POINTH, 0x01);
+ /* 0x04; 0x2e */
+ reg_w1(gspca_dev, R2F_POINTB, 0x12);
+ /* 0x04; 0x2f */
+ reg_w1(gspca_dev, R30_POINTBH, 0x01);
+ /* 0x04; 0x30 */
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* 0x00<-0x84 */
/*************************************************/
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
msleep(200);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
/*************************************************/
tv_8532_setReg(gspca_dev);
/*************************************************/
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
/*************************************************/
tv_8532_setReg(gspca_dev);
/*************************************************/
@@ -377,11 +330,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int brightness = sd->brightness;
- reg_w_2(gspca_dev, TV8532_EXPOSURE,
- brightness >> 8, brightness); /* 1c */
- reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->brightness);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* 0x84 */
}
/* -- start the camera -- */
@@ -389,57 +341,50 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
+ * slope rate 2 */
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
tv_8532ReadRegisters(gspca_dev);
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
- reg_w_2(gspca_dev, TV8532_ADHEIGHT_L,
- ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */
-/* reg_w_2(gspca_dev, TV8532_EXPOSURE,
- EXPOL, EXPOH); * 350d 0x014c; 1c */
+ reg_w1(gspca_dev, R3B_Test3, 0x0b);
+
+ reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
setbrightness(gspca_dev);
- reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+ reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); /* 0x20; 0x0c */
+ reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
/************************************************/
- reg_w_1(gspca_dev, TV8532_QUANT_COMP,
- TESTCOMP); /* 0x72 compressed mode 0x28 */
+ reg_w1(gspca_dev, R28_QUANT, 0x90);
+ /* 0x72 compressed mode 0x28 */
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
/* 176x144 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R29_LINE, 0x41);
+ /* CIF - 2 lines/packet */
} else {
/* 352x288 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R29_LINE, 0x81);
+ /* CIF - 2 lines/packet */
}
/************************************************/
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_POINT_L,
- TESTPTL); /* 0x38; 0x2d */
- reg_w_1(gspca_dev, TV8532_POINT_H,
- TESTPTH); /* 0x04; 0x2e */
- reg_w_1(gspca_dev, TV8532_POINTB_L,
- TESTPTBL); /* 0x04; 0x2f */
- reg_w_1(gspca_dev, TV8532_POINTB_H,
- TESTPTBH); /* 0x04; 0x30 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10); /* slow clock */
+ reg_w1(gspca_dev, R2D_POINT, 0x14);
+ reg_w1(gspca_dev, R2E_POINTH, 0x01);
+ reg_w1(gspca_dev, R2F_POINTB, 0x12);
+ reg_w1(gspca_dev, R30_POINTBH, 0x01);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
/************************************************/
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
msleep(200);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
/************************************************/
tv_8532_setReg(gspca_dev);
/************************************************/
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
/************************************************/
tv_8532_setReg(gspca_dev);
/************************************************/
tv_8532_PollReg(gspca_dev);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
gspca_dev->empty_packet = 0; /* check the empty packets */
sd->packet = 0; /* ignore the first packets */
@@ -449,7 +394,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -473,9 +418,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* each packet contains:
* - header 2 bytes
- * - RG line
+ * - RGRG line
* - 4 bytes
- * - GB line
+ * - GBGB line
* - 4 bytes
*/
gspca_frame_add(gspca_dev, packet_type0,
@@ -484,10 +429,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
frame, data + gspca_dev->width + 6, gspca_dev->width);
}
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -506,24 +447,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
- return 0;
-}
-
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -570,8 +493,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 0525ea51a6d..4c802fb12cd 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -37,18 +37,21 @@ struct sd {
__u8 lightfreq;
__u8 sharpness;
+ u8 image_offset;
+
char bridge;
#define BRIDGE_VC0321 0
#define BRIDGE_VC0323 1
char sensor;
#define SENSOR_HV7131R 0
#define SENSOR_MI0360 1
-#define SENSOR_MI1320 2
-#define SENSOR_MI1310_SOC 3
-#define SENSOR_OV7660 4
-#define SENSOR_OV7670 5
-#define SENSOR_PO1200 6
-#define SENSOR_PO3130NC 7
+#define SENSOR_MI1310_SOC 2
+#define SENSOR_MI1320 3
+#define SENSOR_MI1320_SOC 4
+#define SENSOR_OV7660 5
+#define SENSOR_OV7670 6
+#define SENSOR_PO1200 7
+#define SENSOR_PO3130NC 8
};
/* V4L2 controls supported by the driver */
@@ -149,8 +152,50 @@ static const struct v4l2_pix_format vc0323_mode[] = {
.sizeimage = 640 * 480 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv = 0},
+ {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi13x0_soc only */
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 1 / 4 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+};
+static const struct v4l2_pix_format bi_mode[] = {
+/*fixme: jeg does not work
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 5},
+*/
+ {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 4},
+/*
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 3},
+*/
+ {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+/*
+ {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 1 / 4 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+*/
+ {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
};
-
static const struct v4l2_pix_format svga_mode[] = {
{800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 800,
@@ -400,92 +445,208 @@ static const __u8 mi0360_initQVGA_JPG[][4] = {
static const __u8 mi1310_socinitVGA_JPG[][4] = {
{0xb0, 0x03, 0x19, 0xcc},
{0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
{0xb3, 0x08, 0x01, 0xcc},
{0xb3, 0x09, 0x0c, 0xcc},
{0xb3, 0x34, 0x02, 0xcc},
{0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
{0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
{0xb3, 0x20, 0x00, 0xcc},
{0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
{0xb3, 0x14, 0x00, 0xcc},
{0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0xd0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb},
- {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x13, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
{0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
{0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb},
- {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb},
- {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb},
- {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb},
- {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb},
- {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb},
- {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
{0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb},
- {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb},
- {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb},
- {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb},
- {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb},
- {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb},
- {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb},
- {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb},
- {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc},
- {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x0f, 0xbb},
{0xb6, 0x00, 0x00, 0xcc},
{0xb6, 0x03, 0x02, 0xcc},
{0xb6, 0x02, 0x80, 0xcc},
{0xb6, 0x05, 0x01, 0xcc},
{0xb6, 0x04, 0xe0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x25, 0xcc},
+ {0xb6, 0x12, 0x78, 0xcc},
{0xb6, 0x18, 0x02, 0xcc},
{0xb6, 0x17, 0x58, 0xcc},
{0xb6, 0x16, 0x00, 0xcc},
{0xb6, 0x22, 0x12, 0xcc},
{0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
{0xbf, 0xc0, 0x39, 0xcc},
{0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x0a, 0xcc},
+ {0xb9, 0x14, 0x0a, 0xcc},
+ {0xb9, 0x15, 0x0a, 0xcc},
+ {0xb9, 0x16, 0x0a, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x0f, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0x03, 0x03, 0xc0, 0xbb},
+ {0x06, 0x00, 0x10, 0xbb},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
+ {},
+};
+static const __u8 mi1310_socinitQVGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x13, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x0f, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x01, 0xcc},
+ {0xb6, 0x02, 0x40, 0xcc},
+ {0xb6, 0x05, 0x00, 0xcc},
+ {0xb6, 0x04, 0xf0, 0xcc},
+ {0xb6, 0x12, 0x78, 0xcc},
+ {0xb6, 0x18, 0x00, 0xcc},
+ {0xb6, 0x17, 0x96, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x0a, 0xcc},
+ {0xb9, 0x14, 0x0a, 0xcc},
+ {0xb9, 0x15, 0x0a, 0xcc},
+ {0xb9, 0x16, 0x0a, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x0f, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
{0xbc, 0x02, 0x18, 0xcc},
{0xbc, 0x03, 0x50, 0xcc},
{0xbc, 0x04, 0x18, 0xcc},
@@ -496,131 +657,123 @@ static const __u8 mi1310_socinitVGA_JPG[][4] = {
{0xbc, 0x0a, 0x10, 0xcc},
{0xbc, 0x0b, 0x00, 0xcc},
{0xbc, 0x0c, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb},
- {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb},
- {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb},
- {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb},
- {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb},
- {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb},
- {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb},
- {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb},
- {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb},
- {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb},
- {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb},
- {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb},
- {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb},
- {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb},
- {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb},
- {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb},
- {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb},
- {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb},
- {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x34, 0x0c, 0x50, 0xbb},
{0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
{0x03, 0x03, 0xc0, 0xbb},
+ {0x06, 0x00, 0x10, 0xbb},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
{},
};
-static const __u8 mi1310_socinitQVGA_JPG[][4] = {
- {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc},
- {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc},
- {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb},
- {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb},
- {0x03, 0x03, 0xc0, 0xbb},
- {},
+static const u8 mi1310_soc_InitSXGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb8, 0x06, 0x00, 0xcc},
+ {0xb8, 0x07, 0x05, 0xcc},
+ {0xb8, 0x08, 0x00, 0xcc},
+ {0xb8, 0x09, 0x04, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x11, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x05, 0xcc},
+ {0xb6, 0x02, 0x00, 0xcc},
+ {0xb6, 0x05, 0x04, 0xcc},
+ {0xb6, 0x04, 0x00, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x18, 0x0a, 0xcc},
+ {0xb6, 0x17, 0x00, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x14, 0xcc},
+ {0xb9, 0x14, 0x14, 0xcc},
+ {0xb9, 0x15, 0x14, 0xcc},
+ {0xb9, 0x16, 0x14, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x1e, 0xcc},
+ {0xb9, 0x1a, 0x1e, 0xcc},
+ {0xb9, 0x1b, 0x1e, 0xcc},
+ {0xb9, 0x1c, 0x1e, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
+ {}
};
static const __u8 mi1320_gamma[17] = {
@@ -778,6 +931,722 @@ static const __u8 mi1320_initQVGA_data[][4] = {
{}
};
+static const u8 mi1320_soc_InitVGA[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitVGA_JPG[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x02, 0xcc},
+ {0xb6, 0x02, 0x80, 0xcc},
+ {0xb6, 0x05, 0x01, 0xcc},
+ {0xb6, 0x04, 0xe0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x05, 0xcc},
+ {0xb6, 0x18, 0x02, 0xcc},
+ {0xb6, 0x17, 0x58, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitQVGA[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc},
+ {0xbc, 0x02, 0x18, 0xcc},
+ {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc},
+ {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc},
+ {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitQVGA_JPG[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x01, 0xcc},
+ {0xb6, 0x02, 0x40, 0xcc},
+ {0xb6, 0x05, 0x00, 0xcc},
+ {0xb6, 0x04, 0xf0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x05, 0xcc},
+ {0xb6, 0x18, 0x00, 0xcc},
+ {0xb6, 0x17, 0x96, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xbc, 0x02, 0x18, 0xcc},
+ {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc},
+ {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc},
+ {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitSXGA_JPG[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x33, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x00, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xc8, 0x9f, 0x0b, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0x5b, 0x00, 0x01, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x05, 0xcc},
+ {0xb6, 0x02, 0x00, 0xcc},
+ {0xb6, 0x05, 0x04, 0xcc},
+ {0xb6, 0x04, 0x00, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x29, 0xcc},
+ {0xb6, 0x18, 0x0a, 0xcc},
+ {0xb6, 0x17, 0x00, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x13, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x00, 0x85, 0xbb},
+ {0x08, 0x00, 0x27, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0x0d, 0xbb},
+ {0x3a, 0x06, 0x1b, 0xbb},
+ {0x3b, 0x00, 0x95, 0xbb},
+ {0x3c, 0x04, 0xdb, 0xbb},
+ {0x57, 0x02, 0x00, 0xbb},
+ {0x58, 0x02, 0x66, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0x5a, 0x01, 0x33, 0xbb},
+ {0x5c, 0x12, 0x0d, 0xbb},
+ {0x5d, 0x16, 0x11, 0xbb},
+ {0x64, 0x5e, 0x1c, 0xbb},
+ {0x2f, 0x90, 0x00, 0xbb},
+ {}
+};
+static const u8 mi1320_soc_InitSXGA[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xc8, 0x9f, 0x0b, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0x5b, 0x00, 0x01, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x13, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x00, 0x85, 0xbb},
+ {0x08, 0x00, 0x27, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0x0d, 0xbb},
+ {0x3a, 0x06, 0x1b, 0xbb},
+ {0x3b, 0x00, 0x95, 0xbb},
+ {0x3c, 0x04, 0xdb, 0xbb},
+ {0x57, 0x02, 0x00, 0xbb},
+ {0x58, 0x02, 0x66, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0x5a, 0x01, 0x33, 0xbb},
+ {0x5c, 0x12, 0x0d, 0xbb},
+ {0x5d, 0x16, 0x11, 0xbb},
+ {0x64, 0x5e, 0x1c, 0xbb},
+ {}
+};
static const __u8 po3130_gamma[17] = {
0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
@@ -1764,26 +2633,43 @@ static const __u8 po1200_initVGA_data[][4] = {
};
struct sensor_info {
- int sensorId;
- __u8 I2cAdd;
- __u8 IdAdd;
- __u16 VpId;
- __u8 m1;
- __u8 m2;
- __u8 op;
- };
+ s8 sensorId;
+ u8 I2cAdd;
+ u8 IdAdd;
+ u16 VpId;
+ u8 m1;
+ u8 m2;
+ u8 op;
+};
static const struct sensor_info sensor_info_data[] = {
/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
- {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
- {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+ {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
+ {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
+/* (tested in vc032x_probe_sensor) */
+/* {-1, 0x80 | 0x20, 0x83, 0x0000, 0x24, 0x25, 0x01}, */
{SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01},
- {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01},
- {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
{SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
/* (tested in vc032x_probe_sensor) */
/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
+ {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
+ {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
+ {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
+ {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, */
+ {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01}, */
+/* {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, */
+ {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
{SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
+ {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01},
+ {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+ {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
+ {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01},
+/*fixme: previously detected?*/
+ {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
+/*fixme: not in the ms-win probe - may be found before?*/
+ {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
};
/* read 'len' bytes in gspca_dev->usb_buf */
@@ -1814,51 +2700,49 @@ static void reg_w(struct usb_device *dev,
500);
}
-static void read_sensor_register(struct gspca_dev *gspca_dev,
- __u16 address, __u16 *value)
+static u16 read_sensor_register(struct gspca_dev *gspca_dev,
+ u16 address)
{
struct usb_device *dev = gspca_dev->dev;
- __u8 ldata, mdata, hdata;
+ u8 ldata, mdata, hdata;
int retry = 50;
- *value = 0;
-
reg_r(gspca_dev, 0xa1, 0xb33f, 1);
- /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */
if (!(gspca_dev->usb_buf[0] & 0x02)) {
- PDEBUG(D_ERR, "I2c Bus Busy Wait %d",
- gspca_dev->usb_buf[0] & 0x02);
- return;
+ PDEBUG(D_ERR, "I2c Bus Busy Wait %02x",
+ gspca_dev->usb_buf[0]);
+ return 0;
}
reg_w(dev, 0xa0, address, 0xb33a);
reg_w(dev, 0xa0, 0x02, 0xb339);
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
- while (retry-- && gspca_dev->usb_buf[0]) {
+ do {
reg_r(gspca_dev, 0xa1, 0xb33b, 1);
-/* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */
- msleep(1);
- }
+ if (gspca_dev->usb_buf[0] == 0x00)
+ break;
+ msleep(40);
+ } while (--retry >= 0);
+
reg_r(gspca_dev, 0xa1, 0xb33e, 1);
ldata = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0xa1, 0xb33d, 1);
mdata = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0xa1, 0xb33c, 1);
hdata = gspca_dev->usb_buf[0];
- PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
- hdata, mdata, ldata);
+ if (hdata != 0 && mdata != 0 && ldata != 0)
+ PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
+ hdata, mdata, ldata);
reg_r(gspca_dev, 0xa1, 0xb334, 1);
if (gspca_dev->usb_buf[0] == 0x02)
- *value = (hdata << 8) + mdata;
- else
- *value = hdata;
+ return (hdata << 8) + mdata;
+ return hdata;
}
static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
int i;
- __u16 value;
+ u16 value;
const struct sensor_info *ptsensor_info;
reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
@@ -1872,48 +2756,51 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
reg_w(dev, 0xa0, 0x0c, 0xb309);
reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
- read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value);
- if (value == ptsensor_info->VpId)
- return ptsensor_info->sensorId;
-
- /* special case for MI0360 */
- if (ptsensor_info->sensorId == SENSOR_MI1310_SOC
- && value == 0x8243)
- return SENSOR_MI0360;
+ value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd);
+ if (value == 0 && ptsensor_info->IdAdd == 0x82)
+ value = read_sensor_register(gspca_dev, 0x83);
+ if (value != 0) {
+ PDEBUG(D_ERR|D_PROBE, "Sensor ID %04x (%d)",
+ value, i);
+ if (value == ptsensor_info->VpId)
+ return ptsensor_info->sensorId;
+
+ switch (value) {
+ case 0x7673:
+ return SENSOR_OV7670;
+ case 0x8243:
+ return SENSOR_MI0360;
+ }
+/*fixme: should return here*/
+ }
}
return -1;
}
-static __u8 i2c_write(struct gspca_dev *gspca_dev,
- __u8 reg, const __u8 *val, __u8 size)
+static void i2c_write(struct gspca_dev *gspca_dev,
+ u8 reg, const u8 *val,
+ u8 size) /* 1 or 2 */
{
struct usb_device *dev = gspca_dev->dev;
+ int retry;
- if (size > 3 || size < 1)
- return -EINVAL;
reg_r(gspca_dev, 0xa1, 0xb33f, 1);
+/*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/
reg_w(dev, 0xa0, size, 0xb334);
reg_w(dev, 0xa0, reg, 0xb33a);
- switch (size) {
- case 1:
- reg_w(dev, 0xa0, val[0], 0xb336);
- break;
- case 2:
- reg_w(dev, 0xa0, val[0], 0xb336);
+ reg_w(dev, 0xa0, val[0], 0xb336);
+ if (size > 1)
reg_w(dev, 0xa0, val[1], 0xb337);
- break;
- case 3:
- reg_w(dev, 0xa0, val[0], 0xb336);
- reg_w(dev, 0xa0, val[1], 0xb337);
- reg_w(dev, 0xa0, val[2], 0xb338);
- break;
- default:
- reg_w(dev, 0xa0, 0x01, 0xb334);
- return -EINVAL;
- }
reg_w(dev, 0xa0, 0x01, 0xb339);
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
- return gspca_dev->usb_buf[0] == 0;
+ retry = 4;
+ do {
+ reg_r(gspca_dev, 0xa1, 0xb33b, 1);
+ if (gspca_dev->usb_buf[0] == 0)
+ break;
+ msleep(20);
+ } while (--retry > 0);
+ if (retry <= 0)
+ PDEBUG(D_ERR, "i2c_write failed");
}
static void put_tab_to_reg(struct gspca_dev *gspca_dev,
@@ -1938,7 +2825,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
return;
case 0xcc: /* normal write */
reg_w(dev, 0xa0, data[i][2],
- ((data[i][0])<<8) | data[i][1]);
+ (data[i][0]) << 8 | data[i][1]);
break;
case 0xaa: /* i2c op */
i2c_write(gspca_dev, data[i][1], &data[i][2], 1);
@@ -1955,19 +2842,6 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
/*not reached*/
}
-/*
- "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff
- "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66
- */
-
-static void vc0321_reset(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d);
- reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301);
- msleep(100);
- reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003);
- msleep(100);
-}
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
@@ -1979,10 +2853,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
int sensor;
cam = &gspca_dev->cam;
- cam->epaddr = 0x02;
sd->bridge = id->driver_info;
-
- vc0321_reset(gspca_dev);
sensor = vc032x_probe_sensor(gspca_dev);
switch (sensor) {
case -1:
@@ -2001,6 +2872,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
case SENSOR_MI1320:
PDEBUG(D_PROBE, "Find Sensor MI1320");
break;
+ case SENSOR_MI1320_SOC:
+ PDEBUG(D_PROBE, "Find Sensor MI1320_SOC");
+ break;
case SENSOR_OV7660:
PDEBUG(D_PROBE, "Find Sensor OV7660");
break;
@@ -2020,12 +2894,23 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = vc0321_mode;
cam->nmodes = ARRAY_SIZE(vc0321_mode);
} else {
- if (sensor != SENSOR_PO1200) {
- cam->cam_mode = vc0323_mode;
- cam->nmodes = ARRAY_SIZE(vc0323_mode);
- } else {
+ switch (sensor) {
+ case SENSOR_PO1200:
cam->cam_mode = svga_mode;
cam->nmodes = ARRAY_SIZE(svga_mode);
+ break;
+ case SENSOR_MI1310_SOC:
+ cam->cam_mode = vc0323_mode;
+ cam->nmodes = ARRAY_SIZE(vc0323_mode);
+ break;
+ case SENSOR_MI1320_SOC:
+ cam->cam_mode = bi_mode;
+ cam->nmodes = ARRAY_SIZE(bi_mode);
+ break;
+ default:
+ cam->cam_mode = vc0323_mode;
+ cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1;
+ break;
}
}
@@ -2061,7 +2946,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
return 0;
}
-/* this function is called at probe and time */
+/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
return 0;
@@ -2124,9 +3009,18 @@ static void setsharpness(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ const __u8 (*init)[4];
const __u8 *GammaT = NULL;
const __u8 *MatrixT = NULL;
int mode;
+ static const u8 (*mi1320_soc_init[])[4] = {
+ mi1320_soc_InitSXGA,
+ mi1320_soc_InitSXGA_JPG,
+ mi1320_soc_InitVGA,
+ mi1320_soc_InitVGA_JPG,
+ mi1320_soc_InitQVGA,
+ mi1320_soc_InitQVGA_JPG
+ };
/* Assume start use the good resolution from gspca_dev->mode */
if (sd->bridge == BRIDGE_VC0321) {
@@ -2134,6 +3028,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed);
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee);
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef);
+ sd->image_offset = 46;
+ } else {
+ if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].pixelformat
+ == V4L2_PIX_FMT_JPEG)
+ sd->image_offset = 0;
+ else
+ sd->image_offset = 32;
}
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -2141,115 +3042,87 @@ static int sd_start(struct gspca_dev *gspca_dev)
case SENSOR_HV7131R:
GammaT = hv7131r_gamma;
MatrixT = hv7131r_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, hv7131r_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, hv7131r_initVGA_data);
- }
+ if (mode)
+ init = hv7131r_initQVGA_data; /* 320x240 */
+ else
+ init = hv7131r_initVGA_data; /* 640x480 */
break;
case SENSOR_OV7660:
GammaT = ov7660_gamma;
MatrixT = ov7660_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, ov7660_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, ov7660_initVGA_data);
- }
+ if (mode)
+ init = ov7660_initQVGA_data; /* 320x240 */
+ else
+ init = ov7660_initVGA_data; /* 640x480 */
break;
case SENSOR_OV7670:
/*GammaT = ov7660_gamma; */
/*MatrixT = ov7660_matrix; */
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, ov7670_initQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, ov7670_initVGA_JPG);
- }
+ if (mode)
+ init = ov7670_initQVGA_JPG; /* 320x240 */
+ else
+ init = ov7670_initVGA_JPG; /* 640x480 */
break;
case SENSOR_MI0360:
GammaT = mi1320_gamma;
MatrixT = mi0360_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi0360_initQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi0360_initVGA_JPG);
- }
+ if (mode)
+ init = mi0360_initQVGA_JPG; /* 320x240 */
+ else
+ init = mi0360_initVGA_JPG; /* 640x480 */
break;
case SENSOR_MI1310_SOC:
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi1310_socinitVGA_JPG);
+ GammaT = mi1320_gamma;
+ MatrixT = mi1320_matrix;
+ switch (mode) {
+ case 1:
+ init = mi1310_socinitQVGA_JPG; /* 320x240 */
+ break;
+ case 0:
+ init = mi1310_socinitVGA_JPG; /* 640x480 */
+ break;
+ default:
+ init = mi1310_soc_InitSXGA_JPG; /* 1280x1024 */
+ break;
}
break;
case SENSOR_MI1320:
GammaT = mi1320_gamma;
MatrixT = mi1320_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi1320_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi1320_initVGA_data);
- }
+ if (mode)
+ init = mi1320_initQVGA_data; /* 320x240 */
+ else
+ init = mi1320_initVGA_data; /* 640x480 */
+ break;
+ case SENSOR_MI1320_SOC:
+ GammaT = mi1320_gamma;
+ MatrixT = mi1320_matrix;
+ init = mi1320_soc_init[mode];
break;
case SENSOR_PO3130NC:
GammaT = po3130_gamma;
MatrixT = po3130_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, po3130_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, po3130_initVGA_data);
- }
- usb_exchange(gspca_dev, po3130_rundata);
+ if (mode)
+ init = po3130_initQVGA_data; /* 320x240 */
+ else
+ init = po3130_initVGA_data; /* 640x480 */
+ usb_exchange(gspca_dev, init);
+ init = po3130_rundata;
break;
- case SENSOR_PO1200:
+ default:
+/* case SENSOR_PO1200: */
GammaT = po1200_gamma;
MatrixT = po1200_matrix;
- usb_exchange(gspca_dev, po1200_initVGA_data);
+ init = po1200_initVGA_data;
break;
- default:
- PDEBUG(D_PROBE, "Damned !! no sensor found Bye");
- return -EMEDIUMTYPE;
}
+ usb_exchange(gspca_dev, init);
if (GammaT && MatrixT) {
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a);
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b);
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
- /* Seem SHARPNESS */
- /*
- reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e);
- */
- /* all 0x40 ??? do nothing
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822);
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823);
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824);
- */
- /* Only works for HV7131R ??
- reg_r (gspca_dev, 0xa1, 0xb881, 1);
- reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881);
- reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801);
- */
- /* only hv7131r et ov7660
- reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80
- reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS
- */
/* set the led on 0x0892 0x0896 */
if (sd->sensor != SENSOR_PO1200) {
reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
@@ -2296,12 +3169,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
"vc032x header packet found len %d", len);
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
- if (sd->bridge == BRIDGE_VC0321) {
-#define VCHDRSZ 46
- data += VCHDRSZ;
- len -= VCHDRSZ;
-#undef VCHDRSZ
- }
+ data += sd->image_offset;
+ len -= sd->image_offset;
gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
data, len);
return;
@@ -2399,7 +3268,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
strcpy((char *) menu->name, "50 Hz");
return 0;
- case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+ default:
+/* case 2: * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
strcpy((char *) menu->name, "60 Hz");
return 0;
}
@@ -2424,6 +3294,7 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321},
@@ -2432,6 +3303,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321},
+ {USB_DEVICE(0x15b8, 0x6001), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x15b8, 0x6002), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323},
{}
@@ -2460,8 +3332,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index ec2a53d53fe..4fe01d8b6c8 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -23,6 +23,7 @@
#define MODULE_NAME "zc3xx"
#include "gspca.h"
+#include "jpeg.h"
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, "
"Serge A. Suchkov <Serge.A.S@tochka.ru>");
@@ -31,7 +32,7 @@ MODULE_LICENSE("GPL");
static int force_sensor = -1;
-#include "jpeg.h"
+#define QUANT_VAL 1 /* quantization table */
#include "zc3xx-reg.h"
/* specific webcam descriptor */
@@ -44,30 +45,36 @@ struct sd {
__u8 autogain;
__u8 lightfreq;
__u8 sharpness;
+ u8 quality; /* image quality */
+#define QUALITY_MIN 40
+#define QUALITY_MAX 60
+#define QUALITY_DEF 50
- char qindex;
signed char sensor; /* Type of image sensor chip */
/* !! values used in different tables */
-#define SENSOR_CS2102 0
-#define SENSOR_CS2102K 1
-#define SENSOR_GC0305 2
-#define SENSOR_HDCS2020b 3
-#define SENSOR_HV7131B 4
-#define SENSOR_HV7131C 5
-#define SENSOR_ICM105A 6
-#define SENSOR_MC501CB 7
-#define SENSOR_OV7620 8
-/*#define SENSOR_OV7648 8 - same values */
-#define SENSOR_OV7630C 9
-#define SENSOR_PAS106 10
-#define SENSOR_PAS202B 11
-#define SENSOR_PB0330 12
-#define SENSOR_PO2030 13
-#define SENSOR_TAS5130CK 14
-#define SENSOR_TAS5130CXX 15
-#define SENSOR_TAS5130C_VF0250 16
-#define SENSOR_MAX 17
+#define SENSOR_ADCM2700 0
+#define SENSOR_CS2102 1
+#define SENSOR_CS2102K 2
+#define SENSOR_GC0305 3
+#define SENSOR_HDCS2020b 4
+#define SENSOR_HV7131B 5
+#define SENSOR_HV7131C 6
+#define SENSOR_ICM105A 7
+#define SENSOR_MC501CB 8
+#define SENSOR_OV7620 9
+/*#define SENSOR_OV7648 9 - same values */
+#define SENSOR_OV7630C 10
+#define SENSOR_PAS106 11
+#define SENSOR_PAS202B 12
+#define SENSOR_PB0330 13
+#define SENSOR_PO2030 14
+#define SENSOR_TAS5130CK 15
+#define SENSOR_TAS5130CXX 16
+#define SENSOR_TAS5130C_VF0250 17
+#define SENSOR_MAX 18
unsigned short chip_revision;
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -206,6 +213,213 @@ struct usb_action {
__u16 idx;
};
+static const struct usb_action adcm2700_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
+ {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
+ {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
+ {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
+ {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
+ {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
+ {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
+ {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
+ {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
+ {0xbb, 0x86, 0x0002}, /* 00,86,02,bb */
+ {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
+ {0xbb, 0x86, 0x0802}, /* 08,86,02,bb */
+ {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
+/*mswin+*/
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xaa, 0xfe, 0x0002},
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xaa, 0xb4, 0xcd37},
+ {0xaa, 0xa4, 0x0004},
+ {0xaa, 0xa8, 0x0007},
+ {0xaa, 0xac, 0x0004},
+/*mswin-*/
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
+ {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
+static const struct usb_action adcm2700_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
+ {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
+ {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
+ {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0050}, /* 00,00,50,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
+ {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
+ {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
+ {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
+ {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
+ {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
+ {0xbb, 0x86, 0x0002}, /* 00,88,02,bb */
+ {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
+ {0xbb, 0x86, 0x0802}, /* 08,88,02,bb */
+ {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
+ /*******/
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
+ {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
+static const struct usb_action adcm2700_50HZ[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */
+ {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */
+ {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */
+ {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
+ {}
+};
+static const struct usb_action adcm2700_60HZ[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
+ {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */
+ {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */
+ {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
+ {}
+};
+static const struct usb_action adcm2700_NoFliker[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
+ {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */
+ {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
static const struct usb_action cs2102_Initial[] = {
{0xa1, 0x01, 0x0008},
{0xa1, 0x01, 0x0008},
@@ -877,7 +1091,7 @@ static const struct usb_action cs2102K_Initial[] = {
};
static const struct usb_action cs2102K_InitialScale[] = {
- {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
{0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
@@ -894,6 +1108,7 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
{0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
{0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+/*fixme: next sequence = i2c exchanges*/
{0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
{0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
@@ -1077,207 +1292,6 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x60, ZC3XX_R116_RGAIN},
{0xa0, 0x40, ZC3XX_R117_GGAIN},
{0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x01, 0x01b1},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
- {0xa0, 0x38, ZC3XX_R121_GAMMA01},
- {0xa0, 0x59, ZC3XX_R122_GAMMA02},
- {0xa0, 0x79, ZC3XX_R123_GAMMA03},
- {0xa0, 0x92, ZC3XX_R124_GAMMA04},
- {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
- {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
- {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
- {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
- {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
- {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x26, ZC3XX_R130_GAMMA10},
- {0xa0, 0x22, ZC3XX_R131_GAMMA11},
- {0xa0, 0x20, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
- {0xa0, 0x16, ZC3XX_R134_GAMMA14},
- {0xa0, 0x13, ZC3XX_R135_GAMMA15},
- {0xa0, 0x10, ZC3XX_R136_GAMMA16},
- {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
- {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
- {0xa0, 0x09, ZC3XX_R139_GAMMA19},
- {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
- {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf4, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf4, ZC3XX_R10D_RGB10},
- {0xa0, 0x58, ZC3XX_R10E_RGB11},
- {0xa0, 0xf4, ZC3XX_R10F_RGB12},
- {0xa0, 0xf4, ZC3XX_R110_RGB20},
- {0xa0, 0xf4, ZC3XX_R111_RGB21},
- {0xa0, 0x58, ZC3XX_R112_RGB22},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
- {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
@@ -1334,6 +1348,7 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+/*fixme:what does the next sequence?*/
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
@@ -6237,7 +6252,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
{}
};
-static int reg_r_i(struct gspca_dev *gspca_dev,
+static u8 reg_r_i(struct gspca_dev *gspca_dev,
__u16 index)
{
usb_control_msg(gspca_dev->dev,
@@ -6250,10 +6265,10 @@ static int reg_r_i(struct gspca_dev *gspca_dev,
return gspca_dev->usb_buf[0];
}
-static int reg_r(struct gspca_dev *gspca_dev,
+static u8 reg_r(struct gspca_dev *gspca_dev,
__u16 index)
{
- int ret;
+ u8 ret;
ret = reg_r_i(gspca_dev, index);
PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret);
@@ -6286,8 +6301,8 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
__u8 retbyte;
__u16 retval;
- reg_w_i(gspca_dev->dev, reg, 0x92);
- reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */
+ reg_w_i(gspca_dev->dev, reg, 0x0092);
+ reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */
msleep(25);
retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
@@ -6332,6 +6347,12 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
action->idx & 0xff, /* valL */
action->idx >> 8); /* valH */
break;
+ case 0xbb:
+ i2c_write(gspca_dev,
+ action->idx >> 8, /* reg */
+ action->idx & 0xff, /* valL */
+ action->val); /* valH */
+ break;
default:
/* case 0xdd: * delay */
msleep(action->val / 64 + 10);
@@ -6347,6 +6368,10 @@ static void setmatrix(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int i;
const __u8 *matrix;
+ static const u8 adcm2700_matrix[9] =
+/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */
+/*ms-win*/
+ {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74};
static const __u8 gc0305_matrix[9] =
{0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
static const __u8 ov7620_matrix[9] =
@@ -6358,23 +6383,24 @@ static void setmatrix(struct gspca_dev *gspca_dev)
static const __u8 vf0250_matrix[9] =
{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
static const __u8 *matrix_tb[SENSOR_MAX] = {
- NULL, /* SENSOR_CS2102 0 */
- NULL, /* SENSOR_CS2102K 1 */
- gc0305_matrix, /* SENSOR_GC0305 2 */
- NULL, /* SENSOR_HDCS2020b 3 */
- NULL, /* SENSOR_HV7131B 4 */
- NULL, /* SENSOR_HV7131C 5 */
- NULL, /* SENSOR_ICM105A 6 */
- NULL, /* SENSOR_MC501CB 7 */
- ov7620_matrix, /* SENSOR_OV7620 8 */
- NULL, /* SENSOR_OV7630C 9 */
- NULL, /* SENSOR_PAS106 10 */
- pas202b_matrix, /* SENSOR_PAS202B 11 */
- NULL, /* SENSOR_PB0330 12 */
- po2030_matrix, /* SENSOR_PO2030 13 */
- NULL, /* SENSOR_TAS5130CK 14 */
- NULL, /* SENSOR_TAS5130CXX 15 */
- vf0250_matrix, /* SENSOR_TAS5130C_VF0250 16 */
+ adcm2700_matrix, /* SENSOR_ADCM2700 0 */
+ NULL, /* SENSOR_CS2102 1 */
+ NULL, /* SENSOR_CS2102K 2 */
+ gc0305_matrix, /* SENSOR_GC0305 3 */
+ NULL, /* SENSOR_HDCS2020b 4 */
+ NULL, /* SENSOR_HV7131B 5 */
+ NULL, /* SENSOR_HV7131C 6 */
+ NULL, /* SENSOR_ICM105A 7 */
+ NULL, /* SENSOR_MC501CB 8 */
+ ov7620_matrix, /* SENSOR_OV7620 9 */
+ NULL, /* SENSOR_OV7630C 10 */
+ NULL, /* SENSOR_PAS106 11 */
+ pas202b_matrix, /* SENSOR_PAS202B 12 */
+ NULL, /* SENSOR_PB0330 13 */
+ po2030_matrix, /* SENSOR_PO2030 14 */
+ NULL, /* SENSOR_TAS5130CK 15 */
+ NULL, /* SENSOR_TAS5130CXX 16 */
+ vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */
};
matrix = matrix_tb[sd->sensor];
@@ -6398,8 +6424,11 @@ 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)
+ switch (sd->sensor) {
+ case SENSOR_ADCM2700:
+ case SENSOR_HV7131B:
return;
+ }
if (brightness < 0x70)
brightness += 0x10;
else
@@ -6536,10 +6565,10 @@ static void setquality(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
- __u8 quality;
__u8 frxt;
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_HV7131B:
case SENSOR_OV7620:
@@ -6547,26 +6576,18 @@ static void setquality(struct gspca_dev *gspca_dev)
return;
}
/*fixme: is it really 0008 0007 0018 for all other sensors? */
- quality = sd->qindex;
- reg_w(dev, quality, 0x0008);
+ reg_w(dev, QUANT_VAL, 0x0008);
frxt = 0x30;
reg_w(dev, frxt, 0x0007);
- switch (quality) {
- case 0:
- case 1:
- case 2:
- frxt = 0xff;
- break;
- case 3:
- frxt = 0xf0;
- break;
- case 4:
- frxt = 0xe0;
- break;
- case 5:
- frxt = 0x20;
- break;
- }
+#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
+ frxt = 0xff;
+#elif QUANT_VAL == 3
+ frxt = 0xf0;
+#elif QUANT_VAL == 4
+ frxt = 0xe0;
+#else
+ frxt = 0x20;
+#endif
reg_w(dev, frxt, 0x0018);
}
@@ -6583,71 +6604,75 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
int i, mode;
const struct usb_action *zc3_freq;
static const struct usb_action *freq_tb[SENSOR_MAX][6] = {
-/* SENSOR_CS2102 0 */
+/* SENSOR_ADCM2700 0 */
+ {adcm2700_NoFliker, adcm2700_NoFliker,
+ adcm2700_50HZ, adcm2700_50HZ,
+ adcm2700_60HZ, adcm2700_60HZ},
+/* SENSOR_CS2102 1 */
{cs2102_NoFliker, cs2102_NoFlikerScale,
cs2102_50HZ, cs2102_50HZScale,
cs2102_60HZ, cs2102_60HZScale},
-/* SENSOR_CS2102K 1 */
+/* SENSOR_CS2102K 2 */
{cs2102_NoFliker, cs2102_NoFlikerScale,
NULL, NULL, /* currently disabled */
NULL, NULL},
-/* SENSOR_GC0305 2 */
+/* SENSOR_GC0305 3 */
{gc0305_NoFliker, gc0305_NoFliker,
gc0305_50HZ, gc0305_50HZ,
gc0305_60HZ, gc0305_60HZ},
-/* SENSOR_HDCS2020b 3 */
+/* SENSOR_HDCS2020b 4 */
{hdcs2020b_NoFliker, hdcs2020b_NoFliker,
hdcs2020b_50HZ, hdcs2020b_50HZ,
hdcs2020b_60HZ, hdcs2020b_60HZ},
-/* SENSOR_HV7131B 4 */
+/* SENSOR_HV7131B 5 */
{hv7131b_NoFlikerScale, hv7131b_NoFliker,
hv7131b_50HZScale, hv7131b_50HZ,
hv7131b_60HZScale, hv7131b_60HZ},
-/* SENSOR_HV7131C 5 */
+/* SENSOR_HV7131C 6 */
{NULL, NULL,
NULL, NULL,
NULL, NULL},
-/* SENSOR_ICM105A 6 */
+/* SENSOR_ICM105A 7 */
{icm105a_NoFliker, icm105a_NoFlikerScale,
icm105a_50HZ, icm105a_50HZScale,
icm105a_60HZ, icm105a_60HZScale},
-/* SENSOR_MC501CB 7 */
+/* SENSOR_MC501CB 8 */
{MC501CB_NoFliker, MC501CB_NoFlikerScale,
MC501CB_50HZ, MC501CB_50HZScale,
MC501CB_60HZ, MC501CB_60HZScale},
-/* SENSOR_OV7620 8 */
+/* SENSOR_OV7620 9 */
{OV7620_NoFliker, OV7620_NoFliker,
OV7620_50HZ, OV7620_50HZ,
OV7620_60HZ, OV7620_60HZ},
-/* SENSOR_OV7630C 9 */
+/* SENSOR_OV7630C 10 */
{NULL, NULL,
NULL, NULL,
NULL, NULL},
-/* SENSOR_PAS106 10 */
+/* SENSOR_PAS106 11 */
{pas106b_NoFliker, pas106b_NoFliker,
pas106b_50HZ, pas106b_50HZ,
pas106b_60HZ, pas106b_60HZ},
-/* SENSOR_PAS202B 11 */
+/* SENSOR_PAS202B 12 */
{pas202b_NoFlikerScale, pas202b_NoFliker,
pas202b_50HZScale, pas202b_50HZ,
pas202b_60HZScale, pas202b_60HZ},
-/* SENSOR_PB0330 12 */
+/* SENSOR_PB0330 13 */
{pb0330_NoFliker, pb0330_NoFlikerScale,
pb0330_50HZ, pb0330_50HZScale,
pb0330_60HZ, pb0330_60HZScale},
-/* SENSOR_PO2030 13 */
+/* SENSOR_PO2030 14 */
{PO2030_NoFliker, PO2030_NoFliker,
PO2030_50HZ, PO2030_50HZ,
PO2030_60HZ, PO2030_60HZ},
-/* SENSOR_TAS5130CK 14 */
+/* SENSOR_TAS5130CK 15 */
{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
tas5130cxx_50HZ, tas5130cxx_50HZScale,
tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130CXX 15 */
+/* SENSOR_TAS5130CXX 16 */
{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
tas5130cxx_50HZ, tas5130cxx_50HZScale,
tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130C_VF0250 16 */
+/* SENSOR_TAS5130C_VF0250 17 */
{tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
@@ -6701,6 +6726,7 @@ static void send_unknown(struct usb_device *dev, int sensor)
reg_w(dev, 0x0c, 0x003b);
reg_w(dev, 0x08, 0x0038);
break;
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PB0330:
@@ -6743,26 +6769,25 @@ static int sif_probe(struct gspca_dev *gspca_dev)
static int vga_2wr_probe(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
- __u8 retbyte;
- __u16 checkword;
+ u16 retword;
start_2wr_probe(dev, 0x00); /* HV7131B */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x00; /* HV7131B */
start_2wr_probe(dev, 0x04); /* CS2102 */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x04; /* CS2102 */
start_2wr_probe(dev, 0x06); /* OmniVision */
reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x11);
- if (retbyte != 0) {
+ retword = i2c_read(gspca_dev, 0x11);
+ if (retword != 0) {
/* (should have returned 0xaa) --> Omnivision? */
/* reg_r 0x10 -> 0x06 --> */
goto ov_check;
@@ -6770,40 +6795,40 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
start_2wr_probe(dev, 0x08); /* HDCS2020 */
i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x15);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x15);
+ if (retword != 0)
return 0x08; /* HDCS2020 */
start_2wr_probe(dev, 0x0a); /* PB0330 */
i2c_write(gspca_dev, 0x07, 0xaa, 0xaa);
- retbyte = i2c_read(gspca_dev, 0x07);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x07);
+ if (retword != 0)
return 0x0a; /* PB0330 */
- retbyte = i2c_read(gspca_dev, 0x03);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x03);
+ if (retword != 0)
return 0x0a; /* PB0330 ?? */
- retbyte = i2c_read(gspca_dev, 0x04);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x04);
+ if (retword != 0)
return 0x0a; /* PB0330 ?? */
start_2wr_probe(dev, 0x0c); /* ICM105A */
i2c_write(gspca_dev, 0x01, 0x11, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x0c; /* ICM105A */
start_2wr_probe(dev, 0x0e); /* PAS202BCB */
reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
msleep(500);
- retbyte = i2c_read(gspca_dev, 0x03);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x03);
+ if (retword != 0)
return 0x0e; /* PAS202BCB */
start_2wr_probe(dev, 0x02); /* ?? */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x02; /* ?? */
ov_check:
reg_r(gspca_dev, 0x0010); /* ?? */
@@ -6817,12 +6842,10 @@ ov_check:
msleep(500);
reg_w(dev, 0x01, 0x0012);
i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */
- retbyte = i2c_read(gspca_dev, 0x0a);
- checkword = retbyte << 8;
- retbyte = i2c_read(gspca_dev, 0x0b);
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword);
- switch (checkword) {
+ retword = i2c_read(gspca_dev, 0x0a) << 8;
+ retword |= i2c_read(gspca_dev, 0x0b);
+ PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword);
+ switch (retword) {
case 0x7631: /* OV7630C */
reg_w(dev, 0x06, 0x0010);
break;
@@ -6832,7 +6855,7 @@ ov_check:
default:
return -1; /* not OmniVision */
}
- return checkword;
+ return retword;
}
struct sensor_by_chipset_revision {
@@ -6845,6 +6868,7 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
{0x8001, 0x13},
{0x8000, 0x14}, /* CS2102K */
{0x8400, 0x15}, /* TAS5130K */
+ {0x4001, 0x16}, /* ADCM2700 */
};
static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6853,7 +6877,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
struct usb_device *dev = gspca_dev->dev;
int i;
__u8 retbyte;
- __u16 checkword;
+ u16 retword;
/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
reg_w(dev, 0x02, 0x0010);
@@ -6865,27 +6889,25 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x14);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x14);
+ if (retword != 0)
return 0x11; /* HV7131R */
- retbyte = i2c_read(gspca_dev, 0x15);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x15);
+ if (retword != 0)
return 0x11; /* HV7131R */
- retbyte = i2c_read(gspca_dev, 0x16);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x16);
+ if (retword != 0)
return 0x11; /* HV7131R */
reg_w(dev, 0x02, 0x0010);
- retbyte = reg_r(gspca_dev, 0x000b);
- checkword = retbyte << 8;
- retbyte = reg_r(gspca_dev, 0x000a);
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword);
+ retword = reg_r(gspca_dev, 0x000b) << 8;
+ retword |= reg_r(gspca_dev, 0x000a);
+ PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
reg_r(gspca_dev, 0x0010);
/* this is tested only once anyway */
for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
- if (chipset_revision_sensor[i].revision == checkword) {
- sd->chip_revision = checkword;
+ if (chipset_revision_sensor[i].revision == retword) {
+ sd->chip_revision = retword;
send_unknown(dev, SENSOR_PB0330);
return chipset_revision_sensor[i].internal_sensor_id;
}
@@ -6897,8 +6919,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x0a, 0x0010);
reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x00);
- if (retbyte != 0) {
+ retword = i2c_read(gspca_dev, 0x00);
+ if (retword != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
return 0x0a; /* ?? */
}
@@ -6910,14 +6932,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012);
msleep(2);
reg_w(dev, 0x01, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x00);
- if (retbyte != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte);
- if (retbyte == 0x11) /* VF0250 */
+ retword = i2c_read(gspca_dev, 0x00);
+ if (retword != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword);
+ if (retword == 0x0011) /* VF0250 */
return 0x0250;
- if (retbyte == 0x29) /* gc0305 */
+ if (retword == 0x0029) /* gc0305 */
send_unknown(dev, SENSOR_GC0305);
- return retbyte;
+ return retword;
}
reg_w(dev, 0x01, 0x0000); /* check OmniVision */
@@ -6927,8 +6949,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x06, 0x0010);
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */
- && i2c_read(gspca_dev, 0x1d) == 0xa2) {
+ if (i2c_read(gspca_dev, 0x1c) == 0x007f /* OV7610 - manufacturer ID */
+ && i2c_read(gspca_dev, 0x1d) == 0x00a2) {
send_unknown(dev, SENSOR_OV7620);
return 0x06; /* OmniVision confirm ? */
}
@@ -6942,16 +6964,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
/* msleep(150); */
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x0000); /* ID 0 */
- checkword = retbyte << 8;
- retbyte = i2c_read(gspca_dev, 0x0001); /* ID 1 */
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword);
- if (checkword == 0x2030) {
+ retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */
+ retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */
+ PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
+ if (retword == 0x2030) {
retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
send_unknown(dev, SENSOR_PO2030);
- return checkword;
+ return retword;
}
reg_w(dev, 0x01, 0x0000);
@@ -6962,10 +6982,10 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0001);
reg_w(dev, 0xd3, 0x008b);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
- return 0x0a; /* ?? */
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
+ return retword;
}
return -1;
}
@@ -6973,7 +6993,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int sensor, sensor2;
+ int sensor;
switch (sd->sensor) {
case SENSOR_MC501CB:
@@ -6988,16 +7008,9 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
break;
}
sensor = vga_2wr_probe(gspca_dev);
- if (sensor >= 0) {
- if (sensor < 0x7600)
- return sensor;
- /* next probe is needed for OmniVision ? */
- }
- sensor2 = vga_3wr_probe(gspca_dev);
- if (sensor2 >= 0
- && sensor >= 0)
+ if (sensor >= 0)
return sensor;
- return sensor2;
+ return vga_3wr_probe(gspca_dev);
}
/* this function is called at probe time */
@@ -7009,23 +7022,24 @@ static int sd_config(struct gspca_dev *gspca_dev,
int sensor;
int vga = 1; /* 1: vga, 0: sif */
static const __u8 gamma[SENSOR_MAX] = {
- 5, /* SENSOR_CS2102 0 */
- 5, /* SENSOR_CS2102K 1 */
- 4, /* SENSOR_GC0305 2 */
- 4, /* SENSOR_HDCS2020b 3 */
- 4, /* SENSOR_HV7131B 4 */
- 4, /* SENSOR_HV7131C 5 */
- 4, /* SENSOR_ICM105A 6 */
- 4, /* SENSOR_MC501CB 7 */
- 3, /* SENSOR_OV7620 8 */
- 4, /* SENSOR_OV7630C 9 */
- 4, /* SENSOR_PAS106 10 */
- 4, /* SENSOR_PAS202B 11 */
- 4, /* SENSOR_PB0330 12 */
- 4, /* SENSOR_PO2030 13 */
- 4, /* SENSOR_TAS5130CK 14 */
- 4, /* SENSOR_TAS5130CXX 15 */
- 3, /* SENSOR_TAS5130C_VF0250 16 */
+ 4, /* SENSOR_ADCM2700 0 */
+ 5, /* SENSOR_CS2102 1 */
+ 5, /* SENSOR_CS2102K 2 */
+ 4, /* SENSOR_GC0305 3 */
+ 4, /* SENSOR_HDCS2020b 4 */
+ 4, /* SENSOR_HV7131B 5 */
+ 4, /* SENSOR_HV7131C 6 */
+ 4, /* SENSOR_ICM105A 7 */
+ 4, /* SENSOR_MC501CB 8 */
+ 3, /* SENSOR_OV7620 9 */
+ 4, /* SENSOR_OV7630C 10 */
+ 4, /* SENSOR_PAS106 11 */
+ 4, /* SENSOR_PAS202B 12 */
+ 4, /* SENSOR_PB0330 13 */
+ 4, /* SENSOR_PO2030 14 */
+ 4, /* SENSOR_TAS5130CK 15 */
+ 4, /* SENSOR_TAS5130CXX 16 */
+ 3, /* SENSOR_TAS5130C_VF0250 17 */
};
/* define some sensors from the vendor/product */
@@ -7033,7 +7047,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info;
sensor = zcxx_probeSensor(gspca_dev);
if (sensor >= 0)
- PDEBUG(D_PROBE, "probe sensor -> %02x", sensor);
+ PDEBUG(D_PROBE, "probe sensor -> %04x", sensor);
if ((unsigned) force_sensor < SENSOR_MAX) {
sd->sensor = force_sensor;
PDEBUG(D_PROBE, "sensor forced to %d", force_sensor);
@@ -7112,6 +7126,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->chip_revision);
sd->sensor = SENSOR_TAS5130CK;
break;
+ case 0x16:
+ PDEBUG(D_PROBE, "Find Sensor ADCM2700");
+ sd->sensor = SENSOR_ADCM2700;
+ break;
case 0x29:
PDEBUG(D_PROBE, "Find Sensor GC0305");
sd->sensor = SENSOR_GC0305;
@@ -7129,12 +7147,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Find Sensor OV7620");
sd->sensor = SENSOR_OV7620;
break;
+ case 0x7631:
+ PDEBUG(D_PROBE, "Find Sensor OV7630C");
+ sd->sensor = SENSOR_OV7630C;
+ break;
case 0x7648:
PDEBUG(D_PROBE, "Find Sensor OV7648");
sd->sensor = SENSOR_OV7620; /* same sensor (?) */
break;
default:
- PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor);
+ PDEBUG(D_ERR|D_PROBE, "Unknown sensor %04x", sensor);
return -EINVAL;
}
}
@@ -7147,7 +7169,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
/*fixme:test*/
gspca_dev->nbalt--;
if (vga) {
@@ -7157,12 +7178,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
- sd->qindex = 1;
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->gamma = gamma[(int) sd->sensor];
sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
+ sd->quality = QUALITY_DEF;
switch (sd->sensor) {
case SENSOR_GC0305:
@@ -7196,27 +7217,34 @@ static int sd_start(struct gspca_dev *gspca_dev)
const struct usb_action *zc3_init;
int mode;
static const struct usb_action *init_tb[SENSOR_MAX][2] = {
- {cs2102_InitialScale, cs2102_Initial}, /* 0 */
- {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */
- {gc0305_Initial, gc0305_InitialScale}, /* 2 */
- {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 3 */
- {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 4 */
- {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 5 */
- {icm105axx_InitialScale, icm105axx_Initial}, /* 6 */
- {MC501CB_InitialScale, MC501CB_Initial}, /* 7 */
- {OV7620_mode0, OV7620_mode1}, /* 8 */
- {ov7630c_InitialScale, ov7630c_Initial}, /* 9 */
- {pas106b_InitialScale, pas106b_Initial}, /* 10 */
- {pas202b_Initial, pas202b_InitialScale}, /* 11 */
- {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */
+ {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */
+ {cs2102_InitialScale, cs2102_Initial}, /* 1 */
+ {cs2102K_InitialScale, cs2102K_Initial}, /* 2 */
+ {gc0305_Initial, gc0305_InitialScale}, /* 3 */
+ {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */
+ {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */
+ {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */
+ {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */
+ {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */
+ {OV7620_mode0, OV7620_mode1}, /* 9 */
+ {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */
+ {pas106b_InitialScale, pas106b_Initial}, /* 11 */
+ {pas202b_Initial, pas202b_InitialScale}, /* 12 */
+ {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */
/* or {pb03303x_InitialScale, pb03303x_Initial}, */
- {PO2030_mode0, PO2030_mode1}, /* 13 */
- {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */
- {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */
+ {PO2030_mode0, PO2030_mode1}, /* 14 */
+ {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */
+ {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */
{tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
- /* 16 */
+ /* 17 */
};
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
zc3_init = init_tb[(int) sd->sensor][mode];
switch (sd->sensor) {
@@ -7243,11 +7271,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
usb_exchange(gspca_dev, zc3_init);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PO2030:
case SENSOR_TAS5130C_VF0250:
- msleep(100); /* ?? */
+/* msleep(100); * ?? */
reg_r(gspca_dev, 0x0002); /* --> 0x40 */
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
@@ -7260,6 +7289,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
setmatrix(gspca_dev);
setbrightness(gspca_dev);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_OV7620:
reg_r(gspca_dev, 0x0008);
reg_w(dev, 0x00, 0x0008);
@@ -7301,6 +7331,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
setlightfreq(gspca_dev);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
+ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
+ reg_w(dev, 0x15, 0x01ae);
+ reg_w(dev, 0x02, 0x0180);
+ /* ms-win + */
+ reg_w(dev, 0x40, 0x0117);
+ break;
case SENSOR_GC0305:
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
@@ -7323,19 +7360,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
setautogain(gspca_dev);
switch (sd->sensor) {
- case SENSOR_PAS202B:
- reg_w(dev, 0x00, 0x0007); /* (from win traces) */
- break;
case SENSOR_PO2030:
msleep(500);
reg_r(gspca_dev, 0x0008);
reg_r(gspca_dev, 0x0007);
+ /*fall thru*/
+ case SENSOR_PAS202B:
reg_w(dev, 0x00, 0x0007); /* (from win traces) */
- reg_w(dev, 0x02, 0x0008);
+ reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
break;
}
- if (sd->sensor == SENSOR_PAS202B)
- reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
return 0;
}
@@ -7344,6 +7378,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ kfree(sd->jpeg_hdr);
if (!gspca_dev->present)
return;
send_unknown(gspca_dev->dev, sd->sensor);
@@ -7354,14 +7389,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
__u8 *data,
int len)
{
+ struct sd *sd = (struct sd *) gspca_dev;
if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x21);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
+
/* remove the webcam's header:
* ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp
* - 'ss ss' is the frame sequence number (BE)
@@ -7503,6 +7539,34 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
return -EINVAL;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
.ctrls = sd_ctrls,
@@ -7513,6 +7577,8 @@ static const struct sd_desc sd_desc = {
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.querymenu = sd_querymenu,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
static const __devinitdata struct usb_device_id device_table[] = {
@@ -7563,11 +7629,9 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x055f, 0xd004)},
{USB_DEVICE(0x0698, 0x2003)},
{USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x0ac8, 0x0302)},
+ {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106},
{USB_DEVICE(0x0ac8, 0x301b)},
-#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
{USB_DEVICE(0x0ac8, 0x303b)},
-#endif
{USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
{USB_DEVICE(0x0ac8, 0x307b)},
{USB_DEVICE(0x10fd, 0x0128)},
@@ -7600,8 +7664,10 @@ static struct usb_driver sd_driver = {
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}