Lines Matching full:bridge

3  * Driver for ST MIPID02 CSI-2 to PARALLEL bridge
241 static int mipid02_read_reg(struct mipid02_dev *bridge, u16 reg, u8 *val) in mipid02_read_reg() argument
243 struct i2c_client *client = bridge->i2c_client; in mipid02_read_reg()
271 static int mipid02_write_reg(struct mipid02_dev *bridge, u16 reg, u8 val) in mipid02_write_reg() argument
273 struct i2c_client *client = bridge->i2c_client; in mipid02_write_reg()
297 static int mipid02_get_regulators(struct mipid02_dev *bridge) in mipid02_get_regulators() argument
302 bridge->supplies[i].supply = mipid02_supply_name[i]; in mipid02_get_regulators()
304 return devm_regulator_bulk_get(&bridge->i2c_client->dev, in mipid02_get_regulators()
306 bridge->supplies); in mipid02_get_regulators()
309 static void mipid02_apply_reset(struct mipid02_dev *bridge) in mipid02_apply_reset() argument
311 gpiod_set_value_cansleep(bridge->reset_gpio, 0); in mipid02_apply_reset()
313 gpiod_set_value_cansleep(bridge->reset_gpio, 1); in mipid02_apply_reset()
315 gpiod_set_value_cansleep(bridge->reset_gpio, 0); in mipid02_apply_reset()
319 static int mipid02_set_power_on(struct mipid02_dev *bridge) in mipid02_set_power_on() argument
321 struct i2c_client *client = bridge->i2c_client; in mipid02_set_power_on()
324 ret = clk_prepare_enable(bridge->xclk); in mipid02_set_power_on()
331 bridge->supplies); in mipid02_set_power_on()
338 if (bridge->reset_gpio) { in mipid02_set_power_on()
340 mipid02_apply_reset(bridge); in mipid02_set_power_on()
349 clk_disable_unprepare(bridge->xclk); in mipid02_set_power_on()
353 static void mipid02_set_power_off(struct mipid02_dev *bridge) in mipid02_set_power_off() argument
355 regulator_bulk_disable(MIPID02_NUM_SUPPLIES, bridge->supplies); in mipid02_set_power_off()
356 clk_disable_unprepare(bridge->xclk); in mipid02_set_power_off()
359 static int mipid02_detect(struct mipid02_dev *bridge) in mipid02_detect() argument
367 return mipid02_read_reg(bridge, MIPID02_CLK_LANE_WR_REG1, &reg); in mipid02_detect()
370 static u32 mipid02_get_link_freq_from_cid_link_freq(struct mipid02_dev *bridge, in mipid02_get_link_freq_from_cid_link_freq() argument
389 static u32 mipid02_get_link_freq_from_cid_pixel_rate(struct mipid02_dev *bridge, in mipid02_get_link_freq_from_cid_pixel_rate() argument
392 struct v4l2_fwnode_endpoint *ep = &bridge->rx; in mipid02_get_link_freq_from_cid_pixel_rate()
395 u32 bpp = bpp_from_code(bridge->fmt.code); in mipid02_get_link_freq_from_cid_pixel_rate()
410 static int mipid02_configure_from_rx_speed(struct mipid02_dev *bridge) in mipid02_configure_from_rx_speed() argument
412 struct i2c_client *client = bridge->i2c_client; in mipid02_configure_from_rx_speed()
413 struct v4l2_subdev *subdev = bridge->s_subdev; in mipid02_configure_from_rx_speed()
416 link_freq = mipid02_get_link_freq_from_cid_link_freq(bridge, subdev); in mipid02_configure_from_rx_speed()
418 link_freq = mipid02_get_link_freq_from_cid_pixel_rate(bridge, in mipid02_configure_from_rx_speed()
427 bridge->r.clk_lane_reg1 |= (2000000000 / link_freq) << 2; in mipid02_configure_from_rx_speed()
432 static int mipid02_configure_clk_lane(struct mipid02_dev *bridge) in mipid02_configure_clk_lane() argument
434 struct i2c_client *client = bridge->i2c_client; in mipid02_configure_clk_lane()
435 struct v4l2_fwnode_endpoint *ep = &bridge->rx; in mipid02_configure_clk_lane()
443 bridge->r.clk_lane_reg1 |= (polarities[0] << 1) | CLK_ENABLE; in mipid02_configure_clk_lane()
448 static int mipid02_configure_data0_lane(struct mipid02_dev *bridge, int nb, in mipid02_configure_data0_lane() argument
461 bridge->r.data_lane0_reg1 = 1 << 1; in mipid02_configure_data0_lane()
462 bridge->r.data_lane0_reg1 |= DATA_ENABLE; in mipid02_configure_data0_lane()
467 static int mipid02_configure_data1_lane(struct mipid02_dev *bridge, int nb, in mipid02_configure_data1_lane() argument
476 bridge->r.data_lane1_reg1 = 1 << 1; in mipid02_configure_data1_lane()
477 bridge->r.data_lane1_reg1 |= DATA_ENABLE; in mipid02_configure_data1_lane()
482 static int mipid02_configure_from_rx(struct mipid02_dev *bridge) in mipid02_configure_from_rx() argument
484 struct v4l2_fwnode_endpoint *ep = &bridge->rx; in mipid02_configure_from_rx()
490 ret = mipid02_configure_clk_lane(bridge); in mipid02_configure_from_rx()
494 ret = mipid02_configure_data0_lane(bridge, nb, are_lanes_swap, in mipid02_configure_from_rx()
499 ret = mipid02_configure_data1_lane(bridge, nb, are_lanes_swap, in mipid02_configure_from_rx()
504 bridge->r.mode_reg1 |= are_lanes_swap ? MODE_DATA_SWAP : 0; in mipid02_configure_from_rx()
505 bridge->r.mode_reg1 |= (nb - 1) << 1; in mipid02_configure_from_rx()
507 return mipid02_configure_from_rx_speed(bridge); in mipid02_configure_from_rx()
510 static int mipid02_configure_from_tx(struct mipid02_dev *bridge) in mipid02_configure_from_tx() argument
512 struct v4l2_fwnode_endpoint *ep = &bridge->tx; in mipid02_configure_from_tx()
514 bridge->r.data_selection_ctrl = SELECTION_MANUAL_WIDTH; in mipid02_configure_from_tx()
515 bridge->r.pix_width_ctrl = ep->bus.parallel.bus_width; in mipid02_configure_from_tx()
516 bridge->r.pix_width_ctrl_emb = ep->bus.parallel.bus_width; in mipid02_configure_from_tx()
518 bridge->r.mode_reg2 |= MODE_HSYNC_ACTIVE_HIGH; in mipid02_configure_from_tx()
520 bridge->r.mode_reg2 |= MODE_VSYNC_ACTIVE_HIGH; in mipid02_configure_from_tx()
522 bridge->r.mode_reg2 |= MODE_PCLK_SAMPLE_RISING; in mipid02_configure_from_tx()
527 static int mipid02_configure_from_code(struct mipid02_dev *bridge) in mipid02_configure_from_code() argument
531 bridge->r.data_id_rreg = 0; in mipid02_configure_from_code()
533 if (bridge->fmt.code != MEDIA_BUS_FMT_JPEG_1X8) { in mipid02_configure_from_code()
534 bridge->r.data_selection_ctrl |= SELECTION_MANUAL_DATA; in mipid02_configure_from_code()
536 data_type = data_type_from_code(bridge->fmt.code); in mipid02_configure_from_code()
539 bridge->r.data_id_rreg = data_type; in mipid02_configure_from_code()
545 static int mipid02_stream_disable(struct mipid02_dev *bridge) in mipid02_stream_disable() argument
547 struct i2c_client *client = bridge->i2c_client; in mipid02_stream_disable()
550 if (!bridge->s_subdev) in mipid02_stream_disable()
553 ret = v4l2_subdev_call(bridge->s_subdev, video, s_stream, 0); in mipid02_stream_disable()
558 ret = mipid02_write_reg(bridge, MIPID02_CLK_LANE_REG1, 0); in mipid02_stream_disable()
561 ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE0_REG1, 0); in mipid02_stream_disable()
564 ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE1_REG1, 0); in mipid02_stream_disable()
574 static int mipid02_stream_enable(struct mipid02_dev *bridge) in mipid02_stream_enable() argument
576 struct i2c_client *client = bridge->i2c_client; in mipid02_stream_enable()
579 if (!bridge->s_subdev) in mipid02_stream_enable()
582 memset(&bridge->r, 0, sizeof(bridge->r)); in mipid02_stream_enable()
584 ret = mipid02_configure_from_rx(bridge); in mipid02_stream_enable()
587 ret = mipid02_configure_from_tx(bridge); in mipid02_stream_enable()
590 ret = mipid02_configure_from_code(bridge); in mipid02_stream_enable()
595 ret = mipid02_write_reg(bridge, MIPID02_CLK_LANE_REG1, in mipid02_stream_enable()
596 bridge->r.clk_lane_reg1); in mipid02_stream_enable()
599 ret = mipid02_write_reg(bridge, MIPID02_CLK_LANE_REG3, CLK_MIPI_CSI); in mipid02_stream_enable()
602 ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE0_REG1, in mipid02_stream_enable()
603 bridge->r.data_lane0_reg1); in mipid02_stream_enable()
606 ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE0_REG2, in mipid02_stream_enable()
610 ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE1_REG1, in mipid02_stream_enable()
611 bridge->r.data_lane1_reg1); in mipid02_stream_enable()
614 ret = mipid02_write_reg(bridge, MIPID02_DATA_LANE1_REG2, in mipid02_stream_enable()
618 ret = mipid02_write_reg(bridge, MIPID02_MODE_REG1, in mipid02_stream_enable()
619 MODE_NO_BYPASS | bridge->r.mode_reg1); in mipid02_stream_enable()
622 ret = mipid02_write_reg(bridge, MIPID02_MODE_REG2, in mipid02_stream_enable()
623 bridge->r.mode_reg2); in mipid02_stream_enable()
626 ret = mipid02_write_reg(bridge, MIPID02_DATA_ID_RREG, in mipid02_stream_enable()
627 bridge->r.data_id_rreg); in mipid02_stream_enable()
630 ret = mipid02_write_reg(bridge, MIPID02_DATA_SELECTION_CTRL, in mipid02_stream_enable()
631 bridge->r.data_selection_ctrl); in mipid02_stream_enable()
634 ret = mipid02_write_reg(bridge, MIPID02_PIX_WIDTH_CTRL, in mipid02_stream_enable()
635 bridge->r.pix_width_ctrl); in mipid02_stream_enable()
638 ret = mipid02_write_reg(bridge, MIPID02_PIX_WIDTH_CTRL_EMB, in mipid02_stream_enable()
639 bridge->r.pix_width_ctrl_emb); in mipid02_stream_enable()
643 ret = v4l2_subdev_call(bridge->s_subdev, video, s_stream, 1); in mipid02_stream_enable()
651 mipid02_stream_disable(bridge); in mipid02_stream_enable()
658 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_s_stream() local
659 struct i2c_client *client = bridge->i2c_client; in mipid02_s_stream()
663 enable, bridge->streaming); in mipid02_s_stream()
664 mutex_lock(&bridge->lock); in mipid02_s_stream()
666 if (bridge->streaming == enable) in mipid02_s_stream()
669 ret = enable ? mipid02_stream_enable(bridge) : in mipid02_s_stream()
670 mipid02_stream_disable(bridge); in mipid02_s_stream()
672 bridge->streaming = enable; in mipid02_s_stream()
676 bridge->streaming, ret); in mipid02_s_stream()
677 mutex_unlock(&bridge->lock); in mipid02_s_stream()
686 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_enum_mbus_code() local
698 code->code = serial_to_parallel_code(bridge->fmt.code); in mipid02_enum_mbus_code()
714 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_get_fmt() local
715 struct i2c_client *client = bridge->i2c_client; in mipid02_get_fmt()
727 fmt = v4l2_subdev_get_try_format(&bridge->sd, sd_state, in mipid02_get_fmt()
730 fmt = &bridge->fmt; in mipid02_get_fmt()
732 mutex_lock(&bridge->lock); in mipid02_get_fmt()
739 mutex_unlock(&bridge->lock); in mipid02_get_fmt()
748 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_set_fmt_source() local
752 format->format = bridge->fmt; in mipid02_set_fmt_source()
772 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_set_fmt_sink() local
781 fmt = &bridge->fmt; in mipid02_set_fmt_sink()
797 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_set_fmt() local
798 struct i2c_client *client = bridge->i2c_client; in mipid02_set_fmt()
809 mutex_lock(&bridge->lock); in mipid02_set_fmt()
811 if (bridge->streaming) { in mipid02_set_fmt()
822 mutex_unlock(&bridge->lock); in mipid02_set_fmt()
850 struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd); in mipid02_async_bound() local
851 struct i2c_client *client = bridge->i2c_client; in mipid02_async_bound()
867 &bridge->sd.entity, 0, in mipid02_async_bound()
875 bridge->s_subdev = s_subdev; in mipid02_async_bound()
884 struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd); in mipid02_async_unbind() local
886 bridge->s_subdev = NULL; in mipid02_async_unbind()
894 static int mipid02_parse_rx_ep(struct mipid02_dev *bridge) in mipid02_parse_rx_ep() argument
897 struct i2c_client *client = bridge->i2c_client; in mipid02_parse_rx_ep()
903 ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node, in mipid02_parse_rx_ep()
927 bridge->rx = ep; in mipid02_parse_rx_ep()
930 v4l2_async_subdev_nf_init(&bridge->notifier, &bridge->sd); in mipid02_parse_rx_ep()
931 asd = v4l2_async_nf_add_fwnode_remote(&bridge->notifier, in mipid02_parse_rx_ep()
941 bridge->notifier.ops = &mipid02_notifier_ops; in mipid02_parse_rx_ep()
943 ret = v4l2_async_nf_register(&bridge->notifier); in mipid02_parse_rx_ep()
945 v4l2_async_nf_cleanup(&bridge->notifier); in mipid02_parse_rx_ep()
956 static int mipid02_parse_tx_ep(struct mipid02_dev *bridge) in mipid02_parse_tx_ep() argument
959 struct i2c_client *client = bridge->i2c_client; in mipid02_parse_tx_ep()
964 ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node, in mipid02_parse_tx_ep()
979 bridge->tx = ep; in mipid02_parse_tx_ep()
993 struct mipid02_dev *bridge; in mipid02_probe() local
997 bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL); in mipid02_probe()
998 if (!bridge) in mipid02_probe()
1001 init_format(&bridge->fmt); in mipid02_probe()
1003 bridge->i2c_client = client; in mipid02_probe()
1004 v4l2_i2c_subdev_init(&bridge->sd, client, &mipid02_subdev_ops); in mipid02_probe()
1007 bridge->xclk = devm_clk_get(dev, "xclk"); in mipid02_probe()
1008 if (IS_ERR(bridge->xclk)) { in mipid02_probe()
1010 return PTR_ERR(bridge->xclk); in mipid02_probe()
1013 clk_freq = clk_get_rate(bridge->xclk); in mipid02_probe()
1020 bridge->reset_gpio = devm_gpiod_get_optional(dev, "reset", in mipid02_probe()
1023 if (IS_ERR(bridge->reset_gpio)) { in mipid02_probe()
1025 return PTR_ERR(bridge->reset_gpio); in mipid02_probe()
1028 ret = mipid02_get_regulators(bridge); in mipid02_probe()
1034 mutex_init(&bridge->lock); in mipid02_probe()
1035 bridge->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in mipid02_probe()
1036 bridge->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in mipid02_probe()
1037 bridge->sd.entity.ops = &mipid02_subdev_entity_ops; in mipid02_probe()
1038 bridge->pad[0].flags = MEDIA_PAD_FL_SINK; in mipid02_probe()
1039 bridge->pad[1].flags = MEDIA_PAD_FL_SINK; in mipid02_probe()
1040 bridge->pad[2].flags = MEDIA_PAD_FL_SOURCE; in mipid02_probe()
1041 ret = media_entity_pads_init(&bridge->sd.entity, MIPID02_PAD_NB, in mipid02_probe()
1042 bridge->pad); in mipid02_probe()
1049 ret = mipid02_set_power_on(bridge); in mipid02_probe()
1053 ret = mipid02_detect(bridge); in mipid02_probe()
1059 ret = mipid02_parse_tx_ep(bridge); in mipid02_probe()
1065 ret = mipid02_parse_rx_ep(bridge); in mipid02_probe()
1071 ret = v4l2_async_register_subdev(&bridge->sd); in mipid02_probe()
1083 v4l2_async_nf_unregister(&bridge->notifier); in mipid02_probe()
1084 v4l2_async_nf_cleanup(&bridge->notifier); in mipid02_probe()
1086 mipid02_set_power_off(bridge); in mipid02_probe()
1088 media_entity_cleanup(&bridge->sd.entity); in mipid02_probe()
1090 mutex_destroy(&bridge->lock); in mipid02_probe()
1098 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_remove() local
1100 v4l2_async_nf_unregister(&bridge->notifier); in mipid02_remove()
1101 v4l2_async_nf_cleanup(&bridge->notifier); in mipid02_remove()
1102 v4l2_async_unregister_subdev(&bridge->sd); in mipid02_remove()
1103 mipid02_set_power_off(bridge); in mipid02_remove()
1104 media_entity_cleanup(&bridge->sd.entity); in mipid02_remove()
1105 mutex_destroy(&bridge->lock); in mipid02_remove()
1126 MODULE_DESCRIPTION("STMicroelectronics MIPID02 CSI-2 bridge driver");