Lines Matching full:isp
5 * Driver for Renesas R-Car ISP Channel Selector
7 * The ISP hardware is capable of more than just channel selection, features
187 static void risp_write(struct rcar_isp *isp, u32 offset, u32 value) in risp_write() argument
189 iowrite32(value, isp->base + offset); in risp_write()
192 static u32 risp_read(struct rcar_isp *isp, u32 offset) in risp_read() argument
194 return ioread32(isp->base + offset); in risp_read()
197 static int risp_power_on(struct rcar_isp *isp) in risp_power_on() argument
201 ret = pm_runtime_resume_and_get(isp->dev); in risp_power_on()
205 ret = reset_control_deassert(isp->rstc); in risp_power_on()
207 pm_runtime_put(isp->dev); in risp_power_on()
214 static void risp_power_off(struct rcar_isp *isp) in risp_power_off() argument
216 reset_control_assert(isp->rstc); in risp_power_off()
217 pm_runtime_put(isp->dev); in risp_power_off()
220 static int risp_start(struct rcar_isp *isp, struct v4l2_subdev_state *state) in risp_start() argument
234 dev_err(isp->dev, "Unsupported bus format\n"); in risp_start()
238 ret = risp_power_on(isp); in risp_start()
240 dev_err(isp->dev, "Failed to power on ISP\n"); in risp_start()
245 if (isp->csi_input == RISP_CSI_INPUT1) in risp_start()
248 risp_write(isp, ISPINPUTSEL0_REG, in risp_start()
249 risp_read(isp, ISPINPUTSEL0_REG) | sel_csi); in risp_start()
256 risp_write(isp, ISPCS_FILTER_ID_CH_REG(ch), BIT(vc)); in risp_start()
257 risp_write(isp, ISPCS_DT_CODE03_CH_REG(ch), in risp_start()
265 risp_write(isp, ISPPROCMODE_DT_REG(format->datatype), in risp_start()
271 /* Start ISP. */ in risp_start()
272 risp_write(isp, ISPSTART_REG, ISPSTART_START); in risp_start()
274 ret = v4l2_subdev_enable_streams(isp->remote, isp->remote_pad, in risp_start()
277 risp_power_off(isp); in risp_start()
282 static void risp_stop(struct rcar_isp *isp) in risp_stop() argument
284 v4l2_subdev_disable_streams(isp->remote, isp->remote_pad, BIT_ULL(0)); in risp_stop()
286 /* Stop ISP. */ in risp_stop()
287 risp_write(isp, ISPSTART_REG, ISPSTART_STOP); in risp_stop()
289 risp_power_off(isp); in risp_stop()
296 struct rcar_isp *isp = sd_to_isp(sd); in risp_enable_streams() local
302 if (!isp->remote) in risp_enable_streams()
305 if (isp->stream_count == 0) { in risp_enable_streams()
306 ret = risp_start(isp, state); in risp_enable_streams()
311 isp->stream_count += 1; in risp_enable_streams()
320 struct rcar_isp *isp = sd_to_isp(sd); in risp_disable_streams() local
325 if (!isp->remote) in risp_disable_streams()
328 if (isp->stream_count == 1) in risp_disable_streams()
329 risp_stop(isp); in risp_disable_streams()
331 isp->stream_count -= 1; in risp_disable_streams()
376 struct rcar_isp *isp = notifier_to_isp(notifier); in risp_notify_bound() local
382 dev_err(isp->dev, "Failed to find pad for %s\n", subdev->name); in risp_notify_bound()
386 isp->remote = subdev; in risp_notify_bound()
387 isp->remote_pad = pad; in risp_notify_bound()
389 dev_dbg(isp->dev, "Bound %s pad: %d\n", subdev->name, pad); in risp_notify_bound()
392 &isp->subdev.entity, 0, in risp_notify_bound()
401 struct rcar_isp *isp = notifier_to_isp(notifier); in risp_notify_unbind() local
403 isp->remote = NULL; in risp_notify_unbind()
405 dev_dbg(isp->dev, "Unbind %s\n", subdev->name); in risp_notify_unbind()
413 static int risp_parse_dt(struct rcar_isp *isp) in risp_parse_dt() argument
422 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(isp->dev), in risp_parse_dt()
429 dev_err(isp->dev, "Not connected to subdevice\n"); in risp_parse_dt()
434 isp->csi_input = RISP_CSI_INPUT1; in risp_parse_dt()
439 dev_dbg(isp->dev, "Found '%pOF'\n", to_of_node(fwnode)); in risp_parse_dt()
441 v4l2_async_subdev_nf_init(&isp->notifier, &isp->subdev); in risp_parse_dt()
442 isp->notifier.ops = &risp_notify_ops; in risp_parse_dt()
444 asd = v4l2_async_nf_add_fwnode(&isp->notifier, fwnode, in risp_parse_dt()
450 ret = v4l2_async_nf_register(&isp->notifier); in risp_parse_dt()
452 v4l2_async_nf_cleanup(&isp->notifier); in risp_parse_dt()
465 static int risp_probe_resources(struct rcar_isp *isp, in risp_probe_resources() argument
468 isp->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); in risp_probe_resources()
469 if (IS_ERR(isp->base)) in risp_probe_resources()
470 return PTR_ERR(isp->base); in risp_probe_resources()
472 isp->rstc = devm_reset_control_get(&pdev->dev, NULL); in risp_probe_resources()
474 return PTR_ERR_OR_ZERO(isp->rstc); in risp_probe_resources()
478 { .compatible = "renesas,r8a779a0-isp" },
479 { .compatible = "renesas,r8a779g0-isp" },
481 { .compatible = "renesas,rcar-gen4-isp" },
488 struct rcar_isp *isp; in risp_probe() local
492 isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); in risp_probe()
493 if (!isp) in risp_probe()
496 isp->dev = &pdev->dev; in risp_probe()
498 ret = risp_probe_resources(isp, pdev); in risp_probe()
500 dev_err(isp->dev, "Failed to get resources\n"); in risp_probe()
504 platform_set_drvdata(pdev, isp); in risp_probe()
508 ret = risp_parse_dt(isp); in risp_probe()
512 isp->subdev.owner = THIS_MODULE; in risp_probe()
513 isp->subdev.dev = &pdev->dev; in risp_probe()
514 v4l2_subdev_init(&isp->subdev, &rcar_isp_subdev_ops); in risp_probe()
515 v4l2_set_subdevdata(&isp->subdev, &pdev->dev); in risp_probe()
516 snprintf(isp->subdev.name, sizeof(isp->subdev.name), "%s %s", in risp_probe()
518 isp->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; in risp_probe()
520 isp->subdev.entity.function = MEDIA_ENT_F_VID_MUX; in risp_probe()
521 isp->subdev.entity.ops = &risp_entity_ops; in risp_probe()
523 isp->pads[RCAR_ISP_SINK].flags = MEDIA_PAD_FL_SINK; in risp_probe()
525 isp->pads[i].flags = MEDIA_PAD_FL_SOURCE; in risp_probe()
527 ret = media_entity_pads_init(&isp->subdev.entity, RCAR_ISP_NUM_PADS, in risp_probe()
528 isp->pads); in risp_probe()
532 ret = v4l2_subdev_init_finalize(&isp->subdev); in risp_probe()
536 ret = v4l2_async_register_subdev(&isp->subdev); in risp_probe()
540 dev_info(isp->dev, "Using CSI-2 input: %u\n", isp->csi_input); in risp_probe()
545 v4l2_subdev_cleanup(&isp->subdev); in risp_probe()
547 v4l2_async_nf_unregister(&isp->notifier); in risp_probe()
548 v4l2_async_nf_cleanup(&isp->notifier); in risp_probe()
557 struct rcar_isp *isp = platform_get_drvdata(pdev); in risp_remove() local
559 v4l2_async_nf_unregister(&isp->notifier); in risp_remove()
560 v4l2_async_nf_cleanup(&isp->notifier); in risp_remove()
562 v4l2_async_unregister_subdev(&isp->subdev); in risp_remove()
563 v4l2_subdev_cleanup(&isp->subdev); in risp_remove()
570 .name = "rcar-isp",
581 MODULE_DESCRIPTION("Renesas R-Car ISP Channel Selector driver");