Lines Matching +full:vdig +full:- +full:supply

1 // SPDX-License-Identifier: GPL-2.0
26 #include <media/v4l2-cci.h>
27 #include <media/v4l2-ctrls.h>
28 #include <media/v4l2-device.h>
29 #include <media/v4l2-event.h>
30 #include <media/v4l2-fwnode.h>
31 #include <media/v4l2-mediabus.h>
79 /* HBLANK control - read only */
157 /* V-timing */
164 /* To Access Addresses 3000-5fff, send the following commands */
232 "VANA", /* Analog (2.8V) supply */
233 "VDIG", /* Digital Core (1.8V) supply */
234 "VDDL", /* IF (1.2V) supply */
243 * - no flip
244 * - h flip
245 * - v flip
246 * - h&v flips
261 * Initialisation delay between XCLR low->high and the moment when the sensor
274 * This start-up time can be optimized a bit more, if we start the writes
279 * This delay doesn't account for the power supply startup time. If needed,
281 * case of DT for regulator-fixed one should define the startup-delay-us
357 i = (i & ~3) | (imx219->vflip->val ? 2 : 0) | in imx219_get_format_code()
358 (imx219->hflip->val ? 1 : 0); in imx219_get_format_code()
363 /* -----------------------------------------------------------------------------
370 container_of(ctrl->handler, struct imx219, ctrl_handler); in imx219_set_ctrl()
371 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_set_ctrl()
376 state = v4l2_subdev_get_locked_active_state(&imx219->sd); in imx219_set_ctrl()
379 if (ctrl->id == V4L2_CID_VBLANK) { in imx219_set_ctrl()
383 exposure_max = format->height + ctrl->val - 4; in imx219_set_ctrl()
386 __v4l2_ctrl_modify_range(imx219->exposure, in imx219_set_ctrl()
387 imx219->exposure->minimum, in imx219_set_ctrl()
388 exposure_max, imx219->exposure->step, in imx219_set_ctrl()
396 if (pm_runtime_get_if_in_use(&client->dev) == 0) in imx219_set_ctrl()
399 switch (ctrl->id) { in imx219_set_ctrl()
401 cci_write(imx219->regmap, IMX219_REG_ANALOG_GAIN, in imx219_set_ctrl()
402 ctrl->val, &ret); in imx219_set_ctrl()
405 cci_write(imx219->regmap, IMX219_REG_EXPOSURE, in imx219_set_ctrl()
406 ctrl->val, &ret); in imx219_set_ctrl()
409 cci_write(imx219->regmap, IMX219_REG_DIGITAL_GAIN, in imx219_set_ctrl()
410 ctrl->val, &ret); in imx219_set_ctrl()
413 cci_write(imx219->regmap, IMX219_REG_TEST_PATTERN, in imx219_set_ctrl()
414 imx219_test_pattern_val[ctrl->val], &ret); in imx219_set_ctrl()
418 cci_write(imx219->regmap, IMX219_REG_ORIENTATION, in imx219_set_ctrl()
419 imx219->hflip->val | imx219->vflip->val << 1, &ret); in imx219_set_ctrl()
422 cci_write(imx219->regmap, IMX219_REG_VTS, in imx219_set_ctrl()
423 format->height + ctrl->val, &ret); in imx219_set_ctrl()
426 cci_write(imx219->regmap, IMX219_REG_TESTP_RED, in imx219_set_ctrl()
427 ctrl->val, &ret); in imx219_set_ctrl()
430 cci_write(imx219->regmap, IMX219_REG_TESTP_GREENR, in imx219_set_ctrl()
431 ctrl->val, &ret); in imx219_set_ctrl()
434 cci_write(imx219->regmap, IMX219_REG_TESTP_BLUE, in imx219_set_ctrl()
435 ctrl->val, &ret); in imx219_set_ctrl()
438 cci_write(imx219->regmap, IMX219_REG_TESTP_GREENB, in imx219_set_ctrl()
439 ctrl->val, &ret); in imx219_set_ctrl()
442 dev_info(&client->dev, in imx219_set_ctrl()
444 ctrl->id, ctrl->val); in imx219_set_ctrl()
445 ret = -EINVAL; in imx219_set_ctrl()
449 pm_runtime_put(&client->dev); in imx219_set_ctrl()
460 return (imx219->lanes == 2) ? IMX219_PIXEL_RATE : IMX219_PIXEL_RATE_4LANE; in imx219_get_pixel_rate()
466 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_init_controls()
473 ctrl_hdlr = &imx219->ctrl_handler; in imx219_init_controls()
479 imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
485 imx219->link_freq = in imx219_init_controls()
488 ARRAY_SIZE(imx219_link_freq_menu) - 1, 0, in imx219_init_controls()
489 (imx219->lanes == 2) ? imx219_link_freq_menu : in imx219_init_controls()
491 if (imx219->link_freq) in imx219_init_controls()
492 imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx219_init_controls()
495 imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
497 IMX219_VTS_MAX - mode->height, 1, in imx219_init_controls()
498 mode->vts_def - mode->height); in imx219_init_controls()
499 hblank = IMX219_PPL_DEFAULT - mode->width; in imx219_init_controls()
500 imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
503 if (imx219->hblank) in imx219_init_controls()
504 imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx219_init_controls()
505 exposure_max = mode->vts_def - 4; in imx219_init_controls()
508 imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
522 imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
524 if (imx219->hflip) in imx219_init_controls()
525 imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; in imx219_init_controls()
527 imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
529 if (imx219->vflip) in imx219_init_controls()
530 imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; in imx219_init_controls()
534 ARRAY_SIZE(imx219_test_pattern_menu) - 1, in imx219_init_controls()
552 if (ctrl_hdlr->error) { in imx219_init_controls()
553 ret = ctrl_hdlr->error; in imx219_init_controls()
554 dev_err_probe(&client->dev, ret, "Control init failed\n"); in imx219_init_controls()
558 ret = v4l2_fwnode_device_parse(&client->dev, &props); in imx219_init_controls()
567 imx219->sd.ctrl_handler = ctrl_hdlr; in imx219_init_controls()
579 v4l2_ctrl_handler_free(imx219->sd.ctrl_handler); in imx219_free_controls()
582 /* -----------------------------------------------------------------------------
598 switch (format->code) { in imx219_set_framefmt()
615 cci_write(imx219->regmap, IMX219_REG_X_ADD_STA_A, in imx219_set_framefmt()
616 crop->left - IMX219_PIXEL_ARRAY_LEFT, &ret); in imx219_set_framefmt()
617 cci_write(imx219->regmap, IMX219_REG_X_ADD_END_A, in imx219_set_framefmt()
618 crop->left - IMX219_PIXEL_ARRAY_LEFT + crop->width - 1, &ret); in imx219_set_framefmt()
619 cci_write(imx219->regmap, IMX219_REG_Y_ADD_STA_A, in imx219_set_framefmt()
620 crop->top - IMX219_PIXEL_ARRAY_TOP, &ret); in imx219_set_framefmt()
621 cci_write(imx219->regmap, IMX219_REG_Y_ADD_END_A, in imx219_set_framefmt()
622 crop->top - IMX219_PIXEL_ARRAY_TOP + crop->height - 1, &ret); in imx219_set_framefmt()
624 switch (crop->width / format->width) { in imx219_set_framefmt()
634 switch (crop->height / format->height) { in imx219_set_framefmt()
644 cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_H, bin_h, &ret); in imx219_set_framefmt()
645 cci_write(imx219->regmap, IMX219_REG_BINNING_MODE_V, bin_v, &ret); in imx219_set_framefmt()
647 cci_write(imx219->regmap, IMX219_REG_X_OUTPUT_SIZE, in imx219_set_framefmt()
648 format->width, &ret); in imx219_set_framefmt()
649 cci_write(imx219->regmap, IMX219_REG_Y_OUTPUT_SIZE, in imx219_set_framefmt()
650 format->height, &ret); in imx219_set_framefmt()
652 cci_write(imx219->regmap, IMX219_REG_TP_WINDOW_WIDTH, in imx219_set_framefmt()
653 format->width, &ret); in imx219_set_framefmt()
654 cci_write(imx219->regmap, IMX219_REG_TP_WINDOW_HEIGHT, in imx219_set_framefmt()
655 format->height, &ret); in imx219_set_framefmt()
657 cci_write(imx219->regmap, IMX219_REG_CSI_DATA_FORMAT_A, in imx219_set_framefmt()
659 cci_write(imx219->regmap, IMX219_REG_OPPXCK_DIV, bpp, &ret); in imx219_set_framefmt()
666 return cci_write(imx219->regmap, IMX219_REG_CSI_LANE_MODE, in imx219_configure_lanes()
667 imx219->lanes == 2 ? IMX219_CSI_2_LANE_MODE : in imx219_configure_lanes()
674 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_start_streaming()
677 ret = pm_runtime_resume_and_get(&client->dev); in imx219_start_streaming()
682 ret = cci_multi_reg_write(imx219->regmap, imx219_common_regs, in imx219_start_streaming()
685 dev_err(&client->dev, "%s failed to send mfg header\n", __func__); in imx219_start_streaming()
692 dev_err(&client->dev, "%s failed to configure lanes\n", __func__); in imx219_start_streaming()
699 dev_err(&client->dev, "%s failed to set frame format: %d\n", in imx219_start_streaming()
705 ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); in imx219_start_streaming()
710 ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, in imx219_start_streaming()
716 __v4l2_ctrl_grab(imx219->vflip, true); in imx219_start_streaming()
717 __v4l2_ctrl_grab(imx219->hflip, true); in imx219_start_streaming()
722 pm_runtime_put(&client->dev); in imx219_start_streaming()
728 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_stop_streaming()
732 ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, in imx219_stop_streaming()
735 dev_err(&client->dev, "%s failed to set stream\n", __func__); in imx219_stop_streaming()
737 __v4l2_ctrl_grab(imx219->vflip, false); in imx219_stop_streaming()
738 __v4l2_ctrl_grab(imx219->hflip, false); in imx219_stop_streaming()
740 pm_runtime_put(&client->dev); in imx219_stop_streaming()
765 fmt->code = imx219_get_format_code(imx219, code); in imx219_update_pad_format()
766 fmt->width = mode->width; in imx219_update_pad_format()
767 fmt->height = mode->height; in imx219_update_pad_format()
768 fmt->field = V4L2_FIELD_NONE; in imx219_update_pad_format()
769 fmt->colorspace = V4L2_COLORSPACE_RAW; in imx219_update_pad_format()
770 fmt->ycbcr_enc = V4L2_YCBCR_ENC_601; in imx219_update_pad_format()
771 fmt->quantization = V4L2_QUANTIZATION_FULL_RANGE; in imx219_update_pad_format()
772 fmt->xfer_func = V4L2_XFER_FUNC_NONE; in imx219_update_pad_format()
781 if (code->index >= (ARRAY_SIZE(imx219_mbus_formats) / 4)) in imx219_enum_mbus_code()
782 return -EINVAL; in imx219_enum_mbus_code()
784 code->code = imx219_get_format_code(imx219, imx219_mbus_formats[code->index * 4]); in imx219_enum_mbus_code()
796 if (fse->index >= ARRAY_SIZE(supported_modes)) in imx219_enum_frame_size()
797 return -EINVAL; in imx219_enum_frame_size()
799 code = imx219_get_format_code(imx219, fse->code); in imx219_enum_frame_size()
800 if (fse->code != code) in imx219_enum_frame_size()
801 return -EINVAL; in imx219_enum_frame_size()
803 fse->min_width = supported_modes[fse->index].width; in imx219_enum_frame_size()
804 fse->max_width = fse->min_width; in imx219_enum_frame_size()
805 fse->min_height = supported_modes[fse->index].height; in imx219_enum_frame_size()
806 fse->max_height = fse->min_height; in imx219_enum_frame_size()
824 fmt->format.width, fmt->format.height); in imx219_set_pad_format()
826 imx219_update_pad_format(imx219, mode, &fmt->format, fmt->format.code); in imx219_set_pad_format()
829 *format = fmt->format; in imx219_set_pad_format()
835 bin_h = min(IMX219_PIXEL_ARRAY_WIDTH / format->width, 2U); in imx219_set_pad_format()
836 bin_v = min(IMX219_PIXEL_ARRAY_HEIGHT / format->height, 2U); in imx219_set_pad_format()
839 crop->width = format->width * bin_h; in imx219_set_pad_format()
840 crop->height = format->height * bin_v; in imx219_set_pad_format()
841 crop->left = (IMX219_NATIVE_WIDTH - crop->width) / 2; in imx219_set_pad_format()
842 crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2; in imx219_set_pad_format()
844 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { in imx219_set_pad_format()
850 __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN, in imx219_set_pad_format()
851 IMX219_VTS_MAX - mode->height, 1, in imx219_set_pad_format()
852 mode->vts_def - mode->height); in imx219_set_pad_format()
853 __v4l2_ctrl_s_ctrl(imx219->vblank, in imx219_set_pad_format()
854 mode->vts_def - mode->height); in imx219_set_pad_format()
856 exposure_max = mode->vts_def - 4; in imx219_set_pad_format()
859 __v4l2_ctrl_modify_range(imx219->exposure, in imx219_set_pad_format()
860 imx219->exposure->minimum, in imx219_set_pad_format()
861 exposure_max, imx219->exposure->step, in imx219_set_pad_format()
865 * depends on mode->width only, and is not changeble in any in imx219_set_pad_format()
868 hblank = IMX219_PPL_DEFAULT - mode->width; in imx219_set_pad_format()
869 __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, in imx219_set_pad_format()
880 switch (sel->target) { in imx219_get_selection()
882 sel->r = *v4l2_subdev_state_get_crop(state, 0); in imx219_get_selection()
887 sel->r.top = 0; in imx219_get_selection()
888 sel->r.left = 0; in imx219_get_selection()
889 sel->r.width = IMX219_NATIVE_WIDTH; in imx219_get_selection()
890 sel->r.height = IMX219_NATIVE_HEIGHT; in imx219_get_selection()
896 sel->r.top = IMX219_PIXEL_ARRAY_TOP; in imx219_get_selection()
897 sel->r.left = IMX219_PIXEL_ARRAY_LEFT; in imx219_get_selection()
898 sel->r.width = IMX219_PIXEL_ARRAY_WIDTH; in imx219_get_selection()
899 sel->r.height = IMX219_PIXEL_ARRAY_HEIGHT; in imx219_get_selection()
904 return -EINVAL; in imx219_get_selection()
952 /* -----------------------------------------------------------------------------
963 imx219->supplies); in imx219_power_on()
970 ret = clk_prepare_enable(imx219->xclk); in imx219_power_on()
977 gpiod_set_value_cansleep(imx219->reset_gpio, 1); in imx219_power_on()
984 regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); in imx219_power_on()
994 gpiod_set_value_cansleep(imx219->reset_gpio, 0); in imx219_power_off()
995 regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); in imx219_power_off()
996 clk_disable_unprepare(imx219->xclk); in imx219_power_off()
1001 /* -----------------------------------------------------------------------------
1007 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_get_regulators()
1011 imx219->supplies[i].supply = imx219_supply_name[i]; in imx219_get_regulators()
1013 return devm_regulator_bulk_get(&client->dev, in imx219_get_regulators()
1015 imx219->supplies); in imx219_get_regulators()
1021 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_identify_module()
1025 ret = cci_read(imx219->regmap, IMX219_REG_CHIP_ID, &val, NULL); in imx219_identify_module()
1027 return dev_err_probe(&client->dev, ret, in imx219_identify_module()
1032 return dev_err_probe(&client->dev, -EIO, in imx219_identify_module()
1045 int ret = -EINVAL; in imx219_check_hwcfg()
1049 return dev_err_probe(dev, -EINVAL, "endpoint node not found\n"); in imx219_check_hwcfg()
1052 dev_err_probe(dev, -EINVAL, "could not parse endpoint\n"); in imx219_check_hwcfg()
1059 dev_err_probe(dev, -EINVAL, in imx219_check_hwcfg()
1063 imx219->lanes = ep_cfg.bus.mipi_csi2.num_data_lanes; in imx219_check_hwcfg()
1067 dev_err_probe(dev, -EINVAL, in imx219_check_hwcfg()
1068 "link-frequency property not found in DT\n"); in imx219_check_hwcfg()
1073 (ep_cfg.link_frequencies[0] != ((imx219->lanes == 2) ? in imx219_check_hwcfg()
1075 dev_err_probe(dev, -EINVAL, in imx219_check_hwcfg()
1092 struct device *dev = &client->dev; in imx219_probe()
1096 imx219 = devm_kzalloc(&client->dev, sizeof(*imx219), GFP_KERNEL); in imx219_probe()
1098 return -ENOMEM; in imx219_probe()
1100 v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops); in imx219_probe()
1101 imx219->sd.internal_ops = &imx219_internal_ops; in imx219_probe()
1105 return -EINVAL; in imx219_probe()
1107 imx219->regmap = devm_cci_regmap_init_i2c(client, 16); in imx219_probe()
1108 if (IS_ERR(imx219->regmap)) in imx219_probe()
1109 return dev_err_probe(dev, PTR_ERR(imx219->regmap), in imx219_probe()
1113 imx219->xclk = devm_clk_get(dev, NULL); in imx219_probe()
1114 if (IS_ERR(imx219->xclk)) in imx219_probe()
1115 return dev_err_probe(dev, PTR_ERR(imx219->xclk), in imx219_probe()
1118 imx219->xclk_freq = clk_get_rate(imx219->xclk); in imx219_probe()
1119 if (imx219->xclk_freq != IMX219_XCLK_FREQ) in imx219_probe()
1120 return dev_err_probe(dev, -EINVAL, in imx219_probe()
1122 imx219->xclk_freq); in imx219_probe()
1129 imx219->reset_gpio = devm_gpiod_get_optional(dev, "reset", in imx219_probe()
1145 * Sensor doesn't enter LP-11 state upon power up until and unless in imx219_probe()
1147 * streaming -> standby in imx219_probe()
1149 ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, in imx219_probe()
1157 ret = cci_write(imx219->regmap, IMX219_REG_MODE_SELECT, in imx219_probe()
1169 imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in imx219_probe()
1171 imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in imx219_probe()
1174 imx219->pad.flags = MEDIA_PAD_FL_SOURCE; in imx219_probe()
1176 ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad); in imx219_probe()
1182 imx219->sd.state_lock = imx219->ctrl_handler.lock; in imx219_probe()
1183 ret = v4l2_subdev_init_finalize(&imx219->sd); in imx219_probe()
1189 ret = v4l2_async_register_subdev_sensor(&imx219->sd); in imx219_probe()
1192 "failed to register sensor sub-device\n"); in imx219_probe()
1204 v4l2_subdev_cleanup(&imx219->sd); in imx219_probe()
1207 media_entity_cleanup(&imx219->sd.entity); in imx219_probe()
1225 media_entity_cleanup(&sd->entity); in imx219_remove()
1228 pm_runtime_disable(&client->dev); in imx219_remove()
1229 if (!pm_runtime_status_suspended(&client->dev)) in imx219_remove()
1230 imx219_power_off(&client->dev); in imx219_remove()
1231 pm_runtime_set_suspended(&client->dev); in imx219_remove()