Lines Matching full:bridge

3  * Driver for ST MIPID02 CSI-2 to PARALLEL bridge
216 static int mipid02_get_regulators(struct mipid02_dev *bridge) in mipid02_get_regulators() argument
221 bridge->supplies[i].supply = mipid02_supply_name[i]; in mipid02_get_regulators()
223 return devm_regulator_bulk_get(&bridge->i2c_client->dev, in mipid02_get_regulators()
225 bridge->supplies); in mipid02_get_regulators()
228 static void mipid02_apply_reset(struct mipid02_dev *bridge) in mipid02_apply_reset() argument
230 gpiod_set_value_cansleep(bridge->reset_gpio, 0); in mipid02_apply_reset()
232 gpiod_set_value_cansleep(bridge->reset_gpio, 1); in mipid02_apply_reset()
234 gpiod_set_value_cansleep(bridge->reset_gpio, 0); in mipid02_apply_reset()
241 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_set_power_on() local
242 struct i2c_client *client = bridge->i2c_client; in mipid02_set_power_on()
245 ret = clk_prepare_enable(bridge->xclk); in mipid02_set_power_on()
252 bridge->supplies); in mipid02_set_power_on()
259 if (bridge->reset_gpio) { in mipid02_set_power_on()
261 mipid02_apply_reset(bridge); in mipid02_set_power_on()
270 clk_disable_unprepare(bridge->xclk); in mipid02_set_power_on()
277 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_set_power_off() local
279 regulator_bulk_disable(MIPID02_NUM_SUPPLIES, bridge->supplies); in mipid02_set_power_off()
280 clk_disable_unprepare(bridge->xclk); in mipid02_set_power_off()
285 static int mipid02_detect(struct mipid02_dev *bridge) in mipid02_detect() argument
293 return cci_read(bridge->regmap, MIPID02_CLK_LANE_WR_REG1, &reg, NULL); in mipid02_detect()
301 static int mipid02_configure_from_rx_speed(struct mipid02_dev *bridge, in mipid02_configure_from_rx_speed() argument
304 struct i2c_client *client = bridge->i2c_client; in mipid02_configure_from_rx_speed()
305 struct v4l2_subdev *subdev = bridge->s_subdev; in mipid02_configure_from_rx_speed()
306 struct v4l2_fwnode_endpoint *ep = &bridge->rx; in mipid02_configure_from_rx_speed()
324 bridge->r.clk_lane_reg1 |= ui_4 << 2; in mipid02_configure_from_rx_speed()
329 static int mipid02_configure_clk_lane(struct mipid02_dev *bridge) in mipid02_configure_clk_lane() argument
331 struct i2c_client *client = bridge->i2c_client; in mipid02_configure_clk_lane()
332 struct v4l2_fwnode_endpoint *ep = &bridge->rx; in mipid02_configure_clk_lane()
340 bridge->r.clk_lane_reg1 |= (polarities[0] << 1) | CLK_ENABLE; in mipid02_configure_clk_lane()
345 static int mipid02_configure_data0_lane(struct mipid02_dev *bridge, int nb, in mipid02_configure_data0_lane() argument
358 bridge->r.data_lane0_reg1 = 1 << 1; in mipid02_configure_data0_lane()
359 bridge->r.data_lane0_reg1 |= DATA_ENABLE; in mipid02_configure_data0_lane()
364 static int mipid02_configure_data1_lane(struct mipid02_dev *bridge, int nb, in mipid02_configure_data1_lane() argument
373 bridge->r.data_lane1_reg1 = 1 << 1; in mipid02_configure_data1_lane()
374 bridge->r.data_lane1_reg1 |= DATA_ENABLE; in mipid02_configure_data1_lane()
379 static int mipid02_configure_from_rx(struct mipid02_dev *bridge, in mipid02_configure_from_rx() argument
382 struct v4l2_fwnode_endpoint *ep = &bridge->rx; in mipid02_configure_from_rx()
388 ret = mipid02_configure_clk_lane(bridge); in mipid02_configure_from_rx()
392 ret = mipid02_configure_data0_lane(bridge, nb, are_lanes_swap, in mipid02_configure_from_rx()
397 ret = mipid02_configure_data1_lane(bridge, nb, are_lanes_swap, in mipid02_configure_from_rx()
402 bridge->r.mode_reg1 |= are_lanes_swap ? MODE_DATA_SWAP : 0; in mipid02_configure_from_rx()
403 bridge->r.mode_reg1 |= (nb - 1) << 1; in mipid02_configure_from_rx()
405 return mipid02_configure_from_rx_speed(bridge, fmt); in mipid02_configure_from_rx()
408 static int mipid02_configure_from_tx(struct mipid02_dev *bridge) in mipid02_configure_from_tx() argument
410 struct v4l2_fwnode_endpoint *ep = &bridge->tx; in mipid02_configure_from_tx()
412 bridge->r.data_selection_ctrl = SELECTION_MANUAL_WIDTH; in mipid02_configure_from_tx()
413 bridge->r.pix_width_ctrl = ep->bus.parallel.bus_width; in mipid02_configure_from_tx()
414 bridge->r.pix_width_ctrl_emb = ep->bus.parallel.bus_width; in mipid02_configure_from_tx()
416 bridge->r.mode_reg2 |= MODE_HSYNC_ACTIVE_HIGH; in mipid02_configure_from_tx()
418 bridge->r.mode_reg2 |= MODE_VSYNC_ACTIVE_HIGH; in mipid02_configure_from_tx()
420 bridge->r.mode_reg2 |= MODE_PCLK_SAMPLE_RISING; in mipid02_configure_from_tx()
425 static int mipid02_configure_from_code(struct mipid02_dev *bridge, in mipid02_configure_from_code() argument
430 bridge->r.data_id_rreg = 0; in mipid02_configure_from_code()
433 bridge->r.data_selection_ctrl |= SELECTION_MANUAL_DATA; in mipid02_configure_from_code()
438 bridge->r.data_id_rreg = data_type; in mipid02_configure_from_code()
448 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_disable_streams() local
449 struct i2c_client *client = bridge->i2c_client; in mipid02_disable_streams()
452 if (!bridge->s_subdev) in mipid02_disable_streams()
455 ret = v4l2_subdev_disable_streams(bridge->s_subdev, in mipid02_disable_streams()
456 bridge->s_subdev_pad_id, BIT(0)); in mipid02_disable_streams()
461 cci_write(bridge->regmap, MIPID02_CLK_LANE_REG1, 0, &ret); in mipid02_disable_streams()
462 cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG1, 0, &ret); in mipid02_disable_streams()
463 cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG1, 0, &ret); in mipid02_disable_streams()
481 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_enable_streams() local
482 struct i2c_client *client = bridge->i2c_client; in mipid02_enable_streams()
486 if (!bridge->s_subdev) in mipid02_enable_streams()
489 memset(&bridge->r, 0, sizeof(bridge->r)); in mipid02_enable_streams()
494 ret = mipid02_configure_from_rx(bridge, fmt); in mipid02_enable_streams()
497 ret = mipid02_configure_from_tx(bridge); in mipid02_enable_streams()
500 ret = mipid02_configure_from_code(bridge, fmt); in mipid02_enable_streams()
509 cci_write(bridge->regmap, MIPID02_CLK_LANE_REG1, in mipid02_enable_streams()
510 bridge->r.clk_lane_reg1, &ret); in mipid02_enable_streams()
511 cci_write(bridge->regmap, MIPID02_CLK_LANE_REG3, CLK_MIPI_CSI, &ret); in mipid02_enable_streams()
512 cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG1, in mipid02_enable_streams()
513 bridge->r.data_lane0_reg1, &ret); in mipid02_enable_streams()
514 cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG2, DATA_MIPI_CSI, &ret); in mipid02_enable_streams()
515 cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG1, in mipid02_enable_streams()
516 bridge->r.data_lane1_reg1, &ret); in mipid02_enable_streams()
517 cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG2, DATA_MIPI_CSI, &ret); in mipid02_enable_streams()
518 cci_write(bridge->regmap, MIPID02_MODE_REG1, in mipid02_enable_streams()
519 MODE_NO_BYPASS | bridge->r.mode_reg1, &ret); in mipid02_enable_streams()
520 cci_write(bridge->regmap, MIPID02_MODE_REG2, bridge->r.mode_reg2, &ret); in mipid02_enable_streams()
521 cci_write(bridge->regmap, MIPID02_DATA_ID_RREG, bridge->r.data_id_rreg, in mipid02_enable_streams()
523 cci_write(bridge->regmap, MIPID02_DATA_SELECTION_CTRL, in mipid02_enable_streams()
524 bridge->r.data_selection_ctrl, &ret); in mipid02_enable_streams()
525 cci_write(bridge->regmap, MIPID02_PIX_WIDTH_CTRL, in mipid02_enable_streams()
526 bridge->r.pix_width_ctrl, &ret); in mipid02_enable_streams()
527 cci_write(bridge->regmap, MIPID02_PIX_WIDTH_CTRL_EMB, in mipid02_enable_streams()
528 bridge->r.pix_width_ctrl_emb, &ret); in mipid02_enable_streams()
532 ret = v4l2_subdev_enable_streams(bridge->s_subdev, in mipid02_enable_streams()
533 bridge->s_subdev_pad_id, BIT(0)); in mipid02_enable_streams()
540 cci_write(bridge->regmap, MIPID02_CLK_LANE_REG1, 0, &ret); in mipid02_enable_streams()
541 cci_write(bridge->regmap, MIPID02_DATA_LANE0_REG1, 0, &ret); in mipid02_enable_streams()
542 cci_write(bridge->regmap, MIPID02_DATA_LANE1_REG1, 0, &ret); in mipid02_enable_streams()
604 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_set_fmt() local
605 struct i2c_client *client = bridge->i2c_client; in mipid02_set_fmt()
663 struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd); in mipid02_async_bound() local
664 struct i2c_client *client = bridge->i2c_client; in mipid02_async_bound()
680 &bridge->sd.entity, 0, in mipid02_async_bound()
688 bridge->s_subdev = s_subdev; in mipid02_async_bound()
689 bridge->s_subdev_pad_id = source_pad; in mipid02_async_bound()
698 struct mipid02_dev *bridge = to_mipid02_dev(notifier->sd); in mipid02_async_unbind() local
700 bridge->s_subdev = NULL; in mipid02_async_unbind()
708 static int mipid02_parse_rx_ep(struct mipid02_dev *bridge) in mipid02_parse_rx_ep() argument
711 struct i2c_client *client = bridge->i2c_client; in mipid02_parse_rx_ep()
717 ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node, in mipid02_parse_rx_ep()
741 bridge->rx = ep; in mipid02_parse_rx_ep()
744 v4l2_async_subdev_nf_init(&bridge->notifier, &bridge->sd); in mipid02_parse_rx_ep()
745 asd = v4l2_async_nf_add_fwnode_remote(&bridge->notifier, in mipid02_parse_rx_ep()
755 bridge->notifier.ops = &mipid02_notifier_ops; in mipid02_parse_rx_ep()
757 ret = v4l2_async_nf_register(&bridge->notifier); in mipid02_parse_rx_ep()
759 v4l2_async_nf_cleanup(&bridge->notifier); in mipid02_parse_rx_ep()
770 static int mipid02_parse_tx_ep(struct mipid02_dev *bridge) in mipid02_parse_tx_ep() argument
773 struct i2c_client *client = bridge->i2c_client; in mipid02_parse_tx_ep()
778 ep_node = of_graph_get_endpoint_by_regs(bridge->i2c_client->dev.of_node, in mipid02_parse_tx_ep()
793 bridge->tx = ep; in mipid02_parse_tx_ep()
807 struct mipid02_dev *bridge; in mipid02_probe() local
811 bridge = devm_kzalloc(dev, sizeof(*bridge), GFP_KERNEL); in mipid02_probe()
812 if (!bridge) in mipid02_probe()
815 bridge->i2c_client = client; in mipid02_probe()
816 v4l2_i2c_subdev_init(&bridge->sd, client, &mipid02_subdev_ops); in mipid02_probe()
819 bridge->xclk = devm_clk_get(dev, "xclk"); in mipid02_probe()
820 if (IS_ERR(bridge->xclk)) { in mipid02_probe()
822 return PTR_ERR(bridge->xclk); in mipid02_probe()
825 clk_freq = clk_get_rate(bridge->xclk); in mipid02_probe()
832 bridge->reset_gpio = devm_gpiod_get_optional(dev, "reset", in mipid02_probe()
835 if (IS_ERR(bridge->reset_gpio)) { in mipid02_probe()
837 return PTR_ERR(bridge->reset_gpio); in mipid02_probe()
840 ret = mipid02_get_regulators(bridge); in mipid02_probe()
847 bridge->regmap = devm_cci_regmap_init_i2c(client, 16); in mipid02_probe()
848 if (IS_ERR(bridge->regmap)) in mipid02_probe()
849 return dev_err_probe(dev, PTR_ERR(bridge->regmap), in mipid02_probe()
852 bridge->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in mipid02_probe()
853 bridge->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in mipid02_probe()
854 bridge->sd.internal_ops = &mipid02_subdev_internal_ops; in mipid02_probe()
855 bridge->sd.entity.ops = &mipid02_subdev_entity_ops; in mipid02_probe()
856 bridge->pad[0].flags = MEDIA_PAD_FL_SINK; in mipid02_probe()
857 bridge->pad[1].flags = MEDIA_PAD_FL_SINK; in mipid02_probe()
858 bridge->pad[2].flags = MEDIA_PAD_FL_SOURCE; in mipid02_probe()
859 ret = media_entity_pads_init(&bridge->sd.entity, MIPID02_PAD_NB, in mipid02_probe()
860 bridge->pad); in mipid02_probe()
866 ret = v4l2_subdev_init_finalize(&bridge->sd); in mipid02_probe()
877 ret = mipid02_detect(bridge); in mipid02_probe()
883 ret = mipid02_parse_tx_ep(bridge); in mipid02_probe()
889 ret = mipid02_parse_rx_ep(bridge); in mipid02_probe()
904 ret = v4l2_async_register_subdev(&bridge->sd); in mipid02_probe()
916 v4l2_async_nf_unregister(&bridge->notifier); in mipid02_probe()
917 v4l2_async_nf_cleanup(&bridge->notifier); in mipid02_probe()
923 media_entity_cleanup(&bridge->sd.entity); in mipid02_probe()
931 struct mipid02_dev *bridge = to_mipid02_dev(sd); in mipid02_remove() local
933 v4l2_async_nf_unregister(&bridge->notifier); in mipid02_remove()
934 v4l2_async_nf_cleanup(&bridge->notifier); in mipid02_remove()
935 v4l2_async_unregister_subdev(&bridge->sd); in mipid02_remove()
941 media_entity_cleanup(&bridge->sd.entity); in mipid02_remove()
967 MODULE_DESCRIPTION("STMicroelectronics MIPID02 CSI-2 bridge driver");