int sensor_2p8_cis_mode_change(struct v4l2_subdev *subdev, u32 mode) { int ret = 0; struct fimc_is_cis *cis = NULL; BUG_ON(!subdev); cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev); BUG_ON(!cis); BUG_ON(!cis->cis_data); if (mode > sensor_2p8_max_setfile_num) { err("invalid mode(%d)!!", mode); ret = -EINVAL; goto p_err; } sensor_2p8_cis_data_calculation(sensor_2p8_pllinfos[mode], cis->cis_data); ret = sensor_cis_set_registers(subdev, sensor_2p8_setfiles[mode], sensor_2p8_setfile_sizes[mode]); if (ret < 0) { err("sensor_2p8_set_registers fail!!"); goto p_err; } cis->cis_data->frame_time = (cis->cis_data->line_readOut_time * cis->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); dbg_sensor("[%s] mode changed(%d)\n", __func__, mode); p_err: return ret; }
int sensor_2p8_cis_get_digital_gain(struct v4l2_subdev *subdev, u32 *dgain) { int ret = 0; int hold = 0; struct fimc_is_cis *cis; struct i2c_client *client; u16 digital_gain = 0; #ifdef DEBUG_SENSOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif BUG_ON(!subdev); BUG_ON(!dgain); cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev); BUG_ON(!cis); client = cis->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } hold = sensor_2p8_cis_group_param_hold_func(subdev, 0x01); if (hold < 0) { ret = hold; goto p_err; } ret = fimc_is_sensor_read16(client, 0x020E, &digital_gain); if (ret < 0) goto p_err; *dgain = sensor_cis_calc_dgain_permile(digital_gain); dbg_sensor("[MOD:D:%d] %s, cur_dgain = %d us, digital_gain(%#x)\n", cis->id, __func__, *dgain, digital_gain); #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: if (hold > 0) { hold = sensor_2p8_cis_group_param_hold_func(subdev, 0x00); if (hold < 0) ret = hold; } return ret; }
int sensor_2p8_cis_set_frame_rate(struct v4l2_subdev *subdev, u32 min_fps) { int ret = 0; struct fimc_is_cis *cis; cis_shared_data *cis_data; u32 frame_duration = 0; #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); cis_data = cis->cis_data; if (min_fps > cis_data->max_fps) { err("[MOD:D:%d] %s, request FPS is too high(%d), set to max(%d)\n", cis->id, __func__, min_fps, cis_data->max_fps); min_fps = cis_data->max_fps; } if (min_fps == 0) { err("[MOD:D:%d] %s, request FPS is 0, set to min FPS(1)\n", cis->id, __func__); min_fps = 1; } frame_duration = (1 * 1000 * 1000) / min_fps; dbg_sensor("[MOD:D:%d] %s, set FPS(%d), frame duration(%d)\n", cis->id, __func__, min_fps, frame_duration); ret = sensor_2p8_cis_set_frame_duration(subdev, frame_duration); if (ret < 0) { err("[MOD:D:%d] %s, set frame duration is fail(%d)\n", cis->id, __func__, ret); goto p_err; } cis_data->min_frame_us_time = frame_duration; #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 void sensor_ak7348_print_log(int step) { int i; if (step > 0) { dbg_sensor("initial position "); for (i = 0; i < step; i++) { dbg_sensor(" %d", sysfs_actuator.init_positions[i]); } dbg_sensor(" setting"); } }
int sensor_2p8_cis_adjust_frame_duration(struct v4l2_subdev *subdev, u32 input_exposure_time, u32 *target_duration) { int ret = 0; struct fimc_is_cis *cis; cis_shared_data *cis_data; u32 vt_pic_clk_freq_mhz = 0; u32 line_length_pck = 0; u32 frame_length_lines = 0; u32 frame_duration = 0; #ifdef DEBUG_SENSOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif BUG_ON(!subdev); BUG_ON(!target_duration); cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev); BUG_ON(!cis); BUG_ON(!cis->cis_data); cis_data = cis->cis_data; vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000); line_length_pck = cis_data->line_length_pck; frame_length_lines = ((vt_pic_clk_freq_mhz * input_exposure_time) / line_length_pck); frame_length_lines += cis_data->max_margin_coarse_integration_time; frame_duration = (frame_length_lines * line_length_pck) / vt_pic_clk_freq_mhz; dbg_sensor("[%s](vsync cnt = %d) input exp(%d), adj duration, frame duraion(%d), min_frame_us(%d)\n", __func__, cis_data->sen_vsync_count, input_exposure_time, frame_duration, cis_data->min_frame_us_time); dbg_sensor("[%s](vsync cnt = %d) adj duration, frame duraion(%d), min_frame_us(%d)\n", __func__, cis_data->sen_vsync_count, frame_duration, cis_data->min_frame_us_time); *target_duration = MAX(frame_duration, cis_data->min_frame_us_time); #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 return ret; }
int sensor_2p8_cis_get_max_digital_gain(struct v4l2_subdev *subdev, u32 *max_dgain) { int ret = 0; struct fimc_is_cis *cis; struct i2c_client *client; cis_shared_data *cis_data; u16 read_value = 0; #ifdef DEBUG_SENSOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif BUG_ON(!subdev); BUG_ON(!max_dgain); 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; fimc_is_sensor_read16(client, 0x1086, &read_value); cis_data->max_digital_gain[0] = read_value; cis_data->max_digital_gain[1] = sensor_cis_calc_dgain_permile(read_value); *max_dgain = cis_data->max_digital_gain[1]; dbg_sensor("[%s] code %d, permile %d\n", __func__, cis_data->max_digital_gain[0], cis_data->max_digital_gain[1]); #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; }
int sensor_ak7348_actuator_set_position(struct v4l2_subdev *subdev, u32 *info) { int ret = 0; struct fimc_is_actuator *actuator; struct i2c_client *client; u32 position = 0; #ifdef DEBUG_ACTUATOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif BUG_ON(!subdev); BUG_ON(!info); dbg_sensor("%s\n", __func__); actuator = (struct fimc_is_actuator *)v4l2_get_subdevdata(subdev); BUG_ON(!actuator); client = actuator->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } position = *info; if (position > AK7348_POS_MAX_SIZE) { err("Invalid af position(position : %d, Max : %d).\n", position, AK7348_POS_MAX_SIZE); ret = -EINVAL; goto p_err; } /* position Set */ ret = sensor_ak7348_write_position(client, position); if (ret <0) goto p_err; actuator->position = position; dbg_sensor("Actuator position: %d\n", position); #ifdef DEBUG_ACTUATOR_TIME do_gettimeofday(&end); pr_info("[%s] time %lu us", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec)); #endif p_err: return ret; }
int sensor_2p8_cis_get_min_exposure_time(struct v4l2_subdev *subdev, u32 *min_expo) { int ret = 0; struct fimc_is_cis *cis = NULL; cis_shared_data *cis_data = NULL; u32 min_integration_time = 0; u32 min_coarse = 0; u32 min_fine = 0; u32 vt_pic_clk_freq_mhz = 0; u32 line_length_pck = 0; #ifdef DEBUG_SENSOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif BUG_ON(!subdev); BUG_ON(!min_expo); cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev); BUG_ON(!cis); BUG_ON(!cis->cis_data); cis_data = cis->cis_data; vt_pic_clk_freq_mhz = cis_data->pclk / (1000 * 1000); if (vt_pic_clk_freq_mhz == 0) { pr_err("[MOD:D:%d] %s, Invalid vt_pic_clk_freq_mhz(%d)\n", cis->id, __func__, vt_pic_clk_freq_mhz); goto p_err; } line_length_pck = cis_data->line_length_pck; min_coarse = cis_data->min_coarse_integration_time; min_fine = cis_data->min_fine_integration_time; min_integration_time = ((line_length_pck * min_coarse) + min_fine) / vt_pic_clk_freq_mhz; *min_expo = min_integration_time; dbg_sensor("[%s] min integration time %d\n", __func__, min_integration_time); #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 fimc_is_bayer_start_streaming(struct vb2_queue *q, unsigned int count) { int ret = 0; struct fimc_is_video_sensor *video = q->drv_priv; struct fimc_is_video_common *common = &video->common; struct fimc_is_device_sensor *sensor = common->device; dbg_sensor("%s\n", __func__); if (!test_bit(FIMC_IS_VIDEO_STREAM_ON, &common->state) && test_bit(FIMC_IS_VIDEO_BUFFER_READY, &common->state)) { set_bit(FIMC_IS_VIDEO_STREAM_ON, &common->state); fimc_is_sensor_back_start(sensor, common); } else { err("already stream on or buffer is not ready(%ld)", common->state); clear_bit(FIMC_IS_VIDEO_BUFFER_READY, &common->state); clear_bit(FIMC_IS_VIDEO_BUFFER_PREPARED, &common->state); fimc_is_sensor_back_stop(sensor); ret = -EINVAL; } return 0; }
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 unsigned int fimc_is_bayer_video_poll(struct file *file, struct poll_table_struct *wait) { struct fimc_is_core *isp = video_drvdata(file); dbg_sensor("%s\n", __func__); return vb2_poll(&isp->video_sensor.common.vbq, file, wait); }
static int fimc_is_bayer_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, unsigned int *num_buffers, unsigned int *num_planes, unsigned int sizes[], void *allocators[]) { int ret = 0; struct fimc_is_video_sensor *video = vq->drv_priv; dbg_sensor("%s\n", __func__); ret = fimc_is_video_queue_setup(&video->common, num_planes, sizes, allocators); dbg_sensor("(num_planes : %d)(size : %d)\n", (int)*num_planes, (int)sizes[0]); return ret; }
static int fimc_is_bayer_video_querybuf(struct file *file, void *priv, struct v4l2_buffer *buf) { int ret; struct fimc_is_video_sensor *video = file->private_data; dbg_sensor("%s\n", __func__); ret = vb2_querybuf(&video->common.vbq, buf); return ret; }
static int fimc_is_bayer_video_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { int ret = 0; struct fimc_is_video_sensor *video = file->private_data; dbg_sensor("%s\n", __func__); ret = fimc_is_video_streamoff(&video->common, type); return ret; }
static int fimc_is_bayer_video_s_input(struct file *file, void *priv, unsigned int input) { int ret = 0; struct fimc_is_video_sensor *video = file->private_data; struct fimc_is_device_sensor *sensor = video->common.device; dbg_sensor("%s(input : %d)\n", __func__, input); fimc_is_sensor_s_active_sensor(sensor, input); return ret; }
static void fimc_is_bayer_buffer_queue(struct vb2_buffer *vb) { struct fimc_is_video_sensor *video = vb->vb2_queue->drv_priv; struct fimc_is_video_common *common = &video->common; struct fimc_is_device_sensor *sensor = common->device; #ifdef DBG_STREAMING dbg_sensor("%s(%d)\n", __func__, vb->v4l2_buf.index); #endif fimc_is_video_buffer_queue(common, vb, sensor->framemgr); fimc_is_sensor_buffer_queue(sensor, vb->v4l2_buf.index); }
static void fimc_is_ss1_buffer_queue(struct vb2_buffer *vb) { struct fimc_is_video_ctx *vctx = vb->vb2_queue->drv_priv; struct fimc_is_queue *queue = &vctx->q_dst; struct fimc_is_video *video = vctx->video; struct fimc_is_device_sensor *sensor = vctx->device; #ifdef DBG_STREAMING dbg_sensor("%s(%d)\n", __func__, vb->v4l2_buf.index); #endif fimc_is_queue_buffer_queue(queue, video->vb2, vb); fimc_is_sensor_buffer_queue(sensor, vb->v4l2_buf.index); }
static int fimc_is_bayer_video_open(struct file *file) { struct fimc_is_core *core = video_drvdata(file); struct fimc_is_video_sensor *video = &core->video_sensor; struct fimc_is_device_sensor *sensor = &core->sensor; dbg_sensor("%s\n", __func__); file->private_data = video; fimc_is_video_open(&video->common, sensor, VIDEO_SENSOR_READY_BUFFERS); fimc_is_sensor_open(sensor); return 0; }
static int fimc_is_bayer_buffer_finish(struct vb2_buffer *vb) { int ret = 0; struct fimc_is_video_sensor *video = vb->vb2_queue->drv_priv; struct fimc_is_device_sensor *sensor = video->common.device; #ifdef DBG_STREAMING dbg_sensor("%s(%d)\n", __func__, vb->v4l2_buf.index); #endif ret = fimc_is_sensor_buffer_finish( sensor, vb->v4l2_buf.index); return 0; }
static int fimc_is_ss1_video_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *buf) { int ret = 0; struct fimc_is_video_ctx *vctx = file->private_data; BUG_ON(!vctx); dbg_sensor("%s(buffers : %d)\n", __func__, buf->count); ret = fimc_is_video_reqbufs(file, vctx, buf); if (ret) merr("fimc_is_video_reqbufs is fail(error %d)", vctx, ret); return ret; }
static int fimc_is_bayer_video_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *buf) { int ret = 0; struct fimc_is_video_sensor *video = file->private_data; struct fimc_is_video_common *common = &video->common; struct fimc_is_device_sensor *sensor = common->device; dbg_sensor("%s(buffers : %d)\n", __func__, buf->count); ret = fimc_is_video_reqbufs(common, sensor->framemgr, buf); if (ret) err("fimc_is_video_reqbufs is fail(error %d)", ret); return ret; }
static int fimc_is_bayer_video_set_format_mplane(struct file *file, void *fh, struct v4l2_format *format) { int ret = 0; struct fimc_is_video_sensor *video = file->private_data; dbg_scp("%s\n", __func__); ret = fimc_is_video_set_format_mplane(&video->common, format); dbg_sensor("req w : %d req h : %d\n", video->common.frame.width, video->common.frame.height); return ret; }
static int fimc_is_bayer_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) { struct fimc_is_core *isp = video_drvdata(file); strncpy(cap->driver, isp->pdev->name, sizeof(cap->driver) - 1); dbg_sensor("%s(devname : %s)\n", __func__, cap->driver); strncpy(cap->card, isp->pdev->name, sizeof(cap->card) - 1); cap->bus_info[0] = 0; cap->version = KERNEL_VERSION(1, 0, 0); cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_CAPTURE_MPLANE; return 0; }
int sensor_2p8_cis_adjust_analog_gain(struct v4l2_subdev *subdev, u32 input_again, u32 *target_permile) { int ret = 0; struct fimc_is_cis *cis; cis_shared_data *cis_data; u32 again_code = 0; u32 again_permile = 0; #ifdef DEBUG_SENSOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif BUG_ON(!subdev); BUG_ON(!target_permile); cis = (struct fimc_is_cis *)v4l2_get_subdevdata(subdev); BUG_ON(!cis); BUG_ON(!cis->cis_data); cis_data = cis->cis_data; again_code = sensor_cis_calc_again_code(input_again); if (again_code > cis_data->max_analog_gain[0]) { again_code = cis_data->max_analog_gain[0]; } else if (again_code < cis_data->min_analog_gain[0]) { again_code = cis_data->min_analog_gain[0]; } again_permile = sensor_cis_calc_again_permile(again_code); dbg_sensor("[%s] min again(%d), max(%d), input_again(%d), code(%d), permile(%d)\n", __func__, cis_data->max_analog_gain[0], cis_data->min_analog_gain[0], input_again, again_code, again_permile); *target_permile = again_permile; return ret; }
int fimc_is_sensor_video_probe(void *data) { int ret = 0; struct fimc_is_core *core = (struct fimc_is_core *)data; struct fimc_is_video_sensor *video = &core->video_sensor; dbg_sensor("%s\n", __func__); ret = fimc_is_video_probe(&video->common, data, video, FIMC_IS_VIDEO_BAYER_NAME, FIMC_IS_VIDEO_NUM_BAYER, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, &fimc_is_bayer_video_fops, &fimc_is_bayer_video_ioctl_ops, &fimc_is_bayer_qops); return ret; }
int sensor_ak7348_actuator_get_status(struct v4l2_subdev *subdev, u32 *info) { int ret = 0; struct fimc_is_actuator *actuator = NULL; struct i2c_client *client = NULL; enum fimc_is_actuator_status status = ACTUATOR_STATUS_NO_BUSY; #ifdef DEBUG_ACTUATOR_TIME struct timeval st, end; do_gettimeofday(&st); #endif dbg_sensor("%s\n", __func__); BUG_ON(!subdev); BUG_ON(!info); actuator = (struct fimc_is_actuator *)v4l2_get_subdevdata(subdev); BUG_ON(!actuator); client = actuator->client; if (unlikely(!client)) { err("client is NULL"); ret = -EINVAL; goto p_err; } /* * The info is busy flag. * But, this module can't get busy flag. */ status = ACTUATOR_STATUS_NO_BUSY; *info = status; #ifdef DEBUG_ACTUATOR_TIME do_gettimeofday(&end); pr_info("[%s] time %lu us", __func__, (end.tv_sec - st.tv_sec) * 1000000 + (end.tv_usec - st.tv_usec)); #endif p_err: return ret; }
static int fimc_is_bayer_stop_streaming(struct vb2_queue *q) { int ret = 0; struct fimc_is_video_sensor *video = q->drv_priv; struct fimc_is_video_common *common = &video->common; struct fimc_is_device_sensor *sensor = video->common.device; dbg_sensor("%s\n", __func__); if (test_bit(FIMC_IS_VIDEO_STREAM_ON, &common->state)) { clear_bit(FIMC_IS_VIDEO_STREAM_ON, &common->state); clear_bit(FIMC_IS_VIDEO_BUFFER_READY, &common->state); clear_bit(FIMC_IS_VIDEO_BUFFER_PREPARED, &common->state); ret = fimc_is_sensor_back_stop(sensor); } else { err("already stream off"); ret = -EINVAL; } return ret; }
static int sensor_ak7348_init_position(struct i2c_client *client, struct fimc_is_actuator *actuator) { int i; int ret = 0; int init_step = 0; init_step = sensor_ak7348_valid_check(client); if (init_step > 0) { for (i = 0; i < init_step; i++) { ret = sensor_ak7348_write_position(client, sysfs_actuator.init_positions[i]); if (ret < 0) goto p_err; mdelay(sysfs_actuator.init_delays[i]); } actuator->position = sysfs_actuator.init_positions[i]; sensor_ak7348_print_log(init_step); } else { ret = sensor_ak7348_write_position(client, DEF_AK7348_FIRST_POSITION); if (ret < 0) goto p_err; mdelay(DEF_AK7348_FIRST_DELAY); actuator->position = DEF_AK7348_FIRST_POSITION; dbg_sensor("initial position %d setting\n", DEF_AK7348_FIRST_POSITION); } p_err: return ret; }
int fimc_is_ss1_video_probe(void *data) { int ret = 0; struct fimc_is_core *core = (struct fimc_is_core *)data; struct fimc_is_video *video = &core->video_ss1; dbg_sensor("%s\n", __func__); ret = fimc_is_video_probe(video, data, FIMC_IS_VIDEO_SEN1_NAME, FIMC_IS_VIDEO_SS1_NUM, VFL_DIR_RX, &video->lock, &fimc_is_ss1_video_fops, &fimc_is_ss1_video_ioctl_ops); if (ret != 0) dev_err(&(core->pdev->dev), "%s::Failed to fimc_is_video_probe()\n", __func__); return ret; }
static int fimc_is_bayer_video_g_input(struct file *file, void *priv, unsigned int *input) { dbg_sensor("%s\n", __func__); return 0; }