2008-06-30 22:50:11 +04:00
/*
* Connexant Cx11646 library
* Copyright ( C ) 2004 Michel Xhaard mxhaard @ magic . fr
*
* V4L2 by Jean - Francois Moine < http : //moinejf.free.fr>
*
* 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 "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 " ) ;
/* specific webcam descriptor */
struct sd {
struct gspca_dev gspca_dev ; /* !! must be the first item */
unsigned char brightness ;
unsigned char contrast ;
unsigned char colors ;
unsigned char qindex ;
} ;
/* V4L2 controls supported by the driver */
static int sd_setbrightness ( struct gspca_dev * gspca_dev , __s32 val ) ;
static int sd_getbrightness ( struct gspca_dev * gspca_dev , __s32 * val ) ;
static int sd_setcontrast ( struct gspca_dev * gspca_dev , __s32 val ) ;
static int sd_getcontrast ( struct gspca_dev * gspca_dev , __s32 * val ) ;
static int sd_setcolors ( struct gspca_dev * gspca_dev , __s32 val ) ;
static int sd_getcolors ( struct gspca_dev * gspca_dev , __s32 * val ) ;
static struct ctrl sd_ctrls [ ] = {
{
{
. id = V4L2_CID_BRIGHTNESS ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Brightness " ,
. minimum = 0 ,
. maximum = 255 ,
. step = 1 ,
2008-07-05 18:49:20 +04:00
# define BRIGHTNESS_DEF 0xd4
. default_value = BRIGHTNESS_DEF ,
2008-06-30 22:50:11 +04:00
} ,
. set = sd_setbrightness ,
. get = sd_getbrightness ,
} ,
{
{
. id = V4L2_CID_CONTRAST ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Contrast " ,
. minimum = 0x0a ,
. maximum = 0x1f ,
. step = 1 ,
2008-07-05 18:49:20 +04:00
# define CONTRAST_DEF 0x0c
. default_value = CONTRAST_DEF ,
2008-06-30 22:50:11 +04:00
} ,
. set = sd_setcontrast ,
. get = sd_getcontrast ,
} ,
{
{
. id = V4L2_CID_SATURATION ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Color " ,
. minimum = 0 ,
. maximum = 7 ,
. step = 1 ,
2008-07-05 18:49:20 +04:00
# define COLOR_DEF 3
. default_value = COLOR_DEF ,
2008-06-30 22:50:11 +04:00
} ,
. set = sd_setcolors ,
. get = sd_getcolors ,
} ,
} ;
2008-07-05 18:49:20 +04:00
static 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 } ,
2008-06-30 22:50:11 +04:00
} ;
2008-07-14 16:38:29 +04:00
/* the read bytes are found in gspca_dev->usb_buf */
static void reg_r ( struct gspca_dev * gspca_dev ,
__u16 index ,
__u16 len )
2008-06-30 22:50:11 +04:00
{
2008-07-14 16:38:29 +04:00
struct usb_device * dev = gspca_dev - > dev ;
# ifdef CONFIG_VIDEO_ADV_DEBUG
if ( len > sizeof gspca_dev - > usb_buf ) {
err ( " reg_r: buffer overflow " ) ;
return ;
}
# endif
2008-06-30 22:50:11 +04:00
usb_control_msg ( dev ,
usb_rcvctrlpipe ( dev , 0 ) ,
0 ,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE ,
0 ,
2008-07-14 16:38:29 +04:00
index , gspca_dev - > usb_buf , len ,
2008-06-30 22:50:11 +04:00
500 ) ;
2008-07-14 16:38:29 +04:00
PDEBUG ( D_USBI , " reg read [%02x] -> %02x .. " ,
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 ) ;
2008-06-30 22:50:11 +04:00
}
2008-07-14 16:38:29 +04:00
static void reg_w ( struct gspca_dev * gspca_dev ,
2008-06-30 22:50:11 +04:00
__u16 index ,
2008-07-14 16:38:29 +04:00
const __u8 * buffer ,
__u16 len )
2008-06-30 22:50:11 +04:00
{
2008-07-14 16:38:29 +04:00
struct usb_device * dev = gspca_dev - > dev ;
2008-07-03 18:09:12 +04:00
# ifdef CONFIG_VIDEO_ADV_DEBUG
2008-07-14 16:38:29 +04:00
if ( len > sizeof gspca_dev - > usb_buf ) {
err ( " reg_w: buffer overflow " ) ;
2008-07-03 18:09:12 +04:00
return ;
}
PDEBUG ( D_USBO , " reg write [%02x] = %02x.. " , index , * buffer ) ;
# endif
2008-07-14 16:38:29 +04:00
memcpy ( gspca_dev - > usb_buf , buffer , len ) ;
2008-06-30 22:50:11 +04:00
usb_control_msg ( dev ,
usb_sndctrlpipe ( dev , 0 ) ,
0 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE ,
0 ,
2008-07-14 16:38:29 +04:00
index , gspca_dev - > usb_buf , len , 500 ) ;
2008-06-30 22:50:11 +04:00
}
static const __u8 cx_sensor_init [ ] [ 4 ] = {
{ 0x88 , 0x11 , 0x01 , 0x01 } ,
{ 0x88 , 0x12 , 0x70 , 0x01 } ,
{ 0x88 , 0x0f , 0x00 , 0x01 } ,
{ 0x88 , 0x05 , 0x01 , 0x01 } ,
{ }
} ;
static const __u8 cx11646_fw1 [ ] [ 3 ] = {
{ 0x00 , 0x02 , 0x00 } ,
{ 0x01 , 0x43 , 0x00 } ,
{ 0x02 , 0xA7 , 0x00 } ,
{ 0x03 , 0x8B , 0x01 } ,
{ 0x04 , 0xE9 , 0x02 } ,
{ 0x05 , 0x08 , 0x04 } ,
{ 0x06 , 0x08 , 0x05 } ,
{ 0x07 , 0x07 , 0x06 } ,
{ 0x08 , 0xE7 , 0x06 } ,
{ 0x09 , 0xC6 , 0x07 } ,
{ 0x0A , 0x86 , 0x08 } ,
{ 0x0B , 0x46 , 0x09 } ,
{ 0x0C , 0x05 , 0x0A } ,
{ 0x0D , 0xA5 , 0x0A } ,
{ 0x0E , 0x45 , 0x0B } ,
{ 0x0F , 0xE5 , 0x0B } ,
{ 0x10 , 0x85 , 0x0C } ,
{ 0x11 , 0x25 , 0x0D } ,
{ 0x12 , 0xC4 , 0x0D } ,
{ 0x13 , 0x45 , 0x0E } ,
{ 0x14 , 0xE4 , 0x0E } ,
{ 0x15 , 0x64 , 0x0F } ,
{ 0x16 , 0xE4 , 0x0F } ,
{ 0x17 , 0x64 , 0x10 } ,
{ 0x18 , 0xE4 , 0x10 } ,
{ 0x19 , 0x64 , 0x11 } ,
{ 0x1A , 0xE4 , 0x11 } ,
{ 0x1B , 0x64 , 0x12 } ,
{ 0x1C , 0xE3 , 0x12 } ,
{ 0x1D , 0x44 , 0x13 } ,
{ 0x1E , 0xC3 , 0x13 } ,
{ 0x1F , 0x24 , 0x14 } ,
{ 0x20 , 0xA3 , 0x14 } ,
{ 0x21 , 0x04 , 0x15 } ,
{ 0x22 , 0x83 , 0x15 } ,
{ 0x23 , 0xE3 , 0x15 } ,
{ 0x24 , 0x43 , 0x16 } ,
{ 0x25 , 0xA4 , 0x16 } ,
{ 0x26 , 0x23 , 0x17 } ,
{ 0x27 , 0x83 , 0x17 } ,
{ 0x28 , 0xE3 , 0x17 } ,
{ 0x29 , 0x43 , 0x18 } ,
{ 0x2A , 0xA3 , 0x18 } ,
{ 0x2B , 0x03 , 0x19 } ,
{ 0x2C , 0x63 , 0x19 } ,
{ 0x2D , 0xC3 , 0x19 } ,
{ 0x2E , 0x22 , 0x1A } ,
{ 0x2F , 0x63 , 0x1A } ,
{ 0x30 , 0xC3 , 0x1A } ,
{ 0x31 , 0x23 , 0x1B } ,
{ 0x32 , 0x83 , 0x1B } ,
{ 0x33 , 0xE2 , 0x1B } ,
{ 0x34 , 0x23 , 0x1C } ,
{ 0x35 , 0x83 , 0x1C } ,
{ 0x36 , 0xE2 , 0x1C } ,
{ 0x37 , 0x23 , 0x1D } ,
{ 0x38 , 0x83 , 0x1D } ,
{ 0x39 , 0xE2 , 0x1D } ,
{ 0x3A , 0x23 , 0x1E } ,
{ 0x3B , 0x82 , 0x1E } ,
{ 0x3C , 0xC3 , 0x1E } ,
{ 0x3D , 0x22 , 0x1F } ,
{ 0x3E , 0x63 , 0x1F } ,
{ 0x3F , 0xC1 , 0x1F } ,
{ }
} ;
static void cx11646_fw ( struct gspca_dev * gspca_dev )
{
int i = 0 ;
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x006a , 0x02 ) ;
2008-06-30 22:50:11 +04:00
while ( cx11646_fw1 [ i ] [ 1 ] ) {
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x006b , cx11646_fw1 [ i ] , 3 ) ;
2008-06-30 22:50:11 +04:00
i + + ;
}
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x006a , 0x00 ) ;
2008-06-30 22:50:11 +04:00
}
2008-07-04 18:16:16 +04:00
static const __u8 cxsensor [ ] = {
2008-06-30 22:50:11 +04:00
0x88 , 0x12 , 0x70 , 0x01 ,
0x88 , 0x0d , 0x02 , 0x01 ,
0x88 , 0x0f , 0x00 , 0x01 ,
0x88 , 0x03 , 0x71 , 0x01 , 0x88 , 0x04 , 0x00 , 0x01 , /* 3 */
0x88 , 0x02 , 0x10 , 0x01 ,
0x88 , 0x00 , 0xD4 , 0x01 , 0x88 , 0x01 , 0x01 , 0x01 , /* 5 */
0x88 , 0x0B , 0x00 , 0x01 ,
0x88 , 0x0A , 0x0A , 0x01 ,
0x88 , 0x00 , 0x08 , 0x01 , 0x88 , 0x01 , 0x00 , 0x01 , /* 8 */
0x88 , 0x05 , 0x01 , 0x01 ,
0xA1 , 0x18 , 0x00 , 0x01 ,
0x00
} ;
2008-07-04 18:16:16 +04:00
static const __u8 reg20 [ ] = { 0x10 , 0x42 , 0x81 , 0x19 , 0xd3 , 0xff , 0xa7 , 0xff } ;
static const __u8 reg28 [ ] = { 0x87 , 0x00 , 0x87 , 0x00 , 0x8f , 0xff , 0xea , 0xff } ;
static const __u8 reg10 [ ] = { 0xb1 , 0xb1 } ;
static const __u8 reg71a [ ] = { 0x08 , 0x18 , 0x0a , 0x1e } ; /* 640 */
static const __u8 reg71b [ ] = { 0x04 , 0x0c , 0x05 , 0x0f } ;
2008-06-30 22:50:11 +04:00
/* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
2008-07-04 18:16:16 +04:00
static const __u8 reg71c [ ] = { 0x02 , 0x07 , 0x03 , 0x09 } ;
2008-06-30 22:50:11 +04:00
/* 320{0x04,0x0c,0x05,0x0f}; //320 */
2008-07-04 18:16:16 +04:00
static const __u8 reg71d [ ] = { 0x02 , 0x07 , 0x03 , 0x09 } ; /* 176 */
static const __u8 reg7b [ ] = { 0x00 , 0xff , 0x00 , 0xff , 0x00 , 0xff } ;
2008-06-30 22:50:11 +04:00
static void cx_sensor ( struct gspca_dev * gspca_dev )
{
int i = 0 ;
2008-07-04 18:16:16 +04:00
int length ;
const __u8 * ptsensor = cxsensor ;
2008-06-30 22:50:11 +04:00
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0020 , reg20 , 8 ) ;
reg_w ( gspca_dev , 0x0028 , reg28 , 8 ) ;
reg_w ( gspca_dev , 0x0010 , reg10 , 8 ) ;
reg_w_val ( gspca_dev , 0x0092 , 0x03 ) ;
2008-06-30 22:50:11 +04:00
2008-07-05 18:49:20 +04:00
switch ( gspca_dev - > cam . cam_mode [ ( int ) gspca_dev - > curr_mode ] . priv ) {
2008-06-30 22:50:11 +04:00
case 0 :
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0071 , reg71a , 4 ) ;
2008-06-30 22:50:11 +04:00
break ;
case 1 :
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0071 , reg71b , 4 ) ;
2008-06-30 22:50:11 +04:00
break ;
default :
2008-07-03 18:09:12 +04:00
/* case 2: */
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0071 , reg71c , 4 ) ;
2008-06-30 22:50:11 +04:00
break ;
case 3 :
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0071 , reg71d , 4 ) ;
2008-06-30 22:50:11 +04:00
break ;
}
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x007b , reg7b , 6 ) ;
reg_w_val ( gspca_dev , 0x00f8 , 0x00 ) ;
reg_w ( gspca_dev , 0x0010 , reg10 , 8 ) ;
reg_w_val ( gspca_dev , 0x0098 , 0x41 ) ;
2008-06-30 22:50:11 +04:00
for ( i = 0 ; i < 11 ; i + + ) {
if ( i = = 3 | | i = = 5 | | i = = 8 )
length = 8 ;
else
length = 4 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x00e5 , ptsensor , length ) ;
2008-06-30 22:50:11 +04:00
if ( length = = 4 )
2008-07-14 16:38:29 +04:00
reg_r ( gspca_dev , 0x00e8 , 1 ) ;
2008-06-30 22:50:11 +04:00
else
2008-07-14 16:38:29 +04:00
reg_r ( gspca_dev , 0x00e8 , length ) ;
2008-06-30 22:50:11 +04:00
ptsensor + = length ;
}
2008-07-14 16:38:29 +04:00
reg_r ( gspca_dev , 0x00e7 , 8 ) ;
2008-06-30 22:50:11 +04:00
}
2008-07-04 18:16:16 +04:00
static const __u8 cx_inits_176 [ ] = {
2008-06-30 22:50:11 +04:00
0x33 , 0x81 , 0xB0 , 0x00 , 0x90 , 0x00 , 0x0A , 0x03 , /* 176x144 */
0x00 , 0x03 , 0x03 , 0x03 , 0x1B , 0x05 , 0x30 , 0x03 ,
0x65 , 0x15 , 0x18 , 0x25 , 0x03 , 0x25 , 0x08 , 0x30 ,
0x3B , 0x25 , 0x10 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0xDC , 0xFF , 0xEE , 0xFF , 0xC5 , 0xFF , 0xBF , 0xFF ,
0xF7 , 0xFF , 0x88 , 0xFF , 0x66 , 0x02 , 0x28 , 0x02 ,
0x1E , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
} ;
2008-07-04 18:16:16 +04:00
static const __u8 cx_inits_320 [ ] = {
2008-06-30 22:50:11 +04:00
0x7f , 0x7f , 0x40 , 0x01 , 0xf0 , 0x00 , 0x02 , 0x01 ,
0x00 , 0x01 , 0x01 , 0x01 , 0x10 , 0x00 , 0x02 , 0x01 ,
0x65 , 0x45 , 0xfa , 0x4c , 0x2c , 0xdf , 0xb9 , 0x81 ,
0x30 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0xe2 , 0xff , 0xf1 , 0xff , 0xc2 , 0xff , 0xbc , 0xff ,
0xf5 , 0xff , 0x6d , 0xff , 0xf6 , 0x01 , 0x43 , 0x02 ,
0xd3 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
} ;
2008-07-04 18:16:16 +04:00
static const __u8 cx_inits_352 [ ] = {
2008-06-30 22:50:11 +04:00
0x2e , 0x7c , 0x60 , 0x01 , 0x20 , 0x01 , 0x05 , 0x03 ,
0x00 , 0x06 , 0x03 , 0x06 , 0x1b , 0x10 , 0x05 , 0x3b ,
0x30 , 0x25 , 0x18 , 0x25 , 0x08 , 0x30 , 0x03 , 0x25 ,
0x3b , 0x30 , 0x25 , 0x1b , 0x10 , 0x05 , 0x00 , 0x00 ,
0xe3 , 0xff , 0xf1 , 0xff , 0xc2 , 0xff , 0xbc , 0xff ,
0xf5 , 0xff , 0x6b , 0xff , 0xee , 0x01 , 0x43 , 0x02 ,
0xe4 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
} ;
2008-07-04 18:16:16 +04:00
static const __u8 cx_inits_640 [ ] = {
2008-06-30 22:50:11 +04:00
0x7e , 0x7e , 0x80 , 0x02 , 0xe0 , 0x01 , 0x01 , 0x01 ,
0x00 , 0x02 , 0x01 , 0x02 , 0x10 , 0x30 , 0x01 , 0x01 ,
0x65 , 0x45 , 0xf7 , 0x52 , 0x2c , 0xdf , 0xb9 , 0x81 ,
0x30 , 0x00 , 0x00 , 0x00 , 0x04 , 0x00 , 0x00 , 0x00 ,
0xe2 , 0xff , 0xf1 , 0xff , 0xc2 , 0xff , 0xbc , 0xff ,
0xf6 , 0xff , 0x7b , 0xff , 0x01 , 0x02 , 0x43 , 0x02 ,
0x77 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
} ;
2008-07-14 16:38:29 +04:00
static void cx11646_initsize ( struct gspca_dev * gspca_dev )
2008-06-30 22:50:11 +04:00
{
2008-07-04 18:16:16 +04:00
const __u8 * cxinit ;
2008-06-30 22:50:11 +04:00
static const __u8 reg12 [ ] = { 0x08 , 0x05 , 0x07 , 0x04 , 0x24 } ;
static const __u8 reg17 [ ] =
{ 0x0a , 0x00 , 0xf2 , 0x01 , 0x0f , 0x00 , 0x97 , 0x02 } ;
2008-07-05 18:49:20 +04:00
switch ( gspca_dev - > cam . cam_mode [ ( int ) gspca_dev - > curr_mode ] . priv ) {
2008-06-30 22:50:11 +04:00
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 ;
}
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x009a , 0x01 ) ;
reg_w_val ( gspca_dev , 0x0010 , 0x10 ) ;
reg_w ( gspca_dev , 0x0012 , reg12 , 5 ) ;
reg_w ( gspca_dev , 0x0017 , reg17 , 8 ) ;
reg_w_val ( gspca_dev , 0x00c0 , 0x00 ) ;
reg_w_val ( gspca_dev , 0x00c1 , 0x04 ) ;
reg_w_val ( gspca_dev , 0x00c2 , 0x04 ) ;
reg_w ( gspca_dev , 0x0061 , cxinit , 8 ) ;
2008-06-30 22:50:11 +04:00
cxinit + = 8 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x00ca , cxinit , 8 ) ;
2008-06-30 22:50:11 +04:00
cxinit + = 8 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x00d2 , cxinit , 8 ) ;
2008-06-30 22:50:11 +04:00
cxinit + = 8 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x00da , cxinit , 6 ) ;
2008-06-30 22:50:11 +04:00
cxinit + = 8 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0041 , cxinit , 8 ) ;
2008-06-30 22:50:11 +04:00
cxinit + = 8 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0049 , cxinit , 8 ) ;
2008-06-30 22:50:11 +04:00
cxinit + = 8 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0051 , cxinit , 2 ) ;
2008-06-30 22:50:11 +04:00
2008-07-14 16:38:29 +04:00
reg_r ( gspca_dev , 0x0010 , 1 ) ;
2008-06-30 22:50:11 +04:00
}
2008-07-04 18:16:16 +04:00
static const __u8 cx_jpeg_init [ ] [ 8 ] = {
2008-06-30 22:50:11 +04:00
{ 0xff , 0xd8 , 0xff , 0xdb , 0x00 , 0x84 , 0x00 , 0x15 } , /* 1 */
{ 0x0f , 0x10 , 0x12 , 0x10 , 0x0d , 0x15 , 0x12 , 0x11 } ,
{ 0x12 , 0x18 , 0x16 , 0x15 , 0x19 , 0x20 , 0x35 , 0x22 } ,
{ 0x20 , 0x1d , 0x1d , 0x20 , 0x41 , 0x2e , 0x31 , 0x26 } ,
{ 0x35 , 0x4d , 0x43 , 0x51 , 0x4f , 0x4b , 0x43 , 0x4a } ,
{ 0x49 , 0x55 , 0x5F , 0x79 , 0x67 , 0x55 , 0x5A , 0x73 } ,
{ 0x5B , 0x49 , 0x4A , 0x6A , 0x90 , 0x6B , 0x73 , 0x7D } ,
{ 0x81 , 0x88 , 0x89 , 0x88 , 0x52 , 0x66 , 0x95 , 0xA0 } ,
{ 0x94 , 0x84 , 0x9E , 0x79 , 0x85 , 0x88 , 0x83 , 0x01 } ,
{ 0x15 , 0x0F , 0x10 , 0x12 , 0x10 , 0x0D , 0x15 , 0x12 } ,
{ 0x11 , 0x12 , 0x18 , 0x16 , 0x15 , 0x19 , 0x20 , 0x35 } ,
{ 0x22 , 0x20 , 0x1D , 0x1D , 0x20 , 0x41 , 0x2E , 0x31 } ,
{ 0x26 , 0x35 , 0x4D , 0x43 , 0x51 , 0x4F , 0x4B , 0x43 } ,
{ 0x4A , 0x49 , 0x55 , 0x5F , 0x79 , 0x67 , 0x55 , 0x5A } ,
{ 0x73 , 0x5B , 0x49 , 0x4A , 0x6A , 0x90 , 0x6B , 0x73 } ,
{ 0x7D , 0x81 , 0x88 , 0x89 , 0x88 , 0x52 , 0x66 , 0x95 } ,
{ 0xA0 , 0x94 , 0x84 , 0x9E , 0x79 , 0x85 , 0x88 , 0x83 } ,
{ 0xFF , 0xC4 , 0x01 , 0xA2 , 0x00 , 0x00 , 0x01 , 0x05 } ,
{ 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x00 , 0x00 } ,
{ 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x01 , 0x02 } ,
{ 0x03 , 0x04 , 0x05 , 0x06 , 0x07 , 0x08 , 0x09 , 0x0A } ,
{ 0x0B , 0x01 , 0x00 , 0x03 , 0x01 , 0x01 , 0x01 , 0x01 } ,
{ 0x01 , 0x01 , 0x01 , 0x01 , 0x01 , 0x00 , 0x00 , 0x00 } ,
{ 0x00 , 0x00 , 0x00 , 0x01 , 0x02 , 0x03 , 0x04 , 0x05 } ,
{ 0x06 , 0x07 , 0x08 , 0x09 , 0x0A , 0x0B , 0x10 , 0x00 } ,
{ 0x02 , 0x01 , 0x03 , 0x03 , 0x02 , 0x04 , 0x03 , 0x05 } ,
{ 0x05 , 0x04 , 0x04 , 0x00 , 0x00 , 0x01 , 0x7D , 0x01 } ,
{ 0x02 , 0x03 , 0x00 , 0x04 , 0x11 , 0x05 , 0x12 , 0x21 } ,
{ 0x31 , 0x41 , 0x06 , 0x13 , 0x51 , 0x61 , 0x07 , 0x22 } ,
{ 0x71 , 0x14 , 0x32 , 0x81 , 0x91 , 0xA1 , 0x08 , 0x23 } ,
{ 0x42 , 0xB1 , 0xC1 , 0x15 , 0x52 , 0xD1 , 0xF0 , 0x24 } ,
{ 0x33 , 0x62 , 0x72 , 0x82 , 0x09 , 0x0A , 0x16 , 0x17 } ,
{ 0x18 , 0x19 , 0x1A , 0x25 , 0x26 , 0x27 , 0x28 , 0x29 } ,
{ 0x2A , 0x34 , 0x35 , 0x36 , 0x37 , 0x38 , 0x39 , 0x3A } ,
{ 0x43 , 0x44 , 0x45 , 0x46 , 0x47 , 0x48 , 0x49 , 0x4A } ,
{ 0x53 , 0x54 , 0x55 , 0x56 , 0x57 , 0x58 , 0x59 , 0x5A } ,
{ 0x63 , 0x64 , 0x65 , 0x66 , 0x67 , 0x68 , 0x69 , 0x6A } ,
{ 0x73 , 0x74 , 0x75 , 0x76 , 0x77 , 0x78 , 0x79 , 0x7A } ,
{ 0x83 , 0x84 , 0x85 , 0x86 , 0x87 , 0x88 , 0x89 , 0x8A } ,
{ 0x92 , 0x93 , 0x94 , 0x95 , 0x96 , 0x97 , 0x98 , 0x99 } ,
{ 0x9A , 0xA2 , 0xA3 , 0xA4 , 0xA5 , 0xA6 , 0xA7 , 0xA8 } ,
{ 0xA9 , 0xAA , 0xB2 , 0xB3 , 0xB4 , 0xB5 , 0xB6 , 0xB7 } ,
{ 0xB8 , 0xB9 , 0xBA , 0xC2 , 0xC3 , 0xC4 , 0xC5 , 0xC6 } ,
{ 0xC7 , 0xC8 , 0xC9 , 0xCA , 0xD2 , 0xD3 , 0xD4 , 0xD5 } ,
{ 0xD6 , 0xD7 , 0xD8 , 0xD9 , 0xDA , 0xE1 , 0xE2 , 0xE3 } ,
{ 0xE4 , 0xE5 , 0xE6 , 0xE7 , 0xE8 , 0xE9 , 0xEA , 0xF1 } ,
{ 0xF2 , 0xF3 , 0xF4 , 0xF5 , 0xF6 , 0xF7 , 0xF8 , 0xF9 } ,
{ 0xFA , 0x11 , 0x00 , 0x02 , 0x01 , 0x02 , 0x04 , 0x04 } ,
{ 0x03 , 0x04 , 0x07 , 0x05 , 0x04 , 0x04 , 0x00 , 0x01 } ,
{ 0x02 , 0x77 , 0x00 , 0x01 , 0x02 , 0x03 , 0x11 , 0x04 } ,
{ 0x05 , 0x21 , 0x31 , 0x06 , 0x12 , 0x41 , 0x51 , 0x07 } ,
{ 0x61 , 0x71 , 0x13 , 0x22 , 0x32 , 0x81 , 0x08 , 0x14 } ,
{ 0x42 , 0x91 , 0xA1 , 0xB1 , 0xC1 , 0x09 , 0x23 , 0x33 } ,
{ 0x52 , 0xF0 , 0x15 , 0x62 , 0x72 , 0xD1 , 0x0A , 0x16 } ,
{ 0x24 , 0x34 , 0xE1 , 0x25 , 0xF1 , 0x17 , 0x18 , 0x19 } ,
{ 0x1A , 0x26 , 0x27 , 0x28 , 0x29 , 0x2A , 0x35 , 0x36 } ,
{ 0x37 , 0x38 , 0x39 , 0x3A , 0x43 , 0x44 , 0x45 , 0x46 } ,
{ 0x47 , 0x48 , 0x49 , 0x4A , 0x53 , 0x54 , 0x55 , 0x56 } ,
{ 0x57 , 0x58 , 0x59 , 0x5A , 0x63 , 0x64 , 0x65 , 0x66 } ,
{ 0x67 , 0x68 , 0x69 , 0x6A , 0x73 , 0x74 , 0x75 , 0x76 } ,
{ 0x77 , 0x78 , 0x79 , 0x7A , 0x82 , 0x83 , 0x84 , 0x85 } ,
{ 0x86 , 0x87 , 0x88 , 0x89 , 0x8A , 0x92 , 0x93 , 0x94 } ,
{ 0x95 , 0x96 , 0x97 , 0x98 , 0x99 , 0x9A , 0xA2 , 0xA3 } ,
{ 0xA4 , 0xA5 , 0xA6 , 0xA7 , 0xA8 , 0xA9 , 0xAA , 0xB2 } ,
{ 0xB3 , 0xB4 , 0xB5 , 0xB6 , 0xB7 , 0xB8 , 0xB9 , 0xBA } ,
{ 0xC2 , 0xC3 , 0xC4 , 0xC5 , 0xC6 , 0xC7 , 0xC8 , 0xC9 } ,
{ 0xCA , 0xD2 , 0xD3 , 0xD4 , 0xD5 , 0xD6 , 0xD7 , 0xD8 } ,
{ 0xD9 , 0xDA , 0xE2 , 0xE3 , 0xE4 , 0xE5 , 0xE6 , 0xE7 } ,
{ 0xE8 , 0xE9 , 0xEA , 0xF2 , 0xF3 , 0xF4 , 0xF5 , 0xF6 } ,
{ 0xF7 , 0xF8 , 0xF9 , 0xFA , 0xFF , 0x20 , 0x00 , 0x1F } ,
{ 0x02 , 0x0C , 0x00 , 0x00 , 0x0A , 0x00 , 0x00 , 0x00 } ,
{ 0x00 , 0x00 , 0x11 , 0x00 , 0x11 , 0x22 , 0x00 , 0x22 } ,
{ 0x22 , 0x11 , 0x22 , 0x22 , 0x11 , 0x33 , 0x33 , 0x11 } ,
{ 0x44 , 0x66 , 0x22 , 0x55 , 0x66 , 0xFF , 0xDD , 0x00 } ,
{ 0x04 , 0x00 , 0x14 , 0xFF , 0xC0 , 0x00 , 0x11 , 0x08 } ,
{ 0x00 , 0xF0 , 0x01 , 0x40 , 0x03 , 0x00 , 0x21 , 0x00 } ,
{ 0x01 , 0x11 , 0x01 , 0x02 , 0x11 , 0x01 , 0xFF , 0xDA } ,
{ 0x00 , 0x0C , 0x03 , 0x00 , 0x00 , 0x01 , 0x11 , 0x02 } ,
{ 0x11 , 0x00 , 0x3F , 0x00 , 0xFF , 0xD9 , 0x00 , 0x00 } /* 79 */
} ;
2008-07-04 18:16:16 +04:00
static const __u8 cxjpeg_640 [ ] [ 8 ] = {
2008-06-30 22:50:11 +04:00
{ 0xff , 0xd8 , 0xff , 0xdb , 0x00 , 0x84 , 0x00 , 0x10 } , /* 1 */
{ 0x0b , 0x0c , 0x0e , 0x0c , 0x0a , 0x10 , 0x0e , 0x0d } ,
{ 0x0e , 0x12 , 0x11 , 0x10 , 0x13 , 0x18 , 0x28 , 0x1a } ,
{ 0x18 , 0x16 , 0x16 , 0x18 , 0x31 , 0x23 , 0x25 , 0x1d } ,
{ 0x28 , 0x3a , 0x33 , 0x3D , 0x3C , 0x39 , 0x33 , 0x38 } ,
{ 0x37 , 0x40 , 0x48 , 0x5C , 0x4E , 0x40 , 0x44 , 0x57 } ,
{ 0x45 , 0x37 , 0x38 , 0x50 , 0x6D , 0x51 , 0x57 , 0x5F } ,
{ 0x62 , 0x67 , 0x68 , 0x67 , 0x3E , 0x4D , 0x71 , 0x79 } ,
{ 0x70 , 0x64 , 0x78 , 0x5C , 0x65 , 0x67 , 0x63 , 0x01 } ,
{ 0x10 , 0x0B , 0x0C , 0x0E , 0x0C , 0x0A , 0x10 , 0x0E } ,
{ 0x0D , 0x0E , 0x12 , 0x11 , 0x10 , 0x13 , 0x18 , 0x28 } ,
{ 0x1A , 0x18 , 0x16 , 0x16 , 0x18 , 0x31 , 0x23 , 0x25 } ,
{ 0x1D , 0x28 , 0x3A , 0x33 , 0x3D , 0x3C , 0x39 , 0x33 } ,
{ 0x38 , 0x37 , 0x40 , 0x48 , 0x5C , 0x4E , 0x40 , 0x44 } ,
{ 0x57 , 0x45 , 0x37 , 0x38 , 0x50 , 0x6D , 0x51 , 0x57 } ,
{ 0x5F , 0x62 , 0x67 , 0x68 , 0x67 , 0x3E , 0x4D , 0x71 } ,
{ 0x79 , 0x70 , 0x64 , 0x78 , 0x5C , 0x65 , 0x67 , 0x63 } ,
{ 0xFF , 0x20 , 0x00 , 0x1F , 0x00 , 0x83 , 0x00 , 0x00 } ,
{ 0x0A , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x11 , 0x00 } ,
{ 0x11 , 0x22 , 0x00 , 0x22 , 0x22 , 0x11 , 0x22 , 0x22 } ,
{ 0x11 , 0x33 , 0x33 , 0x11 , 0x44 , 0x66 , 0x22 , 0x55 } ,
{ 0x66 , 0xFF , 0xDD , 0x00 , 0x04 , 0x00 , 0x28 , 0xFF } ,
{ 0xC0 , 0x00 , 0x11 , 0x08 , 0x01 , 0xE0 , 0x02 , 0x80 } ,
{ 0x03 , 0x00 , 0x21 , 0x00 , 0x01 , 0x11 , 0x01 , 0x02 } ,
{ 0x11 , 0x01 , 0xFF , 0xDA , 0x00 , 0x0C , 0x03 , 0x00 } ,
{ 0x00 , 0x01 , 0x11 , 0x02 , 0x11 , 0x00 , 0x3F , 0x00 } ,
{ 0xFF , 0xD9 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } /* 27 */
} ;
2008-07-04 18:16:16 +04:00
static const __u8 cxjpeg_352 [ ] [ 8 ] = {
2008-06-30 22:50:11 +04:00
{ 0xff , 0xd8 , 0xff , 0xdb , 0x00 , 0x84 , 0x00 , 0x0d } ,
{ 0x09 , 0x09 , 0x0b , 0x09 , 0x08 , 0x0D , 0x0b , 0x0a } ,
{ 0x0b , 0x0e , 0x0d , 0x0d , 0x0f , 0x13 , 0x1f , 0x14 } ,
{ 0x13 , 0x11 , 0x11 , 0x13 , 0x26 , 0x1b , 0x1d , 0x17 } ,
{ 0x1F , 0x2D , 0x28 , 0x30 , 0x2F , 0x2D , 0x28 , 0x2C } ,
{ 0x2B , 0x32 , 0x38 , 0x48 , 0x3D , 0x32 , 0x35 , 0x44 } ,
{ 0x36 , 0x2B , 0x2C , 0x3F , 0x55 , 0x3F , 0x44 , 0x4A } ,
{ 0x4D , 0x50 , 0x51 , 0x50 , 0x30 , 0x3C , 0x58 , 0x5F } ,
{ 0x58 , 0x4E , 0x5E , 0x48 , 0x4F , 0x50 , 0x4D , 0x01 } ,
{ 0x0D , 0x09 , 0x09 , 0x0B , 0x09 , 0x08 , 0x0D , 0x0B } ,
{ 0x0A , 0x0B , 0x0E , 0x0D , 0x0D , 0x0F , 0x13 , 0x1F } ,
{ 0x14 , 0x13 , 0x11 , 0x11 , 0x13 , 0x26 , 0x1B , 0x1D } ,
{ 0x17 , 0x1F , 0x2D , 0x28 , 0x30 , 0x2F , 0x2D , 0x28 } ,
{ 0x2C , 0x2B , 0x32 , 0x38 , 0x48 , 0x3D , 0x32 , 0x35 } ,
{ 0x44 , 0x36 , 0x2B , 0x2C , 0x3F , 0x55 , 0x3F , 0x44 } ,
{ 0x4A , 0x4D , 0x50 , 0x51 , 0x50 , 0x30 , 0x3C , 0x58 } ,
{ 0x5F , 0x58 , 0x4E , 0x5E , 0x48 , 0x4F , 0x50 , 0x4D } ,
{ 0xFF , 0x20 , 0x00 , 0x1F , 0x01 , 0x83 , 0x00 , 0x00 } ,
{ 0x0A , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x11 , 0x00 } ,
{ 0x11 , 0x22 , 0x00 , 0x22 , 0x22 , 0x11 , 0x22 , 0x22 } ,
{ 0x11 , 0x33 , 0x33 , 0x11 , 0x44 , 0x66 , 0x22 , 0x55 } ,
{ 0x66 , 0xFF , 0xDD , 0x00 , 0x04 , 0x00 , 0x16 , 0xFF } ,
{ 0xC0 , 0x00 , 0x11 , 0x08 , 0x01 , 0x20 , 0x01 , 0x60 } ,
{ 0x03 , 0x00 , 0x21 , 0x00 , 0x01 , 0x11 , 0x01 , 0x02 } ,
{ 0x11 , 0x01 , 0xFF , 0xDA , 0x00 , 0x0C , 0x03 , 0x00 } ,
{ 0x00 , 0x01 , 0x11 , 0x02 , 0x11 , 0x00 , 0x3F , 0x00 } ,
{ 0xFF , 0xD9 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }
} ;
2008-07-04 18:16:16 +04:00
static const __u8 cxjpeg_320 [ ] [ 8 ] = {
2008-06-30 22:50:11 +04:00
{ 0xff , 0xd8 , 0xff , 0xdb , 0x00 , 0x84 , 0x00 , 0x05 } ,
{ 0x03 , 0x04 , 0x04 , 0x04 , 0x03 , 0x05 , 0x04 , 0x04 } ,
{ 0x04 , 0x05 , 0x05 , 0x05 , 0x06 , 0x07 , 0x0c , 0x08 } ,
{ 0x07 , 0x07 , 0x07 , 0x07 , 0x0f , 0x0b , 0x0b , 0x09 } ,
{ 0x0C , 0x11 , 0x0F , 0x12 , 0x12 , 0x11 , 0x0f , 0x11 } ,
{ 0x11 , 0x13 , 0x16 , 0x1C , 0x17 , 0x13 , 0x14 , 0x1A } ,
{ 0x15 , 0x11 , 0x11 , 0x18 , 0x21 , 0x18 , 0x1A , 0x1D } ,
{ 0x1D , 0x1F , 0x1F , 0x1F , 0x13 , 0x17 , 0x22 , 0x24 } ,
{ 0x22 , 0x1E , 0x24 , 0x1C , 0x1E , 0x1F , 0x1E , 0x01 } ,
{ 0x05 , 0x03 , 0x04 , 0x04 , 0x04 , 0x03 , 0x05 , 0x04 } ,
{ 0x04 , 0x04 , 0x05 , 0x05 , 0x05 , 0x06 , 0x07 , 0x0C } ,
{ 0x08 , 0x07 , 0x07 , 0x07 , 0x07 , 0x0F , 0x0B , 0x0B } ,
{ 0x09 , 0x0C , 0x11 , 0x0F , 0x12 , 0x12 , 0x11 , 0x0F } ,
{ 0x11 , 0x11 , 0x13 , 0x16 , 0x1C , 0x17 , 0x13 , 0x14 } ,
{ 0x1A , 0x15 , 0x11 , 0x11 , 0x18 , 0x21 , 0x18 , 0x1A } ,
{ 0x1D , 0x1D , 0x1F , 0x1F , 0x1F , 0x13 , 0x17 , 0x22 } ,
{ 0x24 , 0x22 , 0x1E , 0x24 , 0x1C , 0x1E , 0x1F , 0x1E } ,
{ 0xFF , 0x20 , 0x00 , 0x1F , 0x02 , 0x0C , 0x00 , 0x00 } ,
{ 0x0A , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x11 , 0x00 } ,
{ 0x11 , 0x22 , 0x00 , 0x22 , 0x22 , 0x11 , 0x22 , 0x22 } ,
{ 0x11 , 0x33 , 0x33 , 0x11 , 0x44 , 0x66 , 0x22 , 0x55 } ,
{ 0x66 , 0xFF , 0xDD , 0x00 , 0x04 , 0x00 , 0x14 , 0xFF } ,
{ 0xC0 , 0x00 , 0x11 , 0x08 , 0x00 , 0xF0 , 0x01 , 0x40 } ,
{ 0x03 , 0x00 , 0x21 , 0x00 , 0x01 , 0x11 , 0x01 , 0x02 } ,
{ 0x11 , 0x01 , 0xFF , 0xDA , 0x00 , 0x0C , 0x03 , 0x00 } ,
{ 0x00 , 0x01 , 0x11 , 0x02 , 0x11 , 0x00 , 0x3F , 0x00 } ,
{ 0xFF , 0xD9 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } /* 27 */
} ;
2008-07-04 18:16:16 +04:00
static const __u8 cxjpeg_176 [ ] [ 8 ] = {
2008-06-30 22:50:11 +04:00
{ 0xff , 0xd8 , 0xff , 0xdb , 0x00 , 0x84 , 0x00 , 0x0d } ,
{ 0x09 , 0x09 , 0x0B , 0x09 , 0x08 , 0x0D , 0x0B , 0x0A } ,
{ 0x0B , 0x0E , 0x0D , 0x0D , 0x0F , 0x13 , 0x1F , 0x14 } ,
{ 0x13 , 0x11 , 0x11 , 0x13 , 0x26 , 0x1B , 0x1D , 0x17 } ,
{ 0x1F , 0x2D , 0x28 , 0x30 , 0x2F , 0x2D , 0x28 , 0x2C } ,
{ 0x2B , 0x32 , 0x38 , 0x48 , 0x3D , 0x32 , 0x35 , 0x44 } ,
{ 0x36 , 0x2B , 0x2C , 0x3F , 0x55 , 0x3F , 0x44 , 0x4A } ,
{ 0x4D , 0x50 , 0x51 , 0x50 , 0x30 , 0x3C , 0x58 , 0x5F } ,
{ 0x58 , 0x4E , 0x5E , 0x48 , 0x4F , 0x50 , 0x4D , 0x01 } ,
{ 0x0D , 0x09 , 0x09 , 0x0B , 0x09 , 0x08 , 0x0D , 0x0B } ,
{ 0x0A , 0x0B , 0x0E , 0x0D , 0x0D , 0x0F , 0x13 , 0x1F } ,
{ 0x14 , 0x13 , 0x11 , 0x11 , 0x13 , 0x26 , 0x1B , 0x1D } ,
{ 0x17 , 0x1F , 0x2D , 0x28 , 0x30 , 0x2F , 0x2D , 0x28 } ,
{ 0x2C , 0x2B , 0x32 , 0x38 , 0x48 , 0x3D , 0x32 , 0x35 } ,
{ 0x44 , 0x36 , 0x2B , 0x2C , 0x3F , 0x55 , 0x3F , 0x44 } ,
{ 0x4A , 0x4D , 0x50 , 0x51 , 0x50 , 0x30 , 0x3C , 0x58 } ,
{ 0x5F , 0x58 , 0x4E , 0x5E , 0x48 , 0x4F , 0x50 , 0x4D } ,
{ 0xFF , 0x20 , 0x00 , 0x1F , 0x03 , 0xA1 , 0x00 , 0x00 } ,
{ 0x0A , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x11 , 0x00 } ,
{ 0x11 , 0x22 , 0x00 , 0x22 , 0x22 , 0x11 , 0x22 , 0x22 } ,
{ 0x11 , 0x33 , 0x33 , 0x11 , 0x44 , 0x66 , 0x22 , 0x55 } ,
{ 0x66 , 0xFF , 0xDD , 0x00 , 0x04 , 0x00 , 0x0B , 0xFF } ,
{ 0xC0 , 0x00 , 0x11 , 0x08 , 0x00 , 0x90 , 0x00 , 0xB0 } ,
{ 0x03 , 0x00 , 0x21 , 0x00 , 0x01 , 0x11 , 0x01 , 0x02 } ,
{ 0x11 , 0x01 , 0xFF , 0xDA , 0x00 , 0x0C , 0x03 , 0x00 } ,
{ 0x00 , 0x01 , 0x11 , 0x02 , 0x11 , 0x00 , 0x3F , 0x00 } ,
{ 0xFF , 0xD9 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 }
} ;
2008-07-04 18:16:16 +04:00
/* 640 take with the zcx30x part */
static const __u8 cxjpeg_qtable [ ] [ 8 ] = {
2008-06-30 22:50:11 +04:00
{ 0xff , 0xd8 , 0xff , 0xdb , 0x00 , 0x84 , 0x00 , 0x08 } ,
{ 0x06 , 0x06 , 0x07 , 0x06 , 0x05 , 0x08 , 0x07 , 0x07 } ,
{ 0x07 , 0x09 , 0x09 , 0x08 , 0x0a , 0x0c , 0x14 , 0x0a } ,
{ 0x0c , 0x0b , 0x0b , 0x0c , 0x19 , 0x12 , 0x13 , 0x0f } ,
{ 0x14 , 0x1d , 0x1a , 0x1f , 0x1e , 0x1d , 0x1a , 0x1c } ,
{ 0x1c , 0x20 , 0x24 , 0x2e , 0x27 , 0x20 , 0x22 , 0x2c } ,
{ 0x23 , 0x1c , 0x1c , 0x28 , 0x37 , 0x29 , 0x2c , 0x30 } ,
{ 0x31 , 0x34 , 0x34 , 0x34 , 0x1f , 0x27 , 0x39 , 0x3d } ,
{ 0x38 , 0x32 , 0x3c , 0x2e , 0x33 , 0x34 , 0x32 , 0x01 } ,
{ 0x09 , 0x09 , 0x09 , 0x0c , 0x0b , 0x0c , 0x18 , 0x0a } ,
{ 0x0a , 0x18 , 0x32 , 0x21 , 0x1c , 0x21 , 0x32 , 0x32 } ,
{ 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 } ,
{ 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 } ,
{ 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 } ,
{ 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 } ,
{ 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 } ,
{ 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 , 0x32 } ,
{ 0xFF , 0xD9 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } /* 18 */
} ;
static void cx11646_jpegInit ( struct gspca_dev * gspca_dev )
{
int i ;
int length ;
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x00c0 , 0x01 ) ;
reg_w_val ( gspca_dev , 0x00c3 , 0x00 ) ;
reg_w_val ( gspca_dev , 0x00c0 , 0x00 ) ;
reg_r ( gspca_dev , 0x0001 , 1 ) ;
2008-06-30 22:50:11 +04:00
length = 8 ;
for ( i = 0 ; i < 79 ; i + + ) {
if ( i = = 78 )
length = 6 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0008 , cx_jpeg_init [ i ] , length ) ;
2008-06-30 22:50:11 +04:00
}
2008-07-14 16:38:29 +04:00
reg_r ( gspca_dev , 0x0002 , 1 ) ;
reg_w_val ( gspca_dev , 0x0055 , 0x14 ) ;
2008-06-30 22:50:11 +04:00
}
2008-07-04 18:16:16 +04:00
static const __u8 reg12 [ ] = { 0x0a , 0x05 , 0x07 , 0x04 , 0x19 } ;
static const __u8 regE5_8 [ ] =
{ 0x88 , 0x00 , 0xd4 , 0x01 , 0x88 , 0x01 , 0x01 , 0x01 } ;
static const __u8 regE5a [ ] = { 0x88 , 0x0a , 0x0c , 0x01 } ;
static const __u8 regE5b [ ] = { 0x88 , 0x0b , 0x12 , 0x01 } ;
static const __u8 regE5c [ ] = { 0x88 , 0x05 , 0x01 , 0x01 } ;
static const __u8 reg51 [ ] = { 0x77 , 0x03 } ;
2008-07-14 16:38:29 +04:00
# define reg70 0x03
2008-06-30 22:50:11 +04:00
static void cx11646_jpeg ( struct gspca_dev * gspca_dev )
{
int i ;
2008-07-04 18:16:16 +04:00
int length ;
__u8 Reg55 ;
int retry ;
2008-06-30 22:50:11 +04:00
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x00c0 , 0x01 ) ;
reg_w_val ( gspca_dev , 0x00c3 , 0x00 ) ;
reg_w_val ( gspca_dev , 0x00c0 , 0x00 ) ;
reg_r ( gspca_dev , 0x0001 , 1 ) ;
2008-07-04 18:16:16 +04:00
length = 8 ;
2008-07-05 18:49:20 +04:00
switch ( gspca_dev - > cam . cam_mode [ ( int ) gspca_dev - > curr_mode ] . priv ) {
2008-06-30 22:50:11 +04:00
case 0 :
for ( i = 0 ; i < 27 ; i + + ) {
if ( i = = 26 )
length = 2 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0008 , cxjpeg_640 [ i ] , length ) ;
2008-06-30 22:50:11 +04:00
}
Reg55 = 0x28 ;
break ;
case 1 :
for ( i = 0 ; i < 27 ; i + + ) {
if ( i = = 26 )
length = 2 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0008 , cxjpeg_352 [ i ] , length ) ;
2008-06-30 22:50:11 +04:00
}
Reg55 = 0x16 ;
break ;
default :
/* case 2: */
for ( i = 0 ; i < 27 ; i + + ) {
if ( i = = 26 )
length = 2 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0008 , cxjpeg_320 [ i ] , length ) ;
2008-06-30 22:50:11 +04:00
}
Reg55 = 0x14 ;
break ;
case 3 :
for ( i = 0 ; i < 27 ; i + + ) {
if ( i = = 26 )
length = 2 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0008 , cxjpeg_176 [ i ] , length ) ;
2008-06-30 22:50:11 +04:00
}
Reg55 = 0x0B ;
break ;
}
2008-07-14 16:38:29 +04:00
reg_r ( gspca_dev , 0x0002 , 1 ) ;
reg_w_val ( gspca_dev , 0x0055 , Reg55 ) ;
reg_r ( gspca_dev , 0x0002 , 1 ) ;
reg_w ( gspca_dev , 0x0010 , reg10 , 2 ) ;
reg_w_val ( gspca_dev , 0x0054 , 0x02 ) ;
reg_w_val ( gspca_dev , 0x0054 , 0x01 ) ;
reg_w_val ( gspca_dev , 0x0000 , 0x94 ) ;
reg_w_val ( gspca_dev , 0x0053 , 0xc0 ) ;
reg_w_val ( gspca_dev , 0x00fc , 0xe1 ) ;
reg_w_val ( gspca_dev , 0x0000 , 0x00 ) ;
2008-06-30 22:50:11 +04:00
/* wait for completion */
2008-07-04 18:16:16 +04:00
retry = 50 ;
2008-06-30 22:50:11 +04:00
while ( retry - - ) {
2008-07-14 16:38:29 +04:00
reg_r ( gspca_dev , 0x0002 , 1 ) ;
2008-06-30 22:50:11 +04:00
/* 0x07 until 0x00 */
2008-07-14 16:38:29 +04:00
if ( gspca_dev - > usb_buf [ 0 ] = = 0x00 )
2008-06-30 22:50:11 +04:00
break ;
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x0053 , 0x00 ) ;
2008-06-30 22:50:11 +04:00
}
if ( retry = = 0 )
PDEBUG ( D_ERR , " Damned Errors sending jpeg Table " ) ;
/* send the qtable now */
2008-07-14 16:38:29 +04:00
reg_r ( gspca_dev , 0x0001 , 1 ) ; /* -> 0x18 */
2008-06-30 22:50:11 +04:00
length = 8 ;
for ( i = 0 ; i < 18 ; i + + ) {
if ( i = = 17 )
length = 2 ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0008 , cxjpeg_qtable [ i ] , length ) ;
2008-06-30 22:50:11 +04:00
}
2008-07-14 16:38:29 +04:00
reg_r ( gspca_dev , 0x0002 , 1 ) ; /* 0x00 */
reg_r ( gspca_dev , 0x0053 , 1 ) ; /* 0x00 */
reg_w_val ( gspca_dev , 0x0054 , 0x02 ) ;
reg_w_val ( gspca_dev , 0x0054 , 0x01 ) ;
reg_w_val ( gspca_dev , 0x0000 , 0x94 ) ;
reg_w_val ( gspca_dev , 0x0053 , 0xc0 ) ;
reg_r ( gspca_dev , 0x0038 , 1 ) ; /* 0x40 */
reg_r ( gspca_dev , 0x0038 , 1 ) ; /* 0x40 */
reg_r ( gspca_dev , 0x001f , 1 ) ; /* 0x38 */
reg_w ( gspca_dev , 0x0012 , reg12 , 5 ) ;
reg_w ( gspca_dev , 0x00e5 , regE5_8 , 8 ) ;
reg_r ( gspca_dev , 0x00e8 , 8 ) ;
reg_w ( gspca_dev , 0x00e5 , regE5a , 4 ) ;
reg_r ( gspca_dev , 0x00e8 , 1 ) ; /* 0x00 */
reg_w_val ( gspca_dev , 0x009a , 0x01 ) ;
reg_w ( gspca_dev , 0x00e5 , regE5b , 4 ) ;
reg_r ( gspca_dev , 0x00e8 , 1 ) ; /* 0x00 */
reg_w ( gspca_dev , 0x00e5 , regE5c , 4 ) ;
reg_r ( gspca_dev , 0x00e8 , 1 ) ; /* 0x00 */
reg_w ( gspca_dev , 0x0051 , reg51 , 2 ) ;
reg_w ( gspca_dev , 0x0010 , reg10 , 2 ) ;
reg_w_val ( gspca_dev , 0x0070 , reg70 ) ;
2008-06-30 22:50:11 +04:00
}
static void cx11646_init1 ( struct gspca_dev * gspca_dev )
{
int i = 0 ;
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x0010 , 0x00 ) ;
reg_w_val ( gspca_dev , 0x0053 , 0x00 ) ;
reg_w_val ( gspca_dev , 0x0052 , 0x00 ) ;
reg_w_val ( gspca_dev , 0x009b , 0x2f ) ;
reg_w_val ( gspca_dev , 0x009c , 0x10 ) ;
reg_r ( gspca_dev , 0x0098 , 1 ) ;
reg_w_val ( gspca_dev , 0x0098 , 0x40 ) ;
reg_r ( gspca_dev , 0x0099 , 1 ) ;
reg_w_val ( gspca_dev , 0x0099 , 0x07 ) ;
reg_w_val ( gspca_dev , 0x0039 , 0x40 ) ;
reg_w_val ( gspca_dev , 0x003c , 0xff ) ;
reg_w_val ( gspca_dev , 0x003f , 0x1f ) ;
reg_w_val ( gspca_dev , 0x003d , 0x40 ) ;
/* reg_w_val(gspca_dev, 0x003d, 0x60); */
reg_r ( gspca_dev , 0x0099 , 1 ) ; /* ->0x07 */
2008-06-30 22:50:11 +04:00
while ( cx_sensor_init [ i ] [ 0 ] ) {
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x00e5 , cx_sensor_init [ i ] [ 0 ] ) ;
reg_r ( gspca_dev , 0x00e8 , 1 ) ; /* -> 0x00 */
2008-06-30 22:50:11 +04:00
if ( i = = 1 ) {
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x00ed , 0x01 ) ;
reg_r ( gspca_dev , 0x00ed , 1 ) ; /* -> 0x01 */
2008-06-30 22:50:11 +04:00
}
i + + ;
}
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x00c3 , 0x00 ) ;
2008-06-30 22:50:11 +04:00
}
/* 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 ;
cam = & gspca_dev - > cam ;
cam - > epaddr = 0x01 ;
cam - > cam_mode = vga_mode ;
cam - > nmodes = sizeof vga_mode / sizeof vga_mode [ 0 ] ;
2008-07-04 18:16:16 +04:00
sd - > qindex = 0 ; /* set the quantization */
2008-07-05 18:49:20 +04:00
sd - > brightness = BRIGHTNESS_DEF ;
sd - > contrast = CONTRAST_DEF ;
sd - > colors = COLOR_DEF ;
2008-06-30 22:50:11 +04:00
return 0 ;
}
/* this function is called at open time */
static int sd_open ( 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 void sd_start ( struct gspca_dev * gspca_dev )
{
cx11646_initsize ( gspca_dev ) ;
cx11646_fw ( gspca_dev ) ;
cx_sensor ( gspca_dev ) ;
cx11646_jpeg ( gspca_dev ) ;
}
static void sd_stopN ( struct gspca_dev * gspca_dev )
{
}
static void sd_stop0 ( struct gspca_dev * gspca_dev )
{
int retry = 50 ;
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x0000 , 0x00 ) ;
reg_r ( gspca_dev , 0x0002 , 1 ) ;
reg_w_val ( gspca_dev , 0x0053 , 0x00 ) ;
2008-06-30 22:50:11 +04:00
while ( retry - - ) {
2008-07-14 16:38:29 +04:00
/* reg_r(gspca_dev, 0x0002, 1);*/
reg_r ( gspca_dev , 0x0053 , 1 ) ;
if ( gspca_dev - > usb_buf [ 0 ] = = 0 )
2008-06-30 22:50:11 +04:00
break ;
}
2008-07-14 16:38:29 +04:00
reg_w_val ( gspca_dev , 0x0000 , 0x00 ) ;
reg_r ( gspca_dev , 0x0002 , 1 ) ;
reg_w_val ( gspca_dev , 0x0010 , 0x00 ) ;
reg_r ( gspca_dev , 0x0033 , 1 ) ;
reg_w_val ( gspca_dev , 0x00fc , 0xe0 ) ;
2008-06-30 22:50:11 +04:00
}
static void sd_close ( struct gspca_dev * gspca_dev )
{
}
static void sd_pkt_scan ( struct gspca_dev * gspca_dev ,
struct gspca_frame * frame , /* target */
2008-07-04 18:16:16 +04:00
__u8 * data , /* isoc packet */
2008-06-30 22:50:11 +04:00
int len ) /* iso packet length */
{
if ( data [ 0 ] = = 0xff & & data [ 1 ] = = 0xd8 ) {
/* start of frame */
frame = gspca_frame_add ( gspca_dev , LAST_PACKET , frame ,
data , 0 ) ;
/* put the JPEG header in the new frame */
jpeg_put_header ( gspca_dev , frame ,
( ( struct sd * ) gspca_dev ) - > qindex ,
0x22 ) ;
data + = 2 ;
len - = 2 ;
}
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 ;
__u8 regE5cbx [ ] = { 0x88 , 0x00 , 0xd4 , 0x01 , 0x88 , 0x01 , 0x01 , 0x01 } ;
2008-07-04 18:16:16 +04:00
__u8 reg51c [ 2 ] ;
2008-06-30 22:50:11 +04:00
__u8 bright ;
__u8 colors ;
bright = sd - > brightness ;
regE5cbx [ 2 ] = bright ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x00e5 , regE5cbx , 8 ) ;
reg_r ( gspca_dev , 0x00e8 , 8 ) ;
reg_w ( gspca_dev , 0x00e5 , regE5c , 4 ) ;
reg_r ( gspca_dev , 0x00e8 , 1 ) ; /* 0x00 */
2008-06-30 22:50:11 +04:00
2008-07-04 18:16:16 +04:00
colors = sd - > colors ;
reg51c [ 0 ] = 0x77 ;
reg51c [ 1 ] = colors ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0051 , reg51c , 2 ) ;
reg_w ( gspca_dev , 0x0010 , reg10 , 2 ) ;
reg_w_val ( gspca_dev , 0x0070 , reg70 ) ;
2008-06-30 22:50:11 +04:00
}
static void setcontrast ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
__u8 regE5acx [ ] = { 0x88 , 0x0a , 0x0c , 0x01 } ; /* seem MSB */
2008-07-04 18:16:16 +04:00
/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
__u8 reg51c [ 2 ] ;
2008-06-30 22:50:11 +04:00
regE5acx [ 2 ] = sd - > contrast ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x00e5 , regE5acx , 4 ) ;
reg_r ( gspca_dev , 0x00e8 , 1 ) ; /* 0x00 */
2008-07-04 18:16:16 +04:00
reg51c [ 0 ] = 0x77 ;
reg51c [ 1 ] = sd - > colors ;
2008-07-14 16:38:29 +04:00
reg_w ( gspca_dev , 0x0051 , reg51c , 2 ) ;
reg_w ( gspca_dev , 0x0010 , reg10 , 2 ) ;
reg_w_val ( gspca_dev , 0x0070 , reg70 ) ;
2008-06-30 22:50:11 +04:00
}
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_setcontrast ( struct gspca_dev * gspca_dev , __s32 val )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
sd - > contrast = val ;
if ( gspca_dev - > streaming )
setcontrast ( gspca_dev ) ;
return 0 ;
}
static int sd_getcontrast ( struct gspca_dev * gspca_dev , __s32 * val )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
* val = sd - > contrast ;
return 0 ;
}
static int sd_setcolors ( struct gspca_dev * gspca_dev , __s32 val )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
sd - > colors = val ;
if ( gspca_dev - > streaming ) {
setbrightness ( gspca_dev ) ;
setcontrast ( gspca_dev ) ;
}
return 0 ;
}
static int sd_getcolors ( struct gspca_dev * gspca_dev , __s32 * val )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
* val = sd - > colors ;
return 0 ;
}
/* sub-driver description */
static struct sd_desc sd_desc = {
. name = MODULE_NAME ,
. ctrls = sd_ctrls ,
. nctrls = ARRAY_SIZE ( sd_ctrls ) ,
. config = sd_config ,
. open = sd_open ,
. start = sd_start ,
. stopN = sd_stopN ,
. stop0 = sd_stop0 ,
. close = sd_close ,
. pkt_scan = sd_pkt_scan ,
} ;
/* -- module initialisation -- */
static __devinitdata struct usb_device_id device_table [ ] = {
2008-07-25 15:53:03 +04:00
{ USB_DEVICE ( 0x0572 , 0x0041 ) } ,
2008-06-30 22:50:11 +04:00
{ }
} ;
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 ,
} ;
/* -- module insert / remove -- */
static int __init sd_mod_init ( void )
{
if ( usb_register ( & sd_driver ) < 0 )
return - 1 ;
2008-07-22 12:35:10 +04:00
PDEBUG ( D_PROBE , " registered " ) ;
2008-06-30 22:50:11 +04:00
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 ) ;