/* This function called by vpif driver to initialize the decoder with default * values */ static int mt9t001_initialize(void *dec, int flag) { int err = 0; int ch_id; v4l2_std_id std; int index; struct i2c_client *ch_client; if (NULL == dec) { printk(KERN_ERR "dec:NULL pointer"); return -EINVAL; } ch_id = ((struct decoder_device *)dec)->channel_id; ch_client = &mt9t001_channel_info[ch_id].i2c_dev.client; if (mt9t001_channel_info[ch_id].i2c_dev.i2c_registration & 0x01) { printk(KERN_ERR "MT9T001 driver is already initialized..\n"); err = -EINVAL; return err; } /* Register MT9T001 I2C client */ err |= i2c_add_driver(&mt9t001_channel_info[ch_id].i2c_dev.driver); if (err) { printk(KERN_ERR "Failed to register MT9T001 I2C client.\n"); return -EINVAL; } mt9t001_channel_info[ch_id].i2c_dev.i2c_registration |= 0x1; mt9t001_channel_info[ch_id].dec_device = (struct decoder_device *)dec; dev_dbg(mt9t001_i2c_dev[ch_id], "Mt9t001 driver registered\n"); if (DECODER_I2C_BIND_FLAG == flag) { /* check that decoder is set with default values once or not, * if yes return, if not continue */ if (mt9t001_channel_info[ch_id].i2c_dev.i2c_registration & 0x02) return err; } dev_dbg(mt9t001_i2c_dev[ch_id], "Starting mt9t001_init....\n"); if (mt9xxx_set_input_mux(0) < 0) dev_dbg(mt9t001_i2c_dev[ch_id], "Video Mux setting failed\n"); msleep(100); /*Configure the MT9T001 in normalpower up mode */ err |= mt9t001_i2c_write_reg(ch_client, MT9T001_ROW_START, MT9T001_ROW_START_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_COL_START, MT9T001_COLUMN_START_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_WIDTH, MT9T001_ROW_SIZE_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_HEIGHT, MT9T001_COLUMN_SIZE_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_HBLANK, MT9T001_HOR_BLANK_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_VBLANK, MT9T001_VER_BLANK_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_OUTPUT_CTRL, MT9T001_OUTPUT_CTRL_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_SHUTTER_WIDTH_UPPER, MT9T001_SHUTTER_WIDTH_UPPER_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_SHUTTER_WIDTH, MT9T001_SHUTTER_WIDTH_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_PIXEL_CLK_CTRL, MT9T001_PIXEL_CLK_CTRL_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_RESTART, MT9T001_FRAME_RESTART_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_SHUTTER_DELAY, MT9T001_SHUTTER_DELAY_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_READ_MODE1, MT9T001_READ_MODE1_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_READ_MODE2, MT9T001_READ_MODE2_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_READ_MODE3, MT9T001_READ_MODE3_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_ROW_ADDR_MODE, MT9T001_ROW_ADDR_MODE_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_COL_ADDR_MODE, MT9T001_COL_ADDR_MODE_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_GREEN1_GAIN, MT9T001_GREEN1_GAIN_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_BLUE_GAIN, MT9T001_BLUE_GAIN_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_RED_GAIN, MT9T001_RED_GAIN_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_GREEN2_GAIN, MT9T001_GREEN2_GAIN_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_GLOBAL_GAIN, MT9T001_GLOBAL_GAIN_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_BLACK_LEVEL, MT9T001_BLACK_LEVEL_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_CAL_COARSE, MT9T001_CAL_COARSE_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_CAL_TARGET, MT9T001_CAL_TARGET_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_GREEN1_OFFSET, MT9T001_GREEN1_OFFSET_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_GREEN2_OFFSET, MT9T001_GREEN2_OFFSET_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_RED_OFFSET, MT9T001_RED_OFFSET_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_BLUE_OFFSET, MT9T001_BLUE_OFFSET_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_BLK_LVL_CALIB, MT9T001_BLK_LVL_CALIB_DEFAULT, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_CHIP_ENABLE_SYNC, MT9T001_CHIP_ENABLE_SYNC_DEFAULT, MT9T001_I2C_CONFIG); /* Reset the sensor to be in default power up state */ err |= mt9t001_i2c_write_reg(ch_client, MT9T001_RESET, MT9T001_RESET_ENABLE, MT9T001_I2C_CONFIG); /* Clear the bit to resume normal operation */ err |= mt9t001_i2c_write_reg(ch_client, MT9T001_RESET, MT9T001_RESET_DISABLE, MT9T001_I2C_CONFIG); /* delay applying changes */ err |= mt9t001_i2c_write_reg(ch_client, MT9T001_OUTPUT_CTRL, MT9T001_N0_CHANGE_MODE, MT9T001_I2C_CONFIG); err |= mt9t001_i2c_write_reg(ch_client, MT9T001_PIXEL_CLK_CTRL, MT9T001_PIX_CLK_RISING, MT9T001_I2C_CONFIG); /*Configure the MT9T001 in normalpower up mode */ err |= mt9t001_i2c_write_reg(ch_client, MT9T001_OUTPUT_CTRL, MT9T001_NORMAL_OPERATION_MODE, MT9T001_I2C_CONFIG); /* call set standard */ std = mt9t001_channel_info[ch_id].params.std; err |= mt9t001_setstd(&std, dec); /* call query standard */ err |= mt9t001_querystd(&std, dec); /* call get input */ err |= mt9t001_getinput(&index, dec); /* Configure for default video standard */ if (err < 0) { err = -EINVAL; mt9t001_deinitialize(dec); return err; } mt9t001_channel_info[ch_id].i2c_dev.i2c_registration |= 0x2; dev_dbg(mt9t001_i2c_dev[ch_id], "End of mt9t001_init.\n"); return err; }
/* This function will configure MT9T001 for bayer pattern capture */ static int mt9t001_setparams(void *params, void *dec) { int err = 0; unsigned short val; int ch_id; struct mt9t001_params *mt9t_params = (struct mt9t001_params *) params; if (NULL == dec) { printk(KERN_ERR "NULL Pointer\n"); return -EINVAL; } ch_id = ((struct decoder_device *)dec)->channel_id; dev_dbg(mt9t001_i2c_dev[ch_id], "Start of mt9t001 set params function.\n"); /* check for null pointer */ if (mt9t_params == NULL) { dev_err(mt9t001_i2c_dev[ch_id], "Null pointer.\n"); return -EINVAL; } err |= mt9t001_setinput(&(mt9t_params->inputidx), dec); if (err < 0) { dev_dbg(mt9t001_i2c_dev[ch_id], "Set format parameters failed.\n"); return err; } err |= mt9t001_setstd(&(mt9t_params->std), dec); if (err < 0) { dev_dbg(mt9t001_i2c_dev[ch_id], "Set format parameters failed.\n"); return err; } /* set video format related parameters */ err = mt9t001_set_format_params(&mt9t_params->format, dec); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "Set format parameters failed.\n"); return err; } /*Write the gain information */ val = (unsigned short)(mt9t_params->rgb_gain. green1_analog_gain & MT9T001_ANALOG_GAIN_MASK); val |= ((mt9t_params->rgb_gain. green1_digital_gain << MT9T001_DIGITAL_GAIN_SHIFT) & MT9T001_DIGITAL_GAIN_MASK); err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_GREEN1_GAIN, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails....\n"); return err; } val = (unsigned short)(mt9t_params->rgb_gain.red_analog_gain) & MT9T001_ANALOG_GAIN_MASK; val |= (((mt9t_params->rgb_gain.red_digital_gain) << MT9T001_DIGITAL_GAIN_SHIFT) & MT9T001_DIGITAL_GAIN_MASK); err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_RED_GAIN, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } val = (unsigned short)(mt9t_params->rgb_gain.blue_analog_gain) & MT9T001_ANALOG_GAIN_MASK; val |= (((mt9t_params->rgb_gain.blue_digital_gain) << MT9T001_DIGITAL_GAIN_SHIFT) & MT9T001_DIGITAL_GAIN_MASK); err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_BLUE_GAIN, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } val = (unsigned short)((mt9t_params->rgb_gain.green2_analog_gain) << MT9T001_ANALOG_GAIN_SHIFT) & MT9T001_ANALOG_GAIN_MASK; val |= (((mt9t_params->rgb_gain. green2_digital_gain) << MT9T001_DIGITAL_GAIN_SHIFT) & MT9T001_DIGITAL_GAIN_MASK); err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_GREEN2_GAIN, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } /*Write the offset value in register */ val = mt9t_params->black_calib.green1_offset & MT9T001_GREEN1_OFFSET_MASK; err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_GREEN1_OFFSET, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } val = mt9t_params->black_calib.green2_offset & MT9T001_GREEN2_OFFSET_MASK; err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_GREEN2_OFFSET, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } val = mt9t_params->black_calib.red_offset & MT9T001_RED_OFFSET_MASK; err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_RED_OFFSET, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } val = mt9t_params->black_calib.blue_offset & MT9T001_BLUE_OFFSET_MASK; err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_BLUE_OFFSET, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } /*Write other black caliberation information */ val = (unsigned short)(mt9t_params->black_calib.manual_override) & MT9T001_MANUAL_OVERRIDE_MASK; val |= ((mt9t_params->black_calib. disable_calibration) << MT9T001_DISABLE_CALLIBERATION_SHIFT) & MT9T001_DISABLE_CALLIBERATION_MASK; val |= ((mt9t_params->black_calib. recalculate_black_level) << MT9T001_RECAL_BLACK_LEVEL_SHIFT) & MT9T001_RECAL_BLACK_LEVEL_MASK; val |= ((mt9t_params->black_calib.lock_red_blue_calibration) << MT9T001_LOCK_RB_CALIBRATION_SHIFT) & MT9T001_LOCK_RB_CALLIBERATION_MASK; val |= ((mt9t_params->black_calib.lock_green_calibration) << MT9T001_LOCK_GREEN_CALIBRATION_SHIFT) & MT9T001_LOCK_GREEN_CALLIBERATION_MASK; err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_BLK_LVL_CALIB, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } /*Write Thresholds Value */ val = (unsigned short)mt9t_params->black_calib. low_coarse_thrld & MT9T001_LOW_COARSE_THELD_MASK; val |= (mt9t_params->black_calib. high_coarse_thrld << MT9T001_HIGH_COARSE_THELD_SHIFT) & MT9T001_HIGH_COARSE_THELD_MASK; err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_CAL_COARSE, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } val = (unsigned short)mt9t_params->black_calib.low_target_thrld & MT9T001_LOW_TARGET_THELD_MASK; val |= (mt9t_params->black_calib.high_target_thrld << MT9T001_HIGH_TARGET_THELD_SHIFT) & MT9T001_HIGH_TARGET_THELD_MASK; err = mt9t001_i2c_write_reg(&mt9t001_channel_info[ch_id].i2c_dev. client, MT9T001_CAL_TARGET, val, MT9T001_I2C_CONFIG); if (err < 0) { dev_err(mt9t001_i2c_dev[ch_id], "I2C write fails...\n"); return err; } mt9t001_channel_info[ch_id].params = *mt9t_params; dev_dbg(mt9t001_i2c_dev[ch_id], "End of mt9t001 set params...\n"); return err; }
/*This function will provide different control commands for MT9T001 configuration.*/ int mt9t001_ctrl(unsigned int cmd, void *arg, void *params) { int err = 0; printk("WARNING ... Here is in MT9T001 CTRL Func...\n"); switch (cmd) { case MT9T001_SET_PARAMS: { struct mt9t001_params *vpfe_mt9t001params = (struct mt9t001_params *)params; struct mt9t001_params *user_mt9t001params = (struct mt9t001_params *)arg; /* Update the global parameter of vpfe_obj */ if ((arg == NULL) || (params == NULL)) { dev_err(mt9t001_i2c_dev, "Invalid argument for \ MT9T001_SET_PARAMS "); return -1; } memcpy(vpfe_mt9t001params, user_mt9t001params, sizeof(struct mt9t001_params)); err = mt9t001_setparams(arg); if (err < 0) { dev_err(mt9t001_i2c_dev, "\nMT9T001 set parameters fails..."); return err; } break; } case MT9T001_SET_STD: { err = mt9t001_setstd(arg, params); if (err < 0) { dev_err(mt9t001_i2c_dev, "\nMT9T001 set standard fails..."); return err; } else { //mt9t001_readregs(); } break; } case MT9T001_GET_PARAMS: { struct mt9t001_params *vpfe_mt9t001params = (struct mt9t001_params *)params; struct mt9t001_params *user_mt9t001params = (struct mt9t001_params *)arg; err = mt9t001_getparams(arg); if (err < 0) { dev_err(mt9t001_i2c_dev, "\nMT9T001 get parameters fails..."); return err; } /* Update the global parameter of vpfe_obj */ memcpy(vpfe_mt9t001params, user_mt9t001params, sizeof(struct mt9t001_params)); break; } case MT9T001_ENABLE_I2C_SWITCH: /* enable the i2c switch on the MT9T031 head board */ CONFIG_PCA9543A = 1; break; case MT9T001_INIT: { err = mt9t001_init(arg, params); if (err < 0) { printk(KERN_ERR "\n Unable to initialize MT9T001..."); return err; } break; } case MT9T001_CLEANUP: { mt9t001_cleanup(params); break; } case VIDIOC_S_CTRL: { struct v4l2_control *ctrl = arg; if (ctrl->id == V4L2_CID_GAIN) { err = mt9t001_setgain((int)ctrl->value); if (err < 0) { dev_err(mt9t001_i2c_dev, "\n MT9T001 set gain fails..."); return err; } } else { err = -EINVAL; } break; } case VIDIOC_G_CTRL: { struct v4l2_control *ctrl = arg; if (ctrl->id == V4L2_CID_GAIN) { err = mt9t001_getgain((int *) &(ctrl->value)); if (err < 0) { dev_err(mt9t001_i2c_dev, "\n MT9T001 get gain fails..."); return err; } } else { err = -EINVAL; } break; } case VIDIOC_QUERYCTRL: { err = mt9t001_queryctrl(arg); break; } default: { dev_err(mt9t001_i2c_dev, "\n Undefined command"); return -1; } }