linux GT2005摄像头驱动源代码分析

由于近期在研究Android的一些视频通话的一些技术,所以很快就发现实现摄像头的驱动成为必须研究的课题。下面是在telechips公司提供的Android SDK中已经包含的GT2005型号sensor的部分驱动代码。虽然已经有了比较完善的驱动代码,但是我TCC8902板子上的GT2005摄像头还是没能preview出图像来,最近一直在试图进行各种方法的调试和分析。最后觉得硬着头皮来好好研究GT2005 camera的driver,我会分几期来进行分析,如果有不正确的地方,非常欢迎指正。

 

下面的代码是GT2005_2mp.h(GT2005 2百万像素摄像头头文件)

/* * drivers/media/video/tcc83xx/GT2005_2mp.h * * Register definitions for the GT2005 CameraChip. * * Author: zzau ([email protected]) * * Copyright (C) 2008 Telechips, Inc. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any * kind, whether express or implied. */ #include <mach/globals.h> #include "sensor_if.h" #ifndef GT2005_H #define GT2005_H /* The MT9D112 I2C sensor chip has a fixed slave address of 0x78. */ #define SENSOR_I2C_ADDR 0x78 //[suting] : 摄像头涉及I2C总线协议 #define REG_TERM 0x0000 /* terminating list entry for reg */ #define VAL_TERM 0x0000 /* terminating list entry for val */ //CLOCK #define CKC_CAMERA_MCLK 240000 #define CKC_CAMERA_MCLK_SRC DIRECTPLL1 #define CKC_CAMERA_SCLK 480000 #define CKC_CAMERA_SCLK_SRC DIRECTPLL2 #define FRAMESKIP_COUNT_FOR_CAPTURE 3 // ZOOM Setting!! #define PRV_W 800 #define PRV_H 600 #define PRV_ZOFFX 8 #define PRV_ZOFFY 6 #define CAP_W 1600 #define CAP_H 1200 #define CAP_ZOFFX 16 #define CAP_ZOFFY 12 #define CAM_2XMAX_ZOOM_STEP 25 #define CAM_CAPCHG_WIDTH 800 struct sensor_reg { //[suting]: register number and number hold unsigned short reg; unsigned short val; }; struct capture_size { //[suting] : width and height unsigned long width; unsigned long height; }; extern struct capture_size sensor_sizes[]; extern void sensor_init_fnc(SENSOR_FUNC_TYPE *sensor_func); #endif /* GT2005_H */

 

从上面的代码可以看出,GT2005摄像头涉及到了I2C总线协议,因为它在发送命令和接受数据时,都是通过I2C总线的方式来完成的。

上面比较重要的数据结构是:

(1)struct sensor_reg ,它提供的是一个键值对:寄存器号 、 寄存器的值,这样定义的目的是在进行初始化等各种操作时,能够很方便的由寄存器号获得寄存器值,进行I2C总线的读写。

(2)struct capture_size ,它定义了capture后的image的width、heigth。

(3)extern void sensor_init_fnc(SENSOR_FUNC_TYPE *sensor_func);

这个函数用于注册GT2005_2mp.c中实际提供给上层应用程序的接口函数。

SENSOR_FUNC_TYPE类型是在 sensor_if.c/.h中定义的。

 

下面是GT2005_2mp.c 实现文件

#include <linux/delay.h> #include <asm/system.h> #include <mach/hardware.h> #include <asm/io.h> #include "sensor_if.h" #include "cam.h" #include "tcc_cam_i2c.h" #if defined(CONFIG_ARCH_TCC92X) || defined(CONFIG_ARCH_TCC93XX) #include <mach/bsp.h> #elif defined(CONFIG_ARCH_TCC79X) #include <mach/tcc79x.h> #endif //省略了一些注释掉的代吗 //................ /* Array of image sizes supported by GT2005. These must be ordered from * smallest image size to largest. */ struct capture_size sensor_sizes[] = { { 1600, 1200 }, /* UXGA */ { 1280, 960 }, /* SXGA */ { 1024, 768 }, /* XGA */ { 800, 600 }, /* SVGA */ { 640, 480 }, /* VGA */ { 320, 240 }, /* QVGA */ { 176, 144 }, /* QCIF */ }; /* 上面这个结构主要是用于保存capture size,它每个数据项必须按从小到大来排列,因为在sensor_if.c的sensor_find_size()函数中,需要使用这个struct的定义,根据app给出的capture size,协商出最合适的size */ /* register initialization tables for sensor */ /* common sensor register initialization for all image sizes, pixel formats, * and frame rates */ /* ....省略,后面是一些寄存器的键值对定义,主要用于寄存器的初始化,指定对应的image size / pixel format / frmae rate ,这些都可以通过GT2005的数据手册获得 */ /* .....省略,接下来的是一些针对camera的不同属性的寄存器定义,比如:white balance / brightness / special effect等等 */ static int write_regs(const struct sensor_reg reglist[]) //[suting]: write register list { int err; int err_cnt = 0; unsigned char data[132]; unsigned char bytes; const struct sensor_reg *next = reglist; while (!((next->reg == REG_TERM) && (next->val == VAL_TERM))) { if(next->reg == REG_TERM && next->val != VAL_TERM) { mdelay(next->val*2); printk("Sensor init Delay[%d]!!!! /n", next->val); next++; } else { bytes = 0; data[bytes]= next->reg>>8; bytes++; data[bytes]= (u8)next->reg&0xff; bytes++; data[bytes]= next->val; bytes++; err = DDI_I2C_Write(data, 2, bytes-2); //[suting] : DDI_I2C_Write if (err) { err_cnt++; if(err_cnt >= 3) { printk("ERROR: Sensor I2C !!!! /n"); return err; } } else { err_cnt = 0; next++; } } } return 0; } /* 上面这个函数主要用于写寄存器,它被下面很多的接口函数所调用 */ static int sensor_open(void) { int id = 0; int id1 = 0; sensor_power_disable(); sensor_delay(10); sensor_power_enable(); sensor_delay(10); sensor_powerdown_disable(); sensor_delay(10); sensor_powerdown_enable(); sensor_delay(10); sensor_reset_low(); sensor_delay(10); CIF_Open(); //[suting] : open CIF sensor_delay(40); sensor_reset_high(); sensor_delay(15); printk("init sensor GT2005 !!!! /n"); DDI_I2C_Read(0x0000, 2, &id, 1); DDI_I2C_Read(0x0001, 2, &id1, 1); printk("read sensor ID : %x%x/n", id, id1); return write_regs(sensor_reg_common[0]); //[suting]: write_regs for initialization } static int sensor_close(void) { CIF_ONOFF(OFF); //[suting] : close CIF sensor_reset_low(); sensor_power_disable(); sensor_powerdown_disable(); CIF_Close(); msleep(5); return 0; } static int sensor_preview(void) { printk("sensor_preview/r/n"); return write_regs(sensor_reg_common[1]); //[suting] : write_regs for preview } static int sensor_capture(void) { printk("sensor_capture/r/n"); return write_regs(sensor_reg_common[2]); //[suting] : write_regs for capture } static int sensor_capturecfg(int width, int height) { return 0; } /* 上面就是几个比较有代表性的接口函数 */ void sensor_init_fnc(SENSOR_FUNC_TYPE *sensor_func) //[suting] just like register callback functions { sensor_func->Open = sensor_open; sensor_func->Close = sensor_close; sensor_func->Set_Preview = sensor_preview; sensor_func->Set_Capture = sensor_capture; sensor_func->Set_CaptureCfg = sensor_capturecfg; sensor_func->Set_Zoom = sensor_zoom; sensor_func->Set_AF = sensor_autofocus; sensor_func->Set_Effect = sensor_effect; sensor_func->Set_Flip = sensor_flip; sensor_func->Set_ISO = sensor_iso; sensor_func->Set_ME = sensor_me; sensor_func->Set_WB = sensor_wb; sensor_func->Set_Bright = sensor_bright; sensor_func->Set_Scene = sensor_scene; sensor_func->Check_ESD = sensor_check_esd; sensor_func->Check_Luma = sensor_check_luma; } /* 上面就是注册所有的接口函数 */

 

 

你可能感兴趣的:(linux,image,struct,initialization,CAM,delay)