static int sensor_2p8_cis_group_param_hold_func(struct v4l2_subdev *subdev, unsigned int hold) { int ret = 0; struct fimc_is_cis *cis = NULL; struct i2c_client *client = NULL; BUG_ON(!subdev); cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev); BUG_ON(!cis); BUG_ON(!cis->cis_data); client = cis->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } if (hold == cis->cis_data->group_param_hold) { pr_debug("already group_param_hold (%d)\n", cis->cis_data->group_param_hold); goto p_err; } ret = fimc_is_sensor_write8(client, 0x0104, hold); if (ret < 0) goto p_err; cis->cis_data->group_param_hold = hold; ret = 1; p_err: return ret; }
int sensor_8b1_s_exposure(struct v4l2_subdev *subdev, u64 exposure) { int ret = 0; u8 value; struct fimc_is_module_enum *sensor; struct i2c_client *client; BUG_ON(!subdev); pr_info("%s(%d)\n", __func__, (u32)exposure); sensor = (struct fimc_is_module_enum *)v4l2_get_subdevdata(subdev); if (unlikely(!sensor)) { err("sensor is NULL"); ret = -EINVAL; goto p_err; } client = sensor->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } value = exposure & 0xFF; fimc_is_sensor_write8(client, SENSOR_REG_VIS_AE_TARGET, value); p_err: return ret; }
int sensor_8b1_stream_off(struct v4l2_subdev *subdev) { int ret = 0; struct fimc_is_module_enum *sensor; struct i2c_client *client; BUG_ON(!subdev); sensor = (struct fimc_is_module_enum *)v4l2_get_subdevdata(subdev); if (unlikely(!sensor)) { err("sensor is NULL"); ret = -EINVAL; goto p_err; } client = sensor->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } ret = fimc_is_sensor_write8(client, 0x4100, 0); if (ret < 0) { err("fimc_is_sensor_write8 is fail(%d)", ret); goto p_err; } p_err: return ret; }
static int sensor_imx219_init(struct v4l2_subdev *subdev, u32 val) { int i, ret = 0; struct fimc_is_module_enum *module; struct fimc_is_module_imx219 *module_imx219; struct i2c_client *client; BUG_ON(!subdev); module = (struct fimc_is_module_enum *)v4l2_get_subdevdata(subdev); module_imx219 = module->private_data; client = module->client; module_imx219->system_clock = 146 * 1000 * 1000; module_imx219->line_length_pck = 146 * 1000 * 1000; pr_info("%s\n", __func__); /* sensor init */ for (i = 0; i < ARRAY_SIZE(setfile_vision_imx219); i++) { fimc_is_sensor_write8(client, setfile_vision_imx219[i][0], (u8)setfile_vision_imx219[i][1]); } pr_info("[MOD:D:%d] %s(%d)\n", module->id, __func__, val); return ret; }
/* * @ brief * frame duration time * @ unit * nano second * @ remarks */ int sensor_8b1_s_duration(struct v4l2_subdev *subdev, u64 duration) { int ret = 0; u8 value[2]; struct fimc_is_module_enum *sensor; struct i2c_client *client; BUG_ON(!subdev); pr_info("%s\n", __func__); sensor = (struct fimc_is_module_enum *)v4l2_get_subdevdata(subdev); if (unlikely(!sensor)) { err("sensor is NULL"); ret = -EINVAL; goto p_err; } client = sensor->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } /* * forcely set 10fps for 8b1, * because the formula to calc framerate setting is confidential. */ value[0] = 0x52; value[1] = 0x0; fimc_is_sensor_write8(client, SENSOR_REG_VIS_DURATION_MSB, value[1]); fimc_is_sensor_write8(client, SENSOR_REG_VIS_DURATION_LSB, value[0]); p_err: return ret; }
int sensor_2p8_cis_stream_off(struct v4l2_subdev *subdev) { int ret = 0; struct fimc_is_cis *cis; struct i2c_client *client; cis_shared_data *cis_data; #ifdef DEBUG_SENSOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif BUG_ON(!subdev); cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev); BUG_ON(!cis); BUG_ON(!cis->cis_data); client = cis->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } cis_data = cis->cis_data; dbg_sensor("[MOD:D:%d] %s\n", cis->id, __func__); sensor_2p8_cis_group_param_hold_func(subdev, 0x00); /* Sensor stream off */ fimc_is_sensor_write16(client, 0x6028, 0x4000); fimc_is_sensor_write8(client, 0x0100, 0x00); cis_data->stream_on = false; #ifdef DEBUG_SENSOR_TIME do_gettimeofday(&end); dbg_sensor("[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec)*1000000 + (end.tv_usec - st.tv_usec)); #endif p_err: return ret; }
static int sensor_8b1_init(struct v4l2_subdev *subdev, u32 val) { int ret = 0; struct fimc_is_module_enum *module; struct fimc_is_module_8b1 *module_8b1; struct i2c_client *client; BUG_ON(!subdev); module = (struct fimc_is_module_enum *)v4l2_get_subdevdata(subdev); module_8b1 = module->private_data; client = module->client; module_8b1->system_clock = 146 * 1000 * 1000; module_8b1->line_length_pck = 146 * 1000 * 1000; pr_info("%s\n", __func__); /* sensor init */ fimc_is_sensor_write8(client, 0x4200, 0x01); fimc_is_sensor_write8(client, 0x4201, 0x24); fimc_is_sensor_write8(client, 0x4305, 0x06); fimc_is_sensor_write8(client, 0x4307, 0xC0); fimc_is_sensor_write8(client, 0x4342, 0x03); fimc_is_sensor_write8(client, 0x4343, 0x90); fimc_is_sensor_write8(client, 0x4345, 0x08); fimc_is_sensor_write8(client, 0x4347, 0x08); fimc_is_sensor_write8(client, 0x4348, 0x07); fimc_is_sensor_write8(client, 0x4349, 0x83); /* 10 */ fimc_is_sensor_write8(client, 0x434A, 0x04); fimc_is_sensor_write8(client, 0x434B, 0x3A); fimc_is_sensor_write8(client, 0x434C, 0x01); fimc_is_sensor_write8(client, 0x434D, 0x40); fimc_is_sensor_write8(client, 0x434E, 0x00); fimc_is_sensor_write8(client, 0x434F, 0xB4); fimc_is_sensor_write8(client, 0x4381, 0x01); fimc_is_sensor_write8(client, 0x4383, 0x05); fimc_is_sensor_write8(client, 0x4385, 0x06); fimc_is_sensor_write8(client, 0x4387, 0x06); /* 20 */ fimc_is_sensor_write8(client, 0x5004, 0x01); fimc_is_sensor_write8(client, 0x5005, 0x1E); #ifdef VISION_30FPS fimc_is_sensor_write8(client, 0x5014, 0x05); fimc_is_sensor_write8(client, 0x5015, 0x73); #else fimc_is_sensor_write8(client, 0x5014, 0x13); fimc_is_sensor_write8(client, 0x5015, 0x33); #endif fimc_is_sensor_write8(client, 0x5016, 0x00); fimc_is_sensor_write8(client, 0x5017, 0x02); fimc_is_sensor_write8(client, 0x5030, 0x0E); fimc_is_sensor_write8(client, 0x5031, 0x10); fimc_is_sensor_write8(client, 0x5034, 0x00); fimc_is_sensor_write8(client, 0x5035, 0x02); /* 30 */ fimc_is_sensor_write8(client, 0x5036, 0x00); fimc_is_sensor_write8(client, 0x5037, 0x04); fimc_is_sensor_write8(client, 0x5038, 0xC0); fimc_is_sensor_write8(client, 0x503D, 0x20); fimc_is_sensor_write8(client, 0x503E, 0x70); fimc_is_sensor_write8(client, 0x503F, 0x02); fimc_is_sensor_write8(client, 0x600A, 0x3A); fimc_is_sensor_write8(client, 0x600E, 0x05); fimc_is_sensor_write8(client, 0x6014, 0x27); fimc_is_sensor_write8(client, 0x6015, 0x1D); /* 40 */ fimc_is_sensor_write8(client, 0x6018, 0x01); fimc_is_sensor_write8(client, 0x6026, 0x00); #ifdef VISION_30FPS fimc_is_sensor_write8(client, 0x6027, 0x1B); #else fimc_is_sensor_write8(client, 0x6027, 0x52); #endif fimc_is_sensor_write8(client, 0x6029, 0x08); fimc_is_sensor_write8(client, 0x602A, 0x08); fimc_is_sensor_write8(client, 0x602B, 0x00); fimc_is_sensor_write8(client, 0x602c, 0x00); fimc_is_sensor_write8(client, 0x6032, 0x63); fimc_is_sensor_write8(client, 0x6033, 0x94); fimc_is_sensor_write8(client, 0x7007, 0x18); /* 50 */ fimc_is_sensor_write8(client, 0x7015, 0x28); fimc_is_sensor_write8(client, 0x7016, 0x2C); fimc_is_sensor_write8(client, 0x7027, 0x14); fimc_is_sensor_write8(client, 0x7028, 0x3C); fimc_is_sensor_write8(client, 0x7029, 0x02); fimc_is_sensor_write8(client, 0x702A, 0x02); fimc_is_sensor_write8(client, 0x703A, 0x04); fimc_is_sensor_write8(client, 0x703B, 0x36); fimc_is_sensor_write8(client, 0x7042, 0x04); fimc_is_sensor_write8(client, 0x7043, 0x36); /* 60 */ fimc_is_sensor_write8(client, 0x7058, 0x6F); fimc_is_sensor_write8(client, 0x705A, 0x01); fimc_is_sensor_write8(client, 0x705C, 0x40); fimc_is_sensor_write8(client, 0x7060, 0x07); fimc_is_sensor_write8(client, 0x7061, 0x40); fimc_is_sensor_write8(client, 0x7064, 0x43); fimc_is_sensor_write8(client, 0x706D, 0x77); fimc_is_sensor_write8(client, 0x706E, 0xFA); fimc_is_sensor_write8(client, 0x7070, 0x0A); fimc_is_sensor_write8(client, 0x7073, 0x04); /* 70 */ fimc_is_sensor_write8(client, 0x7087, 0x00); fimc_is_sensor_write8(client, 0x7090, 0x01); fimc_is_sensor_write8(client, 0x7115, 0x01); fimc_is_sensor_write8(client, 0x7209, 0xF5); fimc_is_sensor_write8(client, 0x720B, 0xF5); fimc_is_sensor_write8(client, 0x7245, 0xC4); fimc_is_sensor_write8(client, 0x7301, 0x02); fimc_is_sensor_write8(client, 0x7306, 0x02); fimc_is_sensor_write8(client, 0x7339, 0x03); fimc_is_sensor_write8(client, 0x7351, 0x00); /* 80 */ fimc_is_sensor_write8(client, 0x7352, 0xC0); fimc_is_sensor_write8(client, 0x7405, 0x28); fimc_is_sensor_write8(client, 0x7406, 0x28); fimc_is_sensor_write8(client, 0x7407, 0xC0); fimc_is_sensor_write8(client, 0x740C, 0x60); fimc_is_sensor_write8(client, 0x740D, 0x00); fimc_is_sensor_write8(client, 0x7436, 0x03); fimc_is_sensor_write8(client, 0x7437, 0x03); fimc_is_sensor_write8(client, 0x7454, 0x01); fimc_is_sensor_write8(client, 0x7460, 0x00); /* 90 */ fimc_is_sensor_write8(client, 0x7461, 0x01); fimc_is_sensor_write8(client, 0x7462, 0x68); fimc_is_sensor_write8(client, 0x7463, 0x1E); fimc_is_sensor_write8(client, 0x7464, 0x03); fimc_is_sensor_write8(client, 0x7465, 0x4B); fimc_is_sensor_write8(client, 0x7467, 0x20); fimc_is_sensor_write8(client, 0x7468, 0x20); fimc_is_sensor_write8(client, 0x7469, 0x20); fimc_is_sensor_write8(client, 0x746A, 0x20); fimc_is_sensor_write8(client, 0x746B, 0x20); /* 100 */ fimc_is_sensor_write8(client, 0x746C, 0x20); fimc_is_sensor_write8(client, 0x746D, 0x02); fimc_is_sensor_write8(client, 0x746E, 0x80); fimc_is_sensor_write8(client, 0x746F, 0x01); fimc_is_sensor_write8(client, 0x4100, 0x01); pr_info("[MOD:D:%d] %s(%d)\n", module->id, __func__, val); return ret; }
int sensor_2p8_cis_stream_on(struct v4l2_subdev *subdev) { int ret = 0; struct fimc_is_cis *cis; struct i2c_client *client; cis_shared_data *cis_data; #ifdef DEBUG_SENSOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif BUG_ON(!subdev); cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev); BUG_ON(!cis); BUG_ON(!cis->cis_data); client = cis->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } cis_data = cis->cis_data; dbg_sensor("[MOD:D:%d] %s\n", cis->id, __func__); sensor_2p8_cis_group_param_hold_func(subdev, 0x00); #ifdef DEBUG_2P8_PLL { u16 pll; fimc_is_sensor_read16(client, 0x0300, &pll); dbg_sensor("______ vt_pix_clk_div(%x)\n", pll); fimc_is_sensor_read16(client, 0x0302, &pll); dbg_sensor("______ vt_sys_clk_div(%x)\n", pll); fimc_is_sensor_read16(client, 0x0304, &pll); dbg_sensor("______ pre_pll_clk_div(%x)\n", pll); fimc_is_sensor_read16(client, 0x0306, &pll); dbg_sensor("______ pll_multiplier(%x)\n", pll); fimc_is_sensor_read16(client, 0x0308, &pll); dbg_sensor("______ op_pix_clk_div(%x)\n", pll); fimc_is_sensor_read16(client, 0x030a, &pll); dbg_sensor("______ op_sys_clk_div(%x)\n", pll); fimc_is_sensor_read16(client, 0x030c, &pll); dbg_sensor("______ secnd_pre_pll_clk_div(%x)\n", pll); fimc_is_sensor_read16(client, 0x030e, &pll); dbg_sensor("______ secnd_pll_multiplier(%x)\n", pll); fimc_is_sensor_read16(client, 0x0340, &pll); dbg_sensor("______ frame_length_lines(%x)\n", pll); fimc_is_sensor_read16(client, 0x0342, &pll); dbg_sensor("______ line_length_pck(%x)\n", pll); } #endif /* Sensor stream on */ fimc_is_sensor_write16(client, 0x6028, 0x4000); fimc_is_sensor_write8(client, 0x0100, 0x01); /* WDR */ if (cis_data->companion_data.enable_wdr == true) fimc_is_sensor_write8(client, 0x0216, 0x01); else fimc_is_sensor_write8(client, 0x0216, 0x00); cis_data->stream_on = true; #ifdef DEBUG_SENSOR_TIME do_gettimeofday(&end); dbg_sensor("[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec)*1000000 + (end.tv_usec - st.tv_usec)); #endif p_err: return ret; }
/* TODO: Sensor set size sequence(sensor done, sensor stop, 3AA done in FW case */ int sensor_2p8_cis_set_size(struct v4l2_subdev *subdev, cis_shared_data *cis_data) { int ret = 0; bool binning = false; u32 ratio_w = 0, ratio_h = 0, start_x = 0, start_y = 0, end_x = 0, end_y = 0; u32 even_x= 0, odd_x = 0, even_y = 0, odd_y = 0; struct i2c_client *client = NULL; struct fimc_is_cis *cis = NULL; #ifdef DEBUG_SENSOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif BUG_ON(!subdev); cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev); BUG_ON(!cis); dbg_sensor("[MOD:D:%d] %s\n", cis->id, __func__); if (unlikely(!cis_data)) { err("cis data is NULL"); if (unlikely(!cis->cis_data)) { ret = -EINVAL; goto p_err; } else { cis_data = cis->cis_data; } } client = cis->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } /* Wait actual stream off */ ret = sensor_2p8_wait_stream_off_status(cis_data); if (ret) { err("Must stream off\n"); ret = -EINVAL; goto p_err; } binning = cis_data->binning; if (binning) { ratio_w = (SENSOR_2P8_MAX_WIDTH / cis_data->cur_width); ratio_h = (SENSOR_2P8_MAX_HEIGHT / cis_data->cur_height); } else { ratio_w = 1; ratio_h = 1; } if (((cis_data->cur_width * ratio_w) > SENSOR_2P8_MAX_WIDTH) || ((cis_data->cur_height * ratio_h) > SENSOR_2P8_MAX_HEIGHT)) { err("Config max sensor size over~!!\n"); ret = -EINVAL; goto p_err; } /* 1. page_select */ ret = fimc_is_sensor_write16(client, 0x6028, 0x2000); if (ret < 0) goto p_err; /* 2. pixel address region setting */ start_x = ((SENSOR_2P8_MAX_WIDTH - cis_data->cur_width * ratio_w) / 2) & (~0x1); start_y = ((SENSOR_2P8_MAX_HEIGHT - cis_data->cur_height * ratio_h) / 2) & (~0x1); end_x = start_x + (cis_data->cur_width * ratio_w - 1); end_y = start_y + (cis_data->cur_height * ratio_h - 1); if (!(end_x & (0x1)) || !(end_y & (0x1))) { err("Sensor pixel end address must odd\n"); ret = -EINVAL; goto p_err; } ret = fimc_is_sensor_write16(client, 0x0344, start_x); if (ret < 0) goto p_err; ret = fimc_is_sensor_write16(client, 0x0346, start_y); if (ret < 0) goto p_err; ret = fimc_is_sensor_write16(client, 0x0348, end_x); if (ret < 0) goto p_err; ret = fimc_is_sensor_write16(client, 0x034A, end_y); if (ret < 0) goto p_err; /* 3. output address setting */ ret = fimc_is_sensor_write16(client, 0x034C, cis_data->cur_width); if (ret < 0) goto p_err; ret = fimc_is_sensor_write16(client, 0x034E, cis_data->cur_height); if (ret < 0) goto p_err; /* If not use to binning, sensor image should set only crop */ if (!binning) { dbg_sensor("Sensor size set is not binning\n"); goto p_err; } /* 4. sub sampling setting */ even_x = 1; /* 1: not use to even sampling */ even_y = 1; odd_x = (ratio_w * 2) - even_x; odd_y = (ratio_h * 2) - even_y; ret = fimc_is_sensor_write16(client, 0x0380, even_x); if (ret < 0) goto p_err; ret = fimc_is_sensor_write16(client, 0x0382, odd_x); if (ret < 0) goto p_err; ret = fimc_is_sensor_write16(client, 0x0384, even_y); if (ret < 0) goto p_err; ret = fimc_is_sensor_write16(client, 0x0386, odd_y); if (ret < 0) goto p_err; /* 5. binnig setting */ ret = fimc_is_sensor_write8(client, 0x0900, binning); /* 1: binning enable, 0: disable */ if (ret < 0) goto p_err; ret = fimc_is_sensor_write8(client, 0x0901, (ratio_w << 4) | ratio_h); if (ret < 0) goto p_err; /* 6. scaling setting: but not use */ /* scaling_mode (0: No scaling, 1: Horizontal, 2: Full) */ ret = fimc_is_sensor_write16(client, 0x0400, 0x0000); if (ret < 0) goto p_err; /* down_scale_m: 1 to 16 upwards (scale_n: 16(fixed)) down scale factor = down_scale_m / down_scale_n */ ret = fimc_is_sensor_write16(client, 0x0404, 0x0010); if (ret < 0) goto p_err; cis_data->frame_time = (cis_data->line_readOut_time * cis_data->cur_height / 1000); cis->cis_data->rolling_shutter_skew = (cis->cis_data->cur_height - 1) * cis->cis_data->line_readOut_time; dbg_sensor("[%s] frame_time(%d), rolling_shutter_skew(%lld)\n", __func__, cis->cis_data->frame_time, cis->cis_data->rolling_shutter_skew); #ifdef DEBUG_SENSOR_TIME do_gettimeofday(&end); dbg_sensor("[%s] time %lu us\n", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec)); #endif p_err: return ret; }