www.pudn.com > spca5xx-.rar > et61xx51.h
/***************************************************************************
# Etoms Et61x151 GPL Linux driver by Michel Xhaard (09/09/2004)
# This driver is design for embedded Linux hardware but should work happy
# on Linux host computer
# Etoms compagnies did not provided any help and support
# The Linux driver is made by reverse engeneering the usb protocol.
# 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 #
# (at your option) 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 #
# #
****************************************************************************/
#ifndef ET61XX51_H
#define ET61XX51_H
#define ETOMS_ALT_SIZE_1000 12
#define ET_GPIO_DIR_CTRL 0x04 //Control IO bit[0..5] (0 in 1 out)
#define ET_GPIO_OUT 0x05 // Only IO data
#define ET_GPIO_IN 0x06 //Read Only IO data
#define ET_RESET_ALL 0x03
#define ET_ClCK 0x01
#define ET_CTRL 0x02 //enable i2c OutClck Powerdown mode
#define ET_COMP 0x12 //Compression register
#define ET_MAXQt 0x13
#define ET_MINQt 0x14
#define ET_COMP_VAL0 0x02
#define ET_COMP_VAL1 0x03
#define ET_REG1d 0x1d
#define ET_REG1e 0x1e
#define ET_REG1f 0x1f
#define ET_REG20 0x20
#define ET_REG21 0x21
#define ET_REG22 0x22
#define ET_REG23 0x23
#define ET_REG24 0x24
#define ET_REG25 0x25
// base registers for luma calculation
#define ET_LUMA_CENTER 0x39
#define ET_G_RED 0x4d
#define ET_G_GREEN1 0x4e
#define ET_G_BLUE 0x4f
#define ET_G_GREEN2 0x50
#define ET_G_GR_H 0x51
#define ET_G_GB_H 0x52
#define ET_O_RED 0x34
#define ET_O_GREEN1 0x35
#define ET_O_BLUE 0x36
#define ET_O_GREEN2 0x37
#define ET_SYNCHRO 0x68
#define ET_STARTX 0x69
#define ET_STARTY 0x6a
#define ET_WIDTH_LOW 0x6b
#define ET_HEIGTH_LOW 0x6c
#define ET_W_H_HEIGTH 0x6d
#define ET_REG6e 0x6e //OBW
#define ET_REG6f 0x6f //OBW
#define ET_REG70 0x70 //OBW_AWB
#define ET_REG71 0x71 //OBW_AWB
#define ET_REG72 0x72 //OBW_AWB
#define ET_REG73 0x73 //Clkdelay ns
#define ET_REG74 0x74 // test pattern
#define ET_REG75 0x75 // test pattern
#define ET_I2C_CLK 0x8c
#define ET_PXL_CLK 0x60
#define ET_I2C_BASE 0x89
#define ET_I2C_COUNT 0x8a
#define ET_I2C_PREFETCH 0x8b
#define ET_I2C_REG 0x88
#define ET_I2C_DATA7 0x87
#define ET_I2C_DATA6 0x86
#define ET_I2C_DATA5 0x85
#define ET_I2C_DATA4 0x84
#define ET_I2C_DATA3 0x83
#define ET_I2C_DATA2 0x82
#define ET_I2C_DATA1 0x81
#define ET_I2C_DATA0 0x80
#define PAS106_REG2 0x02 //pxlClk = systemClk/(reg2)
#define PAS106_REG3 0x03 //line/frame H [11..4]
#define PAS106_REG4 0x04 //line/frame L [3..0]
#define PAS106_REG5 0x05 //exposure time line offset(default 5)
#define PAS106_REG6 0x06 //exposure time pixel offset(default 6)
#define PAS106_REG7 0x07 //signbit Dac (default 0)
#define PAS106_REG9 0x09
#define PAS106_REG0e 0x0e //global gain [4..0](default 0x0e)
#define PAS106_REG13 0x13 //end i2c write
static __u8 GainRGBG [] ={0x80,0x80,0x80,0x80,0x00,0x00};
static __u8 I2c2 [] ={0x08,0x08,0x08,0x08,0x0d};
static __u8 I2c3 [] ={0x12,0x05};
static __u8 I2c4 [] ={0x41,0x08};
/***************************************************************************/
/******************* Camera Interface ***********************/
static int Et_init (struct usb_spca50x *etx);
static void Et_startCamera(struct usb_spca50x *etx);
static void Et_stopCamera(struct usb_spca50x *etx);
static __u16 Et_setbrightness(struct usb_spca50x *etx);
static __u16 Et_getbrightness(struct usb_spca50x *etx);
static __u16 Et_setcontrast(struct usb_spca50x *etx);
static __u16 Et_getcontrast(struct usb_spca50x *etx);
static __u16 Et_setcolors(struct usb_spca50x *etx);
static __u16 Et_getcolors(struct usb_spca50x *etx);
static void Et_setAutobright (struct usb_spca50x *etx);
static int Etxx_config(struct usb_spca50x *spca50x );
/******************* Camera private ******************************/
static __u8 Et_getgainG (struct usb_spca50x *etx);
static void Et_setgainG (struct usb_spca50x *etx, __u8 gain);
static int Et_i2cwrite(struct usb_device *dev,__u8 reg,__u8 *buffer,__u16 length,__u8 mode);
static int Et_i2cread(struct usb_device *dev,__u8 reg,__u8 *buffer,__u16 length,__u8 mode);
static int Et_WaitStatus(struct usb_device *dev);
static int Et_videoOff (struct usb_device *dev);
static int Et_videoOn (struct usb_device *dev);
static void Et_init1 (struct usb_spca50x *etx);
/***************************************************************************/
static int Et_i2cwrite(struct usb_device *dev,__u8 reg,__u8 *buffer,__u16 length,__u8 mode)
{
/* buffer should be [D0..D7] */
int i,j;
__u8 base = 0x40; // sensor base for the pas106
__u8 ptchcount = 0;
ptchcount =(((length & 0x07)<<4) | (mode & 0x03));
/* set the base address */
Et_RegWrite(dev,0x0,0x0,ET_I2C_BASE,&base,1);
/* set count and prefetch */
Et_RegWrite(dev,0x0,0x0,ET_I2C_COUNT,&ptchcount,1);
/* set the register base */
Et_RegWrite(dev,0x0,0x0,ET_I2C_REG,®,1);
j = length-1;
for (i = 0; i < length;i++){
Et_RegWrite(dev,0x0,0x0,(ET_I2C_DATA0+j),&buffer[j],1);
j--;
}
return 0;
}
static int Et_i2cread(struct usb_device *dev,__u8 reg,__u8 *buffer,__u16 length,__u8 mode)
{
/* buffer should be [D0..D7] */
int i,j;
__u8 base = 0x40; // sensor base for the pas106
__u8 ptchcount = 0;
__u8 prefetch = 0x02;
ptchcount =(((length & 0x07)<<4) | (mode & 0x03));
/* set the base address */
Et_RegWrite(dev,0x0,0x0,ET_I2C_BASE,&base,1);
/* set count and prefetch */
Et_RegWrite(dev,0x0,0x0,ET_I2C_COUNT,&ptchcount,1);
/* set the register base */
Et_RegWrite(dev,0x0,0x0,ET_I2C_REG,®,1);
Et_RegWrite(dev,0x0,0x0,ET_I2C_PREFETCH,&prefetch,1);
prefetch = 0x00;
Et_RegWrite(dev,0x0,0x0,ET_I2C_PREFETCH,&prefetch,1);
j = length-1;
for (i = 0; i < length;i++){
Et_RegRead(dev,0x0,0x0,(ET_I2C_DATA0+j),&buffer[j],1);
j--;
}
return 0;
}
static int Et_WaitStatus(struct usb_device *dev)
{
__u8 bytereceived =0;
int retry =10;
while (retry--){
Et_RegRead(dev,0x0,0x0,ET_ClCK,&bytereceived,1);
if (bytereceived != 0) return 1;
}
return 0;
}
static int Et_videoOff (struct usb_device *dev)
{
int err = -1;
__u8 stopvideo =0;
Et_RegWrite(dev,0x0,0x0,ET_GPIO_OUT,&stopvideo,1);
err =Et_WaitStatus(dev);
if(!err) PDEBUG(5,"timeout Et_waitStatus VideoON");
return err;
}
static int Et_videoOn (struct usb_device *dev)
{
int err = -1;
__u8 startvideo =0x10; //set Bit5
Et_RegWrite(dev,0x0,0x0,ET_GPIO_OUT,&startvideo,1);
err =Et_WaitStatus(dev);
if(!err) PDEBUG(5,"timeout Et_waitStatus VideoOFF");
return err;
}
static void Et_init2 (struct usb_spca50x *etx)
{
__u8 value = 0x00;
__u8 received = 0x00;
__u8 FormLine[] ={0x84,0x03,0x14,0xf4,0x01,0x05};
PDEBUG(5,"Open Init2 ET");
value = 0x2f;
Et_RegWrite(etx->dev,0x0,0x0,ET_GPIO_DIR_CTRL,&value,1);
value = 0x10;
Et_RegWrite(etx->dev,0x0,0x0,ET_GPIO_OUT,&value,1);
Et_RegRead(etx->dev,0x0,0x0,ET_GPIO_IN,&received,1);
value = 0x14; //0x14 // 0x16 enabled pattern
Et_RegWrite(etx->dev,0x0,0x0,ET_ClCK,&value,1);
value = 0x1b;
Et_RegWrite(etx->dev,0x0,0x0,ET_CTRL,&value,1);
/* compression et subsampling */
if (etx->mode){
value = ET_COMP_VAL1; // 320
} else {
value = ET_COMP_VAL0; // 640
}
Et_RegWrite(etx->dev,0x0,0x0,ET_COMP,&value,1);
value = 0x1f;
Et_RegWrite(etx->dev,0x0,0x0,ET_MAXQt,&value,1);
value = 0x04;
Et_RegWrite(etx->dev,0x0,0x0,ET_MINQt,&value,1);
/* undocumented registers */
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG1d,&value,1);
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG1e,&value,1);
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG1f,&value,1);
value = 0x35;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG20,&value,1);
value = 0x01;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG21,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG22,&value,1);
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG23,&value,1);
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG24,&value,1);
value = 0x0f;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG25,&value,1);
/* colors setting */
value = 0x11;
Et_RegWrite(etx->dev,0x0,0x0,0x30,&value,1); //0x30
value = 0x40;
Et_RegWrite(etx->dev,0x0,0x0,0x31,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,0x32,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_O_RED,&value,1); //0x34
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0, ET_O_GREEN1,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_O_BLUE,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_O_GREEN2,&value,1);
/*************/
value = 0x80;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_RED,&value,1); //0x4d
value = 0x80;
Et_RegWrite(etx->dev,0x0,0x0, ET_G_GREEN1,&value,1);
value = 0x80;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_BLUE,&value,1);
value = 0x80;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_GREEN2,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_GR_H,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_GB_H,&value,1); //0x52
/* Window control registers */
value = 0x80; /* use cmc_out */
Et_RegWrite(etx->dev,0x0,0x0,0x61,&value,1);
value = 0x02;
Et_RegWrite(etx->dev,0x0,0x0,0x62,&value,1);
value = 0x03;
Et_RegWrite(etx->dev,0x0,0x0,0x63,&value,1);
value = 0x14;
Et_RegWrite(etx->dev,0x0,0x0,0x64,&value,1);
value = 0x0e;
Et_RegWrite(etx->dev,0x0,0x0,0x65,&value,1);
value = 0x02;
Et_RegWrite(etx->dev,0x0,0x0,0x66,&value,1);
value = 0x02;
Et_RegWrite(etx->dev,0x0,0x0,0x67,&value,1);
/**************************************/
value = 0x8f;
Et_RegWrite(etx->dev,0x0,0x0,ET_SYNCHRO,&value,1); //0x68
value = 0x69; //0x6a //0x69
Et_RegWrite(etx->dev,0x0,0x0,ET_STARTX,&value,1);
value = 0x0d; //0x0d //0x0c
Et_RegWrite(etx->dev,0x0,0x0,ET_STARTY,&value,1);
value = 0x80;
Et_RegWrite(etx->dev,0x0,0x0,ET_WIDTH_LOW,&value,1);
value = 0xe0;
Et_RegWrite(etx->dev,0x0,0x0,ET_HEIGTH_LOW,&value,1);
value = 0x60;
Et_RegWrite(etx->dev,0x0,0x0,ET_W_H_HEIGTH,&value,1); //6d
value = 0x86;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG6e,&value,1);
value = 0x01;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG6f,&value,1);
value = 0x26;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG70,&value,1);
value = 0x7a;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG71,&value,1);
value = 0x01;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG72,&value,1);
/* Clock Pattern registers ***************** */
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG73,&value,1);
value = 0x18; //0x28
Et_RegWrite(etx->dev,0x0,0x0,ET_REG74,&value,1);
value = 0x0f;// 0x01
Et_RegWrite(etx->dev,0x0,0x0,ET_REG75,&value,1);
/**********************************************/
value = 0x20;
Et_RegWrite(etx->dev,0x0,0x0,0x8a,&value,1);
value = 0x0f;
Et_RegWrite(etx->dev,0x0,0x0,0x8d,&value,1);
value = 0x08;
Et_RegWrite(etx->dev,0x0,0x0,0x8e,&value,1);
/**************************************/
value = 0x08;
Et_RegWrite(etx->dev,0x0,0x0,0x03,&value,1);
value = 0x03;
Et_RegWrite(etx->dev,0x0,0x0,ET_PXL_CLK,&value,1);
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,0x81,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,0x80,&value,1);
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,0x81,&value,1);
value = 0x20;
Et_RegWrite(etx->dev,0x0,0x0,0x80,&value,1);
value = 0x01;
Et_RegWrite(etx->dev,0x0,0x0,0x03,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,0x03,&value,1);
value = 0x08;
Et_RegWrite(etx->dev,0x0,0x0,0x03,&value,1);
/********************************************/
// Et_RegRead(etx->dev,0x0,0x0,ET_I2C_BASE,&received,1); always 0x40 as the pas106 ???
/* set the sensor */
if (etx->mode){ /* 320*/
value = 0x04;
Et_RegWrite(etx->dev,0x0,0x0,ET_PXL_CLK,&value,1);
/* now set by fifo the FormatLine setting */
Et_RegWrite(etx->dev,0x0,0x0,0x62,FormLine,6);
} else { /* 640 */
/* setting PixelClock
0x03 mean 24/(3+1) = 6 Mhz
0x05 -> 24/(5+1) = 4 Mhz
0x0b -> 24/(11+1) = 2 Mhz
0x17 -> 24/(23+1) = 1 Mhz
*/
value = 0x1e; //0x17
Et_RegWrite(etx->dev,0x0,0x0,ET_PXL_CLK,&value,1);
/* now set by fifo the FormatLine setting */
Et_RegWrite(etx->dev,0x0,0x0,0x62,FormLine,6);
}
value = 0x47; // 0x47;
Et_RegWrite(etx->dev,0x0,0x0,0x81,&value,1); // set exposure times [ 0..0x78] 0->longvalue 0x78->shortvalue
value = 0x40; // 0x40;
Et_RegWrite(etx->dev,0x0,0x0,0x80,&value,1);
/* Pedro change */
// Brightness change Brith+ decrease value
// Brigth- increase value
// original value = 0x70;
value = 0x30; // 0x20;
Et_RegWrite(etx->dev,0x0,0x0,0x81,&value,1); // set brightness
value = 0x20; // 0x20;
Et_RegWrite(etx->dev,0x0,0x0,0x80,&value,1);
}
static void Et_init1 (struct usb_spca50x *etx)
{
__u8 value = 0x00;
__u8 received = 0x00;
//__u8 I2c0 [] ={0x0a,0x12,0x05,0x22,0xac,0x00,0x01,0x00};
__u8 I2c0 [] ={0x0a,0x12,0x05,0x6d,0xcd,0x00,0x01,0x00}; // try 1/120 0x6d 0xcd 0x40
//__u8 I2c0 [] ={0x0a,0x12,0x05,0xfe,0xfe,0xc0,0x01,0x00}; // 1/60000 hmm ??
PDEBUG(5,"Open Init1 ET");
value = 7;
Et_RegWrite(etx->dev,0x0,0x0,ET_GPIO_DIR_CTRL,&value,1);
Et_RegRead(etx->dev,0x0,0x0,ET_GPIO_IN,&received,1);
value = 1;
Et_RegWrite(etx->dev,0x0,0x0,ET_RESET_ALL,&value,1);
value = 0;
Et_RegWrite(etx->dev,0x0,0x0,ET_RESET_ALL,&value,1);
value = 0x10;
Et_RegWrite(etx->dev,0x0,0x0,ET_ClCK,&value,1);
value = 0x19;
Et_RegWrite(etx->dev,0x0,0x0,ET_CTRL,&value,1);
/* compression et subsampling */
if (etx->mode){
value = ET_COMP_VAL1;
} else {
value = ET_COMP_VAL0;
}
PDEBUG(0,"Open mode %d Compression %d",etx->mode,value);
Et_RegWrite(etx->dev,0x0,0x0,ET_COMP,&value,1);
value = 0x1d;
Et_RegWrite(etx->dev,0x0,0x0,ET_MAXQt,&value,1);
value = 0x02;
Et_RegWrite(etx->dev,0x0,0x0,ET_MINQt,&value,1);
/* undocumented registers */
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG1d,&value,1);
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG1e,&value,1);
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG1f,&value,1);
value = 0x35;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG20,&value,1);
value = 0x01;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG21,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG22,&value,1);
value = 0xf7;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG23,&value,1);
value = 0xff;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG24,&value,1);
value = 0x07;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG25,&value,1);
/* colors setting */
value = 0x80;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_RED,&value,1);
value = 0x80;
Et_RegWrite(etx->dev,0x0,0x0, ET_G_GREEN1,&value,1);
value = 0x80;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_BLUE,&value,1);
value = 0x80;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_GREEN2,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_GR_H,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_G_GB_H,&value,1);
/* Window control registers */
value = 0xf0;
Et_RegWrite(etx->dev,0x0,0x0,ET_SYNCHRO,&value,1);
value = 0x56;//0x56
Et_RegWrite(etx->dev,0x0,0x0,ET_STARTX,&value,1);
value = 0x05;//0x04
Et_RegWrite(etx->dev,0x0,0x0,ET_STARTY,&value,1);
value = 0x60;
Et_RegWrite(etx->dev,0x0,0x0,ET_WIDTH_LOW,&value,1);
value = 0x20;
Et_RegWrite(etx->dev,0x0,0x0,ET_HEIGTH_LOW,&value,1);
value = 0x50;
Et_RegWrite(etx->dev,0x0,0x0,ET_W_H_HEIGTH,&value,1);
value = 0x86;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG6e,&value,1);
value = 0x01;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG6f,&value,1);
value = 0x86;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG70,&value,1);
value = 0x14;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG71,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG72,&value,1);
/* Clock Pattern registers */
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG73,&value,1);
value = 0x00;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG74,&value,1);
value = 0x0a;
Et_RegWrite(etx->dev,0x0,0x0,ET_REG75,&value,1);
value = 0x04;
Et_RegWrite(etx->dev,0x0,0x0,ET_I2C_CLK,&value,1);
value = 0x01;
Et_RegWrite(etx->dev,0x0,0x0,ET_PXL_CLK,&value,1);
/* set the sensor */
if (etx->mode){
I2c0[0] = 0x06;
Et_i2cwrite(etx->dev,PAS106_REG2,I2c0,sizeof(I2c0),1);
Et_i2cwrite(etx->dev,PAS106_REG9,I2c2,sizeof(I2c2),1);
value = 0x06;
Et_i2cwrite(etx->dev,PAS106_REG2,&value,1,1);
Et_i2cwrite(etx->dev,PAS106_REG3,I2c3,sizeof(I2c3),1);
//value = 0x1f;
value = 0x04;
Et_i2cwrite(etx->dev,PAS106_REG0e,&value,1,1);
} else {
I2c0[0] = 0x0a;
Et_i2cwrite(etx->dev,PAS106_REG2,I2c0,sizeof(I2c0),1);
Et_i2cwrite(etx->dev,PAS106_REG9,I2c2,sizeof(I2c2),1);
value = 0x0a;
Et_i2cwrite(etx->dev,PAS106_REG2,&value,1,1);
Et_i2cwrite(etx->dev,PAS106_REG3,I2c3,sizeof(I2c3),1);
value = 0x04;
//value = 0x10;
Et_i2cwrite(etx->dev,PAS106_REG0e,&value,1,1);
/* bit 2 enable bit 1:2 select 0 1 2 3
value = 0x07;// curve 0
Et_i2cwrite(etx->dev,PAS106_REG0f,&value,1,1);
*/
}
//value = 0x01;
//value = 0x22;
//Et_i2cwrite(etx->dev,PAS106_REG5,&value,1,1);
/* magnetude and sign bit for DAC */
Et_i2cwrite(etx->dev,PAS106_REG7,I2c4,sizeof(I2c4),1);
/* now set by fifo the whole colors setting */
Et_RegWrite(etx->dev,0x0,0x0,ET_G_RED,GainRGBG,6);
etx->colour= Et_getcolors(etx);
Et_setcolors(etx);
}
static int Et_init (struct usb_spca50x *etx)
{
int err = -1;
__u8 value = 0x00;
PDEBUG(5,"Initialize ET1");
if(etx->desc == Etoms61x151) {
Et_init1(etx);
} else {
Et_init2(etx);
}
value = 0x08;
Et_RegWrite(etx->dev,0x0,0x0,ET_RESET_ALL,&value,1);
err = Et_videoOff(etx->dev);
PDEBUG(5,"Et_Init_VideoOff %d",err);
return 0;
}
static void Et_startCamera(struct usb_spca50x *etx)
{
int err = -1;
__u8 value = 0x00;
if(etx->desc == Etoms61x151) {
Et_init1(etx);
} else {
Et_init2(etx);
}
value = 0x08;
Et_RegWrite(etx->dev,0x0,0x0,ET_RESET_ALL,&value,1);
err=Et_videoOn(etx->dev);
PDEBUG(5,"Et_VideoOn %d",err);
}
static void Et_stopCamera(struct usb_spca50x *etx)
{
int err = -1;
err = Et_videoOff(etx->dev);
PDEBUG(5,"Et_VideoOff %d",err);
}
static __u16 Et_setbrightness(struct usb_spca50x *etx)
{ int i;
__u8 brightness = etx->brightness >> 9;
for (i=0;i<4;i++){
Et_RegWrite(etx->dev,0x0,0x0,(ET_O_RED +i),&brightness,1);
}
return 0;
}
static __u16 Et_getbrightness(struct usb_spca50x *etx)
{
int i;
int brightness = 0;
__u8 value = 0;
for(i=0;i<4;i++){
Et_RegRead(etx->dev,0x0,0x0,(ET_O_RED+i),&value,1);
brightness += value;
}
return (brightness << 6);
}
static __u16 Et_setcontrast(struct usb_spca50x *etx)
{ __u8 RGBG [] ={0x80,0x80,0x80,0x80,0x00,0x00};
__u8 contrast = etx->contrast >> 8;
memset(RGBG,contrast,sizeof(RGBG)-2);
Et_RegWrite(etx->dev,0x0,0x0,ET_G_RED,RGBG,6);
return 0;
}
static __u16 Et_getcontrast(struct usb_spca50x *etx)
{
int i;
int contrast = 0;
__u8 value = 0;
for(i=0;i<4;i++){
Et_RegRead(etx->dev,0x0,0x0,(ET_G_RED+i),&value,1);
contrast += value;
}
return (contrast << 6);
}
static __u8 Et_getgainG (struct usb_spca50x *etx)
{
__u8 value = 0;
if(etx->sensor == SENSOR_PAS106){
Et_i2cread(etx->dev,PAS106_REG0e,&value,1,1);
PDEBUG(5 , "Etoms gain G %d",value);
return value;
} else {
return 0x1f;
}
}
static void Et_setgainG (struct usb_spca50x *etx, __u8 gain)
{
__u8 i2cflags = 0x01;
if(etx->sensor == SENSOR_PAS106){
Et_i2cwrite(etx->dev,PAS106_REG13,&i2cflags,1,3);
Et_i2cwrite(etx->dev,PAS106_REG0e,&gain,1,1);
#if 0
Et_i2cwrite(etx->dev,0x09,&gain,1,1);
Et_i2cwrite(etx->dev,0x0a,&gain,1,1);
Et_i2cwrite(etx->dev,0x0b,&gain,1,1);
Et_i2cwrite(etx->dev,0x0c,&gain,1,1);
#endif
}
}
#define BLIMIT(bright) (__u8)((bright>0x1F)?0x1f:((bright<4)?3:bright))
#define LIMIT(color) (unsigned char)((color>0xFF)?0xff:((color<0)?0:color))
static void Et_setAutobright (struct usb_spca50x *etx)
{
__u8 GRBG[] = {0,0,0,0};
__u8 luma = 0;
__u8 luma_mean = 128;
__u8 luma_delta = 20;
__u8 spring = 4;
int Gbright = 0;
__u8 r,g,b;
Gbright = Et_getgainG(etx);
Et_RegRead(etx->dev,0x0,0x0,ET_LUMA_CENTER,GRBG,4);
g= (GRBG[0]+GRBG[3]) >> 1;
r= GRBG[1];
b= GRBG[2];
r = ((r << 8)-( r << 4) -( r << 3)) >> 10;
b = (( b << 7) >>10);
g = ((g <<9)+(g << 7)+(g << 5)) >> 10;
luma = LIMIT(r+g+b);
PDEBUG(5 , "Etoms luma G %d",luma);
if ((luma < (luma_mean - luma_delta)) ||
( luma > (luma_mean + luma_delta))) {
Gbright += ((luma_mean-luma) >> spring);
Gbright = BLIMIT(Gbright);
PDEBUG(5 , "Etoms Gbright %d",Gbright);
Et_setgainG (etx, (__u8) Gbright);
}
}
static __u16 Et_setcolors(struct usb_spca50x *etx)
{
static __u8 I2cc [] ={0x05,0x02,0x02,0x05,0x0d};
__u8 i2cflags = 0x01;
//__u8 green = 0;
__u8 colors = (etx->colour >> 12) & 0x0f;
I2cc[3] = colors ; //red
I2cc[0] = 15-colors; //blue
// green = 15 - ((((7*I2cc[0]) >> 2 ) + I2cc[3]) >> 1);
// I2cc[1] = I2cc[2] = green;
if(etx->sensor == SENSOR_PAS106){
Et_i2cwrite(etx->dev,PAS106_REG13,&i2cflags,1,3);
Et_i2cwrite(etx->dev,PAS106_REG9,I2cc,sizeof(I2cc),1);
}
//PDEBUG(5 , "Etoms red %d blue %d green %d",I2cc[3],I2cc[0],green);
return 0;
}
static __u16 Et_getcolors(struct usb_spca50x *etx)
{
//__u8 valblue = 0;
__u8 valred = 0 ;
if(etx->sensor == SENSOR_PAS106){
//Et_i2cread(etx->dev,PAS106_REG9,&valblue,1,1);
Et_i2cread(etx->dev,PAS106_REG9+3,&valred,1,1);
return (((valred) & 0x0f) << 12);
}
return 0;
}
static void set_EtxxVGA(struct usb_spca50x *spca50x )
{
memset (spca50x->mode_cam, 0x00, TOTMODE * sizeof(struct mwebcam));
#if 0
spca50x->mode_cam[VGA].width = 640;
spca50x->mode_cam[VGA].height = 480;
spca50x->mode_cam[VGA].t_palette = P_RAW | P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[VGA].pipe = 1000;
spca50x->mode_cam[VGA].method = 0;
spca50x->mode_cam[VGA].mode = 0;
spca50x->mode_cam[PAL].width = 384;
spca50x->mode_cam[PAL].height = 288;
spca50x->mode_cam[PAL].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[PAL].pipe = 1000;
spca50x->mode_cam[PAL].method = 1;
spca50x->mode_cam[PAL].mode = 0;
spca50x->mode_cam[SIF].width = 352;
spca50x->mode_cam[SIF].height = 288;
spca50x->mode_cam[SIF].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[SIF].pipe = 1000;
spca50x->mode_cam[SIF].method = 1;
spca50x->mode_cam[SIF].mode = 0;
#endif
spca50x->mode_cam[CIF].width = 320;
spca50x->mode_cam[CIF].height = 240;
spca50x->mode_cam[CIF].t_palette = P_RAW | P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[CIF].pipe = 1000;
spca50x->mode_cam[CIF].method = 0;
spca50x->mode_cam[CIF].mode = 1;
spca50x->mode_cam[QPAL].width = 192;
spca50x->mode_cam[QPAL].height = 144;
spca50x->mode_cam[QPAL].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[QPAL].pipe = 1000;
spca50x->mode_cam[QPAL].method = 1;
spca50x->mode_cam[QPAL].mode = 1;
spca50x->mode_cam[QSIF].width = 176;
spca50x->mode_cam[QSIF].height = 144;
spca50x->mode_cam[QSIF].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[QSIF].pipe = 1000;
spca50x->mode_cam[QSIF].method = 1;
spca50x->mode_cam[QSIF].mode = 1;
spca50x->mode_cam[QCIF].width = 160;
spca50x->mode_cam[QCIF].height = 120;
spca50x->mode_cam[QCIF].t_palette = P_RAW | P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[QCIF].pipe = 1000;
spca50x->mode_cam[QCIF].method = 1;
spca50x->mode_cam[QCIF].mode = 1;
}
static void set_EtxxSIF(struct usb_spca50x *spca50x )
{
memset (spca50x->mode_cam, 0x00, TOTMODE * sizeof(struct mwebcam));
spca50x->mode_cam[SIF].width = 352;
spca50x->mode_cam[SIF].height = 288;
spca50x->mode_cam[SIF].t_palette = P_RAW |P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[SIF].pipe = 1000;
spca50x->mode_cam[SIF].method = 0;
spca50x->mode_cam[SIF].mode = 0;
spca50x->mode_cam[CIF].width = 320;
spca50x->mode_cam[CIF].height = 240;
spca50x->mode_cam[CIF].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[CIF].pipe = 1000;
spca50x->mode_cam[CIF].method = 1;
spca50x->mode_cam[CIF].mode = 0;
spca50x->mode_cam[QPAL].width = 192;
spca50x->mode_cam[QPAL].height = 144;
spca50x->mode_cam[QPAL].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[QPAL].pipe = 1000;
spca50x->mode_cam[QPAL].method = 1;
spca50x->mode_cam[QPAL].mode = 0;
spca50x->mode_cam[QSIF].width = 176;
spca50x->mode_cam[QSIF].height = 144;
spca50x->mode_cam[QSIF].t_palette = P_RAW |P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[QSIF].pipe = 1000;
spca50x->mode_cam[QSIF].method = 0;
spca50x->mode_cam[QSIF].mode = 1;
spca50x->mode_cam[QCIF].width = 160;
spca50x->mode_cam[QCIF].height = 120;
spca50x->mode_cam[QCIF].t_palette = P_YUV420 | P_RGB32 | P_RGB24 | P_RGB16;
spca50x->mode_cam[QCIF].pipe = 1000;
spca50x->mode_cam[QCIF].method = 1;
spca50x->mode_cam[QCIF].mode = 1;
}
static int Etxx_config(struct usb_spca50x *spca50x )
{
switch(spca50x->sensor){
case SENSOR_TAS5130C:
set_EtxxVGA(spca50x);
break;
case SENSOR_PAS106:
set_EtxxSIF(spca50x);
break;
default:
return -EINVAL;
break;
}
return 0;
}
#endif /* ET61XX51_H */