Lines Matching full:csi2dc

3  * Microchip CSI2 Demux Controller (CSI2DC) driver
109 * struct csi2dc_format - CSI2DC format type struct
156 * struct csi2dc_device - CSI2DC device driver data/config struct
158 * @csi2dc_sd: v4l2 subdevice for the csi2dc device
159 * This is the subdevice that the csi2dc device itself
161 * @dev: struct device for this csi2dc device
170 * @pads: Media entity pads for the csi2dc subdevice
176 * subdevice to the csi2dc subdevice
178 * csi2dc subdevice
180 * to the csi2dc subdevice sink pad.
230 struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd); in csi2dc_get_fmt() local
241 format->format = csi2dc->format; in csi2dc_get_fmt()
250 struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd); in csi2dc_set_fmt() local
273 dev_dbg(csi2dc->dev, in csi2dc_set_fmt()
274 "CSI2DC unsupported format 0x%x, defaulting to 0x%x\n", in csi2dc_set_fmt()
296 csi2dc->format = req_fmt->format; in csi2dc_set_fmt()
299 csi2dc->cur_fmt = try_fmt; in csi2dc_set_fmt()
301 dev_dbg(csi2dc->dev, "new format set: 0x%x @%dx%d\n", in csi2dc_set_fmt()
302 csi2dc->format.code, csi2dc->format.width, in csi2dc_set_fmt()
303 csi2dc->format.height); in csi2dc_set_fmt()
308 static int csi2dc_power(struct csi2dc_device *csi2dc, int on) in csi2dc_power() argument
313 ret = clk_prepare_enable(csi2dc->pclk); in csi2dc_power()
315 dev_err(csi2dc->dev, "failed to enable pclk:%d\n", ret); in csi2dc_power()
319 ret = clk_prepare_enable(csi2dc->scck); in csi2dc_power()
321 dev_err(csi2dc->dev, "failed to enable scck:%d\n", ret); in csi2dc_power()
322 clk_disable_unprepare(csi2dc->pclk); in csi2dc_power()
327 csi2dc_writel(csi2dc, CSI2DC_GCTLR, CSI2DC_GCTLR_SWRST); in csi2dc_power()
330 csi2dc_writel(csi2dc, CSI2DC_GCTLR, 0); in csi2dc_power()
332 clk_disable_unprepare(csi2dc->scck); in csi2dc_power()
333 clk_disable_unprepare(csi2dc->pclk); in csi2dc_power()
339 static int csi2dc_get_mbus_config(struct csi2dc_device *csi2dc) in csi2dc_get_mbus_config() argument
344 ret = v4l2_subdev_call(csi2dc->input_sd, pad, get_mbus_config, in csi2dc_get_mbus_config()
345 csi2dc->remote_pad, &mbus_config); in csi2dc_get_mbus_config()
347 dev_dbg(csi2dc->dev, in csi2dc_get_mbus_config()
353 dev_err(csi2dc->dev, in csi2dc_get_mbus_config()
358 dev_dbg(csi2dc->dev, "subdev sending on channel %d\n", csi2dc->vc); in csi2dc_get_mbus_config()
360 csi2dc->clk_gated = mbus_config.bus.parallel.flags & in csi2dc_get_mbus_config()
363 dev_dbg(csi2dc->dev, "mbus_config: %s clock\n", in csi2dc_get_mbus_config()
364 csi2dc->clk_gated ? "gated" : "free running"); in csi2dc_get_mbus_config()
369 static void csi2dc_vp_update(struct csi2dc_device *csi2dc) in csi2dc_vp_update() argument
373 if (!csi2dc->video_pipe) { in csi2dc_vp_update()
374 dev_err(csi2dc->dev, "video pipeline unavailable\n"); in csi2dc_vp_update()
378 if (csi2dc->parallel_mode) { in csi2dc_vp_update()
380 gcfg = csi2dc_readl(csi2dc, CSI2DC_GCFG); in csi2dc_vp_update()
382 csi2dc_writel(csi2dc, CSI2DC_GCFG, gcfg); in csi2dc_vp_update()
388 csi2dc_writel(csi2dc, CSI2DC_GCFG, in csi2dc_vp_update()
390 (csi2dc->clk_gated ? 0 : CSI2DC_GCFG_MIPIFRN)); in csi2dc_vp_update()
392 vp = CSI2DC_VPCFG_DT(csi2dc->cur_fmt->dt) & CSI2DC_VPCFG_DT_MASK; in csi2dc_vp_update()
393 vp |= CSI2DC_VPCFG_VC(csi2dc->vc) & CSI2DC_VPCFG_VC_MASK; in csi2dc_vp_update()
400 csi2dc_writel(csi2dc, CSI2DC_VPCFG, vp); in csi2dc_vp_update()
401 csi2dc_writel(csi2dc, CSI2DC_VPE, CSI2DC_VPE_ENABLE); in csi2dc_vp_update()
402 csi2dc_writel(csi2dc, CSI2DC_PU, CSI2DC_PU_VP); in csi2dc_vp_update()
407 struct csi2dc_device *csi2dc = csi2dc_sd_to_csi2dc_device(csi2dc_sd); in csi2dc_s_stream() local
411 ret = pm_runtime_resume_and_get(csi2dc->dev); in csi2dc_s_stream()
415 csi2dc_get_mbus_config(csi2dc); in csi2dc_s_stream()
417 csi2dc_vp_update(csi2dc); in csi2dc_s_stream()
419 return v4l2_subdev_call(csi2dc->input_sd, video, s_stream, in csi2dc_s_stream()
423 dev_dbg(csi2dc->dev, in csi2dc_s_stream()
425 csi2dc_readl(csi2dc, CSI2DC_VPCOL), in csi2dc_s_stream()
426 csi2dc_readl(csi2dc, CSI2DC_VPROW), in csi2dc_s_stream()
427 csi2dc_readl(csi2dc, CSI2DC_VPISR)); in csi2dc_s_stream()
430 ret = v4l2_subdev_call(csi2dc->input_sd, video, s_stream, false); in csi2dc_s_stream()
432 pm_runtime_put_sync(csi2dc->dev); in csi2dc_s_stream()
482 struct csi2dc_device *csi2dc = container_of(notifier, in csi2dc_async_bound() local
487 csi2dc->input_sd = subdev; in csi2dc_async_bound()
492 dev_err(csi2dc->dev, "Failed to find pad for %s\n", in csi2dc_async_bound()
497 csi2dc->remote_pad = pad; in csi2dc_async_bound()
499 ret = media_create_pad_link(&csi2dc->input_sd->entity, in csi2dc_async_bound()
500 csi2dc->remote_pad, in csi2dc_async_bound()
501 &csi2dc->csi2dc_sd.entity, 0, in csi2dc_async_bound()
504 dev_err(csi2dc->dev, in csi2dc_async_bound()
506 csi2dc->input_sd->entity.name, in csi2dc_async_bound()
507 csi2dc->csi2dc_sd.entity.name); in csi2dc_async_bound()
511 dev_dbg(csi2dc->dev, "link with %s pad: %d\n", in csi2dc_async_bound()
512 csi2dc->input_sd->name, csi2dc->remote_pad); in csi2dc_async_bound()
521 static int csi2dc_prepare_notifier(struct csi2dc_device *csi2dc, in csi2dc_prepare_notifier() argument
527 v4l2_async_subdev_nf_init(&csi2dc->notifier, &csi2dc->csi2dc_sd); in csi2dc_prepare_notifier()
529 asd = v4l2_async_nf_add_fwnode_remote(&csi2dc->notifier, in csi2dc_prepare_notifier()
537 dev_err(csi2dc->dev, in csi2dc_prepare_notifier()
540 v4l2_async_nf_cleanup(&csi2dc->notifier); in csi2dc_prepare_notifier()
544 csi2dc->notifier.ops = &csi2dc_async_ops; in csi2dc_prepare_notifier()
546 ret = v4l2_async_nf_register(&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()
682 csi2dc->csi2dc_sd.internal_ops = &csi2dc_internal_ops; in csi2dc_probe()
684 csi2dc->csi2dc_sd.owner = THIS_MODULE; in csi2dc_probe()
685 csi2dc->csi2dc_sd.dev = dev; in csi2dc_probe()
686 snprintf(csi2dc->csi2dc_sd.name, sizeof(csi2dc->csi2dc_sd.name), in csi2dc_probe()
687 "csi2dc"); in csi2dc_probe()
689 csi2dc->csi2dc_sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in csi2dc_probe()
690 csi2dc->csi2dc_sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in csi2dc_probe()
691 csi2dc->csi2dc_sd.entity.ops = &csi2dc_entity_ops; in csi2dc_probe()
693 platform_set_drvdata(pdev, csi2dc); in csi2dc_probe()
695 ret = csi2dc_of_parse(csi2dc, dev->of_node); in csi2dc_probe()
699 csi2dc->pads[CSI2DC_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in csi2dc_probe()
700 if (csi2dc->video_pipe) in csi2dc_probe()
701 csi2dc->pads[CSI2DC_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in csi2dc_probe()
703 ret = media_entity_pads_init(&csi2dc->csi2dc_sd.entity, in csi2dc_probe()
704 csi2dc->video_pipe ? CSI2DC_PADS_NUM : 1, in csi2dc_probe()
705 csi2dc->pads); in csi2dc_probe()
711 csi2dc_default_format(csi2dc); in csi2dc_probe()
714 ret = csi2dc_power(csi2dc, true); in csi2dc_probe()
720 ver = csi2dc_readl(csi2dc, CSI2DC_VERSION); in csi2dc_probe()
727 ret = v4l2_async_register_subdev(&csi2dc->csi2dc_sd); in csi2dc_probe()
729 dev_err(csi2dc->dev, "failed to register the subdevice\n"); in csi2dc_probe()
733 dev_info(dev, "Microchip CSI2DC version %x\n", ver); in csi2dc_probe()
738 v4l2_async_nf_cleanup(&csi2dc->notifier); in csi2dc_probe()
740 media_entity_cleanup(&csi2dc->csi2dc_sd.entity); in csi2dc_probe()
747 struct csi2dc_device *csi2dc = platform_get_drvdata(pdev); in csi2dc_remove() local
751 v4l2_async_unregister_subdev(&csi2dc->csi2dc_sd); in csi2dc_remove()
752 v4l2_async_nf_unregister(&csi2dc->notifier); in csi2dc_remove()
753 v4l2_async_nf_cleanup(&csi2dc->notifier); in csi2dc_remove()
754 media_entity_cleanup(&csi2dc->csi2dc_sd.entity); in csi2dc_remove()
759 struct csi2dc_device *csi2dc = dev_get_drvdata(dev); in csi2dc_runtime_suspend() local
761 return csi2dc_power(csi2dc, false); in csi2dc_runtime_suspend()
766 struct csi2dc_device *csi2dc = dev_get_drvdata(dev); in csi2dc_runtime_resume() local
768 return csi2dc_power(csi2dc, true); in csi2dc_runtime_resume()
776 { .compatible = "microchip,sama7g5-csi2dc" },
786 .name = "microchip-csi2dc",