Lines Matching refs:csi2tx
88 void (*dphy_setup)(struct csi2tx_priv *csi2tx);
175 struct csi2tx_priv *csi2tx = v4l2_subdev_to_csi2tx(subdev); in __csi2tx_get_pad_format() local
181 return &csi2tx->pad_fmts[fmt->pad]; in __csi2tx_get_pad_format()
233 static void csi2tx_dphy_set_wakeup(struct csi2tx_priv *csi2tx) in csi2tx_dphy_set_wakeup() argument
236 csi2tx->base + CSI2TX_DPHY_CLK_WAKEUP_REG); in csi2tx_dphy_set_wakeup()
243 static void csi2tx_dphy_init_finish(struct csi2tx_priv *csi2tx, u32 reg) in csi2tx_dphy_init_finish() argument
251 for (i = 0; i < csi2tx->num_lanes; i++) in csi2tx_dphy_init_finish()
252 reg |= CSI2TX_DPHY_CFG_LANE_ENABLE(csi2tx->lanes[i] - 1); in csi2tx_dphy_init_finish()
253 writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG); in csi2tx_dphy_init_finish()
260 csi2tx->base + CSI2TX_DPHY_CFG_REG); in csi2tx_dphy_init_finish()
264 static void csi2tx_dphy_setup(struct csi2tx_priv *csi2tx) in csi2tx_dphy_setup() argument
269 csi2tx_dphy_set_wakeup(csi2tx); in csi2tx_dphy_setup()
273 for (i = 0; i < csi2tx->num_lanes; i++) in csi2tx_dphy_setup()
274 reg |= CSI2TX_DPHY_CFG_LANE_RESET(csi2tx->lanes[i] - 1); in csi2tx_dphy_setup()
275 writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG); in csi2tx_dphy_setup()
277 csi2tx_dphy_init_finish(csi2tx, reg); in csi2tx_dphy_setup()
281 static void csi2tx_v2_dphy_setup(struct csi2tx_priv *csi2tx) in csi2tx_v2_dphy_setup() argument
285 csi2tx_dphy_set_wakeup(csi2tx); in csi2tx_v2_dphy_setup()
289 writel(reg, csi2tx->base + CSI2TX_V2_DPHY_CFG_REG); in csi2tx_v2_dphy_setup()
291 csi2tx_dphy_init_finish(csi2tx, reg); in csi2tx_v2_dphy_setup()
294 static void csi2tx_reset(struct csi2tx_priv *csi2tx) in csi2tx_reset() argument
296 writel(CSI2TX_CONFIG_SRST_REQ, csi2tx->base + CSI2TX_CONFIG_REG); in csi2tx_reset()
301 static int csi2tx_start(struct csi2tx_priv *csi2tx) in csi2tx_start() argument
303 struct media_entity *entity = &csi2tx->subdev.entity; in csi2tx_start()
307 csi2tx_reset(csi2tx); in csi2tx_start()
309 writel(CSI2TX_CONFIG_CFG_REQ, csi2tx->base + CSI2TX_CONFIG_REG); in csi2tx_start()
313 if (csi2tx->vops && csi2tx->vops->dphy_setup) { in csi2tx_start()
314 csi2tx->vops->dphy_setup(csi2tx); in csi2tx_start()
337 struct media_pad *pad = &csi2tx->pads[i]; in csi2tx_start()
349 mfmt = &csi2tx->pad_fmts[pad_idx]; in csi2tx_start()
364 csi2tx->base + CSI2TX_DT_CFG_REG(stream)); in csi2tx_start()
368 csi2tx->base + CSI2TX_DT_FORMAT_REG(stream)); in csi2tx_start()
375 csi2tx->base + CSI2TX_STREAM_IF_CFG_REG(stream)); in csi2tx_start()
379 writel(0, csi2tx->base + CSI2TX_CONFIG_REG); in csi2tx_start()
384 static void csi2tx_stop(struct csi2tx_priv *csi2tx) in csi2tx_stop() argument
387 csi2tx->base + CSI2TX_CONFIG_REG); in csi2tx_stop()
392 struct csi2tx_priv *csi2tx = v4l2_subdev_to_csi2tx(subdev); in csi2tx_s_stream() local
395 mutex_lock(&csi2tx->lock); in csi2tx_s_stream()
402 if (!csi2tx->count) { in csi2tx_s_stream()
403 ret = csi2tx_start(csi2tx); in csi2tx_s_stream()
408 csi2tx->count++; in csi2tx_s_stream()
410 csi2tx->count--; in csi2tx_s_stream()
415 if (!csi2tx->count) in csi2tx_s_stream()
416 csi2tx_stop(csi2tx); in csi2tx_s_stream()
420 mutex_unlock(&csi2tx->lock); in csi2tx_s_stream()
433 static int csi2tx_get_resources(struct csi2tx_priv *csi2tx, in csi2tx_get_resources() argument
441 csi2tx->base = devm_ioremap_resource(&pdev->dev, res); in csi2tx_get_resources()
442 if (IS_ERR(csi2tx->base)) in csi2tx_get_resources()
443 return PTR_ERR(csi2tx->base); in csi2tx_get_resources()
445 csi2tx->p_clk = devm_clk_get(&pdev->dev, "p_clk"); in csi2tx_get_resources()
446 if (IS_ERR(csi2tx->p_clk)) { in csi2tx_get_resources()
448 return PTR_ERR(csi2tx->p_clk); in csi2tx_get_resources()
451 csi2tx->esc_clk = devm_clk_get(&pdev->dev, "esc_clk"); in csi2tx_get_resources()
452 if (IS_ERR(csi2tx->esc_clk)) { in csi2tx_get_resources()
454 return PTR_ERR(csi2tx->esc_clk); in csi2tx_get_resources()
457 clk_prepare_enable(csi2tx->p_clk); in csi2tx_get_resources()
458 dev_cfg = readl(csi2tx->base + CSI2TX_DEVICE_CONFIG_REG); in csi2tx_get_resources()
459 clk_disable_unprepare(csi2tx->p_clk); in csi2tx_get_resources()
461 csi2tx->max_lanes = dev_cfg & CSI2TX_DEVICE_CONFIG_LANES_MASK; in csi2tx_get_resources()
462 if (csi2tx->max_lanes > CSI2TX_LANES_MAX) { in csi2tx_get_resources()
464 csi2tx->max_lanes); in csi2tx_get_resources()
468 csi2tx->max_streams = (dev_cfg & CSI2TX_DEVICE_CONFIG_STREAMS_MASK) >> 4; in csi2tx_get_resources()
469 if (csi2tx->max_streams > CSI2TX_STREAMS_MAX) { in csi2tx_get_resources()
471 csi2tx->max_streams); in csi2tx_get_resources()
475 csi2tx->has_internal_dphy = !!(dev_cfg & CSI2TX_DEVICE_CONFIG_HAS_DPHY); in csi2tx_get_resources()
477 for (i = 0; i < csi2tx->max_streams; i++) { in csi2tx_get_resources()
481 csi2tx->pixel_clk[i] = devm_clk_get(&pdev->dev, clk_name); in csi2tx_get_resources()
482 if (IS_ERR(csi2tx->pixel_clk[i])) { in csi2tx_get_resources()
485 return PTR_ERR(csi2tx->pixel_clk[i]); in csi2tx_get_resources()
492 static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx) in csi2tx_check_lanes() argument
498 ep = of_graph_get_endpoint_by_regs(csi2tx->dev->of_node, 0, 0); in csi2tx_check_lanes()
504 dev_err(csi2tx->dev, "Could not parse v4l2 endpoint\n"); in csi2tx_check_lanes()
509 dev_err(csi2tx->dev, "Unsupported media bus type: 0x%x\n", in csi2tx_check_lanes()
515 csi2tx->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes; in csi2tx_check_lanes()
516 if (csi2tx->num_lanes > csi2tx->max_lanes) { in csi2tx_check_lanes()
517 dev_err(csi2tx->dev, in csi2tx_check_lanes()
523 for (i = 0; i < csi2tx->num_lanes; i++) { in csi2tx_check_lanes()
525 dev_err(csi2tx->dev, "Invalid lane[%d] number: %u\n", in csi2tx_check_lanes()
532 memcpy(csi2tx->lanes, v4l2_ep.bus.mipi_csi2.data_lanes, in csi2tx_check_lanes()
533 sizeof(csi2tx->lanes)); in csi2tx_check_lanes()
567 struct csi2tx_priv *csi2tx; in csi2tx_probe() local
572 csi2tx = kzalloc(sizeof(*csi2tx), GFP_KERNEL); in csi2tx_probe()
573 if (!csi2tx) in csi2tx_probe()
575 platform_set_drvdata(pdev, csi2tx); in csi2tx_probe()
576 mutex_init(&csi2tx->lock); in csi2tx_probe()
577 csi2tx->dev = &pdev->dev; in csi2tx_probe()
579 ret = csi2tx_get_resources(csi2tx, pdev); in csi2tx_probe()
584 csi2tx->vops = (struct csi2tx_vops *)of_id->data; in csi2tx_probe()
586 v4l2_subdev_init(&csi2tx->subdev, &csi2tx_subdev_ops); in csi2tx_probe()
587 csi2tx->subdev.owner = THIS_MODULE; in csi2tx_probe()
588 csi2tx->subdev.dev = &pdev->dev; in csi2tx_probe()
589 csi2tx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in csi2tx_probe()
590 snprintf(csi2tx->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.%s", in csi2tx_probe()
593 ret = csi2tx_check_lanes(csi2tx); in csi2tx_probe()
598 csi2tx->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in csi2tx_probe()
599 csi2tx->pads[CSI2TX_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE; in csi2tx_probe()
601 csi2tx->pads[i].flags = MEDIA_PAD_FL_SINK; in csi2tx_probe()
610 csi2tx->pad_fmts[i] = fmt_default; in csi2tx_probe()
612 ret = media_entity_pads_init(&csi2tx->subdev.entity, CSI2TX_PAD_MAX, in csi2tx_probe()
613 csi2tx->pads); in csi2tx_probe()
617 ret = v4l2_async_register_subdev(&csi2tx->subdev); in csi2tx_probe()
623 csi2tx->num_lanes, csi2tx->max_lanes, csi2tx->max_streams, in csi2tx_probe()
624 csi2tx->has_internal_dphy ? "internal" : "no"); in csi2tx_probe()
629 kfree(csi2tx); in csi2tx_probe()
635 struct csi2tx_priv *csi2tx = platform_get_drvdata(pdev); in csi2tx_remove() local
637 v4l2_async_unregister_subdev(&csi2tx->subdev); in csi2tx_remove()
638 kfree(csi2tx); in csi2tx_remove()