Lines Matching full:isc

3  * Microchip Image Sensor Controller (ISC) common driver base
25 #include <linux/atmel-isc-media.h>
36 #include "atmel-isc-regs.h"
37 #include "atmel-isc.h"
55 static inline void isc_update_v4l2_ctrls(struct isc_device *isc) in isc_update_v4l2_ctrls() argument
57 struct isc_ctrls *ctrls = &isc->ctrls; in isc_update_v4l2_ctrls()
60 v4l2_ctrl_s_ctrl(isc->r_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_R]); in isc_update_v4l2_ctrls()
61 v4l2_ctrl_s_ctrl(isc->b_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_B]); in isc_update_v4l2_ctrls()
62 v4l2_ctrl_s_ctrl(isc->gr_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GR]); in isc_update_v4l2_ctrls()
63 v4l2_ctrl_s_ctrl(isc->gb_gain_ctrl, ctrls->gain[ISC_HIS_CFG_MODE_GB]); in isc_update_v4l2_ctrls()
65 v4l2_ctrl_s_ctrl(isc->r_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_R]); in isc_update_v4l2_ctrls()
66 v4l2_ctrl_s_ctrl(isc->b_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_B]); in isc_update_v4l2_ctrls()
67 v4l2_ctrl_s_ctrl(isc->gr_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GR]); in isc_update_v4l2_ctrls()
68 v4l2_ctrl_s_ctrl(isc->gb_off_ctrl, ctrls->offset[ISC_HIS_CFG_MODE_GB]); in isc_update_v4l2_ctrls()
71 static inline void isc_update_awb_ctrls(struct isc_device *isc) in isc_update_awb_ctrls() argument
73 struct isc_ctrls *ctrls = &isc->ctrls; in isc_update_awb_ctrls()
77 regmap_write(isc->regmap, ISC_WB_O_RGR, in isc_update_awb_ctrls()
80 regmap_write(isc->regmap, ISC_WB_O_BGB, in isc_update_awb_ctrls()
83 regmap_write(isc->regmap, ISC_WB_G_RGR, in isc_update_awb_ctrls()
86 regmap_write(isc->regmap, ISC_WB_G_BGB, in isc_update_awb_ctrls()
91 static inline void isc_reset_awb_ctrls(struct isc_device *isc) in isc_reset_awb_ctrls() argument
97 isc->ctrls.gain[c] = 1 << 9; in isc_reset_awb_ctrls()
99 isc->ctrls.offset[c] = 0; in isc_reset_awb_ctrls()
153 dev_dbg(isc_clk->dev, "ISC CLK: %s, id = %d, div = %d, parent id = %d\n", in isc_clk_enable()
254 "ISC CLK: %s, best_rate = %ld, parent clk: %s @ %ld\n", in isc_clk_determine_rate()
318 static int isc_clk_register(struct isc_device *isc, unsigned int id) in isc_clk_register() argument
320 struct regmap *regmap = isc->regmap; in isc_clk_register()
321 struct device_node *np = isc->dev->of_node; in isc_clk_register()
340 clk_name = "isc-ispck"; in isc_clk_register()
348 isc_clk = &isc->isc_clks[id]; in isc_clk_register()
352 isc_clk->dev = isc->dev; in isc_clk_register()
355 isc_clk->clk = clk_register(isc->dev, &isc_clk->hw); in isc_clk_register()
357 dev_err(isc->dev, "%s: clock register fail\n", clk_name); in isc_clk_register()
365 int isc_clk_init(struct isc_device *isc) in isc_clk_init() argument
370 for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) in isc_clk_init()
371 isc->isc_clks[i].clk = ERR_PTR(-EINVAL); in isc_clk_init()
373 for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) { in isc_clk_init()
374 ret = isc_clk_register(isc, i); in isc_clk_init()
383 void isc_clk_cleanup(struct isc_device *isc) in isc_clk_cleanup() argument
387 of_clk_del_provider(isc->dev->of_node); in isc_clk_cleanup()
389 for (i = 0; i < ARRAY_SIZE(isc->isc_clks); i++) { in isc_clk_cleanup()
390 struct isc_clk *isc_clk = &isc->isc_clks[i]; in isc_clk_cleanup()
402 struct isc_device *isc = vb2_get_drv_priv(vq); in isc_queue_setup() local
403 unsigned int size = isc->fmt.fmt.pix.sizeimage; in isc_queue_setup()
417 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue); in isc_buffer_prepare() local
418 unsigned long size = isc->fmt.fmt.pix.sizeimage; in isc_buffer_prepare()
421 v4l2_err(&isc->v4l2_dev, "buffer too small (%lu < %lu)\n", in isc_buffer_prepare()
428 vbuf->field = isc->fmt.fmt.pix.field; in isc_buffer_prepare()
433 static void isc_start_dma(struct isc_device *isc) in isc_start_dma() argument
435 struct regmap *regmap = isc->regmap; in isc_start_dma()
436 u32 sizeimage = isc->fmt.fmt.pix.sizeimage; in isc_start_dma()
441 h = isc->fmt.fmt.pix.height; in isc_start_dma()
442 w = isc->fmt.fmt.pix.width; in isc_start_dma()
446 * with two samples on the ISC Data bus (which is 8-12) in isc_start_dma()
447 * ISC will count each sample, so, we need to multiply these values in isc_start_dma()
450 if (!ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) { in isc_start_dma()
456 * We limit the column/row count that the ISC will output according in isc_start_dma()
459 * sending more data, and the ISC will just take it and DMA to memory, in isc_start_dma()
474 addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0); in isc_start_dma()
475 regmap_write(regmap, ISC_DAD0 + isc->offsets.dma, addr0); in isc_start_dma()
477 switch (isc->config.fourcc) { in isc_start_dma()
479 regmap_write(regmap, ISC_DAD1 + isc->offsets.dma, in isc_start_dma()
481 regmap_write(regmap, ISC_DAD2 + isc->offsets.dma, in isc_start_dma()
485 regmap_write(regmap, ISC_DAD1 + isc->offsets.dma, in isc_start_dma()
487 regmap_write(regmap, ISC_DAD2 + isc->offsets.dma, in isc_start_dma()
494 dctrl_dview = isc->config.dctrl_dview; in isc_start_dma()
496 regmap_write(regmap, ISC_DCTRL + isc->offsets.dma, in isc_start_dma()
498 spin_lock(&isc->awb_lock); in isc_start_dma()
500 spin_unlock(&isc->awb_lock); in isc_start_dma()
503 static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) in isc_set_pipeline() argument
505 struct regmap *regmap = isc->regmap; in isc_set_pipeline()
506 struct isc_ctrls *ctrls = &isc->ctrls; in isc_set_pipeline()
514 regmap_field_write(isc->pipeline[i], val); in isc_set_pipeline()
520 bay_cfg = isc->config.sd_format->cfa_baycfg; in isc_set_pipeline()
523 isc_update_awb_ctrls(isc); in isc_set_pipeline()
524 isc_update_v4l2_ctrls(isc); in isc_set_pipeline()
528 gamma = &isc->gamma_table[ctrls->gamma_index][0]; in isc_set_pipeline()
533 isc->config_dpc(isc); in isc_set_pipeline()
534 isc->config_csc(isc); in isc_set_pipeline()
535 isc->config_cbc(isc); in isc_set_pipeline()
536 isc->config_cc(isc); in isc_set_pipeline()
537 isc->config_gam(isc); in isc_set_pipeline()
540 static int isc_update_profile(struct isc_device *isc) in isc_update_profile() argument
542 struct regmap *regmap = isc->regmap; in isc_update_profile()
555 v4l2_warn(&isc->v4l2_dev, "Time out to update profile\n"); in isc_update_profile()
562 static void isc_set_histogram(struct isc_device *isc, bool enable) in isc_set_histogram() argument
564 struct regmap *regmap = isc->regmap; in isc_set_histogram()
565 struct isc_ctrls *ctrls = &isc->ctrls; in isc_set_histogram()
568 regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his, in isc_set_histogram()
570 (isc->config.sd_format->cfa_baycfg in isc_set_histogram()
573 regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his, in isc_set_histogram()
577 isc_update_profile(isc); in isc_set_histogram()
583 regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his, in isc_set_histogram()
590 static int isc_configure(struct isc_device *isc) in isc_configure() argument
592 struct regmap *regmap = isc->regmap; in isc_configure()
594 struct isc_subdev_entity *subdev = isc->current_subdev; in isc_configure()
596 pfe_cfg0 = isc->config.sd_format->pfe_cfg0_bps; in isc_configure()
597 pipeline = isc->config.bits_pipeline; in isc_configure()
599 dcfg = isc->config.dcfg_imode | isc->dcfg; in isc_configure()
609 isc->config_rlp(isc); in isc_configure()
611 regmap_write(regmap, ISC_DCFG + isc->offsets.dma, dcfg); in isc_configure()
614 isc_set_pipeline(isc, pipeline); in isc_configure()
620 if (isc->ctrls.awb && in isc_configure()
621 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) in isc_configure()
622 isc_set_histogram(isc, true); in isc_configure()
624 isc_set_histogram(isc, false); in isc_configure()
627 return isc_update_profile(isc); in isc_configure()
632 struct isc_device *isc = vb2_get_drv_priv(vq); in isc_start_streaming() local
633 struct regmap *regmap = isc->regmap; in isc_start_streaming()
639 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 1); in isc_start_streaming()
641 v4l2_err(&isc->v4l2_dev, "stream on failed in subdev %d\n", in isc_start_streaming()
646 ret = pm_runtime_resume_and_get(isc->dev); in isc_start_streaming()
648 v4l2_err(&isc->v4l2_dev, "RPM resume failed in subdev %d\n", in isc_start_streaming()
653 ret = isc_configure(isc); in isc_start_streaming()
660 spin_lock_irqsave(&isc->dma_queue_lock, flags); in isc_start_streaming()
662 isc->sequence = 0; in isc_start_streaming()
663 isc->stop = false; in isc_start_streaming()
664 reinit_completion(&isc->comp); in isc_start_streaming()
666 isc->cur_frm = list_first_entry(&isc->dma_queue, in isc_start_streaming()
668 list_del(&isc->cur_frm->list); in isc_start_streaming()
670 isc_start_dma(isc); in isc_start_streaming()
672 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); in isc_start_streaming()
675 if (ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) in isc_start_streaming()
676 v4l2_ctrl_activate(isc->do_wb_ctrl, true); in isc_start_streaming()
681 pm_runtime_put_sync(isc->dev); in isc_start_streaming()
683 v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0); in isc_start_streaming()
686 spin_lock_irqsave(&isc->dma_queue_lock, flags); in isc_start_streaming()
687 list_for_each_entry(buf, &isc->dma_queue, list) in isc_start_streaming()
689 INIT_LIST_HEAD(&isc->dma_queue); in isc_start_streaming()
690 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); in isc_start_streaming()
697 struct isc_device *isc = vb2_get_drv_priv(vq); in isc_stop_streaming() local
702 v4l2_ctrl_activate(isc->do_wb_ctrl, false); in isc_stop_streaming()
704 isc->stop = true; in isc_stop_streaming()
707 if (isc->cur_frm && !wait_for_completion_timeout(&isc->comp, 5 * HZ)) in isc_stop_streaming()
708 v4l2_err(&isc->v4l2_dev, in isc_stop_streaming()
712 regmap_write(isc->regmap, ISC_INTDIS, ISC_INT_DDONE); in isc_stop_streaming()
714 pm_runtime_put_sync(isc->dev); in isc_stop_streaming()
717 ret = v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0); in isc_stop_streaming()
719 v4l2_err(&isc->v4l2_dev, "stream off failed in subdev\n"); in isc_stop_streaming()
722 spin_lock_irqsave(&isc->dma_queue_lock, flags); in isc_stop_streaming()
723 if (unlikely(isc->cur_frm)) { in isc_stop_streaming()
724 vb2_buffer_done(&isc->cur_frm->vb.vb2_buf, in isc_stop_streaming()
726 isc->cur_frm = NULL; in isc_stop_streaming()
728 list_for_each_entry(buf, &isc->dma_queue, list) in isc_stop_streaming()
730 INIT_LIST_HEAD(&isc->dma_queue); in isc_stop_streaming()
731 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); in isc_stop_streaming()
738 struct isc_device *isc = vb2_get_drv_priv(vb->vb2_queue); in isc_buffer_queue() local
741 spin_lock_irqsave(&isc->dma_queue_lock, flags); in isc_buffer_queue()
742 if (!isc->cur_frm && list_empty(&isc->dma_queue) && in isc_buffer_queue()
744 isc->cur_frm = buf; in isc_buffer_queue()
745 isc_start_dma(isc); in isc_buffer_queue()
747 list_add_tail(&buf->list, &isc->dma_queue); in isc_buffer_queue()
748 spin_unlock_irqrestore(&isc->dma_queue_lock, flags); in isc_buffer_queue()
751 static struct isc_format *find_format_by_fourcc(struct isc_device *isc, in find_format_by_fourcc() argument
754 unsigned int num_formats = isc->num_user_formats; in find_format_by_fourcc()
759 fmt = isc->user_formats[i]; in find_format_by_fourcc()
780 struct isc_device *isc = video_drvdata(file); in isc_querycap() local
782 strscpy(cap->driver, "microchip-isc", sizeof(cap->driver)); in isc_querycap()
785 "platform:%s", isc->v4l2_dev.name); in isc_querycap()
793 struct isc_device *isc = video_drvdata(file); in isc_enum_fmt_vid_cap() local
797 if (index < isc->controller_formats_size) { in isc_enum_fmt_vid_cap()
798 f->pixelformat = isc->controller_formats[index].fourcc; in isc_enum_fmt_vid_cap()
802 index -= isc->controller_formats_size; in isc_enum_fmt_vid_cap()
806 for (i = 0; i < isc->formats_list_size; i++) { in isc_enum_fmt_vid_cap()
807 if (!ISC_IS_FORMAT_RAW(isc->formats_list[i].mbus_code) || in isc_enum_fmt_vid_cap()
808 !isc->formats_list[i].sd_support) in isc_enum_fmt_vid_cap()
811 f->pixelformat = isc->formats_list[i].fourcc; in isc_enum_fmt_vid_cap()
823 struct isc_device *isc = video_drvdata(file); in isc_g_fmt_vid_cap() local
825 *fmt = isc->fmt; in isc_g_fmt_vid_cap()
831 * Checks the current configured format, if ISC can output it,
832 * considering which type of format the ISC receives from the sensor
834 static int isc_try_validate_formats(struct isc_device *isc) in isc_try_validate_formats() argument
840 switch (isc->try_config.fourcc) { in isc_try_validate_formats()
884 v4l2_dbg(1, debug, &isc->v4l2_dev, in isc_try_validate_formats()
889 if ((bayer) && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) in isc_try_validate_formats()
893 if (grey && !ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code) && in isc_try_validate_formats()
894 !ISC_IS_FORMAT_GREY(isc->try_config.sd_format->mbus_code)) in isc_try_validate_formats()
902 * configured for the ISC.
905 static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) in isc_try_configure_rlp_dma() argument
907 isc->try_config.rlp_cfg_mode = 0; in isc_try_configure_rlp_dma()
909 switch (isc->try_config.fourcc) { in isc_try_configure_rlp_dma()
914 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8; in isc_try_configure_rlp_dma()
915 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; in isc_try_configure_rlp_dma()
916 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
917 isc->try_config.bpp = 8; in isc_try_configure_rlp_dma()
923 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT10; in isc_try_configure_rlp_dma()
924 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
925 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
926 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
932 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT12; in isc_try_configure_rlp_dma()
933 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
934 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
935 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
938 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_RGB565; in isc_try_configure_rlp_dma()
939 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
940 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
941 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
944 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB444; in isc_try_configure_rlp_dma()
945 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
946 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
947 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
950 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB555; in isc_try_configure_rlp_dma()
951 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
952 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
953 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
957 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_ARGB32; in isc_try_configure_rlp_dma()
958 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; in isc_try_configure_rlp_dma()
959 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
960 isc->try_config.bpp = 32; in isc_try_configure_rlp_dma()
963 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; in isc_try_configure_rlp_dma()
964 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC420P; in isc_try_configure_rlp_dma()
965 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR; in isc_try_configure_rlp_dma()
966 isc->try_config.bpp = 12; in isc_try_configure_rlp_dma()
969 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; in isc_try_configure_rlp_dma()
970 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_YC422P; in isc_try_configure_rlp_dma()
971 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PLANAR; in isc_try_configure_rlp_dma()
972 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
975 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_YUYV; in isc_try_configure_rlp_dma()
976 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; in isc_try_configure_rlp_dma()
977 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
978 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
981 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_UYVY; in isc_try_configure_rlp_dma()
982 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; in isc_try_configure_rlp_dma()
983 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
984 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
987 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_VYUY; in isc_try_configure_rlp_dma()
988 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; in isc_try_configure_rlp_dma()
989 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
990 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
993 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY8; in isc_try_configure_rlp_dma()
994 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; in isc_try_configure_rlp_dma()
995 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
996 isc->try_config.bpp = 8; in isc_try_configure_rlp_dma()
999 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10 | ISC_RLP_CFG_LSH; in isc_try_configure_rlp_dma()
1002 isc->try_config.rlp_cfg_mode |= ISC_RLP_CFG_MODE_DATY10; in isc_try_configure_rlp_dma()
1003 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; in isc_try_configure_rlp_dma()
1004 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
1005 isc->try_config.bpp = 16; in isc_try_configure_rlp_dma()
1012 isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DAT8; in isc_try_configure_rlp_dma()
1013 isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED8; in isc_try_configure_rlp_dma()
1014 isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; in isc_try_configure_rlp_dma()
1022 * Configuring pipeline modules, depending on which format the ISC outputs
1025 static int isc_try_configure_pipeline(struct isc_device *isc) in isc_try_configure_pipeline() argument
1027 switch (isc->try_config.fourcc) { in isc_try_configure_pipeline()
1033 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
1034 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
1035 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
1039 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
1043 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
1044 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
1045 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
1050 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
1054 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
1055 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
1056 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
1060 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
1066 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
1067 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
1068 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
1072 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
1077 /* if sensor format is RAW, we convert inside ISC */ in isc_try_configure_pipeline()
1078 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { in isc_try_configure_pipeline()
1079 isc->try_config.bits_pipeline = CFA_ENABLE | in isc_try_configure_pipeline()
1083 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
1087 if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) in isc_try_configure_pipeline()
1088 isc->try_config.bits_pipeline = WB_ENABLE | DPC_BLCENABLE; in isc_try_configure_pipeline()
1090 isc->try_config.bits_pipeline = 0x0; in isc_try_configure_pipeline()
1094 isc->adapt_pipeline(isc); in isc_try_configure_pipeline()
1099 static void isc_try_fse(struct isc_device *isc, in isc_try_fse() argument
1109 if (!isc->try_config.sd_format) in isc_try_fse()
1112 fse.code = isc->try_config.sd_format->mbus_code; in isc_try_fse()
1115 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size, in isc_try_fse()
1119 * just use the maximum ISC can receive. in isc_try_fse()
1122 sd_state->pads->try_crop.width = isc->max_width; in isc_try_fse()
1123 sd_state->pads->try_crop.height = isc->max_height; in isc_try_fse()
1130 static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, in isc_try_fmt() argument
1151 for (i = 0; i < isc->num_user_formats; i++) { in isc_try_fmt()
1152 if (ISC_IS_FORMAT_RAW(isc->user_formats[i]->mbus_code)) { in isc_try_fmt()
1153 sd_fmt = isc->user_formats[i]; in isc_try_fmt()
1160 direct_fmt = find_format_by_fourcc(isc, pixfmt->pixelformat); in isc_try_fmt()
1183 sd_fmt = isc->user_formats[isc->num_user_formats - 1]; in isc_try_fmt()
1184 v4l2_dbg(1, debug, &isc->v4l2_dev, in isc_try_fmt()
1195 v4l2_dbg(1, debug, &isc->v4l2_dev, in isc_try_fmt()
1200 isc->try_config.sd_format = sd_fmt; in isc_try_fmt()
1202 /* Limit to Atmel ISC hardware capabilities */ in isc_try_fmt()
1203 if (pixfmt->width > isc->max_width) in isc_try_fmt()
1204 pixfmt->width = isc->max_width; in isc_try_fmt()
1205 if (pixfmt->height > isc->max_height) in isc_try_fmt()
1206 pixfmt->height = isc->max_height; in isc_try_fmt()
1210 * The pixels will be transferred in this format Sensor -> ISC in isc_try_fmt()
1218 isc->try_config.fourcc = pixfmt->pixelformat; in isc_try_fmt()
1220 if (isc_try_validate_formats(isc)) { in isc_try_fmt()
1221 pixfmt->pixelformat = isc->try_config.fourcc = sd_fmt->fourcc; in isc_try_fmt()
1223 ret = isc_try_validate_formats(isc); in isc_try_fmt()
1228 ret = isc_try_configure_rlp_dma(isc, rlp_dma_direct_dump); in isc_try_fmt()
1232 ret = isc_try_configure_pipeline(isc); in isc_try_fmt()
1237 isc_try_fse(isc, &pad_state); in isc_try_fmt()
1240 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, set_fmt, in isc_try_fmt()
1247 /* Limit to Atmel ISC hardware capabilities */ in isc_try_fmt()
1248 if (pixfmt->width > isc->max_width) in isc_try_fmt()
1249 pixfmt->width = isc->max_width; in isc_try_fmt()
1250 if (pixfmt->height > isc->max_height) in isc_try_fmt()
1251 pixfmt->height = isc->max_height; in isc_try_fmt()
1254 pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp) >> 3; in isc_try_fmt()
1263 v4l2_err(&isc->v4l2_dev, "Could not find any possible format for a working pipeline\n"); in isc_try_fmt()
1265 memset(&isc->try_config, 0, sizeof(isc->try_config)); in isc_try_fmt()
1270 static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) in isc_set_fmt() argument
1278 ret = isc_try_fmt(isc, f, &mbus_code); in isc_set_fmt()
1283 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, in isc_set_fmt()
1288 /* Limit to Atmel ISC hardware capabilities */ in isc_set_fmt()
1289 if (f->fmt.pix.width > isc->max_width) in isc_set_fmt()
1290 f->fmt.pix.width = isc->max_width; in isc_set_fmt()
1291 if (f->fmt.pix.height > isc->max_height) in isc_set_fmt()
1292 f->fmt.pix.height = isc->max_height; in isc_set_fmt()
1294 isc->fmt = *f; in isc_set_fmt()
1296 if (isc->try_config.sd_format && isc->config.sd_format && in isc_set_fmt()
1297 isc->try_config.sd_format != isc->config.sd_format) { in isc_set_fmt()
1298 isc->ctrls.hist_stat = HIST_INIT; in isc_set_fmt()
1299 isc_reset_awb_ctrls(isc); in isc_set_fmt()
1300 isc_update_v4l2_ctrls(isc); in isc_set_fmt()
1303 isc->config = isc->try_config; in isc_set_fmt()
1305 v4l2_dbg(1, debug, &isc->v4l2_dev, "New ISC configuration in place\n"); in isc_set_fmt()
1313 struct isc_device *isc = video_drvdata(file); in isc_s_fmt_vid_cap() local
1315 if (vb2_is_streaming(&isc->vb2_vidq)) in isc_s_fmt_vid_cap()
1318 return isc_set_fmt(isc, f); in isc_s_fmt_vid_cap()
1324 struct isc_device *isc = video_drvdata(file); in isc_try_fmt_vid_cap() local
1326 return isc_try_fmt(isc, f, NULL); in isc_try_fmt_vid_cap()
1359 struct isc_device *isc = video_drvdata(file); in isc_g_parm() local
1361 return v4l2_g_parm_cap(video_devdata(file), isc->current_subdev->sd, a); in isc_g_parm()
1366 struct isc_device *isc = video_drvdata(file); in isc_s_parm() local
1368 return v4l2_s_parm_cap(video_devdata(file), isc->current_subdev->sd, a); in isc_s_parm()
1374 struct isc_device *isc = video_drvdata(file); in isc_enum_framesizes() local
1376 .code = isc->config.sd_format->mbus_code, in isc_enum_framesizes()
1383 for (i = 0; i < isc->num_user_formats; i++) in isc_enum_framesizes()
1384 if (isc->user_formats[i]->fourcc == fsize->pixel_format) in isc_enum_framesizes()
1387 for (i = 0; i < isc->controller_formats_size; i++) in isc_enum_framesizes()
1388 if (isc->controller_formats[i].fourcc == fsize->pixel_format) in isc_enum_framesizes()
1394 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, enum_frame_size, in isc_enum_framesizes()
1409 struct isc_device *isc = video_drvdata(file); in isc_enum_frameintervals() local
1411 .code = isc->config.sd_format->mbus_code, in isc_enum_frameintervals()
1420 for (i = 0; i < isc->num_user_formats; i++) in isc_enum_frameintervals()
1421 if (isc->user_formats[i]->fourcc == fival->pixel_format) in isc_enum_frameintervals()
1424 for (i = 0; i < isc->controller_formats_size; i++) in isc_enum_frameintervals()
1425 if (isc->controller_formats[i].fourcc == fival->pixel_format) in isc_enum_frameintervals()
1431 ret = v4l2_subdev_call(isc->current_subdev->sd, pad, in isc_enum_frameintervals()
1475 struct isc_device *isc = video_drvdata(file); in isc_open() local
1476 struct v4l2_subdev *sd = isc->current_subdev->sd; in isc_open()
1479 if (mutex_lock_interruptible(&isc->lock)) in isc_open()
1495 ret = isc_set_fmt(isc, &isc->fmt); in isc_open()
1502 mutex_unlock(&isc->lock); in isc_open()
1508 struct isc_device *isc = video_drvdata(file); in isc_release() local
1509 struct v4l2_subdev *sd = isc->current_subdev->sd; in isc_release()
1513 mutex_lock(&isc->lock); in isc_release()
1522 mutex_unlock(&isc->lock); in isc_release()
1539 struct isc_device *isc = (struct isc_device *)dev_id; in isc_interrupt() local
1540 struct regmap *regmap = isc->regmap; in isc_interrupt()
1550 spin_lock(&isc->dma_queue_lock); in isc_interrupt()
1551 if (isc->cur_frm) { in isc_interrupt()
1552 struct vb2_v4l2_buffer *vbuf = &isc->cur_frm->vb; in isc_interrupt()
1556 vbuf->sequence = isc->sequence++; in isc_interrupt()
1558 isc->cur_frm = NULL; in isc_interrupt()
1561 if (!list_empty(&isc->dma_queue) && !isc->stop) { in isc_interrupt()
1562 isc->cur_frm = list_first_entry(&isc->dma_queue, in isc_interrupt()
1564 list_del(&isc->cur_frm->list); in isc_interrupt()
1566 isc_start_dma(isc); in isc_interrupt()
1569 if (isc->stop) in isc_interrupt()
1570 complete(&isc->comp); in isc_interrupt()
1573 spin_unlock(&isc->dma_queue_lock); in isc_interrupt()
1577 schedule_work(&isc->awb_work); in isc_interrupt()
1585 static void isc_hist_count(struct isc_device *isc, u32 *min, u32 *max) in isc_hist_count() argument
1587 struct regmap *regmap = isc->regmap; in isc_hist_count()
1588 struct isc_ctrls *ctrls = &isc->ctrls; in isc_hist_count()
1596 regmap_bulk_read(regmap, ISC_HIS_ENTRY + isc->offsets.his_entry, in isc_hist_count()
1694 struct isc_device *isc = in isc_awb_work() local
1696 struct regmap *regmap = isc->regmap; in isc_awb_work()
1697 struct isc_ctrls *ctrls = &isc->ctrls; in isc_awb_work()
1705 if (isc->stop) in isc_awb_work()
1711 isc_hist_count(isc, &min, &max); in isc_awb_work()
1723 baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT; in isc_awb_work()
1725 ret = pm_runtime_resume_and_get(isc->dev); in isc_awb_work()
1740 spin_lock_irqsave(&isc->awb_lock, flags); in isc_awb_work()
1741 isc_update_awb_ctrls(isc); in isc_awb_work()
1742 spin_unlock_irqrestore(&isc->awb_lock, flags); in isc_awb_work()
1749 v4l2_info(&isc->v4l2_dev, in isc_awb_work()
1752 isc_update_v4l2_ctrls(isc); in isc_awb_work()
1756 regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his, in isc_awb_work()
1758 isc_update_profile(isc); in isc_awb_work()
1763 pm_runtime_put_sync(isc->dev); in isc_awb_work()
1768 struct isc_device *isc = container_of(ctrl->handler, in isc_s_ctrl() local
1770 struct isc_ctrls *ctrls = &isc->ctrls; in isc_s_ctrl()
1798 struct isc_device *isc = container_of(ctrl->handler, in isc_s_awb_ctrl() local
1800 struct isc_ctrls *ctrls = &isc->ctrls; in isc_s_awb_ctrl()
1812 /* we did not configure ISC yet */ in isc_s_awb_ctrl()
1813 if (!isc->config.sd_format) in isc_s_awb_ctrl()
1818 ctrls->gain[ISC_HIS_CFG_MODE_R] = isc->r_gain_ctrl->val; in isc_s_awb_ctrl()
1820 ctrls->gain[ISC_HIS_CFG_MODE_B] = isc->b_gain_ctrl->val; in isc_s_awb_ctrl()
1822 ctrls->gain[ISC_HIS_CFG_MODE_GR] = isc->gr_gain_ctrl->val; in isc_s_awb_ctrl()
1824 ctrls->gain[ISC_HIS_CFG_MODE_GB] = isc->gb_gain_ctrl->val; in isc_s_awb_ctrl()
1827 ctrls->offset[ISC_HIS_CFG_MODE_R] = isc->r_off_ctrl->val; in isc_s_awb_ctrl()
1829 ctrls->offset[ISC_HIS_CFG_MODE_B] = isc->b_off_ctrl->val; in isc_s_awb_ctrl()
1831 ctrls->offset[ISC_HIS_CFG_MODE_GR] = isc->gr_off_ctrl->val; in isc_s_awb_ctrl()
1833 ctrls->offset[ISC_HIS_CFG_MODE_GB] = isc->gb_off_ctrl->val; in isc_s_awb_ctrl()
1835 isc_update_awb_ctrls(isc); in isc_s_awb_ctrl()
1837 if (vb2_is_streaming(&isc->vb2_vidq)) { in isc_s_awb_ctrl()
1842 isc_update_profile(isc); in isc_s_awb_ctrl()
1849 v4l2_ctrl_activate(isc->do_wb_ctrl, false); in isc_s_awb_ctrl()
1854 vb2_is_streaming(&isc->vb2_vidq) && in isc_s_awb_ctrl()
1855 ISC_IS_FORMAT_RAW(isc->config.sd_format->mbus_code)) in isc_s_awb_ctrl()
1856 isc_set_histogram(isc, true); in isc_s_awb_ctrl()
1867 isc_set_histogram(isc, true); in isc_s_awb_ctrl()
1868 v4l2_dbg(1, debug, &isc->v4l2_dev, in isc_s_awb_ctrl()
1878 struct isc_device *isc = container_of(ctrl->handler, in isc_g_volatile_awb_ctrl() local
1880 struct isc_ctrls *ctrls = &isc->ctrls; in isc_g_volatile_awb_ctrl()
1948 static int isc_ctrl_init(struct isc_device *isc) in isc_ctrl_init() argument
1951 struct isc_ctrls *ctrls = &isc->ctrls; in isc_ctrl_init()
1956 isc_reset_awb_ctrls(isc); in isc_ctrl_init()
1963 isc->config_ctrls(isc, ops); in isc_ctrl_init()
1968 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, isc->gamma_max, 1, in isc_ctrl_init()
1969 isc->gamma_max); in isc_ctrl_init()
1970 isc->awb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops, in isc_ctrl_init()
1975 isc->do_wb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops, in isc_ctrl_init()
1979 if (!isc->do_wb_ctrl) { in isc_ctrl_init()
1985 v4l2_ctrl_activate(isc->do_wb_ctrl, false); in isc_ctrl_init()
1987 isc->r_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_gain_ctrl, NULL); in isc_ctrl_init()
1988 isc->b_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_gain_ctrl, NULL); in isc_ctrl_init()
1989 isc->gr_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_gain_ctrl, NULL); in isc_ctrl_init()
1990 isc->gb_gain_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_gain_ctrl, NULL); in isc_ctrl_init()
1991 isc->r_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_r_off_ctrl, NULL); in isc_ctrl_init()
1992 isc->b_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_b_off_ctrl, NULL); in isc_ctrl_init()
1993 isc->gr_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gr_off_ctrl, NULL); in isc_ctrl_init()
1994 isc->gb_off_ctrl = v4l2_ctrl_new_custom(hdl, &isc_gb_off_ctrl, NULL); in isc_ctrl_init()
2000 v4l2_ctrl_auto_cluster(10, &isc->awb_ctrl, 0, true); in isc_ctrl_init()
2011 struct isc_device *isc = container_of(notifier->v4l2_dev, in isc_async_bound() local
2016 if (video_is_registered(&isc->video_dev)) { in isc_async_bound()
2017 v4l2_err(&isc->v4l2_dev, "only supports one sub-device.\n"); in isc_async_bound()
2030 struct isc_device *isc = container_of(notifier->v4l2_dev, in isc_async_unbind() local
2032 cancel_work_sync(&isc->awb_work); in isc_async_unbind()
2033 video_unregister_device(&isc->video_dev); in isc_async_unbind()
2034 v4l2_ctrl_handler_free(&isc->ctrls.handler); in isc_async_unbind()
2037 static struct isc_format *find_format_by_code(struct isc_device *isc, in find_format_by_code() argument
2040 struct isc_format *fmt = &isc->formats_list[0]; in find_format_by_code()
2043 for (i = 0; i < isc->formats_list_size; i++) { in find_format_by_code()
2055 static int isc_formats_init(struct isc_device *isc) in isc_formats_init() argument
2058 struct v4l2_subdev *subdev = isc->current_subdev->sd; in isc_formats_init()
2060 u32 list_size = isc->formats_list_size; in isc_formats_init()
2070 fmt = find_format_by_code(isc, mbus_code.code, &i); in isc_formats_init()
2072 v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n", in isc_formats_init()
2084 isc->num_user_formats = num_fmts; in isc_formats_init()
2085 isc->user_formats = devm_kcalloc(isc->dev, in isc_formats_init()
2086 num_fmts, sizeof(*isc->user_formats), in isc_formats_init()
2088 if (!isc->user_formats) in isc_formats_init()
2091 fmt = &isc->formats_list[0]; in isc_formats_init()
2094 isc->user_formats[j++] = fmt; in isc_formats_init()
2101 static int isc_set_default_fmt(struct isc_device *isc) in isc_set_default_fmt() argument
2109 .pixelformat = isc->user_formats[0]->fourcc, in isc_set_default_fmt()
2114 ret = isc_try_fmt(isc, &f, NULL); in isc_set_default_fmt()
2118 isc->fmt = f; in isc_set_default_fmt()
2124 struct isc_device *isc = container_of(notifier->v4l2_dev, in isc_async_complete() local
2126 struct video_device *vdev = &isc->video_dev; in isc_async_complete()
2127 struct vb2_queue *q = &isc->vb2_vidq; in isc_async_complete()
2130 INIT_WORK(&isc->awb_work, isc_awb_work); in isc_async_complete()
2132 ret = v4l2_device_register_subdev_nodes(&isc->v4l2_dev); in isc_async_complete()
2134 v4l2_err(&isc->v4l2_dev, "Failed to register subdev nodes\n"); in isc_async_complete()
2138 isc->current_subdev = container_of(notifier, in isc_async_complete()
2140 mutex_init(&isc->lock); in isc_async_complete()
2141 init_completion(&isc->comp); in isc_async_complete()
2146 q->drv_priv = isc; in isc_async_complete()
2151 q->lock = &isc->lock; in isc_async_complete()
2153 q->dev = isc->dev; in isc_async_complete()
2157 v4l2_err(&isc->v4l2_dev, in isc_async_complete()
2163 INIT_LIST_HEAD(&isc->dma_queue); in isc_async_complete()
2164 spin_lock_init(&isc->dma_queue_lock); in isc_async_complete()
2165 spin_lock_init(&isc->awb_lock); in isc_async_complete()
2167 ret = isc_formats_init(isc); in isc_async_complete()
2169 v4l2_err(&isc->v4l2_dev, in isc_async_complete()
2174 ret = isc_set_default_fmt(isc); in isc_async_complete()
2176 v4l2_err(&isc->v4l2_dev, "Could not set default format\n"); in isc_async_complete()
2180 ret = isc_ctrl_init(isc); in isc_async_complete()
2182 v4l2_err(&isc->v4l2_dev, "Init isc ctrols failed: %d\n", ret); in isc_async_complete()
2187 strscpy(vdev->name, "microchip-isc", sizeof(vdev->name)); in isc_async_complete()
2191 vdev->v4l2_dev = &isc->v4l2_dev; in isc_async_complete()
2194 vdev->lock = &isc->lock; in isc_async_complete()
2195 vdev->ctrl_handler = &isc->ctrls.handler; in isc_async_complete()
2197 video_set_drvdata(vdev, isc); in isc_async_complete()
2201 v4l2_err(&isc->v4l2_dev, in isc_async_complete()
2209 mutex_destroy(&isc->lock); in isc_async_complete()
2220 void isc_subdev_cleanup(struct isc_device *isc) in isc_subdev_cleanup() argument
2224 list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { in isc_subdev_cleanup()
2229 INIT_LIST_HEAD(&isc->subdev_entities); in isc_subdev_cleanup()
2233 int isc_pipeline_init(struct isc_device *isc) in isc_pipeline_init() argument
2235 struct device *dev = isc->dev; in isc_pipeline_init()
2236 struct regmap *regmap = isc->regmap; in isc_pipeline_init()
2256 REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), in isc_pipeline_init()
2257 REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0), in isc_pipeline_init()
2258 REG_FIELD(ISC_SUB422_CTRL + isc->offsets.sub422, 0, 0), in isc_pipeline_init()
2259 REG_FIELD(ISC_SUB420_CTRL + isc->offsets.sub420, 0, 0), in isc_pipeline_init()
2267 isc->pipeline[i] = regs; in isc_pipeline_init()
2286 MODULE_DESCRIPTION("Atmel ISC common code base");