media: rk-isp10: update to v0.1.f

fix MI_CTRL and MI_XTD_FORMAT_CTRL register is not correct
merge isp11: rockchip: v0.2.4 and isp11: rockchip: v0.2.5
merge isp11: Support Y8 for AEC
merge isp11: rockchip: v0.2.7
merge isp11: rockchip: v0.2.9 & v0.2.8
merge isp11: print version
merge isp11: rockchip: v0.2.b
merge isp11: rockchip: v0.2.c
merge isp11: rockchip: v0.3.2
merge isp11: rockchip: v0.3.4
merge isp11: rockchip: modify for debugfs
merge isp11: rockchip: v0.1.7
merge isp11: rockchip: v0.1.8
merge isp11: rockchip: v0.1.9
merge isp11: rockchip: v0.1.d
merge isp11: send afm meas data alone

Change-Id: I00c9181849addf5dd44c0deea2bb39ac02ff999d
Signed-off-by: Hu Kejun <william.hu@rock-chips.com>
This commit is contained in:
Hu Kejun 2018-06-05 10:00:29 +08:00 committed by Tao Huang
parent 244bf7dea0
commit 6ffc8e398a
16 changed files with 2844 additions and 2512 deletions

View File

@ -685,6 +685,8 @@ static const char *cif_isp10_pix_fmt_string(int pixfmt)
return "DATA";
case CIF_JPEG:
return "JPEG";
case CIF_Y10:
return "Y10";
default:
return "unknown/unsupported";
}
@ -1550,14 +1552,21 @@ static int cif_isp10_config_img_src(
ret = (int)cif_isp10_img_src_ioctl(dev->img_src,
RK_VIDIOC_SENSOR_MODE_DATA, &sensor_mode);
if (IS_ERR_VALUE(ret)) {
dev->img_src_exps.exp_valid_frms = 2;
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_T_INDEX] = 4;
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_G_INDEX] = 4;
} else {
if ((sensor_mode.exposure_valid_frame[0] < 2) ||
(sensor_mode.exposure_valid_frame[0] > 6))
dev->img_src_exps.exp_valid_frms = 2;
if ((sensor_mode.exposure_valid_frame[VALID_FR_EXP_T_INDEX] < 2) ||
(sensor_mode.exposure_valid_frame[VALID_FR_EXP_T_INDEX] > 6))
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_T_INDEX] = 4;
else
dev->img_src_exps.exp_valid_frms =
sensor_mode.exposure_valid_frame[0];
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_T_INDEX] =
sensor_mode.exposure_valid_frame[VALID_FR_EXP_T_INDEX];
if ((sensor_mode.exposure_valid_frame[VALID_FR_EXP_G_INDEX] < 2) ||
(sensor_mode.exposure_valid_frame[VALID_FR_EXP_G_INDEX] > 6))
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_G_INDEX] = 2;
else
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_G_INDEX] =
sensor_mode.exposure_valid_frame[VALID_FR_EXP_G_INDEX];
}
cif_isp10_pltfrm_pr_dbg(dev->dev,
"cam_itf: (type: 0x%x, dphy: %d, vc: %d, nb_lanes: %d, bitrate: %d)",
@ -1610,7 +1619,8 @@ static int cif_isp10_config_isp(
output = &dev->config.isp_config.output;
cam_itf = &dev->config.cam_itf;
if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER(in_pix_fmt)) {
if (CIF_ISP10_PIX_FMT_IS_RAW_BAYER(in_pix_fmt) ||
(in_pix_fmt == CIF_Y10)) {
if (!dev->config.mi_config.raw_enable) {
output->pix_fmt = CIF_YUV422I;
@ -1635,15 +1645,23 @@ static int cif_isp10_config_isp(
if (dev->sp_stream.state == CIF_ISP10_STATE_READY) {
output->quantization =
dev->config.mi_config.sp.output.quantization;
if (in_pix_fmt == CIF_Y10)
output->pix_fmt = CIF_YUV400;
}
if (dev->mp_stream.state == CIF_ISP10_STATE_READY) {
output->quantization =
dev->config.mi_config.sp.output.quantization;
dev->config.mi_config.mp.output.quantization;
}
cif_iowrite32(0xc,
dev->config.base_addr + CIF_ISP_DEMOSAIC);
if (in_pix_fmt == CIF_Y10) {
cif_iowrite32(0x40c,
dev->config.base_addr + CIF_ISP_DEMOSAIC);
} else {
cif_iowrite32(0xc,
dev->config.base_addr + CIF_ISP_DEMOSAIC);
}
if (PLTFRM_CAM_ITF_IS_BT656(dev->config.cam_itf.type)) {
cif_iowrite32(
@ -1882,7 +1900,11 @@ static int cif_isp10_config_isp(
CIF_ISP_FRAME |
CIF_ISP_PIC_SIZE_ERROR |
CIF_ISP_FRAME_IN |
CIF_ISP_V_START;
CIF_ISP_V_START |
CIF_ISP_AWB_DONE |
CIF_ISP_AFM_FIN |
CIF_ISP_EXP_END |
CIF_ISP_HIST_MEASURE_RDY;
cif_iowrite32(irq_mask,
dev->config.base_addr + CIF_ISP_IMSC);
@ -1998,6 +2020,8 @@ static int cif_isp10_config_mipi(
(CIF_ISP10_PIX_FMT_YUV_GET_Y_SUBS(in_pix_fmt) == 4) &&
(CIF_ISP10_PIX_FMT_GET_BPP(in_pix_fmt) == 20))
data_type = CSI2_DT_YUV422_10b;
else if (in_pix_fmt == CIF_Y10)
data_type = CSI2_DT_RAW10;
else {
cif_isp10_pltfrm_pr_err(dev->dev,
"unsupported format %s\n",
@ -2178,7 +2202,10 @@ static int cif_isp10_config_mi_mp(
CIF_MI_IMSC, ~0);
if (swap_cb_cr) {
cif_iowrite32OR(swap_cb_cr,
cif_iowrite32OR(CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP,
dev->config.base_addr + CIF_MI_XTD_FORMAT_CTRL);
} else {
cif_iowrite32AND(~CIF_MI_XTD_FMT_CTRL_MP_CB_CR_SWAP,
dev->config.base_addr + CIF_MI_XTD_FORMAT_CTRL);
}
@ -2199,7 +2226,8 @@ static int cif_isp10_config_mi_mp(
" MI_STATUS 0x%08x\n"
" MI_MP_Y_SIZE %d\n"
" MI_MP_CB_SIZE %d\n"
" MI_MP_CR_SIZE %d\n",
" MI_MP_CR_SIZE %d\n"
" MI_XTD_FORMAT_CTRL %d\n",
cif_ioread32(dev->config.base_addr +
CIF_MI_CTRL),
cif_ioread32(dev->config.base_addr +
@ -2209,7 +2237,9 @@ static int cif_isp10_config_mi_mp(
cif_ioread32(dev->config.base_addr +
CIF_MI_MP_CB_SIZE_INIT),
cif_ioread32(dev->config.base_addr +
CIF_MI_MP_CR_SIZE_INIT));
CIF_MI_MP_CR_SIZE_INIT),
cif_ioread32(dev->config.base_addr +
CIF_MI_XTD_FORMAT_CTRL));
return 0;
}
@ -2287,6 +2317,8 @@ static int cif_isp10_config_mi_sp(
CIF_ISP10_PIX_FMT_YUV_GET_NUM_CPLANES(out_pix_fmt);
if (num_cplanes == 0) {
writeformat = CIF_ISP10_BUFF_FMT_INTERLEAVED;
if (out_pix_fmt == CIF_YUV400)
writeformat = CIF_ISP10_BUFF_FMT_PLANAR;
} else {
dev->config.mi_config.sp.y_size =
(dev->config.mi_config.sp.y_size * 4) /
@ -2420,19 +2452,26 @@ static int cif_isp10_config_mi_sp(
CIF_MI_IMSC, ~0);
if (swap_cb_cr) {
cif_iowrite32OR(swap_cb_cr,
cif_iowrite32OR(CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP,
dev->config.base_addr + CIF_MI_XTD_FORMAT_CTRL);
} else {
cif_iowrite32AND(~CIF_MI_XTD_FMT_CTRL_SP_CB_CR_SWAP,
dev->config.base_addr + CIF_MI_XTD_FORMAT_CTRL);
}
mi_ctrl = cif_ioread32(dev->config.base_addr + CIF_MI_CTRL);
mi_ctrl &= ~(CIF_MI_CTRL_SP_WRITE_FMT(3));
mi_ctrl |= CIF_MI_CTRL_SP_WRITE_FMT(writeformat) |
input_format |
output_format |
burst_len |
CIF_MI_CTRL_INIT_BASE_EN |
CIF_MI_CTRL_INIT_OFFSET_EN |
CIF_MI_SP_AUTOUPDATE_ENABLE;
mi_ctrl &= ~(CIF_MI_CTRL_SP_WRITE_FMT(3) |/* SP_WRITE_FMT */
(0x7 << 28) | /* SP_OUTPUT_FMT */
(0x3 << 26) | /* SP_INPUT_FMT */
(0xF << 16)); /* burst_len_chrom & burst_len_lum */
mi_ctrl = mi_ctrl |
CIF_MI_CTRL_SP_WRITE_FMT(writeformat) |
input_format |
output_format |
burst_len |
CIF_MI_CTRL_INIT_BASE_EN |
CIF_MI_CTRL_INIT_OFFSET_EN |
CIF_MI_SP_AUTOUPDATE_ENABLE;
cif_iowrite32_verify(mi_ctrl,
dev->config.base_addr + CIF_MI_CTRL, ~0);
@ -2445,7 +2484,8 @@ static int cif_isp10_config_mi_sp(
" MI_SP_PIC_WIDTH %d\n"
" MI_SP_PIC_HEIGHT %d\n"
" MI_SP_PIC_LLENGTH %d\n"
" MI_SP_PIC_SIZE %d\n",
" MI_SP_PIC_SIZE %d\n"
" MI_XTD_FORMAT_CTRL %d\n",
cif_ioread32(dev->config.base_addr + CIF_MI_CTRL),
cif_ioread32(dev->config.base_addr + CIF_MI_STATUS),
cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_SIZE_INIT),
@ -2454,7 +2494,8 @@ static int cif_isp10_config_mi_sp(
cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_PIC_WIDTH),
cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_PIC_HEIGHT),
cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_LLENGTH),
cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_PIC_SIZE));
cif_ioread32(dev->config.base_addr + CIF_MI_SP_Y_PIC_SIZE),
cif_ioread32(dev->config.base_addr + CIF_MI_XTD_FORMAT_CTRL));
return 0;
err:
@ -3349,6 +3390,9 @@ static int cif_isp10_config_cif(
cif_isp10_config_clk(dev);
cifisp_frame_id_reset(&dev->isp_dev);
dev->isp_dev.frame_id_setexp = 0;
/* Decide when to switch to asynchronous mode */
/*
* TODO: remove dev->isp_dev.ycflt_en check for
@ -3551,6 +3595,7 @@ static void cif_isp10_init_stream(
stream->curr_buf = NULL;
stream->stop = false;
stream->stall = false;
spin_lock_init(&stream->metadata.spinlock);
cif_isp10_pltfrm_event_clear(dev->dev, &stream->done);
@ -3940,6 +3985,18 @@ static int cif_isp10_s_fmt_mp(
strm_fmt->frm_fmt.quantization);
/* TBD: check whether format is a valid format for MP */
if (strm_fmt->frm_fmt.pix_fmt == CIF_YUV400) {
cif_isp10_pltfrm_pr_err(dev->dev,
"format %s %dx%d@%d/%dfps, stride = %d not supported on MP\n",
cif_isp10_pix_fmt_string(strm_fmt->frm_fmt.pix_fmt),
strm_fmt->frm_fmt.width,
strm_fmt->frm_fmt.height,
strm_fmt->frm_intrvl.numerator,
strm_fmt->frm_intrvl.denominator,
stride);
ret = -EINVAL;
goto err;
}
if (PLTFRM_CAM_ITF_INTERLACE(dev->config.cam_itf.type)) {
ret = -EINVAL;
@ -4301,16 +4358,25 @@ static int cif_isp10_mi_frame_end(
vb2_buffer_done(vb2_buf, VB2_BUF_STATE_DONE);
wake_now = false;
spin_lock(&stream->metadata.spinlock);
if (stream->metadata.d && dev->isp_dev.streamon) {
struct v4l2_buffer_metadata_s *metadata;
unsigned int meta_read_id;
metadata = (struct v4l2_buffer_metadata_s *)
(stream->metadata.d +
stream->curr_buf->vb.vb2_buf.index *
CAMERA_METADATA_LEN);
metadata->frame_id = dev->isp_dev.frame_id;
metadata->frame_t.vs_t = dev->isp_dev.vs_t;
metadata->frame_t.fi_t = dev->isp_dev.fi_t;
meta_read_id = dev->isp_dev.meta_info.read_id;
metadata->frame_id = dev->isp_dev.meta_info.frame_id[meta_read_id];
metadata->frame_t.vs_t = dev->isp_dev.meta_info.vs_t[meta_read_id];
metadata->frame_t.fi_t = dev->isp_dev.meta_info.fi_t[meta_read_id];
dev->isp_dev.meta_info.read_cnt++;
if (dev->isp_dev.meta_info.read_cnt >= dev->isp_dev.meta_info.read_max) {
dev->isp_dev.meta_info.read_cnt = 0;
dev->isp_dev.meta_info.read_id = (meta_read_id + 1) % CIF_ISP10_META_INFO_NUM;
}
spin_unlock(&stream->metadata.spinlock);
work = (struct cif_isp10_isp_readout_work *)
kmalloc(
@ -4325,10 +4391,12 @@ static int cif_isp10_mi_frame_end(
work->isp_dev =
&dev->isp_dev;
work->frame_id =
dev->isp_dev.frame_id;
metadata->frame_id;
work->vb =
&stream->curr_buf->vb.vb2_buf;
work->stream_id = stream->id;
work->isp_metadata =
(struct cifisp_isp_metadata *)metadata->isp;
if (!queue_work(dev->isp_dev.readout_wq,
(struct work_struct *)work)) {
cif_isp10_pltfrm_pr_err(
@ -4343,6 +4411,7 @@ static int cif_isp10_mi_frame_end(
wake_now = true;
}
} else {
spin_unlock(&stream->metadata.spinlock);
wake_now = true;
}
@ -4452,14 +4521,78 @@ static int cif_isp10_mi_frame_end(
return 0;
}
static int cif_isp10_update_mi_immediate(
struct cif_isp10_device *dev,
enum cif_isp10_stream_id stream_id)
{
struct cif_isp10_stream *stream;
u32 *next_buff_addr;
CIF_ISP10_PLTFRM_MEM_IO_ADDR y_base_addr;
#ifdef CIF_ISP10_MODE_DMA_SG
struct sg_table *sgt = NULL;
#endif
int (*update_mi)(
struct cif_isp10_device *dev);
if (stream_id == CIF_ISP10_STREAM_MP) {
stream = &dev->mp_stream;
y_base_addr =
dev->config.base_addr + CIF_MI_MP_Y_BASE_AD_SHD;
next_buff_addr = &dev->config.mi_config.mp.next_buff_addr;
update_mi = cif_isp10_update_mi_mp;
} else if (stream_id == CIF_ISP10_STREAM_SP) {
stream = &dev->sp_stream;
y_base_addr =
dev->config.base_addr + CIF_MI_SP_Y_BASE_AD_SHD;
next_buff_addr = &dev->config.mi_config.sp.next_buff_addr;
update_mi = cif_isp10_update_mi_sp;
} else {
BUG();
}
if (stream->state != CIF_ISP10_STATE_STREAMING)
return 0;
if (stream->next_buf)
return 0;
if (!list_empty(&stream->buf_queue)) {
stream->next_buf =
list_first_entry(&stream->buf_queue,
struct cif_isp10_buffer, queue);
list_del(&stream->next_buf->queue);
#ifdef CIF_ISP10_MODE_DMA_CONTIG
*next_buff_addr = vb2_dma_contig_plane_dma_addr(
&stream->next_buf->vb.vb2_buf, 0);
#endif
#ifdef CIF_ISP10_MODE_DMA_SG
sgt = vb2_dma_sg_plane_desc(
&stream->next_buf->vb.vb2_buf, 0);
*next_buff_addr = sg_dma_address(sgt->sgl);
#endif
}
update_mi(dev);
cif_isp10_pltfrm_pr_dbg(dev->dev,
"%s curr_buff: %d, next_buf: %d, 0x%x\n",
cif_isp10_stream_id_string(stream_id),
(stream->curr_buf) ? stream->curr_buf->vb.vb2_buf.index : -1,
(stream->next_buf) ? stream->next_buf->vb.vb2_buf.index : -1,
*next_buff_addr);
return 0;
}
static void cif_isp10_stream_metadata_reset(
struct cif_isp10_stream *stream_dev
)
{
unsigned int i;
unsigned long flags = 0;
struct v4l2_buffer_metadata_s *metadata;
struct cifisp_isp_metadata *isp_metadata;
spin_lock_irqsave(&stream_dev->metadata.spinlock, flags);
if (stream_dev->metadata.d) {
for (i = 0; i < stream_dev->metadata.cnt; i++) {
metadata = (struct v4l2_buffer_metadata_s *)
@ -4471,6 +4604,7 @@ static void cif_isp10_stream_metadata_reset(
isp_metadata->meas_cfg.s_frame_id = 0xffffffff;
}
}
spin_unlock_irqrestore(&stream_dev->metadata.spinlock, flags);
}
static void cif_isp10_start_mi(
@ -4765,6 +4899,8 @@ static int cif_isp10_stop(
spin_unlock_irqrestore(&dev->isp_state_lock, flags);
}
cifisp_clr_readout_wq(&dev->isp_dev);
if (!CIF_ISP10_INP_IS_DMA(dev->config.input_sel)) {
if (IS_ERR_VALUE(cif_isp10_img_src_set_state(dev,
CIF_ISP10_IMG_SRC_STATE_SW_STNDBY)))
@ -4900,7 +5036,7 @@ static int cif_isp10_start(
*/
mdelay(1);
/* start sensor output! */
dev->isp_dev.frame_id = 0;
cifisp_frame_id_reset(&dev->isp_dev);
dev->isp_dev.frame_id_setexp = 0;
list_for_each_entry_safe(
@ -4950,6 +5086,13 @@ static int cif_isp10_start(
cif_isp10_dma_next_buff(dev);
}
dev->isp_dev.meta_info.read_cnt = 0;
dev->isp_dev.meta_info.read_max = 0;
if (dev->sp_stream.state == CIF_ISP10_STATE_STREAMING)
dev->isp_dev.meta_info.read_max++;
if (dev->mp_stream.state == CIF_ISP10_STATE_STREAMING)
dev->isp_dev.meta_info.read_max++;
cif_isp10_pltfrm_pr_dbg(dev->dev,
"SP state = %s, MP state = %s, DMA state = %s, img_src state = %s\n"
" MI_CTRL 0x%08x\n"
@ -5243,12 +5386,13 @@ static void cif_isp10_vs_work(struct work_struct *work)
struct cif_isp10_isp_vs_work *vs_wk =
container_of(work, struct cif_isp10_isp_vs_work, work);
struct cif_isp10_device *dev = vs_wk->dev;
unsigned int v_frame_id;
switch (vs_wk->cmd) {
case CIF_ISP10_VS_EXP: {
struct cif_isp10_img_src_exp *exp =
(struct cif_isp10_img_src_exp *)vs_wk->param;
struct cif_isp10_img_src_ext_ctrl *exp_ctrl = exp->exp;
struct cif_isp10_img_src_ext_ctrl *exp_ctrl = &exp->exp;
struct cif_isp10_img_src_data *new_data;
if (dev->img_src)
@ -5264,8 +5408,19 @@ static void cif_isp10_vs_work(struct work_struct *work)
new_data = &dev->img_src_exps.data[1];
mutex_lock(&dev->img_src_exps.mutex);
new_data->v_frame_id = dev->isp_dev.frame_id +
dev->img_src_exps.exp_valid_frms;
if (exp_ctrl->ctrls->id == V4L2_CID_EXPOSURE)
v_frame_id = dev->isp_dev.frame_id +
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_T_INDEX];
else
v_frame_id = dev->isp_dev.frame_id +
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_G_INDEX];
if (v_frame_id == dev->img_src_exps.data[0].v_frame_id)
new_data = &dev->img_src_exps.data[0];
if (v_frame_id == dev->img_src_exps.data[1].v_frame_id)
new_data = &dev->img_src_exps.data[1];
new_data->v_frame_id = v_frame_id;
cif_isp10_img_src_ioctl(dev->img_src,
RK_VIDIOC_SENSOR_MODE_DATA,
&new_data->data);
@ -5293,10 +5448,8 @@ static void cif_isp10_vs_work(struct work_struct *work)
* new_data->v_frame_id);
*/
kfree(exp->exp->ctrls);
exp->exp->ctrls = NULL;
kfree(exp->exp);
exp->exp = NULL;
kfree(exp->exp.ctrls);
exp->exp.ctrls = NULL;
kfree(exp);
exp = NULL;
break;
@ -5309,6 +5462,38 @@ static void cif_isp10_vs_work(struct work_struct *work)
vs_wk = NULL;
}
static int cif_isp10_vs_work_cmd(
struct cif_isp10_device *dev,
enum cif_isp10_isp_vs_cmd cmd,
void *para)
{
struct cif_isp10_isp_vs_work *vs_wk;
if (cmd == CIF_ISP10_VS_EXP)
vs_wk = kmalloc(sizeof(struct cif_isp10_isp_vs_work),
GFP_ATOMIC);
else
vs_wk = kmalloc(sizeof(struct cif_isp10_isp_vs_work),
GFP_KERNEL);
if (vs_wk) {
vs_wk->cmd = cmd;
vs_wk->dev = dev;
vs_wk->param = (void *)para;
INIT_WORK((struct work_struct *)&vs_wk->work,
cif_isp10_vs_work);
if (!queue_work(dev->vs_wq,
(struct work_struct *)&vs_wk->work)) {
cif_isp10_pltfrm_pr_err(dev->dev,
"%s: queue work failed\n", __func__);
kfree(vs_wk);
}
return 0;
} else {
return -ENOMEM;
}
}
/* Public Functions */
void cif_isp10_sensor_mode_data_sync(
struct cif_isp10_device *dev,
@ -5452,6 +5637,7 @@ int cif_isp10_streamoff(
bool streamoff_mp = stream_ids & CIF_ISP10_STREAM_MP;
bool streamoff_dma = stream_ids & CIF_ISP10_STREAM_DMA;
unsigned int streamoff_all = 0;
unsigned long lock_flags;
cif_isp10_pltfrm_pr_dbg(dev->dev,
"SP state = %s, MP state = %s, DMA state = %s, streamoff SP = %d, streamoff MP = %d, streamoff DMA = %d\n",
@ -5484,8 +5670,20 @@ int cif_isp10_streamoff(
} else {
streamoff_all |= CIF_ISP10_STREAM_MP;
}
if (streamoff_all == (CIF_ISP10_STREAM_MP | CIF_ISP10_STREAM_SP))
if (streamoff_all == (CIF_ISP10_STREAM_MP | CIF_ISP10_STREAM_SP)) {
struct cif_isp10_img_src_exp *exp;
spin_lock_irqsave(&dev->img_src_exps.lock, lock_flags);
if (!list_empty(&dev->img_src_exps.list)) {
exp = list_first_entry(&dev->img_src_exps.list,
struct cif_isp10_img_src_exp,
list);
list_del(&exp->list);
kfree(exp->exp.ctrls);
kfree(exp);
}
spin_unlock_irqrestore(&dev->img_src_exps.lock, lock_flags);
drain_workqueue(dev->vs_wq);
}
ret = cif_isp10_stop(dev, streamoff_sp, streamoff_mp);
if (IS_ERR_VALUE(ret))
@ -5685,6 +5883,8 @@ int cif_isp10_release(
int stream_ids)
{
int ret;
unsigned char *meta_addr = NULL;
unsigned long flags = 0;
struct cif_isp10_stream *strm_dev;
cif_isp10_pltfrm_pr_dbg(NULL, "0x%08x\n", stream_ids);
@ -5710,11 +5910,15 @@ int cif_isp10_release(
strm_dev = NULL;
if (strm_dev) {
spin_lock_irqsave(&strm_dev->metadata.spinlock, flags);
if (strm_dev->metadata.d) {
vfree(strm_dev->metadata.d);
meta_addr = strm_dev->metadata.d;
strm_dev->metadata.d = NULL;
strm_dev->metadata.cnt = 0;
}
spin_unlock_irqrestore(&strm_dev->metadata.spinlock, flags);
if (meta_addr)
vfree(meta_addr);
}
if (stream_ids & CIF_ISP10_STREAM_SP) {
@ -5819,7 +6023,8 @@ struct cif_isp10_device *cif_isp10_create(
cif_isp10_pltfrm_event_init(dev->dev, &dev->sp_stream.done);
cif_isp10_pltfrm_event_init(dev->dev, &dev->mp_stream.done);
dev->img_src_exps.exp_valid_frms = 2;
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_T_INDEX] = 4;
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_G_INDEX] = 4;
mutex_init(&dev->img_src_exps.mutex);
memset(&dev->img_src_exps.data, 0x00, sizeof(dev->img_src_exps.data));
spin_lock_init(&dev->img_src_exps.lock);
@ -5944,9 +6149,11 @@ int cif_isp10_qbuf(
switch (stream) {
case CIF_ISP10_STREAM_SP:
list_add_tail(&buf->queue, &dev->sp_stream.buf_queue);
cif_isp10_update_mi_immediate(dev, CIF_ISP10_STREAM_SP);
break;
case CIF_ISP10_STREAM_MP:
list_add_tail(&buf->queue, &dev->mp_stream.buf_queue);
cif_isp10_update_mi_immediate(dev, CIF_ISP10_STREAM_MP);
break;
case CIF_ISP10_STREAM_DMA:
list_add_tail(&buf->queue, &dev->dma_stream.buf_queue);
@ -5976,6 +6183,7 @@ int cif_isp10_reqbufs(
enum cif_isp10_stream_id strm,
struct v4l2_requestbuffers *req)
{
unsigned long flags = 0;
struct cif_isp10_stream *strm_dev = NULL;
switch (strm) {
@ -5991,7 +6199,9 @@ int cif_isp10_reqbufs(
break;
}
spin_lock_irqsave(&strm_dev->metadata.spinlock, flags);
strm_dev->metadata.cnt = req->count;
spin_unlock_irqrestore(&strm_dev->metadata.spinlock, flags);
return 0;
}
@ -6000,28 +6210,112 @@ int cif_isp10_s_exp(
struct cif_isp10_device *dev,
struct cif_isp10_img_src_ext_ctrl *exp_ctrl)
{
struct cif_isp10_img_src_exp *exp = NULL;
struct cif_isp10_img_src_ctrl *ctrl_exp_t = NULL, *ctrl_exp_g = NULL;
struct cif_isp10_img_src_exp *exp = NULL, *exp_t = NULL, *exp_g = NULL;
unsigned long lock_flags;
int retval;
int retval, i, exp_cnt;
if (!dev->vs_wq)
return -ENODEV;
exp = kmalloc(sizeof(*exp), GFP_KERNEL);
if (!exp) {
retval = -ENOMEM;
goto failed;
if (dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_T_INDEX] ==
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_G_INDEX]) {
exp = kmalloc(sizeof(struct cif_isp10_img_src_exp), GFP_KERNEL);
if (!exp) {
retval = -ENOMEM;
goto failed;
}
exp->exp = *exp_ctrl;
spin_lock_irqsave(&dev->img_src_exps.lock, lock_flags);
list_add_tail(&exp->list, &dev->img_src_exps.list);
spin_unlock_irqrestore(&dev->img_src_exps.lock, lock_flags);
} else {
exp_t = kmalloc(sizeof(struct cif_isp10_img_src_exp), GFP_KERNEL);
if (!exp_t) {
retval = -ENOMEM;
goto failed;
}
ctrl_exp_t = kmalloc(sizeof(struct cif_isp10_img_src_ctrl) * 2, GFP_KERNEL);
if (!ctrl_exp_t) {
retval = -ENOMEM;
goto failed;
}
exp_g = kmalloc(sizeof(struct cif_isp10_img_src_exp), GFP_KERNEL);
if (!exp_g) {
retval = -ENOMEM;
goto failed;
}
ctrl_exp_g = kmalloc(sizeof(struct cif_isp10_img_src_ctrl)*2, GFP_KERNEL);
if (!ctrl_exp_g) {
retval = -ENOMEM;
goto failed;
}
exp_cnt = 0;
for (i = 0; i < exp_ctrl->cnt; i++) {
if (exp_ctrl->ctrls[i].id == V4L2_CID_EXPOSURE) {
*ctrl_exp_t = exp_ctrl->ctrls[i];
exp_cnt++;
}
if (exp_ctrl->ctrls[i].id == RK_V4L2_CID_VTS) {
*(ctrl_exp_t + 1) = exp_ctrl->ctrls[i];
exp_cnt++;
}
if (exp_ctrl->ctrls[i].id == V4L2_CID_GAIN) {
*ctrl_exp_g = exp_ctrl->ctrls[i];
}
if (exp_ctrl->ctrls[i].id == RK_V4L2_CID_GAIN_PERCENT) {
*(ctrl_exp_g+1) = exp_ctrl->ctrls[i];
}
}
kfree(exp_ctrl->ctrls);
exp_ctrl->ctrls = NULL;
exp_t->exp.cnt = exp_cnt;
exp_t->exp.class = exp_ctrl->class;
exp_t->exp.ctrls = ctrl_exp_t;
exp_g->exp.cnt = 2;
exp_g->exp.class = exp_ctrl->class;
exp_g->exp.ctrls = ctrl_exp_g;
if (dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_T_INDEX] <
dev->img_src_exps.exp_valid_frms[VALID_FR_EXP_G_INDEX]) {
spin_lock_irqsave(&dev->img_src_exps.lock, lock_flags);
list_add_tail(&exp_g->list, &dev->img_src_exps.list);
list_add_tail(&exp_t->list, &dev->img_src_exps.list);
spin_unlock_irqrestore(&dev->img_src_exps.lock, lock_flags);
} else {
spin_lock_irqsave(&dev->img_src_exps.lock, lock_flags);
list_add_tail(&exp_t->list, &dev->img_src_exps.list);
list_add_tail(&exp_g->list, &dev->img_src_exps.list);
spin_unlock_irqrestore(&dev->img_src_exps.lock, lock_flags);
}
}
exp->exp = exp_ctrl;
spin_lock_irqsave(&dev->img_src_exps.lock, lock_flags);
list_add_tail(&exp->list, &dev->img_src_exps.list);
spin_unlock_irqrestore(&dev->img_src_exps.lock, lock_flags);
return 0;
failed:
if (exp) {
kfree(exp);
exp = NULL;
}
if (exp_t) {
kfree(exp_t);
exp_t = NULL;
}
if (exp_g) {
kfree(exp_g);
exp_g = NULL;
}
if (ctrl_exp_t) {
kfree(ctrl_exp_t);
ctrl_exp_t = NULL;
}
if (ctrl_exp_g) {
kfree(ctrl_exp_g);
ctrl_exp_g = NULL;
}
return retval;
}
@ -6036,20 +6330,18 @@ int cif_isp10_s_vcm(
return 0;
}
int cif_isp10_s_isp_metadata(
int cif_isp10_s_vb_metadata(
struct cif_isp10_device *dev,
struct cif_isp10_isp_readout_work *readout_work,
struct cifisp_isp_other_cfg *new_other,
struct cifisp_isp_meas_cfg *new_meas,
struct cifisp_stat_buffer *new_stats)
struct cif_isp10_isp_readout_work *readout_work)
{
unsigned long flags = 0;
unsigned int stream_id =
readout_work->stream_id;
struct vb2_buffer *vb =
readout_work->vb;
struct cif_isp10_stream *strm_dev = NULL;
struct v4l2_buffer_metadata_s *metadata;
struct cifisp_isp_metadata *isp_last;
struct isp_supplemental_sensor_mode_data sensor_mode;
switch (stream_id) {
case CIF_ISP10_STREAM_MP:
@ -6061,50 +6353,39 @@ int cif_isp10_s_isp_metadata(
default:
cif_isp10_pltfrm_pr_err(dev->dev,
"unknown stream id%d\n", stream_id);
break;
return -1;
}
if (strm_dev->state != CIF_ISP10_STATE_STREAMING) {
cif_isp10_pltfrm_pr_err(dev->dev,
"stream id%d is not streaming\n", stream_id);
return -1;
}
cif_isp10_sensor_mode_data_sync(dev,
readout_work->frame_id,
&sensor_mode);
spin_lock_irqsave(&strm_dev->metadata.spinlock, flags);
if (vb && strm_dev->metadata.d) {
if (vb->index >= strm_dev->metadata.cnt) {
cif_isp10_pltfrm_pr_err(dev->dev,
"vb->index %d is bigger than metadata.cnt %d\n",
vb->index, strm_dev->metadata.cnt);
spin_unlock_irqrestore(&strm_dev->metadata.spinlock, flags);
return -1;
}
metadata = (struct v4l2_buffer_metadata_s *)
(strm_dev->metadata.d +
vb->index * CAMERA_METADATA_LEN);
metadata->frame_id = readout_work->frame_id;
isp_last =
(struct cifisp_isp_metadata *)metadata->isp;
if (new_meas) {
if ((isp_last->meas_cfg.s_frame_id == 0xffffffff) ||
(isp_last->meas_cfg.s_frame_id <
new_meas->s_frame_id)) {
memcpy(&isp_last->meas_cfg,
new_meas,
sizeof(struct cifisp_isp_meas_cfg));
}
}
if (new_other) {
if ((isp_last->other_cfg.s_frame_id == 0xffffffff) ||
(isp_last->other_cfg.s_frame_id <
new_other->s_frame_id)) {
memcpy(&isp_last->other_cfg,
new_other,
sizeof(struct cifisp_isp_other_cfg));
}
}
if (new_stats) {
memcpy(&isp_last->meas_stat,
new_stats,
sizeof(struct cifisp_stat_buffer));
metadata->sensor.exp_time =
new_stats->sensor_mode.exp_time;
metadata->sensor.gain =
new_stats->sensor_mode.gain;
} else {
isp_last->meas_stat.meas_type = 0x00;
}
metadata->sensor.exp_time =
sensor_mode.exp_time;
metadata->sensor.gain =
sensor_mode.gain;
}
spin_unlock_irqrestore(&strm_dev->metadata.spinlock, flags);
if (vb) {
cif_isp10_pltfrm_pr_dbg(NULL,
@ -6124,6 +6405,7 @@ int cif_isp10_mmap(
void *mem_vaddr;
int retval = 0, pages;
unsigned long mem_size;
unsigned long flags = 0;
switch (stream_id) {
case CIF_ISP10_STREAM_MP:
@ -6169,7 +6451,9 @@ int cif_isp10_mmap(
goto done;
}
spin_lock_irqsave(&strm_dev->metadata.spinlock, flags);
strm_dev->metadata.d = (unsigned char *)mem_vaddr;
spin_unlock_irqrestore(&strm_dev->metadata.spinlock, flags);
vma->vm_private_data = (void *)&strm_dev->metadata;
@ -6578,7 +6862,6 @@ int cif_isp10_isp_isr(unsigned int isp_mis, void *cntxt)
}
if (isp_mis & CIF_ISP_V_START) {
struct cif_isp10_isp_vs_work *vs_wk;
struct cif_isp10_img_src_exp *exp;
do_gettimeofday(&tv);
@ -6620,23 +6903,8 @@ int cif_isp10_isp_isr(unsigned int isp_mis, void *cntxt)
}
spin_unlock(&dev->img_src_exps.lock);
if (exp) {
vs_wk = kmalloc(sizeof(*vs_wk),
GFP_KERNEL);
if (vs_wk) {
vs_wk->cmd = CIF_ISP10_VS_EXP;
vs_wk->dev = dev;
vs_wk->param = (void *)exp;
INIT_WORK((struct work_struct *)&vs_wk->work,
cif_isp10_vs_work);
if (!queue_work(dev->vs_wq,
(struct work_struct *)&vs_wk->work)) {
cif_isp10_pltfrm_pr_err(dev->dev,
"%s: queue work failed\n", __func__);
kfree(vs_wk);
}
}
}
if (exp)
cif_isp10_vs_work_cmd(dev, CIF_ISP10_VS_EXP, (void *)exp);
}
if (isp_mis & CIF_ISP_FRAME_IN) {

View File

@ -246,6 +246,7 @@ enum cif_isp10_pix_fmt {
/* YUV */
CIF_YUV400 = 0x10008000,
CIF_YVU400 = 0x10008004,
CIF_Y10 = 0x1000a000,
CIF_YUV420I = 0x1000c220,
CIF_YUV420SP = 0x1000c221, /* NV12 */
@ -469,6 +470,7 @@ struct cif_isp10_buffer {
struct cif_isp10_metadata_s {
unsigned int cnt;
unsigned int vmas;
spinlock_t spinlock;
unsigned char *d;
};
@ -552,7 +554,7 @@ struct cif_isp10_mi_state {
struct cif_isp10_img_src_exp {
struct list_head list;
struct cif_isp10_img_src_ext_ctrl *exp;
struct cif_isp10_img_src_ext_ctrl exp;
};
struct cif_isp10_img_src_data {
@ -566,11 +568,12 @@ struct cif_isp10_img_src_exps {
struct mutex mutex; /* protect frm_exp */
struct cif_isp10_img_src_data data[2];
unsigned char exp_valid_frms;
unsigned char exp_valid_frms[2];
};
enum cif_isp10_isp_vs_cmd {
CIF_ISP10_VS_EXP = 0,
CIF_ISP10_VS_EXIT = 0,
CIF_ISP10_VS_EXP = 1
};
struct cif_isp10_isp_vs_work {
@ -778,17 +781,9 @@ int cif_isp10_s_ctrl(
const enum cif_isp10_cid id,
int val);
void cif_isp10_dbgfs_fill_sensor_aec_para(
struct cif_isp10_device *cif_isp10_dev,
s32 exp_time,
u16 gain);
int cif_isp10_s_isp_metadata(
int cif_isp10_s_vb_metadata(
struct cif_isp10_device *dev,
struct cif_isp10_isp_readout_work *readout_work,
struct cifisp_isp_other_cfg *new_other,
struct cifisp_isp_meas_cfg *new_meas,
struct cifisp_stat_buffer *new_stats);
struct cif_isp10_isp_readout_work *readout_work);
int cif_isp10_s_exp(
struct cif_isp10_device *dev,

View File

@ -173,3 +173,35 @@ const char *cif_isp10_img_src_g_name(
return img_src->ops->g_name(img_src->img_src);
}
void *cif_isp10_img_src_g_img_src(
struct cif_isp10_img_src *img_src)
{
if (img_src) {
return img_src->img_src;
}
return NULL;
}
int cif_isp10_img_src_s_frame_interval(
struct cif_isp10_img_src *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl)
{
if (img_src)
return img_src->ops->s_frame_interval(
img_src->img_src,
frm_intrvl);
return -EINVAL;
}
int cif_isp10_img_src_g_frame_interval(
struct cif_isp10_img_src *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl)
{
if (img_src)
return img_src->ops->g_frame_interval(
img_src->img_src,
frm_intrvl);
return -EINVAL;
}

View File

@ -23,6 +23,7 @@ struct cif_isp10_strm_fmt;
struct cif_isp10_csi_config;
enum cif_isp10_pix_fmt;
struct cif_isp10_frm_intrvl;
struct cif_isp10_img_src;
struct pltfrm_soc_cfg;
@ -80,4 +81,15 @@ long cif_isp10_img_src_ioctl(
unsigned int cmd,
void *arg);
void *cif_isp10_img_src_g_img_src(
struct cif_isp10_img_src *img_src);
int cif_isp10_img_src_s_frame_interval(
struct cif_isp10_img_src *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl);
int cif_isp10_img_src_g_frame_interval(
struct cif_isp10_img_src *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl);
#endif

View File

@ -53,6 +53,12 @@ struct cif_isp10_img_src_ops {
void *img_src,
unsigned int cmd,
void *arg);
int (*s_frame_interval)(
void *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl);
int (*g_frame_interval)(
void *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl);
};
const struct {
@ -81,7 +87,11 @@ const struct {
.s_ext_ctrls =
cif_isp10_img_src_v4l2_subdev_s_ext_ctrls,
.ioctl =
cif_isp10_img_src_v4l2_subdev_ioctl
cif_isp10_img_src_v4l2_subdev_ioctl,
.s_frame_interval =
cif_isp10_img_src_v4l2_subdev_s_frame_interval,
.g_frame_interval =
cif_isp10_img_src_v4l2_subdev_g_frame_interval,
}
},
};

View File

@ -64,6 +64,10 @@ static enum cif_isp10_pix_fmt img_src_v4l2_subdev_pix_fmt2cif_isp10_pix_fmt(
int img_src_pix_fmt)
{
switch (img_src_pix_fmt) {
case MEDIA_BUS_FMT_Y8_1X8:
return CIF_YUV400;
case MEDIA_BUS_FMT_Y10_1X10:
return CIF_Y10;
case MEDIA_BUS_FMT_YUYV8_1_5X8:
case MEDIA_BUS_FMT_YUYV8_2X8:
case MEDIA_BUS_FMT_YUYV10_2X10:
@ -136,6 +140,10 @@ static int cif_isp10_pix_fmt2img_src_v4l2_subdev_pix_fmt(
enum cif_isp10_pix_fmt cif_isp10_pix_fmt)
{
switch (cif_isp10_pix_fmt) {
case CIF_Y10:
return MEDIA_BUS_FMT_Y10_1X10;
case CIF_YUV400:
return MEDIA_BUS_FMT_Y8_1X8;
case CIF_YUV422I:
return MEDIA_BUS_FMT_YUYV8_2X8;
case CIF_YVU422I:
@ -460,6 +468,8 @@ long cif_isp10_img_src_v4l2_subdev_ioctl(
switch (cmd) {
case RK_VIDIOC_SENSOR_MODE_DATA:
case RK_VIDIOC_CAMERA_MODULEINFO:
case RK_VIDIOC_SENSOR_CONFIGINFO:
case RK_VIDIOC_SENSOR_REG_ACCESS:
case PLTFRM_CIFCAM_G_ITF_CFG:
case PLTFRM_CIFCAM_G_DEFRECT:
@ -484,3 +494,49 @@ long cif_isp10_img_src_v4l2_subdev_ioctl(
return ret;
}
int cif_isp10_img_src_v4l2_subdev_s_frame_interval(
void *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl)
{
int ret = 0;
struct v4l2_subdev *subdev = img_src;
struct v4l2_subdev_frame_interval interval;
interval.interval.numerator = frm_intrvl->numerator;
interval.interval.denominator = frm_intrvl->denominator;
ret = v4l2_subdev_call(subdev, video, s_frame_interval, &interval);
if (IS_ERR_VALUE(ret))
goto err;
return 0;
err:
pr_err("img_src.%s ERR: failed with error %d\n", __func__, ret);
return ret;
}
int cif_isp10_img_src_v4l2_subdev_g_frame_interval(
void *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl)
{
int ret = 0;
struct v4l2_subdev *subdev = img_src;
struct v4l2_subdev_frame_interval interval;
interval.interval.numerator = 0;
interval.interval.denominator = 0;
ret = v4l2_subdev_call(subdev, video, g_frame_interval, &interval);
if (IS_ERR_VALUE(ret))
goto err;
frm_intrvl->denominator = interval.interval.denominator;
frm_intrvl->numerator = interval.interval.numerator;
return 0;
err:
pr_err("img_src.%s ERR: failed with error %d\n", __func__, ret);
return ret;
}

View File

@ -62,4 +62,12 @@ long cif_isp10_img_src_v4l2_subdev_ioctl(
unsigned int cmd,
void *arg);
int cif_isp10_img_src_v4l2_subdev_s_frame_interval(
void *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl);
int cif_isp10_img_src_v4l2_subdev_g_frame_interval(
void *img_src,
struct cif_isp10_frm_intrvl *frm_intrvl);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -25,6 +25,8 @@
/*
* ISP device struct
*/
#define CIF_ISP10_META_INFO_NUM 2
enum cif_isp10_pix_fmt;
enum cif_isp10_pix_fmt_quantization {
@ -33,18 +35,34 @@ enum cif_isp10_pix_fmt_quantization {
CIF_ISP10_QUANTIZATION_LIM_RANGE = 2
};
struct cif_isp10_isp_meta_info {
unsigned int write_id;
unsigned int read_id;
unsigned int read_cnt;
unsigned int read_max;
unsigned int frame_id[CIF_ISP10_META_INFO_NUM];
struct timeval vs_t[CIF_ISP10_META_INFO_NUM];
struct timeval fi_t[CIF_ISP10_META_INFO_NUM];
};
struct cif_isp10_isp_cfgs_log {
unsigned int s_frame_id[3];
unsigned int new_id;
unsigned int curr_id;
};
struct cif_isp10_isp_other_cfgs {
struct cifisp_isp_other_cfg *last_or_new;
struct cifisp_isp_other_cfg *curr;
struct cifisp_isp_other_cfg cfgs[2];
struct cif_isp10_isp_cfgs_log log[CIFISP_MODULE_MAX];
struct cifisp_isp_other_cfg cfgs[3];
unsigned int module_updates;
unsigned int module_actives;
};
struct cif_isp10_isp_meas_cfgs {
struct cifisp_isp_meas_cfg *last_or_new;
struct cifisp_isp_meas_cfg *curr;
struct cifisp_isp_meas_cfg cfgs[2];
struct cif_isp10_isp_cfgs_log log[CIFISP_MODULE_MAX];
struct cifisp_isp_meas_cfg cfgs[3];
unsigned int module_updates;
unsigned int module_actives;
};
struct cif_isp10_isp_meas_stats {
@ -87,10 +105,17 @@ struct cif_isp10_isp_dev {
unsigned int frame_id;
unsigned int frame_id_setexp;
unsigned int active_meas;
unsigned int meas_send_alone;
bool awb_meas_ready;
bool afm_meas_ready;
bool aec_meas_ready;
bool hst_meas_ready;
struct timeval vs_t; /* updated each frame */
struct timeval fi_t; /* updated each frame */
struct workqueue_struct *readout_wq;
struct cif_isp10_isp_meta_info meta_info;
unsigned int *dev_id;
@ -107,11 +132,13 @@ struct cif_isp10_isp_readout_work {
struct cif_isp10_isp_dev *isp_dev;
unsigned int frame_id;
unsigned int active_meas;
struct timeval vs_t;
struct timeval fi_t;
enum cif_isp10_isp_readout_cmd readout;
struct vb2_buffer *vb;
unsigned int stream_id;
struct cifisp_isp_metadata *isp_metadata;
};
int register_cifisp_device(
@ -126,11 +153,14 @@ void cifisp_configure_isp(
enum cif_isp10_pix_fmt_quantization quantization);
void cifisp_disable_isp(struct cif_isp10_isp_dev *isp_dev);
int cifisp_isp_isr(struct cif_isp10_isp_dev *isp_dev, u32 isp_mis);
void cifisp_clr_readout_wq(struct cif_isp10_isp_dev *isp_dev);
void cifisp_v_start(struct cif_isp10_isp_dev *isp_dev,
const struct timeval *timestamp);
void cifisp_frame_in(
struct cif_isp10_isp_dev *isp_dev,
const struct timeval *fi_t);
void cifisp_frame_id_reset(
struct cif_isp10_isp_dev *isp_dev);
void cifisp_isp_readout_work(struct work_struct *work);
#endif

View File

@ -29,7 +29,7 @@
#include "cif_isp10.h"
#include <linux/platform_data/rk_isp10_platform.h>
#include "cif_isp10_regs.h"
#ifndef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/fs.h>
#include <media/v4l2-controls_rockchip.h>
@ -67,12 +67,8 @@ struct cif_isp10_pltfrm_data {
int mis;
int (*isr)(unsigned int mis, void *cntxt);
} irq_handlers[4];
struct list_head csi0_configs;
struct list_head csi1_configs;
s32 exp_time;
u16 gain;
#ifndef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
struct {
struct dentry *dir;
struct dentry *cif_isp10_file;
@ -91,7 +87,7 @@ void cif_isp10_pltfrm_debug_register_print_cb(
struct device *dev,
void (*print)(void *cntxt, const char *block),
void *cntxt) {
#ifndef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
struct cif_isp10_pltfrm_data *pdata = dev->platform_data;
pdata->dbgfs.print_cntxt = cntxt;
@ -99,334 +95,9 @@ void cif_isp10_pltfrm_debug_register_print_cb(
#endif
}
#ifndef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
#define CIF_ISP10_DBGFS_BUF_SIZE 1024
static char cif_isp10_dbgfs_buf[CIF_ISP10_DBGFS_BUF_SIZE];
static int cif_isp10_dbgfs_fill_csi_config_from_string(
struct device *dev,
struct cif_isp10_csi_config *csi_config,
char *strp)
{
char *token;
token = strsep(&strp, " ");
if (IS_ERR_OR_NULL(token))
goto missing_token;
if (IS_ERR_VALUE(kstrtou32(token, 10,
&csi_config->vc)))
goto wrong_token_format;
token = strsep(&strp, " ");
if (IS_ERR_OR_NULL(token))
goto missing_token;
if (IS_ERR_VALUE(kstrtou32(token, 10,
&csi_config->nb_lanes)))
goto wrong_token_format;
token = strsep(&strp, " ");
if (IS_ERR_OR_NULL(token))
goto missing_token;
if (IS_ERR_VALUE(kstrtou32(token, 16,
&csi_config->dphy1)))
goto wrong_token_format;
token = strsep(&strp, " ");
if (IS_ERR_OR_NULL(token))
goto missing_token;
if (IS_ERR_VALUE(kstrtou32(token, 16,
&csi_config->dphy2)))
goto wrong_token_format;
token = strsep(&strp, " ");
if (!IS_ERR_OR_NULL(token)) {
if (IS_ERR_VALUE(kstrtou32(token, 10,
&csi_config->ana_bandgab_bias)))
goto wrong_token_format;
} else {
csi_config->ana_bandgab_bias = (u32)-1;
}
return 0;
missing_token:
cif_isp10_pltfrm_pr_err(dev,
"missing token, command format is 'push <pps> <vc> <#lanes> <HEX dphy1> <HEX dphy2> <analog bandgap bias>'\n");
return -EINVAL;
wrong_token_format:
cif_isp10_pltfrm_pr_err(dev,
"wrong token format, command format is 'push <pps> <vc> <#lanes> <HEX dphy1> <HEX dphy2> <analog bandgap bias>'\n");
return -EINVAL;
}
static int cif_isp10_dbgfs_csi_configs_init(
struct device *dev,
enum cif_isp10_inp inp,
struct list_head *csi_configs)
{
int ret = 0;
struct device *img_src_dev = NULL;
struct device_node *parent_node = NULL;
struct device_node *child_node = NULL, *prev_node = NULL;
struct cif_isp10_pltfrm_csi_config *cfg = NULL;
u32 pps;
img_src_dev = cif_isp10_pltfrm_get_img_src_device(dev, inp);
if (IS_ERR_OR_NULL(img_src_dev)) {
ret = -EFAULT;
goto err;
}
parent_node = of_node_get(img_src_dev->of_node);
put_device(img_src_dev);
img_src_dev = NULL;
while (!IS_ERR_OR_NULL(child_node =
of_get_next_child(parent_node, prev_node))) {
if (!strncasecmp(child_node->name,
"intel,camera-module-csi-config",
strlen("intel,camera-module-csi-config"))) {
ret = of_property_read_u32(child_node,
"intel,csi-pixels-per-second", &pps);
if (IS_ERR_VALUE(ret)) {
cif_isp10_pltfrm_pr_err(dev,
"reading property 'intel,csi-pixels-per-second'\n");
goto err;
}
cfg = kmalloc(
sizeof(struct cif_isp10_pltfrm_csi_config),
GFP_KERNEL);
if (!cfg) {
cif_isp10_pltfrm_pr_err(dev,
"memory allocation failed\n");
ret = -ENOMEM;
goto err;
}
cfg->pps = pps;
ret = cif_isp10_pltfrm_fill_csi_config_from_node(
dev, &cfg->csi_config, child_node);
if (IS_ERR_VALUE(ret))
goto err;
list_add_tail(&cfg->list, csi_configs);
cfg = NULL;
}
of_node_put(prev_node);
prev_node = child_node;
}
of_node_put(prev_node);
of_node_put(parent_node);
return 0;
err:
of_node_put(prev_node);
of_node_put(child_node);
of_node_put(parent_node);
kfree(cfg);
if (!IS_ERR_OR_NULL(img_src_dev))
put_device(img_src_dev);
return ret;
}
static ssize_t cif_isp10_dbgfs_csi_read(
struct file *f,
char __user *out,
size_t count,
loff_t *pos)
{
u32 out_size = 0;
u32 str_len;
struct cif_isp10_pltfrm_csi_config *cfg;
u32 index = 0;
struct list_head *list_pos;
struct device *dev = f->f_inode->i_private;
struct cif_isp10_pltfrm_data *pdata = dev->platform_data;
struct list_head *csi_configs;
enum cif_isp10_inp inp;
if (f->f_inode == pdata->dbgfs.csi0_file->d_inode) {
csi_configs = &pdata->csi0_configs;
inp = CIF_ISP10_INP_CSI_0;
} else if (f->f_inode == pdata->dbgfs.csi1_file->d_inode) {
csi_configs = &pdata->csi1_configs;
inp = CIF_ISP10_INP_CSI_1;
} else {
cif_isp10_pltfrm_pr_err(dev, "wrong file handle\n");
return -EINVAL;
}
if (list_empty(csi_configs))
if (IS_ERR_VALUE(cif_isp10_dbgfs_csi_configs_init(
dev, inp, csi_configs)))
return -EFAULT;
if (*pos)
return 0;
list_for_each(list_pos, csi_configs) {
cfg = list_entry(list_pos,
struct cif_isp10_pltfrm_csi_config, list);
sprintf(cif_isp10_dbgfs_buf,
"csi-config-%d:\n"
" pps = %d\n"
" vc = %d\n"
" nb_lanes = %d\n"
" dphy1 = 0x%08x\n"
" dphy2 = 0x%08x\n"
" ana_bandgap_bias = %d\n",
index,
cfg->pps, cfg->csi_config.vc, cfg->csi_config.nb_lanes,
cfg->csi_config.dphy1, cfg->csi_config.dphy2,
cfg->csi_config.ana_bandgab_bias);
index++;
str_len = strnlen(cif_isp10_dbgfs_buf,
CIF_ISP10_DBGFS_BUF_SIZE);
if (str_len > count) {
*pos += out_size;
return 0;
}
*pos = 0;
if (IS_ERR_VALUE(simple_read_from_buffer(
out + out_size, str_len, pos,
cif_isp10_dbgfs_buf, str_len)))
break;
out_size += strnlen(cif_isp10_dbgfs_buf,
CIF_ISP10_DBGFS_BUF_SIZE);
count -= str_len;
}
*pos += out_size;
return out_size;
}
static ssize_t cif_isp10_dbgfs_csi_write(
struct file *f,
const char __user *in,
size_t count,
loff_t *pos)
{
ssize_t ret;
char *strp = cif_isp10_dbgfs_buf;
char *token;
struct device *dev = f->f_inode->i_private;
struct cif_isp10_pltfrm_data *pdata = dev->platform_data;
struct list_head *csi_configs;
enum cif_isp10_inp inp;
if (count > CIF_ISP10_DBGFS_BUF_SIZE) {
cif_isp10_pltfrm_pr_err(dev, "command line too large\n");
return -EINVAL;
}
if (f->f_inode == pdata->dbgfs.csi0_file->d_inode) {
csi_configs = &pdata->csi0_configs;
inp = CIF_ISP10_INP_CSI_0;
} else if (f->f_inode == pdata->dbgfs.csi1_file->d_inode) {
csi_configs = &pdata->csi1_configs;
inp = CIF_ISP10_INP_CSI_1;
} else {
cif_isp10_pltfrm_pr_err(dev, "wrong file handle\n");
return -EINVAL;
}
if (list_empty(csi_configs))
if (IS_ERR_VALUE(cif_isp10_dbgfs_csi_configs_init(
dev, inp, csi_configs)))
return -EFAULT;
memset(cif_isp10_dbgfs_buf, 0, CIF_ISP10_DBGFS_BUF_SIZE);
ret = simple_write_to_buffer(strp,
CIF_ISP10_DBGFS_BUF_SIZE, pos, in, count);
if (IS_ERR_VALUE(ret))
return ret;
token = strsep(&strp, " ");
if (!strcmp(token, "push")) {
struct cif_isp10_pltfrm_csi_config cfg;
token = strsep(&strp, " ");
if (IS_ERR_OR_NULL(token)) {
cif_isp10_pltfrm_pr_err(dev,
"missing token, command format is 'push <pps> <vc> <#lanes> <HEX dphy1> <HEX dphy2> <analog bandgap bias>'\n");
return -EINVAL;
}
if (IS_ERR_VALUE(kstrtou32(token, 10,
&cfg.pps))) {
cif_isp10_pltfrm_pr_err(dev,
"missing token, command format is 'push <pps> <vc> <#lanes> <HEX dphy1> <HEX dphy2> <analog bandgap bias>'\n");
return -EINVAL;
}
ret = cif_isp10_dbgfs_fill_csi_config_from_string(
dev, &cfg.csi_config, strp);
if (IS_ERR_VALUE(ret))
return ret;
ret = cif_isp10_pltfrm_l_s_csi_config(
dev, inp, cfg.pps, &cfg.csi_config);
if (IS_ERR_VALUE(ret))
return ret;
} else if (!strncmp(token, "reset", 5)) {
} else {
cif_isp10_pltfrm_pr_err(dev, "unknown command %s\n", token);
return -EINVAL;
}
return count;
}
void cif_isp10_dbgfs_fill_sensor_aec_para(
struct cif_isp10_device *cif_isp10_dev,
s32 exp_time,
u16 gain)
{
struct cif_isp10_pltfrm_data *pdata;
pdata = (struct cif_isp10_pltfrm_data *)
cif_isp10_dev->dev->platform_data;
pdata->exp_time = exp_time;
pdata->gain = gain;
}
static ssize_t cif_isp10_dbgfs_sensor_read(
struct file *f,
char __user *out,
size_t count,
loff_t *pos)
{
u32 out_size = 0;
u32 str_len;
struct device *dev = f->f_inode->i_private;
struct cif_isp10_pltfrm_data *pdata = dev->platform_data;
if (*pos)
return 0;
sprintf(cif_isp10_dbgfs_buf,
"sensor current exp_time: %d\n"
" gain = %d\n",
pdata->exp_time,
pdata->gain);
str_len = strnlen(cif_isp10_dbgfs_buf,
CIF_ISP10_DBGFS_BUF_SIZE);
if (str_len > count) {
*pos += out_size;
return 0;
}
*pos = 0;
if (IS_ERR_VALUE(simple_read_from_buffer(
out + out_size, str_len, pos,
cif_isp10_dbgfs_buf, str_len)))
goto ERR;
out_size += strnlen(cif_isp10_dbgfs_buf,
CIF_ISP10_DBGFS_BUF_SIZE);
count -= str_len;
*pos += out_size;
ERR:
return out_size;
}
static ssize_t cif_isp10_dbgfs_sensor_write(
struct file *f,
const char __user *in,
size_t count,
loff_t *pos)
{
return 0;
}
static ssize_t cif_isp10_dbgfs_write(
struct file *f,
const char __user *in,
@ -497,7 +168,7 @@ static ssize_t cif_isp10_dbgfs_write(
}
if (!strncmp(token, "on", 2)) {
if (IS_ERR_VALUE(cif_isp10_pltfrm_pm_set_state(dev,
CIF_ISP10_PM_STATE_SW_STNDBY, NULL)))
CIF_ISP10_PM_STATE_SW_STNDBY)))
cif_isp10_pltfrm_pr_err(dev,
"power on failed\n");
else
@ -505,7 +176,7 @@ static ssize_t cif_isp10_dbgfs_write(
"switched on\n");
} else if (!strncmp(token, "off", 3)) {
if (IS_ERR_VALUE(cif_isp10_pltfrm_pm_set_state(dev,
CIF_ISP10_PM_STATE_OFF, NULL)))
CIF_ISP10_PM_STATE_OFF)))
cif_isp10_pltfrm_pr_err(dev,
"power off failed\n");
else
@ -556,20 +227,10 @@ static ssize_t cif_isp10_dbgfs_write(
return count;
}
static const struct file_operations cif_isp10_dbgfs_csi_fops = {
.read = cif_isp10_dbgfs_csi_read,
.write = cif_isp10_dbgfs_csi_write
};
static const struct file_operations cif_isp10_dbgfs_fops = {
.write = cif_isp10_dbgfs_write
};
static const struct file_operations cif_isp10_dbgfs_sensor_fops = {
.read = cif_isp10_dbgfs_sensor_read,
.write = cif_isp10_dbgfs_sensor_write
};
#ifdef CONFIG_CIF_ISP10_REG_TRACE
static inline int cif_isp10_pltfrm_trace_printf(
@ -614,7 +275,7 @@ static inline int cif_isp10_pltfrm_trace_printf(
return i;
}
inline int cif_isp10_pltfrm_rtrace_printf(
int cif_isp10_pltfrm_rtrace_printf(
struct device *dev,
const char *fmt,
...)
@ -629,7 +290,7 @@ inline int cif_isp10_pltfrm_rtrace_printf(
return i;
}
inline int cif_isp10_pltfrm_ftrace_printf(
int cif_isp10_pltfrm_ftrace_printf(
struct device *dev,
const char *fmt,
...)
@ -1290,35 +951,15 @@ int cif_isp10_pltfrm_dev_init(
dev->platform_data = pdata;
INIT_LIST_HEAD(&pdata->csi0_configs);
INIT_LIST_HEAD(&pdata->csi1_configs);
#ifndef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
pdata->dbgfs.dir = debugfs_create_dir("cif_isp10", NULL);
pdata->dbgfs.csi0_file = debugfs_create_file(
"csi-0",
0644,
pdata->dbgfs.dir,
dev,
&cif_isp10_dbgfs_csi_fops);
pdata->dbgfs.csi1_file = debugfs_create_file(
"csi-1",
0644,
pdata->dbgfs.dir,
dev,
&cif_isp10_dbgfs_csi_fops);
pdata->dbgfs.cif_isp10_file = debugfs_create_file(
"cif_isp20",
0200,
pdata->dbgfs.dir,
dev,
&cif_isp10_dbgfs_fops);
pdata->dbgfs.cif_isp10_file = debugfs_create_file(
"sensor",
0644,
pdata->dbgfs.dir,
dev,
&cif_isp10_dbgfs_sensor_fops);
#ifdef CONFIG_CIF_ISP10_REG_TRACE
pdata->dbgfs.reg_trace_file = debugfs_create_file(
"reg_trace",
@ -1450,7 +1091,7 @@ int cif_isp10_pltfrm_g_interface_config(
PLTFRM_CIFCAM_G_ITF_CFG, (void *)cam_itf);
if (IS_ERR_VALUE(ret)) {
cif_isp10_pltfrm_pr_err(
dev,
NULL,
"cif_isp10_img_src_ioctl PLTFRM_CIFCAM_G_ITF_CFG failed!\n");
return ret;
}
@ -1669,8 +1310,6 @@ int cif_isp10_pltfrm_get_img_src_device(
array_len);
break;
}
} else {
continue;
}
}
@ -1691,7 +1330,7 @@ void cif_isp10_pltfrm_dev_release(
cif_isp10_drm_iommu_cb(dev, cif_isp10_dev, false);
#endif
#ifndef CONFIG_DEBUG_FS
#ifdef CONFIG_DEBUG_FS
{
struct cif_isp10_pltfrm_data *pdata =
dev->platform_data;

View File

@ -30,10 +30,10 @@
#include <linux/pagemap.h>
#include <linux/slab.h>
#define CIF_ISP10_V4L2_SP_DEV_MAJOR 0
#define CIF_ISP10_V4L2_ISP_DEV_MAJOR 1
#define CIF_ISP10_V4L2_MP_DEV_MAJOR 2
#define CIF_ISP10_V4L2_DMA_DEV_MAJOR 3
#define CIF_ISP10_V4L2_SP_DEV_MAJOR -1
#define CIF_ISP10_V4L2_ISP_DEV_MAJOR -1
#define CIF_ISP10_V4L2_MP_DEV_MAJOR -1
#define CIF_ISP10_V4L2_DMA_DEV_MAJOR -1
#define SP_DEV 0
#define MP_DEV 1
@ -330,6 +330,8 @@ static enum cif_isp10_pix_fmt cif_isp10_v4l2_pix_fmt2cif_isp10_pix_fmt(
switch (v4l2_pix_fmt) {
case V4L2_PIX_FMT_GREY:
return CIF_YUV400;
case V4L2_PIX_FMT_Y10:
return CIF_Y10;
case V4L2_PIX_FMT_YUV420:
return CIF_YUV420P;
case V4L2_PIX_FMT_YVU420:
@ -506,6 +508,31 @@ static int cif_isp10_v4l2_register_video_device(
return ret;
}
static int cif_isp10_v4l2_register_imgsrc_subdev(
struct cif_isp10_device *dev)
{
unsigned int i;
struct v4l2_subdev *sd;
for (i = 0; i < dev->img_src_cnt; i++) {
if (dev->img_src_array[i] != NULL) {
sd = (struct v4l2_subdev *)
cif_isp10_img_src_g_img_src(
dev->img_src_array[i]);
if (sd) {
if (v4l2_device_register_subdev(
&dev->v4l2_dev,
sd) < 0)
cif_isp10_pltfrm_pr_err(dev->dev,
"register subdev(%s) failed!",
cif_isp10_img_src_g_name(dev->img_src_array[i]));
}
}
}
return v4l2_device_register_subdev_nodes(&dev->v4l2_dev);
}
static int cif_isp10_v4l2_streamon(
struct file *file,
void *priv,
@ -1133,18 +1160,24 @@ static unsigned int cif_isp10_v4l2_poll(
*/
static void cif_isp10_v4l2_vm_open(struct vm_area_struct *vma)
{
unsigned long flags = 0;
struct cif_isp10_metadata_s *metadata =
(struct cif_isp10_metadata_s *)vma->vm_private_data;
spin_lock_irqsave(&metadata->spinlock, flags);
metadata->vmas++;
spin_unlock_irqrestore(&metadata->spinlock, flags);
}
static void cif_isp10_v4l2_vm_close(struct vm_area_struct *vma)
{
unsigned long flags = 0;
struct cif_isp10_metadata_s *metadata =
(struct cif_isp10_metadata_s *)vma->vm_private_data;
spin_lock_irqsave(&metadata->spinlock, flags);
metadata->vmas--;
spin_unlock_irqrestore(&metadata->spinlock, flags);
}
static const struct vm_operations_struct cif_isp10_vm_ops = {
@ -1348,6 +1381,30 @@ static long v4l2_default_ioctl(struct file *file, void *fh,
"failed to get camera module information\n");
return ret;
}
} else if (cmd == RK_VIDIOC_SENSOR_CONFIGINFO) {
struct sensor_config_info_s *p_sensor_config =
(struct sensor_config_info_s *)arg;
ret = (int)cif_isp10_img_src_ioctl(dev->img_src,
RK_VIDIOC_SENSOR_CONFIGINFO, p_sensor_config);
if (ret < 0) {
cif_isp10_pltfrm_pr_err(dev->dev,
"failed to get camera module information\n");
return ret;
}
} else if (cmd == RK_VIDIOC_SENSOR_REG_ACCESS) {
struct sensor_reg_rw_s *p_sensor_rw =
(struct sensor_reg_rw_s *)arg;
ret = (int)cif_isp10_img_src_ioctl(dev->img_src,
RK_VIDIOC_SENSOR_REG_ACCESS, p_sensor_rw);
if (ret < 0) {
cif_isp10_pltfrm_pr_err(dev->dev,
"failed to get camera module information\n");
return ret;
}
}
return ret;
@ -1511,9 +1568,9 @@ static int v4l2_s_ext_ctrls(struct file *file, void *priv,
struct v4l2_ext_controls *vc_ext)
{
struct cif_isp10_img_src_ctrl *ctrls;
struct cif_isp10_img_src_ext_ctrl *ctrl;
struct vb2_queue *queue = to_vb2_queue(file);
struct cif_isp10_device *dev = to_cif_isp10_device(queue);
struct cif_isp10_img_src_ext_ctrl ctrl;
int ret = -EINVAL;
unsigned int i;
@ -1526,30 +1583,24 @@ static int v4l2_s_ext_ctrls(struct file *file, void *priv,
if (vc_ext->count == 0)
return ret;
ctrl = kmalloc(sizeof(*ctrl), GFP_KERNEL);
if (!ctrl)
return -ENOMEM;
ctrls = kmalloc(vc_ext->count *
sizeof(struct cif_isp10_img_src_ctrl), GFP_KERNEL);
if (!ctrls) {
kfree(ctrl);
if (!ctrls)
return -ENOMEM;
}
ctrl->cnt = vc_ext->count;
ctrl.cnt = vc_ext->count;
/*current kernel version don't define
*this member for struct v4l2_ext_control.
*/
/*ctrl->class = vc_ext->ctrl_class;*/
ctrl->ctrls = ctrls;
/*ctrl.class = vc_ext->ctrl_class;*/
ctrl.ctrls = ctrls;
for (i = 0; i < vc_ext->count; i++) {
ctrls[i].id = vc_ext->controls[i].id;
ctrls[i].val = vc_ext->controls[i].value;
}
ret = cif_isp10_s_exp(dev, ctrl);
ret = cif_isp10_s_exp(dev, &ctrl);
return ret;
}
@ -1768,7 +1819,8 @@ static const struct of_device_id cif_isp10_v4l2_of_match[] = {
{},
};
static unsigned int cif_isp10_v4l2_dev_cnt;
static unsigned int g_cif_isp10_v4l2_dev_cnt;
static struct cif_isp10_v4l2_device *g_cif_isp10_v4l2_dev[4];
static int cif_isp10_v4l2_drv_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
@ -1777,7 +1829,10 @@ static int cif_isp10_v4l2_drv_probe(struct platform_device *pdev)
struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev;
int ret;
cif_isp10_pltfrm_pr_info(NULL, "probing...\n");
cif_isp10_pltfrm_pr_info(NULL, "CIF ISP10 driver version: v%x.%x.%x\n",
CONFIG_CIFISP10_DRIVER_VERSION >> 16,
(CONFIG_CIFISP10_DRIVER_VERSION & 0xff00) >> 8,
CONFIG_CIFISP10_DRIVER_VERSION & 0x00ff);
cif_isp10_v4l2_dev = devm_kzalloc(
&pdev->dev,
@ -1798,7 +1853,7 @@ static int cif_isp10_v4l2_drv_probe(struct platform_device *pdev)
goto err;
}
dev->dev_id = cif_isp10_v4l2_dev_cnt;
dev->dev_id = g_cif_isp10_v4l2_dev_cnt;
dev->isp_dev.dev_id = &dev->dev_id;
dev->nodes = (void *)cif_isp10_v4l2_dev;
dev->isp_state = CIF_ISP10_STATE_IDLE;
@ -1855,9 +1910,14 @@ static int cif_isp10_v4l2_drv_probe(struct platform_device *pdev)
if (ret)
goto err;
cif_isp10_v4l2_register_imgsrc_subdev(
dev);
pm_runtime_enable(&pdev->dev);
cif_isp10_v4l2_dev_cnt++;
g_cif_isp10_v4l2_dev[g_cif_isp10_v4l2_dev_cnt] =
cif_isp10_v4l2_dev;
g_cif_isp10_v4l2_dev_cnt++;
return 0;
err:
cif_isp10_destroy(dev);
@ -1886,7 +1946,8 @@ static int cif_isp10_v4l2_drv_remove(struct platform_device *pdev)
cif_isp10_pltfrm_dev_release(&pdev->dev, cif_isp10_dev);
cif_isp10_destroy(cif_isp10_dev);
cif_isp10_v4l2_dev_cnt--;
g_cif_isp10_v4l2_dev_cnt--;
g_cif_isp10_v4l2_dev[g_cif_isp10_v4l2_dev_cnt] = NULL;
return 0;
}
@ -1976,6 +2037,7 @@ static int cif_isp10_v4l2_init(void)
{
int ret;
g_cif_isp10_v4l2_dev_cnt = 0;
ret = platform_driver_register(&cif_isp10_v4l2_plat_drv);
if (ret) {
cif_isp10_pltfrm_pr_err(NULL,
@ -1993,6 +2055,74 @@ static void __exit cif_isp10_v4l2_exit(void)
platform_driver_unregister(&cif_isp10_v4l2_plat_drv);
}
/* ======================================================================== */
void cif_isp10_v4l2_s_frame_interval(
unsigned int numerator,
unsigned int denominator)
{
struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev;
struct cif_isp10_device *cif_isp10_dev;
struct vb2_queue *queue;
struct cif_isp10_frm_intrvl frm_intrvl;
unsigned int i;
for (i = 0; i < g_cif_isp10_v4l2_dev_cnt; i++) {
if (g_cif_isp10_v4l2_dev[i] == NULL)
continue;
cif_isp10_v4l2_dev =
g_cif_isp10_v4l2_dev[i];
queue = (struct vb2_queue *)
&cif_isp10_v4l2_dev->node[SP_DEV].buf_queue;
cif_isp10_dev = to_cif_isp10_device(queue);
if (cif_isp10_dev->img_src == NULL)
continue;
frm_intrvl.numerator = numerator;
frm_intrvl.denominator = denominator;
cif_isp10_img_src_s_frame_interval(
cif_isp10_dev->img_src,
&frm_intrvl);
}
}
int cif_isp10_v4l2_g_frame_interval(
unsigned int *numerator,
unsigned int *denominator)
{
struct cif_isp10_v4l2_device *cif_isp10_v4l2_dev;
struct cif_isp10_device *cif_isp10_dev;
struct vb2_queue *queue;
struct cif_isp10_frm_intrvl frm_intrvl;
unsigned int i;
int ret = -EFAULT;
for (i = 0; i < g_cif_isp10_v4l2_dev_cnt; i++) {
if (g_cif_isp10_v4l2_dev[i] == NULL)
continue;
cif_isp10_v4l2_dev =
g_cif_isp10_v4l2_dev[i];
queue = (struct vb2_queue *)
&cif_isp10_v4l2_dev->node[SP_DEV].buf_queue;
cif_isp10_dev = to_cif_isp10_device(queue);
if (cif_isp10_dev->img_src == NULL)
continue;
ret = cif_isp10_img_src_g_frame_interval(
cif_isp10_dev->img_src,
&frm_intrvl);
if (ret == 0) {
*numerator = frm_intrvl.numerator;
*denominator = frm_intrvl.denominator;
}
}
return ret;
}
device_initcall_sync(cif_isp10_v4l2_init);
module_exit(cif_isp10_v4l2_exit);

View File

@ -103,8 +103,11 @@
*5. modify for af function.
*6. add module parameter for dumpsys.
*
*v0.1.0xf
*1. merge modification from rv1108 project.
*
*/
#define CONFIG_CIFISP10_DRIVER_VERSION KERNEL_VERSION(0, 1, 0xe)
#define CONFIG_CIFISP10_DRIVER_VERSION KERNEL_VERSION(0, 1, 0xf)
#endif

View File

@ -18,24 +18,47 @@
#include <media/v4l2-config_rockchip.h>
#define CIFISP_MODULE_DPCC BIT(0)
#define CIFISP_MODULE_BLS BIT(1)
#define CIFISP_MODULE_SDG BIT(2)
#define CIFISP_MODULE_HST BIT(3)
#define CIFISP_MODULE_LSC BIT(4)
#define CIFISP_MODULE_AWB_GAIN BIT(5)
#define CIFISP_MODULE_FLT BIT(6)
#define CIFISP_MODULE_BDM BIT(7)
#define CIFISP_MODULE_CTK BIT(8)
#define CIFISP_MODULE_GOC BIT(9)
#define CIFISP_MODULE_CPROC BIT(10)
#define CIFISP_MODULE_AFC BIT(11)
#define CIFISP_MODULE_AWB BIT(12)
#define CIFISP_MODULE_IE BIT(13)
#define CIFISP_MODULE_AEC BIT(14)
#define CIFISP_MODULE_WDR BIT(15)
#define CIFISP_MODULE_DPF BIT(16)
#define CIFISP_MODULE_DPF_STRENGTH BIT(17)
#define CIFISP_MODULE_MAX 18
/* ISP Other module ID */
#define CIFISP_DPCC_ID 0
#define CIFISP_BLS_ID 1
#define CIFISP_SDG_ID 2
#define CIFISP_LSC_ID 3
#define CIFISP_AWB_GAIN_ID 4
#define CIFISP_FLT_ID 5
#define CIFISP_BDM_ID 6
#define CIFISP_CTK_ID 7
#define CIFISP_GOC_ID 8
#define CIFISP_CPROC_ID 9
#define CIFISP_IE_ID 10
#define CIFISP_WDR_ID 11
#define CIFISP_DPF_ID 12
#define CIFISP_DPF_STRENGTH_ID 13
/* ISP Meas module ID, It must be after other id */
#define CIFISP_MEAS_ID 14
#define CIFISP_AEC_ID (CIFISP_MEAS_ID + 0)
#define CIFISP_AFC_ID (CIFISP_MEAS_ID + 1)
#define CIFISP_AWB_ID (CIFISP_MEAS_ID + 2)
#define CIFISP_HST_ID (CIFISP_MEAS_ID + 3)
#define CIFISP_MODULE_DPCC (1 << CIFISP_DPCC_ID)
#define CIFISP_MODULE_BLS (1 << CIFISP_BLS_ID)
#define CIFISP_MODULE_SDG (1 << CIFISP_SDG_ID)
#define CIFISP_MODULE_HST (1 << CIFISP_HST_ID)
#define CIFISP_MODULE_LSC (1 << CIFISP_LSC_ID)
#define CIFISP_MODULE_AWB_GAIN (1 << CIFISP_AWB_GAIN_ID)
#define CIFISP_MODULE_FLT (1 << CIFISP_FLT_ID)
#define CIFISP_MODULE_BDM (1 << CIFISP_BDM_ID)
#define CIFISP_MODULE_CTK (1 << CIFISP_CTK_ID)
#define CIFISP_MODULE_GOC (1 << CIFISP_GOC_ID)
#define CIFISP_MODULE_CPROC (1 << CIFISP_CPROC_ID)
#define CIFISP_MODULE_AFC (1 << CIFISP_AFC_ID)
#define CIFISP_MODULE_AWB (1 << CIFISP_AWB_ID)
#define CIFISP_MODULE_IE (1 << CIFISP_IE_ID)
#define CIFISP_MODULE_AEC (1 << CIFISP_AEC_ID)
#define CIFISP_MODULE_WDR (1 << CIFISP_WDR_ID)
#define CIFISP_MODULE_DPF (1 << CIFISP_DPF_ID)
#define CIFISP_MODULE_DPF_STRENGTH (1 << CIFISP_DPF_STRENGTH_ID)
#define CIFISP_CTK_COEFF_MAX 0x100
#define CIFISP_CTK_OFFSET_MAX 0x800

View File

@ -106,22 +106,22 @@
_IOR('v', BASE_VIDIOC_PRIVATE + 35, struct cifisp_last_capture_config)
/* CIF-ISP Private control IDs */
#define V4L2_CID_CIFISP_DPCC (V4L2_CID_PRIVATE_BASE + 0)
#define V4L2_CID_CIFISP_BLS (V4L2_CID_PRIVATE_BASE + 1)
#define V4L2_CID_CIFISP_SDG (V4L2_CID_PRIVATE_BASE + 2)
#define V4L2_CID_CIFISP_LSC (V4L2_CID_PRIVATE_BASE + 3)
#define V4L2_CID_CIFISP_AWB_MEAS (V4L2_CID_PRIVATE_BASE + 4)
#define V4L2_CID_CIFISP_FLT (V4L2_CID_PRIVATE_BASE + 5)
#define V4L2_CID_CIFISP_BDM (V4L2_CID_PRIVATE_BASE + 6)
#define V4L2_CID_CIFISP_CTK (V4L2_CID_PRIVATE_BASE + 7)
#define V4L2_CID_CIFISP_GOC (V4L2_CID_PRIVATE_BASE + 8)
#define V4L2_CID_CIFISP_HST (V4L2_CID_PRIVATE_BASE + 9)
#define V4L2_CID_CIFISP_AEC (V4L2_CID_PRIVATE_BASE + 10)
#define V4L2_CID_CIFISP_AWB_GAIN (V4L2_CID_PRIVATE_BASE + 11)
#define V4L2_CID_CIFISP_CPROC (V4L2_CID_PRIVATE_BASE + 12)
#define V4L2_CID_CIFISP_AFC (V4L2_CID_PRIVATE_BASE + 13)
#define V4L2_CID_CIFISP_IE (V4L2_CID_PRIVATE_BASE + 14)
#define V4L2_CID_CIFISP_DPF (V4L2_CID_PRIVATE_BASE + 15)
#define V4L2_CID_CIFISP_DPCC (V4L2_CID_PRIVATE_BASE + CIFISP_DPCC_ID)
#define V4L2_CID_CIFISP_BLS (V4L2_CID_PRIVATE_BASE + CIFISP_BLS_ID)
#define V4L2_CID_CIFISP_SDG (V4L2_CID_PRIVATE_BASE + CIFISP_SDG_ID)
#define V4L2_CID_CIFISP_HST (V4L2_CID_PRIVATE_BASE + CIFISP_HST_ID)
#define V4L2_CID_CIFISP_LSC (V4L2_CID_PRIVATE_BASE + CIFISP_LSC_ID)
#define V4L2_CID_CIFISP_AWB_GAIN (V4L2_CID_PRIVATE_BASE + CIFISP_AWB_GAIN_ID)
#define V4L2_CID_CIFISP_FLT (V4L2_CID_PRIVATE_BASE + CIFISP_FLT_ID)
#define V4L2_CID_CIFISP_BDM (V4L2_CID_PRIVATE_BASE + CIFISP_BDM_ID)
#define V4L2_CID_CIFISP_CTK (V4L2_CID_PRIVATE_BASE + CIFISP_CTK_ID)
#define V4L2_CID_CIFISP_GOC (V4L2_CID_PRIVATE_BASE + CIFISP_GOC_ID)
#define V4L2_CID_CIFISP_CPROC (V4L2_CID_PRIVATE_BASE + CIFISP_CPROC_ID)
#define V4L2_CID_CIFISP_AFC (V4L2_CID_PRIVATE_BASE + CIFISP_AFC_ID)
#define V4L2_CID_CIFISP_AWB_MEAS (V4L2_CID_PRIVATE_BASE + CIFISP_AWB_ID)
#define V4L2_CID_CIFISP_IE (V4L2_CID_PRIVATE_BASE + CIFISP_IE_ID)
#define V4L2_CID_CIFISP_AEC (V4L2_CID_PRIVATE_BASE + CIFISP_AEC_ID)
#define V4L2_CID_CIFISP_DPF (V4L2_CID_PRIVATE_BASE + CIFISP_DPF_ID)
/* Camera Sensors' running modes */
#define CI_MODE_PREVIEW 0x8000
@ -130,4 +130,11 @@
#define CI_MODE_CONTINUOUS 0x1000
#define CI_MODE_NONE 0x0000
/* Kernel API */
void cif_isp11_v4l2_s_frame_interval(
unsigned int numerator,
unsigned int denominator);
int cif_isp11_v4l2_g_frame_interval(
unsigned int *numerator,
unsigned int *denominator);
#endif

View File

@ -19,6 +19,11 @@
#define CAMERA_STRLEN 32
#define CAMERA_METADATA_LEN (2 * PAGE_SIZE)
#define VALID_FR_EXP_T_INDEX 0
#define VALID_FR_EXP_G_INDEX 1
#define SENSOR_CONFIG_NUM 4
#define SENSOR_READ_MODE 0
#define SENSOR_WRITE_MODE 1
/* Sensor resolution specific data for AE calculation.*/
struct isp_supplemental_sensor_mode_data {
@ -43,6 +48,11 @@ struct isp_supplemental_sensor_mode_data {
unsigned int isp_output_height;
unsigned char binning_factor_x; /* horizontal binning factor used */
unsigned char binning_factor_y; /* vertical binning factor used */
/*
*0: Exposure time valid fileds;
*1: Exposure gain valid fileds;
*(2 fileds == 1 frames)
*/
unsigned char exposure_valid_frame[2];
int exp_time;
unsigned short gain;
@ -65,6 +75,25 @@ struct camera_module_info_s {
int af_support;
};
struct sensor_resolution_s {
unsigned short width;
unsigned short height;
};
struct sensor_config_info_s {
unsigned char config_num;
unsigned char sensor_fmt[SENSOR_CONFIG_NUM];
struct sensor_resolution_s reso[SENSOR_CONFIG_NUM];
};
struct sensor_reg_rw_s {
unsigned char reg_access_mode;
unsigned char reg_addr_len;
unsigned char reg_data_len;
unsigned short addr;
unsigned short data;
};
struct flash_timeinfo_s {
struct timeval preflash_start_t;
struct timeval preflash_end_t;

View File

@ -24,6 +24,10 @@
_IOWR('v', BASE_VIDIOC_PRIVATE + 10, struct camera_module_info_s)
#define RK_VIDIOC_SENSOR_MODE_DATA \
_IOR('v', BASE_VIDIOC_PRIVATE, struct isp_supplemental_sensor_mode_data)
#define RK_VIDIOC_SENSOR_CONFIGINFO \
_IOR('v', BASE_VIDIOC_PRIVATE + 1, struct sensor_config_info_s)
#define RK_VIDIOC_SENSOR_REG_ACCESS \
_IOWR('v', BASE_VIDIOC_PRIVATE + 2, struct sensor_reg_rw_s)
#define V4L2_CID_USER_RK_BASE (V4L2_CID_USER_BASE + 0x1080)
#define RK_V4L2_CID_VBLANKING (V4L2_CID_USER_RK_BASE + 1)