Lines Matching +full:out +full:- +full:amplitude +full:- +full:microvolt
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>
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)
122 #define MAX9286_REV_AMP(n) ((((n) - 30) / 10) << 1) /* in mV */
127 #define MAX9286_REV_FLEN(n) ((n) - 20)
187 /* The initial reverse control channel amplitude. */
213 source = &priv->sources[0]; in next_source()
217 for (; source < &priv->sources[MAX9286_NUM_GMSL]; source++) { in next_source()
218 if (source->fwnode) in next_source()
228 #define to_index(priv, source) ((source) - &(priv)->sources[0])
274 /* -----------------------------------------------------------------------------
282 ret = i2c_smbus_read_byte_data(priv->client, reg); in max9286_read()
284 dev_err(&priv->client->dev, in max9286_read()
295 ret = i2c_smbus_write_byte_data(priv->client, reg, val); in max9286_write()
297 dev_err(&priv->client->dev, in max9286_write()
304 /* -----------------------------------------------------------------------------
324 priv->mux_open = true; in max9286_i2c_mux_open()
336 priv->mux_open = false; in max9286_i2c_mux_close()
337 priv->mux_channel = -1; in max9286_i2c_mux_close()
345 if (priv->mux_open) in max9286_i2c_mux_select()
348 if (priv->mux_channel == chan) in max9286_i2c_mux_select()
351 priv->mux_channel = chan; in max9286_i2c_mux_select()
364 if (!i2c_check_functionality(priv->client->adapter, in max9286_i2c_mux_init()
366 return -ENODEV; in max9286_i2c_mux_init()
368 priv->mux = i2c_mux_alloc(priv->client->adapter, &priv->client->dev, in max9286_i2c_mux_init()
369 priv->nsources, 0, I2C_MUX_LOCKED, in max9286_i2c_mux_init()
371 if (!priv->mux) in max9286_i2c_mux_init()
372 return -ENOMEM; in max9286_i2c_mux_init()
374 priv->mux->priv = priv; in max9286_i2c_mux_init()
379 ret = i2c_mux_add_adapter(priv->mux, 0, index); in max9286_i2c_mux_init()
387 i2c_mux_del_adapters(priv->mux); in max9286_i2c_mux_init()
394 priv->i2c_mstbt; in max9286_configure_i2c()
408 if (priv->rev_chan_mv == chan_amplitude) in max9286_reverse_channel_setup()
411 priv->rev_chan_mv = chan_amplitude; in max9286_reverse_channel_setup()
419 * - Enable custom reverse channel configuration (through register 0x3f) in max9286_reverse_channel_setup()
421 * - Adjust reverse channel amplitude: values > 130 are programmed in max9286_reverse_channel_setup()
428 chan_amplitude = max(30U, chan_amplitude - 100); in max9286_reverse_channel_setup()
436 * max9286_check_video_links() - Make sure video links are detected and locked
441 * Returns 0 for success, -EIO for errors.
450 * The delay is not characterized in de-serializer manual, wait up in max9286_check_video_links()
456 return -EIO; in max9286_check_video_links()
458 if ((ret & MAX9286_VIDEO_DETECT_MASK) == priv->source_mask) in max9286_check_video_links()
465 dev_err(&priv->client->dev, in max9286_check_video_links()
467 return -EIO; in max9286_check_video_links()
474 return -EIO; in max9286_check_video_links()
483 dev_err(&priv->client->dev, "Not all enabled links locked\n"); in max9286_check_video_links()
484 return -EIO; in max9286_check_video_links()
491 * max9286_check_config_link() - Detect and wait for configuration links
495 * Returns 0 for success, -EIO for errors.
512 return -EIO; in max9286_check_config_link()
522 dev_err(&priv->client->dev, in max9286_check_config_link()
525 return -EIO; in max9286_check_config_link()
528 dev_info(&priv->client->dev, in max9286_check_config_link()
542 if (max9286_formats[i].code == format->code) { in max9286_set_video_format()
554 * in external GPI-to-GPO mode. in max9286_set_video_format()
559 /* Enable CSI-2 Lane D0-D3 only, DBL mode. */ in max9286_set_video_format()
561 MAX9286_CSILANECNT(priv->csi2_data_lanes) | in max9286_set_video_format()
562 info->datatype); in max9286_set_video_format()
579 if (!interval->numerator || !interval->denominator) { in max9286_set_fsync_period()
595 fsync = div_u64((u64)priv->pixelrate * interval->numerator, in max9286_set_fsync_period()
596 interval->denominator); in max9286_set_fsync_period()
598 dev_dbg(&priv->client->dev, "fsync period %u (pclk %u)\n", fsync, in max9286_set_fsync_period()
599 priv->pixelrate); in max9286_set_fsync_period()
609 /* -----------------------------------------------------------------------------
623 ctrl = v4l2_ctrl_find(source->sd->ctrl_handler, in max9286_set_pixelrate()
635 dev_err(&priv->client->dev, in max9286_set_pixelrate()
637 return -EINVAL; in max9286_set_pixelrate()
642 dev_err(&priv->client->dev, in max9286_set_pixelrate()
644 return -EINVAL; in max9286_set_pixelrate()
647 priv->pixelrate = pixelrate; in max9286_set_pixelrate()
650 * The CSI-2 transmitter pixel rate is the single source rate multiplied in max9286_set_pixelrate()
653 return v4l2_ctrl_s_ctrl_int64(priv->pixelrate_ctrl, in max9286_set_pixelrate()
654 pixelrate * priv->nsources); in max9286_set_pixelrate()
661 struct max9286_priv *priv = sd_to_max9286(notifier->sd); in max9286_notify_bound()
662 struct max9286_source *source = to_max9286_asd(asd)->source; in max9286_notify_bound()
667 ret = media_entity_get_fwnode_pad(&subdev->entity, in max9286_notify_bound()
668 source->fwnode, in max9286_notify_bound()
671 dev_err(&priv->client->dev, in max9286_notify_bound()
672 "Failed to find pad for %s\n", subdev->name); in max9286_notify_bound()
676 priv->bound_sources |= BIT(index); in max9286_notify_bound()
677 source->sd = subdev; in max9286_notify_bound()
680 ret = media_create_pad_link(&source->sd->entity, src_pad, in max9286_notify_bound()
681 &priv->sd.entity, index, in max9286_notify_bound()
685 dev_err(&priv->client->dev, in max9286_notify_bound()
686 "Unable to link %s:%u -> %s:%u\n", in max9286_notify_bound()
687 source->sd->name, src_pad, priv->sd.name, index); in max9286_notify_bound()
691 dev_dbg(&priv->client->dev, "Bound %s pad: %u on index %u\n", in max9286_notify_bound()
692 subdev->name, src_pad, index); in max9286_notify_bound()
699 if (priv->bound_sources != priv->source_mask) in max9286_notify_bound()
706 * - Increase the reverse channel amplitude to compensate for the in max9286_notify_bound()
708 * - Verify all configuration links are properly detected in max9286_notify_bound()
709 * - Disable auto-ack as communication on the control channel are now in max9286_notify_bound()
713 max9286_check_config_link(priv, priv->source_mask); in max9286_notify_bound()
723 struct max9286_priv *priv = sd_to_max9286(notifier->sd); in max9286_notify_unbind()
724 struct max9286_source *source = to_max9286_asd(asd)->source; in max9286_notify_unbind()
727 source->sd = NULL; in max9286_notify_unbind()
728 priv->bound_sources &= ~BIT(index); in max9286_notify_unbind()
738 struct device *dev = &priv->client->dev; in max9286_v4l2_notifier_register()
742 if (!priv->nsources) in max9286_v4l2_notifier_register()
745 v4l2_async_subdev_nf_init(&priv->notifier, &priv->sd); in max9286_v4l2_notifier_register()
751 mas = v4l2_async_nf_add_fwnode(&priv->notifier, source->fwnode, in max9286_v4l2_notifier_register()
756 v4l2_async_nf_cleanup(&priv->notifier); in max9286_v4l2_notifier_register()
760 mas->source = source; in max9286_v4l2_notifier_register()
763 priv->notifier.ops = &max9286_notify_ops; in max9286_v4l2_notifier_register()
765 ret = v4l2_async_nf_register(&priv->notifier); in max9286_v4l2_notifier_register()
768 v4l2_async_nf_cleanup(&priv->notifier); in max9286_v4l2_notifier_register()
777 if (!priv->nsources) in max9286_v4l2_notifier_unregister()
780 v4l2_async_nf_unregister(&priv->notifier); in max9286_v4l2_notifier_unregister()
781 v4l2_async_nf_cleanup(&priv->notifier); in max9286_v4l2_notifier_unregister()
816 ret = v4l2_subdev_call(source->sd, video, s_stream, 1); in max9286_s_stream()
842 dev_err(&priv->client->dev, in max9286_s_stream()
844 ret = -EXDEV; /* Invalid cross-device link */ in max9286_s_stream()
849 * Configure the CSI-2 output to line interleaved mode (W x (N in max9286_s_stream()
851 * images stitched side-by-side) and enable it. in max9286_s_stream()
863 v4l2_subdev_call(source->sd, video, s_stream, 0); in max9286_s_stream()
878 if (interval->pad != MAX9286_SRC_PAD) in max9286_get_frame_interval()
879 return -EINVAL; in max9286_get_frame_interval()
881 interval->interval = *v4l2_subdev_state_get_interval(sd_state, in max9286_get_frame_interval()
882 interval->pad); in max9286_get_frame_interval()
891 if (interval->pad != MAX9286_SRC_PAD) in max9286_set_frame_interval()
892 return -EINVAL; in max9286_set_frame_interval()
895 interval->pad) = interval->interval; in max9286_set_frame_interval()
904 if (code->pad || code->index >= ARRAY_SIZE(max9286_formats)) in max9286_enum_mbus_code()
905 return -EINVAL; in max9286_enum_mbus_code()
907 code->code = max9286_formats[code->index].code; in max9286_enum_mbus_code()
924 if (format->pad == MAX9286_SRC_PAD) in max9286_set_fmt()
929 if (max9286_formats[i].code == format->format.code) in max9286_set_fmt()
934 format->format.code = max9286_formats[0].code; in max9286_set_fmt()
943 *v4l2_subdev_state_get_format(state, index) = format->format; in max9286_set_fmt()
946 *v4l2_subdev_state_get_format(state, MAX9286_SRC_PAD) = format->format; in max9286_set_fmt()
994 interval->numerator = 0; in max9286_init_state()
995 interval->denominator = 0; in max9286_init_state()
1010 switch (ctrl->id) { in max9286_s_ctrl()
1014 return -EINVAL; in max9286_s_ctrl()
1024 struct device *dev = &priv->client->dev; in max9286_v4l2_register()
1036 v4l2_i2c_subdev_init(&priv->sd, priv->client, &max9286_subdev_ops); in max9286_v4l2_register()
1037 priv->sd.internal_ops = &max9286_subdev_internal_ops; in max9286_v4l2_register()
1038 priv->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in max9286_v4l2_register()
1040 v4l2_ctrl_handler_init(&priv->ctrls, 1); in max9286_v4l2_register()
1041 priv->pixelrate_ctrl = v4l2_ctrl_new_std(&priv->ctrls, in max9286_v4l2_register()
1046 priv->sd.ctrl_handler = &priv->ctrls; in max9286_v4l2_register()
1047 ret = priv->ctrls.error; in max9286_v4l2_register()
1051 priv->sd.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE; in max9286_v4l2_register()
1052 priv->sd.entity.ops = &max9286_media_ops; in max9286_v4l2_register()
1054 priv->pads[MAX9286_SRC_PAD].flags = MEDIA_PAD_FL_SOURCE; in max9286_v4l2_register()
1056 priv->pads[i].flags = MEDIA_PAD_FL_SINK; in max9286_v4l2_register()
1057 ret = media_entity_pads_init(&priv->sd.entity, MAX9286_N_PADS, in max9286_v4l2_register()
1058 priv->pads); in max9286_v4l2_register()
1062 priv->sd.state_lock = priv->ctrls.lock; in max9286_v4l2_register()
1063 ret = v4l2_subdev_init_finalize(&priv->sd); in max9286_v4l2_register()
1067 ret = v4l2_async_register_subdev(&priv->sd); in max9286_v4l2_register()
1076 v4l2_subdev_cleanup(&priv->sd); in max9286_v4l2_register()
1078 v4l2_ctrl_handler_free(&priv->ctrls); in max9286_v4l2_register()
1086 v4l2_subdev_cleanup(&priv->sd); in max9286_v4l2_unregister()
1087 v4l2_ctrl_handler_free(&priv->ctrls); in max9286_v4l2_unregister()
1088 v4l2_async_unregister_subdev(&priv->sd); in max9286_v4l2_unregister()
1092 /* -----------------------------------------------------------------------------
1132 max9286_reverse_channel_setup(priv, priv->init_rev_chan_mv); in max9286_setup()
1138 max9286_write(priv, 0x00, MAX9286_MSTLINKSEL_AUTO | priv->route_mask); in max9286_setup()
1139 max9286_write(priv, 0x0b, link_order[priv->route_mask]); in max9286_setup()
1140 max9286_write(priv, 0x69, (0xf & ~priv->route_mask)); in max9286_setup()
1148 dev_dbg(&priv->client->dev, "power-up config: %s immunity, %u-bit bus\n", in max9286_setup()
1152 if (priv->bus_width) { in max9286_setup()
1155 if (priv->bus_width == 27) in max9286_setup()
1157 else if (priv->bus_width == 32) in max9286_setup()
1188 priv->gpio_state |= BIT(offset); in max9286_gpio_set()
1190 priv->gpio_state &= ~BIT(offset); in max9286_gpio_set()
1193 MAX9286_0X0F_RESERVED | priv->gpio_state); in max9286_gpio_set()
1208 return priv->gpio_state & BIT(offset); in max9286_gpiochip_get()
1213 struct device *dev = &priv->client->dev; in max9286_register_gpio()
1214 struct gpio_chip *gpio = &priv->gpio; in max9286_register_gpio()
1218 gpio->label = dev_name(dev); in max9286_register_gpio()
1219 gpio->parent = dev; in max9286_register_gpio()
1220 gpio->owner = THIS_MODULE; in max9286_register_gpio()
1221 gpio->ngpio = 2; in max9286_register_gpio()
1222 gpio->base = -1; in max9286_register_gpio()
1223 gpio->set = max9286_gpiochip_set; in max9286_register_gpio()
1224 gpio->get = max9286_gpiochip_get; in max9286_register_gpio()
1225 gpio->can_sleep = true; in max9286_register_gpio()
1236 struct device *dev = &priv->client->dev; in max9286_parse_gpios()
1240 * Parse the "gpio-poc" vendor property. If the property is not in max9286_parse_gpios()
1243 ret = of_property_read_u32_array(dev->of_node, "maxim,gpio-poc", in max9286_parse_gpios()
1244 priv->gpio_poc, 2); in max9286_parse_gpios()
1245 if (ret == -EINVAL) { in max9286_parse_gpios()
1254 if (ret || priv->gpio_poc[0] > 1 || in max9286_parse_gpios()
1255 (priv->gpio_poc[1] != GPIO_ACTIVE_HIGH && in max9286_parse_gpios()
1256 priv->gpio_poc[1] != GPIO_ACTIVE_LOW)) { in max9286_parse_gpios()
1257 dev_err(dev, "Invalid 'gpio-poc' property\n"); in max9286_parse_gpios()
1258 return -EINVAL; in max9286_parse_gpios()
1261 priv->use_gpio_poc = true; in max9286_parse_gpios()
1272 if (priv->regulator) in max9286_poc_power_on()
1273 return regulator_enable(priv->regulator); in max9286_poc_power_on()
1275 if (priv->use_gpio_poc) in max9286_poc_power_on()
1276 return max9286_gpio_set(priv, priv->gpio_poc[0], in max9286_poc_power_on()
1277 !priv->gpio_poc[1]); in max9286_poc_power_on()
1279 /* Otherwise use the per-port regulators. */ in max9286_poc_power_on()
1281 ret = regulator_enable(source->regulator); in max9286_poc_power_on()
1293 regulator_disable(source->regulator); in max9286_poc_power_on()
1304 if (priv->regulator) in max9286_poc_power_off()
1305 return regulator_disable(priv->regulator); in max9286_poc_power_off()
1307 if (priv->use_gpio_poc) in max9286_poc_power_off()
1308 return max9286_gpio_set(priv, priv->gpio_poc[0], in max9286_poc_power_off()
1309 priv->gpio_poc[1]); in max9286_poc_power_off()
1314 err = regulator_disable(source->regulator); in max9286_poc_power_off()
1332 dev_err(&priv->client->dev, "Unable to turn power %s\n", in max9286_poc_enable()
1340 struct i2c_client *client = priv->client; in max9286_init()
1349 dev_err(&client->dev, "Unable to setup max9286\n"); in max9286_init()
1359 dev_err(&client->dev, "Failed to register with V4L2\n"); in max9286_init()
1365 dev_err(&client->dev, "Unable to initialize I2C multiplexer\n"); in max9286_init()
1387 fwnode_handle_put(source->fwnode); in max9286_cleanup_dt()
1388 source->fwnode = NULL; in max9286_cleanup_dt()
1394 struct device *dev = &priv->client->dev; in max9286_parse_dt()
1403 of_node_get(dev->of_node); in max9286_parse_dt()
1404 i2c_mux = of_find_node_by_name(dev->of_node, "i2c-mux"); in max9286_parse_dt()
1406 dev_err(dev, "Failed to find i2c-mux node\n"); in max9286_parse_dt()
1407 return -EINVAL; in max9286_parse_dt()
1410 /* Identify which i2c-mux channels are enabled */ in max9286_parse_dt()
1428 for_each_endpoint_of_node(dev->of_node, node) { in max9286_parse_dt()
1456 priv->csi2_data_lanes = in max9286_parse_dt()
1466 if (priv->sources[ep.port].fwnode) { in max9286_parse_dt()
1474 source = &priv->sources[ep.port]; in max9286_parse_dt()
1475 source->fwnode = fwnode_graph_get_remote_endpoint( in max9286_parse_dt()
1477 if (!source->fwnode) { in max9286_parse_dt()
1485 priv->source_mask |= BIT(ep.port); in max9286_parse_dt()
1486 priv->nsources++; in max9286_parse_dt()
1489 of_property_read_u32(dev->of_node, "maxim,bus-width", &priv->bus_width); in max9286_parse_dt()
1490 switch (priv->bus_width) { in max9286_parse_dt()
1501 dev_err(dev, "Invalid %s value %u\n", "maxim,bus-width", in max9286_parse_dt()
1502 priv->bus_width); in max9286_parse_dt()
1503 return -EINVAL; in max9286_parse_dt()
1506 of_property_read_u32(dev->of_node, "maxim,i2c-remote-bus-hz", in max9286_parse_dt()
1511 if (speed->rate == i2c_clk_freq) { in max9286_parse_dt()
1512 priv->i2c_mstbt = speed->mstbt; in max9286_parse_dt()
1518 dev_err(dev, "Invalid %s value %u\n", "maxim,i2c-remote-bus-hz", in max9286_parse_dt()
1520 return -EINVAL; in max9286_parse_dt()
1524 * Parse the initial value of the reverse channel amplitude from in max9286_parse_dt()
1530 if (of_property_read_u32(dev->of_node, in max9286_parse_dt()
1531 "maxim,reverse-channel-microvolt", in max9286_parse_dt()
1533 priv->init_rev_chan_mv = 170; in max9286_parse_dt()
1535 priv->init_rev_chan_mv = reverse_channel_microvolt / 1000U; in max9286_parse_dt()
1537 priv->route_mask = priv->source_mask; in max9286_parse_dt()
1544 struct device *dev = &priv->client->dev; in max9286_get_poc_supplies()
1549 priv->regulator = devm_regulator_get_optional(dev, "poc"); in max9286_get_poc_supplies()
1550 if (!IS_ERR(priv->regulator)) in max9286_get_poc_supplies()
1553 if (PTR_ERR(priv->regulator) != -ENODEV) in max9286_get_poc_supplies()
1554 return dev_err_probe(dev, PTR_ERR(priv->regulator), in max9286_get_poc_supplies()
1557 /* If there's no global regulator, get per-port regulators. */ in max9286_get_poc_supplies()
1559 "No global PoC regulator, looking for per-port regulators\n"); in max9286_get_poc_supplies()
1560 priv->regulator = NULL; in max9286_get_poc_supplies()
1566 snprintf(name, sizeof(name), "port%u-poc", index); in max9286_get_poc_supplies()
1567 source->regulator = devm_regulator_get(dev, name); in max9286_get_poc_supplies()
1568 if (IS_ERR(source->regulator)) { in max9286_get_poc_supplies()
1569 ret = PTR_ERR(source->regulator); in max9286_get_poc_supplies()
1585 priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL); in max9286_probe()
1587 return -ENOMEM; in max9286_probe()
1589 priv->client = client; in max9286_probe()
1592 priv->gpio_state = BIT(0) | BIT(1); in max9286_probe()
1598 priv->gpiod_pwdn = devm_gpiod_get_optional(&client->dev, "enable", in max9286_probe()
1600 if (IS_ERR(priv->gpiod_pwdn)) { in max9286_probe()
1601 ret = PTR_ERR(priv->gpiod_pwdn); in max9286_probe()
1605 gpiod_set_consumer_name(priv->gpiod_pwdn, "max9286-pwdn"); in max9286_probe()
1606 gpiod_set_value_cansleep(priv->gpiod_pwdn, 1); in max9286_probe()
1609 if (priv->gpiod_pwdn) in max9286_probe()
1614 * ports early to ensure that all channels are disabled if we error out in max9286_probe()
1620 * The MAX9286 initialises with auto-acknowledge enabled by default. in max9286_probe()
1630 if (!priv->use_gpio_poc) { in max9286_probe()
1643 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0); in max9286_probe()
1654 i2c_mux_del_adapters(priv->mux); in max9286_remove()
1660 gpiod_set_value_cansleep(priv->gpiod_pwdn, 0); in max9286_remove()