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
20 #include <linux/i2c-mux.h>
27 #include <media/v4l2-async.h>
28 #include <media/v4l2-ctrls.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-fwnode.h>
31 #include <media/v4l2-subdev.h>
68 #define MAX9286_CSILANECNT(n) (((n) - 1) << 6)
115 #define MAX9286_REV_AMP(n) ((((n) - 30) / 10) << 1) /* in mV */
120 #define MAX9286_REV_FLEN(n) ((n) - 20)
164 struct i2c_mux_core *mux; member
195 source = &priv->sources[0]; in next_source()
199 for (; source < &priv->sources[MAX9286_NUM_GMSL]; source++) { in next_source()
200 if (source->fwnode) in next_source()
210 #define to_index(priv, source) ((source) - &(priv)->sources[0])
217 /* -----------------------------------------------------------------------------
225 ret = i2c_smbus_read_byte_data(priv->client, reg); in max9286_read()
227 dev_err(&priv->client->dev, in max9286_read()
238 ret = i2c_smbus_write_byte_data(priv->client, reg, val); in max9286_write()
240 dev_err(&priv->client->dev, in max9286_write()
247 /* -----------------------------------------------------------------------------
267 priv->mux_open = true; in max9286_i2c_mux_open()
274 * mux, and that the channel ID is invalidated to ensure we reconfigure in max9286_i2c_mux_close()
279 priv->mux_open = false; in max9286_i2c_mux_close()
280 priv->mux_channel = -1; in max9286_i2c_mux_close()
288 if (priv->mux_open) in max9286_i2c_mux_select()
291 if (priv->mux_channel == chan) in max9286_i2c_mux_select()
294 priv->mux_channel = chan; in max9286_i2c_mux_select()
307 if (!i2c_check_functionality(priv->client->adapter, in max9286_i2c_mux_init()
309 return -ENODEV; in max9286_i2c_mux_init()
311 priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev, in max9286_i2c_mux_init()
312 priv->nsources, 0, I2C_MUX_LOCKED, in max9286_i2c_mux_init()
314 if (!priv->mux) in max9286_i2c_mux_init()
315 return -ENOMEM; in max9286_i2c_mux_init()
317 priv->mux->priv = priv; in max9286_i2c_mux_init()
322 ret = i2c_mux_add_adapter(priv->mux, 0, index, 0); in max9286_i2c_mux_init()
330 i2c_mux_del_adapters(priv->mux); in max9286_i2c_mux_init()
351 if (priv->rev_chan_mv == chan_amplitude) in max9286_reverse_channel_setup()
354 priv->rev_chan_mv = chan_amplitude; in max9286_reverse_channel_setup()
362 * - Enable custom reverse channel configuration (through register 0x3f) in max9286_reverse_channel_setup()
364 * - Adjust reverse channel amplitude: values > 130 are programmed in max9286_reverse_channel_setup()
371 chan_amplitude = max(30U, chan_amplitude - 100); in max9286_reverse_channel_setup()
379 * max9286_check_video_links() - Make sure video links are detected and locked
382 * and all enabled links are locked.
384 * Returns 0 for success, -EIO for errors.
393 * The delay is not characterized in de-serializer manual, wait up in max9286_check_video_links()
399 return -EIO; in max9286_check_video_links()
401 if ((ret & MAX9286_VIDEO_DETECT_MASK) == priv->source_mask) in max9286_check_video_links()
408 dev_err(&priv->client->dev, in max9286_check_video_links()
410 return -EIO; in max9286_check_video_links()
413 /* Make sure all enabled links are locked (4ms max). */ in max9286_check_video_links()
417 return -EIO; in max9286_check_video_links()
426 dev_err(&priv->client->dev, "Not all enabled links locked\n"); in max9286_check_video_links()
427 return -EIO; in max9286_check_video_links()
434 * max9286_check_config_link() - Detect and wait for configuration links
438 * Returns 0 for success, -EIO for errors.
455 return -EIO; in max9286_check_config_link()
465 dev_err(&priv->client->dev, in max9286_check_config_link()
468 return -EIO; in max9286_check_config_link()
471 dev_info(&priv->client->dev, in max9286_check_config_link()
478 /* -----------------------------------------------------------------------------
492 ctrl = v4l2_ctrl_find(source->sd->ctrl_handler, in max9286_set_pixelrate()
504 dev_err(&priv->client->dev, in max9286_set_pixelrate()
506 return -EINVAL; in max9286_set_pixelrate()
511 dev_err(&priv->client->dev, in max9286_set_pixelrate()
513 return -EINVAL; in max9286_set_pixelrate()
517 * The CSI-2 transmitter pixel rate is the single source rate multiplied in max9286_set_pixelrate()
520 return v4l2_ctrl_s_ctrl_int64(priv->pixelrate, in max9286_set_pixelrate()
521 pixelrate * priv->nsources); in max9286_set_pixelrate()
528 struct max9286_priv *priv = sd_to_max9286(notifier->sd); in max9286_notify_bound()
529 struct max9286_source *source = to_max9286_asd(asd)->source; in max9286_notify_bound()
534 ret = media_entity_get_fwnode_pad(&subdev->entity, in max9286_notify_bound()
535 source->fwnode, in max9286_notify_bound()
538 dev_err(&priv->client->dev, in max9286_notify_bound()
539 "Failed to find pad for %s\n", subdev->name); in max9286_notify_bound()
543 priv->bound_sources |= BIT(index); in max9286_notify_bound()
544 source->sd = subdev; in max9286_notify_bound()
547 ret = media_create_pad_link(&source->sd->entity, src_pad, in max9286_notify_bound()
548 &priv->sd.entity, index, in max9286_notify_bound()
552 dev_err(&priv->client->dev, in max9286_notify_bound()
553 "Unable to link %s:%u -> %s:%u\n", in max9286_notify_bound()
554 source->sd->name, src_pad, priv->sd.name, index); in max9286_notify_bound()
558 dev_dbg(&priv->client->dev, "Bound %s pad: %u on index %u\n", in max9286_notify_bound()
559 subdev->name, src_pad, index); in max9286_notify_bound()
566 if (priv->bound_sources != priv->source_mask) in max9286_notify_bound()
573 * - Increase the reverse channel amplitude to compensate for the in max9286_notify_bound()
575 * - Verify all configuration links are properly detected in max9286_notify_bound()
576 * - Disable auto-ack as communication on the control channel are now in max9286_notify_bound()
580 max9286_check_config_link(priv, priv->source_mask); in max9286_notify_bound()
590 struct max9286_priv *priv = sd_to_max9286(notifier->sd); in max9286_notify_unbind()
591 struct max9286_source *source = to_max9286_asd(asd)->source; in max9286_notify_unbind()
594 source->sd = NULL; in max9286_notify_unbind()
595 priv->bound_sources &= ~BIT(index); in max9286_notify_unbind()
605 struct device *dev = &priv->client->dev; in max9286_v4l2_notifier_register()
609 if (!priv->nsources) in max9286_v4l2_notifier_register()
612 v4l2_async_nf_init(&priv->notifier); in max9286_v4l2_notifier_register()
618 mas = v4l2_async_nf_add_fwnode(&priv->notifier, source->fwnode, in max9286_v4l2_notifier_register()
623 v4l2_async_nf_cleanup(&priv->notifier); in max9286_v4l2_notifier_register()
627 mas->source = source; in max9286_v4l2_notifier_register()
630 priv->notifier.ops = &max9286_notify_ops; in max9286_v4l2_notifier_register()
632 ret = v4l2_async_subdev_nf_register(&priv->sd, &priv->notifier); in max9286_v4l2_notifier_register()
635 v4l2_async_nf_cleanup(&priv->notifier); in max9286_v4l2_notifier_register()
644 if (!priv->nsources) in max9286_v4l2_notifier_unregister()
647 v4l2_async_nf_unregister(&priv->notifier); in max9286_v4l2_notifier_unregister()
648 v4l2_async_nf_cleanup(&priv->notifier); in max9286_v4l2_notifier_unregister()
669 ret = v4l2_subdev_call(source->sd, video, s_stream, 1); in max9286_s_stream()
679 * Wait until frame synchronization is locked. in max9286_s_stream()
695 dev_err(&priv->client->dev, in max9286_s_stream()
697 return -EXDEV; /* Invalid cross-device link */ in max9286_s_stream()
711 v4l2_subdev_call(source->sd, video, s_stream, 0); in max9286_s_stream()
723 if (code->pad || code->index > 0) in max9286_enum_mbus_code()
724 return -EINVAL; in max9286_enum_mbus_code()
726 code->code = MEDIA_BUS_FMT_UYVY8_1X16; in max9286_enum_mbus_code()
738 return v4l2_subdev_get_try_format(&priv->sd, sd_state, pad); in max9286_get_pad_format()
740 return &priv->fmt[pad]; in max9286_get_pad_format()
753 if (format->pad == MAX9286_SRC_PAD) in max9286_set_fmt()
754 return -EINVAL; in max9286_set_fmt()
757 switch (format->format.code) { in max9286_set_fmt()
764 format->format.code = MEDIA_BUS_FMT_UYVY8_1X16; in max9286_set_fmt()
768 cfg_fmt = max9286_get_pad_format(priv, sd_state, format->pad, in max9286_set_fmt()
769 format->which); in max9286_set_fmt()
771 return -EINVAL; in max9286_set_fmt()
773 mutex_lock(&priv->mutex); in max9286_set_fmt()
774 *cfg_fmt = format->format; in max9286_set_fmt()
775 mutex_unlock(&priv->mutex); in max9286_set_fmt()
786 unsigned int pad = format->pad; in max9286_get_fmt()
795 pad = __ffs(priv->bound_sources); in max9286_get_fmt()
797 cfg_fmt = max9286_get_pad_format(priv, sd_state, pad, format->which); in max9286_get_fmt()
799 return -EINVAL; in max9286_get_fmt()
801 mutex_lock(&priv->mutex); in max9286_get_fmt()
802 format->format = *cfg_fmt; in max9286_get_fmt()
803 mutex_unlock(&priv->mutex); in max9286_get_fmt()
825 fmt->width = 1280; in max9286_init_format()
826 fmt->height = 800; in max9286_init_format()
827 fmt->code = MEDIA_BUS_FMT_UYVY8_1X16; in max9286_init_format()
828 fmt->colorspace = V4L2_COLORSPACE_SRGB; in max9286_init_format()
829 fmt->field = V4L2_FIELD_NONE; in max9286_init_format()
830 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in max9286_init_format()
831 fmt->quantization = V4L2_QUANTIZATION_DEFAULT; in max9286_init_format()
832 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in max9286_init_format()
841 format = v4l2_subdev_get_try_format(subdev, fh->state, i); in max9286_open()
858 switch (ctrl->id) { in max9286_s_ctrl()
862 return -EINVAL; in max9286_s_ctrl()
872 struct device *dev = &priv->client->dev; in max9286_v4l2_register()
887 max9286_init_format(&priv->fmt[i]); in max9286_v4l2_register()
889 v4l2_i2c_subdev_init(&priv->sd, priv->client, &max9286_subdev_ops); in max9286_v4l2_register()
890 priv->sd.internal_ops = &max9286_subdev_internal_ops; in max9286_v4l2_register()
891 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in max9286_v4l2_register()
893 v4l2_ctrl_handler_init(&priv->ctrls, 1); in max9286_v4l2_register()
894 priv->pixelrate = v4l2_ctrl_new_std(&priv->ctrls, in max9286_v4l2_register()
899 priv->sd.ctrl_handler = &priv->ctrls; in max9286_v4l2_register()
900 ret = priv->ctrls.error; in max9286_v4l2_register()
904 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in max9286_v4l2_register()
905 priv->sd.entity.ops = &max9286_media_ops; in max9286_v4l2_register()
907 priv->pads[MAX9286_SRC_PAD].flags = MEDIA_PAD_FL_SOURCE; in max9286_v4l2_register()
909 priv->pads[i].flags = MEDIA_PAD_FL_SINK; in max9286_v4l2_register()
910 ret = media_entity_pads_init(&priv->sd.entity, MAX9286_N_PADS, in max9286_v4l2_register()
911 priv->pads); in max9286_v4l2_register()
919 ret = -ENOENT; in max9286_v4l2_register()
922 priv->sd.fwnode = ep; in max9286_v4l2_register()
924 ret = v4l2_async_register_subdev(&priv->sd); in max9286_v4l2_register()
942 fwnode_handle_put(priv->sd.fwnode); in max9286_v4l2_unregister()
943 v4l2_async_unregister_subdev(&priv->sd); in max9286_v4l2_unregister()
947 /* -----------------------------------------------------------------------------
983 * only. This should be disabled after the mux is initialised. in max9286_setup()
986 max9286_reverse_channel_setup(priv, priv->init_rev_chan_mv); in max9286_setup()
992 max9286_write(priv, 0x00, MAX9286_MSTLINKSEL_AUTO | priv->route_mask); in max9286_setup()
993 max9286_write(priv, 0x0b, link_order[priv->route_mask]); in max9286_setup()
994 max9286_write(priv, 0x69, (0xf & ~priv->route_mask)); in max9286_setup()
1002 /* Enable CSI-2 Lane D0-D3 only, DBL mode, YUV422 8-bit. */ in max9286_setup()
1004 MAX9286_CSILANECNT(priv->csi2_data_lanes) | in max9286_setup()
1040 priv->gpio_state |= BIT(offset); in max9286_gpio_set()
1042 priv->gpio_state &= ~BIT(offset); in max9286_gpio_set()
1045 MAX9286_0X0F_RESERVED | priv->gpio_state); in max9286_gpio_set()
1060 return priv->gpio_state & BIT(offset); in max9286_gpiochip_get()
1065 struct device *dev = &priv->client->dev; in max9286_register_gpio()
1066 struct gpio_chip *gpio = &priv->gpio; in max9286_register_gpio()
1070 gpio->label = dev_name(dev); in max9286_register_gpio()
1071 gpio->parent = dev; in max9286_register_gpio()
1072 gpio->owner = THIS_MODULE; in max9286_register_gpio()
1073 gpio->ngpio = 2; in max9286_register_gpio()
1074 gpio->base = -1; in max9286_register_gpio()
1075 gpio->set = max9286_gpiochip_set; in max9286_register_gpio()
1076 gpio->get = max9286_gpiochip_get; in max9286_register_gpio()
1077 gpio->can_sleep = true; in max9286_register_gpio()
1088 struct device *dev = &priv->client->dev; in max9286_parse_gpios()
1092 priv->gpio_state = BIT(0) | BIT(1); in max9286_parse_gpios()
1095 * Parse the "gpio-poc" vendor property. If the property is not in max9286_parse_gpios()
1098 ret = of_property_read_u32_array(dev->of_node, "maxim,gpio-poc", in max9286_parse_gpios()
1099 priv->gpio_poc, 2); in max9286_parse_gpios()
1100 if (ret == -EINVAL) { in max9286_parse_gpios()
1109 priv->regulator = devm_regulator_get(dev, "poc"); in max9286_parse_gpios()
1110 if (IS_ERR(priv->regulator)) { in max9286_parse_gpios()
1111 return dev_err_probe(dev, PTR_ERR(priv->regulator), in max9286_parse_gpios()
1113 PTR_ERR(priv->regulator)); in max9286_parse_gpios()
1120 if (ret || priv->gpio_poc[0] > 1 || in max9286_parse_gpios()
1121 (priv->gpio_poc[1] != GPIO_ACTIVE_HIGH && in max9286_parse_gpios()
1122 priv->gpio_poc[1] != GPIO_ACTIVE_LOW)) { in max9286_parse_gpios()
1123 dev_err(dev, "Invalid 'gpio-poc' property\n"); in max9286_parse_gpios()
1124 return -EINVAL; in max9286_parse_gpios()
1135 if (!priv->regulator) in max9286_poc_enable()
1136 ret = max9286_gpio_set(priv, priv->gpio_poc[0], in max9286_poc_enable()
1137 enable ^ priv->gpio_poc[1]); in max9286_poc_enable()
1139 ret = regulator_enable(priv->regulator); in max9286_poc_enable()
1141 ret = regulator_disable(priv->regulator); in max9286_poc_enable()
1144 dev_err(&priv->client->dev, "Unable to turn power %s\n", in max9286_poc_enable()
1152 struct i2c_client *client = priv->client; in max9286_init()
1161 dev_err(&client->dev, "Unable to setup max9286\n"); in max9286_init()
1171 dev_err(&client->dev, "Failed to register with V4L2\n"); in max9286_init()
1177 dev_err(&client->dev, "Unable to initialize I2C multiplexer\n"); in max9286_init()
1181 /* Leave the mux channels disabled until they are selected. */ in max9286_init()
1199 fwnode_handle_put(source->fwnode); in max9286_cleanup_dt()
1200 source->fwnode = NULL; in max9286_cleanup_dt()
1206 struct device *dev = &priv->client->dev; in max9286_parse_dt()
1213 of_node_get(dev->of_node); in max9286_parse_dt()
1214 i2c_mux = of_find_node_by_name(dev->of_node, "i2c-mux"); in max9286_parse_dt()
1216 dev_err(dev, "Failed to find i2c-mux node\n"); in max9286_parse_dt()
1217 return -EINVAL; in max9286_parse_dt()
1220 /* Identify which i2c-mux channels are enabled */ in max9286_parse_dt()
1239 for_each_endpoint_of_node(dev->of_node, node) { in max9286_parse_dt()
1267 priv->csi2_data_lanes = in max9286_parse_dt()
1277 if (priv->sources[ep.port].fwnode) { in max9286_parse_dt()
1285 source = &priv->sources[ep.port]; in max9286_parse_dt()
1286 source->fwnode = fwnode_graph_get_remote_endpoint( in max9286_parse_dt()
1288 if (!source->fwnode) { in max9286_parse_dt()
1296 priv->source_mask |= BIT(ep.port); in max9286_parse_dt()
1297 priv->nsources++; in max9286_parse_dt()
1308 if (of_property_read_u32(dev->of_node, in max9286_parse_dt()
1309 "maxim,reverse-channel-microvolt", in max9286_parse_dt()
1311 priv->init_rev_chan_mv = 170; in max9286_parse_dt()
1313 priv->init_rev_chan_mv = reverse_channel_microvolt / 1000U; in max9286_parse_dt()
1315 priv->route_mask = priv->source_mask; in max9286_parse_dt()
1325 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in max9286_probe()
1327 return -ENOMEM; in max9286_probe()
1329 mutex_init(&priv->mutex); in max9286_probe()
1331 priv->client = client; in max9286_probe()
1333 priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable", in max9286_probe()
1335 if (IS_ERR(priv->gpiod_pwdn)) in max9286_probe()
1336 return PTR_ERR(priv->gpiod_pwdn); in max9286_probe()
1338 gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn"); in max9286_probe()
1339 gpiod_set_value_cansleep(priv->gpiod_pwdn, 1); in max9286_probe()
1342 if (priv->gpiod_pwdn) in max9286_probe()
1353 * The MAX9286 initialises with auto-acknowledge enabled by default. in max9286_probe()
1376 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0); in max9286_probe()
1385 i2c_mux_del_adapters(priv->mux); in max9286_remove()
1391 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0); in max9286_remove()