📄 cczr32112.c
字号:
/*!****************************************************************************! 05.03.2002 splitted huge cmoscam.c*! FILE NAME : cczr32112.c*! DESCRIPTION: sensor support for ZR32112*//****************** INCLUDE FILES SECTION ***********************************/#include <linux/module.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/string.h>#include <linux/init.h>#include <linux/config.h>#include <asm/system.h>#include <asm/svinto.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/delay.h>#include <asm/uaccess.h>#include <asm/cmoscama.h>#include "cc303.h"#include "cci2c.h"#include "cczr32112.h"#define D(x)// **************************************************************static unsigned long default_ZR32112[]=\ { P_VIRT_WIDTH, 1288, P_VIRT_HEIGHT, 1032, P_WOI_LEFT, 0, P_WOI_TOP, 0, P_WOI_WIDTH, 1288, P_WOI_HEIGHT, 1032 };// static unsigned int zr32112_inits[zr_init_size]= static unsigned int zr32112_inits[]= \ {0x0108, // |0x80 - test ramp, |0x01 - video 0x10 - flip hor, 0x08 - flip vert 0x0203,0x0303,0x0400,0x0500,0x0600,0x0700,0x08a1, 0x0981,0x1204,0x13fe,0x1400,0x1500,0x1600, 0x2080,0x2100,0x2200, 0x8001,0x8100,0x820a,0x830c, 0x8602,0x871f,0x8801,0x8907, 0x8a1f,0x8b0c,0x8c03,0x8d1f, 0x8e08,0x8f1f,0x900a,0x9111, 0x9208,0x931f,0x9406,0x950a, 0x961f,0x9701,0x980f,0x9900, 0x9a1f,0x9b02,0x9c0f,0x9f07, 0xa01f,0xa101,0xa20a,0xa30f, 0xa417,0xa500,0xa61f,0xa70f, 0xa80a,0xa90f,0xaa17,0xab02, 0xac1f,0xad07,0xae00,0xaf03, 0xb017,0xb30c,0xb41f,0xb500, 0xb600,0xb700,0xb800,0xb900, 0xba00,0xbb00,0xbc01 }; // bit 0 - decimation 1, 1 - decimation2, 2 - decimation 4. "1"->dec width static unsigned char ZRDecWidth[256]= \ {3,1,3,5,1,1,3,5,3,1,1,1,3,1,3,5, 1,1,3,5,3,1,1,1,3,1,3,5,1,1,3,5, 3,1,1,1,3,1,3,5,1,1,3,5,3,1,1,1, 3,1,3,5,1,1,3,5,3,1,1,1,3,1,3,5, 1,1,3,5,3,1,1,1,3,1,3,5,1,1,3,5, 3,1,1,1,3,1,3,5,1,1,3,5,3,1,1,1, 3,1,3,5,1,1,3,5,3,1,1,1,3,1,3,5, 1,1,3,5,3,1,1,1,3,1,3,5,1,1,3,5, 3,1,1,1,3,1,3,5,1,1,3,5,3,1,1,1, 3,1,3,5,1,1,3,5,3,1,1,1,3,1,3,5, 1,1,3,5,3,1,1,1,3,1,3,5,1,1,3,5, 3,1,1,1,3,1,3,5,1,1,3,5,3,1,1,1, 3,1,3,5,1,1,3,5,3,1,1,1,3,1,3,5, 1,1,3,5,3,1,1,1,3,1,3,5,1,1,3,5, 3,1,1,1,3,1,3,5,1,1,3,5,3,1,1,1, 3,1,3,5,1,1,3,5,3,1,1,1,3,1,3,5};void ccamInitWndSizeZR32112 (void) { int i;//,j; int mx; int my;/* needs more experimenting. if right side of the window is off limits actual number of pixels is not predicted correct */ D(for (i=0;i<0x17;i++) printk ("%x ",get_sensor_i2c_regs(i))); D(printk("\r\n")); i= (get_sensor_i2c_regs(P_ZR_FMODE) & 0x02) ? ( (get_sensor_i2c_regs(P_ZR_FMODE) & 0x04) ? 2: 4 ) : 8; //decimation mode mx=161*i; my=129*i;// D(printk("mx= %d my = %d\r\n",mx,my)); set_imageParamsR (P_ACTUAL_WIDTH, (unsigned long) (i * get_sensor_i2c_regs(P_ZR_WWDTH))); set_imageParamsR (P_ACTUAL_HEIGHT, (unsigned long) (i * get_sensor_i2c_regs(P_ZR_WHGHT)));/* j = ((get_sensor_i2c_regs(P_ZR_WSCLH) & 0xff) <<8) + (get_sensor_i2c_regs(P_ZR_WSCLL) & 0xff);// D(printk("j= %d get_imageParamsR (P_ACTUAL_WIDTH) = %d\r\n",j,get_imageParamsR (P_ACTUAL_WIDTH))); if ((get_imageParamsR (P_ACTUAL_WIDTH) + j)> mx) set_imageParamsR (P_ACTUAL_WIDTH, (unsigned long) (mx-j));*/ // table to compensate for ZR bugs when using Horizontal Flip mode/* * decimation 1 - always, * decimation 2 - if (get_sensor_i2c_regs(0x08) & 0x01 ) == 0 * except get_sensor_i2c_regs(0x08)=4+6*N * decimation 4 - if ((get_sensor_i2c_regs(0x08) & 0x03 ) == 3) * except get_sensor_i2c_regs(0x08)=11+12*N **/// static unsigned char ZRDecWidth[256]= \ // bit 0 - decimation 1, 1 - decimation2, 2 - decimation 4. "1"->dec width if (get_sensor_i2c_regs(P_ZR_FMODE) & 0x10) switch (i) { // i=8/4/2 case 8: { if (ZRDecWidth[get_sensor_i2c_regs(P_ZR_WWDTH)] & 1) set_imageParamsR (P_ACTUAL_WIDTH, get_imageParamsR (P_ACTUAL_WIDTH)-1); // was always break; } case 4: { if ((ZRDecWidth[get_sensor_i2c_regs(P_ZR_WWDTH)] & 2) || (get_sensor_i2c_regs(P_ZR_WSCLL) & 2 )) set_imageParamsR (P_ACTUAL_WIDTH, get_imageParamsR (P_ACTUAL_WIDTH)-1); break; } case 2: { if (ZRDecWidth[get_sensor_i2c_regs(P_ZR_WWDTH)] & 4) set_imageParamsR (P_ACTUAL_WIDTH, get_imageParamsR (P_ACTUAL_WIDTH)-1); break; } }/* j = ((get_sensor_i2c_regs(P_ZR_WSRWH) & 0xff) <<8) + (get_sensor_i2c_regs(P_ZR_WSRWL) & 0xff);// D(printk("j= %d get_imageParamsR (P_ACTUAL_HEIGHT) = %d\r\n",j,get_imageParamsR (P_ACTUAL_HEIGHT))); if ((get_imageParamsR (P_ACTUAL_HEIGHT) + j)> my) set_imageParamsR (P_ACTUAL_WIDTH, (unsigned long) (my-j));*/}int init_ZR32112(void) { // returns SENSOR_ZR32112=4 if found unsigned char d[2]; unsigned char d1[20]; int i; d[0]=P_ZR_PARTID;// read register 0, slave address 0x60 i2c_writeData(0, ZR_I2C_ADDR & 0xfe, &d[0], 1); i2c_readData (0, ZR_I2C_ADDR | 1, &d[0], 1); if (d[0]==ZR32112_PARTID) { set_sensor_i2c_addr(ZR_I2C_ADDR); set_imageParamsR(P_SENSOR,SENSOR_ZR32112); printk("Found ZR32112 sensor\n"); printk("Initializing ZR32112 registers with default values:\n");// for (i=0;i<zr_init_size;i++) { for (i=0;i<sizeof(zr32112_inits)/sizeof(zr32112_inits[0]);i++) { d[0]=((zr32112_inits[i]>>8) & 0xff); // i2c address d[1]=( zr32112_inits[i] & 0xff); // i2c data writeSensorReg(d[0],d[1],1); }// read appropriate i2c to shadow registers d[0]=0; // i2c address i2c_writeData(0, get_sensor_i2c_addr() & 0xfe, &d[0], 1); i2c_readData (0, get_sensor_i2c_addr() | 1, &d1[0], 10); // read regs 0..9 for (i=0;i<10;i++) set_sensor_i2c_regs( i+d[0], d1[i]); d[0]=0x12; // i2c address i2c_writeData(0, get_sensor_i2c_addr() & 0xfe, &d[0], 1); i2c_readData (0, get_sensor_i2c_addr() | 1, &d1[0], 5); // read regs 0x12..0x16 for (i=0;i<5;i++) set_sensor_i2c_regs((int) i+d[0], d1[i]); writeSensorDefaults(& default_ZR32112[0],sizeof (default_ZR32112)/sizeof( default_ZR32112[0])/2); // set ZR32112 specific defaults return (get_imageParamsR(P_SENSOR)); } return 0;}int program_ZR32112(void){ // program ZR32112 sensor, returns -1 error, 0 - did not have to change, 1 changed int r=0; int lines; int tline;// video mode does not hold// color/mono set_imageParamsR(P_COLOR, (get_imageParamsW(P_COLOR))?1:0);// window size/position set_imageParamsR(P_WOI_LEFT,(get_imageParamsW(P_WOI_LEFT)>(SENSORWIDTH_ZR32112-8 ))?\ (SENSORWIDTH_ZR32112-8 ):get_imageParamsW(P_WOI_LEFT)); set_imageParamsR(P_WOI_TOP, (get_imageParamsW(P_WOI_TOP) >(SENSORHEIGHT_ZR32112-8))?\ (SENSORHEIGHT_ZR32112-8):get_imageParamsW(P_WOI_TOP));// if (get_imageParamsR(P_COLOR)) {// always even set_imageParamsR(P_WOI_LEFT,get_imageParamsR(P_WOI_LEFT) & 0x7fe); set_imageParamsR(P_WOI_TOP, get_imageParamsR(P_WOI_TOP) & 0x7fe);// } set_imageParamsR(P_WOI_WIDTH,(((get_imageParamsW(P_WOI_WIDTH)+get_imageParamsR(P_WOI_LEFT))>(SENSORWIDTH_ZR32112 ))?\ (SENSORWIDTH_ZR32112-get_imageParamsR(P_WOI_LEFT)):get_imageParamsW(P_WOI_WIDTH)) & 0x7f8); if (get_imageParamsR(P_WOI_WIDTH) <8) set_imageParamsR(P_WOI_WIDTH,8); set_imageParamsR(P_WOI_HEIGHT,(((get_imageParamsW(P_WOI_HEIGHT)+get_imageParamsR(P_WOI_TOP))>(SENSORHEIGHT_ZR32112 ))?\ (SENSORHEIGHT_ZR32112-get_imageParamsR(P_WOI_TOP)):get_imageParamsW(P_WOI_HEIGHT)) & 0x7f8); if (get_imageParamsR(P_WOI_HEIGHT) <8) set_imageParamsR(P_WOI_HEIGHT,8); r |= writeSensorReg(P_ZR_WSCLH, (unsigned char) (get_imageParamsR(P_WOI_LEFT) >> 8), 0); r |= writeSensorReg(P_ZR_WSCLL, (unsigned char) (get_imageParamsR(P_WOI_LEFT) & 0xff), 0); r |= writeSensorReg(P_ZR_WWDTH, (unsigned char) (get_imageParamsR(P_WOI_WIDTH) >> 3), 0); r |= writeSensorReg(P_ZR_WSRWH, (unsigned char) (get_imageParamsR(P_WOI_TOP) >> 8), 0); r |= writeSensorReg(P_ZR_WSRWL, (unsigned char) (get_imageParamsR(P_WOI_TOP) & 0xff), 0); r |= writeSensorReg(P_ZR_WHGHT, (unsigned char) (get_imageParamsR(P_WOI_HEIGHT)>> 3), 0);// orientation set_imageParamsR(P_FLIPH, (get_imageParamsW(P_FLIPH))?1:0); set_imageParamsR(P_FLIPV, (get_imageParamsW(P_FLIPV))?1:0);// decimation set_imageParamsR(P_DCM_HOR, (get_imageParamsW(P_DCM_HOR) <2)? 1:\ (get_imageParamsW(P_DCM_HOR) <4)? 2: 4); set_imageParamsR(P_DCM_VERT, get_imageParamsR(P_DCM_HOR)); // same h/v decimation for Zoran chips// test mode set_imageParamsR(P_TEST, (get_imageParamsW(P_TEST))?1:0);// video/still if (get_imageParamsR(P_VIDEO)) {// video mode - calculate video exposure (if not defined directly) if (get_imageParamsW(P_VEXPOS)) set_imageParamsR(P_VEXPOS,get_imageParamsW(P_VEXPOS)); else {// calculate TLINE/decimation time (in ns). lines=get_imageParamsR(P_WOI_HEIGHT); tline=get_imageParamsR(P_MCLK); switch (get_imageParamsR(P_DCM_HOR)) { // i is 1/2/4 - decimation case 2: {lines=lines>>1; tline= tline*12000; break;} // 960*12.5ns case 4: {lines=lines>>2; tline= tline* 7600; break;} // 608*12.5ns default: { tline= tline*20800;} //1664*12.5ns - case 1: }// visual difference in decimation mode :2 - twice looks brighter. Lets's fix it for now in ZR32212// if (get_imageParamsR(P_DCM_HOR)==2) tline= tline*2;// printk ("tline= %d, lines=%d, W(P_EXPOS)=%d\r\n",tline,lines, get_imageParamsW(P_EXPOS)); if (get_imageParamsW(P_EXPOS)>(((tline>>4)*lines)/62500)) set_imageParamsR(P_VEXPOS,0x7ff); //max else set_imageParamsR(P_VEXPOS,0x7ff-lines+((get_imageParamsW(P_EXPOS)*62500)/(tline>>4))); // to fit into 32-bit int//printk ("R(P_VEXPOS)= %d, (tline>>4)=%d\r\n",get_imageParamsR(P_VEXPOS),(tline>>4)); }// calculate exposures// set video exposure time - does not work with flip vert, formula will be upated later r |= writeSensorReg(P_ZR_VEXPH, (unsigned char) (get_imageParamsR(P_VEXPOS) >> 8), 0); r |= writeSensorReg(P_ZR_VEXPL, (unsigned char) (get_imageParamsR(P_VEXPOS) & 0xff), 0); } r |= writeSensorReg(P_ZR_FMODE, (unsigned char) \ (( get_imageParamsR(P_TEST) << 7) | ( get_imageParamsR(P_FLIPH) << 4) | ( get_imageParamsR(P_FLIPV) << 3) | ((get_imageParamsR(P_DCM_HOR)-1) << 1) | ((get_imageParamsR(P_VIDEO)?1:0) )), 0); // gain(s) set_imageParamsR(P_GAINR, get_imageParamsW(P_GAINR) & 0x3f); set_imageParamsR(P_GAING, (get_imageParamsR(P_COLOR))? (get_imageParamsW(P_GAING) & 0x3f):get_imageParamsR(P_GAINR)); set_imageParamsR(P_GAINB, (get_imageParamsR(P_COLOR))? (get_imageParamsW(P_GAINB) & 0x3f):get_imageParamsR(P_GAINR)); set_imageParamsR(P_GAINGB, get_imageParamsR(P_GAING)); r |= writeSensorReg(P_ZR_GAINR, (unsigned char) get_imageParamsR(P_GAINR), 0); r |= writeSensorReg(P_ZR_GAING, (unsigned char) get_imageParamsR(P_GAING), 0); r |= writeSensorReg(P_ZR_GAINB, (unsigned char) get_imageParamsR(P_GAINB), 0);// TODO: video mode exposure time, virtual frame -- needed for exposure control//#define P_VIDEO 21 /* still (stopped) - 0, video - 1. KAC1310 - video only *///#define P_EXPOS 17 /* P_RW_EXPOS 1 exposure time *///#define P_VEXPOS 42 /* video exposure (if 0 - use P_RW_EXPOS in ms) */ return r;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -