Lines Matching full:ov5693

5  * Adapted from the atomisp-ov5693 driver, with contributions from:
39 /* Yes, this is right. The datasheet for the OV5693 gives its ID as 0x5690 */
356 static int ov5693_flip_vert_configure(struct ov5693_device *ov5693, in ov5693_flip_vert_configure() argument
363 ret = cci_update_bits(ov5693->regmap, OV5693_FORMAT1_REG, bits, in ov5693_flip_vert_configure()
371 static int ov5693_flip_horz_configure(struct ov5693_device *ov5693, in ov5693_flip_horz_configure() argument
378 ret = cci_update_bits(ov5693->regmap, OV5693_FORMAT2_REG, bits, in ov5693_flip_horz_configure()
386 static int ov5693_get_exposure(struct ov5693_device *ov5693, s32 *value) in ov5693_get_exposure() argument
391 ret = cci_read(ov5693->regmap, OV5693_EXPOSURE_CTRL_REG, &exposure, in ov5693_get_exposure()
402 static int ov5693_exposure_configure(struct ov5693_device *ov5693, in ov5693_exposure_configure() argument
409 cci_write(ov5693->regmap, OV5693_EXPOSURE_CTRL_REG, exposure, &ret); in ov5693_exposure_configure()
414 static int ov5693_get_gain(struct ov5693_device *ov5693, u32 *gain) in ov5693_get_gain() argument
419 ret = cci_read(ov5693->regmap, OV5693_GAIN_CTRL_REG, &value, NULL); in ov5693_get_gain()
429 static int ov5693_digital_gain_configure(struct ov5693_device *ov5693, in ov5693_digital_gain_configure() argument
436 cci_write(ov5693->regmap, OV5693_MWB_RED_GAIN_REG, gain, &ret); in ov5693_digital_gain_configure()
437 cci_write(ov5693->regmap, OV5693_MWB_GREEN_GAIN_REG, gain, &ret); in ov5693_digital_gain_configure()
438 cci_write(ov5693->regmap, OV5693_MWB_BLUE_GAIN_REG, gain, &ret); in ov5693_digital_gain_configure()
443 static int ov5693_analog_gain_configure(struct ov5693_device *ov5693, u32 gain) in ov5693_analog_gain_configure() argument
449 cci_write(ov5693->regmap, OV5693_GAIN_CTRL_REG, gain, &ret); in ov5693_analog_gain_configure()
454 static int ov5693_vts_configure(struct ov5693_device *ov5693, u32 vblank) in ov5693_vts_configure() argument
456 u16 vts = ov5693->mode.format.height + vblank; in ov5693_vts_configure()
459 cci_write(ov5693->regmap, OV5693_TIMING_VTS_REG, vts, &ret); in ov5693_vts_configure()
464 static int ov5693_test_pattern_configure(struct ov5693_device *ov5693, u32 idx) in ov5693_test_pattern_configure() argument
468 cci_write(ov5693->regmap, OV5693_TEST_PATTERN_REG, in ov5693_test_pattern_configure()
476 struct ov5693_device *ov5693 = in ov5693_s_ctrl() local
484 exposure_max = ov5693->mode.format.height + ctrl->val - in ov5693_s_ctrl()
486 __v4l2_ctrl_modify_range(ov5693->ctrls.exposure, in ov5693_s_ctrl()
487 ov5693->ctrls.exposure->minimum, in ov5693_s_ctrl()
489 ov5693->ctrls.exposure->step, in ov5693_s_ctrl()
490 min(ov5693->ctrls.exposure->val, in ov5693_s_ctrl()
495 if (!pm_runtime_get_if_in_use(ov5693->dev)) in ov5693_s_ctrl()
500 ret = ov5693_exposure_configure(ov5693, ctrl->val); in ov5693_s_ctrl()
503 ret = ov5693_analog_gain_configure(ov5693, ctrl->val); in ov5693_s_ctrl()
506 ret = ov5693_digital_gain_configure(ov5693, ctrl->val); in ov5693_s_ctrl()
509 ret = ov5693_flip_horz_configure(ov5693, !!ctrl->val); in ov5693_s_ctrl()
512 ret = ov5693_flip_vert_configure(ov5693, !!ctrl->val); in ov5693_s_ctrl()
515 ret = ov5693_vts_configure(ov5693, ctrl->val); in ov5693_s_ctrl()
518 ret = ov5693_test_pattern_configure(ov5693, ctrl->val); in ov5693_s_ctrl()
524 pm_runtime_put(ov5693->dev); in ov5693_s_ctrl()
531 struct ov5693_device *ov5693 = container_of(ctrl->handler, in ov5693_g_volatile_ctrl() local
537 return ov5693_get_exposure(ov5693, &ctrl->val); in ov5693_g_volatile_ctrl()
539 return ov5693_get_gain(ov5693, &ctrl->val); in ov5693_g_volatile_ctrl()
552 static int ov5693_mode_configure(struct ov5693_device *ov5693) in ov5693_mode_configure() argument
554 const struct ov5693_mode *mode = &ov5693->mode; in ov5693_mode_configure()
558 cci_write(ov5693->regmap, OV5693_CROP_START_X_REG, mode->crop.left, in ov5693_mode_configure()
562 cci_write(ov5693->regmap, OV5693_OFFSET_START_X_REG, 0, &ret); in ov5693_mode_configure()
565 cci_write(ov5693->regmap, OV5693_OUTPUT_SIZE_X_REG, mode->format.width, in ov5693_mode_configure()
569 cci_write(ov5693->regmap, OV5693_CROP_END_X_REG, in ov5693_mode_configure()
573 cci_write(ov5693->regmap, OV5693_TIMING_HTS_REG, OV5693_FIXED_PPL, in ov5693_mode_configure()
577 cci_write(ov5693->regmap, OV5693_CROP_START_Y_REG, mode->crop.top, in ov5693_mode_configure()
581 cci_write(ov5693->regmap, OV5693_OFFSET_START_Y_REG, 0, &ret); in ov5693_mode_configure()
584 cci_write(ov5693->regmap, OV5693_OUTPUT_SIZE_Y_REG, mode->format.height, in ov5693_mode_configure()
588 cci_write(ov5693->regmap, OV5693_CROP_END_Y_REG, in ov5693_mode_configure()
592 cci_write(ov5693->regmap, OV5693_SUB_INC_X_REG, in ov5693_mode_configure()
595 cci_write(ov5693->regmap, OV5693_SUB_INC_Y_REG, in ov5693_mode_configure()
599 cci_update_bits(ov5693->regmap, OV5693_FORMAT1_REG, in ov5693_mode_configure()
603 cci_update_bits(ov5693->regmap, OV5693_FORMAT2_REG, in ov5693_mode_configure()
610 static int ov5693_enable_streaming(struct ov5693_device *ov5693, bool enable) in ov5693_enable_streaming() argument
614 cci_write(ov5693->regmap, OV5693_SW_STREAM_REG, in ov5693_enable_streaming()
621 static int ov5693_sw_reset(struct ov5693_device *ov5693) in ov5693_sw_reset() argument
625 cci_write(ov5693->regmap, OV5693_SW_RESET_REG, OV5693_SW_RESET, &ret); in ov5693_sw_reset()
630 static int ov5693_sensor_init(struct ov5693_device *ov5693) in ov5693_sensor_init() argument
634 ret = ov5693_sw_reset(ov5693); in ov5693_sensor_init()
636 return dev_err_probe(ov5693->dev, ret, in ov5693_sensor_init()
639 ret = cci_multi_reg_write(ov5693->regmap, ov5693_global_regs, in ov5693_sensor_init()
642 return dev_err_probe(ov5693->dev, ret, in ov5693_sensor_init()
645 ret = ov5693_mode_configure(ov5693); in ov5693_sensor_init()
647 return dev_err_probe(ov5693->dev, ret, in ov5693_sensor_init()
650 ret = ov5693_enable_streaming(ov5693, false); in ov5693_sensor_init()
652 dev_err(ov5693->dev, "stop streaming error\n"); in ov5693_sensor_init()
657 static void ov5693_sensor_powerdown(struct ov5693_device *ov5693) in ov5693_sensor_powerdown() argument
659 gpiod_set_value_cansleep(ov5693->reset, 1); in ov5693_sensor_powerdown()
660 gpiod_set_value_cansleep(ov5693->powerdown, 1); in ov5693_sensor_powerdown()
662 regulator_bulk_disable(OV5693_NUM_SUPPLIES, ov5693->supplies); in ov5693_sensor_powerdown()
664 clk_disable_unprepare(ov5693->xvclk); in ov5693_sensor_powerdown()
667 static int ov5693_sensor_powerup(struct ov5693_device *ov5693) in ov5693_sensor_powerup() argument
671 gpiod_set_value_cansleep(ov5693->reset, 1); in ov5693_sensor_powerup()
672 gpiod_set_value_cansleep(ov5693->powerdown, 1); in ov5693_sensor_powerup()
674 ret = clk_prepare_enable(ov5693->xvclk); in ov5693_sensor_powerup()
676 dev_err(ov5693->dev, "Failed to enable clk\n"); in ov5693_sensor_powerup()
680 ret = regulator_bulk_enable(OV5693_NUM_SUPPLIES, ov5693->supplies); in ov5693_sensor_powerup()
682 dev_err(ov5693->dev, "Failed to enable regulators\n"); in ov5693_sensor_powerup()
686 gpiod_set_value_cansleep(ov5693->powerdown, 0); in ov5693_sensor_powerup()
687 gpiod_set_value_cansleep(ov5693->reset, 0); in ov5693_sensor_powerup()
694 ov5693_sensor_powerdown(ov5693); in ov5693_sensor_powerup()
701 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_sensor_suspend() local
703 ov5693_sensor_powerdown(ov5693); in ov5693_sensor_suspend()
711 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_sensor_resume() local
714 mutex_lock(&ov5693->lock); in ov5693_sensor_resume()
716 ret = ov5693_sensor_powerup(ov5693); in ov5693_sensor_resume()
720 ret = ov5693_sensor_init(ov5693); in ov5693_sensor_resume()
722 dev_err(dev, "ov5693 sensor init failure\n"); in ov5693_sensor_resume()
729 ov5693_sensor_powerdown(ov5693); in ov5693_sensor_resume()
731 mutex_unlock(&ov5693->lock); in ov5693_sensor_resume()
735 static int ov5693_detect(struct ov5693_device *ov5693) in ov5693_detect() argument
740 ret = cci_read(ov5693->regmap, OV5693_REG_CHIP_ID, &id, NULL); in ov5693_detect()
745 return dev_err_probe(ov5693->dev, -ENODEV, in ov5693_detect()
769 __ov5693_get_pad_format(struct ov5693_device *ov5693, in __ov5693_get_pad_format() argument
777 return &ov5693->mode.format; in __ov5693_get_pad_format()
784 __ov5693_get_pad_crop(struct ov5693_device *ov5693, in __ov5693_get_pad_crop() argument
792 return &ov5693->mode.crop; in __ov5693_get_pad_crop()
802 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_get_fmt() local
804 format->format = ov5693->mode.format; in ov5693_get_fmt()
813 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_set_fmt() local
821 crop = __ov5693_get_pad_crop(ov5693, state, format->pad, format->which); in ov5693_set_fmt()
841 fmt = __ov5693_get_pad_format(ov5693, state, format->pad, in ov5693_set_fmt()
853 mutex_lock(&ov5693->lock); in ov5693_set_fmt()
855 ov5693->mode.binning_x = hratio > 1; in ov5693_set_fmt()
856 ov5693->mode.inc_x_odd = hratio > 1 ? 3 : 1; in ov5693_set_fmt()
857 ov5693->mode.binning_y = vratio > 1; in ov5693_set_fmt()
858 ov5693->mode.inc_y_odd = vratio > 1 ? 3 : 1; in ov5693_set_fmt()
860 ov5693->mode.vts = __ov5693_calc_vts(fmt->height); in ov5693_set_fmt()
862 __v4l2_ctrl_modify_range(ov5693->ctrls.vblank, in ov5693_set_fmt()
865 1, ov5693->mode.vts - fmt->height); in ov5693_set_fmt()
866 __v4l2_ctrl_s_ctrl(ov5693->ctrls.vblank, in ov5693_set_fmt()
867 ov5693->mode.vts - fmt->height); in ov5693_set_fmt()
870 __v4l2_ctrl_modify_range(ov5693->ctrls.hblank, hblank, hblank, 1, in ov5693_set_fmt()
873 exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN; in ov5693_set_fmt()
874 __v4l2_ctrl_modify_range(ov5693->ctrls.exposure, in ov5693_set_fmt()
875 ov5693->ctrls.exposure->minimum, exposure_max, in ov5693_set_fmt()
876 ov5693->ctrls.exposure->step, in ov5693_set_fmt()
877 min(ov5693->ctrls.exposure->val, in ov5693_set_fmt()
880 mutex_unlock(&ov5693->lock); in ov5693_set_fmt()
888 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_get_selection() local
892 mutex_lock(&ov5693->lock); in ov5693_get_selection()
893 sel->r = *__ov5693_get_pad_crop(ov5693, state, sel->pad, in ov5693_get_selection()
895 mutex_unlock(&ov5693->lock); in ov5693_get_selection()
921 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_set_selection() local
949 __crop = __ov5693_get_pad_crop(ov5693, state, sel->pad, sel->which); in ov5693_set_selection()
956 format = __ov5693_get_pad_format(ov5693, state, sel->pad, in ov5693_set_selection()
970 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_s_stream() local
974 ret = pm_runtime_resume_and_get(ov5693->dev); in ov5693_s_stream()
978 mutex_lock(&ov5693->lock); in ov5693_s_stream()
979 ret = __v4l2_ctrl_handler_setup(&ov5693->ctrls.handler); in ov5693_s_stream()
981 mutex_unlock(&ov5693->lock); in ov5693_s_stream()
985 ret = ov5693_enable_streaming(ov5693, true); in ov5693_s_stream()
986 mutex_unlock(&ov5693->lock); in ov5693_s_stream()
988 mutex_lock(&ov5693->lock); in ov5693_s_stream()
989 ret = ov5693_enable_streaming(ov5693, false); in ov5693_s_stream()
990 mutex_unlock(&ov5693->lock); in ov5693_s_stream()
996 pm_runtime_put(ov5693->dev); in ov5693_s_stream()
1000 pm_runtime_put_noidle(ov5693->dev); in ov5693_s_stream()
1008 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_get_frame_interval() local
1009 unsigned int framesize = OV5693_FIXED_PPL * (ov5693->mode.format.height + in ov5693_get_frame_interval()
1010 ov5693->ctrls.vblank->val); in ov5693_get_frame_interval()
1042 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_enum_frame_size() local
1048 __crop = __ov5693_get_pad_crop(ov5693, state, fse->pad, fse->which); in ov5693_enum_frame_size()
1081 static int ov5693_init_controls(struct ov5693_device *ov5693) in ov5693_init_controls() argument
1084 struct ov5693_v4l2_ctrls *ctrls = &ov5693->ctrls; in ov5693_init_controls()
1109 exposure_max = ov5693->mode.vts - OV5693_INTEGRATION_TIME_MARGIN; in ov5693_init_controls()
1137 hblank = OV5693_FIXED_PPL - ov5693->mode.format.width; in ov5693_init_controls()
1145 vblank_max = OV5693_TIMING_MAX_VTS - ov5693->mode.format.height; in ov5693_init_controls()
1146 vblank_def = ov5693->mode.vts - ov5693->mode.format.height; in ov5693_init_controls()
1159 dev_err(ov5693->dev, "Error initialising v4l2 ctrls\n"); in ov5693_init_controls()
1165 ret = v4l2_fwnode_device_parse(ov5693->dev, &props); in ov5693_init_controls()
1175 ctrls->handler.lock = &ov5693->lock; in ov5693_init_controls()
1176 ov5693->sd.ctrl_handler = &ctrls->handler; in ov5693_init_controls()
1185 static int ov5693_configure_gpios(struct ov5693_device *ov5693) in ov5693_configure_gpios() argument
1187 ov5693->reset = devm_gpiod_get_optional(ov5693->dev, "reset", in ov5693_configure_gpios()
1189 if (IS_ERR(ov5693->reset)) { in ov5693_configure_gpios()
1190 dev_err(ov5693->dev, "Error fetching reset GPIO\n"); in ov5693_configure_gpios()
1191 return PTR_ERR(ov5693->reset); in ov5693_configure_gpios()
1194 ov5693->powerdown = devm_gpiod_get_optional(ov5693->dev, "powerdown", in ov5693_configure_gpios()
1196 if (IS_ERR(ov5693->powerdown)) { in ov5693_configure_gpios()
1197 dev_err(ov5693->dev, "Error fetching powerdown GPIO\n"); in ov5693_configure_gpios()
1198 return PTR_ERR(ov5693->powerdown); in ov5693_configure_gpios()
1204 static int ov5693_get_regulators(struct ov5693_device *ov5693) in ov5693_get_regulators() argument
1209 ov5693->supplies[i].supply = ov5693_supply_names[i]; in ov5693_get_regulators()
1211 return devm_regulator_bulk_get(ov5693->dev, OV5693_NUM_SUPPLIES, in ov5693_get_regulators()
1212 ov5693->supplies); in ov5693_get_regulators()
1215 static int ov5693_check_hwcfg(struct ov5693_device *ov5693) in ov5693_check_hwcfg() argument
1217 struct fwnode_handle *fwnode = dev_fwnode(ov5693->dev); in ov5693_check_hwcfg()
1235 dev_err(ov5693->dev, "only a 2-lane CSI2 config is supported"); in ov5693_check_hwcfg()
1241 dev_err(ov5693->dev, "no link frequencies defined\n"); in ov5693_check_hwcfg()
1251 dev_err(ov5693->dev, "supported link freq %ull not found\n", in ov5693_check_hwcfg()
1265 struct ov5693_device *ov5693; in ov5693_probe() local
1269 ov5693 = devm_kzalloc(&client->dev, sizeof(*ov5693), GFP_KERNEL); in ov5693_probe()
1270 if (!ov5693) in ov5693_probe()
1273 ov5693->dev = &client->dev; in ov5693_probe()
1275 ov5693->regmap = devm_cci_regmap_init_i2c(client, 16); in ov5693_probe()
1276 if (IS_ERR(ov5693->regmap)) in ov5693_probe()
1277 return PTR_ERR(ov5693->regmap); in ov5693_probe()
1279 ret = ov5693_check_hwcfg(ov5693); in ov5693_probe()
1283 mutex_init(&ov5693->lock); in ov5693_probe()
1285 v4l2_i2c_subdev_init(&ov5693->sd, client, &ov5693_ops); in ov5693_probe()
1287 ov5693->xvclk = devm_clk_get_optional(&client->dev, "xvclk"); in ov5693_probe()
1288 if (IS_ERR(ov5693->xvclk)) in ov5693_probe()
1289 return dev_err_probe(&client->dev, PTR_ERR(ov5693->xvclk), in ov5693_probe()
1291 PTR_ERR(ov5693->xvclk)); in ov5693_probe()
1293 if (ov5693->xvclk) { in ov5693_probe()
1294 xvclk_rate = clk_get_rate(ov5693->xvclk); in ov5693_probe()
1310 ret = ov5693_configure_gpios(ov5693); in ov5693_probe()
1314 ret = ov5693_get_regulators(ov5693); in ov5693_probe()
1319 ov5693->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in ov5693_probe()
1320 ov5693->pad.flags = MEDIA_PAD_FL_SOURCE; in ov5693_probe()
1321 ov5693->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in ov5693_probe()
1323 ov5693->mode.crop = ov5693_default_crop; in ov5693_probe()
1324 ov5693->mode.format = ov5693_default_fmt; in ov5693_probe()
1325 ov5693->mode.vts = __ov5693_calc_vts(ov5693->mode.format.height); in ov5693_probe()
1327 ret = ov5693_init_controls(ov5693); in ov5693_probe()
1331 ret = media_entity_pads_init(&ov5693->sd.entity, 1, &ov5693->pad); in ov5693_probe()
1342 ret = ov5693_sensor_powerup(ov5693); in ov5693_probe()
1346 ret = ov5693_detect(ov5693); in ov5693_probe()
1354 ret = v4l2_async_register_subdev_sensor(&ov5693->sd); in ov5693_probe()
1371 ov5693_sensor_powerdown(ov5693); in ov5693_probe()
1373 media_entity_cleanup(&ov5693->sd.entity); in ov5693_probe()
1375 v4l2_ctrl_handler_free(&ov5693->ctrls.handler); in ov5693_probe()
1383 struct ov5693_device *ov5693 = to_ov5693_sensor(sd); in ov5693_remove() local
1386 media_entity_cleanup(&ov5693->sd.entity); in ov5693_remove()
1387 v4l2_ctrl_handler_free(&ov5693->ctrls.handler); in ov5693_remove()
1388 mutex_destroy(&ov5693->lock); in ov5693_remove()
1396 ov5693_sensor_powerdown(ov5693); in ov5693_remove()
1411 { .compatible = "ovti,ov5693", },
1418 .name = "ov5693",