由於近期在研究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;
- }
- /* 上面就是註冊所有的接口函數 */