aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/video/gspca
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 09:22:18 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-15 09:22:18 -0700
commit043fe50f8085c12651c96f04576eae4d8a22f3d8 (patch)
tree214b4f985ce7d3b1a4961620e2c2f4f5f06e1c35 /drivers/media/video/gspca
parent227423904c709a8e60245c97081bbeb4fb500655 (diff)
parentea47689e74a1637fac4f5fc44890f3662c976849 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (213 commits) V4L/DVB (12720): em28xx-cards: Add vendor/product id for Kworld DVD Maker 2 V4L/DVB (12713): em28xx: Cleanups at ir_i2c handler V4L/DVB (12712): em28xx: properly load ir-kbd-i2c when needed V4L/DVB (12701): saa7134: ir-kbd-i2c init data needs a persistent object V4L/DVB (12699): cx18: ir-kbd-i2c initialization data should point to a persistent object V4L/DVB (12698): em28xx: ir-kbd-i2c init data needs a persistent object V4L/DVB (12707): gspca - sn9c20x: Add SXGA support to MT9M111 V4L/DVB (12706): gspca - sn9c20x: disable exposure/gain controls for MT9M111 sensors. V4L/DVB (12705): gspca - sn9c20x: Add SXGA support to SOI968 V4L/DVB (12703): gspca - sn9c20x: Reduces size of object V4L/DVB (12704): gspca - sn9c20x: Fix exposure on SOI968 sensors V4L/DVB (12696): gspca - sonixj / sn9c102: Two drivers for 0c45:60fc and 0c45:613e. V4L/DVB (12695): gspca - vc032x: Do the LED work with the sensor hv7131r. V4L/DVB (12694): gspca - vc032x: Change the start exchanges of the sensor hv7131r. V4L/DVB (12693): gspca - sunplus: The brightness is signed. V4L/DVB (12692): gspca - sunplus: Optimize code. V4L/DVB (12691): gspca - sonixj: Don't use mdelay(). V4L/DVB (12690): gspca - pac7311: Webcam 06f8:3009 added. V4L/DVB (12686): dvb-core: check supported QAM modulations V4L/DVB (12685): dvb-core: check fe->ops.set_frontend return value ...
Diffstat (limited to 'drivers/media/video/gspca')
-rw-r--r--drivers/media/video/gspca/Kconfig21
-rw-r--r--drivers/media/video/gspca/Makefile2
-rw-r--r--drivers/media/video/gspca/conex.c2
-rw-r--r--drivers/media/video/gspca/etoms.c4
-rw-r--r--drivers/media/video/gspca/gspca.c66
-rw-r--r--drivers/media/video/gspca/gspca.h5
-rw-r--r--drivers/media/video/gspca/jeilinj.c388
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c4
-rw-r--r--drivers/media/video/gspca/mr97310a.c853
-rw-r--r--drivers/media/video/gspca/pac207.c37
-rw-r--r--drivers/media/video/gspca/pac7311.c2
-rw-r--r--drivers/media/video/gspca/sn9c20x.c235
-rw-r--r--drivers/media/video/gspca/sonixj.c40
-rw-r--r--drivers/media/video/gspca/spca501.c2
-rw-r--r--drivers/media/video/gspca/spca506.c2
-rw-r--r--drivers/media/video/gspca/spca508.c59
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c4
-rw-r--r--drivers/media/video/gspca/sunplus.c386
-rw-r--r--drivers/media/video/gspca/t613.c210
-rw-r--r--drivers/media/video/gspca/tv8532.c2
-rw-r--r--drivers/media/video/gspca/vc032x.c1126
-rw-r--r--drivers/media/video/gspca/zc3xx.c2
22 files changed, 2387 insertions, 1065 deletions
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index e994dcac43f..8897283b0bb 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -47,6 +47,15 @@ config USB_GSPCA_FINEPIX
To compile this driver as a module, choose M here: the
module will be called gspca_finepix.
+config USB_GSPCA_JEILINJ
+ tristate "Jeilin JPEG USB V4L2 driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on this Jeilin chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_jeilinj.
+
config USB_GSPCA_MARS
tristate "Mars USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
@@ -103,9 +112,9 @@ config USB_GSPCA_PAC7311
module will be called gspca_pac7311.
config USB_GSPCA_SN9C20X
- tristate "SN9C20X USB Camera Driver"
- depends on VIDEO_V4L2 && USB_GSPCA
- help
+ tristate "SN9C20X USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
Say Y here if you want support for cameras based on the
sn9c20x chips (SN9C201 and SN9C202).
@@ -113,10 +122,10 @@ config USB_GSPCA_SN9C20X
module will be called gspca_sn9c20x.
config USB_GSPCA_SN9C20X_EVDEV
- bool "Enable evdev support"
+ bool "Enable evdev support"
depends on USB_GSPCA_SN9C20X && INPUT
- ---help---
- Say Y here in order to enable evdev support for sn9c20x webcam button.
+ ---help---
+ Say Y here in order to enable evdev support for sn9c20x webcam button.
config USB_GSPCA_SONIXB
tristate "SONIX Bayer USB Camera Driver"
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index f6d3b86e9ad..035616b5e86 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -2,6 +2,7 @@ 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_JEILINJ) += gspca_jeilinj.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
@@ -30,6 +31,7 @@ gspca_main-objs := gspca.o
gspca_conex-objs := conex.o
gspca_etoms-objs := etoms.o
gspca_finepix-objs := finepix.o
+gspca_jeilinj-objs := jeilinj.o
gspca_mars-objs := mars.o
gspca_mr97310a-objs := mr97310a.o
gspca_ov519-objs := ov519.o
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 8d48ea1742c..eca003566ae 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -820,7 +820,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam = &gspca_dev->cam;
cam->cam_mode = vga_mode;
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ cam->nmodes = ARRAY_SIZE(vga_mode);
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index 2c20d06a03e..c1461e63647 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -635,10 +635,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAS106) {
cam->cam_mode = sif_mode;
- cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+ cam->nmodes = ARRAY_SIZE(sif_mode);
} else {
cam->cam_mode = vga_mode;
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ cam->nmodes = ARRAY_SIZE(vga_mode);
gspca_dev->ctrl_dis = (1 << COLOR_IDX);
}
sd->brightness = BRIGHTNESS_DEF;
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index b8561dfb6c8..cf6540da1e4 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -47,7 +47,7 @@ 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, 6, 0)
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 7, 0)
#ifdef GSPCA_DEBUG
int gspca_debug = D_ERR | D_PROBE;
@@ -486,6 +486,7 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
}
PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
i, ep->desc.bEndpointAddress);
+ gspca_dev->alt = i; /* memorize the current alt setting */
if (gspca_dev->nbalt > 1) {
ret = usb_set_interface(gspca_dev->dev, gspca_dev->iface, i);
if (ret < 0) {
@@ -493,7 +494,6 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
return NULL;
}
}
- gspca_dev->alt = i; /* memorize the current alt setting */
return ep;
}
@@ -512,7 +512,10 @@ static int create_urbs(struct gspca_dev *gspca_dev,
if (!gspca_dev->cam.bulk) { /* isoc */
/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
- psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+ if (gspca_dev->pkt_size == 0)
+ psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
+ else
+ psize = gspca_dev->pkt_size;
npkt = gspca_dev->cam.npkt;
if (npkt == 0)
npkt = 32; /* default value */
@@ -597,13 +600,18 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
/* set the higher alternate setting and
* loop until urb submit succeeds */
gspca_dev->alt = gspca_dev->nbalt;
+ if (gspca_dev->sd_desc->isoc_init) {
+ ret = gspca_dev->sd_desc->isoc_init(gspca_dev);
+ if (ret < 0)
+ goto out;
+ }
+ ep = get_ep(gspca_dev);
+ if (ep == NULL) {
+ ret = -EIO;
+ goto out;
+ }
for (;;) {
PDEBUG(D_STREAM, "init transfer alt %d", gspca_dev->alt);
- ep = get_ep(gspca_dev);
- if (ep == NULL) {
- ret = -EIO;
- goto out;
- }
ret = create_urbs(gspca_dev, ep);
if (ret < 0)
goto out;
@@ -628,21 +636,32 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
/* submit the URBs */
for (n = 0; n < gspca_dev->nurbs; n++) {
ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL);
- if (ret < 0) {
- PDEBUG(D_ERR|D_STREAM,
- "usb_submit_urb [%d] err %d", n, ret);
- gspca_dev->streaming = 0;
- destroy_urbs(gspca_dev);
- if (ret == -ENOSPC) {
- msleep(20); /* wait for kill
- * complete */
- break; /* try the previous alt */
- }
- goto out;
- }
+ if (ret < 0)
+ break;
}
if (ret >= 0)
break;
+ PDEBUG(D_ERR|D_STREAM,
+ "usb_submit_urb alt %d err %d", gspca_dev->alt, ret);
+ gspca_dev->streaming = 0;
+ destroy_urbs(gspca_dev);
+ if (ret != -ENOSPC)
+ goto out;
+
+ /* the bandwidth is not wide enough
+ * negociate or try a lower alternate setting */
+ msleep(20); /* wait for kill complete */
+ if (gspca_dev->sd_desc->isoc_nego) {
+ ret = gspca_dev->sd_desc->isoc_nego(gspca_dev);
+ if (ret < 0)
+ goto out;
+ } else {
+ ep = get_ep(gspca_dev);
+ if (ep == NULL) {
+ ret = -EIO;
+ goto out;
+ }
+ }
}
out:
mutex_unlock(&gspca_dev->usb_lock);
@@ -1473,12 +1492,6 @@ static int vidioc_s_parm(struct file *filp, void *priv,
return 0;
}
-static int vidioc_s_std(struct file *filp, void *priv,
- v4l2_std_id *parm)
-{
- return 0;
-}
-
#ifdef CONFIG_VIDEO_V4L1_COMPAT
static int vidiocgmbuf(struct file *file, void *priv,
struct video_mbuf *mbuf)
@@ -1949,7 +1962,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
.vidioc_s_jpegcomp = vidioc_s_jpegcomp,
.vidioc_g_parm = vidioc_g_parm,
.vidioc_s_parm = vidioc_s_parm,
- .vidioc_s_std = vidioc_s_std,
.vidioc_enum_framesizes = vidioc_enum_framesizes,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register,
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 46c4effdfcd..70b1fd83087 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -98,9 +98,11 @@ struct sd_desc {
/* mandatory operations */
cam_cf_op config; /* called on probe */
cam_op init; /* called on probe and resume */
- cam_op start; /* called on stream on */
+ cam_op start; /* called on stream on after URBs creation */
cam_pkt_op pkt_scan;
/* optional operations */
+ cam_op isoc_init; /* called on stream on before getting the EP */
+ cam_op isoc_nego; /* called when URB submit failed with NOSPC */
cam_v_op stopN; /* called on stream off - main alt */
cam_v_op stop0; /* called on stream off & disconnect - alt 0 */
cam_v_op dq_callback; /* called when a frame has been dequeued */
@@ -178,6 +180,7 @@ struct gspca_dev {
__u8 iface; /* USB interface number */
__u8 alt; /* USB alternate setting */
__u8 nbalt; /* number of USB alternate settings */
+ u16 pkt_size; /* ISOC packet size */
};
int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
new file mode 100644
index 00000000000..dbfa3ed6e8e
--- /dev/null
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -0,0 +1,388 @@
+/*
+ * Jeilinj subdriver
+ *
+ * Supports some Jeilin dual-mode cameras which use bulk transport and
+ * download raw JPEG data.
+ *
+ * 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
+ */
+
+#define MODULE_NAME "jeilinj"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+#include "jpeg.h"
+
+MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/JEILINJ USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define JEILINJ_CMD_TIMEOUT 500
+#define JEILINJ_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define JEILINJ_MAX_TRANSFER 0x200
+
+#define FRAME_HEADER_LEN 0x10
+
+/* 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;
+ u8 quality; /* image quality */
+ u8 jpegqual; /* webcam quality */
+ u8 *jpeg_hdr;
+};
+
+ struct jlj_command {
+ unsigned char instruction[2];
+ unsigned char ack_wanted;
+ };
+
+/* AFAICT these cameras will only do 320x240. */
+static struct v4l2_pix_format jlj_mode[] = {
+ { 320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0}
+};
+
+/*
+ * cam uses endpoint 0x03 to send commands, 0x84 for read commands,
+ * and 0x82 for bulk transfer.
+ */
+
+/* All commands are two bytes only */
+static int jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
+{
+ int retval;
+
+ memcpy(gspca_dev->usb_buf, command, 2);
+ retval = usb_bulk_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 3),
+ gspca_dev->usb_buf, 2, NULL, 500);
+ if (retval < 0)
+ PDEBUG(D_ERR, "command write [%02x] error %d",
+ gspca_dev->usb_buf[0], retval);
+ return retval;
+}
+
+/* Responses are one byte only */
+static int jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
+{
+ int retval;
+
+ retval = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x84),
+ gspca_dev->usb_buf, 1, NULL, 500);
+ response = gspca_dev->usb_buf[0];
+ if (retval < 0)
+ PDEBUG(D_ERR, "read command [%02x] error %d",
+ gspca_dev->usb_buf[0], retval);
+ return retval;
+}
+
+static int jlj_start(struct gspca_dev *gspca_dev)
+{
+ int i;
+ int retval = -1;
+ u8 response = 0xff;
+ struct jlj_command start_commands[] = {
+ {{0x71, 0x81}, 0},
+ {{0x70, 0x05}, 0},
+ {{0x95, 0x70}, 1},
+ {{0x71, 0x81}, 0},
+ {{0x70, 0x04}, 0},
+ {{0x95, 0x70}, 1},
+ {{0x71, 0x00}, 0},
+ {{0x70, 0x08}, 0},
+ {{0x95, 0x70}, 1},
+ {{0x94, 0x02}, 0},
+ {{0xde, 0x24}, 0},
+ {{0x94, 0x02}, 0},
+ {{0xdd, 0xf0}, 0},
+ {{0x94, 0x02}, 0},
+ {{0xe3, 0x2c}, 0},
+ {{0x94, 0x02}, 0},
+ {{0xe4, 0x00}, 0},
+ {{0x94, 0x02}, 0},
+ {{0xe5, 0x00}, 0},
+ {{0x94, 0x02}, 0},
+ {{0xe6, 0x2c}, 0},
+ {{0x94, 0x03}, 0},
+ {{0xaa, 0x00}, 0},
+ {{0x71, 0x1e}, 0},
+ {{0x70, 0x06}, 0},
+ {{0x71, 0x80}, 0},
+ {{0x70, 0x07}, 0}
+ };
+ for (i = 0; i < ARRAY_SIZE(start_commands); i++) {
+ retval = jlj_write2(gspca_dev, start_commands[i].instruction);
+ if (retval < 0)
+ return retval;
+ if (start_commands[i].ack_wanted)
+ retval = jlj_read1(gspca_dev, response);
+ if (retval < 0)
+ return retval;
+ }
+ PDEBUG(D_ERR, "jlj_start retval is %d", retval);
+ return retval;
+}
+
+static int jlj_stop(struct gspca_dev *gspca_dev)
+{
+ int i;
+ int retval;
+ struct jlj_command stop_commands[] = {
+ {{0x71, 0x00}, 0},
+ {{0x70, 0x09}, 0},
+ {{0x71, 0x80}, 0},
+ {{0x70, 0x05}, 0}
+ };
+ for (i = 0; i < ARRAY_SIZE(stop_commands); i++) {
+ retval = jlj_write2(gspca_dev, stop_commands[i].instruction);
+ if (retval < 0)
+ return retval;
+ }
+ return retval;
+}
+
+/* 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 jlj_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 blocks_left; /* 0x200-sized blocks remaining in current frame. */
+ int size_in_blocks;
+ int act_len;
+ int discarding = 0; /* true if we failed to get space for frame. */
+ int packet_type;
+ int ret;
+ u8 *buffer;
+
+ buffer = kmalloc(JEILINJ_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;
+ /* Start a new frame, and add the JPEG header, first thing */
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding)
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ dev->jpeg_hdr, JPEG_HDR_SZ);
+ else
+ discarding = 1;
+ /*
+ * Now request data block 0. Line 0 reports the size
+ * to download, in blocks of size 0x200, and also tells the
+ * "actual" data size, in bytes, which seems best to ignore.
+ */
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x82),
+ buffer, JEILINJ_MAX_TRANSFER, &act_len,
+ JEILINJ_DATA_TIMEOUT);
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for Block 0",
+ act_len, JEILINJ_MAX_TRANSFER);
+ if (ret < 0 || act_len < FRAME_HEADER_LEN)
+ goto quit_stream;
+ size_in_blocks = buffer[0x0a];
+ blocks_left = buffer[0x0a] - 1;
+ PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
+ packet_type = INTER_PACKET;
+ if (frame && !discarding)
+ /* Toss line 0 of data block 0, keep the rest. */
+ gspca_frame_add(gspca_dev, packet_type,
+ frame, buffer + FRAME_HEADER_LEN,
+ JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
+ else
+ discarding = 1;
+ while (blocks_left > 0) {
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x82),
+ buffer, JEILINJ_MAX_TRANSFER, &act_len,
+ JEILINJ_DATA_TIMEOUT);
+ if (ret < 0 || act_len < JEILINJ_MAX_TRANSFER)
+ goto quit_stream;
+ PDEBUG(D_STREAM,
+ "%d blocks remaining for frame", blocks_left);
+ blocks_left -= 1;
+ if (blocks_left == 0)
+ packet_type = LAST_PACKET;
+ else
+ packet_type = INTER_PACKET;
+ if (frame && !discarding)
+ gspca_frame_add(gspca_dev, packet_type,
+ frame, buffer,
+ JEILINJ_MAX_TRANSFER);
+ else
+ discarding = 1;
+ }
+ }
+quit_stream:
+ mutex_lock(&gspca_dev->usb_lock);
+ if (gspca_dev->present)
+ jlj_stop(gspca_dev);
+ 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;
+
+ dev->quality = 85;
+ dev->jpegqual = 85;
+ PDEBUG(D_PROBE,
+ "JEILINJ camera detected"
+ " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ cam->cam_mode = jlj_mode;
+ cam->nmodes = 1;
+ cam->bulk = 1;
+ /* We don't use the buffer gspca allocates so make it small. */
+ cam->bulk_size = 32;
+ INIT_WORK(&dev->work_struct, jlj_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 jlj_dostream to finish */
+ destroy_workqueue(dev->work_thread);
+ dev->work_thread = NULL;
+ mutex_lock(&gspca_dev->usb_lock);
+ kfree(dev->jpeg_hdr);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ 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;
+
+ /* create the JPEG header */
+ dev->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(dev->jpeg_hdr, dev->quality);
+ PDEBUG(D_STREAM, "Start streaming at 320x240");
+ ret = jlj_start(gspca_dev);
+ 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(0x0979, 0x0280)},
+ {}
+};
+
+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/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 7127321ace8..6b89f33a4ce 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -178,8 +178,10 @@ sensor_found:
sens_priv->settings =
kmalloc(sizeof(s32)*ARRAY_SIZE(s5k83a_ctrls), GFP_KERNEL);
- if (!sens_priv->settings)
+ if (!sens_priv->settings) {
+ kfree(sens_priv);
return -ENOMEM;
+ }
sd->gspca_dev.cam.cam_mode = s5k83a_modes;
sd->gspca_dev.cam.nmodes = ARRAY_SIZE(s5k83a_modes);
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
index 30132513400..140c8f320e4 100644
--- a/drivers/media/video/gspca/mr97310a.c
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -3,6 +3,21 @@
*
* Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
*
+ * Support for the MR97310A cameras in addition to the Aiptek Pencam VGA+
+ * and for the routines for detecting and classifying these various cameras,
+ *
+ * Copyright (C) 2009 Theodore Kilgore <kilgota@auburn.edu>
+ *
+ * Acknowledgements:
+ *
+ * The MR97311A support in gspca/mars.c has been helpful in understanding some
+ * of the registers in these cameras.
+ *
+ * Hans de Goede <hdgoede@redhat.com> and
+ * Thomas Kaiser <thomas@kaiser-linux.li>
+ * have assisted with their experience. Each of them has also helped by
+ * testing a previously unsupported camera.
+ *
* 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
@@ -22,18 +37,108 @@
#include "gspca.h"
-MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>");
+#define CAM_TYPE_CIF 0
+#define CAM_TYPE_VGA 1
+
+#define MR97310A_BRIGHTNESS_MIN -254
+#define MR97310A_BRIGHTNESS_MAX 255
+#define MR97310A_BRIGHTNESS_DEFAULT 0
+
+#define MR97310A_EXPOSURE_MIN 300
+#define MR97310A_EXPOSURE_MAX 4095
+#define MR97310A_EXPOSURE_DEFAULT 1000
+
+#define MR97310A_GAIN_MIN 0
+#define MR97310A_GAIN_MAX 31
+#define MR97310A_GAIN_DEFAULT 25
+
+MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>,"
+ "Theodore Kilgore <kilgota@auburn.edu>");
MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
MODULE_LICENSE("GPL");
+/* global parameters */
+int force_sensor_type = -1;
+module_param(force_sensor_type, int, 0644);
+MODULE_PARM_DESC(force_sensor_type, "Force sensor type (-1 (auto), 0 or 1)");
+
/* specific webcam descriptor */
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
u8 sof_read;
+ u8 cam_type; /* 0 is CIF and 1 is VGA */
+ u8 sensor_type; /* We use 0 and 1 here, too. */
+ u8 do_lcd_stop;
+
+ int brightness;
+ u16 exposure;
+ u8 gain;
+};
+
+struct sensor_w_data {
+ u8 reg;
+ u8 flags;
+ u8 data[16];
+ int len;
};
+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_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+static void setbrightness(struct gspca_dev *gspca_dev);
+static void setexposure(struct gspca_dev *gspca_dev);
+static void setgain(struct gspca_dev *gspca_dev);
+
/* V4L2 controls supported by the driver */
static struct ctrl sd_ctrls[] = {
+ {
+#define BRIGHTNESS_IDX 0
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = MR97310A_BRIGHTNESS_MIN,
+ .maximum = MR97310A_BRIGHTNESS_MAX,
+ .step = 1,
+ .default_value = MR97310A_BRIGHTNESS_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+#define EXPOSURE_IDX 1
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Exposure",
+ .minimum = MR97310A_EXPOSURE_MIN,
+ .maximum = MR97310A_EXPOSURE_MAX,
+ .step = 1,
+ .default_value = MR97310A_EXPOSURE_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setexposure,
+ .get = sd_getexposure,
+ },
+ {
+#define GAIN_IDX 2
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = MR97310A_GAIN_MIN,
+ .maximum = MR97310A_GAIN_MAX,
+ .step = 1,
+ .default_value = MR97310A_GAIN_DEFAULT,
+ .flags = 0,
+ },
+ .set = sd_setgain,
+ .get = sd_getgain,
+ },
};
static const struct v4l2_pix_format vga_mode[] = {
@@ -65,7 +170,7 @@ static const struct v4l2_pix_format vga_mode[] = {
};
/* the bytes to write are in gspca_dev->usb_buf */
-static int reg_w(struct gspca_dev *gspca_dev, int len)
+static int mr_write(struct gspca_dev *gspca_dev, int len)
{
int rc;
@@ -78,15 +183,249 @@ static int reg_w(struct gspca_dev *gspca_dev, int len)
return rc;
}
+/* the bytes are read into gspca_dev->usb_buf */
+static int mr_read(struct gspca_dev *gspca_dev, int len)
+{
+ int rc;
+
+ rc = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 3),
+ gspca_dev->usb_buf, len, NULL, 500);
+ if (rc < 0)
+ PDEBUG(D_ERR, "reg read [%02x] error %d",
+ gspca_dev->usb_buf[0], rc);
+ return rc;
+}
+
+static int sensor_write_reg(struct gspca_dev *gspca_dev, u8 reg, u8 flags,
+ const u8 *data, int len)
+{
+ gspca_dev->usb_buf[0] = 0x1f;
+ gspca_dev->usb_buf[1] = flags;
+ gspca_dev->usb_buf[2] = reg;
+ memcpy(gspca_dev->usb_buf + 3, data, len);
+
+ return mr_write(gspca_dev, len + 3);
+}
+
+static int sensor_write_regs(struct gspca_dev *gspca_dev,
+ const struct sensor_w_data *data, int len)
+{
+ int i, rc;
+
+ for (i = 0; i < len; i++) {
+ rc = sensor_write_reg(gspca_dev, data[i].reg, data[i].flags,
+ data[i].data, data[i].len);
+ if (rc < 0)
+ return rc;
+ }
+
+ return 0;
+}
+
+static int sensor_write1(struct gspca_dev *gspca_dev, u8 reg, u8 data)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 buf, confirm_reg;
+ int rc;
+
+ buf = data;
+ rc = sensor_write_reg(gspca_dev, reg, 0x01, &buf, 1);
+ if (rc < 0)
+ return rc;
+
+ buf = 0x01;
+ confirm_reg = sd->sensor_type ? 0x13 : 0x11;
+ rc = sensor_write_reg(gspca_dev, confirm_reg, 0x00, &buf, 1);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+
+static int cam_get_response16(struct gspca_dev *gspca_dev)
+{
+ __u8 *data = gspca_dev->usb_buf;
+ int err_code;
+
+ data[0] = 0x21;
+ err_code = mr_write(gspca_dev, 1);
+ if (err_code < 0)
+ return err_code;
+
+ err_code = mr_read(gspca_dev, 16);
+ return err_code;
+}
+
+static int zero_the_pointer(struct gspca_dev *gspca_dev)
+{
+ __u8 *data = gspca_dev->usb_buf;
+ int err_code;
+ u8 status = 0;
+ int tries = 0;
+
+ err_code = cam_get_response16(gspca_dev);
+ if (err_code < 0)
+ return err_code;
+
+ err_code = mr_write(gspca_dev, 1);
+ data[0] = 0x19;
+ data[1] = 0x51;
+ err_code = mr_write(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ err_code = cam_get_response16(gspca_dev);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x19;
+ data[1] = 0xba;
+ err_code = mr_write(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ err_code = cam_get_response16(gspca_dev);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x19;
+ data[1] = 0x00;
+ err_code = mr_write(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ err_code = cam_get_response16(gspca_dev);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x19;
+ data[1] = 0x00;
+ err_code = mr_write(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ while (status != 0x0a && tries < 256) {
+ err_code = cam_get_response16(gspca_dev);
+ status = data[0];
+ tries++;
+ if (err_code < 0)
+ return err_code;
+ }
+ if (status != 0x0a)
+ PDEBUG(D_ERR, "status is %02x", status);
+
+ tries = 0;
+ while (tries < 4) {
+ data[0] = 0x19;
+ data[1] = 0x00;
+ err_code = mr_write(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ err_code = cam_get_response16(gspca_dev);
+ status = data[0];
+ tries++;
+ if (err_code < 0)
+ return err_code;
+ }
+
+ data[0] = 0x19;
+ err_code = mr_write(gspca_dev, 1);
+ if (err_code < 0)
+ return err_code;
+
+ err_code = mr_read(gspca_dev, 16);
+ if (err_code < 0)
+ return err_code;
+
+ return 0;
+}
+
+static u8 get_sensor_id(struct gspca_dev *gspca_dev)
+{
+ int err_code;
+
+ gspca_dev->usb_buf[0] = 0x1e;
+ err_code = mr_write(gspca_dev, 1);
+ if (err_code < 0)
+ return err_code;
+
+ err_code = mr_read(gspca_dev, 16);
+ if (err_code < 0)
+ return err_code;
+
+ PDEBUG(D_PROBE, "Byte zero reported is %01x", gspca_dev->usb_buf[0]);
+
+ return gspca_dev->usb_buf[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;
+ __u8 *data = gspca_dev->usb_buf;
+ int err_code;
cam = &gspca_dev->cam;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
+
+ if (id->idProduct == 0x010e) {
+ sd->cam_type = CAM_TYPE_CIF;
+ cam->nmodes--;
+
+ data[0] = 0x01;
+ data[1] = 0x01;
+ err_code = mr_write(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ msleep(200);
+ data[0] = get_sensor_id(gspca_dev);
+ /*
+ * Known CIF cameras. If you have another to report, please do
+ *
+ * Name byte just read sd->sensor_type
+ * reported by
+ * Sakar Spy-shot 0x28 T. Kilgore 0
+ * Innovage 0xf5 (unstable) T. Kilgore 0
+ * Vivitar Mini 0x53 H. De Goede 0
+ * Vivitar Mini 0x04 / 0x24 E. Rodriguez 0
+ * Vivitar Mini 0x08 T. Kilgore 1
+ * Elta-Media 8212dc 0x23 T. Kaiser 1
+ * Philips dig. keych. 0x37 T. Kilgore 1
+ */
+ if ((data[0] & 0x78) == 8 ||
+ ((data[0] & 0x2) == 0x2 && data[0] != 0x53))
+ sd->sensor_type = 1;
+ else
+ sd->sensor_type = 0;
+
+ PDEBUG(D_PROBE, "MR97310A CIF camera detected, sensor: %d",
+ sd->sensor_type);
+
+ if (force_sensor_type != -1) {
+ sd->sensor_type = !! force_sensor_type;
+ PDEBUG(D_PROBE, "Forcing sensor type to: %d",
+ sd->sensor_type);
+ }
+
+ if (sd->sensor_type == 0)
+ gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX);
+ } else {
+ sd->cam_type = CAM_TYPE_VGA;
+ PDEBUG(D_PROBE, "MR97310A VGA camera detected");
+ gspca_dev->ctrl_dis = (1 << BRIGHTNESS_IDX) |
+ (1 << EXPOSURE_IDX) | (1 << GAIN_IDX);
+ }
+
+ sd->brightness = MR97310A_BRIGHTNESS_DEFAULT;
+ sd->exposure = MR97310A_EXPOSURE_DEFAULT;
+ sd->gain = MR97310A_GAIN_DEFAULT;
+
return 0;
}
@@ -96,183 +435,462 @@ static int sd_init(struct gspca_dev *gspca_dev)
return 0;
}
-static int sd_start(struct gspca_dev *gspca_dev)
+static int start_cif_cam(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 */
-
+ const __u8 startup_string[] = {
+ 0x00,
+ 0x0d,
+ 0x01,
+ 0x00, /* Hsize/8 for 352 or 320 */
+ 0x00, /* Vsize/4 for 288 or 240 */
+ 0x13, /* or 0xbb, depends on sensor */
+ 0x00, /* Hstart, depends on res. */
+ 0x00, /* reserved ? */
+ 0x00, /* Vstart, depends on res. and sensor */
+ 0x50, /* 0x54 to get 176 or 160 */
+ 0xc0
+ };
+
+ /* Note: Some of the above descriptions guessed from MR97113A driver */
data[0] = 0x01;
data[1] = 0x01;
- err_code = reg_w(gspca_dev, 2);
+ err_code = mr_write(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;
+ memcpy(data, startup_string, 11);
+ if (sd->sensor_type)
+ data[5] = 0xbb;
switch (gspca_dev->width) {
case 160:
- data[9] |= 0x0c; /* reg 8, 4:1 scale down */
+ data[9] |= 0x04; /* reg 8, 2:1 scale down from 320 */
/* 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 */
+ data[3] = 0x28; /* reg 2, H size/8 */
+ data[4] = 0x3c; /* reg 3, V size/4 */
+ data[6] = 0x14; /* reg 5, H start */
+ data[8] = 0x1a + sd->sensor_type; /* reg 7, V start */
break;
-
case 176:
- data[9] |= 0x04; /* reg 8, 2:1 scale down */
+ data[9] |= 0x04; /* reg 8, 2:1 scale down from 352 */
/* 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 */
+ data[3] = 0x2c; /* reg 2, H size/8 */
+ data[4] = 0x48; /* reg 3, V size/4 */
+ data[6] = 0x06; /* reg 5, H start */
+ data[8] = 0x06 + sd->sensor_type; /* reg 7, V start */
break;
}
-
- err_code = reg_w(gspca_dev, 11);
+ err_code = mr_write(gspca_dev, 11);
if (err_code < 0)
return err_code;
- data[0] = 0x0a;
- data[1] = 0x80;
- err_code = reg_w(gspca_dev, 2);
+ if (!sd->sensor_type) {
+ const struct sensor_w_data cif_sensor0_init_data[] = {
+ {0x02, 0x00, {0x03, 0x5a, 0xb5, 0x01,
+ 0x0f, 0x14, 0x0f, 0x10}, 8},
+ {0x0c, 0x00, {0x04, 0x01, 0x01, 0x00, 0x1f}, 5},
+ {0x12, 0x00, {0x07}, 1},
+ {0x1f, 0x00, {0x06}, 1},
+ {0x27, 0x00, {0x04}, 1},
+ {0x29, 0x00, {0x0c}, 1},
+ {0x40, 0x00, {0x40, 0x00, 0x04}, 3},
+ {0x50, 0x00, {0x60}, 1},
+ {0x60, 0x00, {0x06}, 1},
+ {0x6b, 0x00, {0x85, 0x85, 0xc8, 0xc8, 0xc8, 0xc8}, 6},
+ {0x72, 0x00, {0x1e, 0x56}, 2},
+ {0x75, 0x00, {0x58, 0x40, 0xa2, 0x02, 0x31, 0x02,
+ 0x31, 0x80, 0x00}, 9},
+ {0x11, 0x00, {0x01}, 1},
+ {0, 0, {0}, 0}
+ };
+ err_code = sensor_write_regs(gspca_dev, cif_sensor0_init_data,
+ ARRAY_SIZE(cif_sensor0_init_data));
+ } else { /* sd->sensor_type = 1 */
+ const struct sensor_w_data cif_sensor1_init_data[] = {
+ /* Reg 3,4, 7,8 get set by the controls */
+ {0x02, 0x00, {0x10}, 1},
+ {0x05, 0x01, {0x22}, 1}, /* 5/6 also seen as 65h/32h */
+ {0x06, 0x01, {0x00}, 1},
+ {0x09, 0x02, {0x0e}, 1},
+ {0x0a, 0x02, {0x05}, 1},
+ {0x0b, 0x02, {0x05}, 1},
+ {0x0c, 0x02, {0x0f}, 1},
+ {0x0d, 0x02, {0x07}, 1},
+ {0x0e, 0x02, {0x0c}, 1},
+ {0x0f, 0x00, {0x00}, 1},
+ {0x10, 0x00, {0x06}, 1},
+ {0x11, 0x00, {0x07}, 1},
+ {0x12, 0x00, {0x00}, 1},
+ {0x13, 0x00, {0x01}, 1},
+ {0, 0, {0}, 0}
+ };
+ err_code = sensor_write_regs(gspca_dev, cif_sensor1_init_data,
+ ARRAY_SIZE(cif_sensor1_init_data));
+ }
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;
+ setbrightness(gspca_dev);
+ setexposure(gspca_dev);
+ setgain(gspca_dev);
- data[0] = 0x1b;
- data[1] = 0x00;
- err_code = reg_w(gspca_dev, 2);
- if (err_code < 0)
- return err_code;
+ msleep(200);
- data[0] = 0x15;
- data[1] = 0x16;
- err_code = reg_w(gspca_dev, 2);
+ data[0] = 0x00;
+ data[1] = 0x4d; /* ISOC transfering enable... */
+ err_code = mr_write(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;
+ return 0;
+}
- data[0] = 0x17;
- data[1] = 0x3a;
- err_code = reg_w(gspca_dev, 2);
- if (err_code < 0)
- return err_code;
+static int start_vga_cam(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 *data = gspca_dev->usb_buf;
+ int err_code;
+ const __u8 startup_string[] = {0x00, 0x0d, 0x01, 0x00, 0x00, 0x2b,
+ 0x00, 0x00, 0x00, 0x50, 0xc0};
- data[0] = 0x18;
- data[1] = 0x68;
- err_code = reg_w(gspca_dev, 2);
- if (err_code < 0)
- return err_code;
+ /* What some of these mean is explained in start_cif_cam(), above */
+ sd->sof_read = 0;
- 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);
+ /*
+ * We have to know which camera we have, because the register writes
+ * depend upon the camera. This test, run before we actually enter
+ * the initialization routine, distinguishes most of the cameras, If
+ * needed, another routine is done later, too.
+ */
+ memset(data, 0, 16);
+ data[0] = 0x20;
+ err_code = mr_write(gspca_dev, 1);
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);
+ err_code = mr_read(gspca_dev, 16);
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;
+ PDEBUG(D_PROBE, "Byte reported is %02x", data[0]);
+
+ msleep(200);
+ /*
+ * Known VGA cameras. If you have another to report, please do
+ *
+ * Name byte just read sd->sensor_type
+ * sd->do_lcd_stop
+ * Aiptek Pencam VGA+ 0x31 0 1
+ * ION digital 0x31 0 1
+ * Argus DC-1620 0x30 1 0
+ * Argus QuickClix 0x30 1 1 (not caught here)
+ */
+ sd->sensor_type = data[0] & 1;
+ sd->do_lcd_stop = (~data[0]) & 1;
+
+
- data[0] = 0x1f;
- data[1] = 0x04;
- data[2] = 0x11;
- data[3] = 0x01;
- err_code = reg_w(gspca_dev, 4);
+ /* Streaming setup begins here. */
+
+
+ data[0] = 0x01;
+ data[1] = 0x01;
+ err_code = mr_write(gspca_dev, 2);
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);
+ /*
+ * A second test can now resolve any remaining ambiguity in the
+ * identification of the camera type,
+ */
+ if (!sd->sensor_type) {
+ data[0] = get_sensor_id(gspca_dev);
+ if (data[0] == 0x7f) {
+ sd->sensor_type = 1;
+ PDEBUG(D_PROBE, "sensor_type corrected to 1");
+ }
+ msleep(200);
+ }
+
+ if (force_sensor_type != -1) {
+ sd->sensor_type = !! force_sensor_type;
+ PDEBUG(D_PROBE, "Forcing sensor type to: %d",
+ sd->sensor_type);
+ }
+
+ /*
+ * Known VGA cameras.
+ * This test is only run if the previous test returned 0x30, but
+ * here is the information for all others, too, just for reference.
+ *
+ * Name byte just read sd->sensor_type
+ *
+ * Aiptek Pencam VGA+ 0xfb (this test not run) 1
+ * ION digital 0xbd (this test not run) 1
+ * Argus DC-1620 0xe5 (no change) 0
+ * Argus QuickClix 0x7f (reclassified) 1
+ */
+ memcpy(data, startup_string, 11);
+ if (!sd->sensor_type) {
+ data[5] = 0x00;
+ data[10] = 0x91;
+ }
+
+ 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/8 */
+ data[4] = 0x78; /* reg 3, V size/4 */
+ data[6] = 0x04; /* reg 5, H start */
+ data[8] = 0x03; /* reg 7, V start */
+ if (sd->do_lcd_stop)
+ data[8] = 0x04; /* Bayer tile shifted */
+ 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 */
+ if (sd->do_lcd_stop)
+ data[8] = 0x64; /* Bayer tile shifted */
+ break;
+ }
+
+ err_code = mr_write(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 (!sd->sensor_type) {
+ /* The only known sensor_type 0 cam is the Argus DC-1620 */
+ const struct sensor_w_data vga_sensor0_init_data[] = {
+ {0x01, 0x00, {0x0c, 0x00, 0x04}, 3},
+ {0x14, 0x00, {0x01, 0xe4, 0x02, 0x84}, 4},
+ {0x20, 0x00, {0x00, 0x80, 0x00, 0x08}, 4},
+ {0x25, 0x00, {0x03, 0xa9, 0x80}, 3},
+ {0x30, 0x00, {0x30, 0x18, 0x10, 0x18}, 4},
+ {0, 0, {0}, 0}
+ };
+ err_code = sensor_write_regs(gspca_dev, vga_sensor0_init_data,
+ ARRAY_SIZE(vga_sensor0_init_data));
+ } else { /* sd->sensor_type = 1 */
+ const struct sensor_w_data vga_sensor1_init_data[] = {
+ {0x02, 0x00, {0x06, 0x59, 0x0c, 0x16, 0x00,
+ 0x07, 0x00, 0x01}, 8},
+ {0x11, 0x04, {0x01}, 1},
+ /*{0x0a, 0x00, {0x00, 0x01, 0x00, 0x00, 0x01, */
+ {0x0a, 0x00, {0x01, 0x06, 0x00, 0x00, 0x01,
+ 0x00, 0x0a}, 7},
+ {0x11, 0x04, {0x01}, 1},
+ {0x12, 0x00, {0x00, 0x63, 0x00, 0x70, 0x00, 0x00}, 6},
+ {0x11, 0x04, {0x01}, 1},
+ {0, 0, {0}, 0}
+ };
+ err_code = sensor_write_regs(gspca_dev, vga_sensor1_init_data,
+ ARRAY_SIZE(vga_sensor1_init_data));
+ }
if (err_code < 0)
return err_code;
+ msleep(200);
data[0] = 0x00;
data[1] = 0x4d; /* ISOC transfering enable... */
- err_code = reg_w(gspca_dev, 2);
+ err_code = mr_write(gspca_dev, 2);
+
+ return err_code;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int err_code;
+ struct cam *cam;
+
+ cam = &gspca_dev->cam;
+ sd->sof_read = 0;
+ /*
+ * Some of the supported cameras require the memory pointer to be
+ * set to 0, or else they will not stream.
+ */
+ zero_the_pointer(gspca_dev);
+ msleep(200);
+ if (sd->cam_type == CAM_TYPE_CIF) {
+ err_code = start_cif_cam(gspca_dev);
+ } else {
+ err_code = start_vga_cam(gspca_dev);
+ }
return err_code;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int result;
gspca_dev->usb_buf[0] = 1;
gspca_dev->usb_buf[1] = 0;
- result = reg_w(gspca_dev, 2);
+ result = mr_write(gspca_dev, 2);
if (result < 0)
PDEBUG(D_ERR, "Camera Stop failed");
+
+ /* Not all the cams need this, but even if not, probably a good idea */
+ zero_the_pointer(gspca_dev);
+ if (sd->do_lcd_stop) {
+ gspca_dev->usb_buf[0] = 0x19;
+ gspca_dev->usb_buf[1] = 0x54;
+ result = mr_write(gspca_dev, 2);
+ if (result < 0)
+ PDEBUG(D_ERR, "Camera Stop failed");
+ }
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 val;
+
+ if (gspca_dev->ctrl_dis & (1 << BRIGHTNESS_IDX))
+ return;
+
+ /* Note register 7 is also seen as 0x8x or 0xCx in dumps */
+ if (sd->brightness > 0) {
+ sensor_write1(gspca_dev, 7, 0x00);
+ val = sd->brightness;
+ } else {
+ sensor_write1(gspca_dev, 7, 0x01);
+ val = 257 - sd->brightness;
+ }
+ sensor_write1(gspca_dev, 8, val);
+}
+
+static void setexposure(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 val;
+
+ if (gspca_dev->ctrl_dis & (1 << EXPOSURE_IDX))
+ return;
+
+ if (sd->sensor_type) {
+ val = sd->exposure >> 4;
+ sensor_write1(gspca_dev, 3, val);
+ val = sd->exposure & 0xf;
+ sensor_write1(gspca_dev, 4, val);
+ } else {
+ u8 clockdiv;
+ int exposure;
+
+ /* We have both a clock divider and an exposure register.
+ We first calculate the clock divider, as that determines
+ the maximum exposure and then we calculayte the exposure
+ register setting (which goes from 0 - 511).
+
+ Note our 0 - 4095 exposure is mapped to 0 - 511
+ milliseconds exposure time */
+ clockdiv = (60 * sd->exposure + 7999) / 8000;
+
+ /* Limit framerate to not exceed usb bandwidth */
+ if (clockdiv < 3 && gspca_dev->width >= 320)
+ clockdiv = 3;
+ else if (clockdiv < 2)
+ clockdiv = 2;
+
+ /* Frame exposure time in ms = 1000 * clockdiv / 60 ->
+ exposure = (sd->exposure / 8) * 511 / (1000 * clockdiv / 60) */
+ exposure = (60 * 511 * sd->exposure) / (8000 * clockdiv);
+ if (exposure > 511)
+ exposure = 511;
+
+ /* exposure register value is reversed! */
+ exposure = 511 - exposure;
+
+ sensor_write1(gspca_dev, 0x02, clockdiv);
+ sensor_write1(gspca_dev, 0x0e, exposure & 0xff);
+ sensor_write1(gspca_dev, 0x0f, exposure >> 8);
+ }
+}
+
+static void setgain(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (gspca_dev->ctrl_dis & (1 << GAIN_IDX))
+ return;
+
+ if (sd->sensor_type) {
+ sensor_write1(gspca_dev, 0x0e, sd->gain);
+ } else {
+ sensor_write1(gspca_dev, 0x10, sd->gain);
+ }
+}
+
+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)
+ setbrightness(gspca_dev);
+ 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_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->exposure = val;
+ if (gspca_dev->streaming)
+ setexposure(gspca_dev);
+ return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->exposure;
+ return 0;
+}
+
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gain = val;
+ if (gspca_dev->streaming)
+ setgain(gspca_dev);
+ return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gain;
+ return 0;
}
/* Include pac common sof detection functions */
@@ -320,8 +938,9 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x08ca, 0x0111)},
- {USB_DEVICE(0x093a, 0x010f)},
+ {USB_DEVICE(0x08ca, 0x0111)}, /* Aiptek Pencam VGA+ */
+ {USB_DEVICE(0x093a, 0x010f)}, /* All other known MR97310A VGA cams */
+ {USB_DEVICE(0x093a, 0x010e)}, /* All known MR97310A CIF cams */
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index 95a97ab684c..96659433d24 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -35,25 +35,17 @@ MODULE_LICENSE("GPL");
#define PAC207_BRIGHTNESS_MIN 0
#define PAC207_BRIGHTNESS_MAX 255
-#define PAC207_BRIGHTNESS_DEFAULT 4 /* power on default: 4 */
-
-/* An exposure value of 4 also works (3 does not) but then we need to lower
- the compression balance setting when in 352x288 mode, otherwise the usb
- bandwidth is not enough and packets get dropped resulting in corrupt
- frames. The problem with this is that when the compression balance gets
- lowered below 0x80, the pac207 starts using a different compression
- algorithm for some lines, these lines get prefixed with a 0x2dd2 prefix
- and currently we do not know how to decompress these lines, so for now
- we use a minimum exposure value of 5 */
-#define PAC207_EXPOSURE_MIN 5
+#define PAC207_BRIGHTNESS_DEFAULT 46
+
+#define PAC207_EXPOSURE_MIN 3
#define PAC207_EXPOSURE_MAX 26
-#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 ?? */
-#define PAC207_EXPOSURE_KNEE 11 /* 4 = 30 fps, 11 = 8, 15 = 6 */
+#define PAC207_EXPOSURE_DEFAULT 5 /* power on default: 3 */
+#define PAC207_EXPOSURE_KNEE 8 /* 4 = 30 fps, 11 = 8, 15 = 6 */
#define PAC207_GAIN_MIN 0
#define PAC207_GAIN_MAX 31
#define PAC207_GAIN_DEFAULT 9 /* power on default: 9 */
-#define PAC207_GAIN_KNEE 20
+#define PAC207_GAIN_KNEE 31
#define PAC207_AUTOGAIN_DEADZONE 30
@@ -166,16 +158,12 @@ static const struct v4l2_pix_format sif_mode[] = {
};
static const __u8 pac207_sensor_init[][8] = {
- {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0xf0},
- {0x00, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
+ {0x10, 0x12, 0x0d, 0x12, 0x0c, 0x01, 0x29, 0x84},
+ {0x49, 0x64, 0x64, 0x64, 0x04, 0x10, 0xf0, 0x30},
{0x00, 0x00, 0x00, 0x70, 0xa0, 0xf8, 0x00, 0x00},
- {0x00, 0x00, 0x32, 0x00, 0x96, 0x00, 0xa2, 0x02},
{0x32, 0x00, 0x96, 0x00, 0xA2, 0x02, 0xaf, 0x00},
};
- /* 48 reg_72 Rate Control end BalSize_4a =0x36 */
-static const __u8 PacReg72[] = { 0x00, 0x00, 0x36, 0x00 };
-
static int pac207_write_regs(struct gspca_dev *gspca_dev, u16 index,
const u8 *buffer, u16 length)
{
@@ -274,7 +262,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
* Bit_1=LED,
* Bit_2=Compression test mode enable */
pac207_write_reg(gspca_dev, 0x0f, 0x00); /* Power Control */
- pac207_write_reg(gspca_dev, 0x11, 0x30); /* Analog Bias */
return 0;
}
@@ -289,15 +276,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
pac207_write_regs(gspca_dev, 0x0002, pac207_sensor_init[0], 8);
pac207_write_regs(gspca_dev, 0x000a, pac207_sensor_init[1], 8);
pac207_write_regs(gspca_dev, 0x0012, pac207_sensor_init[2], 8);
- pac207_write_regs(gspca_dev, 0x0040, pac207_sensor_init[3], 8);
- pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[4], 8);
- pac207_write_regs(gspca_dev, 0x0048, PacReg72, 4);
+ pac207_write_regs(gspca_dev, 0x0042, pac207_sensor_init[3], 8);
/* Compression Balance */
if (gspca_dev->width == 176)
pac207_write_reg(gspca_dev, 0x4a, 0xff);
else
- pac207_write_reg(gspca_dev, 0x4a, 0x88);
+ pac207_write_reg(gspca_dev, 0x4a, 0x30);
pac207_write_reg(gspca_dev, 0x4b, 0x00); /* Sram test value */
pac207_write_reg(gspca_dev, 0x08, sd->brightness);
@@ -346,7 +331,7 @@ static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
if (sd->autogain_ignore_frames > 0)
sd->autogain_ignore_frames--;
else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
- 100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
+ 100, PAC207_AUTOGAIN_DEADZONE,
PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
sd->autogain_ignore_frames = PAC_AUTOGAIN_IGNORE_FRAMES;
}
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index e1e3a3a5048..052714484e8 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -1057,6 +1057,7 @@ static struct sd_desc sd_desc = {
/* -- module initialisation -- */
static __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x06f8, 0x3009), .driver_info = SENSOR_PAC7302},
{USB_DEVICE(0x093a, 0x2600), .driver_info = SENSOR_PAC7311},
{USB_DEVICE(0x093a, 0x2601), .driver_info = SENSOR_PAC7311},
{USB_DEVICE(0x093a, 0x2603), .driver_info = SENSOR_PAC7311},
@@ -1068,6 +1069,7 @@ static __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2622), .driver_info = SENSOR_PAC7302},
{USB_DEVICE(0x093a, 0x2624), .driver_info = SENSOR_PAC7302},
{USB_DEVICE(0x093a, 0x2626), .driver_info = SENSOR_PAC7302},
+ {USB_DEVICE(0x093a, 0x2629), .driver_info = SENSOR_PAC7302},
{USB_DEVICE(0x093a, 0x262a), .driver_info = SENSOR_PAC7302},
{USB_DEVICE(0x093a, 0x262c), .driver_info = SENSOR_PAC7302},
{}
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index fcfbbd329b4..cdad3db3336 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -94,6 +94,16 @@ struct sd {
#endif
};
+struct i2c_reg_u8 {
+ u8 reg;
+ u8 val;
+};
+
+struct i2c_reg_u16 {
+ u8 reg;
+ u16 val;
+};
+
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);
@@ -403,7 +413,7 @@ static const struct v4l2_pix_format sxga_mode[] = {
.priv = 3 | MODE_RAW | MODE_SXGA},
};
-static const int hsv_red_x[] = {
+static const s16 hsv_red_x[] = {
41, 44, 46, 48, 50, 52, 54, 56,
58, 60, 62, 64, 66, 68, 70, 72,
74, 76, 78, 80, 81, 83, 85, 87,
@@ -451,7 +461,7 @@ static const int hsv_red_x[] = {
24, 26, 28, 30, 33, 35, 37, 39, 41
};
-static const int hsv_red_y[] = {
+static const s16 hsv_red_y[] = {
82, 80, 78, 76, 74, 73, 71, 69,
67, 65, 63, 61, 58, 56, 54, 52,
50, 48, 46, 44, 41, 39, 37, 35,
@@ -499,7 +509,7 @@ static const int hsv_red_y[] = {
96, 94, 92, 91, 89, 87, 85, 84, 82
};
-static const int hsv_green_x[] = {
+static const s16 hsv_green_x[] = {
-124, -124, -125, -125, -125, -125, -125, -125,
-125, -126, -126, -125, -125, -125, -125, -125,
-125, -124, -124, -124, -123, -123, -122, -122,
@@ -547,7 +557,7 @@ static const int hsv_green_x[] = {
-120, -120, -121, -122, -122, -123, -123, -124, -124
};
-static const int hsv_green_y[] = {
+static const s16 hsv_green_y[] = {
-100, -99, -98, -97, -95, -94, -93, -91,
-90, -89, -87, -86, -84, -83, -81, -80,
-78, -76, -75, -73, -71, -70, -68, -66,
@@ -595,7 +605,7 @@ static const int hsv_green_y[] = {
-109, -108, -107, -106, -105, -104, -103, -102, -100
};
-static const int hsv_blue_x[] = {
+static const s16 hsv_blue_x[] = {
112, 113, 114, 114, 115, 116, 117, 117,
118, 118, 119, 119, 120, 120, 120, 121,
121, 121, 122, 122, 122, 122, 122, 122,
@@ -643,7 +653,7 @@ static const int hsv_blue_x[] = {
104, 105, 106, 107, 108, 109, 110, 111, 112
};
-static const int hsv_blue_y[] = {
+static const s16 hsv_blue_y[] = {
-11, -13, -15, -17, -19, -21, -23, -25,
-27, -29, -31, -33, -35, -37, -39, -41,
-43, -45, -46, -48, -50, -52, -54, -55,
@@ -792,21 +802,21 @@ static u8 hv7131r_gain[] = {
0x78 /* 8x */
};
-static u8 soi968_init[][2] = {
+static struct i2c_reg_u8 soi968_init[] = {
{0x12, 0x80}, {0x0c, 0x00}, {0x0f, 0x1f},
{0x11, 0x80}, {0x38, 0x52}, {0x1e, 0x00},
{0x33, 0x08}, {0x35, 0x8c}, {0x36, 0x0c},
{0x37, 0x04}, {0x45, 0x04}, {0x47, 0xff},
{0x3e, 0x00}, {0x3f, 0x00}, {0x3b, 0x20},
{0x3a, 0x96}, {0x3d, 0x0a}, {0x14, 0x8e},
- {0x13, 0x8a}, {0x12, 0x40}, {0x17, 0x13},
+ {0x13, 0x8b}, {0x12, 0x40}, {0x17, 0x13},
{0x18, 0x63}, {0x19, 0x01}, {0x1a, 0x79},
{0x32, 0x24}, {0x03, 0x00}, {0x11, 0x40},
{0x2a, 0x10}, {0x2b, 0xe0}, {0x10, 0x32},
{0x00, 0x00}, {0x01, 0x80}, {0x02, 0x80},
};
-static u8 ov7660_init[][2] = {
+static struct i2c_reg_u8 ov7660_init[] = {
{0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
{0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
{0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
@@ -815,7 +825,7 @@ static u8 ov7660_init[][2] = {
{0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
};
-static u8 ov7670_init[][2] = {
+static struct i2c_reg_u8 ov7670_init[] = {
{0x12, 0x80}, {0x11, 0x80}, {0x3a, 0x04}, {0x12, 0x01},
{0x32, 0xb6}, {0x03, 0x0a}, {0x0c, 0x00}, {0x3e, 0x00},
{0x70, 0x3a}, {0x71, 0x35}, {0x72, 0x11}, {0x73, 0xf0},
@@ -872,7 +882,7 @@ static u8 ov7670_init[][2] = {
{0x93, 0x00},
};
-static u8 ov9650_init[][2] = {
+static struct i2c_reg_u8 ov9650_init[] = {
{0x12, 0x80}, {0x00, 0x00}, {0x01, 0x78},
{0x02, 0x78}, {0x03, 0x36}, {0x04, 0x03},
{0x05, 0x00}, {0x06, 0x00}, {0x08, 0x00},
@@ -902,7 +912,7 @@ static u8 ov9650_init[][2] = {
{0xaa, 0x92}, {0xab, 0x0a},
};
-static u8 ov9655_init[][2] = {
+static struct i2c_reg_u8 ov9655_init[] = {
{0x12, 0x80}, {0x12, 0x01}, {0x0d, 0x00}, {0x0e, 0x61},
{0x11, 0x80}, {0x13, 0xba}, {0x14, 0x2e}, {0x16, 0x24},
{0x1e, 0x04}, {0x1e, 0x04}, {0x1e, 0x04}, {0x27, 0x08},
@@ -939,7 +949,7 @@ static u8 ov9655_init[][2] = {
{0x00, 0x03}, {0x00, 0x0a}, {0x00, 0x10}, {0x00, 0x13},
};
-static u16 mt9v112_init[][2] = {
+static struct i2c_reg_u16 mt9v112_init[] = {
{0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0020},
{0x34, 0xc019}, {0x0a, 0x0011}, {0x0b, 0x000b},
{0x20, 0x0703}, {0x35, 0x2022}, {0xf0, 0x0001},
@@ -958,7 +968,7 @@ static u16 mt9v112_init[][2] = {
{0x2c, 0x00ae}, {0x2d, 0x00ae}, {0x2e, 0x00ae},
};
-static u16 mt9v111_init[][2] = {
+static struct i2c_reg_u16 mt9v111_init[] = {
{0x01, 0x0004}, {0x0d, 0x0001}, {0x0d, 0x0000},
{0x01, 0x0001}, {0x02, 0x0016}, {0x03, 0x01e1},
{0x04, 0x0281}, {0x05, 0x0004}, {0x07, 0x3002},
@@ -985,7 +995,7 @@ static u16 mt9v111_init[][2] = {
{0x0e, 0x0008}, {0x06, 0x002d}, {0x05, 0x0004},
};
-static u16 mt9v011_init[][2] = {
+static struct i2c_reg_u16 mt9v011_init[] = {
{0x07, 0x0002}, {0x0d, 0x0001}, {0x0d, 0x0000},
{0x01, 0x0008}, {0x02, 0x0016}, {0x03, 0x01e1},
{0x04, 0x0281}, {0x05, 0x0083}, {0x06, 0x0006},
@@ -1012,7 +1022,7 @@ static u16 mt9v011_init[][2] = {
{0x06, 0x0029}, {0x05, 0x0009},
};
-static u16 mt9m001_init[][2] = {
+static struct i2c_reg_u16 mt9m001_init[] = {
{0x0d, 0x0001}, {0x0d, 0x0000}, {0x01, 0x000e},
{0x02, 0x0014}, {0x03, 0x03c1}, {0x04, 0x0501},
{0x05, 0x0083}, {0x06, 0x0006}, {0x0d, 0x0002},
@@ -1025,14 +1035,14 @@ static u16 mt9m001_init[][2] = {
{0x2e, 0x0029}, {0x07, 0x0002},
};
-static u16 mt9m111_init[][2] = {
- {0xf0, 0x0000}, {0x0d, 0x0008}, {0x0d, 0x0009},
- {0x0d, 0x0008}, {0xf0, 0x0001}, {0x3a, 0x4300},
- {0x9b, 0x4300}, {0xa1, 0x0280}, {0xa4, 0x0200},
- {0x06, 0x308e}, {0xf0, 0x0000},
+static struct i2c_reg_u16 mt9m111_init[] = {
+ {0xf0, 0x0000}, {0x0d, 0x0021}, {0x0d, 0x0008},
+ {0xf0, 0x0001}, {0x3a, 0x4300}, {0x9b, 0x4300},
+ {0x06, 0x708e}, {0xf0, 0x0002}, {0x2e, 0x0a1e},
+ {0xf0, 0x0000},
};
-static u8 hv7131r_init[][2] = {
+static struct i2c_reg_u8 hv7131r_init[] = {
{0x02, 0x08}, {0x02, 0x00}, {0x01, 0x08},
{0x02, 0x00}, {0x20, 0x00}, {0x21, 0xd0},
{0x22, 0x00}, {0x23, 0x09}, {0x01, 0x08},
@@ -1043,7 +1053,7 @@ static u8 hv7131r_init[][2] = {
{0x23, 0x09}, {0x01, 0x08},
};
-int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
+static int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
{
struct usb_device *dev = gspca_dev->dev;
int result;
@@ -1062,7 +1072,8 @@ int reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length)
return 0;
}
-int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length)
+static int reg_w(struct gspca_dev *gspca_dev, u16 reg,
+ const u8 *buffer, int length)
{
struct usb_device *dev = gspca_dev->dev;
int result;
@@ -1082,13 +1093,13 @@ int reg_w(struct gspca_dev *gspca_dev, u16 reg, const u8 *buffer, int length)
return 0;
}
-int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
+static int reg_w1(struct gspca_dev *gspca_dev, u16 reg, const u8 value)
{
u8 data[1] = {value};
return reg_w(gspca_dev, reg, data, 1);
}
-int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
+static int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
{
int i;
reg_w(gspca_dev, 0x10c0, buffer, 8);
@@ -1096,15 +1107,15 @@ int i2c_w(struct gspca_dev *gspca_dev, const u8 *buffer)
reg_r(gspca_dev, 0x10c0, 1);
if (gspca_dev->usb_buf[0] & 0x04) {
if (gspca_dev->usb_buf[0] & 0x08)
- return -1;
+ return -EIO;
return 0;
}
msleep(1);
}
- return -1;
+ return -EIO;
}
-int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
+static int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1126,7 +1137,7 @@ int i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
return i2c_w(gspca_dev, row);
}
-int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
+static int i2c_w2(struct gspca_dev *gspca_dev, u8 reg, u16 val)
{
struct sd *sd = (struct sd *) gspca_dev;
u8 row[8];
@@ -1152,7 +1163,7 @@ int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
struct sd *sd = (struct sd *) gspca_dev;
u8 row[8];
- row[0] = 0x81 | 0x10;
+ row[0] = 0x81 | (1 << 4);
row[1] = sd->i2c_addr;
row[2] = reg;
row[3] = 0;
@@ -1160,14 +1171,15 @@ int i2c_r1(struct gspca_dev *gspca_dev, u8 reg, u8 *val)
row[5] = 0;
row[6] = 0;
row[7] = 0x10;
- reg_w(gspca_dev, 0x10c0, row, 8);
- msleep(1);
- row[0] = 0x81 | (2 << 4) | 0x02;
+ if (i2c_w(gspca_dev, row) < 0)
+ return -EIO;
+ row[0] = 0x81 | (1 << 4) | 0x02;
row[2] = 0;
- reg_w(gspca_dev, 0x10c0, row, 8);
- msleep(1);
- reg_r(gspca_dev, 0x10c2, 5);
- *val = gspca_dev->usb_buf[3];
+ if (i2c_w(gspca_dev, row) < 0)
+ return -EIO;
+ if (reg_r(gspca_dev, 0x10c2, 5) < 0)
+ return -EIO;
+ *val = gspca_dev->usb_buf[4];
return 0;
}
@@ -1176,7 +1188,7 @@ int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
struct sd *sd = (struct sd *) gspca_dev;
u8 row[8];
- row[0] = 0x81 | 0x10;
+ row[0] = 0x81 | (1 << 4);
row[1] = sd->i2c_addr;
row[2] = reg;
row[3] = 0;
@@ -1184,14 +1196,15 @@ int i2c_r2(struct gspca_dev *gspca_dev, u8 reg, u16 *val)
row[5] = 0;
row[6] = 0;
row[7] = 0x10;
- reg_w(gspca_dev, 0x10c0, row, 8);
- msleep(1);
- row[0] = 0x81 | (3 << 4) | 0x02;
+ if (i2c_w(gspca_dev, row) < 0)
+ return -EIO;
+ row[0] = 0x81 | (2 << 4) | 0x02;
row[2] = 0;
- reg_w(gspca_dev, 0x10c0, row, 8);
- msleep(1);
- reg_r(gspca_dev, 0x10c2, 5);
- *val = (gspca_dev->usb_buf[2] << 8) | gspca_dev->usb_buf[3];
+ if (i2c_w(gspca_dev, row) < 0)
+ return -EIO;
+ if (reg_r(gspca_dev, 0x10c2, 5) < 0)
+ return -EIO;
+ *val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
return 0;
}
@@ -1201,8 +1214,8 @@ static int ov9650_init_sensor(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
for (i = 0; i < ARRAY_SIZE(ov9650_init); i++) {
- if (i2c_w1(gspca_dev, ov9650_init[i][0],
- ov9650_init[i][1]) < 0) {
+ if (i2c_w1(gspca_dev, ov9650_init[i].reg,
+ ov9650_init[i].val) < 0) {
err("OV9650 sensor initialization failed");
return -ENODEV;
}
@@ -1218,8 +1231,8 @@ static int ov9655_init_sensor(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
for (i = 0; i < ARRAY_SIZE(ov9655_init); i++) {
- if (i2c_w1(gspca_dev, ov9655_init[i][0],
- ov9655_init[i][1]) < 0) {
+ if (i2c_w1(gspca_dev, ov9655_init[i].reg,
+ ov9655_init[i].val) < 0) {
err("OV9655 sensor initialization failed");
return -ENODEV;
}
@@ -1237,14 +1250,14 @@ static int soi968_init_sensor(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
for (i = 0; i < ARRAY_SIZE(soi968_init); i++) {
- if (i2c_w1(gspca_dev, soi968_init[i][0],
- soi968_init[i][1]) < 0) {
+ if (i2c_w1(gspca_dev, soi968_init[i].reg,
+ soi968_init[i].val) < 0) {
err("SOI968 sensor initialization failed");
return -ENODEV;
}
}
/* disable hflip and vflip */
- gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX);
+ gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) | (1 << EXPOSURE_IDX);
sd->hstart = 60;
sd->vstart = 11;
return 0;
@@ -1256,8 +1269,8 @@ static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
for (i = 0; i < ARRAY_SIZE(ov7660_init); i++) {
- if (i2c_w1(gspca_dev, ov7660_init[i][0],
- ov7660_init[i][1]) < 0) {
+ if (i2c_w1(gspca_dev, ov7660_init[i].reg,
+ ov7660_init[i].val) < 0) {
err("OV7660 sensor initialization failed");
return -ENODEV;
}
@@ -1275,8 +1288,8 @@ static int ov7670_init_sensor(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
for (i = 0; i < ARRAY_SIZE(ov7670_init); i++) {
- if (i2c_w1(gspca_dev, ov7670_init[i][0],
- ov7670_init[i][1]) < 0) {
+ if (i2c_w1(gspca_dev, ov7670_init[i].reg,
+ ov7670_init[i].val) < 0) {
err("OV7670 sensor initialization failed");
return -ENODEV;
}
@@ -1299,8 +1312,8 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
ret = i2c_r2(gspca_dev, 0xff, &value);
if ((ret == 0) && (value == 0x8243)) {
for (i = 0; i < ARRAY_SIZE(mt9v011_init); i++) {
- if (i2c_w2(gspca_dev, mt9v011_init[i][0],
- mt9v011_init[i][1]) < 0) {
+ if (i2c_w2(gspca_dev, mt9v011_init[i].reg,
+ mt9v011_init[i].val) < 0) {
err("MT9V011 sensor initialization failed");
return -ENODEV;
}
@@ -1317,8 +1330,8 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
ret = i2c_r2(gspca_dev, 0xff, &value);
if ((ret == 0) && (value == 0x823a)) {
for (i = 0; i < ARRAY_SIZE(mt9v111_init); i++) {
- if (i2c_w2(gspca_dev, mt9v111_init[i][0],
- mt9v111_init[i][1]) < 0) {
+ if (i2c_w2(gspca_dev, mt9v111_init[i].reg,
+ mt9v111_init[i].val) < 0) {
err("MT9V111 sensor initialization failed");
return -ENODEV;
}
@@ -1339,8 +1352,8 @@ static int mt9v_init_sensor(struct gspca_dev *gspca_dev)
ret = i2c_r2(gspca_dev, 0x00, &value);
if ((ret == 0) && (value == 0x1229)) {
for (i = 0; i < ARRAY_SIZE(mt9v112_init); i++) {
- if (i2c_w2(gspca_dev, mt9v112_init[i][0],
- mt9v112_init[i][1]) < 0) {
+ if (i2c_w2(gspca_dev, mt9v112_init[i].reg,
+ mt9v112_init[i].val) < 0) {
err("MT9V112 sensor initialization failed");
return -ENODEV;
}
@@ -1360,12 +1373,13 @@ static int mt9m111_init_sensor(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int i;
for (i = 0; i < ARRAY_SIZE(mt9m111_init); i++) {
- if (i2c_w2(gspca_dev, mt9m111_init[i][0],
- mt9m111_init[i][1]) < 0) {
+ if (i2c_w2(gspca_dev, mt9m111_init[i].reg,
+ mt9m111_init[i].val) < 0) {
err("MT9M111 sensor initialization failed");
return -ENODEV;
}
}
+ gspca_dev->ctrl_dis = (1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX) | (1 << GAIN_IDX);
sd->hstart = 0;
sd->vstart = 2;
return 0;
@@ -1376,8 +1390,8 @@ static int mt9m001_init_sensor(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int i;
for (i = 0; i < ARRAY_SIZE(mt9m001_init); i++) {
- if (i2c_w2(gspca_dev, mt9m001_init[i][0],
- mt9m001_init[i][1]) < 0) {
+ if (i2c_w2(gspca_dev, mt9m001_init[i].reg,
+ mt9m001_init[i].val) < 0) {
err("MT9M001 sensor initialization failed");
return -ENODEV;
}
@@ -1395,8 +1409,8 @@ static int hv7131r_init_sensor(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
for (i = 0; i < ARRAY_SIZE(hv7131r_init); i++) {
- if (i2c_w1(gspca_dev, hv7131r_init[i][0],
- hv7131r_init[i][1]) < 0) {
+ if (i2c_w1(gspca_dev, hv7131r_init[i].reg,
+ hv7131r_init[i].val) < 0) {
err("HV7131R Sensor initialization failed");
return -ENODEV;
}
@@ -1620,7 +1634,6 @@ static int set_exposure(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_OV7660:
case SENSOR_OV7670:
- case SENSOR_SOI968:
case SENSOR_OV9655:
case SENSOR_OV9650:
exp[0] |= (3 << 4);
@@ -1629,7 +1642,6 @@ static int set_exposure(struct gspca_dev *gspca_dev)
exp[4] = sd->exposure >> 8;
break;
case SENSOR_MT9M001:
- case SENSOR_MT9M111:
case SENSOR_MT9V112:
case SENSOR_MT9V111:
case SENSOR_MT9V011:
@@ -1645,6 +1657,8 @@ static int set_exposure(struct gspca_dev *gspca_dev)
exp[4] = ((sd->exposure * 0xffffff) / 0xffff) >> 8;
exp[5] = ((sd->exposure * 0xffffff) / 0xffff) & 0xff;
break;
+ default:
+ return 0;
}
i2c_w(gspca_dev, exp);
return 0;
@@ -1671,7 +1685,6 @@ static int set_gain(struct gspca_dev *gspca_dev)
gain[4] = micron1_gain[sd->gain] & 0xff;
break;
case SENSOR_MT9V112:
- case SENSOR_MT9M111:
gain[0] |= (3 << 4);
gain[2] = 0x2f;
gain[3] = micron1_gain[sd->gain] >> 8;
@@ -1688,6 +1701,8 @@ static int set_gain(struct gspca_dev *gspca_dev)
gain[2] = 0x30;
gain[3] = hv7131r_gain[sd->gain];
break;
+ default:
+ return 0;
}
i2c_w(gspca_dev, gain);
return 0;
@@ -1990,7 +2005,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->i2c_addr = id->driver_info & 0xff;
switch (sd->sensor) {
+ case SENSOR_MT9M111:
case SENSOR_OV9650:
+ case SENSOR_SOI968:
cam->cam_mode = sxga_mode;
cam->nmodes = ARRAY_SIZE(sxga_mode);
break;
@@ -2106,6 +2123,25 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
struct sd *sd = (struct sd *) gspca_dev;
u8 value;
switch (sd->sensor) {
+ case SENSOR_SOI968:
+ if (mode & MODE_SXGA) {
+ i2c_w1(gspca_dev, 0x17, 0x1d);
+ i2c_w1(gspca_dev, 0x18, 0xbd);
+ i2c_w1(gspca_dev, 0x19, 0x01);
+ i2c_w1(gspca_dev, 0x1a, 0x81);
+ i2c_w1(gspca_dev, 0x12, 0x00);
+ sd->hstart = 140;
+ sd->vstart = 19;
+ } else {
+ i2c_w1(gspca_dev, 0x17, 0x13);
+ i2c_w1(gspca_dev, 0x18, 0x63);
+ i2c_w1(gspca_dev, 0x19, 0x01);
+ i2c_w1(gspca_dev, 0x1a, 0x79);
+ i2c_w1(gspca_dev, 0x12, 0x40);
+ sd->hstart = 60;
+ sd->vstart = 11;
+ }
+ break;
case SENSOR_OV9650:
if (mode & MODE_SXGA) {
i2c_w1(gspca_dev, 0x17, 0x1b);
@@ -2123,6 +2159,17 @@ static void configure_sensor_output(struct gspca_dev *gspca_dev, int mode)
i2c_w1(gspca_dev, 0x12, (value & 0x7) | 0x40);
}
break;
+ case SENSOR_MT9M111:
+ if (mode & MODE_SXGA) {
+ i2c_w2(gspca_dev, 0xf0, 0x0002);
+ i2c_w2(gspca_dev, 0xc8, 0x970b);
+ i2c_w2(gspca_dev, 0xf0, 0x0000);
+ } else {
+ i2c_w2(gspca_dev, 0xf0, 0x0002);
+ i2c_w2(gspca_dev, 0xc8, 0x8000);
+ i2c_w2(gspca_dev, 0xf0, 0x0000);
+ }
+ break;
}
}
@@ -2211,15 +2258,10 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
kfree(sd->jpeg_hdr);
}
-static void do_autoexposure(struct gspca_dev *gspca_dev)
+static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
{
struct sd *sd = (struct sd *) gspca_dev;
- int avg_lum, new_exp;
-
- if (!sd->auto_exposure)
- return;
-
- avg_lum = atomic_read(&sd->avg_lum);
+ s16 new_exp;
/*
* some hardcoded values are present
@@ -2266,6 +2308,39 @@ static void do_autoexposure(struct gspca_dev *gspca_dev)
}
}
+static void do_autogain(struct gspca_dev *gspca_dev, u16 avg_lum)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (avg_lum < MIN_AVG_LUM) {
+ if (sd->gain + 1 <= 28) {
+ sd->gain++;
+ set_gain(gspca_dev);
+ }
+ }
+ if (avg_lum > MAX_AVG_LUM) {
+ if (sd->gain - 1 >= 0) {
+ sd->gain--;
+ set_gain(gspca_dev);
+ }
+ }
+}
+
+static void sd_dqcallback(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int avg_lum;
+
+ if (!sd->auto_exposure)
+ return;
+
+ avg_lum = atomic_read(&sd->avg_lum);
+ if (sd->sensor == SENSOR_SOI968)
+ do_autogain(gspca_dev, avg_lum);
+ else
+ do_autoexposure(gspca_dev, avg_lum);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
u8 *data, /* isoc packet */
@@ -2333,7 +2408,7 @@ static const struct sd_desc sd_desc = {
.stopN = sd_stopN,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
- .dq_callback = do_autoexposure,
+ .dq_callback = sd_dqcallback,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.set_register = sd_dbg_s_register,
.get_register = sd_dbg_g_register,
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index d6332ab8066..33f4d0a1f6f 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -727,7 +727,7 @@ static const u8 ov7660_sensor_init[][8] = {
{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
/* Outformat = rawRGB */
{0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
- {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
+ {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
/* GAIN BLUE RED VREF */
{0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
/* COM 1 BAVE GEAVE AECHH */
@@ -783,7 +783,7 @@ static const u8 ov7660_sensor_init[][8] = {
{0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
{0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
{0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
- {0xb1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
/****** (some exchanges in the win trace) ******/
{0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
/* bits[3..0]reserved */
@@ -1145,17 +1145,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
reg_w1(gspca_dev, 0x01, 0x42);
break;
case SENSOR_OV7660:
- reg_w1(gspca_dev, 0x01, 0x61);
- reg_w1(gspca_dev, 0x17, 0x20);
- reg_w1(gspca_dev, 0x01, 0x60);
- reg_w1(gspca_dev, 0x01, 0x40);
- break;
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);
+ msleep(100);
reg_w1(gspca_dev, 0x02, 0x62);
break;
/* case SENSOR_HV7131R: */
@@ -1624,6 +1619,8 @@ static void setvflip(struct sd *sd)
static void setinfrared(struct sd *sd)
{
+ if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX))
+ return;
/*fixme: different sequence for StarCam Clip and StarCam 370i */
/* Clip */
i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
@@ -1637,16 +1634,19 @@ static void setfreq(struct gspca_dev *gspca_dev)
if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
return;
if (sd->sensor == SENSOR_OV7660) {
+ u8 com8;
+
+ com8 = 0xdf; /* auto gain/wb/expo */
switch (sd->freq) {
case 0: /* Banding filter disabled */
- i2c_w1(gspca_dev, 0x13, 0xdf);
+ i2c_w1(gspca_dev, 0x13, com8 | 0x20);
break;
case 1: /* 50 hz */
- i2c_w1(gspca_dev, 0x13, 0xff);
+ i2c_w1(gspca_dev, 0x13, com8);
i2c_w1(gspca_dev, 0x3b, 0x0a);
break;
case 2: /* 60 hz */
- i2c_w1(gspca_dev, 0x13, 0xff);
+ i2c_w1(gspca_dev, 0x13, com8);
i2c_w1(gspca_dev, 0x3b, 0x02);
break;
}
@@ -1796,12 +1796,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x99, 0x60);
break;
case SENSOR_OV7660:
- reg_w1(gspca_dev, 0x9a, 0x05);
- if (sd->bridge == BRIDGE_SN9C105)
- reg_w1(gspca_dev, 0x99, 0xff);
- else
- reg_w1(gspca_dev, 0x99, 0x5b);
- break;
case SENSOR_SP80708:
reg_w1(gspca_dev, 0x9a, 0x05);
reg_w1(gspca_dev, 0x99, 0x59);
@@ -2325,18 +2319,19 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
{USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
-/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
+/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6802, 0x??)}, */
/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
{USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
{USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
- {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
+ {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
{USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
#endif
{USB_DEVICE(0x0c45, 0x6100), BSI(SN9C120, MI0360, 0x5d)}, /*sn9c128*/
-/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
+/* {USB_DEVICE(0x0c45, 0x6102), BSI(SN9C120, PO2030N, ??)}, */
+/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6802, 0x21)}, */
{USB_DEVICE(0x0c45, 0x610a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c128*/
{USB_DEVICE(0x0c45, 0x610b), BSI(SN9C120, OV7660, 0x21)}, /*sn9c128*/
{USB_DEVICE(0x0c45, 0x610c), BSI(SN9C120, HV7131R, 0x11)}, /*sn9c128*/
@@ -2352,6 +2347,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
#endif
+/* {USB_DEVICE(0x0c45, 0x6132), BSI(SN9C120, OV7670, 0x21)}, */
{USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
@@ -2359,7 +2355,9 @@ static const __devinitdata struct usb_device_id device_table[] = {
#endif
{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
{USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x21)},
- {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
+/* {USB_DEVICE(0x0c45, 0x6142), BSI(SN9C120, PO2030N, ??)}, *sn9c120b*/
+ {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)}, /*sn9c120b*/
+ {USB_DEVICE(0x0c45, 0x6148), BSI(SN9C120, OM6802, 0x21)}, /*sn9c120b*/
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index d48b27c648c..b74a34218da 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1923,7 +1923,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam = &gspca_dev->cam;
cam->cam_mode = vga_mode;
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ cam->nmodes = ARRAY_SIZE(vga_mode);
sd->subtype = id->driver_info;
sd->brightness = sd_ctrls[MY_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[MY_CONTRAST].qctrl.default_value;
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 3a0c893f942..a199298a641 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -286,7 +286,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam = &gspca_dev->cam;
cam->cam_mode = vga_mode;
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ cam->nmodes = ARRAY_SIZE(vga_mode);
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;
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index 2ed2669bac3..9696c4caf5c 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -1304,19 +1304,70 @@ static int reg_read(struct gspca_dev *gspca_dev,
return gspca_dev->usb_buf[0];
}
+/* send 1 or 2 bytes to the sensor via the Synchronous Serial Interface */
+static int ssi_w(struct gspca_dev *gspca_dev,
+ u16 reg, u16 val)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret, retry;
+
+ ret = reg_write(dev, 0x8802, reg >> 8);
+ if (ret < 0)
+ goto out;
+ ret = reg_write(dev, 0x8801, reg & 0x00ff);
+ if (ret < 0)
+ goto out;
+ if ((reg & 0xff00) == 0x1000) { /* if 2 bytes */
+ ret = reg_write(dev, 0x8805, val & 0x00ff);
+ if (ret < 0)
+ goto out;
+ val >>= 8;
+ }
+ ret = reg_write(dev, 0x8800, val);
+ if (ret < 0)
+ goto out;
+
+ /* poll until not busy */
+ retry = 10;
+ for (;;) {
+ ret = reg_read(gspca_dev, 0x8803);
+ if (ret < 0)
+ break;
+ if (gspca_dev->usb_buf[0] == 0)
+ break;
+ if (--retry <= 0) {
+ PDEBUG(D_ERR, "ssi_w busy %02x",
+ gspca_dev->usb_buf[0]);
+ ret = -1;
+ break;
+ }
+ msleep(8);
+ }
+
+out:
+ return ret;
+}
+
static int write_vector(struct gspca_dev *gspca_dev,
const u16 (*data)[2])
{
struct usb_device *dev = gspca_dev->dev;
- int ret;
+ int ret = 0;
while ((*data)[1] != 0) {
- ret = reg_write(dev, (*data)[1], (*data)[0]);
+ if ((*data)[1] & 0x8000) {
+ if ((*data)[1] == 0xdd00) /* delay */
+ msleep((*data)[0]);
+ else
+ ret = reg_write(dev, (*data)[1], (*data)[0]);
+ } else {
+ ret = ssi_w(gspca_dev, (*data)[1], (*data)[0]);
+ }
if (ret < 0)
- return ret;
+ break;
data++;
}
- return 0;
+ return ret;
}
/* this function is called at probe time */
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 0da8e0de045..7af511b5e9c 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -130,8 +130,8 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
STV06XX_URB_MSG_TIMEOUT);
if (err < 0)
return err;
- }
- return stv06xx_write_sensor_finish(sd);
+ }
+ return stv06xx_write_sensor_finish(sd);
}
int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 5127bbf9dd2..aa8f995ce04 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -32,26 +32,27 @@ 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;
+ s8 brightness;
+ u8 contrast;
+ u8 colors;
+ u8 autogain;
u8 quality;
#define QUALITY_MIN 70
#define QUALITY_MAX 95
#define QUALITY_DEF 85
- char bridge;
+ u8 bridge;
#define BRIDGE_SPCA504 0
#define BRIDGE_SPCA504B 1
#define BRIDGE_SPCA504C 2
#define BRIDGE_SPCA533 3
#define BRIDGE_SPCA536 4
- char subtype;
+ u8 subtype;
#define AiptekMiniPenCam13 1
#define LogitechClickSmart420 2
#define LogitechClickSmart820 3
#define MegapixV4 4
+#define MegaImageVI 5
u8 *jpeg_hdr;
};
@@ -67,21 +68,20 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(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 = 0,
- .maximum = 0xff,
+ .minimum = -128,
+ .maximum = 127,
.step = 1,
- .default_value = 0,
+#define BRIGHTNESS_DEF 0
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
},
-#define SD_CONTRAST 1
{
{
.id = V4L2_CID_CONTRAST,
@@ -90,12 +90,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0xff,
.step = 1,
- .default_value = 0x20,
+#define CONTRAST_DEF 0x20
+ .default_value = CONTRAST_DEF,
},
.set = sd_setcontrast,
.get = sd_getcontrast,
},
-#define SD_COLOR 2
{
{
.id = V4L2_CID_SATURATION,
@@ -104,12 +104,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0xff,
.step = 1,
- .default_value = 0x1a,
+#define COLOR_DEF 0x1a
+ .default_value = COLOR_DEF,
},
.set = sd_setcolors,
.get = sd_getcolors,
},
-#define SD_AUTOGAIN 3
{
{
.id = V4L2_CID_AUTOGAIN,
@@ -118,7 +118,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 1,
+#define AUTOGAIN_DEF 1
+ .default_value = AUTOGAIN_DEF,
},
.set = sd_setautogain,
.get = sd_getautogain,
@@ -180,14 +181,20 @@ static const struct v4l2_pix_format vga_mode2[] = {
#define SPCA504_PCCAM600_OFFSET_MODE 5
#define SPCA504_PCCAM600_OFFSET_DATA 14
/* Frame packet header offsets for the spca533 */
-#define SPCA533_OFFSET_DATA 16
+#define SPCA533_OFFSET_DATA 16
#define SPCA533_OFFSET_FRAMSEQ 15
/* Frame packet header offsets for the spca536 */
-#define SPCA536_OFFSET_DATA 4
-#define SPCA536_OFFSET_FRAMSEQ 1
+#define SPCA536_OFFSET_DATA 4
+#define SPCA536_OFFSET_FRAMSEQ 1
+
+struct cmd {
+ u8 req;
+ u16 val;
+ u16 idx;
+};
/* Initialisation data for the Creative PC-CAM 600 */
-static const __u16 spca504_pccam600_init_data[][3] = {
+static const struct cmd spca504_pccam600_init_data[] = {
/* {0xa0, 0x0000, 0x0503}, * capture mode */
{0x00, 0x0000, 0x2000},
{0x00, 0x0013, 0x2301},
@@ -211,22 +218,20 @@ static const __u16 spca504_pccam600_init_data[][3] = {
{0x00, 0x0003, 0x2000},
{0x00, 0x0013, 0x2301},
{0x00, 0x0003, 0x2000},
- {}
};
/* Creative PC-CAM 600 specific open data, sent before using the
* generic initialisation data from spca504_open_data.
*/
-static const __u16 spca504_pccam600_open_data[][3] = {
+static const struct cmd spca504_pccam600_open_data[] = {
{0x00, 0x0001, 0x2501},
{0x20, 0x0500, 0x0001}, /* snapshot mode */
{0x00, 0x0003, 0x2880},
{0x00, 0x0001, 0x2881},
- {}
};
/* Initialisation data for the logitech clicksmart 420 */
-static const __u16 spca504A_clicksmart420_init_data[][3] = {
+static const struct cmd spca504A_clicksmart420_init_data[] = {
/* {0xa0, 0x0000, 0x0503}, * capture mode */
{0x00, 0x0000, 0x2000},
{0x00, 0x0013, 0x2301},
@@ -243,7 +248,7 @@ static const __u16 spca504A_clicksmart420_init_data[][3] = {
{0xb0, 0x0001, 0x0000},
- {0x0a1, 0x0080, 0x0001},
+ {0xa1, 0x0080, 0x0001},
{0x30, 0x0049, 0x0000},
{0x30, 0x0060, 0x0005},
{0x0c, 0x0004, 0x0000},
@@ -253,11 +258,10 @@ static const __u16 spca504A_clicksmart420_init_data[][3] = {
{0x00, 0x0003, 0x2000},
{0x00, 0x0000, 0x2000},
- {}
};
/* clicksmart 420 open data ? */
-static const __u16 spca504A_clicksmart420_open_data[][3] = {
+static const struct cmd spca504A_clicksmart420_open_data[] = {
{0x00, 0x0001, 0x2501},
{0x20, 0x0502, 0x0000},
{0x06, 0x0000, 0x0000},
@@ -401,10 +405,9 @@ static const __u16 spca504A_clicksmart420_open_data[][3] = {
{0x00, 0x0028, 0x287f},
{0xa0, 0x0000, 0x0503},
- {}
};
-static const __u8 qtable_creative_pccam[2][64] = {
+static const u8 qtable_creative_pccam[2][64] = {
{ /* Q-table Y-components */
0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
@@ -429,7 +432,7 @@ static const __u8 qtable_creative_pccam[2][64] = {
* except for one byte. Possibly a typo?
* NWG: 18/05/2003.
*/
-static const __u8 qtable_spca504_default[2][64] = {
+static const u8 qtable_spca504_default[2][64] = {
{ /* Q-table Y-components */
0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
@@ -453,9 +456,9 @@ static const __u8 qtable_spca504_default[2][64] = {
/* read <len> bytes to gspca_dev->usb_buf */
static void reg_r(struct gspca_dev *gspca_dev,
- __u16 req,
- __u16 index,
- __u16 len)
+ u8 req,
+ u16 index,
+ u16 len)
{
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
@@ -473,31 +476,26 @@ static void reg_r(struct gspca_dev *gspca_dev,
500);
}
-/* write <len> bytes from gspca_dev->usb_buf */
-static void reg_w(struct gspca_dev *gspca_dev,
- __u16 req,
- __u16 value,
- __u16 index,
- __u16 len)
+/* write one byte */
+static void reg_w_1(struct gspca_dev *gspca_dev,
+ u8 req,
+ u16 value,
+ u16 index,
+ u16 byte)
{
-#ifdef GSPCA_DEBUG
- if (len > USB_BUF_SZ) {
- err("reg_w: buffer overflow");
- return;
- }
-#endif
+ gspca_dev->usb_buf[0] = byte;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index,
- len ? gspca_dev->usb_buf : NULL, len,
+ gspca_dev->usb_buf, 1,
500);
}
/* write req / index / value */
static int reg_w_riv(struct usb_device *dev,
- __u16 req, __u16 index, __u16 value)
+ u8 req, u16 index, u16 value)
{
int ret;
@@ -515,7 +513,7 @@ static int reg_w_riv(struct usb_device *dev,
/* read 1 byte */
static int reg_r_1(struct gspca_dev *gspca_dev,
- __u16 value) /* wValue */
+ u16 value) /* wValue */
{
int ret;
@@ -536,9 +534,9 @@ static int reg_r_1(struct gspca_dev *gspca_dev,
/* read 1 or 2 bytes - returns < 0 if error */
static int reg_r_12(struct gspca_dev *gspca_dev,
- __u16 req, /* bRequest */
- __u16 index, /* wIndex */
- __u16 length) /* wLength (1 or 2 only) */
+ u8 req, /* bRequest */
+ u16 index, /* wIndex */
+ u16 length) /* wLength (1 or 2 only) */
{
int ret;
@@ -559,43 +557,40 @@ static int reg_r_12(struct gspca_dev *gspca_dev,
}
static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
+ const struct cmd *data, int ncmds)
{
struct usb_device *dev = gspca_dev->dev;
- int ret, i = 0;
+ int ret;
- while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
- ret = reg_w_riv(dev, data[i][0], data[i][2], data[i][1]);
+ while (--ncmds >= 0) {
+ ret = reg_w_riv(dev, data->req, data->idx, data->val);
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]);
+ "Register write failed for 0x%02x, 0x%04x, 0x%04x",
+ data->req, data->val, data->idx);
return ret;
}
- i++;
+ data++;
}
return 0;
}
static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
- unsigned int request,
- unsigned int ybase,
- unsigned int cbase,
- const __u8 qtable[2][64])
+ const u8 qtable[2][64])
{
struct usb_device *dev = gspca_dev->dev;
int i, err;
/* loop over y components */
for (i = 0; i < 64; i++) {
- err = reg_w_riv(dev, request, ybase + i, qtable[0][i]);
+ err = reg_w_riv(dev, 0x00, 0x2800 + i, qtable[0][i]);
if (err < 0)
return err;
}
/* loop over c components */
for (i = 0; i < 64; i++) {
- err = reg_w_riv(dev, request, cbase + i, qtable[1][i]);
+ err = reg_w_riv(dev, 0x00, 0x2840 + i, qtable[1][i]);
if (err < 0)
return err;
}
@@ -603,34 +598,34 @@ static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
}
static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
- __u16 req, __u16 idx, __u16 val)
+ u8 req, u16 idx, u16 val)
{
struct usb_device *dev = gspca_dev->dev;
- __u8 notdone;
+ int notdone;
reg_w_riv(dev, req, idx, val);
notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
reg_w_riv(dev, req, idx, val);
- PDEBUG(D_FRAM, "before wait 0x%x", notdone);
+ PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
msleep(200);
notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
- PDEBUG(D_FRAM, "after wait 0x%x", notdone);
+ PDEBUG(D_FRAM, "after wait 0x%04x", notdone);
}
static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
- __u16 req,
- __u16 idx, __u16 val, __u8 stat, __u8 count)
+ u8 req,
+ u16 idx, u16 val, u8 stat, u8 count)
{
struct usb_device *dev = gspca_dev->dev;
- __u8 status;
- __u8 endcode;
+ int status;
+ u8 endcode;
reg_w_riv(dev, req, idx, val);
status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
endcode = stat;
- PDEBUG(D_FRAM, "Status 0x%x Need 0x%x", status, stat);
+ PDEBUG(D_FRAM, "Status 0x%x Need 0x%04x", status, stat);
if (!count)
return;
count = 200;
@@ -640,7 +635,7 @@ static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
/* reg_w_riv(dev, req, idx, val); */
status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
if (status == endcode) {
- PDEBUG(D_FRAM, "status 0x%x after wait 0x%x",
+ PDEBUG(D_FRAM, "status 0x%04x after wait %d",
status, 200 - count);
break;
}
@@ -667,8 +662,7 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
while (--count > 0) {
reg_r(gspca_dev, 0x21, 1, 1);
if (gspca_dev->usb_buf[0] != 0) {
- gspca_dev->usb_buf[0] = 0;
- reg_w(gspca_dev, 0x21, 0, 1, 1);
+ reg_w_1(gspca_dev, 0x21, 0, 1, 0);
reg_r(gspca_dev, 0x21, 1, 1);
spca504B_PollingDataReady(gspca_dev);
break;
@@ -679,7 +673,7 @@ static void spca504B_WaitCmdStatus(struct gspca_dev *gspca_dev)
static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
{
- __u8 *data;
+ u8 *data;
data = gspca_dev->usb_buf;
reg_r(gspca_dev, 0x20, 0, 5);
@@ -693,41 +687,34 @@ static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
- __u8 Size;
- __u8 Type;
+ u8 Size;
int rc;
- Size = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
- Type = 0;
+ Size = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
switch (sd->bridge) {
case BRIDGE_SPCA533:
- reg_w(gspca_dev, 0x31, 0, 0, 0);
+ reg_w_riv(dev, 0x31, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
rc = spca504B_PollingDataReady(gspca_dev);
spca50x_GetFirmware(gspca_dev);
- gspca_dev->usb_buf[0] = 2; /* type */
- reg_w(gspca_dev, 0x24, 0, 8, 1);
+ reg_w_1(gspca_dev, 0x24, 0, 8, 2); /* type */
reg_r(gspca_dev, 0x24, 8, 1);
- gspca_dev->usb_buf[0] = Size;
- reg_w(gspca_dev, 0x25, 0, 4, 1);
+ reg_w_1(gspca_dev, 0x25, 0, 4, Size);
reg_r(gspca_dev, 0x25, 4, 1); /* size */
rc = spca504B_PollingDataReady(gspca_dev);
/* Init the cam width height with some values get on init ? */
- reg_w(gspca_dev, 0x31, 0, 4, 0);
+ reg_w_riv(dev, 0x31, 0, 0x04);
spca504B_WaitCmdStatus(gspca_dev);
rc = spca504B_PollingDataReady(gspca_dev);
break;
default:
/* case BRIDGE_SPCA504B: */
/* case BRIDGE_SPCA536: */
- gspca_dev->usb_buf[0] = Size;
- reg_w(gspca_dev, 0x25, 0, 4, 1);
+ reg_w_1(gspca_dev, 0x25, 0, 4, Size);
reg_r(gspca_dev, 0x25, 4, 1); /* size */
- Type = 6;
- gspca_dev->usb_buf[0] = Type;
- reg_w(gspca_dev, 0x27, 0, 0, 1);
+ reg_w_1(gspca_dev, 0x27, 0, 0, 6);
reg_r(gspca_dev, 0x27, 0, 1); /* type */
rc = spca504B_PollingDataReady(gspca_dev);
break;
@@ -767,17 +754,51 @@ static void spca504_wait_status(struct gspca_dev *gspca_dev)
static void spca504B_setQtable(struct gspca_dev *gspca_dev)
{
- gspca_dev->usb_buf[0] = 3;
- reg_w(gspca_dev, 0x26, 0, 0, 1);
+ reg_w_1(gspca_dev, 0x26, 0, 0, 3);
reg_r(gspca_dev, 0x26, 0, 1);
spca504B_PollingDataReady(gspca_dev);
}
-static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ u16 reg;
+
+ reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f0 : 0x21a7;
+ reg_w_riv(dev, 0x00, reg, sd->brightness);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ u16 reg;
+
+ reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f1 : 0x21a8;
+ reg_w_riv(dev, 0x00, reg, sd->contrast);
+}
+
+static void setcolors(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ u16 reg;
+
+ reg = sd->bridge == BRIDGE_SPCA536 ? 0x20f6 : 0x21ae;
+ reg_w_riv(dev, 0x00, reg, sd->colors);
+}
+
+static void init_ctl_reg(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
int pollreg = 1;
+ setbrightness(gspca_dev);
+ setcontrast(gspca_dev);
+ setcolors(gspca_dev);
+
switch (sd->bridge) {
case BRIDGE_SPCA504:
case BRIDGE_SPCA504C:
@@ -786,20 +807,14 @@ static void sp5xx_initContBrigHueRegisters(struct gspca_dev *gspca_dev)
default:
/* case BRIDGE_SPCA533: */
/* case BRIDGE_SPCA504B: */
- reg_w(gspca_dev, 0, 0, 0x21a7, 0); /* brightness */
- reg_w(gspca_dev, 0, 0x20, 0x21a8, 0); /* contrast */
- reg_w(gspca_dev, 0, 0, 0x21ad, 0); /* hue */
- reg_w(gspca_dev, 0, 1, 0x21ac, 0); /* sat/hue */
- reg_w(gspca_dev, 0, 0x20, 0x21ae, 0); /* saturation */
- reg_w(gspca_dev, 0, 0, 0x21a3, 0); /* gamma */
+ reg_w_riv(dev, 0, 0x00, 0x21ad); /* hue */
+ reg_w_riv(dev, 0, 0x01, 0x21ac); /* sat/hue */
+ reg_w_riv(dev, 0, 0x00, 0x21a3); /* gamma */
break;
case BRIDGE_SPCA536:
- reg_w(gspca_dev, 0, 0, 0x20f0, 0);
- reg_w(gspca_dev, 0, 0x21, 0x20f1, 0);
- reg_w(gspca_dev, 0, 0x40, 0x20f5, 0);
- reg_w(gspca_dev, 0, 1, 0x20f4, 0);
- reg_w(gspca_dev, 0, 0x40, 0x20f6, 0);
- reg_w(gspca_dev, 0, 0, 0x2089, 0);
+ reg_w_riv(dev, 0, 0x40, 0x20f5);
+ reg_w_riv(dev, 0, 0x01, 0x20f4);
+ reg_w_riv(dev, 0, 0x00, 0x2089);
break;
}
if (pollreg)
@@ -840,20 +855,24 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* case BRIDGE_SPCA504: */
/* case BRIDGE_SPCA536: */
cam->cam_mode = vga_mode;
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ cam->nmodes =ARRAY_SIZE(vga_mode);
break;
case BRIDGE_SPCA533:
cam->cam_mode = custom_mode;
- cam->nmodes = sizeof custom_mode / sizeof custom_mode[0];
+ if (sd->subtype == MegaImageVI) /* 320x240 only */
+ cam->nmodes = ARRAY_SIZE(custom_mode) - 1;
+ else
+ cam->nmodes = ARRAY_SIZE(custom_mode);
break;
case BRIDGE_SPCA504C:
cam->cam_mode = vga_mode2;
- cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
+ cam->nmodes = ARRAY_SIZE(vga_mode2);
break;
}
- 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 = COLOR_DEF;
+ sd->autogain = AUTOGAIN_DEF;
sd->quality = QUALITY_DEF;
return 0;
}
@@ -863,32 +882,29 @@ static int sd_init(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
- int rc;
- __u8 i;
- __u8 info[6];
- int err_code;
+ int i, err_code;
+ u8 info[6];
switch (sd->bridge) {
case BRIDGE_SPCA504B:
- reg_w(gspca_dev, 0x1d, 0, 0, 0);
- reg_w(gspca_dev, 0, 1, 0x2306, 0);
- reg_w(gspca_dev, 0, 0, 0x0d04, 0);
- reg_w(gspca_dev, 0, 0, 0x2000, 0);
- reg_w(gspca_dev, 0, 0x13, 0x2301, 0);
- reg_w(gspca_dev, 0, 0, 0x2306, 0);
+ reg_w_riv(dev, 0x1d, 0x00, 0);
+ reg_w_riv(dev, 0, 0x01, 0x2306);
+ reg_w_riv(dev, 0, 0x00, 0x0d04);
+ reg_w_riv(dev, 0, 0x00, 0x2000);
+ reg_w_riv(dev, 0, 0x13, 0x2301);
+ reg_w_riv(dev, 0, 0x00, 0x2306);
/* fall thru */
case BRIDGE_SPCA533:
- rc = spca504B_PollingDataReady(gspca_dev);
+ spca504B_PollingDataReady(gspca_dev);
spca50x_GetFirmware(gspca_dev);
break;
case BRIDGE_SPCA536:
spca50x_GetFirmware(gspca_dev);
reg_r(gspca_dev, 0x00, 0x5002, 1);
- gspca_dev->usb_buf[0] = 0;
- reg_w(gspca_dev, 0x24, 0, 0, 1);
+ reg_w_1(gspca_dev, 0x24, 0, 0, 0);
reg_r(gspca_dev, 0x24, 0, 1);
- rc = spca504B_PollingDataReady(gspca_dev);
- reg_w(gspca_dev, 0x34, 0, 0, 0);
+ spca504B_PollingDataReady(gspca_dev);
+ reg_w_riv(dev, 0x34, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
break;
case BRIDGE_SPCA504C: /* pccam600 */
@@ -898,12 +914,13 @@ static int sd_init(struct gspca_dev *gspca_dev)
spca504_wait_status(gspca_dev);
if (sd->subtype == LogitechClickSmart420)
write_vector(gspca_dev,
- spca504A_clicksmart420_open_data);
+ spca504A_clicksmart420_open_data,
+ ARRAY_SIZE(spca504A_clicksmart420_open_data));
else
- write_vector(gspca_dev, spca504_pccam600_open_data);
+ write_vector(gspca_dev, spca504_pccam600_open_data,
+ ARRAY_SIZE(spca504_pccam600_open_data));
err_code = spca50x_setup_qtable(gspca_dev,
- 0x00, 0x2800,
- 0x2840, qtable_creative_pccam);
+ qtable_creative_pccam);
if (err_code < 0) {
PDEBUG(D_ERR|D_STREAM, "spca50x_setup_qtable failed");
return err_code;
@@ -941,8 +958,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
6, 0, 0x86, 1); */
/* spca504A_acknowledged_command (gspca_dev, 0x24,
0, 0, 0x9D, 1); */
- reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
- reg_w_riv(dev, 0x0, 0x2310, 0x05);
+ reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
+ reg_w_riv(dev, 0x00, 0x2310, 0x05);
spca504A_acknowledged_command(gspca_dev, 0x01,
0x0f, 0, 0xff, 0);
}
@@ -950,8 +967,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
reg_w_riv(dev, 0, 0x2000, 0);
reg_w_riv(dev, 0, 0x2883, 1);
err_code = spca50x_setup_qtable(gspca_dev,
- 0x00, 0x2800,
- 0x2840,
qtable_spca504_default);
if (err_code < 0) {
PDEBUG(D_ERR, "spca50x_setup_qtable failed");
@@ -966,10 +981,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
- int rc;
int enable;
- __u8 i;
- __u8 info[6];
+ int i;
+ u8 info[6];
/* create the JPEG header */
sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
@@ -987,16 +1001,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA504B: */
/* case BRIDGE_SPCA533: */
/* case BRIDGE_SPCA536: */
- if (sd->subtype == MegapixV4 ||
- sd->subtype == LogitechClickSmart820) {
- reg_w(gspca_dev, 0xf0, 0, 0, 0);
+ switch (sd->subtype) {
+ case MegapixV4:
+ case LogitechClickSmart820:
+ case MegaImageVI:
+ reg_w_riv(dev, 0xf0, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
reg_r(gspca_dev, 0xf0, 4, 0);
spca504B_WaitCmdStatus(gspca_dev);
- } else {
- reg_w(gspca_dev, 0x31, 0, 4, 0);
+ break;
+ default:
+ reg_w_riv(dev, 0x31, 0, 0x04);
spca504B_WaitCmdStatus(gspca_dev);
- rc = spca504B_PollingDataReady(gspca_dev);
+ spca504B_PollingDataReady(gspca_dev);
+ break;
}
break;
case BRIDGE_SPCA504:
@@ -1030,15 +1048,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
}
spca504B_SetSizeType(gspca_dev);
- reg_w_riv(dev, 0x0, 0x270c, 0x05); /* L92 sno1t.txt */
- reg_w_riv(dev, 0x0, 0x2310, 0x05);
+ reg_w_riv(dev, 0x00, 0x270c, 0x05); /* L92 sno1t.txt */
+ reg_w_riv(dev, 0x00, 0x2310, 0x05);
break;
case BRIDGE_SPCA504C:
if (sd->subtype == LogitechClickSmart420) {
write_vector(gspca_dev,
- spca504A_clicksmart420_init_data);
+ spca504A_clicksmart420_init_data,
+ ARRAY_SIZE(spca504A_clicksmart420_init_data));
} else {
- write_vector(gspca_dev, spca504_pccam600_init_data);
+ write_vector(gspca_dev, spca504_pccam600_init_data,
+ ARRAY_SIZE(spca504_pccam600_init_data));
}
enable = (sd->autogain ? 0x04 : 0x01);
reg_w_riv(dev, 0x0c, 0x0000, enable); /* auto exposure */
@@ -1050,7 +1070,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
spca504B_SetSizeType(gspca_dev);
break;
}
- sp5xx_initContBrigHueRegisters(gspca_dev);
+ init_ctl_reg(gspca_dev);
return 0;
}
@@ -1064,7 +1084,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
/* case BRIDGE_SPCA533: */
/* case BRIDGE_SPCA536: */
/* case BRIDGE_SPCA504B: */
- reg_w(gspca_dev, 0x31, 0, 0, 0);
+ reg_w_riv(dev, 0x31, 0, 0);
spca504B_WaitCmdStatus(gspca_dev);
spca504B_PollingDataReady(gspca_dev);
break;
@@ -1082,7 +1102,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
0x0f, 0x00, 0xff, 1);
} else {
spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
- reg_w_riv(dev, 0x01, 0x000f, 0x00);
+ reg_w_riv(dev, 0x01, 0x000f, 0x0000);
}
break;
}
@@ -1097,12 +1117,12 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
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;
int i, sof = 0;
- static unsigned char ffd9[] = {0xff, 0xd9};
+ static u8 ffd9[] = {0xff, 0xd9};
/* frames are jpeg 4.1.1 without 0xff escape */
switch (sd->bridge) {
@@ -1190,63 +1210,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- reg_w_riv(dev, 0x0, 0x21a7, sd->brightness);
- break;
- case BRIDGE_SPCA536:
- reg_w_riv(dev, 0x0, 0x20f0, sd->brightness);
- break;
- }
-}
-
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- reg_w_riv(dev, 0x0, 0x21a8, sd->contrast);
- break;
- case BRIDGE_SPCA536:
- reg_w_riv(dev, 0x0, 0x20f1, sd->contrast);
- break;
- }
-}
-
-static void setcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- reg_w_riv(dev, 0x0, 0x21ae, sd->colors);
- break;
- case BRIDGE_SPCA536:
- reg_w_riv(dev, 0x0, 0x20f6, sd->colors);
- break;
- }
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1384,6 +1347,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x04fc, 0x5360), BS(SPCA536, 0)},
{USB_DEVICE(0x04fc, 0xffff), BS(SPCA504B, 0)},
{USB_DEVICE(0x052b, 0x1513), BS(SPCA533, MegapixV4)},
+ {USB_DEVICE(0x052b, 0x1803), BS(SPCA533, MegaImageVI)},
{USB_DEVICE(0x0546, 0x3155), BS(SPCA533, 0)},
{USB_DEVICE(0x0546, 0x3191), BS(SPCA504B, 0)},
{USB_DEVICE(0x0546, 0x3273), BS(SPCA504B, 0)},
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 404214b8cd2..1d321c30d22 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -264,6 +264,10 @@ static const struct v4l2_pix_format vga_mode_t16[] = {
/* sensor specific data */
struct additional_sensor_data {
+ const u8 n3[6];
+ const u8 *n4, n4sz;
+ const u8 reg80, reg8e;
+ const u8 nset8[6];
const u8 data1[10];
const u8 data2[9];
const u8 data3[9];
@@ -272,14 +276,55 @@ struct additional_sensor_data {
const u8 stream[4];
};
+static const u8 n4_om6802[] = {
+ 0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
+ 0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
+ 0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
+ 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
+ 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
+ 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
+ 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 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 n4_tas5130a[] = {
+ 0x80, 0x3c, 0x81, 0x68, 0x83, 0xa0, 0x84, 0x20,
+ 0x8a, 0x68, 0x8b, 0x58, 0x8c, 0x88, 0x8e, 0xb4,
+ 0x8f, 0x24, 0xa1, 0xb1, 0xa2, 0x30, 0xa5, 0x10,
+ 0xa6, 0x4a, 0xae, 0x03, 0xb1, 0x44, 0xb2, 0x08,
+ 0xb7, 0x06, 0xb9, 0xe7, 0xbb, 0xc4, 0xbc, 0x4a,
+ 0xbe, 0x36, 0xbf, 0xff, 0xc2, 0x88, 0xc5, 0xc8,
+ 0xc6, 0xda
+};
+
static const struct additional_sensor_data sensor_data[] = {
- { /* OM6802 */
+ { /* 0: OM6802 */
+ .n3 =
+ {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
+ .n4 = n4_om6802,
+ .n4sz = sizeof n4_om6802,
+ .reg80 = 0x3c,
+ .reg8e = 0x33,
+ .nset8 = {0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00},
.data1 =
{0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
0xb3, 0xfc},
.data2 =
{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
0xff},
+ .data3 =
+ {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 */
@@ -287,13 +332,23 @@ static const struct additional_sensor_data sensor_data[] = {
.stream =
{0x0b, 0x04, 0x0a, 0x78},
},
- { /* OTHER */
+ { /* 1: OTHER */
+ .n3 =
+ {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
+ .n4 = n4_other,
+ .n4sz = sizeof n4_other,
+ .reg80 = 0xac,
+ .reg8e = 0xb8,
+ .nset8 = {0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00},
.data1 =
{0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
0xe8, 0xfc},
.data2 =
{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
0xd9},
+ .data3 =
+ {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
+ 0xd9},
.data4 =
{0x66, 0x00, 0xa8, 0xa8},
.data5 =
@@ -301,13 +356,23 @@ static const struct additional_sensor_data sensor_data[] = {
.stream =
{0x0b, 0x04, 0x0a, 0x00},
},
- { /* TAS5130A */
+ { /* 2: TAS5130A */
+ .n3 =
+ {0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
+ .n4 = n4_tas5130a,
+ .n4sz = sizeof n4_tas5130a,
+ .reg80 = 0x3c,
+ .reg8e = 0xb4,
+ .nset8 = {0xa8, 0xf0, 0xc6, 0xda, 0xc0, 0x00},
.data1 =
{0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
0xc8, 0xfc},
.data2 =
{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
0xe0},
+ .data3 =
+ {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
+ 0xe0},
.data4 = /* Freq (50/60Hz). Splitted for test purpose */
{0x66, 0x00, 0xa8, 0xe8},
.data5 =
@@ -364,7 +429,7 @@ static const u8 gamma_table[GAMMA_MAX][17] = {
{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 */
+ {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 */
@@ -385,8 +450,6 @@ 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},
- {0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
- {},
};
static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
@@ -633,10 +696,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
* but wont hurt anyway, and can help someone with similar webcam
* to see the initial parameters.*/
struct sd *sd = (struct sd *) gspca_dev;
+ const struct additional_sensor_data *sensor;
int i;
u16 sensor_id;
u8 test_byte = 0;
- u16 reg80, reg8e;
static const u8 read_indexs[] =
{ 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
@@ -645,37 +708,6 @@ static int sd_init(struct gspca_dev *gspca_dev)
{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
static const u8 n2[] =
{0x08, 0x00};
- static const u8 n3[6] =
- {0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
- 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,
- 0xa2, 0x60, 0xa5, 0x30, 0xa6, 0x3a, 0xa8, 0xe8,
- 0xae, 0x05, 0xb1, 0x00, 0xbb, 0x04, 0xbc, 0x48,
- 0xbe, 0x36, 0xc6, 0x88, 0xe9, 0x00, 0xc5, 0xc0,
- 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 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 };
- 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);
@@ -709,8 +741,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
}
if (i < 0) {
err("Bad sensor reset %02x", test_byte);
-/* return -EIO; */
-/*fixme: test - continue */
+ return -EIO;
}
reg_w_buf(gspca_dev, n2, sizeof n2);
}
@@ -723,31 +754,17 @@ static int sd_init(struct gspca_dev *gspca_dev)
i++;
}
- 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;
- }
+ sensor = &sensor_data[sd->sensor];
+ reg_w_buf(gspca_dev, sensor->n3, sizeof sensor->n3);
+ reg_w_buf(gspca_dev, sensor->n4, sensor->n4sz);
- reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
- sizeof sensor_data[sd->sensor].data1);
- 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_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
- reg_w(gspca_dev, reg80);
- reg_w(gspca_dev, reg80);
- reg_w(gspca_dev, reg8e);
+ reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
+ reg_w(gspca_dev, (sensor->reg80 << 8) + 0x80);
+ reg_w(gspca_dev, (sensor->reg8e << 8) + 0x8e);
setbrightness(gspca_dev);
setcontrast(gspca_dev);
@@ -760,25 +777,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x2088);
reg_w(gspca_dev, 0x2089);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
- sizeof sensor_data[sd->sensor].data4);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
- sizeof sensor_data[sd->sensor].data5);
- 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->data4, sizeof sensor->data4);
+ reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
+ reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
+ reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
- reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
- sizeof sensor_data[sd->sensor].data1);
- 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_ixbuf(gspca_dev, 0xd0, sensor->data1, sizeof sensor->data1);
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor->data2, sizeof sensor->data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor->data3, sizeof sensor->data3);
return 0;
}
@@ -828,7 +834,6 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
* i added some module parameters for test with some users */
static void poll_sensor(struct gspca_dev *gspca_dev)
{
- struct sd *sd = (struct sd *) gspca_dev;
static const u8 poll1[] =
{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
@@ -844,24 +849,23 @@ static void poll_sensor(struct gspca_dev *gspca_dev)
0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
0xc2, 0x80, 0xc3, 0x10};
- 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);
- reg_w_buf(gspca_dev, poll3, sizeof poll3);
- reg_w_buf(gspca_dev, poll4, sizeof poll4);
- }
+ PDEBUG(D_STREAM, "[Sensor requires polling]");
+ reg_w_buf(gspca_dev, poll1, sizeof poll1);
+ reg_w_buf(gspca_dev, poll2, sizeof poll2);
+ reg_w_buf(gspca_dev, poll3, sizeof poll3);
+ reg_w_buf(gspca_dev, poll4, sizeof poll4);
}
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ const struct additional_sensor_data *sensor;
int i, mode;
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;
+ mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
switch (mode) {
case 0: /* 640x480 (0x00) */
break;
@@ -889,34 +893,33 @@ static int sd_start(struct gspca_dev *gspca_dev)
default:
/* case SENSOR_TAS5130A: */
i = 0;
- while (tas5130a_sensor_init[i][0] != 0) {
+ for (;;) {
reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
sizeof tas5130a_sensor_init[0]);
+ if (i >= ARRAY_SIZE(tas5130a_sensor_init) - 1)
+ break;
i++;
}
reg_w(gspca_dev, 0x3c80);
/* just in case and to keep sync with logs (for mine) */
- reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
+ reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
sizeof tas5130a_sensor_init[0]);
reg_w(gspca_dev, 0x3c80);
break;
}
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
- sizeof sensor_data[sd->sensor].data4);
+ sensor = &sensor_data[sd->sensor];
+ reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
reg_r(gspca_dev, 0x0012);
reg_w_buf(gspca_dev, t2, sizeof t2);
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,
- sizeof sensor_data[sd->sensor].stream);
- poll_sensor(gspca_dev);
+ reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
+ reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
+
+ if (sd->sensor == SENSOR_OM6802)
+ poll_sensor(gspca_dev);
- /* restart on each start, just in case, sometimes regs goes wrong
- * when using controls from app */
- setbrightness(gspca_dev);
- setcontrast(gspca_dev);
- setcolors(gspca_dev);
return 0;
}
@@ -926,10 +929,9 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
sizeof sensor_data[sd->sensor].stream);
- msleep(20);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
sizeof sensor_data[sd->sensor].stream);
- if (sd->sensor != SENSOR_OTHER) {
+ if (sd->sensor == SENSOR_OM6802) {
msleep(20);
reg_w(gspca_dev, 0x0309);
}
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 9f243d7e311..4b44dde9f8b 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -426,7 +426,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, packet_type0,
frame, data + 2, gspca_dev->width);
gspca_frame_add(gspca_dev, packet_type1,
- frame, data + gspca_dev->width + 6, gspca_dev->width);
+ frame, data + gspca_dev->width + 5, gspca_dev->width);
}
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 26dd155efcc..619250e7071 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -32,14 +32,14 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- __u8 hflip;
- __u8 vflip;
- __u8 lightfreq;
- __u8 sharpness;
+ u8 hflip;
+ u8 vflip;
+ u8 lightfreq;
+ u8 sharpness;
u8 image_offset;
- char bridge;
+ u8 bridge;
#define BRIDGE_VC0321 0
#define BRIDGE_VC0323 1
u8 sensor;
@@ -52,6 +52,10 @@ struct sd {
#define SENSOR_OV7670 6
#define SENSOR_PO1200 7
#define SENSOR_PO3130NC 8
+ u8 flags;
+#define FL_SAMSUNG 0x01 /* SamsungQ1 (2 sensors) */
+#define FL_HFLIP 0x02 /* mirrored by default */
+#define FL_VFLIP 0x04 /* vertical flipped by default */
};
/* V4L2 controls supported by the driver */
@@ -65,7 +69,7 @@ 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[] = {
-/* next 2 controls work with ov7660 and ov7670 only */
+/* next 2 controls work with some sensors only */
#define HFLIP_IDX 0
{
{
@@ -152,9 +156,9 @@ 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 */
+ {1280, 960, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi1310_soc only */
.bytesperline = 1280,
- .sizeimage = 1280 * 1024 * 1 / 4 + 590,
+ .sizeimage = 1280 * 960 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv = 2},
};
@@ -188,11 +192,11 @@ static const struct v4l2_pix_format svga_mode[] = {
#define OV7660_MVFP_MIRROR 0x20
#define OV7660_MVFP_VFLIP 0x10
-static const __u8 mi0360_matrix[9] = {
+static const u8 mi0360_matrix[9] = {
0x50, 0xf8, 0xf8, 0xf5, 0x50, 0xfb, 0xff, 0xf1, 0x50
};
-static const __u8 mi0360_initVGA_JPG[][4] = {
+static const u8 mi0360_initVGA_JPG[][4] = {
{0xb0, 0x03, 0x19, 0xcc},
{0xb0, 0x04, 0x02, 0xcc},
{0xb3, 0x00, 0x24, 0xcc},
@@ -301,7 +305,7 @@ static const __u8 mi0360_initVGA_JPG[][4] = {
{0xb3, 0x5c, 0x01, 0xcc},
{}
};
-static const __u8 mi0360_initQVGA_JPG[][4] = {
+static const u8 mi0360_initQVGA_JPG[][4] = {
{0xb0, 0x03, 0x19, 0xcc},
{0xb0, 0x04, 0x02, 0xcc},
{0xb3, 0x00, 0x24, 0xcc},
@@ -421,211 +425,95 @@ static const __u8 mi0360_initQVGA_JPG[][4] = {
{}
};
-static const __u8 mi1310_socinitVGA_JPG[][4] = {
+static const u8 mi1310_socinitVGA_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, 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, 0x0d, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
{0xb3, 0x20, 0x00, 0xcc},
{0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x01, 0xcc},
- {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x22, 0x03, 0xcc},
+ {0xb3, 0x23, 0xc0, 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, 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},
+ {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},
{0xf0, 0x00, 0x00, 0xbb},
- {0x00, 0x01, 0x00, 0xdd},
- {0x0d, 0x00, 0x09, 0xbb},
- {0x0d, 0x00, 0x08, 0xbb},
+ {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
{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},
+ {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},
- {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},
+ {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, 0x02, 0xcc},
{0xb6, 0x02, 0x80, 0xcc},
{0xb6, 0x05, 0x01, 0xcc},
{0xb6, 0x04, 0xe0, 0xcc},
- {0xb6, 0x12, 0x78, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x25, 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, 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},
+ {0xbf, 0xcc, 0x00, 0xcc},
{0xbc, 0x02, 0x18, 0xcc},
{0xbc, 0x03, 0x50, 0xcc},
{0xbc, 0x04, 0x18, 0xcc},
@@ -636,133 +524,335 @@ static const __u8 mi1310_socinitQVGA_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},
+ {},
+};
+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}, /* h/v flip */
+ {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},
- {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_soc_InitSXGA_JPG[][4] = {
{0xb0, 0x03, 0x19, 0xcc},
{0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x24, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x65, 0xcc},
{0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x5c, 0x01, 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, 0x0d, 0xcc},
{0xb3, 0x20, 0x00, 0xcc},
{0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x04, 0xcc},
- {0xb3, 0x23, 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},
- {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},
+ {0xb3, 0x00, 0x65, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0x70, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0xc8, 0x9f, 0x0b, 0xbb},
+ {0x5b, 0x00, 0x01, 0xbb},
{0xf0, 0x00, 0x00, 0xbb},
- {0x00, 0x01, 0x00, 0xdd},
- {0x0d, 0x00, 0x09, 0xbb},
- {0x0d, 0x00, 0x08, 0xbb},
+ {0x20, 0x03, 0x02, 0xbb}, /* h/v flip */
{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},
+ {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, 0x60, 0xbb},
+ {0x21, 0xb6, 0x6e, 0xbb},
+ {0x37, 0x01, 0x40, 0xbb},
{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},
+ {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},
{0xb6, 0x00, 0x00, 0xcc},
{0xb6, 0x03, 0x05, 0xcc},
{0xb6, 0x02, 0x00, 0xcc},
- {0xb6, 0x05, 0x04, 0xcc},
- {0xb6, 0x04, 0x00, 0xcc},
+ {0xb6, 0x05, 0x03, 0xcc},
+ {0xb6, 0x04, 0xc0, 0xcc},
{0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x18, 0x0a, 0xcc},
- {0xb6, 0x17, 0x00, 0xcc},
+ {0xb6, 0x13, 0x29, 0xcc},
+ {0xb6, 0x18, 0x09, 0xcc},
+ {0xb6, 0x17, 0x60, 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},
+ {0xbf, 0xcc, 0x00, 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},
+ {0x00, 0x00, 0x80, 0xdd},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {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},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0x06, 0xf0, 0x8e, 0xbb},
+ {0x00, 0x00, 0x80, 0xdd},
+ {0x06, 0x70, 0x8e, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0x5e, 0x6a, 0x53, 0xbb},
+ {0x5f, 0x40, 0x2c, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0x58, 0x00, 0x00, 0xbb},
+ {0x53, 0x09, 0x03, 0xbb},
+ {0x54, 0x31, 0x18, 0xbb},
+ {0x55, 0x8b, 0x5f, 0xbb},
+ {0x56, 0xc0, 0xa9, 0xbb},
+ {0x57, 0xe0, 0xd2, 0xbb},
+ {0xe1, 0x00, 0x00, 0xbb},
+ {0xdc, 0x09, 0x03, 0xbb},
+ {0xdd, 0x31, 0x18, 0xbb},
+ {0xde, 0x8b, 0x5f, 0xbb},
+ {0xdf, 0xc0, 0xa9, 0xbb},
+ {0xe0, 0xe0, 0xd2, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xf0, 0x8e, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x2f, 0xde, 0x20, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x24, 0x50, 0x20, 0xbb},
+ {0xbc, 0x0e, 0x00, 0xcc},
+ {0xbc, 0x0f, 0x05, 0xcc},
+ {0xbc, 0x10, 0xc0, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x34, 0x0c, 0x50, 0xbb},
+ {0xbc, 0x11, 0x03, 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, 0x00, 0xbb},
+ {0x03, 0x03, 0xc0, 0xbb},
{}
};
-static const __u8 mi1320_gamma[17] = {
+static const u8 mi1320_gamma[17] = {
0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
};
-static const __u8 mi1320_matrix[9] = {
+static const u8 mi1320_matrix[9] = {
0x54, 0xda, 0x06, 0xf1, 0x50, 0xf4, 0xf7, 0xea, 0x52
};
-static const __u8 mi1320_initVGA_data[][4] = {
+static const u8 mi1320_initVGA_data[][4] = {
{0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
{0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
{0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
@@ -841,7 +931,7 @@ static const __u8 mi1320_initVGA_data[][4] = {
{0xb3, 0x5c, 0x01, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
{}
};
-static const __u8 mi1320_initQVGA_data[][4] = {
+static const u8 mi1320_initQVGA_data[][4] = {
{0xb3, 0x01, 0x01, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
{0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
{0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x33, 0xdd},
@@ -948,7 +1038,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
{0x07, 0x00, 0xe0, 0xbb},
{0x08, 0x00, 0x0b, 0xbb},
{0x21, 0x00, 0x0c, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
{0xbf, 0xc0, 0x26, 0xcc},
{0xbf, 0xc1, 0x02, 0xcc},
{0xbf, 0xcc, 0x04, 0xcc},
@@ -958,7 +1048,7 @@ static const u8 mi1320_soc_InitVGA[][4] = {
{0x06, 0x00, 0x11, 0xbb},
{0x07, 0x01, 0x42, 0xbb},
{0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
{0x21, 0x80, 0x00, 0xbb},
{0x22, 0x0d, 0x0f, 0xbb},
{0x24, 0x80, 0x00, 0xbb},
@@ -1051,7 +1141,7 @@ static const u8 mi1320_soc_InitQVGA[][4] = {
{0x07, 0x00, 0xe0, 0xbb},
{0x08, 0x00, 0x0b, 0xbb},
{0x21, 0x00, 0x0c, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
{0xbf, 0xc0, 0x26, 0xcc},
{0xbf, 0xc1, 0x02, 0xcc},
{0xbf, 0xcc, 0x04, 0xcc},
@@ -1071,7 +1161,7 @@ static const u8 mi1320_soc_InitQVGA[][4] = {
{0x06, 0x00, 0x11, 0xbb},
{0x07, 0x01, 0x42, 0xbb},
{0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
{0x21, 0x80, 0x00, 0xbb},
{0x22, 0x0d, 0x0f, 0xbb},
{0x24, 0x80, 0x00, 0xbb},
@@ -1161,7 +1251,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
{0x00, 0x00, 0x20, 0xdd},
{0xf0, 0x00, 0x00, 0xbb},
{0x00, 0x00, 0x30, 0xdd},
- {0x20, 0x01, 0x03, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
{0x00, 0x00, 0x20, 0xdd},
{0xbf, 0xc0, 0x26, 0xcc},
{0xbf, 0xc1, 0x02, 0xcc},
@@ -1172,7 +1262,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
{0x06, 0x00, 0x11, 0xbb},
{0x07, 0x01, 0x42, 0xbb},
{0x08, 0x00, 0x11, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
{0x21, 0x80, 0x00, 0xbb},
{0x22, 0x0d, 0x0f, 0xbb},
{0x24, 0x80, 0x00, 0xbb},
@@ -1230,7 +1320,7 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
{0x06, 0x00, 0x11, 0xbb},
{0x07, 0x00, 0x85, 0xbb},
{0x08, 0x00, 0x27, 0xbb},
- {0x20, 0x01, 0x03, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb}, /* h/v flip */
{0x21, 0x80, 0x00, 0xbb},
{0x22, 0x0d, 0x0f, 0xbb},
{0x24, 0x80, 0x00, 0xbb},
@@ -1249,15 +1339,15 @@ static const u8 mi1320_soc_InitSXGA[][4] = {
{0x64, 0x5e, 0x1c, 0xbb},
{}
};
-static const __u8 po3130_gamma[17] = {
+static const u8 po3130_gamma[17] = {
0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
};
-static const __u8 po3130_matrix[9] = {
+static const u8 po3130_matrix[9] = {
0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
};
-static const __u8 po3130_initVGA_data[][4] = {
+static const u8 po3130_initVGA_data[][4] = {
{0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
{0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
{0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc},
@@ -1340,7 +1430,7 @@ static const __u8 po3130_initVGA_data[][4] = {
{0xb3, 0x5c, 0x00, 0xcc}, {0xb3, 0x01, 0x41, 0xcc},
{}
};
-static const __u8 po3130_rundata[][4] = {
+static const u8 po3130_rundata[][4] = {
{0x00, 0x47, 0x45, 0xaa}, {0x00, 0x48, 0x9b, 0xaa},
{0x00, 0x49, 0x3a, 0xaa}, {0x00, 0x4a, 0x01, 0xaa},
{0x00, 0x44, 0x40, 0xaa},
@@ -1355,7 +1445,7 @@ static const __u8 po3130_rundata[][4] = {
{}
};
-static const __u8 po3130_initQVGA_data[][4] = {
+static const u8 po3130_initQVGA_data[][4] = {
{0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
{0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x09, 0xcc},
{0xb3, 0x00, 0x04, 0xcc}, {0xb3, 0x00, 0x24, 0xcc},
@@ -1441,121 +1531,207 @@ static const __u8 po3130_initQVGA_data[][4] = {
{}
};
-static const __u8 hv7131r_gamma[17] = {
-/* 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
- * 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff */
- 0x04, 0x1a, 0x36, 0x55, 0x6f, 0x87, 0x9d, 0xb0, 0xc1,
- 0xcf, 0xda, 0xe4, 0xec, 0xf3, 0xf8, 0xfd, 0xff
+static const u8 hv7131r_gamma[17] = {
+ 0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
+ 0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
};
-static const __u8 hv7131r_matrix[9] = {
+static const u8 hv7131r_matrix[9] = {
0x5f, 0xec, 0xf5, 0xf1, 0x5a, 0xf5, 0xf1, 0xec, 0x63
};
-static const __u8 hv7131r_initVGA_data[][4] = {
- {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
- {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
+static const u8 hv7131r_initVGA_data[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x20, 0xdd},
{0xb3, 0x00, 0x24, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x01, 0x45, 0xcc}, {0xb3, 0x03, 0x0b, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x01, 0x45, 0xcc},
+ {0xb3, 0x03, 0x0b, 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, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x02, 0xcc},
{0xb3, 0x16, 0x02, 0xcc},
- {0xb3, 0x17, 0x7f, 0xcc}, {0xb3, 0x34, 0x01, 0xcc},
- {0xb3, 0x35, 0x91, 0xcc}, {0xb3, 0x00, 0x27, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x34, 0x01, 0xcc},
+ {0xb3, 0x35, 0x91, 0xcc},
+ {0xb3, 0x00, 0x27, 0xcc},
{0xbc, 0x00, 0x73, 0xcc},
- {0xb8, 0x00, 0x23, 0xcc}, {0x00, 0x01, 0x0c, 0xaa},
- {0x00, 0x14, 0x01, 0xaa}, {0x00, 0x15, 0xe6, 0xaa},
- {0x00, 0x16, 0x02, 0xaa},
- {0x00, 0x17, 0x86, 0xaa}, {0x00, 0x23, 0x00, 0xaa},
- {0x00, 0x25, 0x09, 0xaa}, {0x00, 0x26, 0x27, 0xaa},
- {0x00, 0x27, 0xc0, 0xaa},
- {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
- {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
+ {0xb8, 0x00, 0x23, 0xcc},
+ {0xb8, 0x2c, 0x50, 0xcc},
+ {0xb8, 0x2d, 0xf8, 0xcc},
+ {0xb8, 0x2e, 0xf8, 0xcc},
+ {0xb8, 0x2f, 0xf8, 0xcc},
{0xb8, 0x30, 0x50, 0xcc},
- {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc},
- {0xb8, 0x33, 0xf8, 0xcc}, {0xb8, 0x34, 0x65, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf8, 0xcc},
+ {0xb8, 0x33, 0xf8, 0xcc},
+ {0xb8, 0x34, 0x58, 0xcc},
{0xb8, 0x35, 0x00, 0xcc},
- {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc},
- {0xb8, 0x27, 0x20, 0xcc}, {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
{0xb8, 0x81, 0x09, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc},
- {0xb8, 0xff, 0x28, 0xcc}, {0xb9, 0x00, 0x28, 0xcc},
- {0xb9, 0x01, 0x28, 0xcc},
- {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
- {0xb9, 0x04, 0x00, 0xcc}, {0xb9, 0x05, 0x3c, 0xcc},
- {0xb9, 0x06, 0x3c, 0xcc},
- {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc},
- {0xb8, 0x8e, 0x00, 0xcc}, {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0x00, 0x01, 0x0c, 0xaa},
+ {0x00, 0x14, 0x01, 0xaa},
+ {0x00, 0x15, 0xe6, 0xaa},
+ {0x00, 0x16, 0x02, 0xaa},
+ {0x00, 0x17, 0x86, 0xaa},
+ {0x00, 0x23, 0x00, 0xaa},
+ {0x00, 0x25, 0x03, 0xaa},
+ {0x00, 0x26, 0xa9, 0xaa},
+ {0x00, 0x27, 0x80, 0xaa},
{0x00, 0x30, 0x18, 0xaa},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x02, 0xcc},
+ {0xb6, 0x02, 0x80, 0xcc},
+ {0xb6, 0x05, 0x01, 0xcc},
+ {0xb6, 0x04, 0xe0, 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, 0x10, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x0a, 0xcc},
+ {0xb9, 0x14, 0x0a, 0xcc},
+ {0xb9, 0x15, 0x0a, 0xcc},
+ {0xb9, 0x16, 0x0a, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x0f, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
{}
};
-static const __u8 hv7131r_initQVGA_data[][4] = {
- {0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
- {0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
+static const u8 hv7131r_initQVGA_data[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x20, 0xdd},
{0xb3, 0x00, 0x24, 0xcc},
- {0xb3, 0x00, 0x25, 0xcc}, {0xb3, 0x08, 0x01, 0xcc},
- {0xb3, 0x09, 0x0c, 0xcc}, {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x01, 0xcc},
- {0xb3, 0x03, 0x0b, 0xcc}, {0xb3, 0x04, 0x05, 0xcc},
- {0xb3, 0x20, 0x00, 0xcc}, {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x01, 0x45, 0xcc},
+ {0xb3, 0x03, 0x0b, 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, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x02, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
{0xb3, 0x17, 0x7f, 0xcc},
- {0xb3, 0x34, 0x01, 0xcc}, {0xb3, 0x35, 0x91, 0xcc},
- {0xb3, 0x00, 0x27, 0xcc}, {0xbc, 0x00, 0xd1, 0xcc},
- {0xb8, 0x00, 0x21, 0xcc},
- {0x00, 0x01, 0x0c, 0xaa}, {0x00, 0x14, 0x01, 0xaa},
- {0x00, 0x15, 0xe6, 0xaa}, {0x00, 0x16, 0x02, 0xaa},
- {0x00, 0x17, 0x86, 0xaa},
- {0x00, 0x23, 0x00, 0xaa}, {0x00, 0x25, 0x01, 0xaa},
- {0x00, 0x26, 0xd4, 0xaa}, {0x00, 0x27, 0xc0, 0xaa},
- {0xbc, 0x02, 0x08, 0xcc},
- {0xbc, 0x03, 0x70, 0xcc}, {0xbc, 0x04, 0x08, 0xcc},
- {0xbc, 0x05, 0x00, 0xcc}, {0xbc, 0x06, 0x00, 0xcc},
- {0xbc, 0x08, 0x3c, 0xcc},
- {0xbc, 0x09, 0x40, 0xcc}, {0xbc, 0x0a, 0x04, 0xcc},
- {0xbc, 0x0b, 0x00, 0xcc}, {0xbc, 0x0c, 0x00, 0xcc},
- {0xb8, 0xfe, 0x02, 0xcc},
- {0xb8, 0xff, 0x07, 0xcc}, {0xb9, 0x00, 0x14, 0xcc},
- {0xb9, 0x01, 0x14, 0xcc}, {0xb9, 0x02, 0x14, 0xcc},
- {0xb9, 0x03, 0x00, 0xcc},
- {0xb9, 0x04, 0x02, 0xcc}, {0xb9, 0x05, 0x05, 0xcc},
- {0xb9, 0x06, 0x0f, 0xcc}, {0xb9, 0x07, 0x0f, 0xcc},
- {0xb9, 0x08, 0x0f, 0xcc},
- {0xb8, 0x2c, 0x60, 0xcc}, {0xb8, 0x2d, 0xf8, 0xcc},
- {0xb8, 0x2e, 0xf8, 0xcc}, {0xb8, 0x2f, 0xf8, 0xcc},
+ {0xb3, 0x34, 0x01, 0xcc},
+ {0xb3, 0x35, 0x91, 0xcc},
+ {0xb3, 0x00, 0x27, 0xcc},
+ {0xbc, 0x00, 0xd3, 0xcc},
+ {0xb8, 0x00, 0x23, 0xcc},
+ {0xb8, 0x2c, 0x50, 0xcc},
+ {0xb8, 0x2d, 0xf8, 0xcc},
+ {0xb8, 0x2e, 0xf8, 0xcc},
+ {0xb8, 0x2f, 0xf8, 0xcc},
{0xb8, 0x30, 0x50, 0xcc},
- {0xb8, 0x31, 0xf8, 0xcc}, {0xb8, 0x32, 0xf8, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf8, 0xcc},
{0xb8, 0x33, 0xf8, 0xcc},
- {0xb8, 0x34, 0x65, 0xcc}, {0xb8, 0x35, 0x00, 0xcc},
- {0xb8, 0x36, 0x00, 0xcc}, {0xb8, 0x37, 0x00, 0xcc},
+ {0xb8, 0x34, 0x58, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
{0xb8, 0x27, 0x20, 0xcc},
- {0xb8, 0x01, 0x7d, 0xcc}, {0xb8, 0x81, 0x09, 0xcc},
- {0xb3, 0x01, 0x41, 0xcc}, {0xb8, 0xfe, 0x00, 0xcc},
- {0xb8, 0xff, 0x28, 0xcc},
- {0xb9, 0x00, 0x28, 0xcc}, {0xb9, 0x01, 0x28, 0xcc},
- {0xb9, 0x02, 0x28, 0xcc}, {0xb9, 0x03, 0x00, 0xcc},
- {0xb9, 0x04, 0x00, 0xcc},
- {0xb9, 0x05, 0x3c, 0xcc}, {0xb9, 0x06, 0x3c, 0xcc},
- {0xb9, 0x07, 0x3c, 0xcc}, {0xb9, 0x08, 0x3c, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
{0xb8, 0x8e, 0x00, 0xcc},
- {0xb8, 0x8f, 0xff, 0xcc}, {0x00, 0x30, 0x18, 0xaa},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0x00, 0x01, 0x0c, 0xaa},
+ {0x00, 0x14, 0x01, 0xaa},
+ {0x00, 0x15, 0xe6, 0xaa},
+ {0x00, 0x16, 0x02, 0xaa},
+ {0x00, 0x17, 0x86, 0xaa},
+ {0x00, 0x23, 0x00, 0xaa},
+ {0x00, 0x25, 0x03, 0xaa},
+ {0x00, 0x26, 0xa9, 0xaa},
+ {0x00, 0x27, 0x80, 0xaa},
+ {0x00, 0x30, 0x18, 0xaa},
+ {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},
+ {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},
+ {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},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
{}
};
-static const __u8 ov7660_gamma[17] = {
+static const u8 ov7660_gamma[17] = {
0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
};
-static const __u8 ov7660_matrix[9] = {
+static const u8 ov7660_matrix[9] = {
0x5a, 0xf0, 0xf6, 0xf3, 0x57, 0xf6, 0xf3, 0xef, 0x62
};
-static const __u8 ov7660_initVGA_data[][4] = {
+static const u8 ov7660_initVGA_data[][4] = {
{0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
{0x00, 0x00, 0x50, 0xdd},
{0xb0, 0x03, 0x01, 0xcc},
@@ -1613,7 +1789,7 @@ static const __u8 ov7660_initVGA_data[][4] = {
{0x00, 0x29, 0x3c, 0xaa}, {0xb3, 0x01, 0x45, 0xcc},
{}
};
-static const __u8 ov7660_initQVGA_data[][4] = {
+static const u8 ov7660_initQVGA_data[][4] = {
{0xb0, 0x4d, 0x00, 0xcc}, {0xb3, 0x01, 0x01, 0xcc},
{0x00, 0x00, 0x50, 0xdd}, {0xb0, 0x03, 0x01, 0xcc},
{0xb3, 0x00, 0x21, 0xcc}, {0xb3, 0x00, 0x26, 0xcc},
@@ -1682,26 +1858,26 @@ static const __u8 ov7660_initQVGA_data[][4] = {
{}
};
-static const __u8 ov7660_50HZ[][4] = {
+static const u8 ov7660_50HZ[][4] = {
{0x00, 0x3b, 0x08, 0xaa},
{0x00, 0x9d, 0x40, 0xaa},
{0x00, 0x13, 0xa7, 0xaa},
{}
};
-static const __u8 ov7660_60HZ[][4] = {
+static const u8 ov7660_60HZ[][4] = {
{0x00, 0x3b, 0x00, 0xaa},
{0x00, 0x9e, 0x40, 0xaa},
{0x00, 0x13, 0xa7, 0xaa},
{}
};
-static const __u8 ov7660_NoFliker[][4] = {
+static const u8 ov7660_NoFliker[][4] = {
{0x00, 0x13, 0x87, 0xaa},
{}
};
-static const __u8 ov7670_initVGA_JPG[][4] = {
+static const u8 ov7670_initVGA_JPG[][4] = {
{0xb3, 0x01, 0x05, 0xcc},
{0x00, 0x00, 0x30, 0xdd}, {0xb0, 0x03, 0x19, 0xcc},
{0x00, 0x00, 0x10, 0xdd},
@@ -1831,7 +2007,7 @@ static const __u8 ov7670_initVGA_JPG[][4] = {
{},
};
-static const __u8 ov7670_initQVGA_JPG[][4] = {
+static const u8 ov7670_initQVGA_JPG[][4] = {
{0xb3, 0x01, 0x05, 0xcc}, {0x00, 0x00, 0x30, 0xdd},
{0xb0, 0x03, 0x19, 0xcc}, {0x00, 0x00, 0x10, 0xdd},
{0xb0, 0x04, 0x02, 0xcc}, {0x00, 0x00, 0x10, 0xdd},
@@ -1966,14 +2142,14 @@ static const __u8 ov7670_initQVGA_JPG[][4] = {
};
/* PO1200 - values from usbvm326.inf and ms-win trace */
-static const __u8 po1200_gamma[17] = {
+static const u8 po1200_gamma[17] = {
0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
};
-static const __u8 po1200_matrix[9] = {
+static const u8 po1200_matrix[9] = {
0x60, 0xf9, 0xe5, 0xe7, 0x50, 0x05, 0xf3, 0xe6, 0x5e
};
-static const __u8 po1200_initVGA_data[][4] = {
+static const u8 po1200_initVGA_data[][4] = {
{0xb0, 0x03, 0x19, 0xcc}, /* reset? */
{0xb0, 0x03, 0x19, 0xcc},
/* {0x00, 0x00, 0x33, 0xdd}, */
@@ -2276,9 +2452,9 @@ static const struct sensor_info sensor_info_data[] = {
/* read 'len' bytes in gspca_dev->usb_buf */
static void reg_r(struct gspca_dev *gspca_dev,
- __u16 req,
- __u16 index,
- __u16 len)
+ u16 req,
+ u16 index,
+ u16 len)
{
usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -2290,9 +2466,9 @@ static void reg_r(struct gspca_dev *gspca_dev,
}
static void reg_w(struct usb_device *dev,
- __u16 req,
- __u16 value,
- __u16 index)
+ u16 req,
+ u16 value,
+ u16 index)
{
usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
@@ -2342,11 +2518,18 @@ static u16 read_sensor_register(struct gspca_dev *gspca_dev,
static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
int i;
u16 value;
const struct sensor_info *ptsensor_info;
+/*fixme: should also check the other sensor (back mi1320_soc, front mc501cb)*/
+ if (sd->flags & FL_SAMSUNG) {
+ reg_w(dev, 0xa0, 0x01, 0xb301);
+ reg_w(dev, 0x89, 0xf0ff, 0xffff); /* select the back sensor */
+ }
+
reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
PDEBUG(D_PROBE, "check sensor header %02x", gspca_dev->usb_buf[0]);
for (i = 0; i < ARRAY_SIZE(sensor_info_data); i++) {
@@ -2406,17 +2589,17 @@ static void i2c_write(struct gspca_dev *gspca_dev,
}
static void put_tab_to_reg(struct gspca_dev *gspca_dev,
- const __u8 *tab, __u8 tabsize, __u16 addr)
+ const u8 *tab, u8 tabsize, u16 addr)
{
int j;
- __u16 ad = addr;
+ u16 ad = addr;
for (j = 0; j < tabsize; j++)
reg_w(gspca_dev->dev, 0xa0, tab[j], ad++);
}
static void usb_exchange(struct gspca_dev *gspca_dev,
- const __u8 data[][4])
+ const u8 data[][4])
{
struct usb_device *dev = gspca_dev->dev;
int i = 0;
@@ -2466,7 +2649,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
};
cam = &gspca_dev->cam;
- sd->bridge = id->driver_info;
+ sd->bridge = id->driver_info >> 8;
+ sd->flags = id->driver_info & 0xff;
sensor = vc032x_probe_sensor(gspca_dev);
switch (sensor) {
case -1:
@@ -2519,8 +2703,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
case SENSOR_MI1320_SOC:
cam->cam_mode = bi_mode;
cam->nmodes = ARRAY_SIZE(bi_mode);
- cam->input_flags = V4L2_IN_ST_VFLIP |
- V4L2_IN_ST_HFLIP;
break;
default:
cam->cam_mode = vc0323_mode;
@@ -2532,14 +2714,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->hflip = HFLIP_DEF;
sd->vflip = VFLIP_DEF;
- if (sd->sensor == SENSOR_OV7670) {
- sd->hflip = 1;
- sd->vflip = 1;
- }
+ if (sd->sensor == SENSOR_OV7670)
+ sd->flags |= FL_HFLIP | FL_VFLIP;
sd->lightfreq = FREQ_DEF;
if (sd->sensor != SENSOR_OV7670)
gspca_dev->ctrl_dis = (1 << LIGHTFREQ_IDX);
switch (sd->sensor) {
+ case SENSOR_MI1310_SOC:
+ case SENSOR_MI1320_SOC:
case SENSOR_OV7660:
case SENSOR_OV7670:
case SENSOR_PO1200:
@@ -2568,39 +2750,50 @@ static int sd_init(struct gspca_dev *gspca_dev)
return 0;
}
-/* for OV7660 and OV7670 only */
+/* some sensors only */
static void sethvflip(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 data;
-
+ u8 data[2], hflip, vflip;
+
+ hflip = sd->hflip;
+ if (sd->flags & FL_HFLIP)
+ hflip = !hflip;
+ vflip = sd->vflip;
+ if (sd->flags & FL_VFLIP)
+ vflip = !vflip;
switch (sd->sensor) {
- case SENSOR_OV7660:
- data = 1;
+ case SENSOR_MI1310_SOC:
+ case SENSOR_MI1320_SOC:
+ data[0] = data[1] = 0; /* select page 0 */
+ i2c_write(gspca_dev, 0xf0, data, 2);
+ data[0] = sd->sensor == SENSOR_MI1310_SOC ? 0x03 : 0x01;
+ data[1] = 0x02 * hflip
+ | 0x01 * vflip;
+ i2c_write(gspca_dev, 0x20, data, 2);
break;
+ case SENSOR_OV7660:
case SENSOR_OV7670:
- data = 7;
+ data[0] = sd->sensor == SENSOR_OV7660 ? 0x01 : 0x07;
+ data[0] |= OV7660_MVFP_MIRROR * hflip
+ | OV7660_MVFP_VFLIP * vflip;
+ i2c_write(gspca_dev, OV7660_REG_MVFP, data, 1);
break;
case SENSOR_PO1200:
- data = 0;
- i2c_write(gspca_dev, 0x03, &data, 1);
- data = 0x80 * sd->hflip
- | 0x40 * sd->vflip
+ data[0] = 0;
+ i2c_write(gspca_dev, 0x03, data, 1);
+ data[0] = 0x80 * hflip
+ | 0x40 * vflip
| 0x06;
- i2c_write(gspca_dev, 0x1e, &data, 1);
- return;
- default:
- return;
+ i2c_write(gspca_dev, 0x1e, data, 1);
+ break;
}
- data |= OV7660_MVFP_MIRROR * sd->hflip
- | OV7660_MVFP_VFLIP * sd->vflip;
- i2c_write(gspca_dev, OV7660_REG_MVFP, &data, 1);
}
static void setlightfreq(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 (*ov7660_freq_tb[3])[4] =
+ static const u8 (*ov7660_freq_tb[3])[4] =
{ov7660_NoFliker, ov7660_50HZ, ov7660_60HZ};
if (sd->sensor != SENSOR_OV7660)
@@ -2612,7 +2805,7 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
static void setsharpness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 data;
+ u8 data;
if (sd->sensor != SENSOR_PO1200)
return;
@@ -2625,9 +2818,9 @@ 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;
+ const u8 (*init)[4];
+ const u8 *GammaT = NULL;
+ const u8 *MatrixT = NULL;
int mode;
static const u8 (*mi1320_soc_init[])[4] = {
mi1320_soc_InitSXGA,
@@ -2635,6 +2828,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
mi1320_soc_InitQVGA,
};
+/*fixme: back sensor only*/
+ if (sd->flags & FL_SAMSUNG) {
+ reg_w(gspca_dev->dev, 0x89, 0xf0ff, 0xffff);
+ reg_w(gspca_dev->dev, 0xa9, 0x8348, 0x000e);
+ reg_w(gspca_dev->dev, 0xa9, 0x0000, 0x001a);
+ }
+
/* Assume start use the good resolution from gspca_dev->mode */
if (sd->bridge == BRIDGE_VC0321) {
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfec);
@@ -2737,16 +2937,22 @@ static int sd_start(struct gspca_dev *gspca_dev)
put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
/* set the led on 0x0892 0x0896 */
- if (sd->sensor != SENSOR_PO1200) {
- reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
- msleep(100);
- sethvflip(gspca_dev);
- setlightfreq(gspca_dev);
- } else {
- setsharpness(gspca_dev);
- sethvflip(gspca_dev);
+ switch (sd->sensor) {
+ case SENSOR_PO1200:
+ case SENSOR_HV7131R:
reg_w(gspca_dev->dev, 0x89, 0x0400, 0x1415);
+ break;
+ case SENSOR_MI1310_SOC:
+ reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
+ break;
+ default:
+ reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
+ break;
}
+ msleep(100);
+ setsharpness(gspca_dev);
+ sethvflip(gspca_dev);
+ setlightfreq(gspca_dev);
}
return 0;
}
@@ -2754,8 +2960,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
+ struct sd *sd = (struct sd *) gspca_dev;
- reg_w(dev, 0x89, 0xffff, 0xffff);
+ if (sd->sensor == SENSOR_MI1310_SOC)
+ reg_w(dev, 0x89, 0x058c, 0x00ff);
+ else
+ reg_w(dev, 0x89, 0xffff, 0xffff);
reg_w(dev, 0xa0, 0x01, 0xb301);
reg_w(dev, 0xa0, 0x09, 0xb003);
}
@@ -2764,15 +2974,20 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
+ struct sd *sd = (struct sd *) gspca_dev;
if (!gspca_dev->present)
return;
- reg_w(dev, 0x89, 0xffff, 0xffff);
+/*fixme: is this useful?*/
+ if (sd->sensor == SENSOR_MI1310_SOC)
+ reg_w(dev, 0x89, 0x058c, 0x00ff);
+ else
+ reg_w(dev, 0x89, 0xffff, 0xffff);
}
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 pkt length */
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -2872,21 +3087,12 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu)
{
+ static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
+
switch (menu->id) {
case V4L2_CID_POWER_LINE_FREQUENCY:
- switch (menu->index) {
- case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
- strcpy((char *) menu->name, "NoFliker");
- return 0;
- case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
- strcpy((char *) menu->name, "50 Hz");
- return 0;
- default:
-/* case 2: * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
- strcpy((char *) menu->name, "60 Hz");
- return 0;
- }
- break;
+ strcpy((char *) menu->name, freq_nm[menu->index]);
+ return 0;
}
return -EINVAL;
}
@@ -2906,19 +3112,23 @@ static const struct sd_desc sd_desc = {
};
/* -- module initialisation -- */
+#define BF(bridge, flags) \
+ .driver_info = (BRIDGE_ ## bridge << 8) \
+ | (flags)
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},
- {USB_DEVICE(0x0ac8, 0x0321), .driver_info = BRIDGE_VC0321},
- {USB_DEVICE(0x0ac8, 0x0323), .driver_info = BRIDGE_VC0323},
- {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},
+ {USB_DEVICE(0x041e, 0x405b), BF(VC0323, FL_VFLIP)},
+ {USB_DEVICE(0x046d, 0x0892), BF(VC0321, 0)},
+ {USB_DEVICE(0x046d, 0x0896), BF(VC0321, 0)},
+ {USB_DEVICE(0x046d, 0x0897), BF(VC0321, 0)},
+ {USB_DEVICE(0x0ac8, 0x0321), BF(VC0321, 0)},
+ {USB_DEVICE(0x0ac8, 0x0323), BF(VC0323, 0)},
+ {USB_DEVICE(0x0ac8, 0x0328), BF(VC0321, 0)},
+ {USB_DEVICE(0x0ac8, 0xc001), BF(VC0321, 0)},
+ {USB_DEVICE(0x0ac8, 0xc002), BF(VC0321, 0)},
+ {USB_DEVICE(0x0ac8, 0xc301), BF(VC0323, FL_SAMSUNG)},
+ {USB_DEVICE(0x15b8, 0x6001), BF(VC0323, 0)},
+ {USB_DEVICE(0x15b8, 0x6002), BF(VC0323, 0)},
+ {USB_DEVICE(0x17ef, 0x4802), BF(VC0323, 0)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 3d2756f7874..cdf3357b4c9 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -7574,7 +7574,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
.ctrls = sd_ctrls,
- .nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
+ .nctrls = ARRAY_SIZE(sd_ctrls),
.config = sd_config,
.init = sd_init,
.start = sd_start,