Lines Matching +full:pwdn +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0
16 #include <media/media-entity.h>
17 #include <media/v4l2-async.h>
18 #include <media/v4l2-cci.h>
19 #include <media/v4l2-ctrls.h>
20 #include <media/v4l2-subdev.h>
21 #include <media/v4l2-fwnode.h>
251 /* pre-ISP control */
254 /* OTP-DPC control */
326 fmt->code = MEDIA_BUS_FMT_SBGGR10_1X10; in ov4689_fill_fmt()
327 fmt->width = mode->width; in ov4689_fill_fmt()
328 fmt->height = mode->height; in ov4689_fill_fmt()
329 fmt->field = V4L2_FIELD_NONE; in ov4689_fill_fmt()
336 struct v4l2_mbus_framefmt *mbus_fmt = &fmt->format; in ov4689_set_fmt()
340 ov4689_fill_fmt(ov4689->cur_mode, mbus_fmt); in ov4689_set_fmt()
349 if (code->index != 0) in ov4689_enum_mbus_code()
350 return -EINVAL; in ov4689_enum_mbus_code()
351 code->code = MEDIA_BUS_FMT_SBGGR10_1X10; in ov4689_enum_mbus_code()
360 if (fse->index >= ARRAY_SIZE(supported_modes)) in ov4689_enum_frame_sizes()
361 return -EINVAL; in ov4689_enum_frame_sizes()
363 if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10) in ov4689_enum_frame_sizes()
364 return -EINVAL; in ov4689_enum_frame_sizes()
366 fse->min_width = supported_modes[fse->index].width; in ov4689_enum_frame_sizes()
367 fse->max_width = supported_modes[fse->index].width; in ov4689_enum_frame_sizes()
368 fse->max_height = supported_modes[fse->index].height; in ov4689_enum_frame_sizes()
369 fse->min_height = supported_modes[fse->index].height; in ov4689_enum_frame_sizes()
379 val = (pattern - 1) | OV4689_TEST_PATTERN_ENABLE; in ov4689_enable_test_pattern()
383 return cci_write(ov4689->regmap, OV4689_REG_TEST_PATTERN, in ov4689_enable_test_pattern()
391 if (sel->which != V4L2_SUBDEV_FORMAT_ACTIVE) in ov4689_get_selection()
392 return -EINVAL; in ov4689_get_selection()
394 switch (sel->target) { in ov4689_get_selection()
396 sel->r.top = 0; in ov4689_get_selection()
397 sel->r.left = 0; in ov4689_get_selection()
398 sel->r.width = OV4689_PIXEL_ARRAY_WIDTH; in ov4689_get_selection()
399 sel->r.height = OV4689_PIXEL_ARRAY_HEIGHT; in ov4689_get_selection()
403 sel->r.top = OV4689_DUMMY_ROWS; in ov4689_get_selection()
404 sel->r.left = OV4689_DUMMY_COLUMNS; in ov4689_get_selection()
405 sel->r.width = in ov4689_get_selection()
406 OV4689_PIXEL_ARRAY_WIDTH - 2 * OV4689_DUMMY_COLUMNS; in ov4689_get_selection()
407 sel->r.height = in ov4689_get_selection()
408 OV4689_PIXEL_ARRAY_HEIGHT - 2 * OV4689_DUMMY_ROWS; in ov4689_get_selection()
412 return -EINVAL; in ov4689_get_selection()
417 const struct ov4689_mode *mode = ov4689->cur_mode; in ov4689_setup_timings()
418 struct regmap *rm = ov4689->regmap; in ov4689_setup_timings()
426 cci_write(rm, OV4689_REG_H_OUTPUT_SIZE, mode->width, &ret); in ov4689_setup_timings()
427 cci_write(rm, OV4689_REG_V_OUTPUT_SIZE, mode->height, &ret); in ov4689_setup_timings()
439 struct regmap *rm = ov4689->regmap; in ov4689_setup_blc_anchors()
454 struct device *dev = ov4689->dev; in ov4689_s_stream()
457 sd_state = v4l2_subdev_lock_and_get_active_state(&ov4689->subdev); in ov4689_s_stream()
464 ret = cci_multi_reg_write(ov4689->regmap, in ov4689_s_stream()
465 ov4689->cur_mode->reg_list, in ov4689_s_stream()
466 ov4689->cur_mode->num_regs, in ov4689_s_stream()
485 ret = __v4l2_ctrl_handler_setup(&ov4689->ctrl_handler); in ov4689_s_stream()
491 ret = cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, in ov4689_s_stream()
498 cci_write(ov4689->regmap, OV4689_REG_CTRL_MODE, in ov4689_s_stream()
514 DIV_ROUND_UP(ov4689->clock_rate, 1000)); in ov4689_cal_delay()
524 ret = clk_prepare_enable(ov4689->xvclk); in ov4689_power_on()
530 gpiod_set_value_cansleep(ov4689->reset_gpio, 1); in ov4689_power_on()
533 ov4689->supplies); in ov4689_power_on()
539 gpiod_set_value_cansleep(ov4689->reset_gpio, 0); in ov4689_power_on()
541 gpiod_set_value_cansleep(ov4689->pwdn_gpio, 0); in ov4689_power_on()
550 clk_disable_unprepare(ov4689->xvclk); in ov4689_power_on()
560 gpiod_set_value_cansleep(ov4689->pwdn_gpio, 1); in ov4689_power_off()
561 clk_disable_unprepare(ov4689->xvclk); in ov4689_power_off()
562 gpiod_set_value_cansleep(ov4689->reset_gpio, 1); in ov4689_power_off()
564 ov4689->supplies); in ov4689_power_off()
620 dev_warn_ratelimited(ov4689->dev, in ov4689_map_gain()
623 return -EINVAL; in ov4689_map_gain()
628 *result = clamp(range->offset + (logical_gain) / range->divider, in ov4689_map_gain()
629 range->physical_min, range->physical_max); in ov4689_map_gain()
636 container_of(ctrl->handler, struct ov4689, ctrl_handler); in ov4689_set_ctrl()
637 struct regmap *regmap = ov4689->regmap; in ov4689_set_ctrl()
638 struct device *dev = ov4689->dev; in ov4689_set_ctrl()
644 switch (ctrl->id) { in ov4689_set_ctrl()
647 max_expo = ov4689->cur_mode->height + ctrl->val - 4; in ov4689_set_ctrl()
648 __v4l2_ctrl_modify_range(ov4689->exposure, in ov4689_set_ctrl()
649 ov4689->exposure->minimum, max_expo, in ov4689_set_ctrl()
650 ov4689->exposure->step, in ov4689_set_ctrl()
651 ov4689->exposure->default_value); in ov4689_set_ctrl()
658 switch (ctrl->id) { in ov4689_set_ctrl()
661 cci_write(regmap, OV4689_REG_EXPOSURE, ctrl->val << 4, &ret); in ov4689_set_ctrl()
664 ret = ov4689_map_gain(ov4689, ctrl->val, &sensor_gain); in ov4689_set_ctrl()
669 ctrl->val + ov4689->cur_mode->height, &ret); in ov4689_set_ctrl()
672 ret = ov4689_enable_test_pattern(ov4689, ctrl->val); in ov4689_set_ctrl()
676 (ctrl->val + ov4689->cur_mode->width) / in ov4689_set_ctrl()
682 ctrl->val ? OV4689_TIMING_FLIP_BOTH : 0, &ret); in ov4689_set_ctrl()
687 ctrl->val ? 0 : OV4689_TIMING_FLIP_BOTH, &ret); in ov4689_set_ctrl()
690 cci_write(regmap, OV4689_REG_DIG_GAIN, ctrl->val, &ret); in ov4689_set_ctrl()
693 cci_write(regmap, OV4689_REG_WB_GAIN_RED, ctrl->val, &ret); in ov4689_set_ctrl()
696 cci_write(regmap, OV4689_REG_WB_GAIN_BLUE, ctrl->val, &ret); in ov4689_set_ctrl()
700 __func__, ctrl->id, ctrl->val); in ov4689_set_ctrl()
701 ret = -EINVAL; in ov4689_set_ctrl()
717 struct i2c_client *client = v4l2_get_subdevdata(&ov4689->subdev); in ov4689_initialize_controls()
726 handler = &ov4689->ctrl_handler; in ov4689_initialize_controls()
727 mode = ov4689->cur_mode; in ov4689_initialize_controls()
735 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in ov4689_initialize_controls()
738 mode->pixel_rate, 1, mode->pixel_rate); in ov4689_initialize_controls()
740 hblank_def = mode->hts_def - mode->width; in ov4689_initialize_controls()
741 hblank_min = mode->hts_min - mode->width; in ov4689_initialize_controls()
743 hblank_min, OV4689_HTS_MAX - mode->width, in ov4689_initialize_controls()
746 vblank_def = mode->vts_def - mode->height; in ov4689_initialize_controls()
748 vblank_def, OV4689_VTS_MAX - mode->height, 1, in ov4689_initialize_controls()
751 exposure_max = mode->vts_def - 4; in ov4689_initialize_controls()
752 ov4689->exposure = in ov4689_initialize_controls()
755 OV4689_EXPOSURE_STEP, mode->exp_def); in ov4689_initialize_controls()
759 ov4689_gain_ranges[ARRAY_SIZE(ov4689_gain_ranges) - 1] in ov4689_initialize_controls()
765 ARRAY_SIZE(ov4689_test_pattern_menu) - 1, in ov4689_initialize_controls()
783 if (handler->error) { in ov4689_initialize_controls()
784 ret = handler->error; in ov4689_initialize_controls()
785 dev_err(ov4689->dev, "Failed to init controls(%d)\n", ret); in ov4689_initialize_controls()
789 ret = v4l2_fwnode_device_parse(&client->dev, &props); in ov4689_initialize_controls()
798 ov4689->subdev.ctrl_handler = handler; in ov4689_initialize_controls()
811 struct device *dev = ov4689->dev; in ov4689_check_sensor_id()
815 ret = cci_read(ov4689->regmap, OV4689_REG_CHIP_ID, &id, NULL); in ov4689_check_sensor_id()
824 return -ENODEV; in ov4689_check_sensor_id()
837 ov4689->supplies[i].supply = ov4689_supply_names[i]; in ov4689_configure_regulators()
839 return devm_regulator_bulk_get(ov4689->dev, in ov4689_configure_regulators()
841 ov4689->supplies); in ov4689_configure_regulators()
850 for (j = 0; j < ep->nr_of_link_frequencies; j++) in ov4689_check_link_frequency()
851 if (freqs[i] == ep->link_frequencies[j]) in ov4689_check_link_frequency()
869 return -EINVAL; in ov4689_check_hwcfg()
877 dev_err(dev, "Only a 4-lane CSI2 config is supported"); in ov4689_check_hwcfg()
878 ret = -EINVAL; in ov4689_check_hwcfg()
884 ret = -EINVAL; in ov4689_check_hwcfg()
895 struct device *dev = &client->dev; in ov4689_probe()
906 return -ENOMEM; in ov4689_probe()
908 ov4689->dev = dev; in ov4689_probe()
910 ov4689->cur_mode = &supported_modes[OV4689_MODE_2688_1520]; in ov4689_probe()
912 ov4689->xvclk = devm_clk_get_optional(dev, NULL); in ov4689_probe()
913 if (IS_ERR(ov4689->xvclk)) in ov4689_probe()
914 return dev_err_probe(dev, PTR_ERR(ov4689->xvclk), in ov4689_probe()
917 if (!ov4689->xvclk) { in ov4689_probe()
919 "No clock provided, using clock-frequency property\n"); in ov4689_probe()
920 device_property_read_u32(dev, "clock-frequency", in ov4689_probe()
921 &ov4689->clock_rate); in ov4689_probe()
923 ov4689->clock_rate = clk_get_rate(ov4689->xvclk); in ov4689_probe()
926 if (ov4689->clock_rate != OV4689_XVCLK_FREQ) { in ov4689_probe()
929 ov4689->clock_rate, OV4689_XVCLK_FREQ); in ov4689_probe()
930 return -EINVAL; in ov4689_probe()
933 ov4689->regmap = devm_cci_regmap_init_i2c(client, 16); in ov4689_probe()
934 if (IS_ERR(ov4689->regmap)) { in ov4689_probe()
935 ret = PTR_ERR(ov4689->regmap); in ov4689_probe()
940 ov4689->reset_gpio = devm_gpiod_get_optional(dev, "reset", in ov4689_probe()
942 if (IS_ERR(ov4689->reset_gpio)) { in ov4689_probe()
943 dev_err(dev, "Failed to get reset-gpios\n"); in ov4689_probe()
944 return PTR_ERR(ov4689->reset_gpio); in ov4689_probe()
947 ov4689->pwdn_gpio = devm_gpiod_get_optional(dev, "pwdn", GPIOD_OUT_LOW); in ov4689_probe()
948 if (IS_ERR(ov4689->pwdn_gpio)) { in ov4689_probe()
949 dev_err(dev, "Failed to get pwdn-gpios\n"); in ov4689_probe()
950 return PTR_ERR(ov4689->pwdn_gpio); in ov4689_probe()
958 sd = &ov4689->subdev; in ov4689_probe()
960 sd->internal_ops = &ov4689_internal_ops; in ov4689_probe()
961 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in ov4689_probe()
977 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov4689_probe()
978 ov4689->pad.flags = MEDIA_PAD_FL_SOURCE; in ov4689_probe()
979 ret = media_entity_pads_init(&sd->entity, 1, &ov4689->pad); in ov4689_probe()
983 sd->state_lock = ov4689->ctrl_handler.lock; in ov4689_probe()
1012 media_entity_cleanup(&sd->entity); in ov4689_probe()
1016 v4l2_ctrl_handler_free(&ov4689->ctrl_handler); in ov4689_probe()
1027 media_entity_cleanup(&sd->entity); in ov4689_remove()
1029 v4l2_ctrl_handler_free(&ov4689->ctrl_handler); in ov4689_remove()
1031 pm_runtime_disable(&client->dev); in ov4689_remove()
1032 if (!pm_runtime_status_suspended(&client->dev)) in ov4689_remove()
1033 ov4689_power_off(&client->dev); in ov4689_remove()
1034 pm_runtime_set_suspended(&client->dev); in ov4689_remove()