Lines Matching +full:convert +full:- +full:sample +full:- +full:format

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2016-2019 Microchip Technology, Inc.
21 #include <linux/atmel-isc-media.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-device.h>
25 #include <media/v4l2-event.h>
26 #include <media/v4l2-image-sizes.h>
27 #include <media/v4l2-ioctl.h>
28 #include <media/v4l2-fwnode.h>
29 #include <media/v4l2-subdev.h>
30 #include <media/videobuf2-dma-contig.h>
32 #include "microchip-isc-regs.h"
33 #include "microchip-isc.h"
44 struct isc_ctrls *ctrls = &isc->ctrls; in isc_update_v4l2_ctrls()
47 v4l2_ctrl_s_ctrl(isc->r_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_R]); in isc_update_v4l2_ctrls()
48 v4l2_ctrl_s_ctrl(isc->b_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_B]); in isc_update_v4l2_ctrls()
49 v4l2_ctrl_s_ctrl(isc->gr_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GR]); in isc_update_v4l2_ctrls()
50 v4l2_ctrl_s_ctrl(isc->gb_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GB]); in isc_update_v4l2_ctrls()
52 v4l2_ctrl_s_ctrl(isc->r_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_R]); in isc_update_v4l2_ctrls()
53 v4l2_ctrl_s_ctrl(isc->b_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_B]); in isc_update_v4l2_ctrls()
54 v4l2_ctrl_s_ctrl(isc->gr_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GR]); in isc_update_v4l2_ctrls()
55 v4l2_ctrl_s_ctrl(isc->gb_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GB]); in isc_update_v4l2_ctrls()
60 struct isc_ctrls *ctrls = &isc->ctrls; in isc_update_awb_ctrls()
64 regmap_write(isc->regmap, ISC_WB_O_RGR, in isc_update_awb_ctrls()
65 ((ctrls->offset[ISC_HIS_CFG_MODE_R])) | in isc_update_awb_ctrls()
66 ((ctrls->offset[ISC_HIS_CFG_MODE_GR]) << 16)); in isc_update_awb_ctrls()
67 regmap_write(isc->regmap, ISC_WB_O_BGB, in isc_update_awb_ctrls()
68 ((ctrls->offset[ISC_HIS_CFG_MODE_B])) | in isc_update_awb_ctrls()
69 ((ctrls->offset[ISC_HIS_CFG_MODE_GB]) << 16)); in isc_update_awb_ctrls()
70 regmap_write(isc->regmap, ISC_WB_G_RGR, in isc_update_awb_ctrls()
71 ctrls->gain[ISC_HIS_CFG_MODE_R] | in isc_update_awb_ctrls()
72 (ctrls->gain[ISC_HIS_CFG_MODE_GR] << 16)); in isc_update_awb_ctrls()
73 regmap_write(isc->regmap, ISC_WB_G_BGB, in isc_update_awb_ctrls()
74 ctrls->gain[ISC_HIS_CFG_MODE_B] | in isc_update_awb_ctrls()
75 (ctrls->gain[ISC_HIS_CFG_MODE_GB] << 16)); in isc_update_awb_ctrls()
84 isc->ctrls.gain[c] = 1 << 9; in isc_reset_awb_ctrls()
86 isc->ctrls.offset[c] = 0; in isc_reset_awb_ctrls()
95 unsigned int size = isc->fmt.fmt.pix.sizeimage; in isc_queue_setup()
98 return sizes[0] < size ? -EINVAL : 0; in isc_queue_setup()
109 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue); in isc_buffer_prepare()
110 unsigned long size = isc->fmt.fmt.pix.sizeimage; in isc_buffer_prepare()
113 dev_err(isc->dev, "buffer too small (%lu < %lu)\n", in isc_buffer_prepare()
115 return -EINVAL; in isc_buffer_prepare()
120 vbuf->field = isc->fmt.fmt.pix.field; in isc_buffer_prepare()
127 struct regmap *regmap = isc->regmap; in isc_crop_pfe()
130 h = isc->fmt.fmt.pix.height; in isc_crop_pfe()
131 w = isc->fmt.fmt.pix.width; in isc_crop_pfe()
134 * In case the sensor is not RAW, it will output a pixel (12-16 bits) in isc_crop_pfe()
135 * with two samples on the ISC Data bus (which is 8-12) in isc_crop_pfe()
136 * ISC will count each sample, so, we need to multiply these values in isc_crop_pfe()
139 if (!ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) { in isc_crop_pfe()
153 (ISC_PFE_CFG1_COLMAX(w - 1) & ISC_PFE_CFG1_COLMAX_MASK)); in isc_crop_pfe()
157 (ISC_PFE_CFG2_ROWMAX(h - 1) & ISC_PFE_CFG2_ROWMAX_MASK)); in isc_crop_pfe()
166 struct regmap *regmap = isc->regmap; in isc_start_dma()
167 u32 sizeimage = isc->fmt.fmt.pix.sizeimage; in isc_start_dma()
171 addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0); in isc_start_dma()
172 regmap_write(regmap, ISC_DAD0 + isc->offsets.dma, addr0); in isc_start_dma()
174 switch (isc->config.fourcc) { in isc_start_dma()
176 regmap_write(regmap, ISC_DAD1 + isc->offsets.dma, in isc_start_dma()
178 regmap_write(regmap, ISC_DAD2 + isc->offsets.dma, in isc_start_dma()
182 regmap_write(regmap, ISC_DAD1 + isc->offsets.dma, in isc_start_dma()
184 regmap_write(regmap, ISC_DAD2 + isc->offsets.dma, in isc_start_dma()
191 dctrl_dview = isc->config.dctrl_dview; in isc_start_dma()
193 regmap_write(regmap, ISC_DCTRL + isc->offsets.dma, in isc_start_dma()
195 spin_lock(&isc->awb_lock); in isc_start_dma()
197 spin_unlock(&isc->awb_lock); in isc_start_dma()
202 struct regmap *regmap = isc->regmap; in isc_set_pipeline()
203 struct isc_ctrls *ctrls = &isc->ctrls; in isc_set_pipeline()
208 /* WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB422-->SUB420 */ in isc_set_pipeline()
211 regmap_field_write(isc->pipeline[i], val); in isc_set_pipeline()
217 bay_cfg = isc->config.sd_format->cfa_baycfg; in isc_set_pipeline()
225 gamma = &isc->gamma_table[ctrls->gamma_index][0]; in isc_set_pipeline()
230 isc->config_dpc(isc); in isc_set_pipeline()
231 isc->config_csc(isc); in isc_set_pipeline()
232 isc->config_cbc(isc); in isc_set_pipeline()
233 isc->config_cc(isc); in isc_set_pipeline()
234 isc->config_gam(isc); in isc_set_pipeline()
239 struct regmap *regmap = isc->regmap; in isc_update_profile()
246 while ((sr & ISC_CTRL_UPPRO) && counter--) { in isc_update_profile()
252 v4l2_warn(&isc->v4l2_dev, "Time out to update profile\n"); in isc_update_profile()
253 return -ETIMEDOUT; in isc_update_profile()
261 struct regmap *regmap = isc->regmap; in isc_set_histogram()
262 struct isc_ctrls *ctrls = &isc->ctrls; in isc_set_histogram()
265 regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his, in isc_set_histogram()
267 (isc->config.sd_format->cfa_baycfg in isc_set_histogram()
270 regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his, in isc_set_histogram()
273 ctrls->hist_id = ISC_HIS_CFG_MODE_GR; in isc_set_histogram()
277 ctrls->hist_stat = HIST_ENABLED; in isc_set_histogram()
280 regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his, in isc_set_histogram()
283 ctrls->hist_stat = HIST_DISABLED; in isc_set_histogram()
289 struct regmap *regmap = isc->regmap; in isc_configure()
291 struct isc_subdev_entity *subdev = isc->current_subdev; in isc_configure()
293 pfe_cfg0 = isc->config.sd_format->pfe_cfg0_bps; in isc_configure()
294 pipeline = isc->config.bits_pipeline; in isc_configure()
296 dcfg = isc->config.dcfg_imode | isc->dcfg; in isc_configure()
298 pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE; in isc_configure()
306 isc->config_rlp(isc); in isc_configure()
308 regmap_write(regmap, ISC_DCFG + isc->offsets.dma, dcfg); in isc_configure()
317 if (isc->ctrls.awb && in isc_configure()
318 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) in isc_configure()
331 return media_pipeline_start(isc->video_dev.entity.pads, &isc->mpipe); in isc_prepare_streaming()
337 struct regmap *regmap = isc->regmap; in isc_start_streaming()
343 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1); in isc_start_streaming()
344 if (ret && ret != -ENOIOCTLCMD) { in isc_start_streaming()
345 dev_err(isc->dev, "stream on failed in subdev %d\n", ret); in isc_start_streaming()
349 ret = pm_runtime_resume_and_get(isc->dev); in isc_start_streaming()
351 dev_err(isc->dev, "RPM resume failed in subdev %d\n", in isc_start_streaming()
363 spin_lock_irqsave(&isc->dma_queue_lock, flags); in isc_start_streaming()
365 isc->sequence = 0; in isc_start_streaming()
366 isc->stop = false; in isc_start_streaming()
367 reinit_completion(&isc->comp); in isc_start_streaming()
369 isc->cur_frm = list_first_entry(&isc->dma_queue, in isc_start_streaming()
371 list_del(&isc->cur_frm->list); in isc_start_streaming()
376 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); in isc_start_streaming()
378 /* if we streaming from RAW, we can do one-shot white balance adj */ in isc_start_streaming()
379 if (ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) in isc_start_streaming()
380 v4l2_ctrl_activate(isc->do_wb_ctrl, true); in isc_start_streaming()
385 pm_runtime_put_sync(isc->dev); in isc_start_streaming()
387 v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0); in isc_start_streaming()
390 spin_lock_irqsave(&isc->dma_queue_lock, flags); in isc_start_streaming()
391 list_for_each_entry(buf, &isc->dma_queue, list) in isc_start_streaming()
392 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); in isc_start_streaming()
393 INIT_LIST_HEAD(&isc->dma_queue); in isc_start_streaming()
394 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); in isc_start_streaming()
404 media_pipeline_stop(isc->video_dev.entity.pads); in isc_unprepare_streaming()
414 mutex_lock(&isc->awb_mutex); in isc_stop_streaming()
415 v4l2_ctrl_activate(isc->do_wb_ctrl, false); in isc_stop_streaming()
417 isc->stop = true; in isc_stop_streaming()
420 if (isc->cur_frm && !wait_for_completion_timeout(&isc->comp, 5 * HZ)) in isc_stop_streaming()
421 dev_err(isc->dev, "Timeout waiting for end of the capture\n"); in isc_stop_streaming()
423 mutex_unlock(&isc->awb_mutex); in isc_stop_streaming()
426 regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE); in isc_stop_streaming()
428 pm_runtime_put_sync(isc->dev); in isc_stop_streaming()
431 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0); in isc_stop_streaming()
432 if (ret && ret != -ENOIOCTLCMD) in isc_stop_streaming()
433 dev_err(isc->dev, "stream off failed in subdev\n"); in isc_stop_streaming()
436 spin_lock_irqsave(&isc->dma_queue_lock, flags); in isc_stop_streaming()
437 if (unlikely(isc->cur_frm)) { in isc_stop_streaming()
438 vb2_buffer_done(&isc->cur_frm->vb.vb2_buf, in isc_stop_streaming()
440 isc->cur_frm = NULL; in isc_stop_streaming()
442 list_for_each_entry(buf, &isc->dma_queue, list) in isc_stop_streaming()
443 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in isc_stop_streaming()
444 INIT_LIST_HEAD(&isc->dma_queue); in isc_stop_streaming()
445 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); in isc_stop_streaming()
452 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue); in isc_buffer_queue()
455 spin_lock_irqsave(&isc->dma_queue_lock, flags); in isc_buffer_queue()
456 if (!isc->cur_frm && list_empty(&isc->dma_queue) && in isc_buffer_queue()
457 vb2_start_streaming_called(vb->vb2_queue)) { in isc_buffer_queue()
458 isc->cur_frm = buf; in isc_buffer_queue()
461 list_add_tail(&buf->list, &isc->dma_queue); in isc_buffer_queue()
463 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); in isc_buffer_queue()
479 strscpy(cap->driver, "microchip-isc", sizeof(cap->driver)); in isc_querycap()
480 strscpy(cap->card, "Microchip Image Sensor Controller", sizeof(cap->card)); in isc_querycap()
489 u32 index = f->index; in isc_enum_fmt_vid_cap()
497 if (!f->mbus_code) { in isc_enum_fmt_vid_cap()
498 if (index >= isc->controller_formats_size) in isc_enum_fmt_vid_cap()
499 return -EINVAL; in isc_enum_fmt_vid_cap()
501 f->pixelformat = isc->controller_formats[index].fourcc; in isc_enum_fmt_vid_cap()
514 fmt = isc_find_format_by_code(isc, f->mbus_code, &i); in isc_enum_fmt_vid_cap()
516 return -EINVAL; in isc_enum_fmt_vid_cap()
519 f->pixelformat = fmt->fourcc; in isc_enum_fmt_vid_cap()
527 if (!ISC_IS_FORMAT_RAW(f->mbus_code)) in isc_enum_fmt_vid_cap()
528 return -EINVAL; in isc_enum_fmt_vid_cap()
532 * We have to search through the formats we can convert to. in isc_enum_fmt_vid_cap()
533 * We have to skip the raw formats, we cannot convert to raw. in isc_enum_fmt_vid_cap()
534 * E.g. 'AR12' (16-bit ARGB 4-4-4-4), 'AR15' (16-bit ARGB 1-5-5-5), etc. in isc_enum_fmt_vid_cap()
536 for (i = 0; i < isc->controller_formats_size; i++) { in isc_enum_fmt_vid_cap()
537 if (isc->controller_formats[i].raw) in isc_enum_fmt_vid_cap()
540 f->pixelformat = isc->controller_formats[i].fourcc; in isc_enum_fmt_vid_cap()
546 return -EINVAL; in isc_enum_fmt_vid_cap()
554 *fmt = isc->fmt; in isc_g_fmt_vid_cap()
560 * Checks the current configured format, if ISC can output it,
561 * considering which type of format the ISC receives from the sensor
569 switch (isc->try_config.fourcc) { in isc_try_validate_formats()
611 dev_err(isc->dev, "Requested unsupported format.\n"); in isc_try_validate_formats()
612 ret = -EINVAL; in isc_try_validate_formats()
614 dev_dbg(isc->dev, in isc_try_validate_formats()
615 "Format validation, requested rgb=%u, yuv=%u, grey=%u, bayer=%u\n", in isc_try_validate_formats()
619 !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_validate_formats()
620 dev_err(isc->dev, "Cannot output RAW if we do not receive RAW.\n"); in isc_try_validate_formats()
621 return -EINVAL; in isc_try_validate_formats()
624 if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) && in isc_try_validate_formats()
625 !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) { in isc_try_validate_formats()
626 dev_err(isc->dev, "Cannot output GREY if we do not receive RAW/GREY.\n"); in isc_try_validate_formats()
627 return -EINVAL; in isc_try_validate_formats()
631 ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) { in isc_try_validate_formats()
632 dev_err(isc->dev, "Cannot convert GREY to another format.\n"); in isc_try_validate_formats()
633 return -EINVAL; in isc_try_validate_formats()
640 * Configures the RLP and DMA modules, depending on the output format
642 * If direct_dump == true, just dump raw data 8/16 bits depending on format.
646 isc->try_config.rlp_cfg_mode = 0; in isc_try_configure_rlp_dma()
648 switch (isc->try_config.fourcc) { in isc_try_configure_rlp_dma()
653 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8; in isc_try_configure_rlp_dma()
654 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; in isc_try_configure_rlp_dma()
655 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
656 isc->try_config.bpp = 8; in isc_try_configure_rlp_dma()
657 isc->try_config.bpp_v4l2 = 8; in isc_try_configure_rlp_dma()
663 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10; in isc_try_configure_rlp_dma()
664 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
665 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
666 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
667 isc->try_config.bpp_v4l2 = 16; in isc_try_configure_rlp_dma()
673 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12; in isc_try_configure_rlp_dma()
674 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
675 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
676 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
677 isc->try_config.bpp_v4l2 = 16; in isc_try_configure_rlp_dma()
680 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565; in isc_try_configure_rlp_dma()
681 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
682 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
683 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
684 isc->try_config.bpp_v4l2 = 16; in isc_try_configure_rlp_dma()
687 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444; in isc_try_configure_rlp_dma()
688 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
689 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
690 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
691 isc->try_config.bpp_v4l2 = 16; in isc_try_configure_rlp_dma()
694 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555; in isc_try_configure_rlp_dma()
695 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
696 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
697 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
698 isc->try_config.bpp_v4l2 = 16; in isc_try_configure_rlp_dma()
702 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB32; in isc_try_configure_rlp_dma()
703 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; in isc_try_configure_rlp_dma()
704 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
705 isc->try_config.bpp = 32; in isc_try_configure_rlp_dma()
706 isc->try_config.bpp_v4l2 = 32; in isc_try_configure_rlp_dma()
709 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; in isc_try_configure_rlp_dma()
710 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC420P; in isc_try_configure_rlp_dma()
711 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR; in isc_try_configure_rlp_dma()
712 isc->try_config.bpp = 12; in isc_try_configure_rlp_dma()
713 isc->try_config.bpp_v4l2 = 8; /* only first plane */ in isc_try_configure_rlp_dma()
716 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; in isc_try_configure_rlp_dma()
717 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC422P; in isc_try_configure_rlp_dma()
718 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR; in isc_try_configure_rlp_dma()
719 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
720 isc->try_config.bpp_v4l2 = 8; /* only first plane */ in isc_try_configure_rlp_dma()
723 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_YUYV; in isc_try_configure_rlp_dma()
724 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; in isc_try_configure_rlp_dma()
725 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
726 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
727 isc->try_config.bpp_v4l2 = 16; in isc_try_configure_rlp_dma()
730 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_UYVY; in isc_try_configure_rlp_dma()
731 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; in isc_try_configure_rlp_dma()
732 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
733 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
734 isc->try_config.bpp_v4l2 = 16; in isc_try_configure_rlp_dma()
737 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_VYUY; in isc_try_configure_rlp_dma()
738 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; in isc_try_configure_rlp_dma()
739 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
740 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
741 isc->try_config.bpp_v4l2 = 16; in isc_try_configure_rlp_dma()
744 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8; in isc_try_configure_rlp_dma()
745 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; in isc_try_configure_rlp_dma()
746 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
747 isc->try_config.bpp = 8; in isc_try_configure_rlp_dma()
748 isc->try_config.bpp_v4l2 = 8; in isc_try_configure_rlp_dma()
751 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10 | ISC_RLP_CFG_LSH; in isc_try_configure_rlp_dma()
754 isc->try_config.rlp_cfg_mode |= ISC_RLP_CFG_MODE_DATY10; in isc_try_configure_rlp_dma()
755 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
756 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
757 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
758 isc->try_config.bpp_v4l2 = 16; in isc_try_configure_rlp_dma()
761 return -EINVAL; in isc_try_configure_rlp_dma()
765 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8; in isc_try_configure_rlp_dma()
766 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; in isc_try_configure_rlp_dma()
767 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
775 * Configuring pipeline modules, depending on which format the ISC outputs
776 * and considering which format it has as input from the sensor.
780 switch (isc->try_config.fourcc) { in isc_try_configure_pipeline()
786 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
787 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
788 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
792 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
796 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
797 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
798 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
803 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
807 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
808 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
809 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
813 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
819 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
820 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
821 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
825 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
830 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
831 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
832 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
836 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
840 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) in isc_try_configure_pipeline()
841 isc->try_config.bits_pipeline = WB_ENABLE | DPC_BLCENABLE; in isc_try_configure_pipeline()
843 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
847 isc->adapt_pipeline(isc); in isc_try_configure_pipeline()
854 struct v4l2_pix_format *pixfmt = &f->fmt.pix; in isc_try_fmt()
857 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) in isc_try_fmt()
858 return -EINVAL; in isc_try_fmt()
860 isc->try_config.fourcc = isc->controller_formats[0].fourcc; in isc_try_fmt()
862 /* find if the format requested is supported */ in isc_try_fmt()
863 for (i = 0; i < isc->controller_formats_size; i++) in isc_try_fmt()
864 if (isc->controller_formats[i].fourcc == pixfmt->pixelformat) { in isc_try_fmt()
865 isc->try_config.fourcc = pixfmt->pixelformat; in isc_try_fmt()
872 v4l_bound_align_image(&pixfmt->width, 16, isc->max_width, 0, in isc_try_fmt()
873 &pixfmt->height, 16, isc->max_height, 0, 0); in isc_try_fmt()
874 /* If we did not find the requested format, we will fallback here */ in isc_try_fmt()
875 pixfmt->pixelformat = isc->try_config.fourcc; in isc_try_fmt()
876 pixfmt->colorspace = V4L2_COLORSPACE_SRGB; in isc_try_fmt()
877 pixfmt->field = V4L2_FIELD_NONE; in isc_try_fmt()
879 pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp_v4l2) >> 3; in isc_try_fmt()
880 pixfmt->sizeimage = ((pixfmt->width * isc->try_config.bpp) >> 3) * in isc_try_fmt()
881 pixfmt->height; in isc_try_fmt()
883 isc->try_fmt = *f; in isc_try_fmt()
893 isc->config = isc->try_config; in isc_set_fmt()
894 isc->fmt = isc->try_fmt; in isc_set_fmt()
896 dev_dbg(isc->dev, "ISC set_fmt to %.4s @%dx%d\n", in isc_set_fmt()
897 (char *)&f->fmt.pix.pixelformat, in isc_set_fmt()
898 f->fmt.pix.width, f->fmt.pix.height); in isc_set_fmt()
906 media_entity_to_video_device(link->sink->entity); in isc_link_validate()
911 struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix; in isc_link_validate()
912 struct v4l2_subdev_format format = { in isc_link_validate() local
914 .pad = isc->remote_pad, in isc_link_validate()
917 /* Get current format from subdev */ in isc_link_validate()
918 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, get_fmt, NULL, in isc_link_validate()
919 &format); in isc_link_validate()
923 /* Identify the subdev's format configuration */ in isc_link_validate()
924 for (i = 0; i < isc->formats_list_size; i++) in isc_link_validate()
925 if (isc->formats_list[i].mbus_code == format.format.code) { in isc_link_validate()
926 sd_fmt = &isc->formats_list[i]; in isc_link_validate()
930 /* Check if the format is not supported */ in isc_link_validate()
932 dev_err(isc->dev, in isc_link_validate()
934 format.format.code); in isc_link_validate()
935 return -EPIPE; in isc_link_validate()
938 /* At this moment we know which format the subdev will use */ in isc_link_validate()
939 isc->try_config.sd_format = sd_fmt; in isc_link_validate()
942 if (!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) in isc_link_validate()
946 v4l_bound_align_image(&format.format.width, 16, isc->max_width, 0, in isc_link_validate()
947 &format.format.height, 16, isc->max_height, 0, 0); in isc_link_validate()
950 if (pixfmt->height != format.format.height || in isc_link_validate()
951 pixfmt->width != format.format.width) { in isc_link_validate()
952 dev_err(isc->dev, in isc_link_validate()
954 format.format.width, format.format.height); in isc_link_validate()
955 return -EPIPE; in isc_link_validate()
958 dev_dbg(isc->dev, in isc_link_validate()
959 "Identified subdev using format %.4s with %dx%d %d bpp\n", in isc_link_validate()
960 (char *)&sd_fmt->fourcc, pixfmt->width, pixfmt->height, in isc_link_validate()
961 isc->try_config.bpp); in isc_link_validate()
963 /* Reset and restart AWB if the subdevice changed the format */ in isc_link_validate()
964 if (isc->try_config.sd_format && isc->config.sd_format && in isc_link_validate()
965 isc->try_config.sd_format != isc->config.sd_format) { in isc_link_validate()
966 isc->ctrls.hist_stat = HIST_INIT; in isc_link_validate()
981 isc->config = isc->try_config; in isc_link_validate()
983 dev_dbg(isc->dev, "New ISC configuration in place\n"); in isc_link_validate()
993 if (vb2_is_busy(&isc->vb2_vidq)) in isc_s_fmt_vid_cap()
994 return -EBUSY; in isc_s_fmt_vid_cap()
1010 if (inp->index != 0) in isc_enum_input()
1011 return -EINVAL; in isc_enum_input()
1013 inp->type = V4L2_INPUT_TYPE_CAMERA; in isc_enum_input()
1014 inp->std = 0; in isc_enum_input()
1015 strscpy(inp->name, "Camera", sizeof(inp->name)); in isc_enum_input()
1030 return -EINVAL; in isc_s_input()
1039 return v4l2_g_parm_cap(video_devdata(file), isc->current_subdev->sd, a); in isc_g_parm()
1046 return v4l2_s_parm_cap(video_devdata(file), isc->current_subdev->sd, a); in isc_s_parm()
1053 int ret = -EINVAL; in isc_enum_framesizes()
1056 if (fsize->index) in isc_enum_framesizes()
1057 return -EINVAL; in isc_enum_framesizes()
1059 for (i = 0; i < isc->controller_formats_size; i++) in isc_enum_framesizes()
1060 if (isc->controller_formats[i].fourcc == fsize->pixel_format) in isc_enum_framesizes()
1066 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS; in isc_enum_framesizes()
1068 fsize->stepwise.min_width = 16; in isc_enum_framesizes()
1069 fsize->stepwise.max_width = isc->max_width; in isc_enum_framesizes()
1070 fsize->stepwise.min_height = 16; in isc_enum_framesizes()
1071 fsize->stepwise.max_height = isc->max_height; in isc_enum_framesizes()
1072 fsize->stepwise.step_width = 1; in isc_enum_framesizes()
1073 fsize->stepwise.step_height = 1; in isc_enum_framesizes()
1111 struct v4l2_subdev *sd = isc->current_subdev->sd; in isc_open()
1114 if (mutex_lock_interruptible(&isc->lock)) in isc_open()
1115 return -ERESTARTSYS; in isc_open()
1125 if (ret < 0 && ret != -ENOIOCTLCMD) { in isc_open()
1130 ret = isc_set_fmt(isc, &isc->fmt); in isc_open()
1137 mutex_unlock(&isc->lock); in isc_open()
1144 struct v4l2_subdev *sd = isc->current_subdev->sd; in isc_release()
1148 mutex_lock(&isc->lock); in isc_release()
1157 mutex_unlock(&isc->lock); in isc_release()
1175 struct regmap *regmap = isc->regmap; in microchip_isc_interrupt()
1185 spin_lock(&isc->dma_queue_lock); in microchip_isc_interrupt()
1186 if (isc->cur_frm) { in microchip_isc_interrupt()
1187 struct vb2_v4l2_buffer *vbuf = &isc->cur_frm->vb; in microchip_isc_interrupt()
1188 struct vb2_buffer *vb = &vbuf->vb2_buf; in microchip_isc_interrupt()
1190 vb->timestamp = ktime_get_ns(); in microchip_isc_interrupt()
1191 vbuf->sequence = isc->sequence++; in microchip_isc_interrupt()
1193 isc->cur_frm = NULL; in microchip_isc_interrupt()
1196 if (!list_empty(&isc->dma_queue) && !isc->stop) { in microchip_isc_interrupt()
1197 isc->cur_frm = list_first_entry(&isc->dma_queue, in microchip_isc_interrupt()
1199 list_del(&isc->cur_frm->list); in microchip_isc_interrupt()
1204 if (isc->stop) in microchip_isc_interrupt()
1205 complete(&isc->comp); in microchip_isc_interrupt()
1208 spin_unlock(&isc->dma_queue_lock); in microchip_isc_interrupt()
1212 schedule_work(&isc->awb_work); in microchip_isc_interrupt()
1222 struct regmap *regmap = isc->regmap; in isc_hist_count()
1223 struct isc_ctrls *ctrls = &isc->ctrls; in isc_hist_count()
1224 u32 *hist_count = &ctrls->hist_count[ctrls->hist_id]; in isc_hist_count()
1225 u32 *hist_entry = &ctrls->hist_entry[0]; in isc_hist_count()
1231 regmap_bulk_read(regmap, ISC_HIS_ENTRY + isc->offsets.his_entry, in isc_hist_count()
1250 dev_dbg(isc->dev, "isc wb: hist_id %u, hist_count %u", in isc_hist_count()
1251 ctrls->hist_id, *hist_count); in isc_hist_count()
1257 u32 *hist_count = &ctrls->hist_count[0]; in isc_wb_update()
1273 dev_dbg(isc->dev, "isc wb: green components average %llu\n", avg); in isc_wb_update()
1285 offset[c] = ctrls->hist_minmax[c][HIST_MIN_INDEX]; in isc_wb_update()
1295 ctrls->offset[c] = (offset[c] - 1) << 3; in isc_wb_update()
1302 ctrls->offset[c] = -ctrls->offset[c]; in isc_wb_update()
1306 * divided by the actual range of color component (Max - Min) in isc_wb_update()
1313 (ctrls->hist_minmax[c][HIST_MAX_INDEX] - in isc_wb_update()
1314 ctrls->hist_minmax[c][HIST_MIN_INDEX] + 1); in isc_wb_update()
1327 dev_dbg(isc->dev, in isc_wb_update()
1331 ctrls->gain[c] = s_gain[c] * gw_gain[c]; in isc_wb_update()
1332 ctrls->gain[c] >>= 9; in isc_wb_update()
1335 ctrls->gain[c] = clamp_val(ctrls->gain[c], 0, GENMASK(12, 0)); in isc_wb_update()
1337 dev_dbg(isc->dev, "isc wb: component %d, final gain %u\n", in isc_wb_update()
1338 c, ctrls->gain[c]); in isc_wb_update()
1346 struct regmap *regmap = isc->regmap; in isc_awb_work()
1347 struct isc_ctrls *ctrls = &isc->ctrls; in isc_awb_work()
1348 u32 hist_id = ctrls->hist_id; in isc_awb_work()
1354 if (ctrls->hist_stat != HIST_ENABLED) in isc_awb_work()
1359 dev_dbg(isc->dev, in isc_awb_work()
1362 ctrls->hist_minmax[hist_id][HIST_MIN_INDEX] = min; in isc_awb_work()
1363 ctrls->hist_minmax[hist_id][HIST_MAX_INDEX] = max; in isc_awb_work()
1372 ctrls->hist_id = hist_id; in isc_awb_work()
1373 baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT; in isc_awb_work()
1375 ret = pm_runtime_resume_and_get(isc->dev); in isc_awb_work()
1383 if (hist_id == ISC_HIS_CFG_MODE_GR || ctrls->awb == ISC_WB_NONE) { in isc_awb_work()
1390 spin_lock_irqsave(&isc->awb_lock, flags); in isc_awb_work()
1392 spin_unlock_irqrestore(&isc->awb_lock, flags); in isc_awb_work()
1398 if (ctrls->awb == ISC_WB_ONETIME) { in isc_awb_work()
1399 dev_info(isc->dev, in isc_awb_work()
1400 "Completed one time white-balance adjustment.\n"); in isc_awb_work()
1403 ctrls->awb = ISC_WB_NONE; in isc_awb_work()
1406 regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his, in isc_awb_work()
1414 mutex_lock(&isc->awb_mutex); in isc_awb_work()
1417 if (isc->stop) { in isc_awb_work()
1418 mutex_unlock(&isc->awb_mutex); in isc_awb_work()
1424 mutex_unlock(&isc->awb_mutex); in isc_awb_work()
1427 if (ctrls->awb) in isc_awb_work()
1430 pm_runtime_put_sync(isc->dev); in isc_awb_work()
1435 struct isc_device *isc = container_of(ctrl->handler, in isc_s_ctrl()
1437 struct isc_ctrls *ctrls = &isc->ctrls; in isc_s_ctrl()
1439 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) in isc_s_ctrl()
1442 switch (ctrl->id) { in isc_s_ctrl()
1444 ctrls->brightness = ctrl->val & ISC_CBC_BRIGHT_MASK; in isc_s_ctrl()
1447 ctrls->contrast = ctrl->val & ISC_CBC_CONTRAST_MASK; in isc_s_ctrl()
1450 ctrls->gamma_index = ctrl->val; in isc_s_ctrl()
1453 return -EINVAL; in isc_s_ctrl()
1465 struct isc_device *isc = container_of(ctrl->handler, in isc_s_awb_ctrl()
1467 struct isc_ctrls *ctrls = &isc->ctrls; in isc_s_awb_ctrl()
1469 if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) in isc_s_awb_ctrl()
1472 switch (ctrl->id) { in isc_s_awb_ctrl()
1474 if (ctrl->val == 1) in isc_s_awb_ctrl()
1475 ctrls->awb = ISC_WB_AUTO; in isc_s_awb_ctrl()
1477 ctrls->awb = ISC_WB_NONE; in isc_s_awb_ctrl()
1480 if (ctrl->cluster[ISC_CTRL_R_GAIN]->is_new) in isc_s_awb_ctrl()
1481 ctrls->gain[ISC_HIS_CFG_MODE_R] = isc->r_gain_ctrl->val; in isc_s_awb_ctrl()
1482 if (ctrl->cluster[ISC_CTRL_B_GAIN]->is_new) in isc_s_awb_ctrl()
1483 ctrls->gain[ISC_HIS_CFG_MODE_B] = isc->b_gain_ctrl->val; in isc_s_awb_ctrl()
1484 if (ctrl->cluster[ISC_CTRL_GR_GAIN]->is_new) in isc_s_awb_ctrl()
1485 ctrls->gain[ISC_HIS_CFG_MODE_GR] = isc->gr_gain_ctrl->val; in isc_s_awb_ctrl()
1486 if (ctrl->cluster[ISC_CTRL_GB_GAIN]->is_new) in isc_s_awb_ctrl()
1487 ctrls->gain[ISC_HIS_CFG_MODE_GB] = isc->gb_gain_ctrl->val; in isc_s_awb_ctrl()
1489 if (ctrl->cluster[ISC_CTRL_R_OFF]->is_new) in isc_s_awb_ctrl()
1490 ctrls->offset[ISC_HIS_CFG_MODE_R] = isc->r_off_ctrl->val; in isc_s_awb_ctrl()
1491 if (ctrl->cluster[ISC_CTRL_B_OFF]->is_new) in isc_s_awb_ctrl()
1492 ctrls->offset[ISC_HIS_CFG_MODE_B] = isc->b_off_ctrl->val; in isc_s_awb_ctrl()
1493 if (ctrl->cluster[ISC_CTRL_GR_OFF]->is_new) in isc_s_awb_ctrl()
1494 ctrls->offset[ISC_HIS_CFG_MODE_GR] = isc->gr_off_ctrl->val; in isc_s_awb_ctrl()
1495 if (ctrl->cluster[ISC_CTRL_GB_OFF]->is_new) in isc_s_awb_ctrl()
1496 ctrls->offset[ISC_HIS_CFG_MODE_GB] = isc->gb_off_ctrl->val; in isc_s_awb_ctrl()
1500 mutex_lock(&isc->awb_mutex); in isc_s_awb_ctrl()
1501 if (vb2_is_streaming(&isc->vb2_vidq)) { in isc_s_awb_ctrl()
1513 v4l2_ctrl_activate(isc->do_wb_ctrl, false); in isc_s_awb_ctrl()
1515 mutex_unlock(&isc->awb_mutex); in isc_s_awb_ctrl()
1518 if (ctrls->awb == ISC_WB_AUTO && in isc_s_awb_ctrl()
1519 vb2_is_streaming(&isc->vb2_vidq) && in isc_s_awb_ctrl()
1520 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) in isc_s_awb_ctrl()
1527 if (ctrls->awb == ISC_WB_NONE && in isc_s_awb_ctrl()
1528 ctrl->cluster[ISC_CTRL_DO_WB]->is_new && in isc_s_awb_ctrl()
1529 !(ctrl->cluster[ISC_CTRL_DO_WB]->flags & in isc_s_awb_ctrl()
1531 ctrls->awb = ISC_WB_ONETIME; in isc_s_awb_ctrl()
1533 dev_dbg(isc->dev, "One time white-balance started.\n"); in isc_s_awb_ctrl()
1542 struct isc_device *isc = container_of(ctrl->handler, in isc_g_volatile_awb_ctrl()
1544 struct isc_ctrls *ctrls = &isc->ctrls; in isc_g_volatile_awb_ctrl()
1546 switch (ctrl->id) { in isc_g_volatile_awb_ctrl()
1549 ctrl->cluster[ISC_CTRL_R_GAIN]->val = in isc_g_volatile_awb_ctrl()
1550 ctrls->gain[ISC_HIS_CFG_MODE_R]; in isc_g_volatile_awb_ctrl()
1551 ctrl->cluster[ISC_CTRL_B_GAIN]->val = in isc_g_volatile_awb_ctrl()
1552 ctrls->gain[ISC_HIS_CFG_MODE_B]; in isc_g_volatile_awb_ctrl()
1553 ctrl->cluster[ISC_CTRL_GR_GAIN]->val = in isc_g_volatile_awb_ctrl()
1554 ctrls->gain[ISC_HIS_CFG_MODE_GR]; in isc_g_volatile_awb_ctrl()
1555 ctrl->cluster[ISC_CTRL_GB_GAIN]->val = in isc_g_volatile_awb_ctrl()
1556 ctrls->gain[ISC_HIS_CFG_MODE_GB]; in isc_g_volatile_awb_ctrl()
1558 ctrl->cluster[ISC_CTRL_R_OFF]->val = in isc_g_volatile_awb_ctrl()
1559 ctrls->offset[ISC_HIS_CFG_MODE_R]; in isc_g_volatile_awb_ctrl()
1560 ctrl->cluster[ISC_CTRL_B_OFF]->val = in isc_g_volatile_awb_ctrl()
1561 ctrls->offset[ISC_HIS_CFG_MODE_B]; in isc_g_volatile_awb_ctrl()
1562 ctrl->cluster[ISC_CTRL_GR_OFF]->val = in isc_g_volatile_awb_ctrl()
1563 ctrls->offset[ISC_HIS_CFG_MODE_GR]; in isc_g_volatile_awb_ctrl()
1564 ctrl->cluster[ISC_CTRL_GB_OFF]->val = in isc_g_volatile_awb_ctrl()
1565 ctrls->offset[ISC_HIS_CFG_MODE_GB]; in isc_g_volatile_awb_ctrl()
1583 .min = -4095, \
1615 struct isc_ctrls *ctrls = &isc->ctrls; in isc_ctrl_init()
1616 struct v4l2_ctrl_handler *hdl = &ctrls->handler; in isc_ctrl_init()
1619 ctrls->hist_stat = HIST_INIT; in isc_ctrl_init()
1627 isc->config_ctrls(isc, ops); in isc_ctrl_init()
1629 ctrls->brightness = 0; in isc_ctrl_init()
1631 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0); in isc_ctrl_init()
1632 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, isc->gamma_max, 1, in isc_ctrl_init()
1633 isc->gamma_max); in isc_ctrl_init()
1634 isc->awb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops, in isc_ctrl_init()
1639 isc->do_wb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops, in isc_ctrl_init()
1643 if (!isc->do_wb_ctrl) { in isc_ctrl_init()
1644 ret = hdl->error; in isc_ctrl_init()
1649 v4l2_ctrl_activate(isc->do_wb_ctrl, false); in isc_ctrl_init()
1651 isc->r_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_gain_ctrl, NULL); in isc_ctrl_init()
1652 isc->b_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_gain_ctrl, NULL); in isc_ctrl_init()
1653 isc->gr_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_gain_ctrl, NULL); in isc_ctrl_init()
1654 isc->gb_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_gain_ctrl, NULL); in isc_ctrl_init()
1655 isc->r_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_off_ctrl, NULL); in isc_ctrl_init()
1656 isc->b_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_off_ctrl, NULL); in isc_ctrl_init()
1657 isc->gr_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_off_ctrl, NULL); in isc_ctrl_init()
1658 isc->gb_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_off_ctrl, NULL); in isc_ctrl_init()
1664 v4l2_ctrl_auto_cluster(10, &isc->awb_ctrl, 0, true); in isc_ctrl_init()
1675 struct isc_device *isc = container_of(notifier->v4l2_dev, in isc_async_bound()
1681 if (video_is_registered(&isc->video_dev)) { in isc_async_bound()
1682 dev_err(isc->dev, "only supports one sub-device.\n"); in isc_async_bound()
1683 return -EBUSY; in isc_async_bound()
1686 subdev_entity->sd = subdev; in isc_async_bound()
1688 pad = media_entity_get_fwnode_pad(&subdev->entity, asd->match.fwnode, in isc_async_bound()
1691 dev_err(isc->dev, "failed to find pad for %s\n", subdev->name); in isc_async_bound()
1695 isc->remote_pad = pad; in isc_async_bound()
1704 struct isc_device *isc = container_of(notifier->v4l2_dev, in isc_async_unbind()
1706 mutex_destroy(&isc->awb_mutex); in isc_async_unbind()
1707 cancel_work_sync(&isc->awb_work); in isc_async_unbind()
1708 video_unregister_device(&isc->video_dev); in isc_async_unbind()
1709 v4l2_ctrl_handler_free(&isc->ctrls.handler); in isc_async_unbind()
1715 struct isc_format *fmt = &isc->formats_list[0]; in isc_find_format_by_code()
1718 for (i = 0; i < isc->formats_list_size; i++) { in isc_find_format_by_code()
1719 if (fmt->mbus_code == code) { in isc_find_format_by_code()
1739 .pixelformat = isc->controller_formats[0].fourcc, in isc_set_default_fmt()
1748 isc->fmt = f; in isc_set_default_fmt()
1754 struct isc_device *isc = container_of(notifier->v4l2_dev, in isc_async_complete()
1756 struct video_device *vdev = &isc->video_dev; in isc_async_complete()
1757 struct vb2_queue *q = &isc->vb2_vidq; in isc_async_complete()
1760 INIT_WORK(&isc->awb_work, isc_awb_work); in isc_async_complete()
1762 ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev); in isc_async_complete()
1764 dev_err(isc->dev, "Failed to register subdev nodes\n"); in isc_async_complete()
1768 isc->current_subdev = container_of(notifier, in isc_async_complete()
1770 mutex_init(&isc->lock); in isc_async_complete()
1771 mutex_init(&isc->awb_mutex); in isc_async_complete()
1773 init_completion(&isc->comp); in isc_async_complete()
1776 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in isc_async_complete()
1777 q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; in isc_async_complete()
1778 q->drv_priv = isc; in isc_async_complete()
1779 q->buf_struct_size = sizeof(struct isc_buffer); in isc_async_complete()
1780 q->ops = &isc_vb2_ops; in isc_async_complete()
1781 q->mem_ops = &vb2_dma_contig_memops; in isc_async_complete()
1782 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in isc_async_complete()
1783 q->lock = &isc->lock; in isc_async_complete()
1784 q->min_queued_buffers = 1; in isc_async_complete()
1785 q->dev = isc->dev; in isc_async_complete()
1789 dev_err(isc->dev, "vb2_queue_init() failed: %d\n", ret); in isc_async_complete()
1794 INIT_LIST_HEAD(&isc->dma_queue); in isc_async_complete()
1795 spin_lock_init(&isc->dma_queue_lock); in isc_async_complete()
1796 spin_lock_init(&isc->awb_lock); in isc_async_complete()
1800 dev_err(isc->dev, "Could not set default format\n"); in isc_async_complete()
1806 dev_err(isc->dev, "Init isc ctrols failed: %d\n", ret); in isc_async_complete()
1811 strscpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name)); in isc_async_complete()
1812 vdev->release = video_device_release_empty; in isc_async_complete()
1813 vdev->fops = &isc_fops; in isc_async_complete()
1814 vdev->ioctl_ops = &isc_ioctl_ops; in isc_async_complete()
1815 vdev->v4l2_dev = &isc->v4l2_dev; in isc_async_complete()
1816 vdev->vfl_dir = VFL_DIR_RX; in isc_async_complete()
1817 vdev->queue = q; in isc_async_complete()
1818 vdev->lock = &isc->lock; in isc_async_complete()
1819 vdev->ctrl_handler = &isc->ctrls.handler; in isc_async_complete()
1820 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE | in isc_async_complete()
1824 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in isc_async_complete()
1826 dev_err(isc->dev, "video_register_device failed: %d\n", ret); in isc_async_complete()
1834 ret = media_device_register(&isc->mdev); in isc_async_complete()
1844 mutex_destroy(&isc->awb_mutex); in isc_async_complete()
1845 mutex_destroy(&isc->lock); in isc_async_complete()
1860 list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { in microchip_isc_subdev_cleanup()
1861 v4l2_async_nf_unregister(&subdev_entity->notifier); in microchip_isc_subdev_cleanup()
1862 v4l2_async_nf_cleanup(&subdev_entity->notifier); in microchip_isc_subdev_cleanup()
1865 INIT_LIST_HEAD(&isc->subdev_entities); in microchip_isc_subdev_cleanup()
1871 struct device *dev = isc->dev; in microchip_isc_pipeline_init()
1872 struct regmap *regmap = isc->regmap; in microchip_isc_pipeline_init()
1877 * DPCEN-->GDCEN-->BLCEN-->WB-->CFA-->CC--> in microchip_isc_pipeline_init()
1878 * GAM-->VHXS-->CSC-->CBC-->SUB422-->SUB420 in microchip_isc_pipeline_init()
1892 REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), in microchip_isc_pipeline_init()
1893 REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0), in microchip_isc_pipeline_init()
1894 REG_FIELD(ISC_SUB422_CTRL + isc->offsets.sub422, 0, 0), in microchip_isc_pipeline_init()
1895 REG_FIELD(ISC_SUB420_CTRL + isc->offsets.sub420, 0, 0), in microchip_isc_pipeline_init()
1903 isc->pipeline[i] = regs; in microchip_isc_pipeline_init()
1919 isc->video_dev.entity.function = MEDIA_ENT_F_IO_V4L; in isc_mc_init()
1920 isc->video_dev.entity.flags = MEDIA_ENT_FL_DEFAULT; in isc_mc_init()
1921 isc->video_dev.entity.ops = &isc_entity_operations; in isc_mc_init()
1923 isc->pads[ISC_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in isc_mc_init()
1925 ret = media_entity_pads_init(&isc->video_dev.entity, ISC_PADS_NUM, in isc_mc_init()
1926 isc->pads); in isc_mc_init()
1928 dev_err(isc->dev, "media entity init failed\n"); in isc_mc_init()
1932 isc->mdev.dev = isc->dev; in isc_mc_init()
1934 match = of_match_node(isc->dev->driver->of_match_table, in isc_mc_init()
1935 isc->dev->of_node); in isc_mc_init()
1937 strscpy(isc->mdev.driver_name, KBUILD_MODNAME, in isc_mc_init()
1938 sizeof(isc->mdev.driver_name)); in isc_mc_init()
1939 strscpy(isc->mdev.model, match->compatible, sizeof(isc->mdev.model)); in isc_mc_init()
1940 isc->mdev.hw_revision = ver; in isc_mc_init()
1942 media_device_init(&isc->mdev); in isc_mc_init()
1944 isc->v4l2_dev.mdev = &isc->mdev; in isc_mc_init()
1952 media_entity_cleanup(&isc->video_dev.entity); in isc_mc_cleanup()
1953 media_device_cleanup(&isc->mdev); in isc_mc_cleanup()