Lines Matching full:csi2dc

3  * Microchip CSI2 Demux Controller (CSI2DC) driver
110 * struct csi2dc_format - CSI2DC format type struct
157 * struct csi2dc_device - CSI2DC device driver data/config struct
159 * @csi2dc_sd: v4l2 subdevice for the csi2dc device
160 * This is the subdevice that the csi2dc device itself
162 * @dev: struct device for this csi2dc device
171 * @pads: Media entity pads for the csi2dc subdevice
177 * subdevice to the csi2dc subdevice
179 * csi2dc subdevice
181 * to the csi2dc subdevice sink pad.
231 struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd); in csi2dc_get_fmt() local
242 format->format = csi2dc->format; in csi2dc_get_fmt()
251 struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd); in csi2dc_set_fmt() local
274 dev_dbg(csi2dc->dev, in csi2dc_set_fmt()
275 "CSI2DC unsupported format 0x%x, defaulting to 0x%x\n", in csi2dc_set_fmt()
298 csi2dc->format = req_fmt->format; in csi2dc_set_fmt()
301 csi2dc->cur_fmt = try_fmt; in csi2dc_set_fmt()
303 dev_dbg(csi2dc->dev, "new format set: 0x%x @%dx%d\n", in csi2dc_set_fmt()
304 csi2dc->format.code, csi2dc->format.width, in csi2dc_set_fmt()
305 csi2dc->format.height); in csi2dc_set_fmt()
310 static int csi2dc_power(struct csi2dc_device *csi2dc, int on) in csi2dc_power() argument
315 ret = clk_prepare_enable(csi2dc->pclk); in csi2dc_power()
317 dev_err(csi2dc->dev, "failed to enable pclk:%d\n", ret); in csi2dc_power()
321 ret = clk_prepare_enable(csi2dc->scck); in csi2dc_power()
323 dev_err(csi2dc->dev, "failed to enable scck:%d\n", ret); in csi2dc_power()
324 clk_disable_unprepare(csi2dc->pclk); in csi2dc_power()
329 csi2dc_writel(csi2dc, CSI2DC_GCTLR, CSI2DC_GCTLR_SWRST); in csi2dc_power()
332 csi2dc_writel(csi2dc, CSI2DC_GCTLR, 0); in csi2dc_power()
334 clk_disable_unprepare(csi2dc->scck); in csi2dc_power()
335 clk_disable_unprepare(csi2dc->pclk); in csi2dc_power()
341 static int csi2dc_get_mbus_config(struct csi2dc_device *csi2dc) in csi2dc_get_mbus_config() argument
346 ret = v4l2_subdev_call(csi2dc->input_sd, pad, get_mbus_config, in csi2dc_get_mbus_config()
347 csi2dc->remote_pad, &mbus_config); in csi2dc_get_mbus_config()
349 dev_dbg(csi2dc->dev, in csi2dc_get_mbus_config()
355 dev_err(csi2dc->dev, in csi2dc_get_mbus_config()
360 dev_dbg(csi2dc->dev, "subdev sending on channel %d\n", csi2dc->vc); in csi2dc_get_mbus_config()
362 csi2dc->clk_gated = mbus_config.bus.parallel.flags & in csi2dc_get_mbus_config()
365 dev_dbg(csi2dc->dev, "mbus_config: %s clock\n", in csi2dc_get_mbus_config()
366 csi2dc->clk_gated ? "gated" : "free running"); in csi2dc_get_mbus_config()
371 static void csi2dc_vp_update(struct csi2dc_device *csi2dc) in csi2dc_vp_update() argument
375 if (!csi2dc->video_pipe) { in csi2dc_vp_update()
376 dev_err(csi2dc->dev, "video pipeline unavailable\n"); in csi2dc_vp_update()
380 if (csi2dc->parallel_mode) { in csi2dc_vp_update()
382 gcfg = csi2dc_readl(csi2dc, CSI2DC_GCFG); in csi2dc_vp_update()
384 csi2dc_writel(csi2dc, CSI2DC_GCFG, gcfg); in csi2dc_vp_update()
390 csi2dc_writel(csi2dc, CSI2DC_GCFG, in csi2dc_vp_update()
392 (csi2dc->clk_gated ? 0 : CSI2DC_GCFG_MIPIFRN)); in csi2dc_vp_update()
394 vp = CSI2DC_VPCFG_DT(csi2dc->cur_fmt->dt) & CSI2DC_VPCFG_DT_MASK; in csi2dc_vp_update()
395 vp |= CSI2DC_VPCFG_VC(csi2dc->vc) & CSI2DC_VPCFG_VC_MASK; in csi2dc_vp_update()
402 csi2dc_writel(csi2dc, CSI2DC_VPCFG, vp); in csi2dc_vp_update()
403 csi2dc_writel(csi2dc, CSI2DC_VPE, CSI2DC_VPE_ENABLE); in csi2dc_vp_update()
404 csi2dc_writel(csi2dc, CSI2DC_PU, CSI2DC_PU_VP); in csi2dc_vp_update()
409 struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd); in csi2dc_s_stream() local
413 ret = pm_runtime_resume_and_get(csi2dc->dev); in csi2dc_s_stream()
417 csi2dc_get_mbus_config(csi2dc); in csi2dc_s_stream()
419 csi2dc_vp_update(csi2dc); in csi2dc_s_stream()
421 return v4l2_subdev_call(csi2dc->input_sd, video, s_stream, in csi2dc_s_stream()
425 dev_dbg(csi2dc->dev, in csi2dc_s_stream()
427 csi2dc_readl(csi2dc, CSI2DC_VPCOL), in csi2dc_s_stream()
428 csi2dc_readl(csi2dc, CSI2DC_VPROW), in csi2dc_s_stream()
429 csi2dc_readl(csi2dc, CSI2DC_VPISR)); in csi2dc_s_stream()
432 ret = v4l2_subdev_call(csi2dc->input_sd, video, s_stream, false); in csi2dc_s_stream()
434 pm_runtime_put_sync(csi2dc->dev); in csi2dc_s_stream()
481 struct csi2dc_device *csi2dc = container_of(notifier, in csi2dc_async_bound() local
486 csi2dc->input_sd = subdev; in csi2dc_async_bound()
491 dev_err(csi2dc->dev, "Failed to find pad for %s\n", in csi2dc_async_bound()
496 csi2dc->remote_pad = pad; in csi2dc_async_bound()
498 ret = media_create_pad_link(&csi2dc->input_sd->entity, in csi2dc_async_bound()
499 csi2dc->remote_pad, in csi2dc_async_bound()
500 &csi2dc->csi2dc_sd.entity, 0, in csi2dc_async_bound()
503 dev_err(csi2dc->dev, in csi2dc_async_bound()
505 csi2dc->input_sd->entity.name, in csi2dc_async_bound()
506 csi2dc->csi2dc_sd.entity.name); in csi2dc_async_bound()
510 dev_dbg(csi2dc->dev, "link with %s pad: %d\n", in csi2dc_async_bound()
511 csi2dc->input_sd->name, csi2dc->remote_pad); in csi2dc_async_bound()
520 static int csi2dc_prepare_notifier(struct csi2dc_device *csi2dc, in csi2dc_prepare_notifier() argument
526 v4l2_async_nf_init(&csi2dc->notifier); in csi2dc_prepare_notifier()
528 asd = v4l2_async_nf_add_fwnode_remote(&csi2dc->notifier, in csi2dc_prepare_notifier()
536 dev_err(csi2dc->dev, in csi2dc_prepare_notifier()
539 v4l2_async_nf_cleanup(&csi2dc->notifier); in csi2dc_prepare_notifier()
543 csi2dc->notifier.ops = &csi2dc_async_ops; in csi2dc_prepare_notifier()
545 ret = v4l2_async_subdev_nf_register(&csi2dc->csi2dc_sd, in csi2dc_prepare_notifier()
546 &csi2dc->notifier); in csi2dc_prepare_notifier()
548 dev_err(csi2dc->dev, "fail to register async notifier: %d\n", in csi2dc_prepare_notifier()
550 v4l2_async_nf_cleanup(&csi2dc->notifier); in csi2dc_prepare_notifier()
556 static int csi2dc_of_parse(struct csi2dc_device *csi2dc, in csi2dc_of_parse() argument
567 dev_err(csi2dc->dev, in csi2dc_of_parse()
575 dev_err(csi2dc->dev, "endpoint not defined at %pOF\n", of_node); in csi2dc_of_parse()
581 csi2dc->parallel_mode = true; in csi2dc_of_parse()
582 dev_dbg(csi2dc->dev, in csi2dc_of_parse()
587 csi2dc->clk_gated = input_endpoint.bus.mipi_csi2.flags & in csi2dc_of_parse()
589 dev_dbg(csi2dc->dev, in csi2dc_of_parse()
591 dev_dbg(csi2dc->dev, "DT: %s clock\n", in csi2dc_of_parse()
592 csi2dc->clk_gated ? "gated" : "free running"); in csi2dc_of_parse()
605 dev_info(csi2dc->dev, in csi2dc_of_parse()
611 dev_err(csi2dc->dev, in csi2dc_of_parse()
617 csi2dc->video_pipe = true; in csi2dc_of_parse()
619 dev_dbg(csi2dc->dev, in csi2dc_of_parse()
627 return csi2dc_prepare_notifier(csi2dc, input_fwnode); in csi2dc_of_parse()
634 static void csi2dc_default_format(struct csi2dc_device *csi2dc) in csi2dc_default_format() argument
636 csi2dc->cur_fmt = &csi2dc_formats[0]; in csi2dc_default_format()
638 csi2dc->format.height = 480; in csi2dc_default_format()
639 csi2dc->format.width = 640; in csi2dc_default_format()
640 csi2dc->format.code = csi2dc_formats[0].mbus_code; in csi2dc_default_format()
641 csi2dc->format.colorspace = V4L2_COLORSPACE_SRGB; in csi2dc_default_format()
642 csi2dc->format.field = V4L2_FIELD_NONE; in csi2dc_default_format()
643 csi2dc->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in csi2dc_default_format()
644 csi2dc->format.quantization = V4L2_QUANTIZATION_DEFAULT; in csi2dc_default_format()
645 csi2dc->format.xfer_func = V4L2_XFER_FUNC_DEFAULT; in csi2dc_default_format()
651 struct csi2dc_device *csi2dc; in csi2dc_probe() local
655 csi2dc = devm_kzalloc(dev, sizeof(*csi2dc), GFP_KERNEL); in csi2dc_probe()
656 if (!csi2dc) in csi2dc_probe()
659 csi2dc->dev = dev; in csi2dc_probe()
661 csi2dc->base = devm_platform_ioremap_resource(pdev, 0); in csi2dc_probe()
662 if (IS_ERR(csi2dc->base)) { in csi2dc_probe()
664 return PTR_ERR(csi2dc->base); in csi2dc_probe()
667 csi2dc->pclk = devm_clk_get(dev, "pclk"); in csi2dc_probe()
668 if (IS_ERR(csi2dc->pclk)) { in csi2dc_probe()
669 ret = PTR_ERR(csi2dc->pclk); in csi2dc_probe()
674 csi2dc->scck = devm_clk_get(dev, "scck"); in csi2dc_probe()
675 if (IS_ERR(csi2dc->scck)) { in csi2dc_probe()
676 ret = PTR_ERR(csi2dc->scck); in csi2dc_probe()
681 v4l2_subdev_init(&csi2dc->csi2dc_sd, &csi2dc_subdev_ops); in csi2dc_probe()
683 csi2dc->csi2dc_sd.owner = THIS_MODULE; in csi2dc_probe()
684 csi2dc->csi2dc_sd.dev = dev; in csi2dc_probe()
685 snprintf(csi2dc->csi2dc_sd.name, sizeof(csi2dc->csi2dc_sd.name), in csi2dc_probe()
686 "csi2dc"); in csi2dc_probe()
688 csi2dc->csi2dc_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in csi2dc_probe()
689 csi2dc->csi2dc_sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in csi2dc_probe()
690 csi2dc->csi2dc_sd.entity.ops = &csi2dc_entity_ops; in csi2dc_probe()
692 platform_set_drvdata(pdev, csi2dc); in csi2dc_probe()
694 ret = csi2dc_of_parse(csi2dc, dev->of_node); in csi2dc_probe()
698 csi2dc->pads[CSI2DC_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in csi2dc_probe()
699 if (csi2dc->video_pipe) in csi2dc_probe()
700 csi2dc->pads[CSI2DC_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in csi2dc_probe()
702 ret = media_entity_pads_init(&csi2dc->csi2dc_sd.entity, in csi2dc_probe()
703 csi2dc->video_pipe ? CSI2DC_PADS_NUM : 1, in csi2dc_probe()
704 csi2dc->pads); in csi2dc_probe()
710 csi2dc_default_format(csi2dc); in csi2dc_probe()
713 ret = csi2dc_power(csi2dc, true); in csi2dc_probe()
719 ver = csi2dc_readl(csi2dc, CSI2DC_VERSION); in csi2dc_probe()
726 ret = v4l2_async_register_subdev(&csi2dc->csi2dc_sd); in csi2dc_probe()
728 dev_err(csi2dc->dev, "failed to register the subdevice\n"); in csi2dc_probe()
732 dev_info(dev, "Microchip CSI2DC version %x\n", ver); in csi2dc_probe()
737 v4l2_async_nf_cleanup(&csi2dc->notifier); in csi2dc_probe()
739 media_entity_cleanup(&csi2dc->csi2dc_sd.entity); in csi2dc_probe()
746 struct csi2dc_device *csi2dc = platform_get_drvdata(pdev); in csi2dc_remove() local
750 v4l2_async_unregister_subdev(&csi2dc->csi2dc_sd); in csi2dc_remove()
751 v4l2_async_nf_unregister(&csi2dc->notifier); in csi2dc_remove()
752 v4l2_async_nf_cleanup(&csi2dc->notifier); in csi2dc_remove()
753 media_entity_cleanup(&csi2dc->csi2dc_sd.entity); in csi2dc_remove()
760 struct csi2dc_device *csi2dc = dev_get_drvdata(dev); in csi2dc_runtime_suspend() local
762 return csi2dc_power(csi2dc, false); in csi2dc_runtime_suspend()
767 struct csi2dc_device *csi2dc = dev_get_drvdata(dev); in csi2dc_runtime_resume() local
769 return csi2dc_power(csi2dc, true); in csi2dc_runtime_resume()
777 { .compatible = "microchip,sama7g5-csi2dc" },
787 .name = "microchip-csi2dc",