📄 camera_mt9v111.c
字号:
/* * drivers/media/video/mx2ads/camera_mt9v111.c * * driver for a Motorola MX2ADS on-board CMOS Image Sensor * - Micron MT9V111 (aka Imagic 8012) * * Author: MontaVista Software, Inc. <source@mvista.com> * * 2005 (c) MontaVista Software, 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 <linux/config.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/videodev.h>#include <asm/uaccess.h>#include <asm/hardware.h>#define MODULE_NAME "mt9v111"#include "common.h"#include "camif.h"#define MT9V111_IC_VERSION 0x36 /* Imager Core Version Register */#define MT9V111_CORE_VERSION 0x823A /* Imager Core Version */static struct camera *this;extern const struct image_size mx2ads_image_size[];extern const int mx2ads_pixfmt_depth[];#define V4L2_CID_AUTO_SHARPENING V4L2_CID_PRIVATE_BASE+0#define V4L2_CID_SHARPENING V4L2_CID_PRIVATE_BASE+1#define V4L2_CID_AUTO_FLICKER_CANCELLATION V4L2_CID_PRIVATE_BASE+2#define V4L2_CID_FLICKER_CANCELLATION V4L2_CID_PRIVATE_BASE+3#define V4L2_CID_AUTO_SATURATION V4L2_CID_PRIVATE_BASE+4#define V4L2_CID_LAST_PRIV V4L2_CID_PRIVATE_BASE+4static int mt9v111_red_balance(struct v4l2_control *vc, int write);static int mt9v111_blue_balance(struct v4l2_control *vc, int write);static int mt9v111_auto_white_balance(struct v4l2_control *vc, int write);static int mt9v111_hflip(struct v4l2_control *vc, int write);static int mt9v111_vflip(struct v4l2_control *vc, int write);static int mt9v111_auto_saturation(struct v4l2_control *vc, int write);static int mt9v111_saturation(struct v4l2_control *vc, int write);static int mt9v111_auto_sharpening(struct v4l2_control *vc, int write);static int mt9v111_sharpening(struct v4l2_control *vc, int write);static int mt9v111_auto_flicker_cancellation(struct v4l2_control *vc, int write);static int mt9v111_flicker_cancellation(struct v4l2_control *vc, int write);static int mt9v111_close(void);/* Video controls */static struct vcontrol { struct v4l2_queryctrl qc; int (*handler) (struct v4l2_control * vc, int write);} control[] = { { {V4L2_CID_RED_BALANCE, "Red Balance", 0, 255, 1, 0, V4L2_CTRL_TYPE_INTEGER}, mt9v111_red_balance}, { {V4L2_CID_BLUE_BALANCE, "Blue Balance", 0, 255, 1, 0,V4L2_CTRL_TYPE_INTEGER}, mt9v111_blue_balance}, { {V4L2_CID_AUTO_WHITE_BALANCE, "Auto White Balance", 0, 1, 0, 1, V4L2_CTRL_TYPE_BOOLEAN}, mt9v111_auto_white_balance}, { {V4L2_CID_HFLIP, "Horizontal Flip", 0, 1, 0, 0, V4L2_CTRL_TYPE_BOOLEAN}, mt9v111_hflip}, { {V4L2_CID_VFLIP, "Vertical Flip", 0, 1, 0, 0, V4L2_CTRL_TYPE_BOOLEAN}, mt9v111_vflip}, { {V4L2_CID_SATURATION, "Saturation", 0, 6, 1, 0, V4L2_CTRL_TYPE_INTEGER}, mt9v111_saturation}, { {V4L2_CID_AUTO_SATURATION, "Auto Saturation", 0, 1, 0, 1,V4L2_CTRL_TYPE_BOOLEAN}, mt9v111_auto_saturation}, { {V4L2_CID_AUTO_SHARPENING, "Auto Sharpening", 0, 1, 0, 1,V4L2_CTRL_TYPE_BOOLEAN}, mt9v111_auto_sharpening}, { {V4L2_CID_SHARPENING, "Sharpening", 0, 7, 1, 3, V4L2_CTRL_TYPE_INTEGER}, mt9v111_sharpening}, { {V4L2_CID_AUTO_FLICKER_CANCELLATION,"Auto Flicker Cancellation", 0, 1, 0, 0, V4L2_CTRL_TYPE_BOOLEAN}, mt9v111_auto_flicker_cancellation}, { {V4L2_CID_FLICKER_CANCELLATION, "Flicker Cancellation",0, 2, 1, 0, V4L2_CTRL_TYPE_INTEGER}, mt9v111_flicker_cancellation},};/*may be add AWB Boundary - present in the freescale's code*/#define NUM_CONTROLS (sizeof(control)/sizeof(control[0]))/* Micron has 2 areas - Image core and Image flow processor */#define MT9V111_IFP 0x01 /* set R1 to choose Image Flow Processor (IFP) */#define MT9V111_IC 0x04 /* set R1 to choose Image Core (IC) */static int mt9v111_reg_mode;static int MT9V111_WRITE16(u16 _mode, u8 _reg, u16 _val){ struct camera_serial_bus * sbus = this->camif->sbus; u8 buf[2]; if (mt9v111_reg_mode != _mode) { buf[0] = (_mode >> 8) & 0xff; buf[1] = _mode & 0xff; sbus->write(0x1, buf, 2); mt9v111_reg_mode = _mode; } buf[0] = (_val >> 8) & 0xff; buf[1] = _val & 0xff; sbus->write((_reg), buf, 2); return 0;}static int MT9V111_READ16(u16 _mode, u8 _reg, u16 * _val){ struct camera_serial_bus * sbus = this->camif->sbus; u8 buf[2]; if (mt9v111_reg_mode != _mode) { buf[0] = (_mode >> 8) & 0xff; buf[1] = _mode & 0xff; sbus->write(0x1, buf, 2); mt9v111_reg_mode = _mode; } sbus->read((_reg), (u8 *)_val, 2); return 0;}#define MT9V111_IFP_WRITE16(_reg, _val) \ MT9V111_WRITE16(MT9V111_IFP, (_reg), (_val))#define MT9V111_IC_WRITE16(_reg, _val) \ MT9V111_WRITE16(MT9V111_IC, (_reg), (_val))#define MT9V111_IFP_READ16(_reg, _val) \ MT9V111_READ16(MT9V111_IFP, (_reg), (_val))#define MT9V111_IC_READ16(_reg, _val) \ MT9V111_READ16(MT9V111_IC, (_reg), (_val))/*frame timing v-blank, h-blank control*/static inline voidmt9v111_blanking_ctrl(void){/*set to minimum blanking time => max frame rate*/ MT9V111_IC_WRITE16(0x05, 0x9); MT9V111_IC_WRITE16(0x06, 0x3);}/*lens geometry correction*/static inline voidmt9v111_lens_correction(void){ unsigned short nValue; MT9V111_IFP_READ16(0x08, &nValue); MT9V111_IFP_WRITE16(0x08, nValue |= 0x0100); /*turn on Lens Shading correction */ /*Vertical direction,split into 5 vertical segment */ MT9V111_IFP_WRITE16(0x81, 0xDD0C); /*Red pixel in first vertex */ MT9V111_IFP_WRITE16(0x82, 0x04F4); /*Red pixel in second & third vertex */ MT9V111_IFP_WRITE16(0x83, 0x3C11); /*Red pixel in fourth & fifth vertex */ MT9V111_IFP_WRITE16(0x84, 0xE20C); /*Green pixel in first vertex */ MT9V111_IFP_WRITE16(0x85, 0x02F6); /*Green pixel in second & third vertex */ MT9V111_IFP_WRITE16(0x86, 0x3211); /*Green pixel in fourth & fifth vertex */ MT9V111_IFP_WRITE16(0x87, 0xDD0C); /*Blue pixel in first vertex */ MT9V111_IFP_WRITE16(0x88, 0x00F4); /*Blue pixel in second & third vertex */ MT9V111_IFP_WRITE16(0x89, 0x3216); /*Blue pixel in fourth & fifth vertex */ /*Horizontal diretion, split into 6 horizontal segment */ MT9V111_IFP_WRITE16(0x8A, 0x8832); /*Red pixel in first vertex */ MT9V111_IFP_WRITE16(0x8B, 0xF7DD); /*Red pixel in second & third vertex */ MT9V111_IFP_WRITE16(0x8C, 0x3C0C); /*Red pixel in fourth & fifth vertex */ MT9V111_IFP_WRITE16(0x8D, 0x007F); /*Red pixel in sixth vertex */ MT9V111_IFP_WRITE16(0x8E, 0xBA1E); /*Green pixel in first vertex */ MT9V111_IFP_WRITE16(0x8F, 0xF7EC); /*Green pixel in second & third vertex */ MT9V111_IFP_WRITE16(0x90, 0x3708); /*Green pixel in fourth & fifth vertex */ MT9V111_IFP_WRITE16(0x91, 0x0064); /*Green pixel in sixth vertex */ MT9V111_IFP_WRITE16(0x92, 0xBF1E); /*Blue pixel in first vertex */ MT9V111_IFP_WRITE16(0x93, 0xF7EE); /*Blue pixel in second & third vertex */ MT9V111_IFP_WRITE16(0x94, 0x320F); /*Blue pixel in fourth & fifth vertex */ MT9V111_IFP_WRITE16(0x95, 0x0064); /*Blue pixel in sixth vertex */}/*photodiode black threshold calibration*/static inline voidmt9v111_black_threshold(void){ unsigned short nValue; MT9V111_IC_READ16(0x62, &nValue); MT9V111_IC_WRITE16(0x62, nValue |= 0x0001); /*Manual mode */ MT9V111_IC_WRITE16(0x5F, 0xA31D); /*Calibration(Calib) threshold */ MT9V111_IC_WRITE16(0x60, 0x001C); /*Calib Green1 */ MT9V111_IC_WRITE16(0x61, 0x0024); /*Calib Green2 */ MT9V111_IC_WRITE16(0x63, 0x0023); /*Calib Red */ MT9V111_IC_WRITE16(0x64, 0x0023); /*Calib Blue */ MT9V111_IC_WRITE16(0x62, nValue &= 0xFFFE); /*Resume normal mode */}/* * Initialise board-specfic settings to init Micron camera */static intmt9v111_init(void){ struct v4l2_control vc; int i; /* * Reset Image core */ MT9V111_IC_WRITE16(0x0D, 0x01); MT9V111_IC_WRITE16(0x0D, 0x00); /* * Reset Image Flow */ MT9V111_IFP_WRITE16(0x07, 0x01); MT9V111_IFP_WRITE16(0x07, 0x00); /* * Set all default settings */ mt9v111_blanking_ctrl(); mt9v111_lens_correction(); mt9v111_black_threshold(); for (i = 0; i < NUM_CONTROLS; i++) { vc.id = control[i].qc.id; vc.value = control[i].qc.default_value; control[i].handler(&vc, 1); } mt9v111_close(); return 0;}static intmt9v111_set_fp(int fp, int xclk, int test){ dbg("Not implemented yet\n"); return -1;}static intmt9v111_get_fp(void){ dbg("Not implemented yet\n"); return -1;}static intifp_reg_get_set(u8 reg_num, u16 mask, u8 shift, struct v4l2_control *vc, int write){ u16 val; MT9V111_IFP_READ16(reg_num, &val); if (write) { val = (val & ~(mask << shift)) | (vc->value << shift); MT9V111_IFP_WRITE16(reg_num, val); } else { vc->value = (val >> shift) & mask; } return 0;}static intmt9v111_red_balance(struct v4l2_control *vc, int write){ if (write) dbg("new red balance value %d\n",vc->value); return ifp_reg_get_set(0x21, 0xff, 8, vc, write);}static intmt9v111_blue_balance(struct v4l2_control *vc, int write){ if (write) dbg("new blue balance value %d\n",vc->value); return ifp_reg_get_set(0x21, 0xff, 0, vc, write);}static intmt9v111_auto_white_balance(struct v4l2_control *vc, int write){ if (write) dbg("new auto white balance value %d\n",vc->value); return ifp_reg_get_set(0x6, 0x1, 1, vc, write);}static intmt9v111_hflip(struct v4l2_control *vc, int write){ u16 val; MT9V111_IC_READ16(0x20, &val); if (write) { val = (val & ~0x4020) | (0x4020 * vc->value); MT9V111_IC_WRITE16(0x20, val); } else { vc->value = ((val >> 14) & 1); } return 0;}static intmt9v111_vflip(struct v4l2_control *vc, int write){ u16 val; MT9V111_IC_READ16(0x20, &val); if (write) { val = (val & ~0x8080) | (0x8080 * vc->value); MT9V111_IC_WRITE16(0x20, val); } else { vc->value = (val >> 15) & 1; } return 0;}static intmt9v111_auto_saturation(struct v4l2_control *vc, int write){ if (write) dbg("new auto saturation value %d\n",vc->value); return ifp_reg_get_set(0x25, 0x1, 14, vc, write);}static intmt9v111_saturation(struct v4l2_control *vc, int write){ if (write) dbg("new saturation value %d\n",vc->value); return ifp_reg_get_set(0x25, 0x7, 11, vc, write);}static intmt9v111_auto_sharpening(struct v4l2_control *vc, int write){ if (write) dbg("new auto sharpening value %d\n",vc->value); return ifp_reg_get_set(0x5, 0x1, 3, vc, write);}static intmt9v111_sharpening(struct v4l2_control *vc, int write){ if (write) dbg("new sharpening value %d\n",vc->value); return ifp_reg_get_set(0x5, 0x7, 0, vc, write);}static int mt9v111_auto_flicker_cancellation_en;static int mt9v111_flicker_cancellation_en;static intmt9v111_auto_flicker_cancellation(struct v4l2_control *vc, int write){ u16 val;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -