📄 mt9v111.c
字号:
*saturation = 100; break; case 1: *saturation = 75; break; case 2: *saturation = 50; break; case 3: *saturation = 37; break; case 4: *saturation = 25; break; case 5: *saturation = 150; break; case 6: *saturation = 0; break; default: *saturation = 0; break; }}/*! * mt9v111 sensor set AE measurement window mode configuration * * @param ae_mode int * @return None */static void mt9v111_set_ae_mode(int ae_mode){ u8 reg; u16 data; mt9v111_device.ifpReg->modeControl &= 0xfff3; mt9v111_device.ifpReg->modeControl |= (ae_mode & 0x03) << 2; reg = MT9V111I_ADDR_SPACE_SEL; data = mt9v111_device.ifpReg->addrSpaceSel; mt9v111_write_reg(reg, data); reg = MT9V111I_MODE_CONTROL; data = mt9v111_device.ifpReg->modeControl; mt9v111_write_reg(reg, data);}/*! * mt9v111 sensor get AE measurement window mode configuration * * @param ae_mode int * * @return None */static void mt9v111_get_ae_mode(int *ae_mode){ if (ae_mode != NULL) { *ae_mode = (mt9v111_device.ifpReg->modeControl & 0xc) >> 2; }}/*! * mt9v111 sensor enable/disable AE * * @param active int * @return None */static void mt9v111_set_ae(int active){ u8 reg; u16 data; mt9v111_device.ifpReg->modeControl &= 0xfff3; mt9v111_device.ifpReg->modeControl |= (active & 0x01) << 14; reg = MT9V111I_ADDR_SPACE_SEL; data = mt9v111_device.ifpReg->addrSpaceSel; mt9v111_write_reg(reg, data); reg = MT9V111I_MODE_CONTROL; data = mt9v111_device.ifpReg->modeControl; mt9v111_write_reg(reg, data);}/*! * mt9v111 sensor enable/disable auto white balance * * @param active int * @return None */static void mt9v111_set_awb(int active){ u8 reg; u16 data; mt9v111_device.ifpReg->modeControl &= 0xfff3; mt9v111_device.ifpReg->modeControl |= (active & 0x01) << 1; reg = MT9V111I_ADDR_SPACE_SEL; data = mt9v111_device.ifpReg->addrSpaceSel; mt9v111_write_reg(reg, data); reg = MT9V111I_MODE_CONTROL; data = mt9v111_device.ifpReg->modeControl; mt9v111_write_reg(reg, data);}/*! * mt9v111 sensor set the flicker control * * @param control int * @return None */static void mt9v111_flicker_control(int control){ u8 reg; u16 data; reg = MT9V111I_ADDR_SPACE_SEL; data = mt9v111_device.ifpReg->addrSpaceSel; mt9v111_write_reg(reg, data); switch (control) { case MT9V111_FLICKER_DISABLE: mt9v111_device.ifpReg->formatControl &= ~(0x01 << 11); reg = MT9V111I_FORMAT_CONTROL; data = mt9v111_device.ifpReg->formatControl; mt9v111_write_reg(reg, data); break; case MT9V111_FLICKER_MANUAL_50: if (!(mt9v111_device.ifpReg->formatControl & (0x01 << 11))) { mt9v111_device.ifpReg->formatControl |= (0x01 << 11); reg = MT9V111I_FORMAT_CONTROL; data = mt9v111_device.ifpReg->formatControl; mt9v111_write_reg(reg, data); } mt9v111_device.ifpReg->flickerCtrl = 0x01; reg = MT9V111I_FLICKER_CONTROL; data = mt9v111_device.ifpReg->flickerCtrl; mt9v111_write_reg(reg, data); break; case MT9V111_FLICKER_MANUAL_60: if (!(mt9v111_device.ifpReg->formatControl & (0x01 << 11))) { mt9v111_device.ifpReg->formatControl |= (0x01 << 11); reg = MT9V111I_FORMAT_CONTROL; data = mt9v111_device.ifpReg->formatControl; mt9v111_write_reg(reg, data); } mt9v111_device.ifpReg->flickerCtrl = 0x03; reg = MT9V111I_FLICKER_CONTROL; data = mt9v111_device.ifpReg->flickerCtrl; mt9v111_write_reg(reg, data); break; case MT9V111_FLICKER_AUTO_DETECTION: if (!(mt9v111_device.ifpReg->formatControl & (0x01 << 11))) { mt9v111_device.ifpReg->formatControl |= (0x01 << 11); reg = MT9V111I_FORMAT_CONTROL; data = mt9v111_device.ifpReg->formatControl; mt9v111_write_reg(reg, data); } mt9v111_device.ifpReg->flickerCtrl = 0x10; reg = MT9V111I_FLICKER_CONTROL; data = mt9v111_device.ifpReg->flickerCtrl; mt9v111_write_reg(reg, data); break; } return;}/*! * mt9v111 Get mode&flicker control parameters * * @return None */static void mt9v111_get_control_params(int *ae, int *awb, int *flicker){ if ((ae != NULL) && (awb != NULL) && (flicker != NULL)) { *ae = (mt9v111_device.ifpReg->modeControl & 0x4000) >> 14; *awb = (mt9v111_device.ifpReg->modeControl & 0x02) >> 1; *flicker = (mt9v111_device.ifpReg->formatControl & 0x800) >> 9; if (*flicker) { *flicker = (mt9v111_device.ifpReg->flickerCtrl & 0x03); switch (*flicker) { case 1: *flicker = MT9V111_FLICKER_MANUAL_50; break; case 3: *flicker = MT9V111_FLICKER_MANUAL_60; break; default: *flicker = MT9V111_FLICKER_AUTO_DETECTION; break; } } else *flicker = MT9V111_FLICKER_DISABLE; } return;}/*! * mt9v111 Reset function * * @return None */static sensor_interface *mt9v111_reset(void){ return mt9v111_config(&reset_frame_rate, 0);}/*! * mt9v111 get_status function * * @return int */static int mt9v111_get_status(void){ int retval = 0; u8 reg; u16 data = 0; if (!interface_param) return -ENODEV; reg = MT9V111I_ADDR_SPACE_SEL; data = MT9V111I_SEL_SCA; retval = mt9v111_write_reg(reg, data); reg = MT9V111S_SENSOR_CORE_VERSION; retval = mt9v111_read_reg(®, &data); data = mt9v111_endian_swap16(data); if (MT9V111_CHIP_VERSION != data) retval = -ENODEV; return retval;}struct camera_sensor camera_sensor_if = { .set_color = mt9v111_set_color, .get_color = mt9v111_get_color, .set_ae_mode = mt9v111_set_ae_mode, .get_ae_mode = mt9v111_get_ae_mode, .set_ae = mt9v111_set_ae, .set_awb = mt9v111_set_awb, .flicker_control = mt9v111_flicker_control, .get_control_params = mt9v111_get_control_params, .config = mt9v111_config, .reset = mt9v111_reset, .get_status = mt9v111_get_status,};#ifdef MT9V111_DEBUG/*! * Set sensor to test mode, which will generate test pattern. * * @return none */static void mt9v111_test_pattern(bool flag){ u8 reg; u16 data; // switch to sensor registers reg = MT9V111I_ADDR_SPACE_SEL; data = MT9V111I_SEL_SCA; mt9v111_write_reg(reg, data); if (flag == true) { testpattern = MT9V111S_OUTCTRL_TEST_MODE; reg = MT9V111S_ROW_NOISE_CTRL; data = mt9v111_read_reg(®, &data) & 0xBF; data = mt9v111_endian_swap16(data); mt9v111_write_reg(reg, data); reg = MT9V111S_TEST_DATA; data = 0; mt9v111_write_reg(reg, data); reg = MT9V111S_OUTPUT_CTRL; // changes take effect data = MT9V111S_OUTCTRL_CHIP_ENABLE | testpattern | 0x3000; mt9v111_write_reg(reg, data); } else { testpattern = 0; reg = MT9V111S_ROW_NOISE_CTRL; data = mt9v111_read_reg(®, &data) | 0x40; data = mt9v111_endian_swap16(data); mt9v111_write_reg(reg, data); reg = MT9V111S_OUTPUT_CTRL; // changes take effect data = MT9V111S_OUTCTRL_CHIP_ENABLE | testpattern | 0x3000; mt9v111_write_reg(reg, data); }}#endif/*! * mt9v111 I2C detect_client function * * @param adapter struct i2c_adapter * * @param address int * @param kind int * * @return Error code indicating success or failure */static int mt9v111_detect_client(struct i2c_adapter *adapter, int address, int kind){ mt9v111_i2c_client.adapter = adapter; if (i2c_attach_client(&mt9v111_i2c_client)) { mt9v111_i2c_client.adapter = NULL; printk(KERN_ERR "mt9v111_attach: i2c_attach_client failed\n"); return -1; } interface_param = (sensor_interface *) kmalloc(sizeof(sensor_interface), GFP_KERNEL); if (!interface_param) { printk(KERN_ERR "mt9v111_attach: kmalloc failed \n"); return -1; } printk(KERN_INFO "MT9V111 Detected\n"); return 0;}static unsigned short normal_i2c[] = { MT9V111_I2C_ADDRESS, I2C_CLIENT_END };/* Magic definition of all other variables and things */I2C_CLIENT_INSMOD;/*! * mt9v111 I2C attach function * * @param adapter struct i2c_adapter * * @return Error code indicating success or failure */static int mt9v111_attach(struct i2c_adapter *adap){ uint32_t mclk = 27000000; struct clk *clk; int err; clk = clk_get(NULL, "csi_clk"); clk_enable(clk); set_mclk_rate(&mclk); err = i2c_probe(adap, &addr_data, &mt9v111_detect_client); clk_disable(clk); clk_put(clk); return err;}/*! * mt9v111 I2C detach function * * @param client struct i2c_client * * @return Error code indicating success or failure */static int mt9v111_detach(struct i2c_client *client){ int err; if (!mt9v111_i2c_client.adapter) return -1; err = i2c_detach_client(&mt9v111_i2c_client); mt9v111_i2c_client.adapter = NULL; if (interface_param) kfree(interface_param); interface_param = NULL; return err;}extern void gpio_sensor_active(void);/*! * MT9V111 init function * * @return Error code indicating success or failure */static __init int mt9v111_init(void){ u8 err; gpio_sensor_active(); mt9v111_device.coreReg = (mt9v111_coreReg *) kmalloc(sizeof(mt9v111_coreReg), GFP_KERNEL); if (!mt9v111_device.coreReg) return -1; memset(mt9v111_device.coreReg, 0, sizeof(mt9v111_coreReg)); mt9v111_device.ifpReg = (mt9v111_IFPReg *) kmalloc(sizeof(mt9v111_IFPReg), GFP_KERNEL); if (!mt9v111_device.ifpReg) { kfree(mt9v111_device.coreReg); mt9v111_device.coreReg = NULL; return -1; } memset(mt9v111_device.ifpReg, 0, sizeof(mt9v111_IFPReg)); err = i2c_add_driver(&mt9v111_i2c_driver); return err;}extern void gpio_sensor_inactive(void);/*! * MT9V111 cleanup function * * @return Error code indicating success or failure */static void __exit mt9v111_clean(void){ if (mt9v111_device.coreReg) { kfree(mt9v111_device.coreReg); mt9v111_device.coreReg = NULL; } if (mt9v111_device.ifpReg) { kfree(mt9v111_device.ifpReg); mt9v111_device.ifpReg = NULL; } i2c_del_driver(&mt9v111_i2c_driver); gpio_sensor_inactive();}module_init(mt9v111_init);module_exit(mt9v111_clean);/* Exported symbols for modules. */EXPORT_SYMBOL(camera_sensor_if);MODULE_AUTHOR("Freescale Semiconductor, Inc.");MODULE_DESCRIPTION("Mt9v111 Camera Driver");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -