Lines Matching +full:mux +full:- +full:locked
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
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 */
119 #define MAX9286_REV_FLEN(n) ((n) - 20)
163 struct i2c_mux_core *mux; member
192 source = &priv->sources[0]; in next_source()
196 for (; source < &priv->sources[MAX9286_NUM_GMSL]; source++) { in next_source()
197 if (source->fwnode) in next_source()
207 #define to_index(priv, source) ((source) - &(priv)->sources[0])
214 /* -----------------------------------------------------------------------------
222 ret = i2c_smbus_read_byte_data(priv->client, reg); in max9286_read()
224 dev_err(&priv->client->dev, in max9286_read()
235 ret = i2c_smbus_write_byte_data(priv->client, reg, val); in max9286_write()
237 dev_err(&priv->client->dev, in max9286_write()
244 /* -----------------------------------------------------------------------------
264 priv->mux_open = true; in max9286_i2c_mux_open()
271 * mux, and that the channel ID is invalidated to ensure we reconfigure in max9286_i2c_mux_close()
276 priv->mux_open = false; in max9286_i2c_mux_close()
277 priv->mux_channel = -1; in max9286_i2c_mux_close()
285 if (priv->mux_open) in max9286_i2c_mux_select()
288 if (priv->mux_channel == chan) in max9286_i2c_mux_select()
291 priv->mux_channel = chan; in max9286_i2c_mux_select()
304 if (!i2c_check_functionality(priv->client->adapter, in max9286_i2c_mux_init()
306 return -ENODEV; in max9286_i2c_mux_init()
308 priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev, in max9286_i2c_mux_init()
309 priv->nsources, 0, I2C_MUX_LOCKED, in max9286_i2c_mux_init()
311 if (!priv->mux) in max9286_i2c_mux_init()
312 return -ENOMEM; in max9286_i2c_mux_init()
314 priv->mux->priv = priv; in max9286_i2c_mux_init()
319 ret = i2c_mux_add_adapter(priv->mux, 0, index, 0); in max9286_i2c_mux_init()
327 i2c_mux_del_adapters(priv->mux); in max9286_i2c_mux_init()
348 if (priv->rev_chan_mv == chan_amplitude) in max9286_reverse_channel_setup()
351 priv->rev_chan_mv = chan_amplitude; in max9286_reverse_channel_setup()
359 * - Enable custom reverse channel configuration (through register 0x3f) in max9286_reverse_channel_setup()
361 * - Adjust reverse channel amplitude: values > 130 are programmed in max9286_reverse_channel_setup()
368 chan_amplitude = max(30U, chan_amplitude - 100); in max9286_reverse_channel_setup()
376 * max9286_check_video_links() - Make sure video links are detected and locked
379 * and all enabled links are locked.
381 * Returns 0 for success, -EIO for errors.
390 * The delay is not characterized in de-serializer manual, wait up in max9286_check_video_links()
396 return -EIO; in max9286_check_video_links()
398 if ((ret & MAX9286_VIDEO_DETECT_MASK) == priv->source_mask) in max9286_check_video_links()
405 dev_err(&priv->client->dev, in max9286_check_video_links()
407 return -EIO; in max9286_check_video_links()
410 /* Make sure all enabled links are locked (4ms max). */ in max9286_check_video_links()
414 return -EIO; in max9286_check_video_links()
423 dev_err(&priv->client->dev, "Not all enabled links locked\n"); in max9286_check_video_links()
424 return -EIO; in max9286_check_video_links()
431 * max9286_check_config_link() - Detect and wait for configuration links
435 * Returns 0 for success, -EIO for errors.
452 return -EIO; in max9286_check_config_link()
462 dev_err(&priv->client->dev, in max9286_check_config_link()
465 return -EIO; in max9286_check_config_link()
468 dev_info(&priv->client->dev, in max9286_check_config_link()
475 /* -----------------------------------------------------------------------------
489 ctrl = v4l2_ctrl_find(source->sd->ctrl_handler, in max9286_set_pixelrate()
501 dev_err(&priv->client->dev, in max9286_set_pixelrate()
503 return -EINVAL; in max9286_set_pixelrate()
508 dev_err(&priv->client->dev, in max9286_set_pixelrate()
510 return -EINVAL; in max9286_set_pixelrate()
514 * The CSI-2 transmitter pixel rate is the single source rate multiplied in max9286_set_pixelrate()
517 return v4l2_ctrl_s_ctrl_int64(priv->pixelrate, in max9286_set_pixelrate()
518 pixelrate * priv->nsources); in max9286_set_pixelrate()
525 struct max9286_priv *priv = sd_to_max9286(notifier->sd); in max9286_notify_bound()
526 struct max9286_source *source = to_max9286_asd(asd)->source; in max9286_notify_bound()
531 ret = media_entity_get_fwnode_pad(&subdev->entity, in max9286_notify_bound()
532 source->fwnode, in max9286_notify_bound()
535 dev_err(&priv->client->dev, in max9286_notify_bound()
536 "Failed to find pad for %s\n", subdev->name); in max9286_notify_bound()
540 priv->bound_sources |= BIT(index); in max9286_notify_bound()
541 source->sd = subdev; in max9286_notify_bound()
544 ret = media_create_pad_link(&source->sd->entity, src_pad, in max9286_notify_bound()
545 &priv->sd.entity, index, in max9286_notify_bound()
549 dev_err(&priv->client->dev, in max9286_notify_bound()
550 "Unable to link %s:%u -> %s:%u\n", in max9286_notify_bound()
551 source->sd->name, src_pad, priv->sd.name, index); in max9286_notify_bound()
555 dev_dbg(&priv->client->dev, "Bound %s pad: %u on index %u\n", in max9286_notify_bound()
556 subdev->name, src_pad, index); in max9286_notify_bound()
563 if (priv->bound_sources != priv->source_mask) in max9286_notify_bound()
570 * - Increase the reverse channel amplitude to compensate for the in max9286_notify_bound()
572 * - Verify all configuration links are properly detected in max9286_notify_bound()
573 * - Disable auto-ack as communication on the control channel are now in max9286_notify_bound()
577 max9286_check_config_link(priv, priv->source_mask); in max9286_notify_bound()
587 struct max9286_priv *priv = sd_to_max9286(notifier->sd); in max9286_notify_unbind()
588 struct max9286_source *source = to_max9286_asd(asd)->source; in max9286_notify_unbind()
591 source->sd = NULL; in max9286_notify_unbind()
592 priv->bound_sources &= ~BIT(index); in max9286_notify_unbind()
602 struct device *dev = &priv->client->dev; in max9286_v4l2_notifier_register()
606 if (!priv->nsources) in max9286_v4l2_notifier_register()
609 v4l2_async_notifier_init(&priv->notifier); in max9286_v4l2_notifier_register()
615 mas = v4l2_async_notifier_add_fwnode_subdev(&priv->notifier, in max9286_v4l2_notifier_register()
616 source->fwnode, in max9286_v4l2_notifier_register()
621 v4l2_async_notifier_cleanup(&priv->notifier); in max9286_v4l2_notifier_register()
625 mas->source = source; in max9286_v4l2_notifier_register()
628 priv->notifier.ops = &max9286_notify_ops; in max9286_v4l2_notifier_register()
630 ret = v4l2_async_subdev_notifier_register(&priv->sd, &priv->notifier); in max9286_v4l2_notifier_register()
633 v4l2_async_notifier_cleanup(&priv->notifier); in max9286_v4l2_notifier_register()
642 if (!priv->nsources) in max9286_v4l2_notifier_unregister()
645 v4l2_async_notifier_unregister(&priv->notifier); in max9286_v4l2_notifier_unregister()
646 v4l2_async_notifier_cleanup(&priv->notifier); in max9286_v4l2_notifier_unregister()
667 ret = v4l2_subdev_call(source->sd, video, s_stream, 1); in max9286_s_stream()
677 * Wait until frame synchronization is locked. in max9286_s_stream()
693 dev_err(&priv->client->dev, in max9286_s_stream()
695 return -EXDEV; /* Invalid cross-device link */ in max9286_s_stream()
709 v4l2_subdev_call(source->sd, video, s_stream, 0); in max9286_s_stream()
721 if (code->pad || code->index > 0) in max9286_enum_mbus_code()
722 return -EINVAL; in max9286_enum_mbus_code()
724 code->code = MEDIA_BUS_FMT_UYVY8_1X16; in max9286_enum_mbus_code()
736 return v4l2_subdev_get_try_format(&priv->sd, sd_state, pad); in max9286_get_pad_format()
738 return &priv->fmt[pad]; in max9286_get_pad_format()
751 if (format->pad == MAX9286_SRC_PAD) in max9286_set_fmt()
752 return -EINVAL; in max9286_set_fmt()
755 switch (format->format.code) { in max9286_set_fmt()
762 format->format.code = MEDIA_BUS_FMT_UYVY8_1X16; in max9286_set_fmt()
766 cfg_fmt = max9286_get_pad_format(priv, sd_state, format->pad, in max9286_set_fmt()
767 format->which); in max9286_set_fmt()
769 return -EINVAL; in max9286_set_fmt()
771 mutex_lock(&priv->mutex); in max9286_set_fmt()
772 *cfg_fmt = format->format; in max9286_set_fmt()
773 mutex_unlock(&priv->mutex); in max9286_set_fmt()
784 unsigned int pad = format->pad; in max9286_get_fmt()
793 pad = __ffs(priv->bound_sources); in max9286_get_fmt()
795 cfg_fmt = max9286_get_pad_format(priv, sd_state, pad, format->which); in max9286_get_fmt()
797 return -EINVAL; in max9286_get_fmt()
799 mutex_lock(&priv->mutex); in max9286_get_fmt()
800 format->format = *cfg_fmt; in max9286_get_fmt()
801 mutex_unlock(&priv->mutex); in max9286_get_fmt()
823 fmt->width = 1280; in max9286_init_format()
824 fmt->height = 800; in max9286_init_format()
825 fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; in max9286_init_format()
826 fmt->colorspace = V4L2_COLORSPACE_SRGB; in max9286_init_format()
827 fmt->field = V4L2_FIELD_NONE; in max9286_init_format()
828 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in max9286_init_format()
829 fmt->quantization = V4L2_QUANTIZATION_DEFAULT; in max9286_init_format()
830 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in max9286_init_format()
839 format = v4l2_subdev_get_try_format(subdev, fh->state, i); in max9286_open()
852 switch (ctrl->id) { in max9286_s_ctrl()
856 return -EINVAL; in max9286_s_ctrl()
866 struct device *dev = &priv->client->dev; in max9286_v4l2_register()
881 max9286_init_format(&priv->fmt[i]); in max9286_v4l2_register()
883 v4l2_i2c_subdev_init(&priv->sd, priv->client, &max9286_subdev_ops); in max9286_v4l2_register()
884 priv->sd.internal_ops = &max9286_subdev_internal_ops; in max9286_v4l2_register()
885 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in max9286_v4l2_register()
887 v4l2_ctrl_handler_init(&priv->ctrls, 1); in max9286_v4l2_register()
888 priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls, in max9286_v4l2_register()
893 priv->sd.ctrl_handler = &priv->ctrls; in max9286_v4l2_register()
894 ret = priv->ctrls.error; in max9286_v4l2_register()
898 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in max9286_v4l2_register()
900 priv->pads[MAX9286_SRC_PAD].flags = MEDIA_PAD_FL_SOURCE; in max9286_v4l2_register()
902 priv->pads[i].flags = MEDIA_PAD_FL_SINK; in max9286_v4l2_register()
903 ret = media_entity_pads_init(&priv->sd.entity, MAX9286_N_PADS, in max9286_v4l2_register()
904 priv->pads); in max9286_v4l2_register()
912 ret = -ENOENT; in max9286_v4l2_register()
915 priv->sd.fwnode = ep; in max9286_v4l2_register()
917 ret = v4l2_async_register_subdev(&priv->sd); in max9286_v4l2_register()
935 fwnode_handle_put(priv->sd.fwnode); in max9286_v4l2_unregister()
936 v4l2_async_unregister_subdev(&priv->sd); in max9286_v4l2_unregister()
940 /* -----------------------------------------------------------------------------
976 * only. This should be disabled after the mux is initialised. in max9286_setup()
979 max9286_reverse_channel_setup(priv, priv->init_rev_chan_mv); in max9286_setup()
985 max9286_write(priv, 0x00, MAX9286_MSTLINKSEL_AUTO | priv->route_mask); in max9286_setup()
986 max9286_write(priv, 0x0b, link_order[priv->route_mask]); in max9286_setup()
987 max9286_write(priv, 0x69, (0xf & ~priv->route_mask)); in max9286_setup()
995 /* Enable CSI-2 Lane D0-D3 only, DBL mode, YUV422 8-bit. */ in max9286_setup()
997 MAX9286_CSILANECNT(priv->csi2_data_lanes) | in max9286_setup()
1035 priv->gpio_state |= BIT(offset); in max9286_gpio_set()
1037 priv->gpio_state &= ~BIT(offset); in max9286_gpio_set()
1039 max9286_write(priv, 0x0f, MAX9286_0X0F_RESERVED | priv->gpio_state); in max9286_gpio_set()
1046 return priv->gpio_state & BIT(offset); in max9286_gpio_get()
1051 struct device *dev = &priv->client->dev; in max9286_register_gpio()
1052 struct gpio_chip *gpio = &priv->gpio; in max9286_register_gpio()
1056 gpio->label = dev_name(dev); in max9286_register_gpio()
1057 gpio->parent = dev; in max9286_register_gpio()
1058 gpio->owner = THIS_MODULE; in max9286_register_gpio()
1059 gpio->of_node = dev->of_node; in max9286_register_gpio()
1060 gpio->ngpio = 2; in max9286_register_gpio()
1061 gpio->base = -1; in max9286_register_gpio()
1062 gpio->set = max9286_gpio_set; in max9286_register_gpio()
1063 gpio->get = max9286_gpio_get; in max9286_register_gpio()
1064 gpio->can_sleep = true; in max9286_register_gpio()
1067 priv->gpio_state = BIT(0) | BIT(1); in max9286_register_gpio()
1086 ret = regulator_enable(priv->regulator); in max9286_init()
1088 dev_err(&client->dev, "Unable to turn PoC on\n"); in max9286_init()
1114 /* Leave the mux channels disabled until they are selected. */ in max9286_init()
1122 regulator_disable(priv->regulator); in max9286_init()
1132 fwnode_handle_put(source->fwnode); in max9286_cleanup_dt()
1133 source->fwnode = NULL; in max9286_cleanup_dt()
1139 struct device *dev = &priv->client->dev; in max9286_parse_dt()
1146 of_node_get(dev->of_node); in max9286_parse_dt()
1147 i2c_mux = of_find_node_by_name(dev->of_node, "i2c-mux"); in max9286_parse_dt()
1149 dev_err(dev, "Failed to find i2c-mux node\n"); in max9286_parse_dt()
1150 return -EINVAL; in max9286_parse_dt()
1153 /* Identify which i2c-mux channels are enabled */ in max9286_parse_dt()
1172 for_each_endpoint_of_node(dev->of_node, node) { in max9286_parse_dt()
1200 priv->csi2_data_lanes = in max9286_parse_dt()
1210 if (priv->sources[ep.port].fwnode) { in max9286_parse_dt()
1218 source = &priv->sources[ep.port]; in max9286_parse_dt()
1219 source->fwnode = fwnode_graph_get_remote_endpoint( in max9286_parse_dt()
1221 if (!source->fwnode) { in max9286_parse_dt()
1229 priv->source_mask |= BIT(ep.port); in max9286_parse_dt()
1230 priv->nsources++; in max9286_parse_dt()
1241 if (of_property_read_u32(dev->of_node, in max9286_parse_dt()
1242 "maxim,reverse-channel-microvolt", in max9286_parse_dt()
1244 priv->init_rev_chan_mv = 170; in max9286_parse_dt()
1246 priv->init_rev_chan_mv = reverse_channel_microvolt / 1000U; in max9286_parse_dt()
1248 priv->route_mask = priv->source_mask; in max9286_parse_dt()
1258 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in max9286_probe()
1260 return -ENOMEM; in max9286_probe()
1262 mutex_init(&priv->mutex); in max9286_probe()
1264 priv->client = client; in max9286_probe()
1267 priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable", in max9286_probe()
1269 if (IS_ERR(priv->gpiod_pwdn)) in max9286_probe()
1270 return PTR_ERR(priv->gpiod_pwdn); in max9286_probe()
1272 gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn"); in max9286_probe()
1273 gpiod_set_value_cansleep(priv->gpiod_pwdn, 1); in max9286_probe()
1276 if (priv->gpiod_pwdn) in max9286_probe()
1287 * The MAX9286 initialises with auto-acknowledge enabled by default. in max9286_probe()
1297 priv->regulator = devm_regulator_get(&client->dev, "poc"); in max9286_probe()
1298 if (IS_ERR(priv->regulator)) { in max9286_probe()
1299 if (PTR_ERR(priv->regulator) != -EPROBE_DEFER) in max9286_probe()
1300 dev_err(&client->dev, in max9286_probe()
1302 PTR_ERR(priv->regulator)); in max9286_probe()
1303 ret = PTR_ERR(priv->regulator); in max9286_probe()
1311 ret = max9286_init(&client->dev); in max9286_probe()
1320 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0); in max9286_probe()
1329 i2c_mux_del_adapters(priv->mux); in max9286_remove()
1333 regulator_disable(priv->regulator); in max9286_remove()
1335 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0); in max9286_remove()