Lines Matching +full:ld +full:- +full:pulse +full:- +full:delay +full:- +full:us
1 // SPDX-License-Identifier: GPL-2.0+
5 * Copyright (C) 2017-2019 Jacopo Mondi
6 * Copyright (C) 2017-2019 Kieran Bingham
7 * Copyright (C) 2017-2019 Laurent Pinchart
8 * Copyright (C) 2017-2019 Niklas Söderlund
13 #include <linux/delay.h>
19 #include <linux/i2c-mux.h>
26 #include <media/v4l2-async.h>
27 #include <media/v4l2-ctrls.h>
28 #include <media/v4l2-device.h>
29 #include <media/v4l2-fwnode.h>
30 #include <media/v4l2-subdev.h>
67 #define MAX9286_CSILANECNT(n) (((n) - 1) << 6)
114 #define MAX9286_REV_AMP(n) ((((n) - 30) / 10) << 1) /* in mV */
118 #define MAX9286_REV_FLEN(n) ((n) - 20)
187 source = &priv->sources[0]; in next_source()
191 for (; source < &priv->sources[MAX9286_NUM_GMSL]; source++) { in next_source()
192 if (source->fwnode) in next_source()
202 #define to_index(priv, source) ((source) - &(priv)->sources[0])
209 /* -----------------------------------------------------------------------------
217 ret = i2c_smbus_read_byte_data(priv->client, reg); in max9286_read()
219 dev_err(&priv->client->dev, in max9286_read()
230 ret = i2c_smbus_write_byte_data(priv->client, reg, val); in max9286_write()
232 dev_err(&priv->client->dev, in max9286_write()
239 /* -----------------------------------------------------------------------------
259 priv->mux_open = true; in max9286_i2c_mux_open()
271 priv->mux_open = false; in max9286_i2c_mux_close()
272 priv->mux_channel = -1; in max9286_i2c_mux_close()
280 if (priv->mux_open) in max9286_i2c_mux_select()
283 if (priv->mux_channel == chan) in max9286_i2c_mux_select()
286 priv->mux_channel = chan; in max9286_i2c_mux_select()
300 if (!i2c_check_functionality(priv->client->adapter, in max9286_i2c_mux_init()
302 return -ENODEV; in max9286_i2c_mux_init()
304 priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev, in max9286_i2c_mux_init()
305 priv->nsources, 0, I2C_MUX_LOCKED, in max9286_i2c_mux_init()
307 if (!priv->mux) in max9286_i2c_mux_init()
308 return -ENOMEM; in max9286_i2c_mux_init()
310 priv->mux->priv = priv; in max9286_i2c_mux_init()
315 ret = i2c_mux_add_adapter(priv->mux, 0, index, 0); in max9286_i2c_mux_init()
323 i2c_mux_del_adapters(priv->mux); in max9286_i2c_mux_init()
340 * max9286_check_video_links() - Make sure video links are detected and locked
345 * Returns 0 for success, -EIO for errors.
354 * The delay is not characterized in de-serializer manual, wait up in max9286_check_video_links()
360 return -EIO; in max9286_check_video_links()
362 if ((ret & MAX9286_VIDEO_DETECT_MASK) == priv->source_mask) in max9286_check_video_links()
369 dev_err(&priv->client->dev, in max9286_check_video_links()
371 return -EIO; in max9286_check_video_links()
378 return -EIO; in max9286_check_video_links()
387 dev_err(&priv->client->dev, "Not all enabled links locked\n"); in max9286_check_video_links()
388 return -EIO; in max9286_check_video_links()
395 * max9286_check_config_link() - Detect and wait for configuration links
399 * Returns 0 for success, -EIO for errors.
410 * The delay is not characterized in the chip manual: wait up in max9286_check_config_link()
416 return -EIO; in max9286_check_config_link()
426 dev_err(&priv->client->dev, in max9286_check_config_link()
429 return -EIO; in max9286_check_config_link()
432 dev_info(&priv->client->dev, in max9286_check_config_link()
439 /* -----------------------------------------------------------------------------
453 ctrl = v4l2_ctrl_find(source->sd->ctrl_handler, in max9286_set_pixelrate()
465 dev_err(&priv->client->dev, in max9286_set_pixelrate()
467 return -EINVAL; in max9286_set_pixelrate()
472 dev_err(&priv->client->dev, in max9286_set_pixelrate()
474 return -EINVAL; in max9286_set_pixelrate()
478 * The CSI-2 transmitter pixel rate is the single source rate multiplied in max9286_set_pixelrate()
481 return v4l2_ctrl_s_ctrl_int64(priv->pixelrate, in max9286_set_pixelrate()
482 pixelrate * priv->nsources); in max9286_set_pixelrate()
489 struct max9286_priv *priv = sd_to_max9286(notifier->sd); in max9286_notify_bound()
490 struct max9286_source *source = to_max9286_asd(asd)->source; in max9286_notify_bound()
495 ret = media_entity_get_fwnode_pad(&subdev->entity, in max9286_notify_bound()
496 source->fwnode, in max9286_notify_bound()
499 dev_err(&priv->client->dev, in max9286_notify_bound()
500 "Failed to find pad for %s\n", subdev->name); in max9286_notify_bound()
504 priv->bound_sources |= BIT(index); in max9286_notify_bound()
505 source->sd = subdev; in max9286_notify_bound()
508 ret = media_create_pad_link(&source->sd->entity, src_pad, in max9286_notify_bound()
509 &priv->sd.entity, index, in max9286_notify_bound()
513 dev_err(&priv->client->dev, in max9286_notify_bound()
514 "Unable to link %s:%u -> %s:%u\n", in max9286_notify_bound()
515 source->sd->name, src_pad, priv->sd.name, index); in max9286_notify_bound()
519 dev_dbg(&priv->client->dev, "Bound %s pad: %u on index %u\n", in max9286_notify_bound()
520 subdev->name, src_pad, index); in max9286_notify_bound()
524 * means to register a complete callback. bound_sources allows us to in max9286_notify_bound()
527 if (priv->bound_sources != priv->source_mask) in max9286_notify_bound()
534 * - Verify all configuration links are properly detected in max9286_notify_bound()
535 * - Disable auto-ack as communication on the control channel are now in max9286_notify_bound()
538 max9286_check_config_link(priv, priv->source_mask); in max9286_notify_bound()
541 * Re-configure I2C with local acknowledge disabled after cameras have in max9286_notify_bound()
553 struct max9286_priv *priv = sd_to_max9286(notifier->sd); in max9286_notify_unbind()
554 struct max9286_source *source = to_max9286_asd(asd)->source; in max9286_notify_unbind()
557 source->sd = NULL; in max9286_notify_unbind()
558 priv->bound_sources &= ~BIT(index); in max9286_notify_unbind()
568 struct device *dev = &priv->client->dev; in max9286_v4l2_notifier_register()
572 if (!priv->nsources) in max9286_v4l2_notifier_register()
575 v4l2_async_notifier_init(&priv->notifier); in max9286_v4l2_notifier_register()
581 asd = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier, in max9286_v4l2_notifier_register()
582 source->fwnode, in max9286_v4l2_notifier_register()
585 dev_err(dev, "Failed to add subdev for source %u: %ld", in max9286_v4l2_notifier_register()
587 v4l2_async_notifier_cleanup(&priv->notifier); in max9286_v4l2_notifier_register()
591 to_max9286_asd(asd)->source = source; in max9286_v4l2_notifier_register()
594 priv->notifier.ops = &max9286_notify_ops; in max9286_v4l2_notifier_register()
596 ret = v4l2_async_subdev_notifier_register(&priv->sd, &priv->notifier); in max9286_v4l2_notifier_register()
599 v4l2_async_notifier_cleanup(&priv->notifier); in max9286_v4l2_notifier_register()
608 if (!priv->nsources) in max9286_v4l2_notifier_unregister()
611 v4l2_async_notifier_unregister(&priv->notifier); in max9286_v4l2_notifier_unregister()
612 v4l2_async_notifier_cleanup(&priv->notifier); in max9286_v4l2_notifier_unregister()
633 ret = v4l2_subdev_call(source->sd, video, s_stream, 1); in max9286_s_stream()
659 dev_err(&priv->client->dev, in max9286_s_stream()
661 return -EXDEV; /* Invalid cross-device link */ in max9286_s_stream()
675 v4l2_subdev_call(source->sd, video, s_stream, 0); in max9286_s_stream()
687 if (code->pad || code->index > 0) in max9286_enum_mbus_code()
688 return -EINVAL; in max9286_enum_mbus_code()
690 code->code = MEDIA_BUS_FMT_UYVY8_1X16; in max9286_enum_mbus_code()
702 return v4l2_subdev_get_try_format(&priv->sd, cfg, pad); in max9286_get_pad_format()
704 return &priv->fmt[pad]; in max9286_get_pad_format()
717 if (format->pad == MAX9286_SRC_PAD) in max9286_set_fmt()
718 return -EINVAL; in max9286_set_fmt()
721 switch (format->format.code) { in max9286_set_fmt()
728 format->format.code = MEDIA_BUS_FMT_UYVY8_1X16; in max9286_set_fmt()
732 cfg_fmt = max9286_get_pad_format(priv, cfg, format->pad, format->which); in max9286_set_fmt()
734 return -EINVAL; in max9286_set_fmt()
736 mutex_lock(&priv->mutex); in max9286_set_fmt()
737 *cfg_fmt = format->format; in max9286_set_fmt()
738 mutex_unlock(&priv->mutex); in max9286_set_fmt()
749 unsigned int pad = format->pad; in max9286_get_fmt()
758 pad = __ffs(priv->bound_sources); in max9286_get_fmt()
760 cfg_fmt = max9286_get_pad_format(priv, cfg, pad, format->which); in max9286_get_fmt()
762 return -EINVAL; in max9286_get_fmt()
764 mutex_lock(&priv->mutex); in max9286_get_fmt()
765 format->format = *cfg_fmt; in max9286_get_fmt()
766 mutex_unlock(&priv->mutex); in max9286_get_fmt()
788 fmt->width = 1280; in max9286_init_format()
789 fmt->height = 800; in max9286_init_format()
790 fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; in max9286_init_format()
791 fmt->colorspace = V4L2_COLORSPACE_SRGB; in max9286_init_format()
792 fmt->field = V4L2_FIELD_NONE; in max9286_init_format()
793 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in max9286_init_format()
794 fmt->quantization = V4L2_QUANTIZATION_DEFAULT; in max9286_init_format()
795 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in max9286_init_format()
804 format = v4l2_subdev_get_try_format(subdev, fh->pad, i); in max9286_open()
817 switch (ctrl->id) { in max9286_s_ctrl()
821 return -EINVAL; in max9286_s_ctrl()
831 struct device *dev = &priv->client->dev; in max9286_v4l2_register()
846 max9286_init_format(&priv->fmt[i]); in max9286_v4l2_register()
848 v4l2_i2c_subdev_init(&priv->sd, priv->client, &max9286_subdev_ops); in max9286_v4l2_register()
849 priv->sd.internal_ops = &max9286_subdev_internal_ops; in max9286_v4l2_register()
850 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in max9286_v4l2_register()
852 v4l2_ctrl_handler_init(&priv->ctrls, 1); in max9286_v4l2_register()
853 priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls, in max9286_v4l2_register()
858 priv->sd.ctrl_handler = &priv->ctrls; in max9286_v4l2_register()
859 ret = priv->ctrls.error; in max9286_v4l2_register()
863 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in max9286_v4l2_register()
865 priv->pads[MAX9286_SRC_PAD].flags = MEDIA_PAD_FL_SOURCE; in max9286_v4l2_register()
867 priv->pads[i].flags = MEDIA_PAD_FL_SINK; in max9286_v4l2_register()
868 ret = media_entity_pads_init(&priv->sd.entity, MAX9286_N_PADS, in max9286_v4l2_register()
869 priv->pads); in max9286_v4l2_register()
877 ret = -ENOENT; in max9286_v4l2_register()
880 priv->sd.fwnode = ep; in max9286_v4l2_register()
882 ret = v4l2_async_register_subdev(&priv->sd); in max9286_v4l2_register()
900 fwnode_handle_put(priv->sd.fwnode); in max9286_v4l2_unregister()
901 v4l2_async_unregister_subdev(&priv->sd); in max9286_v4l2_unregister()
905 /* -----------------------------------------------------------------------------
948 * - Enable custom reverse channel configuration (through register 0x3f) in max9286_setup()
949 * and set the first pulse length to 35 clock cycles. in max9286_setup()
950 * - Increase the reverse channel amplitude to 170mV to accommodate the in max9286_setup()
962 max9286_write(priv, 0x00, MAX9286_MSTLINKSEL_AUTO | priv->route_mask); in max9286_setup()
963 max9286_write(priv, 0x0b, link_order[priv->route_mask]); in max9286_setup()
964 max9286_write(priv, 0x69, (0xf & ~priv->route_mask)); in max9286_setup()
972 /* Enable CSI-2 Lane D0-D3 only, DBL mode, YUV422 8-bit. */ in max9286_setup()
974 MAX9286_CSILANECNT(priv->csi2_data_lanes) | in max9286_setup()
987 * the delay between vsync and frame sync, generating an error if the in max9286_setup()
988 * delay is bigger than the programmed window, though it's not yet clear in max9286_setup()
1012 priv->gpio_state |= BIT(offset); in max9286_gpio_set()
1014 priv->gpio_state &= ~BIT(offset); in max9286_gpio_set()
1016 max9286_write(priv, 0x0f, MAX9286_0X0F_RESERVED | priv->gpio_state); in max9286_gpio_set()
1023 return priv->gpio_state & BIT(offset); in max9286_gpio_get()
1028 struct device *dev = &priv->client->dev; in max9286_register_gpio()
1029 struct gpio_chip *gpio = &priv->gpio; in max9286_register_gpio()
1033 gpio->label = dev_name(dev); in max9286_register_gpio()
1034 gpio->parent = dev; in max9286_register_gpio()
1035 gpio->owner = THIS_MODULE; in max9286_register_gpio()
1036 gpio->of_node = dev->of_node; in max9286_register_gpio()
1037 gpio->ngpio = 2; in max9286_register_gpio()
1038 gpio->base = -1; in max9286_register_gpio()
1039 gpio->set = max9286_gpio_set; in max9286_register_gpio()
1040 gpio->get = max9286_gpio_get; in max9286_register_gpio()
1041 gpio->can_sleep = true; in max9286_register_gpio()
1044 priv->gpio_state = BIT(0) | BIT(1); in max9286_register_gpio()
1063 ret = regulator_enable(priv->regulator); in max9286_init()
1065 dev_err(&client->dev, "Unable to turn PoC on\n"); in max9286_init()
1099 regulator_disable(priv->regulator); in max9286_init()
1109 fwnode_handle_put(source->fwnode); in max9286_cleanup_dt()
1110 source->fwnode = NULL; in max9286_cleanup_dt()
1116 struct device *dev = &priv->client->dev; in max9286_parse_dt()
1122 of_node_get(dev->of_node); in max9286_parse_dt()
1123 i2c_mux = of_find_node_by_name(dev->of_node, "i2c-mux"); in max9286_parse_dt()
1125 dev_err(dev, "Failed to find i2c-mux node\n"); in max9286_parse_dt()
1126 return -EINVAL; in max9286_parse_dt()
1129 /* Identify which i2c-mux channels are enabled */ in max9286_parse_dt()
1148 for_each_endpoint_of_node(dev->of_node, node) { in max9286_parse_dt()
1176 priv->csi2_data_lanes = in max9286_parse_dt()
1186 if (priv->sources[ep.port].fwnode) { in max9286_parse_dt()
1194 source = &priv->sources[ep.port]; in max9286_parse_dt()
1195 source->fwnode = fwnode_graph_get_remote_endpoint( in max9286_parse_dt()
1197 if (!source->fwnode) { in max9286_parse_dt()
1205 priv->source_mask |= BIT(ep.port); in max9286_parse_dt()
1206 priv->nsources++; in max9286_parse_dt()
1210 priv->route_mask = priv->source_mask; in max9286_parse_dt()
1220 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in max9286_probe()
1222 return -ENOMEM; in max9286_probe()
1224 mutex_init(&priv->mutex); in max9286_probe()
1226 priv->client = client; in max9286_probe()
1229 priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable", in max9286_probe()
1231 if (IS_ERR(priv->gpiod_pwdn)) in max9286_probe()
1232 return PTR_ERR(priv->gpiod_pwdn); in max9286_probe()
1234 gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn"); in max9286_probe()
1235 gpiod_set_value_cansleep(priv->gpiod_pwdn, 1); in max9286_probe()
1238 if (priv->gpiod_pwdn) in max9286_probe()
1249 * The MAX9286 initialises with auto-acknowledge enabled by default. in max9286_probe()
1259 priv->regulator = devm_regulator_get(&client->dev, "poc"); in max9286_probe()
1260 if (IS_ERR(priv->regulator)) { in max9286_probe()
1261 if (PTR_ERR(priv->regulator) != -EPROBE_DEFER) in max9286_probe()
1262 dev_err(&client->dev, in max9286_probe()
1263 "Unable to get PoC regulator (%ld)\n", in max9286_probe()
1264 PTR_ERR(priv->regulator)); in max9286_probe()
1265 ret = PTR_ERR(priv->regulator); in max9286_probe()
1273 ret = max9286_init(&client->dev); in max9286_probe()
1282 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0); in max9286_probe()
1291 i2c_mux_del_adapters(priv->mux); in max9286_remove()
1295 regulator_disable(priv->regulator); in max9286_remove()
1297 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0); in max9286_remove()