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
140 static void risp_write(struct rcar_isp *isp, u32 offset, u32 value) in risp_write() argument
142 iowrite32(value, isp->base + offset); in risp_write()
145 static u32 risp_read(struct rcar_isp *isp, u32 offset) in risp_read() argument
147 return ioread32(isp->base + offset); in risp_read()
150 static int risp_power_on(struct rcar_isp *isp) in risp_power_on() argument
154 ret = pm_runtime_resume_and_get(isp->dev); in risp_power_on()
158 ret = reset_control_deassert(isp->rstc); in risp_power_on()
160 pm_runtime_put(isp->dev); in risp_power_on()
167 static void risp_power_off(struct rcar_isp *isp) in risp_power_off() argument
169 reset_control_assert(isp->rstc); in risp_power_off()
170 pm_runtime_put(isp->dev); in risp_power_off()
173 static int risp_start(struct rcar_isp *isp) in risp_start() argument
180 format = risp_code_to_fmt(isp->mf.code); in risp_start()
182 dev_err(isp->dev, "Unsupported bus format\n"); in risp_start()
186 ret = risp_power_on(isp); in risp_start()
188 dev_err(isp->dev, "Failed to power on ISP\n"); in risp_start()
193 if (isp->csi_input == RISP_CSI_INPUT1) in risp_start()
196 risp_write(isp, ISPINPUTSEL0_REG, in risp_start()
197 risp_read(isp, ISPINPUTSEL0_REG) | sel_csi); in risp_start()
204 risp_write(isp, ISPCS_FILTER_ID_CH_REG(ch), BIT(vc)); in risp_start()
205 risp_write(isp, ISPCS_DT_CODE03_CH_REG(ch), in risp_start()
213 risp_write(isp, ISPPROCMODE_DT_REG(format->datatype), in risp_start()
219 /* Start ISP. */ in risp_start()
220 risp_write(isp, ISPSTART_REG, ISPSTART_START); in risp_start()
222 ret = v4l2_subdev_call(isp->remote, video, s_stream, 1); in risp_start()
224 risp_power_off(isp); in risp_start()
229 static void risp_stop(struct rcar_isp *isp) in risp_stop() argument
231 v4l2_subdev_call(isp->remote, video, s_stream, 0); in risp_stop()
233 /* Stop ISP. */ in risp_stop()
234 risp_write(isp, ISPSTART_REG, ISPSTART_STOP); in risp_stop()
236 risp_power_off(isp); in risp_stop()
241 struct rcar_isp *isp = sd_to_isp(sd); in risp_s_stream() local
244 mutex_lock(&isp->lock); in risp_s_stream()
246 if (!isp->remote) { in risp_s_stream()
251 if (enable && isp->stream_count == 0) { in risp_s_stream()
252 ret = risp_start(isp); in risp_s_stream()
255 } else if (!enable && isp->stream_count == 1) { in risp_s_stream()
256 risp_stop(isp); in risp_s_stream()
259 isp->stream_count += enable ? 1 : -1; in risp_s_stream()
261 mutex_unlock(&isp->lock); in risp_s_stream()
274 struct rcar_isp *isp = sd_to_isp(sd); in risp_set_pad_format() local
277 mutex_lock(&isp->lock); in risp_set_pad_format()
283 isp->mf = format->format; in risp_set_pad_format()
289 mutex_unlock(&isp->lock); in risp_set_pad_format()
298 struct rcar_isp *isp = sd_to_isp(sd); in risp_get_pad_format() local
300 mutex_lock(&isp->lock); in risp_get_pad_format()
303 format->format = isp->mf; in risp_get_pad_format()
307 mutex_unlock(&isp->lock); in risp_get_pad_format()
331 struct rcar_isp *isp = notifier_to_isp(notifier); in risp_notify_bound() local
337 dev_err(isp->dev, "Failed to find pad for %s\n", subdev->name); in risp_notify_bound()
341 isp->remote = subdev; in risp_notify_bound()
343 dev_dbg(isp->dev, "Bound %s pad: %d\n", subdev->name, pad); in risp_notify_bound()
346 &isp->subdev.entity, 0, in risp_notify_bound()
355 struct rcar_isp *isp = notifier_to_isp(notifier); in risp_notify_unbind() local
357 isp->remote = NULL; in risp_notify_unbind()
359 dev_dbg(isp->dev, "Unbind %s\n", subdev->name); in risp_notify_unbind()
367 static int risp_parse_dt(struct rcar_isp *isp) in risp_parse_dt() argument
376 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(isp->dev), in risp_parse_dt()
383 dev_err(isp->dev, "Not connected to subdevice\n"); in risp_parse_dt()
388 isp->csi_input = RISP_CSI_INPUT1; in risp_parse_dt()
393 dev_dbg(isp->dev, "Found '%pOF'\n", to_of_node(fwnode)); in risp_parse_dt()
395 v4l2_async_subdev_nf_init(&isp->notifier, &isp->subdev); in risp_parse_dt()
396 isp->notifier.ops = &risp_notify_ops; in risp_parse_dt()
398 asd = v4l2_async_nf_add_fwnode(&isp->notifier, fwnode, in risp_parse_dt()
404 ret = v4l2_async_nf_register(&isp->notifier); in risp_parse_dt()
406 v4l2_async_nf_cleanup(&isp->notifier); in risp_parse_dt()
419 static int risp_probe_resources(struct rcar_isp *isp, in risp_probe_resources() argument
422 isp->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); in risp_probe_resources()
423 if (IS_ERR(isp->base)) in risp_probe_resources()
424 return PTR_ERR(isp->base); in risp_probe_resources()
426 isp->rstc = devm_reset_control_get(&pdev->dev, NULL); in risp_probe_resources()
428 return PTR_ERR_OR_ZERO(isp->rstc); in risp_probe_resources()
432 { .compatible = "renesas,r8a779a0-isp" },
433 { .compatible = "renesas,r8a779g0-isp" },
440 struct rcar_isp *isp; in risp_probe() local
444 isp = devm_kzalloc(&pdev->dev, sizeof(*isp), GFP_KERNEL); in risp_probe()
445 if (!isp) in risp_probe()
448 isp->dev = &pdev->dev; in risp_probe()
450 mutex_init(&isp->lock); in risp_probe()
452 ret = risp_probe_resources(isp, pdev); in risp_probe()
454 dev_err(isp->dev, "Failed to get resources\n"); in risp_probe()
458 platform_set_drvdata(pdev, isp); in risp_probe()
462 ret = risp_parse_dt(isp); in risp_probe()
466 isp->subdev.owner = THIS_MODULE; in risp_probe()
467 isp->subdev.dev = &pdev->dev; in risp_probe()
468 v4l2_subdev_init(&isp->subdev, &rcar_isp_subdev_ops); in risp_probe()
469 v4l2_set_subdevdata(&isp->subdev, &pdev->dev); in risp_probe()
470 snprintf(isp->subdev.name, sizeof(isp->subdev.name), "%s %s", in risp_probe()
472 isp->subdev.flags = V4L2_SUBDEV_FL_HAS_DEVNODE; in risp_probe()
474 isp->subdev.entity.function = MEDIA_ENT_F_VID_MUX; in risp_probe()
475 isp->subdev.entity.ops = &risp_entity_ops; in risp_probe()
477 isp->pads[RCAR_ISP_SINK].flags = MEDIA_PAD_FL_SINK; in risp_probe()
479 isp->pads[i].flags = MEDIA_PAD_FL_SOURCE; in risp_probe()
481 ret = media_entity_pads_init(&isp->subdev.entity, RCAR_ISP_NUM_PADS, in risp_probe()
482 isp->pads); in risp_probe()
486 ret = v4l2_async_register_subdev(&isp->subdev); in risp_probe()
490 dev_info(isp->dev, "Using CSI-2 input: %u\n", isp->csi_input); in risp_probe()
494 v4l2_async_nf_unregister(&isp->notifier); in risp_probe()
495 v4l2_async_nf_cleanup(&isp->notifier); in risp_probe()
499 mutex_destroy(&isp->lock); in risp_probe()
506 struct rcar_isp *isp = platform_get_drvdata(pdev); in risp_remove() local
508 v4l2_async_nf_unregister(&isp->notifier); in risp_remove()
509 v4l2_async_nf_cleanup(&isp->notifier); in risp_remove()
511 v4l2_async_unregister_subdev(&isp->subdev); in risp_remove()
515 mutex_destroy(&isp->lock); in risp_remove()
520 .name = "rcar-isp",
531 MODULE_DESCRIPTION("Renesas R-Car ISP Channel Selector driver");