// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Connexant Cx11646 library
* Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
*
* V4L2 by Jean-Francois Moine <http://moinejf.free.fr >
*/
#define pr_fmt(fmt) KBUILD_MODNAME
": " fmt
#define MODULE_NAME
"conex"
#include "gspca.h"
#define CONEX_CAM
1 /* special JPEG header */
#include "jpeg.h"
MODULE_AUTHOR(
"Michel Xhaard <mxhaard@users.sourceforge.net>" );
MODULE_DESCRIPTION(
"GSPCA USB Conexant Camera Driver" );
MODULE_LICENSE(
"GPL" );
#define QUALITY
50
/* specific webcam descriptor */
struct sd {
struct gspca_dev gspca_dev;
/* !! must be the first item */
struct v4l2_ctrl *brightness;
struct v4l2_ctrl *contrast;
struct v4l2_ctrl *sat;
u8 jpeg_hdr[JPEG_HDR_SZ];
};
static const struct v4l2_pix_format vga_mode[] = {
{
176 ,
144 , V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline =
176 ,
.sizeimage =
176 *
144 *
3 /
8 +
590 ,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv =
3 },
{
320 ,
240 , V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline =
320 ,
.sizeimage =
320 *
240 *
3 /
8 +
590 ,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv =
2 },
{
352 ,
288 , V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline =
352 ,
.sizeimage =
352 *
288 *
3 /
8 +
590 ,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv =
1 },
{
640 ,
480 , V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline =
640 ,
.sizeimage =
640 *
480 *
3 /
8 +
590 ,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv =
0 },
};
/* the read bytes are found in gspca_dev->usb_buf */
static void reg_r(
struct gspca_dev *gspca_dev,
__u16 index,
__u16 len)
{
struct usb_device *dev = gspca_dev->dev;
if (len > USB_BUF_SZ) {
gspca_err(gspca_dev,
"reg_r: buffer overflow\n" );
return ;
}
usb_control_msg(dev,
usb_rcvctrlpipe(dev,
0 ),
0 ,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0 ,
index, gspca_dev->usb_buf, len,
500 );
gspca_dbg(gspca_dev, D_USBI,
"reg read [%02x] -> %02x ..\n" ,
index, gspca_dev->usb_buf[
0 ]);
}
/* the bytes to write are in gspca_dev->usb_buf */
static void reg_w_val(
struct gspca_dev *gspca_dev,
__u16 index,
__u8 val)
{
struct usb_device *dev = gspca_dev->dev;
gspca_dev->usb_buf[
0 ] = val;
usb_control_msg(dev,
usb_sndctrlpipe(dev,
0 ),
0 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0 ,
index, gspca_dev->usb_buf,
1 ,
500 );
}
static void reg_w(
struct gspca_dev *gspca_dev,
__u16 index,
const __u8 *buffer,
__u16 len)
{
struct usb_device *dev = gspca_dev->dev;
if (len > USB_BUF_SZ) {
gspca_err(gspca_dev,
"reg_w: buffer overflow\n" );
return ;
}
gspca_dbg(gspca_dev, D_USBO,
"reg write [%02x] = %02x..\n" ,
index, *buffer);
memcpy(gspca_dev->usb_buf, buffer, len);
usb_control_msg(dev,
usb_sndctrlpipe(dev,
0 ),
0 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0 ,
index, gspca_dev->usb_buf, len,
500 );
}
static const __u8 cx_sensor_init[][
4 ] = {
{
0 x88,
0 x11,
0 x01,
0 x01},
{
0 x88,
0 x12,
0 x70,
0 x01},
{
0 x88,
0 x0f,
0 x00,
0 x01},
{
0 x88,
0 x05,
0 x01,
0 x01},
{}
};
static const __u8 cx11646_fw1[][
3 ] = {
{
0 x00,
0 x02,
0 x00},
{
0 x01,
0 x43,
0 x00},
{
0 x02,
0 xA7,
0 x00},
{
0 x03,
0 x8B,
0 x01},
{
0 x04,
0 xE9,
0 x02},
{
0 x05,
0 x08,
0 x04},
{
0 x06,
0 x08,
0 x05},
{
0 x07,
0 x07,
0 x06},
{
0 x08,
0 xE7,
0 x06},
{
0 x09,
0 xC6,
0 x07},
{
0 x0A,
0 x86,
0 x08},
{
0 x0B,
0 x46,
0 x09},
{
0 x0C,
0 x05,
0 x0A},
{
0 x0D,
0 xA5,
0 x0A},
{
0 x0E,
0 x45,
0 x0B},
{
0 x0F,
0 xE5,
0 x0B},
{
0 x10,
0 x85,
0 x0C},
{
0 x11,
0 x25,
0 x0D},
{
0 x12,
0 xC4,
0 x0D},
{
0 x13,
0 x45,
0 x0E},
{
0 x14,
0 xE4,
0 x0E},
{
0 x15,
0 x64,
0 x0F},
{
0 x16,
0 xE4,
0 x0F},
{
0 x17,
0 x64,
0 x10},
{
0 x18,
0 xE4,
0 x10},
{
0 x19,
0 x64,
0 x11},
{
0 x1A,
0 xE4,
0 x11},
{
0 x1B,
0 x64,
0 x12},
{
0 x1C,
0 xE3,
0 x12},
{
0 x1D,
0 x44,
0 x13},
{
0 x1E,
0 xC3,
0 x13},
{
0 x1F,
0 x24,
0 x14},
{
0 x20,
0 xA3,
0 x14},
{
0 x21,
0 x04,
0 x15},
{
0 x22,
0 x83,
0 x15},
{
0 x23,
0 xE3,
0 x15},
{
0 x24,
0 x43,
0 x16},
{
0 x25,
0 xA4,
0 x16},
{
0 x26,
0 x23,
0 x17},
{
0 x27,
0 x83,
0 x17},
{
0 x28,
0 xE3,
0 x17},
{
0 x29,
0 x43,
0 x18},
{
0 x2A,
0 xA3,
0 x18},
{
0 x2B,
0 x03,
0 x19},
{
0 x2C,
0 x63,
0 x19},
{
0 x2D,
0 xC3,
0 x19},
{
0 x2E,
0 x22,
0 x1A},
{
0 x2F,
0 x63,
0 x1A},
{
0 x30,
0 xC3,
0 x1A},
{
0 x31,
0 x23,
0 x1B},
{
0 x32,
0 x83,
0 x1B},
{
0 x33,
0 xE2,
0 x1B},
{
0 x34,
0 x23,
0 x1C},
{
0 x35,
0 x83,
0 x1C},
{
0 x36,
0 xE2,
0 x1C},
{
0 x37,
0 x23,
0 x1D},
{
0 x38,
0 x83,
0 x1D},
{
0 x39,
0 xE2,
0 x1D},
{
0 x3A,
0 x23,
0 x1E},
{
0 x3B,
0 x82,
0 x1E},
{
0 x3C,
0 xC3,
0 x1E},
{
0 x3D,
0 x22,
0 x1F},
{
0 x3E,
0 x63,
0 x1F},
{
0 x3F,
0 xC1,
0 x1F},
{}
};
static void cx11646_fw(
struct gspca_dev*gspca_dev)
{
int i =
0 ;
reg_w_val(gspca_dev,
0 x006a,
0 x02);
while (cx11646_fw1[i][
1 ]) {
reg_w(gspca_dev,
0 x006b, cx11646_fw1[i],
3 );
i++;
}
reg_w_val(gspca_dev,
0 x006a,
0 x00);
}
static const __u8 cxsensor[] = {
0 x88,
0 x12,
0 x70,
0 x01,
0 x88,
0 x0d,
0 x02,
0 x01,
0 x88,
0 x0f,
0 x00,
0 x01,
0 x88,
0 x03,
0 x71,
0 x01,
0 x88,
0 x04,
0 x00,
0 x01,
/* 3 */
0 x88,
0 x02,
0 x10,
0 x01,
0 x88,
0 x00,
0 xD4,
0 x01,
0 x88,
0 x01,
0 x01,
0 x01,
/* 5 */
0 x88,
0 x0B,
0 x00,
0 x01,
0 x88,
0 x0A,
0 x0A,
0 x01,
0 x88,
0 x00,
0 x08,
0 x01,
0 x88,
0 x01,
0 x00,
0 x01,
/* 8 */
0 x88,
0 x05,
0 x01,
0 x01,
0 xA1,
0 x18,
0 x00,
0 x01,
0 x00
};
static const __u8 reg20[] = {
0 x10,
0 x42,
0 x81,
0 x19,
0 xd3,
0 xff,
0 xa7,
0 xff };
static const __u8 reg28[] = {
0 x87,
0 x00,
0 x87,
0 x00,
0 x8f,
0 xff,
0 xea,
0 xff };
static const __u8 reg10[] = {
0 xb1,
0 xb1 };
static const __u8 reg71a[] = {
0 x08,
0 x18,
0 x0a,
0 x1e };
/* 640 */
static const __u8 reg71b[] = {
0 x04,
0 x0c,
0 x05,
0 x0f };
/* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
static const __u8 reg71c[] = {
0 x02,
0 x07,
0 x03,
0 x09 };
/* 320{0x04,0x0c,0x05,0x0f}; //320 */
static const __u8 reg71d[] = {
0 x02,
0 x07,
0 x03,
0 x09 };
/* 176 */
static const __u8 reg7b[] = {
0 x00,
0 xff,
0 x00,
0 xff,
0 x00,
0 xff };
static void cx_sensor(
struct gspca_dev*gspca_dev)
{
int i =
0 ;
int length;
const __u8 *ptsensor = cxsensor;
reg_w(gspca_dev,
0 x0020, reg20,
8 );
reg_w(gspca_dev,
0 x0028, reg28,
8 );
reg_w(gspca_dev,
0 x0010, reg10,
2 );
reg_w_val(gspca_dev,
0 x0092,
0 x03);
switch (gspca_dev->cam.cam_mode[(
int ) gspca_dev->curr_mode].priv) {
case 0 :
reg_w(gspca_dev,
0 x0071, reg71a,
4 );
break ;
case 1 :
reg_w(gspca_dev,
0 x0071, reg71b,
4 );
break ;
default :
/* case 2: */
reg_w(gspca_dev,
0 x0071, reg71c,
4 );
break ;
case 3 :
reg_w(gspca_dev,
0 x0071, reg71d,
4 );
break ;
}
reg_w(gspca_dev,
0 x007b, reg7b,
6 );
reg_w_val(gspca_dev,
0 x00f8,
0 x00);
reg_w(gspca_dev,
0 x0010, reg10,
2 );
reg_w_val(gspca_dev,
0 x0098,
0 x41);
for (i =
0 ; i <
11 ; i++) {
if (i ==
3 || i ==
5 || i ==
8 )
length =
8 ;
else
length =
4 ;
reg_w(gspca_dev,
0 x00e5, ptsensor, length);
if (length ==
4 )
reg_r(gspca_dev,
0 x00e8,
1 );
else
reg_r(gspca_dev,
0 x00e8, length);
ptsensor += length;
}
reg_r(gspca_dev,
0 x00e7,
8 );
}
static const __u8 cx_inits_176[] = {
0 x33,
0 x81,
0 xB0,
0 x00,
0 x90,
0 x00,
0 x0A,
0 x03,
/* 176x144 */
0 x00,
0 x03,
0 x03,
0 x03,
0 x1B,
0 x05,
0 x30,
0 x03,
0 x65,
0 x15,
0 x18,
0 x25,
0 x03,
0 x25,
0 x08,
0 x30,
0 x3B,
0 x25,
0 x10,
0 x00,
0 x04,
0 x00,
0 x00,
0 x00,
0 xDC,
0 xFF,
0 xEE,
0 xFF,
0 xC5,
0 xFF,
0 xBF,
0 xFF,
0 xF7,
0 xFF,
0 x88,
0 xFF,
0 x66,
0 x02,
0 x28,
0 x02,
0 x1E,
0 x03,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00
};
static const __u8 cx_inits_320[] = {
0 x7f,
0 x7f,
0 x40,
0 x01,
0 xf0,
0 x00,
0 x02,
0 x01,
0 x00,
0 x01,
0 x01,
0 x01,
0 x10,
0 x00,
0 x02,
0 x01,
0 x65,
0 x45,
0 xfa,
0 x4c,
0 x2c,
0 xdf,
0 xb9,
0 x81,
0 x30,
0 x00,
0 x00,
0 x00,
0 x04,
0 x00,
0 x00,
0 x00,
0 xe2,
0 xff,
0 xf1,
0 xff,
0 xc2,
0 xff,
0 xbc,
0 xff,
0 xf5,
0 xff,
0 x6d,
0 xff,
0 xf6,
0 x01,
0 x43,
0 x02,
0 xd3,
0 x03,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00
};
static const __u8 cx_inits_352[] = {
0 x2e,
0 x7c,
0 x60,
0 x01,
0 x20,
0 x01,
0 x05,
0 x03,
0 x00,
0 x06,
0 x03,
0 x06,
0 x1b,
0 x10,
0 x05,
0 x3b,
0 x30,
0 x25,
0 x18,
0 x25,
0 x08,
0 x30,
0 x03,
0 x25,
0 x3b,
0 x30,
0 x25,
0 x1b,
0 x10,
0 x05,
0 x00,
0 x00,
0 xe3,
0 xff,
0 xf1,
0 xff,
0 xc2,
0 xff,
0 xbc,
0 xff,
0 xf5,
0 xff,
0 x6b,
0 xff,
0 xee,
0 x01,
0 x43,
0 x02,
0 xe4,
0 x03,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00
};
static const __u8 cx_inits_640[] = {
0 x7e,
0 x7e,
0 x80,
0 x02,
0 xe0,
0 x01,
0 x01,
0 x01,
0 x00,
0 x02,
0 x01,
0 x02,
0 x10,
0 x30,
0 x01,
0 x01,
0 x65,
0 x45,
0 xf7,
0 x52,
0 x2c,
0 xdf,
0 xb9,
0 x81,
0 x30,
0 x00,
0 x00,
0 x00,
0 x04,
0 x00,
0 x00,
0 x00,
0 xe2,
0 xff,
0 xf1,
0 xff,
0 xc2,
0 xff,
0 xbc,
0 xff,
0 xf6,
0 xff,
0 x7b,
0 xff,
0 x01,
0 x02,
0 x43,
0 x02,
0 x77,
0 x03,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00
};
static void cx11646_initsize(
struct gspca_dev *gspca_dev)
{
const __u8 *cxinit;
static const __u8 reg12[] = {
0 x08,
0 x05,
0 x07,
0 x04,
0 x24 };
static const __u8 reg17[] =
{
0 x0a,
0 x00,
0 xf2,
0 x01,
0 x0f,
0 x00,
0 x97,
0 x02 };
switch (gspca_dev->cam.cam_mode[(
int ) gspca_dev->curr_mode].priv) {
case 0 :
cxinit = cx_inits_640;
break ;
case 1 :
cxinit = cx_inits_352;
break ;
default :
/* case 2: */
cxinit = cx_inits_320;
break ;
case 3 :
cxinit = cx_inits_176;
break ;
}
reg_w_val(gspca_dev,
0 x009a,
0 x01);
reg_w_val(gspca_dev,
0 x0010,
0 x10);
reg_w(gspca_dev,
0 x0012, reg12,
5 );
reg_w(gspca_dev,
0 x0017, reg17,
8 );
reg_w_val(gspca_dev,
0 x00c0,
0 x00);
reg_w_val(gspca_dev,
0 x00c1,
0 x04);
reg_w_val(gspca_dev,
0 x00c2,
0 x04);
reg_w(gspca_dev,
0 x0061, cxinit,
8 );
cxinit +=
8 ;
reg_w(gspca_dev,
0 x00ca, cxinit,
8 );
cxinit +=
8 ;
reg_w(gspca_dev,
0 x00d2, cxinit,
8 );
cxinit +=
8 ;
reg_w(gspca_dev,
0 x00da, cxinit,
6 );
cxinit +=
8 ;
reg_w(gspca_dev,
0 x0041, cxinit,
8 );
cxinit +=
8 ;
reg_w(gspca_dev,
0 x0049, cxinit,
8 );
cxinit +=
8 ;
reg_w(gspca_dev,
0 x0051, cxinit,
2 );
reg_r(gspca_dev,
0 x0010,
1 );
}
static const __u8 cx_jpeg_init[][
8 ] = {
{
0 xff,
0 xd8,
0 xff,
0 xdb,
0 x00,
0 x84,
0 x00,
0 x15},
/* 1 */
{
0 x0f,
0 x10,
0 x12,
0 x10,
0 x0d,
0 x15,
0 x12,
0 x11},
{
0 x12,
0 x18,
0 x16,
0 x15,
0 x19,
0 x20,
0 x35,
0 x22},
{
0 x20,
0 x1d,
0 x1d,
0 x20,
0 x41,
0 x2e,
0 x31,
0 x26},
{
0 x35,
0 x4d,
0 x43,
0 x51,
0 x4f,
0 x4b,
0 x43,
0 x4a},
{
0 x49,
0 x55,
0 x5F,
0 x79,
0 x67,
0 x55,
0 x5A,
0 x73},
{
0 x5B,
0 x49,
0 x4A,
0 x6A,
0 x90,
0 x6B,
0 x73,
0 x7D},
{
0 x81,
0 x88,
0 x89,
0 x88,
0 x52,
0 x66,
0 x95,
0 xA0},
{
0 x94,
0 x84,
0 x9E,
0 x79,
0 x85,
0 x88,
0 x83,
0 x01},
{
0 x15,
0 x0F,
0 x10,
0 x12,
0 x10,
0 x0D,
0 x15,
0 x12},
{
0 x11,
0 x12,
0 x18,
0 x16,
0 x15,
0 x19,
0 x20,
0 x35},
{
0 x22,
0 x20,
0 x1D,
0 x1D,
0 x20,
0 x41,
0 x2E,
0 x31},
{
0 x26,
0 x35,
0 x4D,
0 x43,
0 x51,
0 x4F,
0 x4B,
0 x43},
{
0 x4A,
0 x49,
0 x55,
0 x5F,
0 x79,
0 x67,
0 x55,
0 x5A},
{
0 x73,
0 x5B,
0 x49,
0 x4A,
0 x6A,
0 x90,
0 x6B,
0 x73},
{
0 x7D,
0 x81,
0 x88,
0 x89,
0 x88,
0 x52,
0 x66,
0 x95},
{
0 xA0,
0 x94,
0 x84,
0 x9E,
0 x79,
0 x85,
0 x88,
0 x83},
{
0 xFF,
0 xC4,
0 x01,
0 xA2,
0 x00,
0 x00,
0 x01,
0 x05},
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x00,
0 x00},
{
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x01,
0 x02},
{
0 x03,
0 x04,
0 x05,
0 x06,
0 x07,
0 x08,
0 x09,
0 x0A},
{
0 x0B,
0 x01,
0 x00,
0 x03,
0 x01,
0 x01,
0 x01,
0 x01},
{
0 x01,
0 x01,
0 x01,
0 x01,
0 x01,
0 x00,
0 x00,
0 x00},
{
0 x00,
0 x00,
0 x00,
0 x01,
0 x02,
0 x03,
0 x04,
0 x05},
{
0 x06,
0 x07,
0 x08,
0 x09,
0 x0A,
0 x0B,
0 x10,
0 x00},
{
0 x02,
0 x01,
0 x03,
0 x03,
0 x02,
0 x04,
0 x03,
0 x05},
{
0 x05,
0 x04,
0 x04,
0 x00,
0 x00,
0 x01,
0 x7D,
0 x01},
{
0 x02,
0 x03,
0 x00,
0 x04,
0 x11,
0 x05,
0 x12,
0 x21},
{
0 x31,
0 x41,
0 x06,
0 x13,
0 x51,
0 x61,
0 x07,
0 x22},
{
0 x71,
0 x14,
0 x32,
0 x81,
0 x91,
0 xA1,
0 x08,
0 x23},
{
0 x42,
0 xB1,
0 xC1,
0 x15,
0 x52,
0 xD1,
0 xF0,
0 x24},
{
0 x33,
0 x62,
0 x72,
0 x82,
0 x09,
0 x0A,
0 x16,
0 x17},
{
0 x18,
0 x19,
0 x1A,
0 x25,
0 x26,
0 x27,
0 x28,
0 x29},
{
0 x2A,
0 x34,
0 x35,
0 x36,
0 x37,
0 x38,
0 x39,
0 x3A},
{
0 x43,
0 x44,
0 x45,
0 x46,
0 x47,
0 x48,
0 x49,
0 x4A},
{
0 x53,
0 x54,
0 x55,
0 x56,
0 x57,
0 x58,
0 x59,
0 x5A},
{
0 x63,
0 x64,
0 x65,
0 x66,
0 x67,
0 x68,
0 x69,
0 x6A},
{
0 x73,
0 x74,
0 x75,
0 x76,
0 x77,
0 x78,
0 x79,
0 x7A},
{
0 x83,
0 x84,
0 x85,
0 x86,
0 x87,
0 x88,
0 x89,
0 x8A},
{
0 x92,
0 x93,
0 x94,
0 x95,
0 x96,
0 x97,
0 x98,
0 x99},
{
0 x9A,
0 xA2,
0 xA3,
0 xA4,
0 xA5,
0 xA6,
0 xA7,
0 xA8},
{
0 xA9,
0 xAA,
0 xB2,
0 xB3,
0 xB4,
0 xB5,
0 xB6,
0 xB7},
{
0 xB8,
0 xB9,
0 xBA,
0 xC2,
0 xC3,
0 xC4,
0 xC5,
0 xC6},
{
0 xC7,
0 xC8,
0 xC9,
0 xCA,
0 xD2,
0 xD3,
0 xD4,
0 xD5},
{
0 xD6,
0 xD7,
0 xD8,
0 xD9,
0 xDA,
0 xE1,
0 xE2,
0 xE3},
{
0 xE4,
0 xE5,
0 xE6,
0 xE7,
0 xE8,
0 xE9,
0 xEA,
0 xF1},
{
0 xF2,
0 xF3,
0 xF4,
0 xF5,
0 xF6,
0 xF7,
0 xF8,
0 xF9},
{
0 xFA,
0 x11,
0 x00,
0 x02,
0 x01,
0 x02,
0 x04,
0 x04},
{
0 x03,
0 x04,
0 x07,
0 x05,
0 x04,
0 x04,
0 x00,
0 x01},
{
0 x02,
0 x77,
0 x00,
0 x01,
0 x02,
0 x03,
0 x11,
0 x04},
{
0 x05,
0 x21,
0 x31,
0 x06,
0 x12,
0 x41,
0 x51,
0 x07},
{
0 x61,
0 x71,
0 x13,
0 x22,
0 x32,
0 x81,
0 x08,
0 x14},
{
0 x42,
0 x91,
0 xA1,
0 xB1,
0 xC1,
0 x09,
0 x23,
0 x33},
{
0 x52,
0 xF0,
0 x15,
0 x62,
0 x72,
0 xD1,
0 x0A,
0 x16},
{
0 x24,
0 x34,
0 xE1,
0 x25,
0 xF1,
0 x17,
0 x18,
0 x19},
{
0 x1A,
0 x26,
0 x27,
0 x28,
0 x29,
0 x2A,
0 x35,
0 x36},
{
0 x37,
0 x38,
0 x39,
0 x3A,
0 x43,
0 x44,
0 x45,
0 x46},
{
0 x47,
0 x48,
0 x49,
0 x4A,
0 x53,
0 x54,
0 x55,
0 x56},
{
0 x57,
0 x58,
0 x59,
0 x5A,
0 x63,
0 x64,
0 x65,
0 x66},
{
0 x67,
0 x68,
0 x69,
0 x6A,
0 x73,
0 x74,
0 x75,
0 x76},
{
0 x77,
0 x78,
0 x79,
0 x7A,
0 x82,
0 x83,
0 x84,
0 x85},
{
0 x86,
0 x87,
0 x88,
0 x89,
0 x8A,
0 x92,
0 x93,
0 x94},
{
0 x95,
0 x96,
0 x97,
0 x98,
0 x99,
0 x9A,
0 xA2,
0 xA3},
{
0 xA4,
0 xA5,
0 xA6,
0 xA7,
0 xA8,
0 xA9,
0 xAA,
0 xB2},
{
0 xB3,
0 xB4,
0 xB5,
0 xB6,
0 xB7,
0 xB8,
0 xB9,
0 xBA},
{
0 xC2,
0 xC3,
0 xC4,
0 xC5,
0 xC6,
0 xC7,
0 xC8,
0 xC9},
{
0 xCA,
0 xD2,
0 xD3,
0 xD4,
0 xD5,
0 xD6,
0 xD7,
0 xD8},
{
0 xD9,
0 xDA,
0 xE2,
0 xE3,
0 xE4,
0 xE5,
0 xE6,
0 xE7},
{
0 xE8,
0 xE9,
0 xEA,
0 xF2,
0 xF3,
0 xF4,
0 xF5,
0 xF6},
{
0 xF7,
0 xF8,
0 xF9,
0 xFA,
0 xFF,
0 x20,
0 x00,
0 x1F},
{
0 x02,
0 x0C,
0 x00,
0 x00,
0 x0A,
0 x00,
0 x00,
0 x00},
{
0 x00,
0 x00,
0 x11,
0 x00,
0 x11,
0 x22,
0 x00,
0 x22},
{
0 x22,
0 x11,
0 x22,
0 x22,
0 x11,
0 x33,
0 x33,
0 x11},
{
0 x44,
0 x66,
0 x22,
0 x55,
0 x66,
0 xFF,
0 xDD,
0 x00},
{
0 x04,
0 x00,
0 x14,
0 xFF,
0 xC0,
0 x00,
0 x11,
0 x08},
{
0 x00,
0 xF0,
0 x01,
0 x40,
0 x03,
0 x00,
0 x21,
0 x00},
{
0 x01,
0 x11,
0 x01,
0 x02,
0 x11,
0 x01,
0 xFF,
0 xDA},
{
0 x00,
0 x0C,
0 x03,
0 x00,
0 x00,
0 x01,
0 x11,
0 x02},
{
0 x11,
0 x00,
0 x3F,
0 x00,
0 xFF,
0 xD9,
0 x00,
0 x00}
/* 79 */
};
static const __u8 cxjpeg_640[][
8 ] = {
{
0 xff,
0 xd8,
0 xff,
0 xdb,
0 x00,
0 x84,
0 x00,
0 x10},
/* 1 */
{
0 x0b,
0 x0c,
0 x0e,
0 x0c,
0 x0a,
0 x10,
0 x0e,
0 x0d},
{
0 x0e,
0 x12,
0 x11,
0 x10,
0 x13,
0 x18,
0 x28,
0 x1a},
{
0 x18,
0 x16,
0 x16,
0 x18,
0 x31,
0 x23,
0 x25,
0 x1d},
{
0 x28,
0 x3a,
0 x33,
0 x3D,
0 x3C,
0 x39,
0 x33,
0 x38},
{
0 x37,
0 x40,
0 x48,
0 x5C,
0 x4E,
0 x40,
0 x44,
0 x57},
{
0 x45,
0 x37,
0 x38,
0 x50,
0 x6D,
0 x51,
0 x57,
0 x5F},
{
0 x62,
0 x67,
0 x68,
0 x67,
0 x3E,
0 x4D,
0 x71,
0 x79},
{
0 x70,
0 x64,
0 x78,
0 x5C,
0 x65,
0 x67,
0 x63,
0 x01},
{
0 x10,
0 x0B,
0 x0C,
0 x0E,
0 x0C,
0 x0A,
0 x10,
0 x0E},
{
0 x0D,
0 x0E,
0 x12,
0 x11,
0 x10,
0 x13,
0 x18,
0 x28},
{
0 x1A,
0 x18,
0 x16,
0 x16,
0 x18,
0 x31,
0 x23,
0 x25},
{
0 x1D,
0 x28,
0 x3A,
0 x33,
0 x3D,
0 x3C,
0 x39,
0 x33},
{
0 x38,
0 x37,
0 x40,
0 x48,
0 x5C,
0 x4E,
0 x40,
0 x44},
{
0 x57,
0 x45,
0 x37,
0 x38,
0 x50,
0 x6D,
0 x51,
0 x57},
{
0 x5F,
0 x62,
0 x67,
0 x68,
0 x67,
0 x3E,
0 x4D,
0 x71},
{
0 x79,
0 x70,
0 x64,
0 x78,
0 x5C,
0 x65,
0 x67,
0 x63},
{
0 xFF,
0 x20,
0 x00,
0 x1F,
0 x00,
0 x83,
0 x00,
0 x00},
{
0 x0A,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x11,
0 x00},
{
0 x11,
0 x22,
0 x00,
0 x22,
0 x22,
0 x11,
0 x22,
0 x22},
{
0 x11,
0 x33,
0 x33,
0 x11,
0 x44,
0 x66,
0 x22,
0 x55},
{
0 x66,
0 xFF,
0 xDD,
0 x00,
0 x04,
0 x00,
0 x28,
0 xFF},
{
0 xC0,
0 x00,
0 x11,
0 x08,
0 x01,
0 xE0,
0 x02,
0 x80},
{
0 x03,
0 x00,
0 x21,
0 x00,
0 x01,
0 x11,
0 x01,
0 x02},
{
0 x11,
0 x01,
0 xFF,
0 xDA,
0 x00,
0 x0C,
0 x03,
0 x00},
{
0 x00,
0 x01,
0 x11,
0 x02,
0 x11,
0 x00,
0 x3F,
0 x00},
{
0 xFF,
0 xD9,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00}
/* 27 */
};
static const __u8 cxjpeg_352[][
8 ] = {
{
0 xff,
0 xd8,
0 xff,
0 xdb,
0 x00,
0 x84,
0 x00,
0 x0d},
{
0 x09,
0 x09,
0 x0b,
0 x09,
0 x08,
0 x0D,
0 x0b,
0 x0a},
{
0 x0b,
0 x0e,
0 x0d,
0 x0d,
0 x0f,
0 x13,
0 x1f,
0 x14},
{
0 x13,
0 x11,
0 x11,
0 x13,
0 x26,
0 x1b,
0 x1d,
0 x17},
{
0 x1F,
0 x2D,
0 x28,
0 x30,
0 x2F,
0 x2D,
0 x28,
0 x2C},
{
0 x2B,
0 x32,
0 x38,
0 x48,
0 x3D,
0 x32,
0 x35,
0 x44},
{
0 x36,
0 x2B,
0 x2C,
0 x3F,
0 x55,
0 x3F,
0 x44,
0 x4A},
{
0 x4D,
0 x50,
0 x51,
0 x50,
0 x30,
0 x3C,
0 x58,
0 x5F},
{
0 x58,
0 x4E,
0 x5E,
0 x48,
0 x4F,
0 x50,
0 x4D,
0 x01},
{
0 x0D,
0 x09,
0 x09,
0 x0B,
0 x09,
0 x08,
0 x0D,
0 x0B},
{
0 x0A,
0 x0B,
0 x0E,
0 x0D,
0 x0D,
0 x0F,
0 x13,
0 x1F},
{
0 x14,
0 x13,
0 x11,
0 x11,
0 x13,
0 x26,
0 x1B,
0 x1D},
{
0 x17,
0 x1F,
0 x2D,
0 x28,
0 x30,
0 x2F,
0 x2D,
0 x28},
{
0 x2C,
0 x2B,
0 x32,
0 x38,
0 x48,
0 x3D,
0 x32,
0 x35},
{
0 x44,
0 x36,
0 x2B,
0 x2C,
0 x3F,
0 x55,
0 x3F,
0 x44},
{
0 x4A,
0 x4D,
0 x50,
0 x51,
0 x50,
0 x30,
0 x3C,
0 x58},
{
0 x5F,
0 x58,
0 x4E,
0 x5E,
0 x48,
0 x4F,
0 x50,
0 x4D},
{
0 xFF,
0 x20,
0 x00,
0 x1F,
0 x01,
0 x83,
0 x00,
0 x00},
{
0 x0A,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x11,
0 x00},
{
0 x11,
0 x22,
0 x00,
0 x22,
0 x22,
0 x11,
0 x22,
0 x22},
{
0 x11,
0 x33,
0 x33,
0 x11,
0 x44,
0 x66,
0 x22,
0 x55},
{
0 x66,
0 xFF,
0 xDD,
0 x00,
0 x04,
0 x00,
0 x16,
0 xFF},
{
0 xC0,
0 x00,
0 x11,
0 x08,
0 x01,
0 x20,
0 x01,
0 x60},
{
0 x03,
0 x00,
0 x21,
0 x00,
0 x01,
0 x11,
0 x01,
0 x02},
{
0 x11,
0 x01,
0 xFF,
0 xDA,
0 x00,
0 x0C,
0 x03,
0 x00},
{
0 x00,
0 x01,
0 x11,
0 x02,
0 x11,
0 x00,
0 x3F,
0 x00},
{
0 xFF,
0 xD9,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00}
};
static const __u8 cxjpeg_320[][
8 ] = {
{
0 xff,
0 xd8,
0 xff,
0 xdb,
0 x00,
0 x84,
0 x00,
0 x05},
{
0 x03,
0 x04,
0 x04,
0 x04,
0 x03,
0 x05,
0 x04,
0 x04},
{
0 x04,
0 x05,
0 x05,
0 x05,
0 x06,
0 x07,
0 x0c,
0 x08},
{
0 x07,
0 x07,
0 x07,
0 x07,
0 x0f,
0 x0b,
0 x0b,
0 x09},
{
0 x0C,
0 x11,
0 x0F,
0 x12,
0 x12,
0 x11,
0 x0f,
0 x11},
{
0 x11,
0 x13,
0 x16,
0 x1C,
0 x17,
0 x13,
0 x14,
0 x1A},
{
0 x15,
0 x11,
0 x11,
0 x18,
0 x21,
0 x18,
0 x1A,
0 x1D},
{
0 x1D,
0 x1F,
0 x1F,
0 x1F,
0 x13,
0 x17,
0 x22,
0 x24},
{
0 x22,
0 x1E,
0 x24,
0 x1C,
0 x1E,
0 x1F,
0 x1E,
0 x01},
{
0 x05,
0 x03,
0 x04,
0 x04,
0 x04,
0 x03,
0 x05,
0 x04},
{
0 x04,
0 x04,
0 x05,
0 x05,
0 x05,
0 x06,
0 x07,
0 x0C},
{
0 x08,
0 x07,
0 x07,
0 x07,
0 x07,
0 x0F,
0 x0B,
0 x0B},
{
0 x09,
0 x0C,
0 x11,
0 x0F,
0 x12,
0 x12,
0 x11,
0 x0F},
{
0 x11,
0 x11,
0 x13,
0 x16,
0 x1C,
0 x17,
0 x13,
0 x14},
{
0 x1A,
0 x15,
0 x11,
0 x11,
0 x18,
0 x21,
0 x18,
0 x1A},
{
0 x1D,
0 x1D,
0 x1F,
0 x1F,
0 x1F,
0 x13,
0 x17,
0 x22},
{
0 x24,
0 x22,
0 x1E,
0 x24,
0 x1C,
0 x1E,
0 x1F,
0 x1E},
{
0 xFF,
0 x20,
0 x00,
0 x1F,
0 x02,
0 x0C,
0 x00,
0 x00},
{
0 x0A,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x11,
0 x00},
{
0 x11,
0 x22,
0 x00,
0 x22,
0 x22,
0 x11,
0 x22,
0 x22},
{
0 x11,
0 x33,
0 x33,
0 x11,
0 x44,
0 x66,
0 x22,
0 x55},
{
0 x66,
0 xFF,
0 xDD,
0 x00,
0 x04,
0 x00,
0 x14,
0 xFF},
{
0 xC0,
0 x00,
0 x11,
0 x08,
0 x00,
0 xF0,
0 x01,
0 x40},
{
0 x03,
0 x00,
0 x21,
0 x00,
0 x01,
0 x11,
0 x01,
0 x02},
{
0 x11,
0 x01,
0 xFF,
0 xDA,
0 x00,
0 x0C,
0 x03,
0 x00},
{
0 x00,
0 x01,
0 x11,
0 x02,
0 x11,
0 x00,
0 x3F,
0 x00},
{
0 xFF,
0 xD9,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00}
/* 27 */
};
static const __u8 cxjpeg_176[][
8 ] = {
{
0 xff,
0 xd8,
0 xff,
0 xdb,
0 x00,
0 x84,
0 x00,
0 x0d},
{
0 x09,
0 x09,
0 x0B,
0 x09,
0 x08,
0 x0D,
0 x0B,
0 x0A},
{
0 x0B,
0 x0E,
0 x0D,
0 x0D,
0 x0F,
0 x13,
0 x1F,
0 x14},
{
0 x13,
0 x11,
0 x11,
0 x13,
0 x26,
0 x1B,
0 x1D,
0 x17},
{
0 x1F,
0 x2D,
0 x28,
0 x30,
0 x2F,
0 x2D,
0 x28,
0 x2C},
{
0 x2B,
0 x32,
0 x38,
0 x48,
0 x3D,
0 x32,
0 x35,
0 x44},
{
0 x36,
0 x2B,
0 x2C,
0 x3F,
0 x55,
0 x3F,
0 x44,
0 x4A},
{
0 x4D,
0 x50,
0 x51,
0 x50,
0 x30,
0 x3C,
0 x58,
0 x5F},
{
0 x58,
0 x4E,
0 x5E,
0 x48,
0 x4F,
0 x50,
0 x4D,
0 x01},
{
0 x0D,
0 x09,
0 x09,
0 x0B,
0 x09,
0 x08,
0 x0D,
0 x0B},
{
0 x0A,
0 x0B,
0 x0E,
0 x0D,
0 x0D,
0 x0F,
0 x13,
0 x1F},
{
0 x14,
0 x13,
0 x11,
0 x11,
0 x13,
0 x26,
0 x1B,
0 x1D},
{
0 x17,
0 x1F,
0 x2D,
0 x28,
0 x30,
0 x2F,
0 x2D,
0 x28},
{
0 x2C,
0 x2B,
0 x32,
0 x38,
0 x48,
0 x3D,
0 x32,
0 x35},
{
0 x44,
0 x36,
0 x2B,
0 x2C,
0 x3F,
0 x55,
0 x3F,
0 x44},
{
0 x4A,
0 x4D,
0 x50,
0 x51,
0 x50,
0 x30,
0 x3C,
0 x58},
{
0 x5F,
0 x58,
0 x4E,
0 x5E,
0 x48,
0 x4F,
0 x50,
0 x4D},
{
0 xFF,
0 x20,
0 x00,
0 x1F,
0 x03,
0 xA1,
0 x00,
0 x00},
{
0 x0A,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x11,
0 x00},
{
0 x11,
0 x22,
0 x00,
0 x22,
0 x22,
0 x11,
0 x22,
0 x22},
{
0 x11,
0 x33,
0 x33,
0 x11,
0 x44,
0 x66,
0 x22,
0 x55},
{
0 x66,
0 xFF,
0 xDD,
0 x00,
0 x04,
0 x00,
0 x0B,
0 xFF},
{
0 xC0,
0 x00,
0 x11,
0 x08,
0 x00,
0 x90,
0 x00,
0 xB0},
{
0 x03,
0 x00,
0 x21,
0 x00,
0 x01,
0 x11,
0 x01,
0 x02},
{
0 x11,
0 x01,
0 xFF,
0 xDA,
0 x00,
0 x0C,
0 x03,
0 x00},
{
0 x00,
0 x01,
0 x11,
0 x02,
0 x11,
0 x00,
0 x3F,
0 x00},
{
0 xFF,
0 xD9,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00}
};
/* 640 take with the zcx30x part */
static const __u8 cxjpeg_qtable[][
8 ] = {
{
0 xff,
0 xd8,
0 xff,
0 xdb,
0 x00,
0 x84,
0 x00,
0 x08},
{
0 x06,
0 x06,
0 x07,
0 x06,
0 x05,
0 x08,
0 x07,
0 x07},
{
0 x07,
0 x09,
0 x09,
0 x08,
0 x0a,
0 x0c,
0 x14,
0 x0a},
{
0 x0c,
0 x0b,
0 x0b,
0 x0c,
0 x19,
0 x12,
0 x13,
0 x0f},
{
0 x14,
0 x1d,
0 x1a,
0 x1f,
0 x1e,
0 x1d,
0 x1a,
0 x1c},
{
0 x1c,
0 x20,
0 x24,
0 x2e,
0 x27,
0 x20,
0 x22,
0 x2c},
{
0 x23,
0 x1c,
0 x1c,
0 x28,
0 x37,
0 x29,
0 x2c,
0 x30},
{
0 x31,
0 x34,
0 x34,
0 x34,
0 x1f,
0 x27,
0 x39,
0 x3d},
{
0 x38,
0 x32,
0 x3c,
0 x2e,
0 x33,
0 x34,
0 x32,
0 x01},
{
0 x09,
0 x09,
0 x09,
0 x0c,
0 x0b,
0 x0c,
0 x18,
0 x0a},
{
0 x0a,
0 x18,
0 x32,
0 x21,
0 x1c,
0 x21,
0 x32,
0 x32},
{
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32},
{
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32},
{
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32},
{
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32},
{
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32},
{
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32,
0 x32},
{
0 xFF,
0 xD9,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00,
0 x00}
/* 18 */
};
static void cx11646_jpegInit(
struct gspca_dev*gspca_dev)
{
int i;
int length;
reg_w_val(gspca_dev,
0 x00c0,
0 x01);
reg_w_val(gspca_dev,
0 x00c3,
0 x00);
reg_w_val(gspca_dev,
0 x00c0,
0 x00);
reg_r(gspca_dev,
0 x0001,
1 );
length =
8 ;
for (i =
0 ; i <
79 ; i++) {
if (i ==
78 )
length =
6 ;
reg_w(gspca_dev,
0 x0008, cx_jpeg_init[i], length);
}
reg_r(gspca_dev,
0 x0002,
1 );
reg_w_val(gspca_dev,
0 x0055,
0 x14);
}
static const __u8 reg12[] = {
0 x0a,
0 x05,
0 x07,
0 x04,
0 x19 };
static const __u8 regE5_8[] =
{
0 x88,
0 x00,
0 xd4,
0 x01,
0 x88,
0 x01,
0 x01,
0 x01 };
static const __u8 regE5a[] = {
0 x88,
0 x0a,
0 x0c,
0 x01 };
static const __u8 regE5b[] = {
0 x88,
0 x0b,
0 x12,
0 x01 };
static const __u8 regE5c[] = {
0 x88,
0 x05,
0 x01,
0 x01 };
static const __u8 reg51[] = {
0 x77,
0 x03 };
#define reg70
0 x03
static void cx11646_jpeg(
struct gspca_dev*gspca_dev)
{
int i;
int length;
__u8 Reg55;
int retry;
reg_w_val(gspca_dev,
0 x00c0,
0 x01);
reg_w_val(gspca_dev,
0 x00c3,
0 x00);
reg_w_val(gspca_dev,
0 x00c0,
0 x00);
reg_r(gspca_dev,
0 x0001,
1 );
length =
8 ;
switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
case 0 :
for (i =
0 ; i <
27 ; i++) {
if (i ==
26 )
length =
2 ;
reg_w(gspca_dev,
0 x0008, cxjpeg_640[i], length);
}
Reg55 =
0 x28;
break ;
case 1 :
for (i =
0 ; i <
27 ; i++) {
if (i ==
26 )
length =
2 ;
reg_w(gspca_dev,
0 x0008, cxjpeg_352[i], length);
}
Reg55 =
0 x16;
break ;
default :
/* case 2: */
for (i =
0 ; i <
27 ; i++) {
if (i ==
26 )
length =
2 ;
reg_w(gspca_dev,
0 x0008, cxjpeg_320[i], length);
}
Reg55 =
0 x14;
break ;
case 3 :
for (i =
0 ; i <
27 ; i++) {
if (i ==
26 )
length =
2 ;
reg_w(gspca_dev,
0 x0008, cxjpeg_176[i], length);
}
Reg55 =
0 x0B;
break ;
}
reg_r(gspca_dev,
0 x0002,
1 );
reg_w_val(gspca_dev,
0 x0055, Reg55);
reg_r(gspca_dev,
0 x0002,
1 );
reg_w(gspca_dev,
0 x0010, reg10,
2 );
reg_w_val(gspca_dev,
0 x0054,
0 x02);
reg_w_val(gspca_dev,
0 x0054,
0 x01);
reg_w_val(gspca_dev,
0 x0000,
0 x94);
reg_w_val(gspca_dev,
0 x0053,
0 xc0);
reg_w_val(gspca_dev,
0 x00fc,
0 xe1);
reg_w_val(gspca_dev,
0 x0000,
0 x00);
/* wait for completion */
retry =
50 ;
do {
reg_r(gspca_dev,
0 x0002,
1 );
/* 0x07 until 0x00 */
if (gspca_dev->usb_buf[
0 ] ==
0 x00)
break ;
reg_w_val(gspca_dev,
0 x0053,
0 x00);
}
while (--retry);
if (retry ==
0 )
gspca_err(gspca_dev,
"Damned Errors sending jpeg Table\n" );
/* send the qtable now */
reg_r(gspca_dev,
0 x0001,
1 );
/* -> 0x18 */
length =
8 ;
for (i =
0 ; i <
18 ; i++) {
if (i ==
17 )
length =
2 ;
reg_w(gspca_dev,
0 x0008, cxjpeg_qtable[i], length);
}
reg_r(gspca_dev,
0 x0002,
1 );
/* 0x00 */
reg_r(gspca_dev,
0 x0053,
1 );
/* 0x00 */
reg_w_val(gspca_dev,
0 x0054,
0 x02);
reg_w_val(gspca_dev,
0 x0054,
0 x01);
reg_w_val(gspca_dev,
0 x0000,
0 x94);
reg_w_val(gspca_dev,
0 x0053,
0 xc0);
reg_r(gspca_dev,
0 x0038,
1 );
/* 0x40 */
reg_r(gspca_dev,
0 x0038,
1 );
/* 0x40 */
reg_r(gspca_dev,
0 x001f,
1 );
/* 0x38 */
reg_w(gspca_dev,
0 x0012, reg12,
5 );
reg_w(gspca_dev,
0 x00e5, regE5_8,
8 );
reg_r(gspca_dev,
0 x00e8,
8 );
reg_w(gspca_dev,
0 x00e5, regE5a,
4 );
reg_r(gspca_dev,
0 x00e8,
1 );
/* 0x00 */
reg_w_val(gspca_dev,
0 x009a,
0 x01);
reg_w(gspca_dev,
0 x00e5, regE5b,
4 );
reg_r(gspca_dev,
0 x00e8,
1 );
/* 0x00 */
reg_w(gspca_dev,
0 x00e5, regE5c,
4 );
reg_r(gspca_dev,
0 x00e8,
1 );
/* 0x00 */
reg_w(gspca_dev,
0 x0051, reg51,
2 );
reg_w(gspca_dev,
0 x0010, reg10,
2 );
reg_w_val(gspca_dev,
0 x0070, reg70);
}
static void cx11646_init1(
struct gspca_dev *gspca_dev)
{
int i =
0 ;
reg_w_val(gspca_dev,
0 x0010,
0 x00);
reg_w_val(gspca_dev,
0 x0053,
0 x00);
reg_w_val(gspca_dev,
0 x0052,
0 x00);
reg_w_val(gspca_dev,
0 x009b,
0 x2f);
reg_w_val(gspca_dev,
0 x009c,
0 x10);
reg_r(gspca_dev,
0 x0098,
1 );
reg_w_val(gspca_dev,
0 x0098,
0 x40);
reg_r(gspca_dev,
0 x0099,
1 );
reg_w_val(gspca_dev,
0 x0099,
0 x07);
reg_w_val(gspca_dev,
0 x0039,
0 x40);
reg_w_val(gspca_dev,
0 x003c,
0 xff);
reg_w_val(gspca_dev,
0 x003f,
0 x1f);
reg_w_val(gspca_dev,
0 x003d,
0 x40);
/* reg_w_val(gspca_dev, 0x003d, 0x60); */
reg_r(gspca_dev,
0 x0099,
1 );
/* ->0x07 */
while (cx_sensor_init[i][
0 ]) {
reg_w_val(gspca_dev,
0 x00e5, cx_sensor_init[i][
0 ]);
reg_r(gspca_dev,
0 x00e8,
1 );
/* -> 0x00 */
if (i ==
1 ) {
reg_w_val(gspca_dev,
0 x00ed,
0 x01);
reg_r(gspca_dev,
0 x00ed,
1 );
/* -> 0x01 */
}
i++;
}
reg_w_val(gspca_dev,
0 x00c3,
0 x00);
}
/* this function is called at probe time */
static int sd_config(
struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
struct cam *cam;
cam = &gspca_dev->cam;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
return 0 ;
}
/* this function is called at probe and resume time */
static int sd_init(
struct gspca_dev *gspca_dev)
{
cx11646_init1(gspca_dev);
cx11646_initsize(gspca_dev);
cx11646_fw(gspca_dev);
cx_sensor(gspca_dev);
cx11646_jpegInit(gspca_dev);
return 0 ;
}
static int sd_start(
struct gspca_dev *gspca_dev)
{
struct sd *sd = (
struct sd *) gspca_dev;
/* create the JPEG header */
jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
gspca_dev->pixfmt.width,
0 x22);
/* JPEG 411 */
jpeg_set_qual(sd->jpeg_hdr, QUALITY);
cx11646_initsize(gspca_dev);
cx11646_fw(gspca_dev);
cx_sensor(gspca_dev);
cx11646_jpeg(gspca_dev);
return 0 ;
}
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(
struct gspca_dev *gspca_dev)
{
int retry =
50 ;
if (!gspca_dev->present)
return ;
reg_w_val(gspca_dev,
0 x0000,
0 x00);
reg_r(gspca_dev,
0 x0002,
1 );
reg_w_val(gspca_dev,
0 x0053,
0 x00);
while (retry--) {
/* reg_r(gspca_dev, 0x0002, 1);*/
reg_r(gspca_dev,
0 x0053,
1 );
if (gspca_dev->usb_buf[
0 ] ==
0 )
break ;
}
reg_w_val(gspca_dev,
0 x0000,
0 x00);
reg_r(gspca_dev,
0 x0002,
1 );
reg_w_val(gspca_dev,
0 x0010,
0 x00);
reg_r(gspca_dev,
0 x0033,
1 );
reg_w_val(gspca_dev,
0 x00fc,
0 xe0);
}
static void sd_pkt_scan(
struct gspca_dev *gspca_dev,
u8 *data,
/* isoc packet */
int len)
/* iso packet length */
{
struct sd *sd = (
struct sd *) gspca_dev;
if (data[
0 ] ==
0 xff && data[
1 ] ==
0 xd8) {
/* start of frame */
gspca_frame_add(gspca_dev, LAST_PACKET, NULL,
0 );
/* put the JPEG header in the new frame */
gspca_frame_add(gspca_dev, FIRST_PACKET,
sd->jpeg_hdr, JPEG_HDR_SZ);
data +=
2 ;
len -=
2 ;
}
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
}
static void setbrightness(
struct gspca_dev *gspca_dev, s32 val, s32 sat)
{
__u8 regE5cbx[] = {
0 x88,
0 x00,
0 xd4,
0 x01,
0 x88,
0 x01,
0 x01,
0 x01 };
__u8 reg51c[
2 ];
regE5cbx[
2 ] = val;
reg_w(gspca_dev,
0 x00e5, regE5cbx,
8 );
reg_r(gspca_dev,
0 x00e8,
8 );
reg_w(gspca_dev,
0 x00e5, regE5c,
4 );
reg_r(gspca_dev,
0 x00e8,
1 );
/* 0x00 */
reg51c[
0 ] =
0 x77;
reg51c[
1 ] = sat;
reg_w(gspca_dev,
0 x0051, reg51c,
2 );
reg_w(gspca_dev,
0 x0010, reg10,
2 );
reg_w_val(gspca_dev,
0 x0070, reg70);
}
static void setcontrast(
struct gspca_dev *gspca_dev, s32 val, s32 sat)
{
__u8 regE5acx[] = {
0 x88,
0 x0a,
0 x0c,
0 x01 };
/* seem MSB */
/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
__u8 reg51c[
2 ];
regE5acx[
2 ] = val;
reg_w(gspca_dev,
0 x00e5, regE5acx,
4 );
reg_r(gspca_dev,
0 x00e8,
1 );
/* 0x00 */
reg51c[
0 ] =
0 x77;
reg51c[
1 ] = sat;
reg_w(gspca_dev,
0 x0051, reg51c,
2 );
reg_w(gspca_dev,
0 x0010, reg10,
2 );
reg_w_val(gspca_dev,
0 x0070, reg70);
}
static int sd_s_ctrl(
struct v4l2_ctrl *ctrl)
{
struct gspca_dev *gspca_dev =
container_of(ctrl->handler,
struct gspca_dev, ctrl_handler);
struct sd *sd = (
struct sd *)gspca_dev;
gspca_dev->usb_err =
0 ;
if (!gspca_dev->streaming)
return 0 ;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
break ;
case V4L2_CID_CONTRAST:
setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
break ;
case V4L2_CID_SATURATION:
setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
break ;
}
return gspca_dev->usb_err;
}
static const struct v4l2_ctrl_ops sd_ctrl_ops = {
.s_ctrl = sd_s_ctrl,
};
static int sd_init_controls(
struct gspca_dev *gspca_dev)
{
struct sd *sd = (
struct sd *)gspca_dev;
struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
gspca_dev->vdev.ctrl_handler = hdl;
v4l2_ctrl_handler_init(hdl,
3 );
sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
V4L2_CID_BRIGHTNESS,
0 ,
255 ,
1 ,
0 xd4);
sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
V4L2_CID_CONTRAST,
0 x0a,
0 x1f,
1 ,
0 x0c);
sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
V4L2_CID_SATURATION,
0 ,
7 ,
1 ,
3 );
if (hdl->error) {
pr_err(
"Could not initialize controls\n" );
return hdl->error;
}
return 0 ;
}
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
.config = sd_config,
.init = sd_init,
.init_controls = sd_init_controls,
.start = sd_start,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
};
/* -- module initialisation -- */
static const struct usb_device_id device_table[] = {
{USB_DEVICE(
0 x0572,
0 x0041)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
/* -- device connect -- */
static int sd_probe(
struct usb_interface *intf,
const struct usb_device_id *id)
{
return gspca_dev_probe(intf, id, &sd_desc,
sizeof (
struct sd),
THIS_MODULE);
}
static struct usb_driver sd_driver = {
.name = MODULE_NAME,
.id_table = device_table,
.probe = sd_probe,
.disconnect = gspca_disconnect,
#ifdef CONFIG_PM
.suspend = gspca_suspend,
.resume = gspca_resume,
.reset_resume = gspca_resume,
#endif
};
module_usb_driver(sd_driver);
Messung V0.5 in Prozent C=94 H=93 G=93
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland