2008-06-30 15:50:11 -03:00
/*
2009-11-02 10:00:48 -03:00
* Sonix sn9c102p sn9c105 sn9c120 ( jpeg ) subdriver
2009-11-07 06:10:08 -03:00
*
2011-08-10 05:54:34 -03:00
* Copyright ( C ) 2009 - 2011 Jean - François Moine < http : //moinejf.free.fr>
2009-11-02 10:00:48 -03:00
* Copyright ( C ) 2005 Michel Xhaard mxhaard @ magic . fr
2008-06-30 15:50:11 -03:00
*
* 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
*/
2011-08-21 19:56:57 -03:00
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
2008-06-30 15:50:11 -03:00
# define MODULE_NAME "sonixj"
2010-01-31 12:54:29 -03:00
# include <linux/input.h>
2008-06-30 15:50:11 -03:00
# include "gspca.h"
# include "jpeg.h"
2010-04-02 06:59:13 -03:00
MODULE_AUTHOR ( " Jean-François Moine <http://moinejf.free.fr> " ) ;
2008-06-30 15:50:11 -03:00
MODULE_DESCRIPTION ( " GSPCA/SONIX JPEG USB Camera Driver " ) ;
MODULE_LICENSE ( " GPL " ) ;
2010-10-02 04:35:25 -03:00
/* controls */
enum e_ctrl {
BRIGHTNESS ,
CONTRAST ,
COLORS ,
BLUE ,
RED ,
GAMMA ,
2012-02-27 06:57:04 -03:00
EXPOSURE ,
2010-10-02 04:35:25 -03:00
AUTOGAIN ,
2012-02-27 06:57:04 -03:00
GAIN ,
2010-10-19 03:33:47 -03:00
HFLIP ,
2010-10-02 04:35:25 -03:00
VFLIP ,
SHARPNESS ,
2011-01-13 06:39:11 -03:00
ILLUM ,
2010-10-02 04:35:25 -03:00
FREQ ,
NCTRLS /* number of controls */
} ;
2008-06-30 15:50:11 -03:00
/* specific webcam descriptor */
struct sd {
struct gspca_dev gspca_dev ; /* !! must be the first item */
2010-10-02 04:35:25 -03:00
struct gspca_ctrl ctrls [ NCTRLS ] ;
2008-08-03 07:52:53 -03:00
atomic_t avg_lum ;
2009-01-19 07:37:33 -03:00
u32 exposure ;
2011-02-10 07:38:58 -03:00
struct work_struct work ;
struct workqueue_struct * work_thread ;
u32 pktsz ; /* (used by pkt_scan) */
u16 npkt ;
2011-05-23 08:09:18 -03:00
s8 nchg ;
2011-02-10 07:15:24 -03:00
s8 short_mark ;
2009-03-03 05:33:41 -03:00
u8 quality ; /* image quality */
2011-02-10 07:38:58 -03:00
# define QUALITY_MIN 25
# define QUALITY_MAX 90
# define QUALITY_DEF 70
2009-03-03 05:33:41 -03:00
2010-12-14 16:17:40 -03:00
u8 reg01 ;
u8 reg17 ;
2009-03-03 05:33:41 -03:00
u8 reg18 ;
2010-12-14 16:15:37 -03:00
u8 flags ;
2008-06-30 15:50:11 -03:00
2009-01-19 07:37:33 -03:00
s8 ag_cnt ;
2008-06-30 15:50:11 -03:00
# define AG_CNT_START 13
2009-01-19 07:37:33 -03:00
u8 bridge ;
2008-07-15 05:36:30 -03:00
# define BRIDGE_SN9C102P 0
# define BRIDGE_SN9C105 1
# define BRIDGE_SN9C110 2
# define BRIDGE_SN9C120 3
2009-01-19 07:37:33 -03:00
u8 sensor ; /* Type of image sensor chip */
2010-07-26 06:39:40 -03:00
u8 i2c_addr ;
u8 jpeg_hdr [ JPEG_HDR_SZ ] ;
} ;
enum sensors {
2010-03-17 15:25:32 -03:00
SENSOR_ADCM1700 ,
2010-03-18 05:15:30 -03:00
SENSOR_GC0307 ,
2010-03-17 15:25:32 -03:00
SENSOR_HV7131R ,
SENSOR_MI0360 ,
2010-10-01 07:51:24 -03:00
SENSOR_MI0360B ,
2010-03-17 15:25:32 -03:00
SENSOR_MO4000 ,
SENSOR_MT9V111 ,
SENSOR_OM6802 ,
SENSOR_OV7630 ,
SENSOR_OV7648 ,
SENSOR_OV7660 ,
SENSOR_PO1030 ,
2010-03-18 05:15:30 -03:00
SENSOR_PO2030N ,
2010-04-25 14:45:43 -03:00
SENSOR_SOI768 ,
2010-03-17 15:25:32 -03:00
SENSOR_SP80708 ,
2008-06-30 15:50:11 -03:00
} ;
2011-02-10 07:38:58 -03:00
static void qual_upd ( struct work_struct * work ) ;
2010-12-14 16:16:16 -03:00
/* device flags */
2011-01-13 06:39:11 -03:00
# define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */
# define F_ILLUM 0x02 /* presence of illuminator */
2010-12-14 16:16:16 -03:00
2010-12-14 16:16:58 -03:00
/* sn9c1xx definitions */
/* register 0x01 */
# define S_PWR_DN 0x01 /* sensor power down */
# define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */
# define V_TX_EN 0x04 /* video transfer enable */
# define LED 0x08 /* output to pin LED */
# define SCL_SEL_OD 0x20 /* open-drain mode */
# define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */
/* register 0x17 */
# define MCK_SIZE_MASK 0x1f /* sensor master clock */
# define SEN_CLK_EN 0x20 /* enable sensor clock */
# define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
2008-06-30 15:50:11 -03:00
/* V4L2 controls supported by the driver */
2010-10-02 04:35:25 -03:00
static void setbrightness ( struct gspca_dev * gspca_dev ) ;
static void setcontrast ( struct gspca_dev * gspca_dev ) ;
static void setcolors ( struct gspca_dev * gspca_dev ) ;
static void setredblue ( struct gspca_dev * gspca_dev ) ;
static void setgamma ( struct gspca_dev * gspca_dev ) ;
2012-02-27 06:57:04 -03:00
static void setexposure ( struct gspca_dev * gspca_dev ) ;
static int sd_setautogain ( struct gspca_dev * gspca_dev , __s32 val ) ;
static void setgain ( struct gspca_dev * gspca_dev ) ;
2010-10-19 03:33:47 -03:00
static void sethvflip ( struct gspca_dev * gspca_dev ) ;
2010-10-02 04:35:25 -03:00
static void setsharpness ( struct gspca_dev * gspca_dev ) ;
2011-01-13 06:39:11 -03:00
static void setillum ( struct gspca_dev * gspca_dev ) ;
2010-10-02 04:35:25 -03:00
static void setfreq ( struct gspca_dev * gspca_dev ) ;
static const struct ctrl sd_ctrls [ NCTRLS ] = {
2011-08-10 05:54:34 -03:00
[ BRIGHTNESS ] = {
2008-06-30 15:50:11 -03:00
{
. id = V4L2_CID_BRIGHTNESS ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Brightness " ,
. minimum = 0 ,
2010-10-02 04:35:25 -03:00
. maximum = 0xff ,
2008-06-30 15:50:11 -03:00
. step = 1 ,
2010-10-02 04:35:25 -03:00
. default_value = 0x80 ,
2008-06-30 15:50:11 -03:00
} ,
2010-10-02 04:35:25 -03:00
. set_control = setbrightness
2008-06-30 15:50:11 -03:00
} ,
2010-10-02 04:35:25 -03:00
[ CONTRAST ] = {
2008-06-30 15:50:11 -03:00
{
. id = V4L2_CID_CONTRAST ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Contrast " ,
. minimum = 0 ,
2008-09-03 16:47:59 -03:00
# define CONTRAST_MAX 127
. maximum = CONTRAST_MAX ,
2008-06-30 15:50:11 -03:00
. step = 1 ,
2011-08-10 05:13:45 -03:00
. default_value = 20 ,
2008-06-30 15:50:11 -03:00
} ,
2010-10-02 04:35:25 -03:00
. set_control = setcontrast
2008-06-30 15:50:11 -03:00
} ,
2010-10-02 04:35:25 -03:00
[ COLORS ] = {
2008-06-30 15:50:11 -03:00
{
. id = V4L2_CID_SATURATION ,
. type = V4L2_CTRL_TYPE_INTEGER ,
2009-06-18 14:31:36 -03:00
. name = " Saturation " ,
2008-06-30 15:50:11 -03:00
. minimum = 0 ,
2008-11-26 04:46:15 -03:00
. maximum = 40 ,
2008-06-30 15:50:11 -03:00
. step = 1 ,
2010-10-02 04:35:25 -03:00
# define COLORS_DEF 25
. default_value = COLORS_DEF ,
2008-06-30 15:50:11 -03:00
} ,
2010-10-02 04:35:25 -03:00
. set_control = setcolors
2008-06-30 15:50:11 -03:00
} ,
2010-10-02 04:35:25 -03:00
[ BLUE ] = {
2008-11-26 04:46:15 -03:00
{
. id = V4L2_CID_BLUE_BALANCE ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Blue Balance " ,
. minimum = 24 ,
. maximum = 40 ,
. step = 1 ,
2010-10-02 04:35:25 -03:00
. default_value = 32 ,
2008-11-26 04:46:15 -03:00
} ,
2010-10-02 04:35:25 -03:00
. set_control = setredblue
2008-11-26 04:46:15 -03:00
} ,
2010-10-02 04:35:25 -03:00
[ RED ] = {
2008-11-26 04:46:15 -03:00
{
. id = V4L2_CID_RED_BALANCE ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Red Balance " ,
. minimum = 24 ,
. maximum = 40 ,
. step = 1 ,
2010-10-02 04:35:25 -03:00
. default_value = 32 ,
2008-11-26 04:46:15 -03:00
} ,
2010-10-02 04:35:25 -03:00
. set_control = setredblue
2008-11-26 04:46:15 -03:00
} ,
2010-10-02 04:35:25 -03:00
[ GAMMA ] = {
2009-01-15 08:01:32 -03:00
{
. id = V4L2_CID_GAMMA ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Gamma " ,
. minimum = 0 ,
. maximum = 40 ,
. step = 1 ,
# define GAMMA_DEF 20
. default_value = GAMMA_DEF ,
} ,
2010-10-02 04:35:25 -03:00
. set_control = setgamma
2009-01-15 08:01:32 -03:00
} ,
2012-02-27 06:57:04 -03:00
[ EXPOSURE ] = {
{
. id = V4L2_CID_EXPOSURE ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Exposure " ,
. minimum = 500 ,
. maximum = 1500 ,
. step = 1 ,
. default_value = 1024
} ,
. set_control = setexposure
} ,
2010-10-02 04:35:25 -03:00
[ AUTOGAIN ] = {
2008-06-30 15:50:11 -03:00
{
. id = V4L2_CID_AUTOGAIN ,
. type = V4L2_CTRL_TYPE_BOOLEAN ,
. name = " Auto Gain " ,
. minimum = 0 ,
. maximum = 1 ,
. step = 1 ,
2010-10-02 04:35:25 -03:00
. default_value = 1
2008-06-30 15:50:11 -03:00
} ,
2012-02-27 06:57:04 -03:00
. set = sd_setautogain ,
} ,
[ GAIN ] = {
{
. id = V4L2_CID_GAIN ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Gain " ,
. minimum = 4 ,
. maximum = 49 ,
. step = 1 ,
. default_value = 15
} ,
. set_control = setgain
2008-06-30 15:50:11 -03:00
} ,
2010-10-19 03:33:47 -03:00
[ HFLIP ] = {
{
. id = V4L2_CID_HFLIP ,
. type = V4L2_CTRL_TYPE_BOOLEAN ,
. name = " Mirror " ,
. minimum = 0 ,
. maximum = 1 ,
. step = 1 ,
. default_value = 0 ,
} ,
. set_control = sethvflip
} ,
2010-10-02 04:35:25 -03:00
[ VFLIP ] = {
2008-09-08 04:57:26 -03:00
{
. id = V4L2_CID_VFLIP ,
. type = V4L2_CTRL_TYPE_BOOLEAN ,
. name = " Vflip " ,
. minimum = 0 ,
. maximum = 1 ,
. step = 1 ,
2010-10-02 04:35:25 -03:00
. default_value = 0 ,
2008-09-08 04:57:26 -03:00
} ,
2010-10-19 03:33:47 -03:00
. set_control = sethvflip
2008-09-08 04:57:26 -03:00
} ,
2010-10-02 04:35:25 -03:00
[ SHARPNESS ] = {
2009-12-30 04:53:07 -03:00
{
. id = V4L2_CID_SHARPNESS ,
. type = V4L2_CTRL_TYPE_INTEGER ,
. name = " Sharpness " ,
. minimum = 0 ,
. maximum = 255 ,
. step = 1 ,
2010-10-02 04:35:25 -03:00
. default_value = 90 ,
2009-12-30 04:53:07 -03:00
} ,
2010-10-02 04:35:25 -03:00
. set_control = setsharpness
2009-12-30 04:53:07 -03:00
} ,
2011-01-13 06:39:11 -03:00
[ ILLUM ] = {
2008-10-17 07:48:24 -03:00
{
2011-01-13 06:39:11 -03:00
. id = V4L2_CID_ILLUMINATORS_1 ,
2008-10-17 07:48:24 -03:00
. type = V4L2_CTRL_TYPE_BOOLEAN ,
2011-01-13 06:39:11 -03:00
. name = " Illuminator / infrared " ,
2008-10-17 07:48:24 -03:00
. minimum = 0 ,
. maximum = 1 ,
. step = 1 ,
2010-10-02 04:35:25 -03:00
. default_value = 0 ,
2008-10-17 07:48:24 -03:00
} ,
2011-01-13 06:39:11 -03:00
. set_control = setillum
2008-10-17 07:48:24 -03:00
} ,
2009-06-18 07:35:36 -03:00
/* ov7630/ov7648/ov7660 only */
2010-10-02 04:35:25 -03:00
[ FREQ ] = {
2009-06-18 07:35:36 -03:00
{
. id = V4L2_CID_POWER_LINE_FREQUENCY ,
. type = V4L2_CTRL_TYPE_MENU ,
. name = " Light frequency filter " ,
. minimum = 0 ,
. maximum = 2 , /* 0: 0, 1: 50Hz, 2:60Hz */
. step = 1 ,
2010-10-02 04:35:25 -03:00
. default_value = 1 ,
2009-06-18 07:35:36 -03:00
} ,
2010-10-02 04:35:25 -03:00
. set_control = setfreq
2009-06-18 07:35:36 -03:00
} ,
2008-06-30 15:50:11 -03:00
} ;
2008-12-05 06:18:37 -03:00
/* table of the disabled controls */
2010-03-17 15:25:32 -03:00
static const __u32 ctrl_dis [ ] = {
2012-02-27 06:57:04 -03:00
[ SENSOR_ADCM1700 ] = ( 1 < < EXPOSURE ) |
( 1 < < AUTOGAIN ) |
( 1 < < GAIN ) |
2010-10-19 03:33:47 -03:00
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) |
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_GC0307 ] = ( 1 < < EXPOSURE ) |
( 1 < < GAIN ) |
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) |
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_HV7131R ] = ( 1 < < EXPOSURE ) |
( 1 < < GAIN ) |
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_MI0360 ] = ( 1 < < EXPOSURE ) |
( 1 < < GAIN ) |
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) |
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_MI0360B ] = ( 1 < < EXPOSURE ) |
( 1 < < GAIN ) |
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) |
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_MO4000 ] = ( 1 < < EXPOSURE ) |
( 1 < < GAIN ) |
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) |
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_MT9V111 ] = ( 1 < < EXPOSURE ) |
( 1 < < GAIN ) |
( 1 < < HFLIP ) |
2010-10-19 03:33:47 -03:00
( 1 < < VFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_OM6802 ] = ( 1 < < EXPOSURE ) |
( 1 < < GAIN ) |
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) |
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_OV7630 ] = ( 1 < < EXPOSURE ) |
( 1 < < GAIN ) |
( 1 < < HFLIP ) ,
2010-10-02 04:35:25 -03:00
2012-02-27 06:57:04 -03:00
[ SENSOR_OV7648 ] = ( 1 < < EXPOSURE ) |
( 1 < < GAIN ) |
( 1 < < HFLIP ) ,
2010-10-02 04:35:25 -03:00
2012-02-27 06:57:04 -03:00
[ SENSOR_OV7660 ] = ( 1 < < EXPOSURE ) |
( 1 < < AUTOGAIN ) |
( 1 < < GAIN ) |
2010-10-19 03:33:47 -03:00
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_PO1030 ] = ( 1 < < EXPOSURE ) |
( 1 < < AUTOGAIN ) |
( 1 < < GAIN ) |
2010-10-19 03:33:47 -03:00
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) |
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_PO2030N ] = ( 1 < < FREQ ) ,
2010-10-19 04:29:10 -03:00
2012-02-27 06:57:04 -03:00
[ SENSOR_SOI768 ] = ( 1 < < EXPOSURE ) |
( 1 < < AUTOGAIN ) |
( 1 < < GAIN ) |
2010-10-19 03:33:47 -03:00
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) |
( 1 < < FREQ ) ,
2012-02-27 06:57:04 -03:00
[ SENSOR_SP80708 ] = ( 1 < < EXPOSURE ) |
( 1 < < AUTOGAIN ) |
( 1 < < GAIN ) |
2010-10-19 03:33:47 -03:00
( 1 < < HFLIP ) |
2010-10-02 04:35:25 -03:00
( 1 < < VFLIP ) |
( 1 < < FREQ ) ,
2008-12-05 06:18:37 -03:00
} ;
2009-12-20 12:31:28 -03:00
static const struct v4l2_pix_format cif_mode [ ] = {
{ 352 , 288 , V4L2_PIX_FMT_JPEG , V4L2_FIELD_NONE ,
. bytesperline = 352 ,
. sizeimage = 352 * 288 * 4 / 8 + 590 ,
. colorspace = V4L2_COLORSPACE_JPEG ,
. priv = 0 } ,
} ;
2008-12-29 07:49:41 -03:00
static const struct v4l2_pix_format vga_mode [ ] = {
2008-07-05 11:49:20 -03:00
{ 160 , 120 , V4L2_PIX_FMT_JPEG , V4L2_FIELD_NONE ,
. bytesperline = 160 ,
2008-09-03 16:48:09 -03:00
. sizeimage = 160 * 120 * 4 / 8 + 590 ,
2008-07-05 11:49:20 -03:00
. colorspace = V4L2_COLORSPACE_JPEG ,
. priv = 2 } ,
{ 320 , 240 , V4L2_PIX_FMT_JPEG , V4L2_FIELD_NONE ,
. bytesperline = 320 ,
. sizeimage = 320 * 240 * 3 / 8 + 590 ,
. colorspace = V4L2_COLORSPACE_JPEG ,
. priv = 1 } ,
{ 640 , 480 , V4L2_PIX_FMT_JPEG , V4L2_FIELD_NONE ,
. bytesperline = 640 ,
2009-06-18 06:03:20 -03:00
/* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
. sizeimage = 640 * 480 * 3 / 4 + 590 ,
2008-07-05 11:49:20 -03:00
. colorspace = V4L2_COLORSPACE_JPEG ,
. priv = 0 } ,
2008-06-30 15:50:11 -03:00
} ;
2009-12-20 12:31:28 -03:00
static const u8 sn_adcm1700 [ 0x1c ] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
2009-12-30 04:53:07 -03:00
0x00 , 0x43 , 0x60 , 0x00 , 0x1a , 0x00 , 0x00 , 0x00 ,
2009-12-20 12:31:28 -03:00
/* reg8 reg9 rega regb regc regd rege regf */
0x80 , 0x51 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x05 , 0x01 , 0x05 , 0x16 , 0x12 , 0x42 ,
/* reg18 reg19 reg1a reg1b */
0x06 , 0x00 , 0x00 , 0x00
} ;
2010-03-18 05:15:30 -03:00
static const u8 sn_gc0307 [ 0x1c ] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00 , 0x61 , 0x62 , 0x00 , 0x1a , 0x00 , 0x00 , 0x00 ,
/* reg8 reg9 rega regb regc regd rege regf */
0x80 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x03 , 0x01 , 0x08 , 0x28 , 0x1e , 0x02 ,
/* reg18 reg19 reg1a reg1b */
0x06 , 0x00 , 0x00 , 0x00
} ;
2009-01-13 05:55:40 -03:00
static const u8 sn_hv7131 [ 0x1c ] = {
2008-07-29 14:14:04 -03:00
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
2010-07-14 06:33:51 -03:00
0x00 , 0x03 , 0x60 , 0x00 , 0x1a , 0x20 , 0x20 , 0x20 ,
2008-07-29 14:14:04 -03:00
/* reg8 reg9 rega regb regc regd rege regf */
2009-11-02 09:56:59 -03:00
0x81 , 0x11 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2008-07-29 14:14:04 -03:00
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x00 , 0x01 , 0x03 , 0x28 , 0x1e , 0x41 ,
2009-01-13 05:55:40 -03:00
/* reg18 reg19 reg1a reg1b */
0x0a , 0x00 , 0x00 , 0x00
2008-06-30 15:50:11 -03:00
} ;
2009-01-13 05:55:40 -03:00
static const u8 sn_mi0360 [ 0x1c ] = {
2008-07-29 14:14:04 -03:00
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
2011-02-10 13:18:58 -03:00
0x00 , 0x63 , 0x40 , 0x00 , 0x1a , 0x20 , 0x20 , 0x20 ,
2008-07-29 14:14:04 -03:00
/* reg8 reg9 rega regb regc regd rege regf */
2009-11-02 09:56:59 -03:00
0x81 , 0x5d , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2008-07-29 14:14:04 -03:00
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x00 , 0x02 , 0x0a , 0x28 , 0x1e , 0x61 ,
2009-01-13 05:55:40 -03:00
/* reg18 reg19 reg1a reg1b */
0x06 , 0x00 , 0x00 , 0x00
2008-06-30 15:50:11 -03:00
} ;
2010-10-01 07:51:24 -03:00
static const u8 sn_mi0360b [ 0x1c ] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00 , 0x61 , 0x40 , 0x00 , 0x1a , 0x00 , 0x00 , 0x00 ,
/* reg8 reg9 rega regb regc regd rege regf */
0x81 , 0x5d , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x00 , 0x02 , 0x0a , 0x28 , 0x1e , 0x40 ,
/* reg18 reg19 reg1a reg1b */
0x06 , 0x00 , 0x00 , 0x00
} ;
2009-01-13 05:55:40 -03:00
static const u8 sn_mo4000 [ 0x1c ] = {
2008-07-29 14:14:04 -03:00
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
2009-01-13 05:55:40 -03:00
0x00 , 0x23 , 0x60 , 0x00 , 0x1a , 0x00 , 0x20 , 0x18 ,
2008-07-29 14:14:04 -03:00
/* reg8 reg9 rega regb regc regd rege regf */
0x81 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x0b , 0x0f , 0x14 , 0x28 , 0x1e , 0x40 ,
2009-01-13 05:55:40 -03:00
/* reg18 reg19 reg1a reg1b */
0x08 , 0x00 , 0x00 , 0x00
2008-06-30 15:50:11 -03:00
} ;
2009-01-29 04:59:45 -03:00
static const u8 sn_mt9v111 [ 0x1c ] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00 , 0x61 , 0x40 , 0x00 , 0x1a , 0x20 , 0x20 , 0x20 ,
/* reg8 reg9 rega regb regc regd rege regf */
2009-11-02 09:56:59 -03:00
0x81 , 0x5c , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2009-01-29 04:59:45 -03:00
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x00 , 0x02 , 0x1c , 0x28 , 0x1e , 0x40 ,
/* reg18 reg19 reg1a reg1b */
0x06 , 0x00 , 0x00 , 0x00
} ;
2009-01-13 05:55:40 -03:00
static const u8 sn_om6802 [ 0x1c ] = {
2008-09-03 16:47:23 -03:00
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
2009-10-17 07:21:29 -03:00
0x00 , 0x23 , 0x72 , 0x00 , 0x1a , 0x20 , 0x20 , 0x19 ,
2008-09-03 16:47:23 -03:00
/* reg8 reg9 rega regb regc regd rege regf */
0x80 , 0x34 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x51 , 0x01 , 0x00 , 0x28 , 0x1e , 0x40 ,
2009-01-13 05:55:40 -03:00
/* reg18 reg19 reg1a reg1b */
0x05 , 0x00 , 0x00 , 0x00
2008-09-03 16:47:23 -03:00
} ;
2009-01-13 05:55:40 -03:00
static const u8 sn_ov7630 [ 0x1c ] = {
2008-09-03 16:47:34 -03:00
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
2010-04-25 14:33:31 -03:00
0x00 , 0x21 , 0x40 , 0x00 , 0x1a , 0x00 , 0x00 , 0x00 ,
2008-09-03 16:47:34 -03:00
/* reg8 reg9 rega regb regc regd rege regf */
2009-11-02 09:56:59 -03:00
0x81 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2008-09-03 16:47:34 -03:00
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x04 , 0x01 , 0x0a , 0x28 , 0x1e , 0xc2 ,
2009-01-13 05:55:40 -03:00
/* reg18 reg19 reg1a reg1b */
0x0b , 0x00 , 0x00 , 0x00
2008-09-03 16:47:34 -03:00
} ;
2009-01-13 05:55:40 -03:00
static const u8 sn_ov7648 [ 0x1c ] = {
2008-07-29 14:14:04 -03:00
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
2008-11-11 08:42:56 -03:00
0x00 , 0x63 , 0x40 , 0x00 , 0x1a , 0x20 , 0x20 , 0x20 ,
2008-07-29 14:14:04 -03:00
/* reg8 reg9 rega regb regc regd rege regf */
2009-11-02 09:56:59 -03:00
0x81 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2008-07-29 14:14:04 -03:00
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
2008-11-11 08:42:56 -03:00
0x03 , 0x00 , 0x00 , 0x01 , 0x00 , 0x28 , 0x1e , 0x00 ,
2009-01-13 05:55:40 -03:00
/* reg18 reg19 reg1a reg1b */
0x0b , 0x00 , 0x00 , 0x00
2008-06-30 15:50:11 -03:00
} ;
2009-01-13 05:55:40 -03:00
static const u8 sn_ov7660 [ 0x1c ] = {
2008-07-29 14:14:04 -03:00
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
2009-04-26 14:46:12 -03:00
0x00 , 0x61 , 0x40 , 0x00 , 0x1a , 0x00 , 0x00 , 0x00 ,
2008-07-29 14:14:04 -03:00
/* reg8 reg9 rega regb regc regd rege regf */
2009-04-26 14:46:12 -03:00
0x81 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2008-07-29 14:14:04 -03:00
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x01 , 0x01 , 0x08 , 0x28 , 0x1e , 0x20 ,
2009-01-13 05:55:40 -03:00
/* reg18 reg19 reg1a reg1b */
0x07 , 0x00 , 0x00 , 0x00
2008-06-30 15:50:11 -03:00
} ;
2009-11-23 06:46:35 -03:00
static const u8 sn_po1030 [ 0x1c ] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00 , 0x21 , 0x62 , 0x00 , 0x1a , 0x20 , 0x20 , 0x20 ,
/* reg8 reg9 rega regb regc regd rege regf */
0x81 , 0x6e , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x00 , 0x06 , 0x06 , 0x28 , 0x1e , 0x00 ,
/* reg18 reg19 reg1a reg1b */
0x07 , 0x00 , 0x00 , 0x00
} ;
2010-03-18 05:15:30 -03:00
static const u8 sn_po2030n [ 0x1c ] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00 , 0x63 , 0x40 , 0x00 , 0x1a , 0x00 , 0x00 , 0x00 ,
/* reg8 reg9 rega regb regc regd rege regf */
0x81 , 0x6e , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x00 , 0x01 , 0x14 , 0x28 , 0x1e , 0x00 ,
/* reg18 reg19 reg1a reg1b */
0x07 , 0x00 , 0x00 , 0x00
} ;
2010-04-25 14:45:43 -03:00
static const u8 sn_soi768 [ 0x1c ] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00 , 0x21 , 0x40 , 0x00 , 0x1a , 0x00 , 0x00 , 0x00 ,
/* reg8 reg9 rega regb regc regd rege regf */
0x81 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x00 , 0x01 , 0x08 , 0x28 , 0x1e , 0x00 ,
/* reg18 reg19 reg1a reg1b */
0x07 , 0x00 , 0x00 , 0x00
} ;
2009-02-01 13:59:42 -03:00
static const u8 sn_sp80708 [ 0x1c ] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00 , 0x63 , 0x60 , 0x00 , 0x1a , 0x20 , 0x20 , 0x20 ,
/* reg8 reg9 rega regb regc regd rege regf */
2009-11-02 09:56:59 -03:00
0x81 , 0x18 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 ,
2009-02-01 13:59:42 -03:00
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03 , 0x00 , 0x00 , 0x03 , 0x04 , 0x28 , 0x1e , 0x00 ,
/* reg18 reg19 reg1a reg1b */
0x07 , 0x00 , 0x00 , 0x00
} ;
2008-06-30 15:50:11 -03:00
/* sequence specific to the sensors - !! index = SENSOR_xxx */
2009-01-13 05:55:40 -03:00
static const u8 * sn_tb [ ] = {
2010-03-17 15:25:32 -03:00
[ SENSOR_ADCM1700 ] = sn_adcm1700 ,
2010-03-18 05:15:30 -03:00
[ SENSOR_GC0307 ] = sn_gc0307 ,
2010-03-17 15:25:32 -03:00
[ SENSOR_HV7131R ] = sn_hv7131 ,
[ SENSOR_MI0360 ] = sn_mi0360 ,
2010-10-01 07:51:24 -03:00
[ SENSOR_MI0360B ] = sn_mi0360b ,
2010-03-17 15:25:32 -03:00
[ SENSOR_MO4000 ] = sn_mo4000 ,
[ SENSOR_MT9V111 ] = sn_mt9v111 ,
[ SENSOR_OM6802 ] = sn_om6802 ,
[ SENSOR_OV7630 ] = sn_ov7630 ,
[ SENSOR_OV7648 ] = sn_ov7648 ,
[ SENSOR_OV7660 ] = sn_ov7660 ,
[ SENSOR_PO1030 ] = sn_po1030 ,
2010-03-18 05:15:30 -03:00
[ SENSOR_PO2030N ] = sn_po2030n ,
2010-04-25 14:45:43 -03:00
[ SENSOR_SOI768 ] = sn_soi768 ,
[ SENSOR_SP80708 ] = sn_sp80708 ,
2008-06-30 15:50:11 -03:00
} ;
2009-02-01 14:20:07 -03:00
/* default gamma table */
2009-01-19 07:37:33 -03:00
static const u8 gamma_def [ 17 ] = {
2008-06-30 15:50:11 -03:00
0x00 , 0x2d , 0x46 , 0x5a , 0x6c , 0x7c , 0x8b , 0x99 ,
0xa6 , 0xb2 , 0xbf , 0xca , 0xd5 , 0xe0 , 0xeb , 0xf5 , 0xff
} ;
2009-12-20 12:31:28 -03:00
/* gamma for sensor ADCM1700 */
static const u8 gamma_spec_0 [ 17 ] = {
0x0f , 0x39 , 0x5a , 0x74 , 0x86 , 0x95 , 0xa6 , 0xb4 ,
0xbd , 0xc4 , 0xcc , 0xd4 , 0xd5 , 0xde , 0xe4 , 0xed , 0xf5
} ;
2009-02-01 14:20:07 -03:00
/* gamma for sensors HV7131R and MT9V111 */
static const u8 gamma_spec_1 [ 17 ] = {
0x08 , 0x3a , 0x52 , 0x65 , 0x75 , 0x83 , 0x91 , 0x9d ,
0xa9 , 0xb4 , 0xbe , 0xc8 , 0xd2 , 0xdb , 0xe4 , 0xed , 0xf5
} ;
2010-03-18 05:15:30 -03:00
/* gamma for sensor GC0307 */
2009-02-01 14:20:07 -03:00
static const u8 gamma_spec_2 [ 17 ] = {
2010-03-18 05:15:30 -03:00
0x14 , 0x37 , 0x50 , 0x6a , 0x7c , 0x8d , 0x9d , 0xab ,
0xb5 , 0xbf , 0xc2 , 0xcb , 0xd1 , 0xd6 , 0xdb , 0xe1 , 0xeb
} ;
/* gamma for sensor SP80708 */
static const u8 gamma_spec_3 [ 17 ] = {
2009-02-01 14:20:07 -03:00
0x0a , 0x2d , 0x4e , 0x68 , 0x7d , 0x8f , 0x9f , 0xab ,
0xb7 , 0xc2 , 0xcc , 0xd3 , 0xd8 , 0xde , 0xe2 , 0xe5 , 0xe6
} ;
2009-01-15 08:01:32 -03:00
2008-10-04 14:17:02 -03:00
/* color matrix and offsets */
2009-01-19 07:37:33 -03:00
static const u8 reg84 [ ] = {
2008-10-04 14:17:02 -03:00
0x14 , 0x00 , 0x27 , 0x00 , 0x07 , 0x00 , /* YR YG YB gains */
0xe8 , 0x0f , 0xda , 0x0f , 0x40 , 0x00 , /* UR UG UB */
0x3e , 0x00 , 0xcd , 0x0f , 0xf7 , 0x0f , /* VR VG VB */
0x00 , 0x00 , 0x00 /* YUV offsets */
2008-06-30 15:50:11 -03:00
} ;
2010-10-18 07:00:48 -03:00
# define DELAY 0xdd
2009-12-20 12:31:28 -03:00
static const u8 adcm1700_sensor_init [ ] [ 8 ] = {
{ 0xa0 , 0x51 , 0xfe , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-12-30 04:53:07 -03:00
{ 0xb0 , 0x51 , 0x04 , 0x08 , 0x00 , 0x00 , 0x00 , 0x10 } , /* reset */
2010-10-18 07:00:48 -03:00
{ DELAY , 0x80 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ,
2009-12-20 12:31:28 -03:00
{ 0xb0 , 0x51 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0x80 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ,
2009-12-20 12:31:28 -03:00
{ 0xb0 , 0x51 , 0x0c , 0xe0 , 0x2e , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x10 , 0x02 , 0x02 , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x14 , 0x0e , 0x0e , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x1c , 0x00 , 0x80 , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x20 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0xff , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ,
2009-12-20 12:31:28 -03:00
{ 0xb0 , 0x51 , 0x04 , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0xff , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } ,
2009-12-20 12:31:28 -03:00
{ 0xb0 , 0x51 , 0x04 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x51 , 0xfe , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x14 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x32 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ }
} ;
static const u8 adcm1700_sensor_param1 [ ] [ 8 ] = {
2009-12-30 04:53:07 -03:00
{ 0xb0 , 0x51 , 0x26 , 0xf9 , 0x01 , 0x00 , 0x00 , 0x10 } , /* exposure? */
2009-12-20 12:31:28 -03:00
{ 0xd0 , 0x51 , 0x1e , 0x8e , 0x8e , 0x8e , 0x8e , 0x10 } ,
{ 0xa0 , 0x51 , 0xfe , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x51 , 0xfe , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x32 , 0x00 , 0x72 , 0x00 , 0x00 , 0x10 } ,
2009-12-30 04:53:07 -03:00
{ 0xd0 , 0x51 , 0x1e , 0xbe , 0xd7 , 0xe8 , 0xbe , 0x10 } , /* exposure? */
2009-12-20 12:31:28 -03:00
2009-12-30 04:53:07 -03:00
{ 0xa0 , 0x51 , 0xfe , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x00 , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x51 , 0xfe , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x51 , 0x32 , 0x00 , 0xa2 , 0x00 , 0x00 , 0x10 } ,
2009-12-20 12:31:28 -03:00
{ }
} ;
2010-03-18 05:15:30 -03:00
static const u8 gc0307_sensor_init [ ] [ 8 ] = {
{ 0xa0 , 0x21 , 0x43 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x44 , 0xa2 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x01 , 0x6a , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x02 , 0x70 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x1c , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x1d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x11 , 0x05 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x05 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x06 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x07 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x08 , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x09 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x0a , 0xe8 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x0b , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x0c , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x0d , 0x22 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x0e , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x0f , 0xb2 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x12 , 0x70 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0x0a , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /*delay 10ms*/
2010-03-18 05:15:30 -03:00
{ 0xa0 , 0x21 , 0x13 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x15 , 0xb8 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x16 , 0x13 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x17 , 0x52 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x18 , 0x50 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x1e , 0x0d , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x1f , 0x32 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x61 , 0x90 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x63 , 0x70 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x65 , 0x98 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x67 , 0x90 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x04 , 0x96 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x45 , 0x27 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x47 , 0x2c , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x43 , 0x47 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x44 , 0xd8 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ }
} ;
static const u8 gc0307_sensor_param1 [ ] [ 8 ] = {
{ 0xa0 , 0x21 , 0x68 , 0x13 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd0 , 0x21 , 0x61 , 0x80 , 0x00 , 0x80 , 0x00 , 0x10 } ,
{ 0xc0 , 0x21 , 0x65 , 0x80 , 0x00 , 0x80 , 0x00 , 0x10 } ,
{ 0xc0 , 0x21 , 0x63 , 0xa0 , 0x00 , 0xa6 , 0x00 , 0x10 } ,
/*param3*/
{ 0xa0 , 0x21 , 0x01 , 0x6e , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x21 , 0x02 , 0x88 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ }
} ;
2009-01-19 07:37:33 -03:00
static const u8 hv7131r_sensor_init [ ] [ 8 ] = {
2009-01-13 05:55:40 -03:00
{ 0xc1 , 0x11 , 0x01 , 0x08 , 0x01 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x11 , 0x34 , 0x17 , 0x7f , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x11 , 0x40 , 0xff , 0x7f , 0x7f , 0x7f , 0x10 } ,
/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
{ 0xd1 , 0x11 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x11 , 0x14 , 0x01 , 0xe2 , 0x02 , 0x82 , 0x10 } ,
/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
{ 0xa1 , 0x11 , 0x01 , 0x08 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x01 , 0x08 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xc1 , 0x11 , 0x25 , 0x00 , 0x61 , 0xa8 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x30 , 0x22 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xc1 , 0x11 , 0x31 , 0x20 , 0x2e , 0x20 , 0x00 , 0x10 } ,
{ 0xc1 , 0x11 , 0x25 , 0x00 , 0xc3 , 0x50 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x30 , 0x07 , 0x00 , 0x00 , 0x00 , 0x10 } , /* gain14 */
{ 0xc1 , 0x11 , 0x31 , 0x10 , 0x10 , 0x10 , 0x00 , 0x10 } , /* r g b 101a10 */
{ 0xa1 , 0x11 , 0x01 , 0x08 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x20 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-10-22 06:27:14 -03:00
{ 0xa1 , 0x11 , 0x21 , 0xd0 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-01-13 05:55:40 -03:00
{ 0xa1 , 0x11 , 0x22 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x23 , 0x09 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x01 , 0x08 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x20 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x21 , 0xd0 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x22 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x11 , 0x23 , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-11-02 09:10:25 -03:00
{ 0xa1 , 0x11 , 0x01 , 0x18 , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* set sensor clock */
2008-07-04 11:16:16 -03:00
{ }
2008-06-30 15:50:11 -03:00
} ;
2009-01-19 07:37:33 -03:00
static const u8 mi0360_sensor_init [ ] [ 8 ] = {
2009-01-13 05:55:40 -03:00
{ 0xb1 , 0x5d , 0x07 , 0x00 , 0x02 , 0x00 , 0x00 , 0x10 } ,
2009-01-19 07:37:33 -03:00
{ 0xb1 , 0x5d , 0x0d , 0x00 , 0x01 , 0x00 , 0x00 , 0x10 } ,
2009-01-29 04:59:45 -03:00
{ 0xb1 , 0x5d , 0x0d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-01-13 05:55:40 -03:00
{ 0xd1 , 0x5d , 0x01 , 0x00 , 0x08 , 0x00 , 0x16 , 0x10 } ,
{ 0xd1 , 0x5d , 0x03 , 0x01 , 0xe2 , 0x02 , 0x82 , 0x10 } ,
{ 0xd1 , 0x5d , 0x05 , 0x00 , 0x09 , 0x00 , 0x53 , 0x10 } ,
{ 0xb1 , 0x5d , 0x0d , 0x00 , 0x02 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x0a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x0c , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x0e , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x12 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x16 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x18 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x1a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x1c , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x32 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x20 , 0x91 , 0x01 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x22 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x24 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x26 , 0x00 , 0x00 , 0x00 , 0x24 , 0x10 } ,
2011-08-10 05:54:34 -03:00
{ 0xd1 , 0x5d , 0x2f , 0xf7 , 0xb0 , 0x00 , 0x04 , 0x10 } ,
2009-01-13 05:55:40 -03:00
{ 0xd1 , 0x5d , 0x31 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x33 , 0x00 , 0x00 , 0x01 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x3d , 0x06 , 0x8f , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x40 , 0x01 , 0xe0 , 0x00 , 0xd1 , 0x10 } ,
{ 0xb1 , 0x5d , 0x44 , 0x00 , 0x82 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x58 , 0x00 , 0x78 , 0x00 , 0x43 , 0x10 } ,
{ 0xd1 , 0x5d , 0x5a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x5c , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x5e , 0x00 , 0x00 , 0xa3 , 0x1d , 0x10 } ,
{ 0xb1 , 0x5d , 0x62 , 0x04 , 0x11 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x20 , 0x91 , 0x01 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x20 , 0x11 , 0x01 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x09 , 0x00 , 0x64 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x2b , 0x00 , 0xa0 , 0x00 , 0xb0 , 0x10 } ,
{ 0xd1 , 0x5d , 0x2d , 0x00 , 0xa0 , 0x00 , 0xa0 , 0x10 } ,
{ 0xb1 , 0x5d , 0x0a , 0x00 , 0x02 , 0x00 , 0x00 , 0x10 } , /* sensor clck ?2 */
{ 0xb1 , 0x5d , 0x06 , 0x00 , 0x30 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x05 , 0x00 , 0x0a , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x09 , 0x02 , 0x35 , 0x00 , 0x00 , 0x10 } , /* exposure 2 */
{ 0xd1 , 0x5d , 0x2b , 0x00 , 0xb9 , 0x00 , 0xe3 , 0x10 } ,
{ 0xd1 , 0x5d , 0x2d , 0x00 , 0x5f , 0x00 , 0xb9 , 0x10 } , /* 42 */
/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
{ 0xb1 , 0x5d , 0x07 , 0x00 , 0x03 , 0x00 , 0x00 , 0x10 } , /* update */
{ 0xb1 , 0x5d , 0x07 , 0x00 , 0x02 , 0x00 , 0x00 , 0x10 } , /* sensor on */
2008-07-04 11:16:16 -03:00
{ }
2008-06-30 15:50:11 -03:00
} ;
2010-10-01 07:51:24 -03:00
static const u8 mi0360b_sensor_init [ ] [ 8 ] = {
{ 0xb1 , 0x5d , 0x07 , 0x00 , 0x02 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x0d , 0x00 , 0x01 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /*delay 20ms*/
2010-10-01 07:51:24 -03:00
{ 0xb1 , 0x5d , 0x0d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /*delay 20ms*/
2010-10-01 07:51:24 -03:00
{ 0xd1 , 0x5d , 0x01 , 0x00 , 0x08 , 0x00 , 0x16 , 0x10 } ,
{ 0xd1 , 0x5d , 0x03 , 0x01 , 0xe2 , 0x02 , 0x82 , 0x10 } ,
{ 0xd1 , 0x5d , 0x05 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x0d , 0x00 , 0x02 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x0a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x0c , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x0e , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x12 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x16 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x18 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x1a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x1c , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x32 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x20 , 0x11 , 0x01 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x22 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x24 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x26 , 0x00 , 0x00 , 0x00 , 0x24 , 0x10 } ,
{ 0xd1 , 0x5d , 0x2f , 0xf7 , 0xb0 , 0x00 , 0x04 , 0x10 } ,
{ 0xd1 , 0x5d , 0x31 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x33 , 0x00 , 0x00 , 0x01 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x3d , 0x06 , 0x8f , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x40 , 0x01 , 0xe0 , 0x00 , 0xd1 , 0x10 } ,
{ 0xb1 , 0x5d , 0x44 , 0x00 , 0x82 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x58 , 0x00 , 0x78 , 0x00 , 0x43 , 0x10 } ,
{ 0xd1 , 0x5d , 0x5a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x5c , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x5e , 0x00 , 0x00 , 0xa3 , 0x1d , 0x10 } ,
{ 0xb1 , 0x5d , 0x62 , 0x04 , 0x11 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x20 , 0x11 , 0x01 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x20 , 0x11 , 0x01 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x09 , 0x00 , 0x64 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x5d , 0x2b , 0x00 , 0x33 , 0x00 , 0xa0 , 0x10 } ,
{ 0xd1 , 0x5d , 0x2d , 0x00 , 0xa0 , 0x00 , 0x33 , 0x10 } ,
{ }
} ;
static const u8 mi0360b_sensor_param1 [ ] [ 8 ] = {
{ 0xb1 , 0x5d , 0x0a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x06 , 0x00 , 0x53 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x05 , 0x00 , 0x09 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5d , 0x09 , 0x02 , 0x35 , 0x00 , 0x00 , 0x10 } , /* exposure 2 */
{ 0xd1 , 0x5d , 0x2b , 0x00 , 0xd1 , 0x01 , 0xc9 , 0x10 } ,
{ 0xd1 , 0x5d , 0x2d , 0x00 , 0xed , 0x00 , 0xd1 , 0x10 } ,
{ 0xb1 , 0x5d , 0x07 , 0x00 , 0x03 , 0x00 , 0x00 , 0x10 } , /* update */
{ 0xb1 , 0x5d , 0x07 , 0x00 , 0x02 , 0x00 , 0x00 , 0x10 } , /* sensor on */
{ }
} ;
2009-01-19 07:37:33 -03:00
static const u8 mo4000_sensor_init [ ] [ 8 ] = {
2008-06-30 15:50:11 -03:00
{ 0xa1 , 0x21 , 0x01 , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x02 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x04 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x05 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x05 , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x06 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x06 , 0x81 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x0e , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x11 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x11 , 0x20 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x11 , 0x30 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x11 , 0x38 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x11 , 0x38 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x12 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x0f , 0x20 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x10 , 0x20 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x11 , 0x38 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2008-07-04 11:16:16 -03:00
{ }
2008-06-30 15:50:11 -03:00
} ;
2009-01-29 04:59:45 -03:00
static const u8 mt9v111_sensor_init [ ] [ 8 ] = {
{ 0xb1 , 0x5c , 0x0d , 0x00 , 0x01 , 0x00 , 0x00 , 0x10 } , /* reset? */
2010-10-18 07:00:48 -03:00
{ DELAY , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 20ms */
2009-01-29 04:59:45 -03:00
{ 0xb1 , 0x5c , 0x0d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x5c , 0x01 , 0x00 , 0x01 , 0x00 , 0x00 , 0x10 } , /* IFP select */
{ 0xb1 , 0x5c , 0x08 , 0x04 , 0x80 , 0x00 , 0x00 , 0x10 } , /* output fmt ctrl */
{ 0xb1 , 0x5c , 0x06 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* op mode ctrl */
{ 0xb1 , 0x5c , 0x01 , 0x00 , 0x04 , 0x00 , 0x00 , 0x10 } , /* sensor select */
{ 0xb1 , 0x5c , 0x08 , 0x00 , 0x08 , 0x00 , 0x00 , 0x10 } , /* row start */
{ 0xb1 , 0x5c , 0x02 , 0x00 , 0x16 , 0x00 , 0x00 , 0x10 } , /* col start */
{ 0xb1 , 0x5c , 0x03 , 0x01 , 0xe7 , 0x00 , 0x00 , 0x10 } , /* window height */
{ 0xb1 , 0x5c , 0x04 , 0x02 , 0x87 , 0x00 , 0x00 , 0x10 } , /* window width */
{ 0xb1 , 0x5c , 0x07 , 0x30 , 0x02 , 0x00 , 0x00 , 0x10 } , /* output ctrl */
{ 0xb1 , 0x5c , 0x0c , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* shutter delay */
{ 0xb1 , 0x5c , 0x12 , 0x00 , 0xb0 , 0x00 , 0x00 , 0x10 } , /* zoom col start */
{ 0xb1 , 0x5c , 0x13 , 0x00 , 0x7c , 0x00 , 0x00 , 0x10 } , /* zoom row start */
{ 0xb1 , 0x5c , 0x1e , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* digital zoom */
{ 0xb1 , 0x5c , 0x20 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* read mode */
{ 0xb1 , 0x5c , 0x20 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-11-02 09:54:04 -03:00
{ }
} ;
static const u8 mt9v111_sensor_param1 [ ] [ 8 ] = {
2011-02-10 07:44:59 -03:00
{ 0xd1 , 0x5c , 0x2b , 0x00 , 0x33 , 0x00 , 0xad , 0x10 } , /* G1 and B gains */
{ 0xd1 , 0x5c , 0x2d , 0x00 , 0xad , 0x00 , 0x33 , 0x10 } , /* R and G2 gains */
{ 0xb1 , 0x5c , 0x06 , 0x00 , 0x40 , 0x00 , 0x00 , 0x10 } , /* vert blanking */
{ 0xb1 , 0x5c , 0x05 , 0x00 , 0x09 , 0x00 , 0x00 , 0x10 } , /* horiz blanking */
2009-01-29 04:59:45 -03:00
{ 0xb1 , 0x5c , 0x35 , 0x01 , 0xc0 , 0x00 , 0x00 , 0x10 } , /* global gain */
{ }
} ;
2009-11-02 09:54:04 -03:00
static const u8 om6802_init0 [ 2 ] [ 8 ] = {
/*fixme: variable*/
{ 0xa0 , 0x34 , 0x29 , 0x0e , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x34 , 0x23 , 0xb0 , 0x00 , 0x00 , 0x00 , 0x10 } ,
} ;
2009-01-19 07:37:33 -03:00
static const u8 om6802_sensor_init [ ] [ 8 ] = {
2009-11-02 09:54:04 -03:00
{ 0xa0 , 0x34 , 0xdf , 0x6d , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* factory mode */
2008-09-03 16:47:23 -03:00
{ 0xa0 , 0x34 , 0xdd , 0x18 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-11-07 06:10:08 -03:00
/* output raw RGB */
2009-11-02 09:54:04 -03:00
{ 0xa0 , 0x34 , 0x5a , 0xc0 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2008-09-03 16:47:23 -03:00
/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
{ 0xa0 , 0x34 , 0xf0 , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-11-07 06:10:08 -03:00
/* auto-exposure speed (0) / white balance mode (auto RGB) */
2008-09-03 16:47:23 -03:00
/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
* set color mode */
/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
* max AGC value in AE */
/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
* preset AGC */
/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
* preset brightness */
/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
* preset contrast */
/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
* preset gamma */
{ 0xa0 , 0x34 , 0xe9 , 0x0f , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-11-07 06:10:08 -03:00
/* luminance mode (0x4f -> AutoExpo on) */
2008-09-03 16:47:23 -03:00
{ 0xa0 , 0x34 , 0xe4 , 0xff , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* preset shutter */
/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
* auto frame rate */
/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
2009-11-02 09:54:04 -03:00
{ 0xa0 , 0x34 , 0x5d , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ }
} ;
static const u8 om6802_sensor_param1 [ ] [ 8 ] = {
{ 0xa0 , 0x34 , 0x71 , 0x84 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x34 , 0x72 , 0x05 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x34 , 0x68 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa0 , 0x34 , 0x69 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2008-09-03 16:47:23 -03:00
{ }
} ;
2009-01-19 07:37:33 -03:00
static const u8 ov7630_sensor_init [ ] [ 8 ] = {
2008-09-03 16:47:34 -03:00
{ 0xa1 , 0x21 , 0x76 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x12 , 0xc8 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 20ms */
2008-09-03 16:47:34 -03:00
{ 0xa1 , 0x21 , 0x12 , 0x48 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x12 , 0xc8 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 20ms */
2008-09-03 16:47:34 -03:00
{ 0xa1 , 0x21 , 0x12 , 0x48 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2008-09-03 16:47:59 -03:00
/* win: i2c_r from 00 to 80 */
2008-09-03 16:47:34 -03:00
{ 0xd1 , 0x21 , 0x03 , 0x80 , 0x10 , 0x20 , 0x80 , 0x10 } ,
{ 0xb1 , 0x21 , 0x0c , 0x20 , 0x20 , 0x00 , 0x00 , 0x10 } ,
2009-06-18 05:14:42 -03:00
/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
{ 0xd1 , 0x21 , 0x11 , 0x01 , 0x48 , 0xc3 , 0x00 , 0x10 } ,
2008-09-03 16:47:34 -03:00
{ 0xb1 , 0x21 , 0x15 , 0x80 , 0x03 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x17 , 0x1b , 0xbd , 0x05 , 0xf6 , 0x10 } ,
{ 0xa1 , 0x21 , 0x1b , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x1f , 0x00 , 0x80 , 0x80 , 0x80 , 0x10 } ,
{ 0xd1 , 0x21 , 0x23 , 0xde , 0x10 , 0x8a , 0xa0 , 0x10 } ,
{ 0xc1 , 0x21 , 0x27 , 0xca , 0xa2 , 0x74 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x2a , 0x88 , 0x00 , 0x88 , 0x01 , 0x10 } ,
{ 0xc1 , 0x21 , 0x2e , 0x80 , 0x00 , 0x18 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x21 , 0x08 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x22 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x2e , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x21 , 0x32 , 0xc2 , 0x08 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x21 , 0x4c , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x60 , 0x05 , 0x40 , 0x12 , 0x57 , 0x10 } ,
{ 0xa1 , 0x21 , 0x64 , 0x73 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x65 , 0x00 , 0x55 , 0x01 , 0xac , 0x10 } ,
{ 0xa1 , 0x21 , 0x69 , 0x38 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x6f , 0x1f , 0x01 , 0x00 , 0x10 , 0x10 } ,
{ 0xd1 , 0x21 , 0x73 , 0x50 , 0x20 , 0x02 , 0x01 , 0x10 } ,
{ 0xd1 , 0x21 , 0x77 , 0xf3 , 0x90 , 0x98 , 0x98 , 0x10 } ,
{ 0xc1 , 0x21 , 0x7b , 0x00 , 0x4c , 0xf7 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x17 , 0x1b , 0xbd , 0x05 , 0xf6 , 0x10 } ,
{ 0xa1 , 0x21 , 0x1b , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-04-25 14:23:39 -03:00
{ }
} ;
static const u8 ov7630_sensor_param1 [ ] [ 8 ] = {
2008-09-03 16:47:34 -03:00
{ 0xa1 , 0x21 , 0x12 , 0x48 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x12 , 0x48 , 0x00 , 0x00 , 0x00 , 0x10 } ,
/*fixme: + 0x12, 0x04*/
2008-09-08 04:57:26 -03:00
/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
* set by setvflip */
2008-09-03 16:47:34 -03:00
{ 0xa1 , 0x21 , 0x10 , 0x32 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x21 , 0x01 , 0x80 , 0x80 , 0x00 , 0x00 , 0x10 } ,
2008-09-03 16:47:59 -03:00
/* */
2009-06-18 07:35:36 -03:00
/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
2008-09-03 16:47:59 -03:00
/* */
2008-09-03 16:47:34 -03:00
{ 0xa1 , 0x21 , 0x10 , 0x83 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2008-09-03 17:12:18 -03:00
/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
2008-09-03 16:47:34 -03:00
{ }
} ;
2008-11-11 08:42:56 -03:00
2009-01-19 07:37:33 -03:00
static const u8 ov7648_sensor_init [ ] [ 8 ] = {
2008-11-11 08:42:56 -03:00
{ 0xa1 , 0x21 , 0x76 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x12 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } , /* reset */
2010-10-18 07:00:48 -03:00
{ DELAY , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 20ms */
2008-11-11 08:42:56 -03:00
{ 0xa1 , 0x21 , 0x12 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x03 , 0xa4 , 0x30 , 0x88 , 0x00 , 0x10 } ,
{ 0xb1 , 0x21 , 0x11 , 0x80 , 0x08 , 0x00 , 0x00 , 0x10 } ,
{ 0xc1 , 0x21 , 0x13 , 0xa0 , 0x04 , 0x84 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x17 , 0x1a , 0x02 , 0xba , 0xf4 , 0x10 } ,
{ 0xa1 , 0x21 , 0x1b , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x1f , 0x41 , 0xc0 , 0x80 , 0x80 , 0x10 } ,
{ 0xd1 , 0x21 , 0x23 , 0xde , 0xa0 , 0x80 , 0x32 , 0x10 } ,
{ 0xd1 , 0x21 , 0x27 , 0xfe , 0xa0 , 0x00 , 0x91 , 0x10 } ,
{ 0xd1 , 0x21 , 0x2b , 0x00 , 0x88 , 0x85 , 0x80 , 0x10 } ,
{ 0xc1 , 0x21 , 0x2f , 0x9c , 0x00 , 0xc4 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x60 , 0xa6 , 0x60 , 0x88 , 0x12 , 0x10 } ,
{ 0xd1 , 0x21 , 0x64 , 0x88 , 0x00 , 0x00 , 0x94 , 0x10 } ,
{ 0xd1 , 0x21 , 0x68 , 0x7a , 0x0c , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x6c , 0x11 , 0x33 , 0x22 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x70 , 0x11 , 0x00 , 0x10 , 0x50 , 0x10 } ,
{ 0xd1 , 0x21 , 0x74 , 0x20 , 0x06 , 0x00 , 0xb5 , 0x10 } ,
{ 0xd1 , 0x21 , 0x78 , 0x8a , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x21 , 0x7c , 0x00 , 0x43 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x21 , 0x21 , 0x86 , 0x00 , 0xde , 0xa0 , 0x10 } ,
/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
2009-06-18 07:35:36 -03:00
/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
2009-11-02 09:54:04 -03:00
{ }
} ;
static const u8 ov7648_sensor_param1 [ ] [ 8 ] = {
2008-11-11 08:42:56 -03:00
/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
2009-02-05 15:12:24 -03:00
/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
* set by setvflip */
2008-11-11 08:42:56 -03:00
{ 0xa1 , 0x21 , 0x19 , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x10 , 0x32 , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
/*...*/
{ 0xa1 , 0x21 , 0x11 , 0x81 , 0x00 , 0x00 , 0x00 , 0x10 } , /* CLKRC */
/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
{ }
} ;
2009-01-19 07:37:33 -03:00
static const u8 ov7660_sensor_init [ ] [ 8 ] = {
2008-06-30 15:50:11 -03:00
{ 0xa1 , 0x21 , 0x12 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } , /* reset SCCB */
2010-10-18 07:00:48 -03:00
{ DELAY , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 20ms */
2008-06-30 15:50:11 -03:00
{ 0xa1 , 0x21 , 0x12 , 0x05 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2008-07-28 06:41:51 -03:00
/* Outformat = rawRGB */
2008-06-30 15:50:11 -03:00
{ 0xa1 , 0x21 , 0x13 , 0xb8 , 0x00 , 0x00 , 0x00 , 0x10 } , /* init COM8 */
2009-07-08 06:33:44 -03:00
{ 0xd1 , 0x21 , 0x00 , 0x01 , 0x74 , 0x92 , 0x00 , 0x10 } ,
2008-06-30 15:50:11 -03:00
/* GAIN BLUE RED VREF */
{ 0xd1 , 0x21 , 0x04 , 0x00 , 0x7d , 0x62 , 0x00 , 0x10 } ,
/* COM 1 BAVE GEAVE AECHH */
{ 0xb1 , 0x21 , 0x08 , 0x83 , 0x01 , 0x00 , 0x00 , 0x10 } , /* RAVE COM2 */
{ 0xd1 , 0x21 , 0x0c , 0x00 , 0x08 , 0x04 , 0x4f , 0x10 } , /* COM 3 4 5 6 */
2009-08-25 06:14:54 -03:00
{ 0xd1 , 0x21 , 0x10 , 0x7f , 0x40 , 0x05 , 0xff , 0x10 } ,
2008-06-30 15:50:11 -03:00
/* AECH CLKRC COM7 COM8 */
{ 0xc1 , 0x21 , 0x14 , 0x2c , 0x00 , 0x02 , 0x00 , 0x10 } , /* COM9 COM10 */
{ 0xd1 , 0x21 , 0x17 , 0x10 , 0x60 , 0x02 , 0x7b , 0x10 } ,
/* HSTART HSTOP VSTRT VSTOP */
{ 0xa1 , 0x21 , 0x1b , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } , /* PSHFT */
{ 0xb1 , 0x21 , 0x1e , 0x01 , 0x0e , 0x00 , 0x00 , 0x10 } , /* MVFP LAEC */
{ 0xd1 , 0x21 , 0x20 , 0x07 , 0x07 , 0x07 , 0x07 , 0x10 } ,
/* BOS GBOS GROS ROS (BGGR offset) */
2008-07-28 06:41:51 -03:00
/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
{ 0xd1 , 0x21 , 0x24 , 0x78 , 0x68 , 0xd4 , 0x80 , 0x10 } ,
2008-06-30 15:50:11 -03:00
/* AEW AEB VPT BBIAS */
{ 0xd1 , 0x21 , 0x28 , 0x80 , 0x30 , 0x00 , 0x00 , 0x10 } ,
/* GbBIAS RSVD EXHCH EXHCL */
{ 0xd1 , 0x21 , 0x2c , 0x80 , 0x00 , 0x00 , 0x62 , 0x10 } ,
/* RBIAS ADVFL ASDVFH YAVE */
{ 0xc1 , 0x21 , 0x30 , 0x08 , 0x30 , 0xb4 , 0x00 , 0x10 } ,
/* HSYST HSYEN HREF */
{ 0xd1 , 0x21 , 0x33 , 0x00 , 0x07 , 0x84 , 0x00 , 0x10 } , /* reserved */
{ 0xd1 , 0x21 , 0x37 , 0x0c , 0x02 , 0x43 , 0x00 , 0x10 } ,
/* ADC ACOM OFON TSLB */
{ 0xd1 , 0x21 , 0x3b , 0x02 , 0x6c , 0x19 , 0x0e , 0x10 } ,
/* COM11 COM12 COM13 COM14 */
{ 0xd1 , 0x21 , 0x3f , 0x41 , 0xc1 , 0x22 , 0x08 , 0x10 } ,
/* EDGE COM15 COM16 COM17 */
{ 0xd1 , 0x21 , 0x43 , 0xf0 , 0x10 , 0x78 , 0xa8 , 0x10 } , /* reserved */
{ 0xd1 , 0x21 , 0x47 , 0x60 , 0x80 , 0x00 , 0x00 , 0x10 } , /* reserved */
{ 0xd1 , 0x21 , 0x4b , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* reserved */
{ 0xd1 , 0x21 , 0x4f , 0x46 , 0x36 , 0x0f , 0x17 , 0x10 } , /* MTX 1 2 3 4 */
{ 0xd1 , 0x21 , 0x53 , 0x7f , 0x96 , 0x40 , 0x40 , 0x10 } , /* MTX 5 6 7 8 */
{ 0xb1 , 0x21 , 0x57 , 0x40 , 0x0f , 0x00 , 0x00 , 0x10 } , /* MTX9 MTXS */
{ 0xd1 , 0x21 , 0x59 , 0xba , 0x9a , 0x22 , 0xb9 , 0x10 } , /* reserved */
{ 0xd1 , 0x21 , 0x5d , 0x9b , 0x10 , 0xf0 , 0x05 , 0x10 } , /* reserved */
{ 0xa1 , 0x21 , 0x61 , 0x60 , 0x00 , 0x00 , 0x00 , 0x10 } , /* reserved */
{ 0xd1 , 0x21 , 0x62 , 0x00 , 0x00 , 0x50 , 0x30 , 0x10 } ,
/* LCC1 LCC2 LCC3 LCC4 */
{ 0xa1 , 0x21 , 0x66 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* LCC5 */
2008-07-28 06:41:51 -03:00
{ 0xd1 , 0x21 , 0x67 , 0x80 , 0x7a , 0x90 , 0x80 , 0x10 } , /* MANU */
2008-06-30 15:50:11 -03:00
{ 0xa1 , 0x21 , 0x6b , 0x0a , 0x00 , 0x00 , 0x00 , 0x10 } ,
2008-07-28 06:41:51 -03:00
/* band gap reference [0:3] DBLV */
2008-06-30 15:50:11 -03:00
{ 0xd1 , 0x21 , 0x6c , 0x30 , 0x48 , 0x80 , 0x74 , 0x10 } , /* gamma curve */
{ 0xd1 , 0x21 , 0x70 , 0x64 , 0x60 , 0x5c , 0x58 , 0x10 } , /* gamma curve */
{ 0xd1 , 0x21 , 0x74 , 0x54 , 0x4c , 0x40 , 0x38 , 0x10 } , /* gamma curve */
{ 0xd1 , 0x21 , 0x78 , 0x34 , 0x30 , 0x2f , 0x2b , 0x10 } , /* gamma curve */
{ 0xd1 , 0x21 , 0x7c , 0x03 , 0x07 , 0x17 , 0x34 , 0x10 } , /* gamma curve */
{ 0xd1 , 0x21 , 0x80 , 0x41 , 0x4d , 0x58 , 0x63 , 0x10 } , /* gamma curve */
{ 0xd1 , 0x21 , 0x84 , 0x6e , 0x77 , 0x87 , 0x95 , 0x10 } , /* gamma curve */
{ 0xc1 , 0x21 , 0x88 , 0xaf , 0xc7 , 0xdf , 0x00 , 0x10 } , /* gamma curve */
{ 0xc1 , 0x21 , 0x8b , 0x99 , 0x99 , 0xcf , 0x00 , 0x10 } , /* reserved */
2008-07-28 06:41:51 -03:00
{ 0xb1 , 0x21 , 0x92 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* DM_LNL/H */
2009-11-02 09:54:04 -03:00
/* not in all ms-win traces*/
2009-08-25 06:14:54 -03:00
{ 0xa1 , 0x21 , 0xa1 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-11-02 09:54:04 -03:00
{ }
} ;
static const u8 ov7660_sensor_param1 [ ] [ 8 ] = {
2008-07-28 06:41:51 -03:00
{ 0xa1 , 0x21 , 0x1e , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } , /* MVFP */
2008-06-30 15:50:11 -03:00
/* bits[3..0]reserved */
{ 0xa1 , 0x21 , 0x1e , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* VREF vertical frame ctrl */
{ 0xa1 , 0x21 , 0x03 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2008-07-28 06:41:51 -03:00
{ 0xa1 , 0x21 , 0x10 , 0x20 , 0x00 , 0x00 , 0x00 , 0x10 } , /* AECH 0x20 */
{ 0xa1 , 0x21 , 0x2d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* ADVFL */
{ 0xa1 , 0x21 , 0x2e , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* ADVFH */
{ 0xa1 , 0x21 , 0x00 , 0x1f , 0x00 , 0x00 , 0x00 , 0x10 } , /* GAIN */
/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
2008-06-30 15:50:11 -03:00
/****** (some exchanges in the win trace) ******/
2009-11-02 09:54:04 -03:00
/*fixme:param2*/
2008-06-30 15:50:11 -03:00
{ 0xa1 , 0x21 , 0x93 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* dummy line hight */
2008-07-28 06:41:51 -03:00
{ 0xa1 , 0x21 , 0x92 , 0x25 , 0x00 , 0x00 , 0x00 , 0x10 } , /* dummy line low */
{ 0xa1 , 0x21 , 0x2a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* EXHCH */
{ 0xa1 , 0x21 , 0x2b , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } , /* EXHCL */
/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
2008-06-30 15:50:11 -03:00
/****** (some exchanges in the win trace) ******/
2008-07-28 06:41:51 -03:00
/******!! startsensor KO if changed !!****/
2009-11-02 09:54:04 -03:00
/*fixme: param3*/
2008-06-30 15:50:11 -03:00
{ 0xa1 , 0x21 , 0x93 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x92 , 0xff , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x2a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x2b , 0xc3 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2008-07-04 11:16:16 -03:00
{ }
2008-06-30 15:50:11 -03:00
} ;
2009-11-23 06:46:35 -03:00
static const u8 po1030_sensor_init [ ] [ 8 ] = {
/* the sensor registers are described in m5602/m5602_po1030.h */
{ 0xa1 , 0x6e , 0x3f , 0x20 , 0x00 , 0x00 , 0x00 , 0x10 } , /* sensor reset */
2010-10-18 07:00:48 -03:00
{ DELAY , 0x14 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 20ms */
2009-11-23 06:46:35 -03:00
{ 0xa1 , 0x6e , 0x3f , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x3e , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x04 , 0x02 , 0xb1 , 0x02 , 0x39 , 0x10 } ,
{ 0xd1 , 0x6e , 0x08 , 0x00 , 0x01 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x0c , 0x02 , 0x7f , 0x01 , 0xe0 , 0x10 } ,
{ 0xd1 , 0x6e , 0x12 , 0x03 , 0x02 , 0x00 , 0x03 , 0x10 } ,
{ 0xd1 , 0x6e , 0x16 , 0x85 , 0x40 , 0x4a , 0x40 , 0x10 } , /* r/g1/b/g2 gains */
{ 0xc1 , 0x6e , 0x1a , 0x00 , 0x80 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x1d , 0x08 , 0x03 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x23 , 0x00 , 0xb0 , 0x00 , 0x94 , 0x10 } ,
{ 0xd1 , 0x6e , 0x27 , 0x58 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x6e , 0x2b , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x2d , 0x14 , 0x35 , 0x61 , 0x84 , 0x10 } , /* gamma corr */
{ 0xd1 , 0x6e , 0x31 , 0xa2 , 0xbd , 0xd8 , 0xff , 0x10 } ,
{ 0xd1 , 0x6e , 0x35 , 0x06 , 0x1e , 0x12 , 0x02 , 0x10 } , /* color matrix */
{ 0xd1 , 0x6e , 0x39 , 0xaa , 0x53 , 0x37 , 0xd5 , 0x10 } ,
{ 0xa1 , 0x6e , 0x3d , 0xf2 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x3e , 0x00 , 0x00 , 0x80 , 0x03 , 0x10 } ,
{ 0xd1 , 0x6e , 0x42 , 0x03 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xc1 , 0x6e , 0x46 , 0x00 , 0x80 , 0x80 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x4b , 0x02 , 0xef , 0x08 , 0xcd , 0x10 } ,
{ 0xd1 , 0x6e , 0x4f , 0x00 , 0xd0 , 0x00 , 0xa0 , 0x10 } ,
{ 0xd1 , 0x6e , 0x53 , 0x01 , 0xaa , 0x01 , 0x40 , 0x10 } ,
{ 0xd1 , 0x6e , 0x5a , 0x50 , 0x04 , 0x30 , 0x03 , 0x10 } , /* raw rgb bayer */
{ 0xa1 , 0x6e , 0x5e , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x5f , 0x10 , 0x40 , 0xff , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x63 , 0x40 , 0x40 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x67 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x6b , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x6f , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xc1 , 0x6e , 0x73 , 0x10 , 0x80 , 0xeb , 0x00 , 0x10 } ,
{ }
} ;
static const u8 po1030_sensor_param1 [ ] [ 8 ] = {
/* from ms-win traces - these values change with auto gain/expo/wb.. */
{ 0xa1 , 0x6e , 0x1e , 0x03 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x1e , 0x03 , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* mean values */
{ 0xc1 , 0x6e , 0x1a , 0x02 , 0xd4 , 0xa4 , 0x00 , 0x10 } , /* integlines */
{ 0xa1 , 0x6e , 0x15 , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } , /* global gain */
{ 0xc1 , 0x6e , 0x16 , 0x40 , 0x40 , 0x40 , 0x00 , 0x10 } , /* r/g1/b gains */
{ 0xa1 , 0x6e , 0x1d , 0x08 , 0x00 , 0x00 , 0x00 , 0x10 } , /* control1 */
{ 0xa1 , 0x6e , 0x06 , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } , /* frameheight */
{ 0xa1 , 0x6e , 0x07 , 0xd5 , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
{ }
} ;
2010-03-18 05:15:30 -03:00
static const u8 po2030n_sensor_init [ ] [ 8 ] = {
{ 0xa1 , 0x6e , 0x1e , 0x1a , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x1f , 0x99 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0x0a , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 10ms */
2010-03-18 05:15:30 -03:00
{ 0xa1 , 0x6e , 0x1e , 0x0a , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x1f , 0x19 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0x0a , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 10ms */
2010-03-18 05:15:30 -03:00
{ 0xa1 , 0x6e , 0x20 , 0x44 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x04 , 0x03 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x05 , 0x70 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x06 , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x07 , 0x25 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x08 , 0x00 , 0xd0 , 0x00 , 0x08 , 0x10 } ,
{ 0xd1 , 0x6e , 0x0c , 0x03 , 0x50 , 0x01 , 0xe8 , 0x10 } ,
{ 0xd1 , 0x6e , 0x1d , 0x20 , 0x0a , 0x19 , 0x44 , 0x10 } ,
{ 0xd1 , 0x6e , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x25 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x29 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x2d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x31 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x35 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x39 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x3d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x41 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x45 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x49 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x4d , 0x00 , 0x00 , 0x00 , 0xed , 0x10 } ,
{ 0xd1 , 0x6e , 0x51 , 0x17 , 0x4a , 0x2f , 0xc0 , 0x10 } ,
{ 0xd1 , 0x6e , 0x55 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x59 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x5d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x61 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x65 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x69 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x6d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x71 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x75 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x79 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x7d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x81 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x85 , 0x00 , 0x00 , 0x00 , 0x08 , 0x10 } ,
{ 0xd1 , 0x6e , 0x89 , 0x01 , 0xe8 , 0x00 , 0x01 , 0x10 } ,
{ 0xa1 , 0x6e , 0x8d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x25 , 0x00 , 0x00 , 0x00 , 0x01 , 0x10 } ,
{ 0xd1 , 0x6e , 0x29 , 0xe6 , 0x00 , 0xbd , 0x03 , 0x10 } ,
{ 0xd1 , 0x6e , 0x2d , 0x41 , 0x38 , 0x68 , 0x40 , 0x10 } ,
{ 0xd1 , 0x6e , 0x31 , 0x2b , 0x00 , 0x36 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x35 , 0x30 , 0x30 , 0x08 , 0x00 , 0x10 } ,
{ 0xd1 , 0x6e , 0x39 , 0x00 , 0x00 , 0x33 , 0x06 , 0x10 } ,
{ 0xb1 , 0x6e , 0x3d , 0x06 , 0x02 , 0x00 , 0x00 , 0x10 } ,
{ }
} ;
static const u8 po2030n_sensor_param1 [ ] [ 8 ] = {
{ 0xa1 , 0x6e , 0x1a , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2010-10-18 07:00:48 -03:00
{ DELAY , 0x08 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 8ms */
2010-03-18 05:15:30 -03:00
{ 0xa1 , 0x6e , 0x1b , 0xf4 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x15 , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2011-11-30 06:20:07 -03:00
{ 0xd1 , 0x6e , 0x16 , 0x40 , 0x40 , 0x40 , 0x40 , 0x10 } , /* RGBG gains */
2010-03-18 05:15:30 -03:00
/*param2*/
{ 0xa1 , 0x6e , 0x1d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x04 , 0x03 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x05 , 0x6f , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x06 , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x6e , 0x07 , 0x25 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ }
} ;
2010-04-25 14:45:43 -03:00
static const u8 soi768_sensor_init [ ] [ 8 ] = {
{ 0xa1 , 0x21 , 0x12 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } , /* reset */
2010-10-18 07:00:48 -03:00
{ DELAY , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } , /* delay 96ms */
2010-04-25 14:45:43 -03:00
{ 0xa1 , 0x21 , 0x12 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x13 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x0f , 0x03 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x19 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ }
} ;
static const u8 soi768_sensor_param1 [ ] [ 8 ] = {
{ 0xa1 , 0x21 , 0x10 , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x2d , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x2e , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x21 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x21 , 0x01 , 0x7f , 0x7f , 0x00 , 0x00 , 0x10 } ,
/* */
/* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
/* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
{ 0xa1 , 0x21 , 0x2b , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
{ 0xa1 , 0x21 , 0x02 , 0x8d , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* the next sequence should be used for auto gain */
{ 0xa1 , 0x21 , 0x00 , 0x07 , 0x00 , 0x00 , 0x00 , 0x10 } ,
/* global gain ? : 07 - change with 0x15 at the end */
{ 0xa1 , 0x21 , 0x10 , 0x3f , 0x00 , 0x00 , 0x00 , 0x10 } , /* ???? : 063f */
{ 0xa1 , 0x21 , 0x04 , 0x06 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2011-08-10 05:47:34 -03:00
{ 0xb1 , 0x21 , 0x2d , 0x63 , 0x03 , 0x00 , 0x00 , 0x10 } ,
2010-04-25 14:45:43 -03:00
/* exposure ? : 0200 - change with 0x1e at the end */
{ }
} ;
2009-02-01 13:59:42 -03:00
static const u8 sp80708_sensor_init [ ] [ 8 ] = {
{ 0xa1 , 0x18 , 0x06 , 0xf9 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x09 , 0x1f , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x0a , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x0d , 0xc0 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x0c , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x0f , 0x0f , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x10 , 0x40 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x11 , 0x4e , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x12 , 0x53 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x15 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x18 , 0x18 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x19 , 0x18 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x1a , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x1b , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x1c , 0x28 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x1d , 0x02 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x1e , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x26 , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x27 , 0x1e , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x28 , 0x5a , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x29 , 0x28 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x2a , 0x78 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x2b , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x2c , 0xf7 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x2d , 0x2d , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x2e , 0xd5 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x39 , 0x42 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x3a , 0x67 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x3b , 0x87 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x3c , 0xa3 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x3d , 0xb0 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x3e , 0xbc , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x3f , 0xc8 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x40 , 0xd4 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x41 , 0xdf , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x42 , 0xea , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x43 , 0xf5 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x45 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x46 , 0x60 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x47 , 0x50 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x48 , 0x30 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x49 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x4d , 0xae , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x4e , 0x03 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x4f , 0x66 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x50 , 0x1c , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x44 , 0x10 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x4a , 0x30 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x51 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x52 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x53 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x54 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x55 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x56 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x57 , 0xe0 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x58 , 0xc0 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x59 , 0xab , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x5a , 0xa0 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x5b , 0x99 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x5c , 0x90 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x5e , 0x24 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x5f , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x60 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x61 , 0x73 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x63 , 0x42 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x64 , 0x42 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x65 , 0x42 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x66 , 0x24 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x67 , 0x24 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x68 , 0x08 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x2f , 0xc9 , 0x00 , 0x00 , 0x00 , 0x10 } ,
2009-11-02 09:54:04 -03:00
{ }
} ;
static const u8 sp80708_sensor_param1 [ ] [ 8 ] = {
2009-02-01 13:59:42 -03:00
{ 0xa1 , 0x18 , 0x0c , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x0c , 0x04 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x03 , 0x01 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x04 , 0xa4 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x14 , 0x3f , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa1 , 0x18 , 0x5d , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb1 , 0x18 , 0x11 , 0x40 , 0x40 , 0x00 , 0x00 , 0x10 } ,
{ }
} ;
2010-03-17 15:25:32 -03:00
static const u8 ( * sensor_init [ ] ) [ 8 ] = {
[ SENSOR_ADCM1700 ] = adcm1700_sensor_init ,
2010-03-18 05:15:30 -03:00
[ SENSOR_GC0307 ] = gc0307_sensor_init ,
2010-03-17 15:25:32 -03:00
[ SENSOR_HV7131R ] = hv7131r_sensor_init ,
[ SENSOR_MI0360 ] = mi0360_sensor_init ,
2010-10-01 07:51:24 -03:00
[ SENSOR_MI0360B ] = mi0360b_sensor_init ,
2010-03-17 15:25:32 -03:00
[ SENSOR_MO4000 ] = mo4000_sensor_init ,
[ SENSOR_MT9V111 ] = mt9v111_sensor_init ,
[ SENSOR_OM6802 ] = om6802_sensor_init ,
[ SENSOR_OV7630 ] = ov7630_sensor_init ,
[ SENSOR_OV7648 ] = ov7648_sensor_init ,
[ SENSOR_OV7660 ] = ov7660_sensor_init ,
[ SENSOR_PO1030 ] = po1030_sensor_init ,
2010-03-18 05:15:30 -03:00
[ SENSOR_PO2030N ] = po2030n_sensor_init ,
2010-04-25 14:45:43 -03:00
[ SENSOR_SOI768 ] = soi768_sensor_init ,
2010-03-17 15:25:32 -03:00
[ SENSOR_SP80708 ] = sp80708_sensor_init ,
2009-11-02 09:10:25 -03:00
} ;
2008-09-03 17:12:19 -03:00
/* read <len> bytes to gspca_dev->usb_buf */
2008-07-14 09:38:29 -03:00
static void reg_r ( struct gspca_dev * gspca_dev ,
2009-01-19 07:37:33 -03:00
u16 value , int len )
2008-06-30 15:50:11 -03:00
{
2010-09-25 06:12:44 -03:00
int ret ;
if ( gspca_dev - > usb_err < 0 )
return ;
2008-09-03 17:12:19 -03:00
# ifdef GSPCA_DEBUG
if ( len > USB_BUF_SZ ) {
2011-08-21 19:56:57 -03:00
pr_err ( " reg_r: buffer overflow \n " ) ;
2008-09-03 17:12:19 -03:00
return ;
}
# endif
2010-09-25 06:12:44 -03:00
ret = usb_control_msg ( gspca_dev - > dev ,
2008-07-14 09:38:29 -03:00
usb_rcvctrlpipe ( gspca_dev - > dev , 0 ) ,
2008-06-30 15:50:11 -03:00
0 ,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE ,
value , 0 ,
2008-07-14 09:38:29 -03:00
gspca_dev - > usb_buf , len ,
2008-06-30 15:50:11 -03:00
500 ) ;
2008-07-18 08:46:19 -03:00
PDEBUG ( D_USBI , " reg_r [%02x] -> %02x " , value , gspca_dev - > usb_buf [ 0 ] ) ;
2010-09-25 06:12:44 -03:00
if ( ret < 0 ) {
2011-08-21 19:56:57 -03:00
pr_err ( " reg_r err %d \n " , ret ) ;
2010-09-25 06:12:44 -03:00
gspca_dev - > usb_err = ret ;
}
2008-06-30 15:50:11 -03:00
}
2008-07-18 08:46:19 -03:00
static void reg_w1 ( struct gspca_dev * gspca_dev ,
2009-01-19 07:37:33 -03:00
u16 value ,
u8 data )
2008-07-18 08:46:19 -03:00
{
2010-09-25 06:12:44 -03:00
int ret ;
if ( gspca_dev - > usb_err < 0 )
return ;
2009-01-29 04:59:45 -03:00
PDEBUG ( D_USBO , " reg_w1 [%04x] = %02x " , value , data ) ;
2008-07-18 08:46:19 -03:00
gspca_dev - > usb_buf [ 0 ] = data ;
2010-09-25 06:12:44 -03:00
ret = usb_control_msg ( gspca_dev - > dev ,
2008-07-18 08:46:19 -03:00
usb_sndctrlpipe ( gspca_dev - > dev , 0 ) ,
0x08 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE ,
value ,
0 ,
gspca_dev - > usb_buf , 1 ,
500 ) ;
2010-09-25 06:12:44 -03:00
if ( ret < 0 ) {
2011-08-21 19:56:57 -03:00
pr_err ( " reg_w1 err %d \n " , ret ) ;
2010-09-25 06:12:44 -03:00
gspca_dev - > usb_err = ret ;
}
2008-07-18 08:46:19 -03:00
}
2008-07-14 09:38:29 -03:00
static void reg_w ( struct gspca_dev * gspca_dev ,
2009-01-19 07:37:33 -03:00
u16 value ,
const u8 * buffer ,
2008-06-30 15:50:11 -03:00
int len )
{
2010-09-25 06:12:44 -03:00
int ret ;
if ( gspca_dev - > usb_err < 0 )
return ;
2009-01-29 04:59:45 -03:00
PDEBUG ( D_USBO , " reg_w [%04x] = %02x %02x .. " ,
2008-07-18 08:46:19 -03:00
value , buffer [ 0 ] , buffer [ 1 ] ) ;
2008-09-03 17:12:19 -03:00
# ifdef GSPCA_DEBUG
if ( len > USB_BUF_SZ ) {
2011-08-21 19:56:57 -03:00
pr_err ( " reg_w: buffer overflow \n " ) ;
2008-09-03 17:12:19 -03:00
return ;
2008-07-03 11:09:12 -03:00
}
2008-09-03 17:12:19 -03:00
# endif
memcpy ( gspca_dev - > usb_buf , buffer , len ) ;
2010-09-25 06:12:44 -03:00
ret = usb_control_msg ( gspca_dev - > dev ,
2008-09-03 17:12:19 -03:00
usb_sndctrlpipe ( gspca_dev - > dev , 0 ) ,
0x08 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE ,
value , 0 ,
gspca_dev - > usb_buf , len ,
500 ) ;
2010-09-25 06:12:44 -03:00
if ( ret < 0 ) {
2011-08-21 19:56:57 -03:00
pr_err ( " reg_w err %d \n " , ret ) ;
2010-09-25 06:12:44 -03:00
gspca_dev - > usb_err = ret ;
}
2008-06-30 15:50:11 -03:00
}
2008-07-18 08:46:19 -03:00
/* I2C write 1 byte */
2009-01-19 07:37:33 -03:00
static void i2c_w1 ( struct gspca_dev * gspca_dev , u8 reg , u8 val )
2008-06-30 15:50:11 -03:00
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2010-09-25 06:12:44 -03:00
int ret ;
2008-06-30 15:50:11 -03:00
2010-09-25 06:12:44 -03:00
if ( gspca_dev - > usb_err < 0 )
return ;
2010-04-25 14:27:39 -03:00
PDEBUG ( D_USBO , " i2c_w1 [%02x] = %02x " , reg , val ) ;
2009-11-02 09:21:06 -03:00
switch ( sd - > sensor ) {
2009-12-20 12:31:28 -03:00
case SENSOR_ADCM1700 :
2010-03-18 05:15:30 -03:00
case SENSOR_OM6802 :
case SENSOR_GC0307 : /* i2c command = a0 (100 kHz) */
2009-11-02 09:21:06 -03:00
gspca_dev - > usb_buf [ 0 ] = 0x80 | ( 2 < < 4 ) ;
break ;
default : /* i2c command = a1 (400 kHz) */
gspca_dev - > usb_buf [ 0 ] = 0x81 | ( 2 < < 4 ) ;
break ;
}
2009-11-07 06:10:08 -03:00
gspca_dev - > usb_buf [ 1 ] = sd - > i2c_addr ;
2008-07-18 08:46:19 -03:00
gspca_dev - > usb_buf [ 2 ] = reg ;
gspca_dev - > usb_buf [ 3 ] = val ;
gspca_dev - > usb_buf [ 4 ] = 0 ;
gspca_dev - > usb_buf [ 5 ] = 0 ;
gspca_dev - > usb_buf [ 6 ] = 0 ;
gspca_dev - > usb_buf [ 7 ] = 0x10 ;
2010-09-25 06:12:44 -03:00
ret = usb_control_msg ( gspca_dev - > dev ,
2008-07-18 08:46:19 -03:00
usb_sndctrlpipe ( gspca_dev - > dev , 0 ) ,
0x08 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE ,
0x08 , /* value = i2c */
0 ,
gspca_dev - > usb_buf , 8 ,
500 ) ;
2010-09-25 06:12:44 -03:00
if ( ret < 0 ) {
2011-08-21 19:56:57 -03:00
pr_err ( " i2c_w1 err %d \n " , ret ) ;
2010-09-25 06:12:44 -03:00
gspca_dev - > usb_err = ret ;
}
2008-06-30 15:50:11 -03:00
}
2008-07-14 09:38:29 -03:00
/* I2C write 8 bytes */
static void i2c_w8 ( struct gspca_dev * gspca_dev ,
2009-01-19 07:37:33 -03:00
const u8 * buffer )
2008-06-30 15:50:11 -03:00
{
2010-09-25 06:12:44 -03:00
int ret ;
if ( gspca_dev - > usb_err < 0 )
return ;
2010-04-25 14:27:39 -03:00
PDEBUG ( D_USBO , " i2c_w8 [%02x] = %02x .. " ,
buffer [ 2 ] , buffer [ 3 ] ) ;
2008-07-18 08:46:19 -03:00
memcpy ( gspca_dev - > usb_buf , buffer , 8 ) ;
2010-09-25 06:12:44 -03:00
ret = usb_control_msg ( gspca_dev - > dev ,
2008-07-18 08:46:19 -03:00
usb_sndctrlpipe ( gspca_dev - > dev , 0 ) ,
0x08 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE ,
0x08 , 0 , /* value, index */
gspca_dev - > usb_buf , 8 ,
500 ) ;
2008-09-21 03:28:55 -03:00
msleep ( 2 ) ;
2010-09-25 06:12:44 -03:00
if ( ret < 0 ) {
2011-08-21 19:56:57 -03:00
pr_err ( " i2c_w8 err %d \n " , ret ) ;
2010-09-25 06:12:44 -03:00
gspca_dev - > usb_err = ret ;
}
2008-06-30 15:50:11 -03:00
}
2009-11-23 06:46:35 -03:00
/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
static void i2c_r ( struct gspca_dev * gspca_dev , u8 reg , int len )
2008-06-30 15:50:11 -03:00
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2009-01-19 07:37:33 -03:00
u8 mode [ 8 ] ;
2008-06-30 15:50:11 -03:00
2009-11-02 09:21:06 -03:00
switch ( sd - > sensor ) {
2009-12-20 12:31:28 -03:00
case SENSOR_ADCM1700 :
2010-03-18 05:15:30 -03:00
case SENSOR_OM6802 :
case SENSOR_GC0307 : /* i2c command = a0 (100 kHz) */
2009-11-02 09:21:06 -03:00
mode [ 0 ] = 0x80 | 0x10 ;
break ;
default : /* i2c command = 91 (400 kHz) */
mode [ 0 ] = 0x81 | 0x10 ;
break ;
}
2009-11-07 06:10:08 -03:00
mode [ 1 ] = sd - > i2c_addr ;
2008-06-30 15:50:11 -03:00
mode [ 2 ] = reg ;
mode [ 3 ] = 0 ;
mode [ 4 ] = 0 ;
mode [ 5 ] = 0 ;
mode [ 6 ] = 0 ;
mode [ 7 ] = 0x10 ;
2008-07-14 09:38:29 -03:00
i2c_w8 ( gspca_dev , mode ) ;
2008-07-18 08:46:19 -03:00
msleep ( 2 ) ;
2009-11-23 06:46:35 -03:00
mode [ 0 ] = ( mode [ 0 ] & 0x81 ) | ( len < < 4 ) | 0x02 ;
2008-06-30 15:50:11 -03:00
mode [ 2 ] = 0 ;
2008-07-14 09:38:29 -03:00
i2c_w8 ( gspca_dev , mode ) ;
2008-07-18 08:46:19 -03:00
msleep ( 2 ) ;
2008-07-14 09:38:29 -03:00
reg_r ( gspca_dev , 0x0a , 5 ) ;
2008-06-30 15:50:11 -03:00
}
2009-11-02 09:10:25 -03:00
static void i2c_w_seq ( struct gspca_dev * gspca_dev ,
const u8 ( * data ) [ 8 ] )
{
while ( ( * data ) [ 0 ] ! = 0 ) {
2010-10-18 07:00:48 -03:00
if ( ( * data ) [ 0 ] ! = DELAY )
2009-11-02 09:10:25 -03:00
i2c_w8 ( gspca_dev , * data ) ;
else
msleep ( ( * data ) [ 1 ] ) ;
data + + ;
}
}
2010-10-29 08:10:37 -03:00
/* check the ID of the hv7131 sensor */
/* this sequence is needed because it activates the sensor */
2009-10-22 06:27:14 -03:00
static void hv7131r_probe ( struct gspca_dev * gspca_dev )
2008-06-30 15:50:11 -03:00
{
2010-10-29 08:10:37 -03:00
i2c_w1 ( gspca_dev , 0x02 , 0 ) ; /* sensor wakeup */
2008-06-30 15:50:11 -03:00
msleep ( 10 ) ;
2010-10-29 08:10:37 -03:00
reg_w1 ( gspca_dev , 0x02 , 0x66 ) ; /* Gpio on */
2008-06-30 15:50:11 -03:00
msleep ( 10 ) ;
2010-10-29 08:10:37 -03:00
i2c_r ( gspca_dev , 0 , 5 ) ; /* read sensor id */
if ( gspca_dev - > usb_buf [ 0 ] = = 0x02 /* chip ID (02 is R) */
2008-07-14 09:38:29 -03:00
& & gspca_dev - > usb_buf [ 1 ] = = 0x09
2010-10-29 08:10:37 -03:00
& & gspca_dev - > usb_buf [ 2 ] = = 0x01 ) {
PDEBUG ( D_PROBE , " Sensor HV7131R found " ) ;
2009-10-22 06:27:14 -03:00
return ;
2008-06-30 15:50:11 -03:00
}
2011-08-21 19:56:57 -03:00
pr_warn ( " Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x \n " ,
2008-07-14 09:38:29 -03:00
gspca_dev - > usb_buf [ 0 ] , gspca_dev - > usb_buf [ 1 ] ,
gspca_dev - > usb_buf [ 2 ] ) ;
2008-06-30 15:50:11 -03:00
}
2009-02-01 14:26:51 -03:00
static void mi0360_probe ( struct gspca_dev * gspca_dev )
2009-01-29 04:59:45 -03:00
{
2009-02-01 14:26:51 -03:00
struct sd * sd = ( struct sd * ) gspca_dev ;
2009-01-29 04:59:45 -03:00
int i , j ;
2009-02-02 16:25:38 -03:00
u16 val = 0 ;
2009-01-29 04:59:45 -03:00
static const u8 probe_tb [ ] [ 4 ] [ 8 ] = {
2009-02-01 14:26:51 -03:00
{ /* mi0360 */
2009-01-29 04:59:45 -03:00
{ 0xb0 , 0x5d , 0x07 , 0x00 , 0x02 , 0x00 , 0x00 , 0x10 } ,
{ 0x90 , 0x5d , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa2 , 0x5d , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xb0 , 0x5d , 0x07 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 }
} ,
2009-02-01 14:26:51 -03:00
{ /* mt9v111 */
2009-01-29 04:59:45 -03:00
{ 0xb0 , 0x5c , 0x01 , 0x00 , 0x04 , 0x00 , 0x00 , 0x10 } ,
{ 0x90 , 0x5c , 0x36 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ 0xa2 , 0x5c , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ,
{ }
} ,
} ;
for ( i = 0 ; i < ARRAY_SIZE ( probe_tb ) ; i + + ) {
reg_w1 ( gspca_dev , 0x17 , 0x62 ) ;
reg_w1 ( gspca_dev , 0x01 , 0x08 ) ;
for ( j = 0 ; j < 3 ; j + + )
i2c_w8 ( gspca_dev , probe_tb [ i ] [ j ] ) ;
msleep ( 2 ) ;
reg_r ( gspca_dev , 0x0a , 5 ) ;
val = ( gspca_dev - > usb_buf [ 3 ] < < 8 ) | gspca_dev - > usb_buf [ 4 ] ;
if ( probe_tb [ i ] [ 3 ] [ 0 ] ! = 0 )
i2c_w8 ( gspca_dev , probe_tb [ i ] [ 3 ] ) ;
reg_w1 ( gspca_dev , 0x01 , 0x29 ) ;
reg_w1 ( gspca_dev , 0x17 , 0x42 ) ;
if ( val ! = 0xffff )
break ;
}
2010-09-25 06:12:44 -03:00
if ( gspca_dev - > usb_err < 0 )
return ;
2009-01-29 04:59:45 -03:00
switch ( val ) {
2010-10-01 07:51:24 -03:00
case 0x8221 :
PDEBUG ( D_PROBE , " Sensor mi0360b " ) ;
sd - > sensor = SENSOR_MI0360B ;
break ;
2009-01-29 04:59:45 -03:00
case 0x823a :
PDEBUG ( D_PROBE , " Sensor mt9v111 " ) ;
2009-02-01 14:26:51 -03:00
sd - > sensor = SENSOR_MT9V111 ;
break ;
2009-01-29 04:59:45 -03:00
case 0x8243 :
PDEBUG ( D_PROBE , " Sensor mi0360 " ) ;
2009-02-01 14:26:51 -03:00
break ;
default :
PDEBUG ( D_PROBE , " Unknown sensor %04x - forced to mi0360 " , val ) ;
break ;
2009-01-29 04:59:45 -03:00
}
}
2010-04-25 14:45:43 -03:00
static void ov7630_probe ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
u16 val ;
/* check ov76xx */
reg_w1 ( gspca_dev , 0x17 , 0x62 ) ;
reg_w1 ( gspca_dev , 0x01 , 0x08 ) ;
sd - > i2c_addr = 0x21 ;
i2c_r ( gspca_dev , 0x0a , 2 ) ;
val = ( gspca_dev - > usb_buf [ 3 ] < < 8 ) | gspca_dev - > usb_buf [ 4 ] ;
reg_w1 ( gspca_dev , 0x01 , 0x29 ) ;
reg_w1 ( gspca_dev , 0x17 , 0x42 ) ;
2010-09-25 06:12:44 -03:00
if ( gspca_dev - > usb_err < 0 )
return ;
2010-04-25 14:45:43 -03:00
if ( val = = 0x7628 ) { /* soi768 */
sd - > sensor = SENSOR_SOI768 ;
/*fixme: only valid for 0c45:613e?*/
gspca_dev - > cam . input_flags =
V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP ;
PDEBUG ( D_PROBE , " Sensor soi768 " ) ;
return ;
}
PDEBUG ( D_PROBE , " Sensor ov%04x " , val ) ;
}
2009-11-23 06:46:35 -03:00
static void ov7648_probe ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2010-04-25 14:41:51 -03:00
u16 val ;
2009-11-23 06:46:35 -03:00
/* check ov76xx */
reg_w1 ( gspca_dev , 0x17 , 0x62 ) ;
reg_w1 ( gspca_dev , 0x01 , 0x08 ) ;
sd - > i2c_addr = 0x21 ;
i2c_r ( gspca_dev , 0x0a , 2 ) ;
2010-04-25 14:41:51 -03:00
val = ( gspca_dev - > usb_buf [ 3 ] < < 8 ) | gspca_dev - > usb_buf [ 4 ] ;
2009-11-23 06:46:35 -03:00
reg_w1 ( gspca_dev , 0x01 , 0x29 ) ;
reg_w1 ( gspca_dev , 0x17 , 0x42 ) ;
2010-04-25 14:41:51 -03:00
if ( ( val & 0xff00 ) = = 0x7600 ) { /* ov76xx */
PDEBUG ( D_PROBE , " Sensor ov%04x " , val ) ;
return ;
}
2009-11-23 06:46:35 -03:00
/* check po1030 */
reg_w1 ( gspca_dev , 0x17 , 0x62 ) ;
reg_w1 ( gspca_dev , 0x01 , 0x08 ) ;
sd - > i2c_addr = 0x6e ;
i2c_r ( gspca_dev , 0x00 , 2 ) ;
2010-04-25 14:41:51 -03:00
val = ( gspca_dev - > usb_buf [ 3 ] < < 8 ) | gspca_dev - > usb_buf [ 4 ] ;
reg_w1 ( gspca_dev , 0x01 , 0x29 ) ;
reg_w1 ( gspca_dev , 0x17 , 0x42 ) ;
2010-09-25 06:12:44 -03:00
if ( gspca_dev - > usb_err < 0 )
return ;
2010-04-25 14:41:51 -03:00
if ( val = = 0x1030 ) { /* po1030 */
2009-11-23 06:46:35 -03:00
PDEBUG ( D_PROBE , " Sensor po1030 " ) ;
sd - > sensor = SENSOR_PO1030 ;
return ;
}
2011-08-21 19:56:57 -03:00
pr_err ( " Unknown sensor %04x \n " , val ) ;
2009-11-23 06:46:35 -03:00
}
2010-03-18 05:15:30 -03:00
/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
static void po2030n_probe ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2010-04-25 14:41:51 -03:00
u16 val ;
2010-03-18 05:15:30 -03:00
/* check gc0307 */
reg_w1 ( gspca_dev , 0x17 , 0x62 ) ;
reg_w1 ( gspca_dev , 0x01 , 0x08 ) ;
reg_w1 ( gspca_dev , 0x02 , 0x22 ) ;
sd - > i2c_addr = 0x21 ;
i2c_r ( gspca_dev , 0x00 , 1 ) ;
2010-04-25 14:41:51 -03:00
val = gspca_dev - > usb_buf [ 4 ] ;
2010-03-18 05:15:30 -03:00
reg_w1 ( gspca_dev , 0x01 , 0x29 ) ; /* reset */
reg_w1 ( gspca_dev , 0x17 , 0x42 ) ;
2010-04-25 14:41:51 -03:00
if ( val = = 0x99 ) { /* gc0307 (?) */
2010-03-18 05:15:30 -03:00
PDEBUG ( D_PROBE , " Sensor gc0307 " ) ;
sd - > sensor = SENSOR_GC0307 ;
return ;
}
/* check po2030n */
reg_w1 ( gspca_dev , 0x17 , 0x62 ) ;
reg_w1 ( gspca_dev , 0x01 , 0x0a ) ;
sd - > i2c_addr = 0x6e ;
i2c_r ( gspca_dev , 0x00 , 2 ) ;
2010-04-25 14:41:51 -03:00
val = ( gspca_dev - > usb_buf [ 3 ] < < 8 ) | gspca_dev - > usb_buf [ 4 ] ;
2010-03-18 05:15:30 -03:00
reg_w1 ( gspca_dev , 0x01 , 0x29 ) ;
reg_w1 ( gspca_dev , 0x17 , 0x42 ) ;
2010-09-25 06:12:44 -03:00
if ( gspca_dev - > usb_err < 0 )
return ;
2010-04-25 14:41:51 -03:00
if ( val = = 0x2030 ) {
2010-03-18 05:15:30 -03:00
PDEBUG ( D_PROBE , " Sensor po2030n " ) ;
/* sd->sensor = SENSOR_PO2030N; */
2010-04-25 14:41:51 -03:00
} else {
2011-08-21 19:56:57 -03:00
pr_err ( " Unknown sensor ID %04x \n " , val ) ;
2010-04-25 14:41:51 -03:00
}
2010-03-18 05:15:30 -03:00
}
2008-06-30 15:50:11 -03: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 ;
2010-01-12 07:12:43 -03:00
sd - > bridge = id - > driver_info > > 16 ;
2010-12-14 16:15:37 -03:00
sd - > sensor = id - > driver_info > > 8 ;
sd - > flags = id - > driver_info ;
2010-01-12 07:12:43 -03:00
2008-06-30 15:50:11 -03:00
cam = & gspca_dev - > cam ;
2009-12-20 12:31:28 -03:00
if ( sd - > sensor = = SENSOR_ADCM1700 ) {
cam - > cam_mode = cif_mode ;
cam - > nmodes = ARRAY_SIZE ( cif_mode ) ;
} else {
cam - > cam_mode = vga_mode ;
cam - > nmodes = ARRAY_SIZE ( vga_mode ) ;
}
2009-04-25 13:29:01 -03:00
cam - > npkt = 24 ; /* 24 packets per ISOC message */
2010-10-02 04:35:25 -03:00
cam - > ctrls = sd - > ctrls ;
2008-07-04 11:16:16 -03:00
2008-08-03 07:52:53 -03:00
sd - > ag_cnt = - 1 ;
2009-03-02 06:40:52 -03:00
sd - > quality = QUALITY_DEF ;
2008-08-03 07:52:53 -03:00
2011-02-10 07:38:58 -03:00
INIT_WORK ( & sd - > work , qual_upd ) ;
2008-06-30 15:50:11 -03:00
return 0 ;
}
2008-09-03 17:12:16 -03:00
/* this function is called at probe and resume time */
static int sd_init ( struct gspca_dev * gspca_dev )
2008-06-30 15:50:11 -03:00
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2009-11-07 06:10:08 -03:00
const u8 * sn9c1xx ;
2011-02-10 07:52:58 -03:00
u8 regGpio [ ] = { 0x29 , 0x70 } ; /* no audio */
2009-01-19 07:37:33 -03:00
u8 regF1 ;
2008-06-30 15:50:11 -03:00
2008-07-15 05:36:30 -03:00
/* setup a selector by bridge */
2008-07-18 08:46:19 -03:00
reg_w1 ( gspca_dev , 0xf1 , 0x01 ) ;
2008-07-14 09:38:29 -03:00
reg_r ( gspca_dev , 0x00 , 1 ) ;
2010-12-14 16:15:00 -03:00
reg_w1 ( gspca_dev , 0xf1 , 0x00 ) ;
2008-07-29 14:14:04 -03:00
reg_r ( gspca_dev , 0x00 , 1 ) ; /* get sonix chip id */
2008-07-14 09:38:29 -03:00
regF1 = gspca_dev - > usb_buf [ 0 ] ;
2010-09-25 06:12:44 -03:00
if ( gspca_dev - > usb_err < 0 )
return gspca_dev - > usb_err ;
2008-07-29 14:14:04 -03:00
PDEBUG ( D_PROBE , " Sonix chip id: %02x " , regF1 ) ;
2011-02-10 07:52:58 -03:00
if ( gspca_dev - > audio )
regGpio [ 1 ] | = 0x04 ; /* with audio */
2008-07-15 05:36:30 -03:00
switch ( sd - > bridge ) {
case BRIDGE_SN9C102P :
2011-01-06 15:23:55 -03:00
case BRIDGE_SN9C105 :
2008-06-30 15:50:11 -03:00
if ( regF1 ! = 0x11 )
return - ENODEV ;
2011-01-06 15:23:55 -03:00
break ;
default :
/* case BRIDGE_SN9C110: */
/* case BRIDGE_SN9C120: */
if ( regF1 ! = 0x12 )
return - ENODEV ;
}
switch ( sd - > sensor ) {
case SENSOR_MI0360 :
mi0360_probe ( gspca_dev ) ;
break ;
case SENSOR_OV7630 :
ov7630_probe ( gspca_dev ) ;
break ;
case SENSOR_OV7648 :
ov7648_probe ( gspca_dev ) ;
break ;
case SENSOR_PO2030N :
po2030n_probe ( gspca_dev ) ;
break ;
}
switch ( sd - > bridge ) {
case BRIDGE_SN9C102P :
2008-07-18 08:46:19 -03:00
reg_w1 ( gspca_dev , 0x02 , regGpio [ 1 ] ) ;
2008-06-30 15:50:11 -03:00
break ;
2011-02-10 08:00:40 -03:00
default :
2008-10-02 08:06:59 -03:00
reg_w ( gspca_dev , 0x01 , regGpio , 2 ) ;
2008-06-30 15:50:11 -03:00
break ;
}
2010-10-02 04:35:25 -03:00
if ( sd - > sensor = = SENSOR_OM6802 )
sd - > ctrls [ SHARPNESS ] . def = 0x10 ;
2010-01-31 12:54:29 -03:00
/* Note we do not disable the sensor clock here (power saving mode),
as that also disables the button on the cam . */
reg_w1 ( gspca_dev , 0xf1 , 0x00 ) ;
2008-06-30 15:50:11 -03:00
2009-11-07 06:10:08 -03:00
/* set the i2c address */
sn9c1xx = sn_tb [ sd - > sensor ] ;
sd - > i2c_addr = sn9c1xx [ 9 ] ;
2009-11-23 06:46:35 -03:00
gspca_dev - > ctrl_dis = ctrl_dis [ sd - > sensor ] ;
2011-01-13 06:39:11 -03:00
if ( ! ( sd - > flags & F_ILLUM ) )
gspca_dev - > ctrl_dis | = ( 1 < < ILLUM ) ;
2009-11-23 06:46:35 -03:00
2010-09-25 06:12:44 -03:00
return gspca_dev - > usb_err ;
2008-06-30 15:50:11 -03:00
}
2012-02-27 06:57:04 -03:00
static u32 expo_adjust ( struct gspca_dev * gspca_dev ,
2009-01-19 07:37:33 -03:00
u32 expo )
2008-06-30 15:50:11 -03:00
{
struct sd * sd = ( struct sd * ) gspca_dev ;
switch ( sd - > sensor ) {
2010-04-02 07:08:39 -03:00
case SENSOR_GC0307 : {
int a , b ;
/* expo = 0..255 -> a = 19..43 */
a = 19 + expo * 25 / 256 ;
i2c_w1 ( gspca_dev , 0x68 , a ) ;
a - = 12 ;
b = a * a * 4 ; /* heuristic */
i2c_w1 ( gspca_dev , 0x03 , b > > 8 ) ;
i2c_w1 ( gspca_dev , 0x04 , b ) ;
break ;
}
2008-06-30 15:50:11 -03:00
case SENSOR_HV7131R : {
2009-01-19 07:37:33 -03:00
u8 Expodoit [ ] =
2009-11-07 06:10:08 -03:00
{ 0xc1 , 0x11 , 0x25 , 0x00 , 0x00 , 0x00 , 0x00 , 0x16 } ;
2008-06-30 15:50:11 -03:00
Expodoit [ 3 ] = expo > > 16 ;
Expodoit [ 4 ] = expo > > 8 ;
Expodoit [ 5 ] = expo ;
2008-07-14 09:38:29 -03:00
i2c_w8 ( gspca_dev , Expodoit ) ;
2008-06-30 15:50:11 -03:00
break ;
}
2010-10-01 07:51:24 -03:00
case SENSOR_MI0360 :
case SENSOR_MI0360B : {
2009-01-29 04:59:45 -03:00
u8 expoMi [ ] = /* exposure 0x0635 -> 4 fp/s 0x10 */
2009-11-07 06:10:08 -03:00
{ 0xb1 , 0x5d , 0x09 , 0x00 , 0x00 , 0x00 , 0x00 , 0x16 } ;
2009-01-19 07:37:33 -03:00
static const u8 doit [ ] = /* update sensor */
{ 0xb1 , 0x5d , 0x07 , 0x00 , 0x03 , 0x00 , 0x00 , 0x10 } ;
static const u8 sensorgo [ ] = /* sensor on */
{ 0xb1 , 0x5d , 0x07 , 0x00 , 0x02 , 0x00 , 0x00 , 0x10 } ;
2008-06-30 15:50:11 -03:00
if ( expo > 0x0635 )
expo = 0x0635 ;
else if ( expo < 0x0001 )
expo = 0x0001 ;
expoMi [ 3 ] = expo > > 8 ;
expoMi [ 4 ] = expo ;
2008-07-14 09:38:29 -03:00
i2c_w8 ( gspca_dev , expoMi ) ;
i2c_w8 ( gspca_dev , doit ) ;
i2c_w8 ( gspca_dev , sensorgo ) ;
2008-06-30 15:50:11 -03:00
break ;
}
case SENSOR_MO4000 : {
2009-01-19 07:37:33 -03:00
u8 expoMof [ ] =
2009-11-07 06:10:08 -03:00
{ 0xa1 , 0x21 , 0x0f , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ;
2009-01-19 07:37:33 -03:00
u8 expoMo10 [ ] =
2009-11-07 06:10:08 -03:00
{ 0xa1 , 0x21 , 0x10 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ;
2009-01-19 07:37:33 -03:00
static const u8 gainMo [ ] =
{ 0xa1 , 0x21 , 0x00 , 0x10 , 0x00 , 0x00 , 0x00 , 0x1d } ;
2008-06-30 15:50:11 -03:00
if ( expo > 0x1fff )
expo = 0x1fff ;
else if ( expo < 0x0001 )
expo = 0x0001 ;
expoMof [ 3 ] = ( expo & 0x03fc ) > > 2 ;
2008-07-14 09:38:29 -03:00
i2c_w8 ( gspca_dev , expoMof ) ;
2008-06-30 15:50:11 -03:00
expoMo10 [ 3 ] = ( ( expo & 0x1c00 ) > > 10 )
| ( ( expo & 0x0003 ) < < 4 ) ;
2008-07-14 09:38:29 -03:00
i2c_w8 ( gspca_dev , expoMo10 ) ;
i2c_w8 ( gspca_dev , gainMo ) ;
2009-01-29 04:59:45 -03:00
PDEBUG ( D_FRAM , " set exposure %d " ,
2008-06-30 15:50:11 -03:00
( ( expoMo10 [ 3 ] & 0x07 ) < < 10 )
| ( expoMof [ 3 ] < < 2 )
| ( ( expoMo10 [ 3 ] & 0x30 ) > > 4 ) ) ;
break ;
}
2009-01-29 04:59:45 -03:00
case SENSOR_MT9V111 : {
u8 expo_c1 [ ] =
{ 0xb1 , 0x5c , 0x09 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ;
2011-02-10 07:49:32 -03:00
if ( expo > 0x0390 )
expo = 0x0390 ;
else if ( expo < 0x0060 )
expo = 0x0060 ;
2009-01-29 04:59:45 -03:00
expo_c1 [ 3 ] = expo > > 8 ;
expo_c1 [ 4 ] = expo ;
i2c_w8 ( gspca_dev , expo_c1 ) ;
break ;
}
2008-09-03 16:47:23 -03:00
case SENSOR_OM6802 : {
2009-01-19 07:37:33 -03:00
u8 gainOm [ ] =
2008-09-03 16:47:23 -03:00
{ 0xa0 , 0x34 , 0xe5 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ;
2009-11-07 06:10:08 -03:00
/* preset AGC - works when AutoExpo = off */
2008-09-03 16:47:23 -03:00
if ( expo > 0x03ff )
expo = 0x03ff ;
if ( expo < 0x0001 )
expo = 0x0001 ;
gainOm [ 3 ] = expo > > 2 ;
i2c_w8 ( gspca_dev , gainOm ) ;
2009-11-07 06:10:08 -03:00
reg_w1 ( gspca_dev , 0x96 , expo > > 5 ) ;
2009-01-29 04:59:45 -03:00
PDEBUG ( D_FRAM , " set exposure %d " , gainOm [ 3 ] ) ;
2008-09-03 16:47:23 -03:00
break ;
}
2008-06-30 15:50:11 -03:00
}
return expo ;
}
static void setbrightness ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
unsigned int expo ;
2010-10-02 04:35:25 -03:00
int brightness ;
2009-01-19 07:37:33 -03:00
u8 k2 ;
2008-06-30 15:50:11 -03:00
2010-10-02 04:35:25 -03:00
brightness = sd - > ctrls [ BRIGHTNESS ] . val ;
k2 = ( brightness - 0x80 ) > > 2 ;
2008-06-30 15:50:11 -03:00
switch ( sd - > sensor ) {
2009-12-20 12:31:28 -03:00
case SENSOR_ADCM1700 :
2009-12-30 04:53:07 -03:00
if ( k2 > 0x1f )
k2 = 0 ; /* only positive Y offset */
break ;
2008-06-30 15:50:11 -03:00
case SENSOR_HV7131R :
2010-10-02 04:35:25 -03:00
expo = brightness < < 12 ;
2008-06-30 15:50:11 -03:00
if ( expo > 0x002dc6c0 )
expo = 0x002dc6c0 ;
else if ( expo < 0x02a0 )
expo = 0x02a0 ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev , expo ) ;
2008-06-30 15:50:11 -03:00
break ;
case SENSOR_MI0360 :
case SENSOR_MO4000 :
2010-10-02 04:35:25 -03:00
expo = brightness < < 4 ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev , expo ) ;
2008-06-30 15:50:11 -03:00
break ;
2010-10-01 07:51:24 -03:00
case SENSOR_MI0360B :
2010-10-02 04:35:25 -03:00
expo = brightness < < 2 ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev , expo ) ;
2010-10-01 07:51:24 -03:00
break ;
2010-04-02 07:08:39 -03:00
case SENSOR_GC0307 :
2010-10-02 04:35:25 -03:00
expo = brightness ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev , expo ) ;
2009-11-07 06:10:08 -03:00
return ; /* don't set the Y offset */
2011-02-10 07:49:32 -03:00
case SENSOR_MT9V111 :
expo = brightness < < 2 ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev , expo ) ;
2011-02-10 07:49:32 -03:00
return ; /* don't set the Y offset */
2008-09-03 16:47:23 -03:00
case SENSOR_OM6802 :
2010-10-02 04:35:25 -03:00
expo = brightness < < 2 ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev , expo ) ;
2011-08-10 05:54:34 -03:00
return ; /* Y offset already set */
2008-06-30 15:50:11 -03:00
}
2009-11-07 06:10:08 -03:00
reg_w1 ( gspca_dev , 0x96 , k2 ) ; /* color matrix Y offset */
2008-06-30 15:50:11 -03:00
}
static void setcontrast ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2009-01-19 07:37:33 -03:00
u8 k2 ;
u8 contrast [ 6 ] ;
2008-06-30 15:50:11 -03:00
2011-08-10 05:13:45 -03:00
k2 = sd - > ctrls [ CONTRAST ] . val * 37 / ( CONTRAST_MAX + 1 )
+ 37 ; /* 37..73 */
2008-11-23 14:47:50 -03:00
contrast [ 0 ] = ( k2 + 1 ) / 2 ; /* red */
2008-12-05 06:18:37 -03:00
contrast [ 1 ] = 0 ;
2008-11-23 14:47:50 -03:00
contrast [ 2 ] = k2 ; /* green */
2008-12-05 06:18:37 -03:00
contrast [ 3 ] = 0 ;
2011-08-10 05:13:45 -03:00
contrast [ 4 ] = k2 / 5 ; /* blue */
2008-12-05 06:18:37 -03:00
contrast [ 5 ] = 0 ;
reg_w ( gspca_dev , 0x84 , contrast , sizeof contrast ) ;
2008-06-30 15:50:11 -03:00
}
static void setcolors ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2010-10-02 04:35:25 -03:00
int i , v , colors ;
2010-10-01 07:51:24 -03:00
const s16 * uv ;
2009-01-19 07:37:33 -03:00
u8 reg8a [ 12 ] ; /* U & V gains */
2010-10-01 07:51:24 -03:00
static const s16 uv_com [ 6 ] = { /* same as reg84 in signed decimal */
2008-11-26 04:46:15 -03:00
- 24 , - 38 , 64 , /* UR UG UB */
62 , - 51 , - 9 /* VR VG VB */
} ;
2010-10-01 07:51:24 -03:00
static const s16 uv_mi0360b [ 6 ] = {
- 20 , - 38 , 64 , /* UR UG UB */
60 , - 51 , - 9 /* VR VG VB */
} ;
2009-11-07 06:10:08 -03:00
2010-10-02 04:35:25 -03:00
colors = sd - > ctrls [ COLORS ] . val ;
2010-10-01 07:51:24 -03:00
if ( sd - > sensor = = SENSOR_MI0360B )
uv = uv_mi0360b ;
else
uv = uv_com ;
2008-11-26 04:46:15 -03:00
for ( i = 0 ; i < 6 ; i + + ) {
2010-10-02 04:35:25 -03:00
v = uv [ i ] * colors / COLORS_DEF ;
2008-12-02 06:58:57 -03:00
reg8a [ i * 2 ] = v ;
reg8a [ i * 2 + 1 ] = ( v > > 8 ) & 0x0f ;
2008-09-03 16:48:01 -03:00
}
2008-12-02 06:58:57 -03:00
reg_w ( gspca_dev , 0x8a , reg8a , sizeof reg8a ) ;
2008-11-26 04:46:15 -03:00
}
static void setredblue ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2011-11-30 06:20:07 -03:00
if ( sd - > sensor = = SENSOR_PO2030N ) {
u8 rg1b [ ] = /* red green1 blue (no g2) */
{ 0xc1 , 0x6e , 0x16 , 0x00 , 0x40 , 0x00 , 0x00 , 0x10 } ;
/* 0x40 = normal value = gain x 1 */
rg1b [ 3 ] = sd - > ctrls [ RED ] . val * 2 ;
rg1b [ 5 ] = sd - > ctrls [ BLUE ] . val * 2 ;
i2c_w8 ( gspca_dev , rg1b ) ;
return ;
}
2010-10-02 04:35:25 -03:00
reg_w1 ( gspca_dev , 0x05 , sd - > ctrls [ RED ] . val ) ;
2008-09-03 16:48:04 -03:00
/* reg_w1(gspca_dev, 0x07, 32); */
2010-10-02 04:35:25 -03:00
reg_w1 ( gspca_dev , 0x06 , sd - > ctrls [ BLUE ] . val ) ;
2008-06-30 15:50:11 -03:00
}
2009-01-15 08:01:32 -03:00
static void setgamma ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2010-10-02 04:35:25 -03:00
int i , val ;
2009-01-15 08:01:32 -03:00
u8 gamma [ 17 ] ;
2009-02-01 14:20:07 -03:00
const u8 * gamma_base ;
2009-01-15 08:01:32 -03:00
static const u8 delta [ 17 ] = {
0x00 , 0x14 , 0x1c , 0x1c , 0x1c , 0x1c , 0x1b , 0x1a ,
0x18 , 0x13 , 0x10 , 0x0e , 0x08 , 0x07 , 0x04 , 0x02 , 0x00
} ;
2009-02-01 14:20:07 -03:00
switch ( sd - > sensor ) {
2009-12-20 12:31:28 -03:00
case SENSOR_ADCM1700 :
gamma_base = gamma_spec_0 ;
break ;
2009-02-01 14:20:07 -03:00
case SENSOR_HV7131R :
2010-10-01 07:51:24 -03:00
case SENSOR_MI0360B :
2009-02-01 14:20:07 -03:00
case SENSOR_MT9V111 :
gamma_base = gamma_spec_1 ;
break ;
2010-03-18 05:15:30 -03:00
case SENSOR_GC0307 :
2009-02-01 14:20:07 -03:00
gamma_base = gamma_spec_2 ;
break ;
2010-03-18 05:15:30 -03:00
case SENSOR_SP80708 :
gamma_base = gamma_spec_3 ;
break ;
2009-02-01 14:20:07 -03:00
default :
gamma_base = gamma_def ;
break ;
}
2009-02-01 13:59:42 -03:00
2010-10-02 04:35:25 -03:00
val = sd - > ctrls [ GAMMA ] . val ;
2009-01-15 08:01:32 -03:00
for ( i = 0 ; i < sizeof gamma ; i + + )
2009-02-01 14:20:07 -03:00
gamma [ i ] = gamma_base [ i ]
2010-10-02 04:35:25 -03:00
+ delta [ i ] * ( val - GAMMA_DEF ) / 32 ;
2009-01-15 08:01:32 -03:00
reg_w ( gspca_dev , 0x20 , gamma , sizeof gamma ) ;
}
2012-02-27 06:57:04 -03:00
static void setexposure ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
if ( sd - > sensor = = SENSOR_PO2030N ) {
u8 rexpo [ ] = /* 1a: expo H, 1b: expo M */
{ 0xa1 , 0x6e , 0x1a , 0x00 , 0x40 , 0x00 , 0x00 , 0x10 } ;
rexpo [ 3 ] = sd - > ctrls [ EXPOSURE ] . val > > 8 ;
i2c_w8 ( gspca_dev , rexpo ) ;
msleep ( 6 ) ;
rexpo [ 2 ] = 0x1b ;
rexpo [ 3 ] = sd - > ctrls [ EXPOSURE ] . val ;
i2c_w8 ( gspca_dev , rexpo ) ;
}
}
2008-08-03 07:52:53 -03:00
static void setautogain ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2010-10-02 04:35:25 -03:00
if ( gspca_dev - > ctrl_dis & ( 1 < < AUTOGAIN ) )
2008-09-03 17:12:14 -03:00
return ;
2009-02-05 15:12:24 -03:00
switch ( sd - > sensor ) {
case SENSOR_OV7630 :
case SENSOR_OV7648 : {
u8 comb ;
if ( sd - > sensor = = SENSOR_OV7630 )
comb = 0xc0 ;
else
comb = 0xa0 ;
2010-10-02 04:35:25 -03:00
if ( sd - > ctrls [ AUTOGAIN ] . val )
2009-06-18 06:05:07 -03:00
comb | = 0x03 ;
2009-02-05 15:12:24 -03:00
i2c_w1 ( & sd - > gspca_dev , 0x13 , comb ) ;
return ;
}
}
2010-10-02 04:35:25 -03:00
if ( sd - > ctrls [ AUTOGAIN ] . val )
2008-09-03 17:12:14 -03:00
sd - > ag_cnt = AG_CNT_START ;
else
sd - > ag_cnt = - 1 ;
2008-08-03 07:52:53 -03:00
}
2012-02-27 06:57:04 -03:00
static void setgain ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
if ( sd - > sensor = = SENSOR_PO2030N ) {
u8 rgain [ ] = /* 15: gain */
{ 0xa1 , 0x6e , 0x15 , 0x00 , 0x40 , 0x00 , 0x00 , 0x15 } ;
rgain [ 3 ] = sd - > ctrls [ GAIN ] . val ;
i2c_w8 ( gspca_dev , rgain ) ;
}
}
2010-10-19 03:33:47 -03:00
static void sethvflip ( struct gspca_dev * gspca_dev )
2008-09-08 04:57:26 -03:00
{
2010-10-02 04:35:25 -03:00
struct sd * sd = ( struct sd * ) gspca_dev ;
2009-02-05 15:12:24 -03:00
u8 comn ;
2010-02-18 04:12:06 -03:00
switch ( sd - > sensor ) {
case SENSOR_HV7131R :
comn = 0x18 ; /* clkdiv = 1, ablcen = 1 */
2010-10-02 04:35:25 -03:00
if ( sd - > ctrls [ VFLIP ] . val )
2010-02-18 04:12:06 -03:00
comn | = 0x01 ;
2010-10-02 04:35:25 -03:00
i2c_w1 ( gspca_dev , 0x01 , comn ) ; /* sctra */
2010-02-18 04:12:06 -03:00
break ;
case SENSOR_OV7630 :
2009-02-05 15:12:24 -03:00
comn = 0x02 ;
2010-10-02 04:35:25 -03:00
if ( ! sd - > ctrls [ VFLIP ] . val )
2009-06-18 14:29:20 -03:00
comn | = 0x80 ;
2010-10-02 04:35:25 -03:00
i2c_w1 ( gspca_dev , 0x75 , comn ) ;
2010-02-18 04:12:06 -03:00
break ;
2010-10-19 03:33:47 -03:00
case SENSOR_OV7648 :
2009-02-05 15:12:24 -03:00
comn = 0x06 ;
2010-10-02 04:35:25 -03:00
if ( sd - > ctrls [ VFLIP ] . val )
2009-06-18 14:29:20 -03:00
comn | = 0x80 ;
2010-10-02 04:35:25 -03:00
i2c_w1 ( gspca_dev , 0x75 , comn ) ;
2010-02-18 04:12:06 -03:00
break ;
2010-10-19 03:33:47 -03:00
case SENSOR_PO2030N :
/* Reg. 0x1E: Timing Generator Control Register 2 (Tgcontrol2)
* ( reset value : 0x0A )
* bit7 : HM : Horizontal Mirror : 0 : disable , 1 : enable
* bit6 : VM : Vertical Mirror : 0 : disable , 1 : enable
* bit5 : ST : Shutter Selection : 0 : electrical , 1 : mechanical
* bit4 : FT : Single Frame Transfer : 0 : disable , 1 : enable
* bit3 - 0 : X
*/
comn = 0x0a ;
if ( sd - > ctrls [ HFLIP ] . val )
comn | = 0x80 ;
if ( sd - > ctrls [ VFLIP ] . val )
comn | = 0x40 ;
i2c_w1 ( & sd - > gspca_dev , 0x1e , comn ) ;
break ;
2009-06-18 14:29:20 -03:00
}
2008-09-08 04:57:26 -03:00
}
2010-10-02 04:35:25 -03:00
static void setsharpness ( struct gspca_dev * gspca_dev )
2009-12-30 04:53:07 -03:00
{
2010-10-02 04:35:25 -03:00
struct sd * sd = ( struct sd * ) gspca_dev ;
reg_w1 ( gspca_dev , 0x99 , sd - > ctrls [ SHARPNESS ] . val ) ;
2009-12-30 04:53:07 -03:00
}
2011-01-13 06:39:11 -03:00
static void setillum ( struct gspca_dev * gspca_dev )
2008-10-17 07:48:24 -03:00
{
2010-10-02 04:35:25 -03:00
struct sd * sd = ( struct sd * ) gspca_dev ;
2011-01-13 06:39:11 -03:00
if ( gspca_dev - > ctrl_dis & ( 1 < < ILLUM ) )
2009-08-25 06:14:54 -03:00
return ;
2011-01-13 07:56:00 -03:00
switch ( sd - > sensor ) {
case SENSOR_ADCM1700 :
reg_w1 ( gspca_dev , 0x02 , /* gpio */
sd - > ctrls [ ILLUM ] . val ? 0x64 : 0x60 ) ;
break ;
case SENSOR_MT9V111 :
2011-02-10 08:03:24 -03:00
reg_w1 ( gspca_dev , 0x02 ,
sd - > ctrls [ ILLUM ] . val ? 0x77 : 0x74 ) ;
/* should have been: */
/* 0x55 : 0x54); * 370i */
/* 0x66 : 0x64); * Clip */
2011-01-13 07:56:00 -03:00
break ;
}
2008-10-17 07:48:24 -03:00
}
2009-06-18 07:35:36 -03:00
static void setfreq ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2010-10-02 04:35:25 -03:00
if ( gspca_dev - > ctrl_dis & ( 1 < < FREQ ) )
2009-07-08 05:21:50 -03:00
return ;
2009-06-18 07:35:36 -03:00
if ( sd - > sensor = = SENSOR_OV7660 ) {
2009-07-08 06:33:44 -03:00
u8 com8 ;
2009-08-25 06:14:54 -03:00
com8 = 0xdf ; /* auto gain/wb/expo */
2010-10-02 04:35:25 -03:00
switch ( sd - > ctrls [ FREQ ] . val ) {
2009-06-18 07:35:36 -03:00
case 0 : /* Banding filter disabled */
2009-08-25 06:14:54 -03:00
i2c_w1 ( gspca_dev , 0x13 , com8 | 0x20 ) ;
2009-06-18 07:35:36 -03:00
break ;
case 1 : /* 50 hz */
2009-07-08 06:33:44 -03:00
i2c_w1 ( gspca_dev , 0x13 , com8 ) ;
2009-06-18 07:35:36 -03:00
i2c_w1 ( gspca_dev , 0x3b , 0x0a ) ;
break ;
case 2 : /* 60 hz */
2009-07-08 06:33:44 -03:00
i2c_w1 ( gspca_dev , 0x13 , com8 ) ;
2009-06-18 07:35:36 -03:00
i2c_w1 ( gspca_dev , 0x3b , 0x02 ) ;
break ;
}
} else {
u8 reg2a = 0 , reg2b = 0 , reg2d = 0 ;
/* Get reg2a / reg2d base values */
switch ( sd - > sensor ) {
case SENSOR_OV7630 :
reg2a = 0x08 ;
reg2d = 0x01 ;
break ;
case SENSOR_OV7648 :
reg2a = 0x11 ;
reg2d = 0x81 ;
break ;
}
2010-10-02 04:35:25 -03:00
switch ( sd - > ctrls [ FREQ ] . val ) {
2009-06-18 07:35:36 -03:00
case 0 : /* Banding filter disabled */
break ;
case 1 : /* 50 hz (filter on and framerate adj) */
reg2a | = 0x80 ;
reg2b = 0xac ;
reg2d | = 0x04 ;
break ;
case 2 : /* 60 hz (filter on, no framerate adj) */
reg2a | = 0x80 ;
reg2d | = 0x04 ;
break ;
}
i2c_w1 ( gspca_dev , 0x2a , reg2a ) ;
i2c_w1 ( gspca_dev , 0x2b , reg2b ) ;
i2c_w1 ( gspca_dev , 0x2d , reg2d ) ;
}
}
2009-03-03 05:33:41 -03:00
static void setjpegqual ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2011-02-10 07:30:03 -03:00
jpeg_set_qual ( sd - > jpeg_hdr , sd - > quality ) ;
2009-03-03 05:33:41 -03:00
# if USB_BUF_SZ < 64
# error "No room enough in usb_buf for quantization table"
# endif
2011-02-10 07:30:03 -03:00
memcpy ( gspca_dev - > usb_buf , & sd - > jpeg_hdr [ JPEG_QT0_OFFSET ] , 64 ) ;
2009-03-03 05:33:41 -03:00
usb_control_msg ( gspca_dev - > dev ,
usb_sndctrlpipe ( gspca_dev - > dev , 0 ) ,
0x08 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE ,
0x0100 , 0 ,
gspca_dev - > usb_buf , 64 ,
500 ) ;
2011-02-10 07:30:03 -03:00
memcpy ( gspca_dev - > usb_buf , & sd - > jpeg_hdr [ JPEG_QT1_OFFSET ] , 64 ) ;
2009-03-03 05:33:41 -03:00
usb_control_msg ( gspca_dev - > dev ,
usb_sndctrlpipe ( gspca_dev - > dev , 0 ) ,
0x08 ,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE ,
0x0140 , 0 ,
gspca_dev - > usb_buf , 64 ,
500 ) ;
sd - > reg18 ^ = 0x40 ;
reg_w1 ( gspca_dev , 0x18 , sd - > reg18 ) ;
}
2011-02-10 07:38:58 -03:00
/* JPEG quality update */
/* This function is executed from a work queue. */
static void qual_upd ( struct work_struct * work )
{
struct sd * sd = container_of ( work , struct sd , work ) ;
struct gspca_dev * gspca_dev = & sd - > gspca_dev ;
mutex_lock ( & gspca_dev - > usb_lock ) ;
PDEBUG ( D_STREAM , " qual_upd %d%% " , sd - > quality ) ;
setjpegqual ( gspca_dev ) ;
mutex_unlock ( & gspca_dev - > usb_lock ) ;
}
2008-06-30 15:50:11 -03:00
/* -- start the camera -- */
2008-09-20 06:39:08 -03:00
static int sd_start ( struct gspca_dev * gspca_dev )
2008-06-30 15:50:11 -03:00
{
struct sd * sd = ( struct sd * ) gspca_dev ;
int i ;
2010-12-14 16:17:40 -03:00
u8 reg01 , reg17 ;
2010-12-14 16:14:10 -03:00
u8 reg0102 [ 2 ] ;
2009-01-19 07:37:33 -03:00
const u8 * sn9c1xx ;
2009-11-02 09:54:04 -03:00
const u8 ( * init ) [ 8 ] ;
2010-12-14 16:15:00 -03:00
const u8 * reg9a ;
2008-06-30 15:50:11 -03:00
int mode ;
2010-12-14 16:14:10 -03:00
static const u8 reg9a_def [ ] =
{ 0x00 , 0x40 , 0x20 , 0x00 , 0x00 , 0x00 } ;
static const u8 reg9a_spec [ ] =
{ 0x00 , 0x40 , 0x38 , 0x30 , 0x00 , 0x20 } ;
static const u8 regd4 [ ] = { 0x60 , 0x00 , 0x00 } ;
2009-01-19 07:37:33 -03:00
static const u8 C0 [ ] = { 0x2d , 0x2d , 0x3a , 0x05 , 0x04 , 0x3f } ;
static const u8 CA [ ] = { 0x28 , 0xd8 , 0x14 , 0xec } ;
2009-12-20 12:31:28 -03:00
static const u8 CA_adcm1700 [ ] =
{ 0x14 , 0xec , 0x0a , 0xf6 } ;
2010-03-18 05:15:30 -03:00
static const u8 CA_po2030n [ ] =
{ 0x1e , 0xe2 , 0x14 , 0xec } ;
2009-01-19 07:37:33 -03:00
static const u8 CE [ ] = { 0x32 , 0xdd , 0x2d , 0xdd } ; /* MI0360 */
2010-03-18 05:15:30 -03:00
static const u8 CE_gc0307 [ ] =
{ 0x32 , 0xce , 0x2d , 0xd3 } ;
2009-01-19 07:37:33 -03:00
static const u8 CE_ov76xx [ ] =
2008-10-02 08:06:59 -03:00
{ 0x32 , 0xdd , 0x32 , 0xdd } ;
2010-03-18 05:15:30 -03:00
static const u8 CE_po2030n [ ] =
{ 0x14 , 0xe7 , 0x1e , 0xdd } ;
2008-06-30 15:50:11 -03:00
2009-03-03 05:33:41 -03:00
/* create the JPEG header */
jpeg_define ( sd - > jpeg_hdr , gspca_dev - > height , gspca_dev - > width ,
0x21 ) ; /* JPEG 422 */
2009-11-02 09:54:04 -03:00
/* initialize the bridge */
sn9c1xx = sn_tb [ sd - > sensor ] ;
2010-12-14 16:14:10 -03:00
/* sensor clock already enabled in sd_init */
/* reg_w1(gspca_dev, 0xf1, 0x00); */
2010-12-14 16:17:40 -03:00
reg01 = sn9c1xx [ 1 ] ;
2011-01-13 06:39:11 -03:00
if ( sd - > flags & F_PDN_INV )
2010-12-14 16:17:40 -03:00
reg01 ^ = S_PDN_INV ; /* power down inverted */
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
2010-12-14 16:14:10 -03:00
/* configure gpio */
2010-12-14 16:17:40 -03:00
reg0102 [ 0 ] = reg01 ;
2010-12-14 16:14:10 -03:00
reg0102 [ 1 ] = sn9c1xx [ 2 ] ;
if ( gspca_dev - > audio )
reg0102 [ 1 ] | = 0x04 ; /* keep the audio connection */
reg_w ( gspca_dev , 0x01 , reg0102 , 2 ) ;
reg_w ( gspca_dev , 0x08 , & sn9c1xx [ 8 ] , 2 ) ;
reg_w ( gspca_dev , 0x17 , & sn9c1xx [ 0x17 ] , 5 ) ;
switch ( sd - > sensor ) {
case SENSOR_GC0307 :
case SENSOR_OV7660 :
case SENSOR_PO1030 :
case SENSOR_PO2030N :
case SENSOR_SOI768 :
case SENSOR_SP80708 :
reg9a = reg9a_spec ;
break ;
default :
reg9a = reg9a_def ;
break ;
}
reg_w ( gspca_dev , 0x9a , reg9a , 6 ) ;
reg_w ( gspca_dev , 0xd4 , regd4 , sizeof regd4 ) ;
reg_w ( gspca_dev , 0x03 , & sn9c1xx [ 3 ] , 0x0f ) ;
2010-12-14 16:17:40 -03:00
reg17 = sn9c1xx [ 0x17 ] ;
2010-12-14 16:14:10 -03:00
switch ( sd - > sensor ) {
case SENSOR_GC0307 :
2010-12-14 16:17:40 -03:00
msleep ( 50 ) ; /*fixme: is it useful? */
2010-12-14 16:14:10 -03:00
break ;
case SENSOR_OM6802 :
msleep ( 10 ) ;
reg_w1 ( gspca_dev , 0x02 , 0x73 ) ;
2010-12-14 16:17:40 -03:00
reg17 | = SEN_CLK_EN ;
reg_w1 ( gspca_dev , 0x17 , reg17 ) ;
2010-12-14 16:14:10 -03:00
reg_w1 ( gspca_dev , 0x01 , 0x22 ) ;
msleep ( 100 ) ;
2010-12-14 16:17:40 -03:00
reg01 = SCL_SEL_OD | S_PDN_INV ;
2011-07-14 23:08:39 -03:00
reg17 & = ~ MCK_SIZE_MASK ;
2010-12-14 16:17:40 -03:00
reg17 | = 0x04 ; /* clock / 4 */
break ;
}
reg01 | = SYS_SEL_48M ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
reg17 | = SEN_CLK_EN ;
reg_w1 ( gspca_dev , 0x17 , reg17 ) ;
reg01 & = ~ S_PWR_DN ; /* sensor power on */
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
2011-11-30 05:58:20 -03:00
reg01 & = ~ SCL_SEL_OD ; /* remove open-drain mode */
2010-12-14 16:17:40 -03:00
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
switch ( sd - > sensor ) {
case SENSOR_HV7131R :
hv7131r_probe ( gspca_dev ) ; /*fixme: is it useful? */
break ;
case SENSOR_OM6802 :
2010-12-14 16:14:10 -03:00
msleep ( 10 ) ;
2010-12-14 16:17:40 -03:00
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
2010-12-14 16:14:10 -03:00
i2c_w8 ( gspca_dev , om6802_init0 [ 0 ] ) ;
i2c_w8 ( gspca_dev , om6802_init0 [ 1 ] ) ;
msleep ( 15 ) ;
reg_w1 ( gspca_dev , 0x02 , 0x71 ) ;
msleep ( 150 ) ;
break ;
case SENSOR_SP80708 :
msleep ( 100 ) ;
reg_w1 ( gspca_dev , 0x02 , 0x62 ) ;
break ;
}
2009-11-07 06:10:08 -03:00
2009-11-02 09:54:04 -03:00
/* initialize the sensor */
i2c_w_seq ( gspca_dev , sensor_init [ sd - > sensor ] ) ;
2008-07-18 08:46:19 -03:00
reg_w1 ( gspca_dev , 0x15 , sn9c1xx [ 0x15 ] ) ;
reg_w1 ( gspca_dev , 0x16 , sn9c1xx [ 0x16 ] ) ;
reg_w1 ( gspca_dev , 0x12 , sn9c1xx [ 0x12 ] ) ;
reg_w1 ( gspca_dev , 0x13 , sn9c1xx [ 0x13 ] ) ;
reg_w1 ( gspca_dev , 0x18 , sn9c1xx [ 0x18 ] ) ;
2009-12-20 12:31:28 -03:00
if ( sd - > sensor = = SENSOR_ADCM1700 ) {
2009-12-30 04:53:07 -03:00
reg_w1 ( gspca_dev , 0xd2 , 0x3a ) ; /* AE_H_SIZE = 116 */
reg_w1 ( gspca_dev , 0xd3 , 0x30 ) ; /* AE_V_SIZE = 96 */
2009-12-20 12:31:28 -03:00
} else {
2009-12-30 04:53:07 -03:00
reg_w1 ( gspca_dev , 0xd2 , 0x6a ) ; /* AE_H_SIZE = 212 */
reg_w1 ( gspca_dev , 0xd3 , 0x50 ) ; /* AE_V_SIZE = 160 */
2009-12-20 12:31:28 -03:00
}
2008-07-18 08:46:19 -03:00
reg_w1 ( gspca_dev , 0xc6 , 0x00 ) ;
reg_w1 ( gspca_dev , 0xc7 , 0x00 ) ;
2009-12-20 12:31:28 -03:00
if ( sd - > sensor = = SENSOR_ADCM1700 ) {
2009-12-30 04:53:07 -03:00
reg_w1 ( gspca_dev , 0xc8 , 0x2c ) ; /* AW_H_STOP = 352 */
reg_w1 ( gspca_dev , 0xc9 , 0x24 ) ; /* AW_V_STOP = 288 */
2009-12-20 12:31:28 -03:00
} else {
2009-12-30 04:53:07 -03:00
reg_w1 ( gspca_dev , 0xc8 , 0x50 ) ; /* AW_H_STOP = 640 */
reg_w1 ( gspca_dev , 0xc9 , 0x3c ) ; /* AW_V_STOP = 480 */
2009-12-20 12:31:28 -03:00
}
2008-07-18 08:46:19 -03:00
reg_w1 ( gspca_dev , 0x18 , sn9c1xx [ 0x18 ] ) ;
2008-09-03 16:47:34 -03:00
switch ( sd - > sensor ) {
2010-12-14 16:17:40 -03:00
case SENSOR_OM6802 :
/* case SENSOR_OV7648: * fixme: sometimes */
2009-11-23 06:46:35 -03:00
break ;
2008-07-15 11:46:06 -03:00
default :
2010-12-14 16:17:40 -03:00
reg17 | = DEF_EN ;
2008-07-15 11:46:06 -03:00
break ;
}
2008-07-29 14:14:04 -03:00
reg_w1 ( gspca_dev , 0x17 , reg17 ) ;
2009-12-30 04:53:07 -03:00
reg_w1 ( gspca_dev , 0x05 , 0x00 ) ; /* red */
reg_w1 ( gspca_dev , 0x07 , 0x00 ) ; /* green */
reg_w1 ( gspca_dev , 0x06 , 0x00 ) ; /* blue */
2008-07-18 08:46:19 -03:00
reg_w1 ( gspca_dev , 0x14 , sn9c1xx [ 0x14 ] ) ;
2009-02-01 14:20:07 -03:00
2009-02-01 13:59:42 -03:00
setgamma ( gspca_dev ) ;
2009-12-30 04:53:07 -03:00
/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
2008-09-03 16:47:59 -03:00
for ( i = 0 ; i < 8 ; i + + )
reg_w ( gspca_dev , 0x84 , reg84 , sizeof reg84 ) ;
2008-10-02 08:06:59 -03:00
switch ( sd - > sensor ) {
2009-12-20 12:31:28 -03:00
case SENSOR_ADCM1700 :
2009-12-30 04:53:07 -03:00
case SENSOR_OV7660 :
case SENSOR_SP80708 :
2009-12-20 12:31:28 -03:00
reg_w1 ( gspca_dev , 0x9a , 0x05 ) ;
break ;
2010-03-18 05:15:30 -03:00
case SENSOR_GC0307 :
2009-01-29 04:59:45 -03:00
case SENSOR_MT9V111 :
2010-10-01 07:51:24 -03:00
case SENSOR_MI0360B :
2009-01-29 04:59:45 -03:00
reg_w1 ( gspca_dev , 0x9a , 0x07 ) ;
2009-11-02 09:54:04 -03:00
break ;
2010-04-25 14:33:31 -03:00
case SENSOR_OV7630 :
2008-11-11 08:42:56 -03:00
case SENSOR_OV7648 :
reg_w1 ( gspca_dev , 0x9a , 0x0a ) ;
2009-02-01 13:59:42 -03:00
break ;
2010-03-18 05:15:30 -03:00
case SENSOR_PO2030N :
2010-04-25 14:45:43 -03:00
case SENSOR_SOI768 :
2010-03-18 05:15:30 -03:00
reg_w1 ( gspca_dev , 0x9a , 0x06 ) ;
break ;
2008-10-02 08:06:59 -03:00
default :
2008-07-18 08:46:19 -03:00
reg_w1 ( gspca_dev , 0x9a , 0x08 ) ;
2008-10-02 08:06:59 -03:00
break ;
}
2010-10-02 04:35:25 -03:00
setsharpness ( gspca_dev ) ;
2008-06-30 15:50:11 -03:00
2009-11-02 09:54:04 -03:00
reg_w ( gspca_dev , 0x84 , reg84 , sizeof reg84 ) ;
2009-12-30 04:53:07 -03:00
reg_w1 ( gspca_dev , 0x05 , 0x20 ) ; /* red */
reg_w1 ( gspca_dev , 0x07 , 0x20 ) ; /* green */
reg_w1 ( gspca_dev , 0x06 , 0x20 ) ; /* blue */
2009-11-02 09:10:25 -03:00
2009-11-02 09:54:04 -03:00
init = NULL ;
2009-11-07 06:10:08 -03:00
mode = gspca_dev - > cam . cam_mode [ gspca_dev - > curr_mode ] . priv ;
2010-12-14 16:17:40 -03:00
reg01 | = SYS_SEL_48M | V_TX_EN ;
reg17 & = ~ MCK_SIZE_MASK ;
reg17 | = 0x02 ; /* clock / 2 */
2008-06-30 15:50:11 -03:00
switch ( sd - > sensor ) {
2009-12-20 12:31:28 -03:00
case SENSOR_ADCM1700 :
init = adcm1700_sensor_param1 ;
break ;
2010-03-18 05:15:30 -03:00
case SENSOR_GC0307 :
init = gc0307_sensor_param1 ;
2010-12-14 16:17:40 -03:00
break ;
case SENSOR_HV7131R :
case SENSOR_MI0360 :
2011-08-10 05:54:34 -03:00
if ( ! mode )
2010-12-14 16:17:40 -03:00
reg01 & = ~ SYS_SEL_48M ; /* 640x480: clk 24Mhz */
reg17 & = ~ MCK_SIZE_MASK ;
reg17 | = 0x01 ; /* clock / 1 */
2010-03-18 05:15:30 -03:00
break ;
2010-10-01 07:51:24 -03:00
case SENSOR_MI0360B :
init = mi0360b_sensor_param1 ;
break ;
2008-06-30 15:50:11 -03:00
case SENSOR_MO4000 :
2010-12-14 16:17:40 -03:00
if ( mode ) { /* if 320x240 */
reg01 & = ~ SYS_SEL_48M ; /* clk 24Mz */
reg17 & = ~ MCK_SIZE_MASK ;
reg17 | = 0x01 ; /* clock / 1 */
2008-06-30 15:50:11 -03:00
}
break ;
2009-01-29 04:59:45 -03:00
case SENSOR_MT9V111 :
2009-11-02 09:54:04 -03:00
init = mt9v111_sensor_param1 ;
2009-01-30 12:14:02 -03:00
break ;
2008-09-03 16:47:23 -03:00
case SENSOR_OM6802 :
2009-11-02 09:54:04 -03:00
init = om6802_sensor_param1 ;
2010-12-14 16:17:40 -03:00
if ( ! mode ) { /* if 640x480 */
reg17 & = ~ MCK_SIZE_MASK ;
2010-12-28 07:39:13 -03:00
reg17 | = 0x04 ; /* clock / 4 */
2011-08-09 15:13:50 -03:00
} else {
reg01 & = ~ SYS_SEL_48M ; /* clk 24Mz */
reg17 & = ~ MCK_SIZE_MASK ;
reg17 | = 0x02 ; /* clock / 2 */
2010-12-14 16:17:40 -03:00
}
2008-09-03 16:47:23 -03:00
break ;
2008-09-03 16:47:34 -03:00
case SENSOR_OV7630 :
2010-04-25 14:23:39 -03:00
init = ov7630_sensor_param1 ;
2008-09-03 16:47:34 -03:00
break ;
2008-06-30 15:50:11 -03:00
case SENSOR_OV7648 :
2009-11-02 09:54:04 -03:00
init = ov7648_sensor_param1 ;
2010-12-14 16:17:40 -03:00
reg17 & = ~ MCK_SIZE_MASK ;
reg17 | = 0x01 ; /* clock / 1 */
2008-06-30 15:50:11 -03:00
break ;
2009-02-01 13:59:42 -03:00
case SENSOR_OV7660 :
2009-11-02 09:54:04 -03:00
init = ov7660_sensor_param1 ;
2008-06-30 15:50:11 -03:00
break ;
2009-11-23 06:46:35 -03:00
case SENSOR_PO1030 :
init = po1030_sensor_param1 ;
break ;
2010-03-18 05:15:30 -03:00
case SENSOR_PO2030N :
init = po2030n_sensor_param1 ;
break ;
2010-04-25 14:45:43 -03:00
case SENSOR_SOI768 :
init = soi768_sensor_param1 ;
break ;
2010-10-21 04:05:15 -03:00
case SENSOR_SP80708 :
2009-11-02 09:54:04 -03:00
init = sp80708_sensor_param1 ;
2009-02-01 13:59:42 -03:00
break ;
2008-06-30 15:50:11 -03:00
}
2009-11-02 09:54:04 -03:00
/* more sensor initialization - param1 */
if ( init ! = NULL ) {
i2c_w_seq ( gspca_dev , init ) ;
/* init = NULL; */
}
2008-07-14 09:38:29 -03:00
reg_w ( gspca_dev , 0xc0 , C0 , 6 ) ;
2010-03-18 05:15:30 -03:00
switch ( sd - > sensor ) {
case SENSOR_ADCM1700 :
case SENSOR_GC0307 :
2010-04-25 14:45:43 -03:00
case SENSOR_SOI768 :
2009-12-20 12:31:28 -03:00
reg_w ( gspca_dev , 0xca , CA_adcm1700 , 4 ) ;
2010-03-18 05:15:30 -03:00
break ;
case SENSOR_PO2030N :
reg_w ( gspca_dev , 0xca , CA_po2030n , 4 ) ;
break ;
default :
2009-12-20 12:31:28 -03:00
reg_w ( gspca_dev , 0xca , CA , 4 ) ;
2010-03-18 05:15:30 -03:00
break ;
}
2008-09-03 16:47:34 -03:00
switch ( sd - > sensor ) {
2009-12-20 12:31:28 -03:00
case SENSOR_ADCM1700 :
2008-09-03 16:47:34 -03:00
case SENSOR_OV7630 :
case SENSOR_OV7648 :
2008-10-02 08:06:59 -03:00
case SENSOR_OV7660 :
2010-04-25 14:45:43 -03:00
case SENSOR_SOI768 :
2008-09-03 16:47:34 -03:00
reg_w ( gspca_dev , 0xce , CE_ov76xx , 4 ) ;
2008-06-30 15:50:11 -03:00
break ;
2010-03-18 05:15:30 -03:00
case SENSOR_GC0307 :
reg_w ( gspca_dev , 0xce , CE_gc0307 , 4 ) ;
break ;
case SENSOR_PO2030N :
reg_w ( gspca_dev , 0xce , CE_po2030n , 4 ) ;
break ;
2008-06-30 15:50:11 -03:00
default :
2008-07-14 09:38:29 -03:00
reg_w ( gspca_dev , 0xce , CE , 4 ) ;
2008-06-30 15:50:11 -03:00
/* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
break ;
}
/* here change size mode 0 -> VGA; 1 -> CIF */
2009-03-03 05:33:41 -03:00
sd - > reg18 = sn9c1xx [ 0x18 ] | ( mode < < 4 ) | 0x40 ;
reg_w1 ( gspca_dev , 0x18 , sd - > reg18 ) ;
setjpegqual ( gspca_dev ) ;
2008-06-30 15:50:11 -03:00
2008-07-18 08:46:19 -03:00
reg_w1 ( gspca_dev , 0x17 , reg17 ) ;
2010-12-14 16:17:40 -03:00
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
sd - > reg01 = reg01 ;
sd - > reg17 = reg17 ;
2009-11-02 09:54:04 -03:00
2010-10-19 03:33:47 -03:00
sethvflip ( gspca_dev ) ;
2008-11-23 14:47:50 -03:00
setbrightness ( gspca_dev ) ;
setcontrast ( gspca_dev ) ;
2010-04-25 14:31:05 -03:00
setcolors ( gspca_dev ) ;
2008-08-03 07:52:53 -03:00
setautogain ( gspca_dev ) ;
2012-02-27 06:57:04 -03:00
if ( ! ( gspca_dev - > ctrl_inac & ( ( 1 < < EXPOSURE ) | ( 1 < < GAIN ) ) ) ) {
setexposure ( gspca_dev ) ;
setgain ( gspca_dev ) ;
}
2009-06-18 07:35:36 -03:00
setfreq ( gspca_dev ) ;
2011-02-10 07:38:58 -03:00
sd - > pktsz = sd - > npkt = 0 ;
sd - > nchg = sd - > short_mark = 0 ;
sd - > work_thread = create_singlethread_workqueue ( MODULE_NAME ) ;
2010-09-25 06:12:44 -03:00
return gspca_dev - > usb_err ;
2008-06-30 15:50:11 -03:00
}
static void sd_stopN ( struct gspca_dev * gspca_dev )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2009-01-19 07:37:33 -03:00
static const u8 stophv7131 [ ] =
2008-06-30 15:50:11 -03:00
{ 0xa1 , 0x11 , 0x02 , 0x09 , 0x00 , 0x00 , 0x00 , 0x10 } ;
2009-01-19 07:37:33 -03:00
static const u8 stopmi0360 [ ] =
2008-06-30 15:50:11 -03:00
{ 0xb1 , 0x5d , 0x07 , 0x00 , 0x00 , 0x00 , 0x00 , 0x10 } ;
2009-01-19 07:37:33 -03:00
static const u8 stopov7648 [ ] =
2008-11-11 08:42:56 -03:00
{ 0xa1 , 0x21 , 0x76 , 0x20 , 0x00 , 0x00 , 0x00 , 0x10 } ;
2010-04-25 14:45:43 -03:00
static const u8 stopsoi768 [ ] =
{ 0xa1 , 0x21 , 0x12 , 0x80 , 0x00 , 0x00 , 0x00 , 0x10 } ;
2010-12-14 16:17:40 -03:00
u8 reg01 ;
u8 reg17 ;
2008-06-30 15:50:11 -03:00
2010-12-14 16:17:40 -03:00
reg01 = sd - > reg01 ;
reg17 = sd - > reg17 & ~ SEN_CLK_EN ;
2008-06-30 15:50:11 -03:00
switch ( sd - > sensor ) {
2010-12-14 16:17:40 -03:00
case SENSOR_ADCM1700 :
2010-03-18 05:15:30 -03:00
case SENSOR_GC0307 :
2010-12-14 16:17:40 -03:00
case SENSOR_PO2030N :
case SENSOR_SP80708 :
reg01 | = LED ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
reg01 & = ~ ( LED | V_TX_EN ) ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
/* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */
2010-03-18 05:15:30 -03:00
break ;
2008-06-30 15:50:11 -03:00
case SENSOR_HV7131R :
2010-12-14 16:17:40 -03:00
reg01 & = ~ V_TX_EN ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
2008-07-14 09:38:29 -03:00
i2c_w8 ( gspca_dev , stophv7131 ) ;
2008-06-30 15:50:11 -03:00
break ;
case SENSOR_MI0360 :
2010-10-01 07:51:24 -03:00
case SENSOR_MI0360B :
2010-12-14 16:17:40 -03:00
reg01 & = ~ V_TX_EN ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
/* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */
2008-07-14 09:38:29 -03:00
i2c_w8 ( gspca_dev , stopmi0360 ) ;
2008-06-30 15:50:11 -03:00
break ;
2009-01-29 04:59:45 -03:00
case SENSOR_MT9V111 :
2010-12-14 16:17:40 -03:00
case SENSOR_OM6802 :
2009-11-23 06:46:35 -03:00
case SENSOR_PO1030 :
2010-12-14 16:17:40 -03:00
reg01 & = ~ V_TX_EN ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
break ;
case SENSOR_OV7630 :
case SENSOR_OV7648 :
reg01 & = ~ V_TX_EN ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
i2c_w8 ( gspca_dev , stopov7648 ) ;
break ;
case SENSOR_OV7660 :
reg01 & = ~ V_TX_EN ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
2008-06-30 15:50:11 -03:00
break ;
2010-04-25 14:45:43 -03:00
case SENSOR_SOI768 :
i2c_w8 ( gspca_dev , stopsoi768 ) ;
break ;
2008-06-30 15:50:11 -03:00
}
2010-12-14 16:17:40 -03:00
reg01 | = SCL_SEL_OD ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
reg01 | = S_PWR_DN ; /* sensor power down */
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
reg_w1 ( gspca_dev , 0x17 , reg17 ) ;
reg01 & = ~ SYS_SEL_48M ; /* clock 24MHz */
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
reg01 | = LED ;
reg_w1 ( gspca_dev , 0x01 , reg01 ) ;
2010-01-31 12:54:29 -03:00
/* Don't disable sensor clock as that disables the button on the cam */
/* reg_w1(gspca_dev, 0xf1, 0x01); */
2008-06-30 15:50:11 -03:00
}
2011-02-10 07:38:58 -03:00
/* 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 * sd = ( struct sd * ) gspca_dev ;
if ( sd - > work_thread ! = NULL ) {
mutex_unlock ( & gspca_dev - > usb_lock ) ;
destroy_workqueue ( sd - > work_thread ) ;
mutex_lock ( & gspca_dev - > usb_lock ) ;
sd - > work_thread = NULL ;
}
}
2012-04-27 11:32:24 -03:00
# define WANT_REGULAR_AUTOGAIN
2012-02-27 06:57:04 -03:00
# include "autogain_functions.h"
2008-08-03 07:52:53 -03:00
static void do_autogain ( struct gspca_dev * gspca_dev )
2008-06-30 15:50:11 -03:00
{
struct sd * sd = ( struct sd * ) gspca_dev ;
int delta ;
2008-08-03 07:52:53 -03:00
int expotimes ;
2009-01-19 07:37:33 -03:00
u8 luma_mean = 130 ;
u8 luma_delta = 20 ;
2008-06-30 15:50:11 -03:00
2008-08-03 07:52:53 -03:00
/* Thanks S., without your advice, autobright should not work :) */
if ( sd - > ag_cnt < 0 )
return ;
if ( - - sd - > ag_cnt > = 0 )
return ;
sd - > ag_cnt = AG_CNT_START ;
delta = atomic_read ( & sd - > avg_lum ) ;
PDEBUG ( D_FRAM , " mean lum %d " , delta ) ;
2012-02-27 06:57:04 -03:00
if ( sd - > sensor = = SENSOR_PO2030N ) {
auto_gain_n_exposure ( gspca_dev , delta , luma_mean , luma_delta ,
15 , 1024 ) ;
return ;
}
2008-06-30 15:50:11 -03:00
if ( delta < luma_mean - luma_delta | |
delta > luma_mean + luma_delta ) {
switch ( sd - > sensor ) {
2010-04-02 07:08:39 -03:00
case SENSOR_GC0307 :
expotimes = sd - > exposure ;
expotimes + = ( luma_mean - delta ) > > 6 ;
if ( expotimes < 0 )
expotimes = 0 ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev ,
2010-04-02 07:08:39 -03:00
( unsigned int ) expotimes ) ;
break ;
2008-06-30 15:50:11 -03:00
case SENSOR_HV7131R :
expotimes = sd - > exposure > > 8 ;
expotimes + = ( luma_mean - delta ) > > 4 ;
if ( expotimes < 0 )
expotimes = 0 ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev ,
2008-06-30 15:50:11 -03:00
( unsigned int ) ( expotimes < < 8 ) ) ;
break ;
2009-10-17 07:21:29 -03:00
case SENSOR_OM6802 :
2011-02-10 07:49:32 -03:00
case SENSOR_MT9V111 :
2009-10-17 07:21:29 -03:00
expotimes = sd - > exposure ;
expotimes + = ( luma_mean - delta ) > > 2 ;
if ( expotimes < 0 )
expotimes = 0 ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev ,
2009-10-17 07:21:29 -03:00
( unsigned int ) expotimes ) ;
setredblue ( gspca_dev ) ;
break ;
2008-08-03 07:52:53 -03:00
default :
/* case SENSOR_MO4000: */
/* case SENSOR_MI0360: */
2010-10-01 07:51:24 -03:00
/* case SENSOR_MI0360B: */
2008-06-30 15:50:11 -03:00
expotimes = sd - > exposure ;
expotimes + = ( luma_mean - delta ) > > 6 ;
if ( expotimes < 0 )
expotimes = 0 ;
2012-02-27 06:57:04 -03:00
sd - > exposure = expo_adjust ( gspca_dev ,
2008-06-30 15:50:11 -03:00
( unsigned int ) expotimes ) ;
2008-11-26 04:46:15 -03:00
setredblue ( gspca_dev ) ;
2008-06-30 15:50:11 -03:00
break ;
}
}
}
2011-02-10 07:01:30 -03:00
/* set the average luminosity from an isoc marker */
static void set_lum ( struct sd * sd ,
u8 * data )
{
int avg_lum ;
/* w0 w1 w2
* w3 w4 w5
* w6 w7 w8
*/
avg_lum = ( data [ 27 ] < < 8 ) + data [ 28 ] /* w3 */
+ ( data [ 31 ] < < 8 ) + data [ 32 ] /* w5 */
+ ( data [ 23 ] < < 8 ) + data [ 24 ] /* w1 */
+ ( data [ 35 ] < < 8 ) + data [ 36 ] /* w7 */
+ ( data [ 29 ] < < 10 ) + ( data [ 30 ] < < 2 ) ; /* w4 * 4 */
avg_lum > > = 10 ;
atomic_set ( & sd - > avg_lum , avg_lum ) ;
}
2008-08-03 07:52:53 -03:00
/* scan the URB packets */
/* This function is run at interrupt level. */
2008-06-30 15:50:11 -03:00
static void sd_pkt_scan ( struct gspca_dev * gspca_dev ,
2009-01-19 07:37:33 -03:00
u8 * data , /* isoc packet */
2008-06-30 15:50:11 -03:00
int len ) /* iso packet length */
{
struct sd * sd = ( struct sd * ) gspca_dev ;
2011-02-10 07:38:58 -03:00
int i , new_qual ;
2011-02-10 07:15:24 -03:00
/*
* A frame ends on the marker
* ff ff 00 c4 c4 96 . .
* which is 62 bytes long and is followed by various information
* including statuses and luminosity .
*
* A marker may be splitted on two packets .
*
* The 6 th byte of a marker contains the bits :
* 0x08 : USB full
* 0xc0 : frame sequence
* When the bit ' USB full ' is set , the frame must be discarded ;
* this is also the case when the 2 bytes before the marker are
* not the JPEG end of frame ( ' ff d9 ' ) .
*/
/*fixme: assumption about the following code:
* - there can be only one marker in a packet
*/
/* skip the remaining bytes of a short marker */
i = sd - > short_mark ;
if ( i ! = 0 ) {
sd - > short_mark = 0 ;
if ( i < 0 /* if 'ff' at end of previous packet */
& & data [ 0 ] = = 0xff
& & data [ 1 ] = = 0x00 )
goto marker_found ;
if ( data [ 0 ] = = 0xff & & data [ 1 ] = = 0xff ) {
i = 0 ;
goto marker_found ;
}
len - = i ;
if ( len < = 0 )
return ;
data + = i ;
}
2011-02-10 07:38:58 -03:00
/* count the packets and their size */
sd - > npkt + + ;
sd - > pktsz + = len ;
2011-02-10 07:15:24 -03:00
/* search backwards if there is a marker in the packet */
for ( i = len - 1 ; - - i > = 0 ; ) {
if ( data [ i ] ! = 0xff ) {
i - - ;
continue ;
}
if ( data [ i + 1 ] = = 0xff ) {
/* (there may be 'ff ff' inside a marker) */
if ( i + 2 > = len | | data [ i + 2 ] = = 0x00 )
goto marker_found ;
}
}
/* no marker found */
/* add the JPEG header if first fragment */
if ( data [ len - 1 ] = = 0xff )
sd - > short_mark = - 1 ;
if ( gspca_dev - > last_packet_type = = LAST_PACKET )
2010-10-01 07:54:30 -03:00
gspca_frame_add ( gspca_dev , FIRST_PACKET ,
sd - > jpeg_hdr , JPEG_HDR_SZ ) ;
gspca_frame_add ( gspca_dev , INTER_PACKET , data , len ) ;
2011-02-10 07:15:24 -03:00
return ;
/* marker found */
2011-02-10 07:38:58 -03:00
/* if some error, discard the frame and decrease the quality */
2011-02-10 07:15:24 -03:00
marker_found :
2011-02-10 07:38:58 -03:00
new_qual = 0 ;
2011-02-10 07:15:24 -03:00
if ( i > 2 ) {
if ( data [ i - 2 ] ! = 0xff | | data [ i - 1 ] ! = 0xd9 ) {
gspca_dev - > last_packet_type = DISCARD_PACKET ;
2011-02-10 07:38:58 -03:00
new_qual = - 3 ;
2011-02-10 07:15:24 -03:00
}
} else if ( i + 6 < len ) {
if ( data [ i + 6 ] & 0x08 ) {
gspca_dev - > last_packet_type = DISCARD_PACKET ;
2011-02-10 07:38:58 -03:00
new_qual = - 5 ;
2011-02-10 07:15:24 -03:00
}
}
2010-10-01 07:54:30 -03:00
2011-02-10 07:15:24 -03:00
gspca_frame_add ( gspca_dev , LAST_PACKET , data , i ) ;
2011-02-10 07:38:58 -03:00
/* compute the filling rate and a new JPEG quality */
if ( new_qual = = 0 ) {
int r ;
r = ( sd - > pktsz * 100 ) /
( sd - > npkt *
gspca_dev - > urb [ 0 ] - > iso_frame_desc [ 0 ] . length ) ;
if ( r > = 85 )
new_qual = - 3 ;
else if ( r < 75 )
new_qual = 2 ;
}
if ( new_qual ! = 0 ) {
sd - > nchg + = new_qual ;
if ( sd - > nchg < - 6 | | sd - > nchg > = 12 ) {
sd - > nchg = 0 ;
new_qual + = sd - > quality ;
if ( new_qual < QUALITY_MIN )
new_qual = QUALITY_MIN ;
else if ( new_qual > QUALITY_MAX )
new_qual = QUALITY_MAX ;
if ( new_qual ! = sd - > quality ) {
sd - > quality = new_qual ;
queue_work ( sd - > work_thread , & sd - > work ) ;
}
}
} else {
sd - > nchg = 0 ;
}
sd - > pktsz = sd - > npkt = 0 ;
2011-02-10 07:15:24 -03:00
/* if the marker is smaller than 62 bytes,
* memorize the number of bytes to skip in the next packet */
if ( i + 62 > len ) { /* no more usable data */
sd - > short_mark = i + 62 - len ;
2010-10-01 07:54:30 -03:00
return ;
2011-02-10 07:15:24 -03:00
}
2011-02-10 07:01:30 -03:00
if ( sd - > ag_cnt > = 0 )
2011-02-10 07:15:24 -03:00
set_lum ( sd , data + i ) ;
/* if more data, start a new frame */
i + = 62 ;
if ( i < len ) {
data + = i ;
len - = i ;
gspca_frame_add ( gspca_dev , FIRST_PACKET ,
sd - > jpeg_hdr , JPEG_HDR_SZ ) ;
gspca_frame_add ( gspca_dev , INTER_PACKET , data , len ) ;
}
2008-06-30 15:50:11 -03:00
}
2012-02-27 06:57:04 -03:00
static int sd_setautogain ( struct gspca_dev * gspca_dev , __s32 val )
{
struct sd * sd = ( struct sd * ) gspca_dev ;
sd - > ctrls [ AUTOGAIN ] . val = val ;
if ( val )
gspca_dev - > ctrl_inac | = ( 1 < < EXPOSURE ) | ( 1 < < GAIN ) ;
else
gspca_dev - > ctrl_inac & = ~ ( 1 < < EXPOSURE ) & ~ ( 1 < < GAIN ) ;
if ( gspca_dev - > streaming )
setautogain ( gspca_dev ) ;
return gspca_dev - > usb_err ;
}
2009-06-18 07:35:36 -03:00
static int sd_querymenu ( struct gspca_dev * gspca_dev ,
struct v4l2_querymenu * menu )
{
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 ;
case 2 : /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
strcpy ( ( char * ) menu - > name , " 60 Hz " ) ;
return 0 ;
}
break ;
}
return - EINVAL ;
}
2010-10-01 07:33:26 -03:00
# if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2010-01-31 12:54:29 -03:00
static int sd_int_pkt_scan ( struct gspca_dev * gspca_dev ,
u8 * data , /* interrupt packet data */
int len ) /* interrupt packet length */
{
int ret = - EINVAL ;
if ( len = = 1 & & data [ 0 ] = = 1 ) {
input_report_key ( gspca_dev - > input_dev , KEY_CAMERA , 1 ) ;
input_sync ( gspca_dev - > input_dev ) ;
input_report_key ( gspca_dev - > input_dev , KEY_CAMERA , 0 ) ;
input_sync ( gspca_dev - > input_dev ) ;
ret = 0 ;
}
return ret ;
}
# endif
2008-06-30 15:50:11 -03:00
/* sub-driver description */
2008-07-04 11:16:16 -03:00
static const struct sd_desc sd_desc = {
2008-06-30 15:50:11 -03:00
. name = MODULE_NAME ,
. ctrls = sd_ctrls ,
2010-10-02 04:35:25 -03:00
. nctrls = NCTRLS ,
2008-06-30 15:50:11 -03:00
. config = sd_config ,
2008-09-03 17:12:16 -03:00
. init = sd_init ,
2008-06-30 15:50:11 -03:00
. start = sd_start ,
. stopN = sd_stopN ,
2011-02-10 07:38:58 -03:00
. stop0 = sd_stop0 ,
2008-06-30 15:50:11 -03:00
. pkt_scan = sd_pkt_scan ,
2008-08-03 07:52:53 -03:00
. dq_callback = do_autogain ,
2009-06-18 07:35:36 -03:00
. querymenu = sd_querymenu ,
2010-10-01 07:33:26 -03:00
# if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2010-01-31 12:54:29 -03:00
. int_pkt_scan = sd_int_pkt_scan ,
# endif
2008-06-30 15:50:11 -03:00
} ;
/* -- module initialisation -- */
2009-11-07 06:10:08 -03:00
# define BS(bridge, sensor) \
2008-07-25 08:53:03 -03:00
. driver_info = ( BRIDGE_ # # bridge < < 16 ) \
2010-12-14 16:15:37 -03:00
| ( SENSOR_ # # sensor < < 8 )
# define BSF(bridge, sensor, flags) \
. driver_info = ( BRIDGE_ # # bridge < < 16 ) \
| ( SENSOR_ # # sensor < < 8 ) \
| ( flags )
2011-01-13 05:20:29 -03:00
static const struct usb_device_id device_table [ ] = {
2009-11-07 06:10:08 -03:00
{ USB_DEVICE ( 0x0458 , 0x7025 ) , BS ( SN9C120 , MI0360 ) } ,
{ USB_DEVICE ( 0x0458 , 0x702e ) , BS ( SN9C120 , OV7660 ) } ,
2011-01-13 06:39:11 -03:00
{ USB_DEVICE ( 0x045e , 0x00f5 ) , BSF ( SN9C105 , OV7660 , F_PDN_INV ) } ,
{ USB_DEVICE ( 0x045e , 0x00f7 ) , BSF ( SN9C105 , OV7660 , F_PDN_INV ) } ,
2009-11-07 06:10:08 -03:00
{ USB_DEVICE ( 0x0471 , 0x0327 ) , BS ( SN9C105 , MI0360 ) } ,
{ USB_DEVICE ( 0x0471 , 0x0328 ) , BS ( SN9C105 , MI0360 ) } ,
{ USB_DEVICE ( 0x0471 , 0x0330 ) , BS ( SN9C105 , MI0360 ) } ,
{ USB_DEVICE ( 0x06f8 , 0x3004 ) , BS ( SN9C105 , OV7660 ) } ,
{ USB_DEVICE ( 0x06f8 , 0x3008 ) , BS ( SN9C105 , OV7660 ) } ,
/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
{ USB_DEVICE ( 0x0c45 , 0x6040 ) , BS ( SN9C102P , HV7131R ) } ,
/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
{ USB_DEVICE ( 0x0c45 , 0x607c ) , BS ( SN9C102P , HV7131R ) } ,
/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
2011-01-13 06:39:11 -03:00
{ USB_DEVICE ( 0x0c45 , 0x60c0 ) , BSF ( SN9C105 , MI0360 , F_ILLUM ) } ,
2010-10-01 07:51:24 -03:00
/* or MT9V111 */
2009-11-07 06:10:08 -03:00
/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
2010-05-07 15:40:04 -03:00
{ USB_DEVICE ( 0x0c45 , 0x60ce ) , BS ( SN9C105 , SP80708 ) } ,
2009-11-07 06:10:08 -03:00
{ USB_DEVICE ( 0x0c45 , 0x60ec ) , BS ( SN9C105 , MO4000 ) } ,
/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
2010-05-07 15:35:08 -03:00
/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
2009-11-07 06:10:08 -03:00
{ USB_DEVICE ( 0x0c45 , 0x60fb ) , BS ( SN9C105 , OV7660 ) } ,
{ USB_DEVICE ( 0x0c45 , 0x60fc ) , BS ( SN9C105 , HV7131R ) } ,
{ USB_DEVICE ( 0x0c45 , 0x60fe ) , BS ( SN9C105 , OV7630 ) } ,
{ USB_DEVICE ( 0x0c45 , 0x6100 ) , BS ( SN9C120 , MI0360 ) } , /*sn9c128*/
2010-09-13 06:40:17 -03:00
{ USB_DEVICE ( 0x0c45 , 0x6102 ) , BS ( SN9C120 , PO2030N ) } , /* /GC0305*/
2009-11-07 06:10:08 -03:00
/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
{ USB_DEVICE ( 0x0c45 , 0x610a ) , BS ( SN9C120 , OV7648 ) } , /*sn9c128*/
{ USB_DEVICE ( 0x0c45 , 0x610b ) , BS ( SN9C120 , OV7660 ) } , /*sn9c128*/
{ USB_DEVICE ( 0x0c45 , 0x610c ) , BS ( SN9C120 , HV7131R ) } , /*sn9c128*/
{ USB_DEVICE ( 0x0c45 , 0x610e ) , BS ( SN9C120 , OV7630 ) } , /*sn9c128*/
/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
{ USB_DEVICE ( 0x0c45 , 0x6128 ) , BS ( SN9C120 , OM6802 ) } , /*sn9c325?*/
2008-09-03 16:47:23 -03:00
/*bw600.inf:*/
2009-11-23 06:46:35 -03:00
{ USB_DEVICE ( 0x0c45 , 0x612a ) , BS ( SN9C120 , OV7648 ) } , /*sn9c325?*/
2010-09-13 06:58:16 -03:00
{ USB_DEVICE ( 0x0c45 , 0x612b ) , BS ( SN9C110 , ADCM1700 ) } ,
2009-11-07 06:10:08 -03:00
{ USB_DEVICE ( 0x0c45 , 0x612c ) , BS ( SN9C110 , MO4000 ) } ,
{ USB_DEVICE ( 0x0c45 , 0x612e ) , BS ( SN9C110 , OV7630 ) } ,
/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
{ USB_DEVICE ( 0x0c45 , 0x6130 ) , BS ( SN9C120 , MI0360 ) } ,
2010-10-01 07:51:24 -03:00
/* or MT9V111 / MI0360B */
2009-11-07 06:10:08 -03:00
/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
{ USB_DEVICE ( 0x0c45 , 0x6138 ) , BS ( SN9C120 , MO4000 ) } ,
{ USB_DEVICE ( 0x0c45 , 0x613a ) , BS ( SN9C120 , OV7648 ) } ,
{ USB_DEVICE ( 0x0c45 , 0x613b ) , BS ( SN9C120 , OV7660 ) } ,
{ USB_DEVICE ( 0x0c45 , 0x613c ) , BS ( SN9C120 , HV7131R ) } ,
{ USB_DEVICE ( 0x0c45 , 0x613e ) , BS ( SN9C120 , OV7630 ) } ,
2010-03-18 05:15:30 -03:00
{ USB_DEVICE ( 0x0c45 , 0x6142 ) , BS ( SN9C120 , PO2030N ) } , /*sn9c120b*/
2010-05-07 15:35:08 -03:00
/* or GC0305 / GC0307 */
2009-11-07 06:10:08 -03:00
{ USB_DEVICE ( 0x0c45 , 0x6143 ) , BS ( SN9C120 , SP80708 ) } , /*sn9c120b*/
{ USB_DEVICE ( 0x0c45 , 0x6148 ) , BS ( SN9C120 , OM6802 ) } , /*sn9c120b*/
2011-01-13 07:56:00 -03:00
{ USB_DEVICE ( 0x0c45 , 0x614a ) , BSF ( SN9C120 , ADCM1700 , F_ILLUM ) } ,
2011-01-06 16:21:57 -03:00
/* {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */ /*sn9c120b*/
2008-06-30 15:50:11 -03: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 ,
2008-09-03 16:48:10 -03:00
# ifdef CONFIG_PM
. suspend = gspca_suspend ,
. resume = gspca_resume ,
# endif
2008-06-30 15:50:11 -03:00
} ;
2011-11-18 09:46:12 -08:00
module_usb_driver ( sd_driver ) ;