• Home
  • Raw
  • Download

Lines Matching full:csi2rx

95 static void csi2rx_reset(struct csi2rx_priv *csi2rx)  in csi2rx_reset()  argument
98 csi2rx->base + CSI2RX_SOFT_RESET_REG); in csi2rx_reset()
102 writel(0, csi2rx->base + CSI2RX_SOFT_RESET_REG); in csi2rx_reset()
105 static int csi2rx_start(struct csi2rx_priv *csi2rx) in csi2rx_start() argument
112 ret = clk_prepare_enable(csi2rx->p_clk); in csi2rx_start()
116 csi2rx_reset(csi2rx); in csi2rx_start()
118 reg = csi2rx->num_lanes << 8; in csi2rx_start()
119 for (i = 0; i < csi2rx->num_lanes; i++) { in csi2rx_start()
120 reg |= CSI2RX_STATIC_CFG_DLANE_MAP(i, csi2rx->lanes[i]); in csi2rx_start()
121 set_bit(csi2rx->lanes[i], &lanes_used); in csi2rx_start()
130 for (i = csi2rx->num_lanes; i < csi2rx->max_lanes; i++) { in csi2rx_start()
132 csi2rx->max_lanes); in csi2rx_start()
137 writel(reg, csi2rx->base + CSI2RX_STATIC_CFG_REG); in csi2rx_start()
139 ret = v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, true); in csi2rx_start()
153 for (i = 0; i < csi2rx->max_streams; i++) { in csi2rx_start()
154 ret = clk_prepare_enable(csi2rx->pixel_clk[i]); in csi2rx_start()
159 csi2rx->base + CSI2RX_STREAM_CFG_REG(i)); in csi2rx_start()
163 csi2rx->base + CSI2RX_STREAM_DATA_CFG_REG(i)); in csi2rx_start()
166 csi2rx->base + CSI2RX_STREAM_CTRL_REG(i)); in csi2rx_start()
169 ret = clk_prepare_enable(csi2rx->sys_clk); in csi2rx_start()
173 clk_disable_unprepare(csi2rx->p_clk); in csi2rx_start()
179 clk_disable_unprepare(csi2rx->pixel_clk[i - 1]); in csi2rx_start()
182 clk_disable_unprepare(csi2rx->p_clk); in csi2rx_start()
187 static void csi2rx_stop(struct csi2rx_priv *csi2rx) in csi2rx_stop() argument
191 clk_prepare_enable(csi2rx->p_clk); in csi2rx_stop()
192 clk_disable_unprepare(csi2rx->sys_clk); in csi2rx_stop()
194 for (i = 0; i < csi2rx->max_streams; i++) { in csi2rx_stop()
195 writel(0, csi2rx->base + CSI2RX_STREAM_CTRL_REG(i)); in csi2rx_stop()
197 clk_disable_unprepare(csi2rx->pixel_clk[i]); in csi2rx_stop()
200 clk_disable_unprepare(csi2rx->p_clk); in csi2rx_stop()
202 if (v4l2_subdev_call(csi2rx->source_subdev, video, s_stream, false)) in csi2rx_stop()
203 dev_warn(csi2rx->dev, "Couldn't disable our subdev\n"); in csi2rx_stop()
208 struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); in csi2rx_s_stream() local
211 mutex_lock(&csi2rx->lock); in csi2rx_s_stream()
218 if (!csi2rx->count) { in csi2rx_s_stream()
219 ret = csi2rx_start(csi2rx); in csi2rx_s_stream()
224 csi2rx->count++; in csi2rx_s_stream()
226 csi2rx->count--; in csi2rx_s_stream()
231 if (!csi2rx->count) in csi2rx_s_stream()
232 csi2rx_stop(csi2rx); in csi2rx_s_stream()
236 mutex_unlock(&csi2rx->lock); in csi2rx_s_stream()
253 struct csi2rx_priv *csi2rx = v4l2_subdev_to_csi2rx(subdev); in csi2rx_async_bound() local
255 csi2rx->source_pad = media_entity_get_fwnode_pad(&s_subdev->entity, in csi2rx_async_bound()
258 if (csi2rx->source_pad < 0) { in csi2rx_async_bound()
259 dev_err(csi2rx->dev, "Couldn't find output pad for subdev %s\n", in csi2rx_async_bound()
261 return csi2rx->source_pad; in csi2rx_async_bound()
264 csi2rx->source_subdev = s_subdev; in csi2rx_async_bound()
266 dev_dbg(csi2rx->dev, "Bound %s pad: %d\n", s_subdev->name, in csi2rx_async_bound()
267 csi2rx->source_pad); in csi2rx_async_bound()
269 return media_create_pad_link(&csi2rx->source_subdev->entity, in csi2rx_async_bound()
270 csi2rx->source_pad, in csi2rx_async_bound()
271 &csi2rx->subdev.entity, 0, in csi2rx_async_bound()
280 static int csi2rx_get_resources(struct csi2rx_priv *csi2rx, in csi2rx_get_resources() argument
288 csi2rx->base = devm_ioremap_resource(&pdev->dev, res); in csi2rx_get_resources()
289 if (IS_ERR(csi2rx->base)) in csi2rx_get_resources()
290 return PTR_ERR(csi2rx->base); in csi2rx_get_resources()
292 csi2rx->sys_clk = devm_clk_get(&pdev->dev, "sys_clk"); in csi2rx_get_resources()
293 if (IS_ERR(csi2rx->sys_clk)) { in csi2rx_get_resources()
295 return PTR_ERR(csi2rx->sys_clk); in csi2rx_get_resources()
298 csi2rx->p_clk = devm_clk_get(&pdev->dev, "p_clk"); in csi2rx_get_resources()
299 if (IS_ERR(csi2rx->p_clk)) { in csi2rx_get_resources()
301 return PTR_ERR(csi2rx->p_clk); in csi2rx_get_resources()
304 csi2rx->dphy = devm_phy_optional_get(&pdev->dev, "dphy"); in csi2rx_get_resources()
305 if (IS_ERR(csi2rx->dphy)) { in csi2rx_get_resources()
307 return PTR_ERR(csi2rx->dphy); in csi2rx_get_resources()
314 if (csi2rx->dphy) { in csi2rx_get_resources()
319 clk_prepare_enable(csi2rx->p_clk); in csi2rx_get_resources()
320 dev_cfg = readl(csi2rx->base + CSI2RX_DEVICE_CFG_REG); in csi2rx_get_resources()
321 clk_disable_unprepare(csi2rx->p_clk); in csi2rx_get_resources()
323 csi2rx->max_lanes = dev_cfg & 7; in csi2rx_get_resources()
324 if (csi2rx->max_lanes > CSI2RX_LANES_MAX) { in csi2rx_get_resources()
326 csi2rx->max_lanes); in csi2rx_get_resources()
330 csi2rx->max_streams = (dev_cfg >> 4) & 7; in csi2rx_get_resources()
331 if (csi2rx->max_streams > CSI2RX_STREAMS_MAX) { in csi2rx_get_resources()
333 csi2rx->max_streams); in csi2rx_get_resources()
337 csi2rx->has_internal_dphy = dev_cfg & BIT(3) ? true : false; in csi2rx_get_resources()
343 if (csi2rx->has_internal_dphy) { in csi2rx_get_resources()
348 for (i = 0; i < csi2rx->max_streams; i++) { in csi2rx_get_resources()
352 csi2rx->pixel_clk[i] = devm_clk_get(&pdev->dev, clk_name); in csi2rx_get_resources()
353 if (IS_ERR(csi2rx->pixel_clk[i])) { in csi2rx_get_resources()
355 return PTR_ERR(csi2rx->pixel_clk[i]); in csi2rx_get_resources()
362 static int csi2rx_parse_dt(struct csi2rx_priv *csi2rx) in csi2rx_parse_dt() argument
369 ep = of_graph_get_endpoint_by_regs(csi2rx->dev->of_node, 0, 0); in csi2rx_parse_dt()
376 dev_err(csi2rx->dev, "Could not parse v4l2 endpoint\n"); in csi2rx_parse_dt()
382 dev_err(csi2rx->dev, "Unsupported media bus type: 0x%x\n", in csi2rx_parse_dt()
388 memcpy(csi2rx->lanes, v4l2_ep.bus.mipi_csi2.data_lanes, in csi2rx_parse_dt()
389 sizeof(csi2rx->lanes)); in csi2rx_parse_dt()
390 csi2rx->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes; in csi2rx_parse_dt()
391 if (csi2rx->num_lanes > csi2rx->max_lanes) { in csi2rx_parse_dt()
392 dev_err(csi2rx->dev, "Unsupported number of data-lanes: %d\n", in csi2rx_parse_dt()
393 csi2rx->num_lanes); in csi2rx_parse_dt()
398 csi2rx->asd.match.fwnode = fwnode_graph_get_remote_port_parent(fwh); in csi2rx_parse_dt()
399 csi2rx->asd.match_type = V4L2_ASYNC_MATCH_FWNODE; in csi2rx_parse_dt()
402 v4l2_async_notifier_init(&csi2rx->notifier); in csi2rx_parse_dt()
404 ret = v4l2_async_notifier_add_subdev(&csi2rx->notifier, &csi2rx->asd); in csi2rx_parse_dt()
406 fwnode_handle_put(csi2rx->asd.match.fwnode); in csi2rx_parse_dt()
410 csi2rx->notifier.ops = &csi2rx_notifier_ops; in csi2rx_parse_dt()
412 ret = v4l2_async_subdev_notifier_register(&csi2rx->subdev, in csi2rx_parse_dt()
413 &csi2rx->notifier); in csi2rx_parse_dt()
415 v4l2_async_notifier_cleanup(&csi2rx->notifier); in csi2rx_parse_dt()
422 struct csi2rx_priv *csi2rx; in csi2rx_probe() local
426 csi2rx = kzalloc(sizeof(*csi2rx), GFP_KERNEL); in csi2rx_probe()
427 if (!csi2rx) in csi2rx_probe()
429 platform_set_drvdata(pdev, csi2rx); in csi2rx_probe()
430 csi2rx->dev = &pdev->dev; in csi2rx_probe()
431 mutex_init(&csi2rx->lock); in csi2rx_probe()
433 ret = csi2rx_get_resources(csi2rx, pdev); in csi2rx_probe()
437 ret = csi2rx_parse_dt(csi2rx); in csi2rx_probe()
441 csi2rx->subdev.owner = THIS_MODULE; in csi2rx_probe()
442 csi2rx->subdev.dev = &pdev->dev; in csi2rx_probe()
443 v4l2_subdev_init(&csi2rx->subdev, &csi2rx_subdev_ops); in csi2rx_probe()
444 v4l2_set_subdevdata(&csi2rx->subdev, &pdev->dev); in csi2rx_probe()
445 snprintf(csi2rx->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.%s", in csi2rx_probe()
449 csi2rx->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in csi2rx_probe()
450 csi2rx->pads[CSI2RX_PAD_SINK].flags = MEDIA_PAD_FL_SINK; in csi2rx_probe()
452 csi2rx->pads[i].flags = MEDIA_PAD_FL_SOURCE; in csi2rx_probe()
454 ret = media_entity_pads_init(&csi2rx->subdev.entity, CSI2RX_PAD_MAX, in csi2rx_probe()
455 csi2rx->pads); in csi2rx_probe()
459 ret = v4l2_async_register_subdev(&csi2rx->subdev); in csi2rx_probe()
464 "Probed CSI2RX with %u/%u lanes, %u streams, %s D-PHY\n", in csi2rx_probe()
465 csi2rx->num_lanes, csi2rx->max_lanes, csi2rx->max_streams, in csi2rx_probe()
466 csi2rx->has_internal_dphy ? "internal" : "no"); in csi2rx_probe()
471 v4l2_async_notifier_cleanup(&csi2rx->notifier); in csi2rx_probe()
473 kfree(csi2rx); in csi2rx_probe()
479 struct csi2rx_priv *csi2rx = platform_get_drvdata(pdev); in csi2rx_remove() local
481 v4l2_async_unregister_subdev(&csi2rx->subdev); in csi2rx_remove()
482 kfree(csi2rx); in csi2rx_remove()
488 { .compatible = "cdns,csi2rx" },
498 .name = "cdns-csi2rx",