Lines Matching refs:isc

21 #include <linux/atmel-isc-media.h>
32 #include "microchip-isc-regs.h"
33 #include "microchip-isc.h"
42 static inline void isc_update_v4l2_ctrls(struct isc_device *isc)
44 struct isc_ctrls *ctrls = &isc->ctrls;
47 v4l2_ctrl_s_ctrl(isc->r_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_R]);
48 v4l2_ctrl_s_ctrl(isc->b_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_B]);
49 v4l2_ctrl_s_ctrl(isc->gr_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GR]);
50 v4l2_ctrl_s_ctrl(isc->gb_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GB]);
52 v4l2_ctrl_s_ctrl(isc->r_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_R]);
53 v4l2_ctrl_s_ctrl(isc->b_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_B]);
54 v4l2_ctrl_s_ctrl(isc->gr_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GR]);
55 v4l2_ctrl_s_ctrl(isc->gb_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GB]);
58 static inline void isc_update_awb_ctrls(struct isc_device *isc)
60 struct isc_ctrls *ctrls = &isc->ctrls;
64 regmap_write(isc->regmap, ISC_WB_O_RGR,
67 regmap_write(isc->regmap, ISC_WB_O_BGB,
70 regmap_write(isc->regmap, ISC_WB_G_RGR,
73 regmap_write(isc->regmap, ISC_WB_G_BGB,
78 static inline void isc_reset_awb_ctrls(struct isc_device *isc)
84 isc->ctrls.gain[c] = 1 << 9;
86 isc->ctrls.offset[c] = 0;
94 struct isc_device *isc = vb2_get_drv_priv(vq);
95 unsigned int size = isc->fmt.fmt.pix.sizeimage;
109 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue);
110 unsigned long size = isc->fmt.fmt.pix.sizeimage;
113 dev_err(isc->dev, "buffer too small (%lu < %lu)\n",
120 vbuf->field = isc->fmt.fmt.pix.field;
125 static void isc_crop_pfe(struct isc_device *isc)
127 struct regmap *regmap = isc->regmap;
130 h = isc->fmt.fmt.pix.height;
131 w = isc->fmt.fmt.pix.width;
139 if (!ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) {
164 static void isc_start_dma(struct isc_device *isc)
166 struct regmap *regmap = isc->regmap;
167 u32 sizeimage = isc->fmt.fmt.pix.sizeimage;
171 addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0);
172 regmap_write(regmap, ISC_DAD0 + isc->offsets.dma, addr0);
174 switch (isc->config.fourcc) {
176 regmap_write(regmap, ISC_DAD1 + isc->offsets.dma,
178 regmap_write(regmap, ISC_DAD2 + isc->offsets.dma,
182 regmap_write(regmap, ISC_DAD1 + isc->offsets.dma,
184 regmap_write(regmap, ISC_DAD2 + isc->offsets.dma,
191 dctrl_dview = isc->config.dctrl_dview;
193 regmap_write(regmap, ISC_DCTRL + isc->offsets.dma,
195 spin_lock(&isc->awb_lock);
197 spin_unlock(&isc->awb_lock);
200 static void isc_set_pipeline(struct isc_device *isc, u32 pipeline)
202 struct regmap *regmap = isc->regmap;
203 struct isc_ctrls *ctrls = &isc->ctrls;
211 regmap_field_write(isc->pipeline[i], val);
217 bay_cfg = isc->config.sd_format->cfa_baycfg;
220 isc_update_awb_ctrls(isc);
221 isc_update_v4l2_ctrls(isc);
225 gamma = &isc->gamma_table[ctrls->gamma_index][0];
230 isc->config_dpc(isc);
231 isc->config_csc(isc);
232 isc->config_cbc(isc);
233 isc->config_cc(isc);
234 isc->config_gam(isc);
237 static int isc_update_profile(struct isc_device *isc)
239 struct regmap *regmap = isc->regmap;
252 v4l2_warn(&isc->v4l2_dev, "Time out to update profile\n");
259 static void isc_set_histogram(struct isc_device *isc, bool enable)
261 struct regmap *regmap = isc->regmap;
262 struct isc_ctrls *ctrls = &isc->ctrls;
265 regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his,
267 (isc->config.sd_format->cfa_baycfg
270 regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his,
274 isc_update_profile(isc);
280 regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his,
287 static int isc_configure(struct isc_device *isc)
289 struct regmap *regmap = isc->regmap;
291 struct isc_subdev_entity *subdev = isc->current_subdev;
293 pfe_cfg0 = isc->config.sd_format->pfe_cfg0_bps;
294 pipeline = isc->config.bits_pipeline;
296 dcfg = isc->config.dcfg_imode | isc->dcfg;
306 isc->config_rlp(isc);
308 regmap_write(regmap, ISC_DCFG + isc->offsets.dma, dcfg);
311 isc_set_pipeline(isc, pipeline);
317 if (isc->ctrls.awb &&
318 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
319 isc_set_histogram(isc, true);
321 isc_set_histogram(isc, false);
324 return isc_update_profile(isc);
329 struct isc_device *isc = vb2_get_drv_priv(vq);
331 return media_pipeline_start(isc->video_dev.entity.pads, &isc->mpipe);
336 struct isc_device *isc = vb2_get_drv_priv(vq);
337 struct regmap *regmap = isc->regmap;
343 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1);
345 dev_err(isc->dev, "stream on failed in subdev %d\n", ret);
349 ret = pm_runtime_resume_and_get(isc->dev);
351 dev_err(isc->dev, "RPM resume failed in subdev %d\n",
356 ret = isc_configure(isc);
363 spin_lock_irqsave(&isc->dma_queue_lock, flags);
365 isc->sequence = 0;
366 isc->stop = false;
367 reinit_completion(&isc->comp);
369 isc->cur_frm = list_first_entry(&isc->dma_queue,
371 list_del(&isc->cur_frm->list);
373 isc_crop_pfe(isc);
374 isc_start_dma(isc);
376 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
379 if (ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
380 v4l2_ctrl_activate(isc->do_wb_ctrl, true);
385 pm_runtime_put_sync(isc->dev);
387 v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0);
390 spin_lock_irqsave(&isc->dma_queue_lock, flags);
391 list_for_each_entry(buf, &isc->dma_queue, list)
393 INIT_LIST_HEAD(&isc->dma_queue);
394 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
401 struct isc_device *isc = vb2_get_drv_priv(vq);
404 media_pipeline_stop(isc->video_dev.entity.pads);
409 struct isc_device *isc = vb2_get_drv_priv(vq);
414 mutex_lock(&isc->awb_mutex);
415 v4l2_ctrl_activate(isc->do_wb_ctrl, false);
417 isc->stop = true;
420 if (isc->cur_frm && !wait_for_completion_timeout(&isc->comp, 5 * HZ))
421 dev_err(isc->dev, "Timeout waiting for end of the capture\n");
423 mutex_unlock(&isc->awb_mutex);
426 regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE);
428 pm_runtime_put_sync(isc->dev);
431 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0);
433 dev_err(isc->dev, "stream off failed in subdev\n");
436 spin_lock_irqsave(&isc->dma_queue_lock, flags);
437 if (unlikely(isc->cur_frm)) {
438 vb2_buffer_done(&isc->cur_frm->vb.vb2_buf,
440 isc->cur_frm = NULL;
442 list_for_each_entry(buf, &isc->dma_queue, list)
444 INIT_LIST_HEAD(&isc->dma_queue);
445 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
452 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue);
455 spin_lock_irqsave(&isc->dma_queue_lock, flags);
456 if (!isc->cur_frm && list_empty(&isc->dma_queue) &&
458 isc->cur_frm = buf;
459 isc_start_dma(isc);
461 list_add_tail(&buf->list, &isc->dma_queue);
463 spin_unlock_irqrestore(&isc->dma_queue_lock, flags);
481 struct isc_device *isc = video_drvdata(file);
483 strscpy(cap->driver, "microchip-isc", sizeof(cap->driver));
486 "platform:%s", isc->v4l2_dev.name);
494 struct isc_device *isc = video_drvdata(file);
504 if (index >= isc->controller_formats_size)
507 f->pixelformat = isc->controller_formats[index].fourcc;
520 fmt = isc_find_format_by_code(isc, f->mbus_code, &i);
542 for (i = 0; i < isc->controller_formats_size; i++) {
543 if (isc->controller_formats[i].raw)
546 f->pixelformat = isc->controller_formats[i].fourcc;
558 struct isc_device *isc = video_drvdata(file);
560 *fmt = isc->fmt;
569 static int isc_try_validate_formats(struct isc_device *isc)
575 switch (isc->try_config.fourcc) {
617 dev_err(isc->dev, "Requested unsupported format.\n");
620 dev_dbg(isc->dev,
625 !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
626 dev_err(isc->dev, "Cannot output RAW if we do not receive RAW.\n");
630 if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) &&
631 !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
632 dev_err(isc->dev, "Cannot output GREY if we do not receive RAW/GREY.\n");
637 ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) {
638 dev_err(isc->dev, "Cannot convert GREY to another format.\n");
650 static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump)
652 isc->try_config.rlp_cfg_mode = 0;
654 switch (isc->try_config.fourcc) {
659 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8;
660 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
661 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
662 isc->try_config.bpp = 8;
663 isc->try_config.bpp_v4l2 = 8;
669 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10;
670 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
671 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
672 isc->try_config.bpp = 16;
673 isc->try_config.bpp_v4l2 = 16;
679 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12;
680 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
681 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
682 isc->try_config.bpp = 16;
683 isc->try_config.bpp_v4l2 = 16;
686 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565;
687 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
688 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
689 isc->try_config.bpp = 16;
690 isc->try_config.bpp_v4l2 = 16;
693 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444;
694 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
695 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
696 isc->try_config.bpp = 16;
697 isc->try_config.bpp_v4l2 = 16;
700 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555;
701 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
702 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
703 isc->try_config.bpp = 16;
704 isc->try_config.bpp_v4l2 = 16;
708 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB32;
709 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32;
710 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
711 isc->try_config.bpp = 32;
712 isc->try_config.bpp_v4l2 = 32;
715 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC;
716 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC420P;
717 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR;
718 isc->try_config.bpp = 12;
719 isc->try_config.bpp_v4l2 = 8; /* only first plane */
722 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC;
723 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC422P;
724 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR;
725 isc->try_config.bpp = 16;
726 isc->try_config.bpp_v4l2 = 8; /* only first plane */
729 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_YUYV;
730 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32;
731 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
732 isc->try_config.bpp = 16;
733 isc->try_config.bpp_v4l2 = 16;
736 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_UYVY;
737 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32;
738 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
739 isc->try_config.bpp = 16;
740 isc->try_config.bpp_v4l2 = 16;
743 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_VYUY;
744 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32;
745 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
746 isc->try_config.bpp = 16;
747 isc->try_config.bpp_v4l2 = 16;
750 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8;
751 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
752 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
753 isc->try_config.bpp = 8;
754 isc->try_config.bpp_v4l2 = 8;
757 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10 | ISC_RLP_CFG_LSH;
760 isc->try_config.rlp_cfg_mode |= ISC_RLP_CFG_MODE_DATY10;
761 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16;
762 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
763 isc->try_config.bpp = 16;
764 isc->try_config.bpp_v4l2 = 16;
771 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8;
772 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8;
773 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED;
784 static int isc_try_configure_pipeline(struct isc_device *isc)
786 switch (isc->try_config.fourcc) {
793 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
794 isc->try_config.bits_pipeline = CFA_ENABLE |
798 isc->try_config.bits_pipeline = 0x0;
803 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
804 isc->try_config.bits_pipeline = CFA_ENABLE |
809 isc->try_config.bits_pipeline = 0x0;
814 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
815 isc->try_config.bits_pipeline = CFA_ENABLE |
819 isc->try_config.bits_pipeline = 0x0;
826 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
827 isc->try_config.bits_pipeline = CFA_ENABLE |
831 isc->try_config.bits_pipeline = 0x0;
837 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) {
838 isc->try_config.bits_pipeline = CFA_ENABLE |
842 isc->try_config.bits_pipeline = 0x0;
846 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
847 isc->try_config.bits_pipeline = WB_ENABLE | DPC_BLCENABLE;
849 isc->try_config.bits_pipeline = 0x0;
853 isc->adapt_pipeline(isc);
858 static void isc_try_fse(struct isc_device *isc,
870 if (!isc->config.sd_format)
873 fse.code = isc->try_config.sd_format->mbus_code;
875 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size,
882 sd_state->pads->try_crop.width = isc->max_width;
883 sd_state->pads->try_crop.height = isc->max_height;
890 static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f)
898 isc->try_config.fourcc = isc->controller_formats[0].fourcc;
901 for (i = 0; i < isc->controller_formats_size; i++)
902 if (isc->controller_formats[i].fourcc == pixfmt->pixelformat) {
903 isc->try_config.fourcc = pixfmt->pixelformat;
907 isc_try_configure_rlp_dma(isc, false);
910 v4l_bound_align_image(&pixfmt->width, 16, isc->max_width, 0,
911 &pixfmt->height, 16, isc->max_height, 0, 0);
913 pixfmt->pixelformat = isc->try_config.fourcc;
917 pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp_v4l2) >> 3;
918 pixfmt->sizeimage = ((pixfmt->width * isc->try_config.bpp) >> 3) *
921 isc->try_fmt = *f;
926 static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f)
928 isc_try_fmt(isc, f);
931 isc->config = isc->try_config;
932 isc->fmt = isc->try_fmt;
934 dev_dbg(isc->dev, "ISC set_fmt to %.4s @%dx%d\n",
941 static int isc_validate(struct isc_device *isc)
946 struct v4l2_pix_format *pixfmt = &isc->fmt.fmt.pix;
949 .pad = isc->remote_pad,
957 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, get_fmt, NULL,
963 for (i = 0; i < isc->formats_list_size; i++)
964 if (isc->formats_list[i].mbus_code == format.format.code) {
965 sd_fmt = &isc->formats_list[i];
971 dev_err(isc->dev,
978 isc->try_config.sd_format = sd_fmt;
981 if (!ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code))
982 isc_try_configure_rlp_dma(isc, true);
985 v4l_bound_align_image(&format.format.width, 16, isc->max_width, 0,
986 &format.format.height, 16, isc->max_height, 0, 0);
991 dev_err(isc->dev,
997 dev_dbg(isc->dev,
1000 isc->try_config.bpp);
1003 if (isc->try_config.sd_format && isc->config.sd_format &&
1004 isc->try_config.sd_format != isc->config.sd_format) {
1005 isc->ctrls.hist_stat = HIST_INIT;
1006 isc_reset_awb_ctrls(isc);
1007 isc_update_v4l2_ctrls(isc);
1011 ret = isc_try_validate_formats(isc);
1016 isc_try_fse(isc, &pad_state);
1019 ret = isc_try_configure_pipeline(isc);
1023 isc->config = isc->try_config;
1025 dev_dbg(isc->dev, "New ISC configuration in place\n");
1033 struct isc_device *isc = video_drvdata(file);
1035 if (vb2_is_busy(&isc->vb2_vidq))
1038 return isc_set_fmt(isc, f);
1044 struct isc_device *isc = video_drvdata(file);
1046 return isc_try_fmt(isc, f);
1079 struct isc_device *isc = video_drvdata(file);
1081 return v4l2_g_parm_cap(video_devdata(file), isc->current_subdev->sd, a);
1086 struct isc_device *isc = video_drvdata(file);
1088 return v4l2_s_parm_cap(video_devdata(file), isc->current_subdev->sd, a);
1094 struct isc_device *isc = video_drvdata(file);
1101 for (i = 0; i < isc->controller_formats_size; i++)
1102 if (isc->controller_formats[i].fourcc == fsize->pixel_format)
1111 fsize->stepwise.max_width = isc->max_width;
1113 fsize->stepwise.max_height = isc->max_height;
1152 struct isc_device *isc = video_drvdata(file);
1153 struct v4l2_subdev *sd = isc->current_subdev->sd;
1156 if (mutex_lock_interruptible(&isc->lock))
1172 ret = isc_set_fmt(isc, &isc->fmt);
1179 mutex_unlock(&isc->lock);
1185 struct isc_device *isc = video_drvdata(file);
1186 struct v4l2_subdev *sd = isc->current_subdev->sd;
1190 mutex_lock(&isc->lock);
1199 mutex_unlock(&isc->lock);
1216 struct isc_device *isc = (struct isc_device *)dev_id;
1217 struct regmap *regmap = isc->regmap;
1227 spin_lock(&isc->dma_queue_lock);
1228 if (isc->cur_frm) {
1229 struct vb2_v4l2_buffer *vbuf = &isc->cur_frm->vb;
1233 vbuf->sequence = isc->sequence++;
1235 isc->cur_frm = NULL;
1238 if (!list_empty(&isc->dma_queue) && !isc->stop) {
1239 isc->cur_frm = list_first_entry(&isc->dma_queue,
1241 list_del(&isc->cur_frm->list);
1243 isc_start_dma(isc);
1246 if (isc->stop)
1247 complete(&isc->comp);
1250 spin_unlock(&isc->dma_queue_lock);
1254 schedule_work(&isc->awb_work);
1262 static void isc_hist_count(struct isc_device *isc, u32 *min, u32 *max)
1264 struct regmap *regmap = isc->regmap;
1265 struct isc_ctrls *ctrls = &isc->ctrls;
1273 regmap_bulk_read(regmap, ISC_HIS_ENTRY + isc->offsets.his_entry,
1292 dev_dbg(isc->dev, "isc wb: hist_id %u, hist_count %u",
1298 struct isc_device *isc = container_of(ctrls, struct isc_device, ctrls);
1315 dev_dbg(isc->dev, "isc wb: green components average %llu\n", avg);
1369 dev_dbg(isc->dev,
1370 "isc wb: component %d, s_gain %u, gw_gain %u\n",
1379 dev_dbg(isc->dev, "isc wb: component %d, final gain %u\n",
1386 struct isc_device *isc =
1388 struct regmap *regmap = isc->regmap;
1389 struct isc_ctrls *ctrls = &isc->ctrls;
1399 isc_hist_count(isc, &min, &max);
1401 dev_dbg(isc->dev,
1402 "isc wb mode %d: hist min %u , max %u\n", hist_id, min, max);
1415 baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT;
1417 ret = pm_runtime_resume_and_get(isc->dev);
1432 spin_lock_irqsave(&isc->awb_lock, flags);
1433 isc_update_awb_ctrls(isc);
1434 spin_unlock_irqrestore(&isc->awb_lock, flags);
1441 dev_info(isc->dev,
1444 isc_update_v4l2_ctrls(isc);
1448 regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his,
1456 mutex_lock(&isc->awb_mutex);
1459 if (isc->stop) {
1460 mutex_unlock(&isc->awb_mutex);
1464 isc_update_profile(isc);
1466 mutex_unlock(&isc->awb_mutex);
1472 pm_runtime_put_sync(isc->dev);
1477 struct isc_device *isc = container_of(ctrl->handler,
1479 struct isc_ctrls *ctrls = &isc->ctrls;
1507 struct isc_device *isc = container_of(ctrl->handler,
1509 struct isc_ctrls *ctrls = &isc->ctrls;
1523 ctrls->gain[ISC_HIS_CFG_MODE_R] = isc->r_gain_ctrl->val;
1525 ctrls->gain[ISC_HIS_CFG_MODE_B] = isc->b_gain_ctrl->val;
1527 ctrls->gain[ISC_HIS_CFG_MODE_GR] = isc->gr_gain_ctrl->val;
1529 ctrls->gain[ISC_HIS_CFG_MODE_GB] = isc->gb_gain_ctrl->val;
1532 ctrls->offset[ISC_HIS_CFG_MODE_R] = isc->r_off_ctrl->val;
1534 ctrls->offset[ISC_HIS_CFG_MODE_B] = isc->b_off_ctrl->val;
1536 ctrls->offset[ISC_HIS_CFG_MODE_GR] = isc->gr_off_ctrl->val;
1538 ctrls->offset[ISC_HIS_CFG_MODE_GB] = isc->gb_off_ctrl->val;
1540 isc_update_awb_ctrls(isc);
1542 mutex_lock(&isc->awb_mutex);
1543 if (vb2_is_streaming(&isc->vb2_vidq)) {
1548 isc_update_profile(isc);
1555 v4l2_ctrl_activate(isc->do_wb_ctrl, false);
1557 mutex_unlock(&isc->awb_mutex);
1561 vb2_is_streaming(&isc->vb2_vidq) &&
1562 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code))
1563 isc_set_histogram(isc, true);
1574 isc_set_histogram(isc, true);
1575 dev_dbg(isc->dev, "One time white-balance started.\n");
1584 struct isc_device *isc = container_of(ctrl->handler,
1586 struct isc_ctrls *ctrls = &isc->ctrls;
1654 static int isc_ctrl_init(struct isc_device *isc)
1657 struct isc_ctrls *ctrls = &isc->ctrls;
1662 isc_reset_awb_ctrls(isc);
1669 isc->config_ctrls(isc, ops);
1674 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, isc->gamma_max, 1,
1675 isc->gamma_max);
1676 isc->awb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops,
1681 isc->do_wb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops,
1685 if (!isc->do_wb_ctrl) {
1691 v4l2_ctrl_activate(isc->do_wb_ctrl, false);
1693 isc->r_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_gain_ctrl, NULL);
1694 isc->b_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_gain_ctrl, NULL);
1695 isc->gr_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_gain_ctrl, NULL);
1696 isc->gb_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_gain_ctrl, NULL);
1697 isc->r_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_off_ctrl, NULL);
1698 isc->b_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_off_ctrl, NULL);
1699 isc->gr_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_off_ctrl, NULL);
1700 isc->gb_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_off_ctrl, NULL);
1706 v4l2_ctrl_auto_cluster(10, &isc->awb_ctrl, 0, true);
1717 struct isc_device *isc = container_of(notifier->v4l2_dev,
1723 if (video_is_registered(&isc->video_dev)) {
1724 dev_err(isc->dev, "only supports one sub-device.\n");
1733 dev_err(isc->dev, "failed to find pad for %s\n", subdev->name);
1737 isc->remote_pad = pad;
1746 struct isc_device *isc = container_of(notifier->v4l2_dev,
1748 mutex_destroy(&isc->awb_mutex);
1749 cancel_work_sync(&isc->awb_work);
1750 video_unregister_device(&isc->video_dev);
1751 v4l2_ctrl_handler_free(&isc->ctrls.handler);
1754 struct isc_format *isc_find_format_by_code(struct isc_device *isc,
1757 struct isc_format *fmt = &isc->formats_list[0];
1760 for (i = 0; i < isc->formats_list_size; i++) {
1773 static int isc_set_default_fmt(struct isc_device *isc)
1781 .pixelformat = isc->controller_formats[0].fourcc,
1786 ret = isc_try_fmt(isc, &f);
1790 isc->fmt = f;
1796 struct isc_device *isc = container_of(notifier->v4l2_dev,
1798 struct video_device *vdev = &isc->video_dev;
1799 struct vb2_queue *q = &isc->vb2_vidq;
1802 INIT_WORK(&isc->awb_work, isc_awb_work);
1804 ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev);
1806 dev_err(isc->dev, "Failed to register subdev nodes\n");
1810 isc->current_subdev = container_of(notifier,
1812 mutex_init(&isc->lock);
1813 mutex_init(&isc->awb_mutex);
1815 init_completion(&isc->comp);
1820 q->drv_priv = isc;
1825 q->lock = &isc->lock;
1827 q->dev = isc->dev;
1831 dev_err(isc->dev, "vb2_queue_init() failed: %d\n", ret);
1836 INIT_LIST_HEAD(&isc->dma_queue);
1837 spin_lock_init(&isc->dma_queue_lock);
1838 spin_lock_init(&isc->awb_lock);
1840 ret = isc_set_default_fmt(isc);
1842 dev_err(isc->dev, "Could not set default format\n");
1846 ret = isc_ctrl_init(isc);
1848 dev_err(isc->dev, "Init isc ctrols failed: %d\n", ret);
1857 vdev->v4l2_dev = &isc->v4l2_dev;
1860 vdev->lock = &isc->lock;
1861 vdev->ctrl_handler = &isc->ctrls.handler;
1864 video_set_drvdata(vdev, isc);
1868 dev_err(isc->dev, "video_register_device failed: %d\n", ret);
1872 ret = isc_scaler_link(isc);
1876 ret = media_device_register(&isc->mdev);
1886 mutex_destroy(&isc->awb_mutex);
1887 mutex_destroy(&isc->lock);
1898 void microchip_isc_subdev_cleanup(struct isc_device *isc)
1902 list_for_each_entry(subdev_entity, &isc->subdev_entities, list) {
1907 INIT_LIST_HEAD(&isc->subdev_entities);
1911 int microchip_isc_pipeline_init(struct isc_device *isc)
1913 struct device *dev = isc->dev;
1914 struct regmap *regmap = isc->regmap;
1934 REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0),
1935 REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0),
1936 REG_FIELD(ISC_SUB422_CTRL + isc->offsets.sub422, 0, 0),
1937 REG_FIELD(ISC_SUB420_CTRL + isc->offsets.sub420, 0, 0),
1945 isc->pipeline[i] = regs;
1956 struct isc_device *isc = video_get_drvdata(vdev);
1963 return isc_validate(isc);
1970 int isc_mc_init(struct isc_device *isc, u32 ver)
1975 isc->video_dev.entity.function = MEDIA_ENT_F_IO_V4L;
1976 isc->video_dev.entity.flags = MEDIA_ENT_FL_DEFAULT;
1977 isc->video_dev.entity.ops = &isc_entity_operations;
1979 isc->pads[ISC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1981 ret = media_entity_pads_init(&isc->video_dev.entity, ISC_PADS_NUM,
1982 isc->pads);
1984 dev_err(isc->dev, "media entity init failed\n");
1988 isc->mdev.dev = isc->dev;
1990 match = of_match_node(isc->dev->driver->of_match_table,
1991 isc->dev->of_node);
1993 strscpy(isc->mdev.driver_name, KBUILD_MODNAME,
1994 sizeof(isc->mdev.driver_name));
1995 strscpy(isc->mdev.model, match->compatible, sizeof(isc->mdev.model));
1996 snprintf(isc->mdev.bus_info, sizeof(isc->mdev.bus_info), "platform:%s",
1997 isc->v4l2_dev.name);
1998 isc->mdev.hw_revision = ver;
2000 media_device_init(&isc->mdev);
2002 isc->v4l2_dev.mdev = &isc->mdev;
2004 return isc_scaler_init(isc);
2008 void isc_mc_cleanup(struct isc_device *isc)
2010 media_entity_cleanup(&isc->video_dev.entity);
2011 media_device_cleanup(&isc->mdev);