Lines Matching +full:user +full:- +full:otp

1 // SPDX-License-Identifier: GPL-2.0
9 #include <media/v4l2-ctrls.h>
10 #include <media/v4l2-device.h>
29 /* HBLANK control - read only */
71 /* OTP Access */
100 /* V-timing */
209 * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample
293 /* OTP data */
318 return codes[imx208->vflip->val][imx208->hflip->val]; in imx208_get_format_code()
324 struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); in imx208_read_reg()
331 return -EINVAL; in imx208_read_reg()
334 msgs[0].addr = client->addr; in imx208_read_reg()
340 msgs[1].addr = client->addr; in imx208_read_reg()
343 msgs[1].buf = &data_buf[4 - len]; in imx208_read_reg()
345 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in imx208_read_reg()
347 return -EIO; in imx208_read_reg()
357 struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); in imx208_write_reg()
361 return -EINVAL; in imx208_write_reg()
364 put_unaligned_be32(val << (8 * (4 - len)), buf + 2); in imx208_write_reg()
366 return -EIO; in imx208_write_reg()
375 struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); in imx208_write_regs()
383 dev_err_ratelimited(&client->dev, in imx208_write_regs()
394 /* Open sub-device */
398 v4l2_subdev_state_get_format(fh->state, 0); in imx208_open()
401 try_fmt->width = supported_modes[0].width; in imx208_open()
402 try_fmt->height = supported_modes[0].height; in imx208_open()
403 try_fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10; in imx208_open()
404 try_fmt->field = V4L2_FIELD_NONE; in imx208_open()
433 container_of(ctrl->handler, struct imx208, ctrl_handler); in imx208_set_ctrl()
434 struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); in imx208_set_ctrl()
441 if (!pm_runtime_get_if_in_use(&client->dev)) in imx208_set_ctrl()
444 switch (ctrl->id) { in imx208_set_ctrl()
447 2, ctrl->val); in imx208_set_ctrl()
451 2, ctrl->val); in imx208_set_ctrl()
454 ret = imx208_update_digital_gain(imx208, 2, ctrl->val); in imx208_set_ctrl()
459 imx208->cur_mode->height + ctrl->val); in imx208_set_ctrl()
463 2, imx208_test_pattern_val[ctrl->val]); in imx208_set_ctrl()
469 imx208->hflip->val | in imx208_set_ctrl()
470 imx208->vflip->val << 1); in imx208_set_ctrl()
473 ret = -EINVAL; in imx208_set_ctrl()
474 dev_err(&client->dev, in imx208_set_ctrl()
476 ctrl->id, ctrl->val); in imx208_set_ctrl()
480 pm_runtime_put(&client->dev); in imx208_set_ctrl()
495 .max = ARRAY_SIZE(imx208_discrete_digital_gain) - 1,
508 if (code->index > 0) in imx208_enum_mbus_code()
509 return -EINVAL; in imx208_enum_mbus_code()
511 code->code = imx208_get_format_code(imx208); in imx208_enum_mbus_code()
522 if (fse->index >= ARRAY_SIZE(supported_modes)) in imx208_enum_frame_size()
523 return -EINVAL; in imx208_enum_frame_size()
525 if (fse->code != imx208_get_format_code(imx208)) in imx208_enum_frame_size()
526 return -EINVAL; in imx208_enum_frame_size()
528 fse->min_width = supported_modes[fse->index].width; in imx208_enum_frame_size()
529 fse->max_width = fse->min_width; in imx208_enum_frame_size()
530 fse->min_height = supported_modes[fse->index].height; in imx208_enum_frame_size()
531 fse->max_height = fse->min_height; in imx208_enum_frame_size()
540 fmt->format.width = mode->width; in imx208_mode_to_pad_format()
541 fmt->format.height = mode->height; in imx208_mode_to_pad_format()
542 fmt->format.code = imx208_get_format_code(imx208); in imx208_mode_to_pad_format()
543 fmt->format.field = V4L2_FIELD_NONE; in imx208_mode_to_pad_format()
550 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) in __imx208_get_pad_format()
551 fmt->format = *v4l2_subdev_state_get_format(sd_state, in __imx208_get_pad_format()
552 fmt->pad); in __imx208_get_pad_format()
554 imx208_mode_to_pad_format(imx208, imx208->cur_mode, fmt); in __imx208_get_pad_format()
566 mutex_lock(&imx208->imx208_mx); in imx208_get_pad_format()
568 mutex_unlock(&imx208->imx208_mx); in imx208_get_pad_format()
585 mutex_lock(&imx208->imx208_mx); in imx208_set_pad_format()
587 fmt->format.code = imx208_get_format_code(imx208); in imx208_set_pad_format()
590 fmt->format.width, fmt->format.height); in imx208_set_pad_format()
592 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in imx208_set_pad_format()
593 *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; in imx208_set_pad_format()
595 imx208->cur_mode = mode; in imx208_set_pad_format()
596 __v4l2_ctrl_s_ctrl(imx208->link_freq, mode->link_freq_index); in imx208_set_pad_format()
597 link_freq = link_freq_menu_items[mode->link_freq_index]; in imx208_set_pad_format()
599 __v4l2_ctrl_s_ctrl_int64(imx208->pixel_rate, pixel_rate); in imx208_set_pad_format()
601 vblank_def = imx208->cur_mode->vts_def - in imx208_set_pad_format()
602 imx208->cur_mode->height; in imx208_set_pad_format()
603 vblank_min = imx208->cur_mode->vts_min - in imx208_set_pad_format()
604 imx208->cur_mode->height; in imx208_set_pad_format()
605 __v4l2_ctrl_modify_range(imx208->vblank, vblank_min, in imx208_set_pad_format()
606 IMX208_VTS_MAX - imx208->cur_mode->height, in imx208_set_pad_format()
608 __v4l2_ctrl_s_ctrl(imx208->vblank, vblank_def); in imx208_set_pad_format()
610 link_freq_configs[mode->link_freq_index].pixels_per_line in imx208_set_pad_format()
611 - imx208->cur_mode->width; in imx208_set_pad_format()
612 __v4l2_ctrl_modify_range(imx208->hblank, h_blank, in imx208_set_pad_format()
616 mutex_unlock(&imx208->imx208_mx); in imx208_set_pad_format()
623 struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); in imx208_identify_module()
627 if (imx208->identified) in imx208_identify_module()
633 dev_err(&client->dev, "failed to read chip id %x\n", in imx208_identify_module()
639 dev_err(&client->dev, "chip id mismatch: %x!=%x\n", in imx208_identify_module()
641 return -EIO; in imx208_identify_module()
644 imx208->identified = true; in imx208_identify_module()
652 struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); in imx208_start_streaming()
661 link_freq_index = imx208->cur_mode->link_freq_index; in imx208_start_streaming()
663 ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs); in imx208_start_streaming()
665 dev_err(&client->dev, "%s failed to set plls\n", __func__); in imx208_start_streaming()
670 reg_list = &imx208->cur_mode->reg_list; in imx208_start_streaming()
671 ret = imx208_write_regs(imx208, reg_list->regs, reg_list->num_of_regs); in imx208_start_streaming()
673 dev_err(&client->dev, "%s failed to set mode\n", __func__); in imx208_start_streaming()
677 /* Apply customized values from user */ in imx208_start_streaming()
678 ret = __v4l2_ctrl_handler_setup(imx208->sd.ctrl_handler); in imx208_start_streaming()
690 struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); in imx208_stop_streaming()
697 dev_err(&client->dev, "%s failed to set stream\n", __func__); in imx208_stop_streaming()
712 mutex_lock(&imx208->imx208_mx); in imx208_set_stream()
715 ret = pm_runtime_resume_and_get(&client->dev); in imx208_set_stream()
717 mutex_unlock(&imx208->imx208_mx); in imx208_set_stream()
730 pm_runtime_put(&client->dev); in imx208_set_stream()
733 mutex_unlock(&imx208->imx208_mx); in imx208_set_stream()
736 v4l2_ctrl_grab(imx208->vflip, enable); in imx208_set_stream()
737 v4l2_ctrl_grab(imx208->hflip, enable); in imx208_set_stream()
742 pm_runtime_put(&client->dev); in imx208_set_stream()
743 mutex_unlock(&imx208->imx208_mx); in imx208_set_stream()
771 struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); in imx208_read_otp()
776 mutex_lock(&imx208->imx208_mx); in imx208_read_otp()
778 if (imx208->otp_read) in imx208_read_otp()
781 ret = pm_runtime_resume_and_get(&client->dev); in imx208_read_otp()
790 msgs[0].addr = client->addr; in imx208_read_otp()
796 msgs[1].addr = client->addr; in imx208_read_otp()
798 msgs[1].len = sizeof(imx208->otp_data); in imx208_read_otp()
799 msgs[1].buf = imx208->otp_data; in imx208_read_otp()
801 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in imx208_read_otp()
803 imx208->otp_read = true; in imx208_read_otp()
808 pm_runtime_put(&client->dev); in imx208_read_otp()
811 mutex_unlock(&imx208->imx208_mx); in imx208_read_otp()
829 memcpy(buf, &imx208->otp_data[off], count); in otp_read()
833 static const BIN_ATTR_RO(otp, IMX208_OTP_SIZE);
838 struct i2c_client *client = v4l2_get_subdevdata(&imx208->sd); in imx208_init_controls()
839 struct v4l2_ctrl_handler *ctrl_hdlr = &imx208->ctrl_handler; in imx208_init_controls()
851 mutex_init(&imx208->imx208_mx); in imx208_init_controls()
852 ctrl_hdlr->lock = &imx208->imx208_mx; in imx208_init_controls()
853 imx208->link_freq = in imx208_init_controls()
857 ARRAY_SIZE(link_freq_menu_items) - 1, in imx208_init_controls()
860 if (imx208->link_freq) in imx208_init_controls()
861 imx208->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx208_init_controls()
865 link_freq_to_pixel_rate(link_freq_menu_items[ARRAY_SIZE(link_freq_menu_items) - 1]); in imx208_init_controls()
867 imx208->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, in imx208_init_controls()
872 vblank_def = imx208->cur_mode->vts_def - imx208->cur_mode->height; in imx208_init_controls()
873 vblank_min = imx208->cur_mode->vts_min - imx208->cur_mode->height; in imx208_init_controls()
874 imx208->vblank = in imx208_init_controls()
877 IMX208_VTS_MAX - imx208->cur_mode->height, 1, in imx208_init_controls()
880 imx208->hblank = in imx208_init_controls()
882 IMX208_PPL_384MHZ - imx208->cur_mode->width, in imx208_init_controls()
883 IMX208_PPL_384MHZ - imx208->cur_mode->width, in imx208_init_controls()
885 IMX208_PPL_384MHZ - imx208->cur_mode->width); in imx208_init_controls()
887 if (imx208->hblank) in imx208_init_controls()
888 imx208->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx208_init_controls()
890 exposure_max = imx208->cur_mode->vts_def - 8; in imx208_init_controls()
895 imx208->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, in imx208_init_controls()
897 if (imx208->hflip) in imx208_init_controls()
898 imx208->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; in imx208_init_controls()
899 imx208->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx208_ctrl_ops, in imx208_init_controls()
901 if (imx208->vflip) in imx208_init_controls()
902 imx208->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; in imx208_init_controls()
912 ARRAY_SIZE(imx208_test_pattern_menu) - 1, in imx208_init_controls()
915 if (ctrl_hdlr->error) { in imx208_init_controls()
916 ret = ctrl_hdlr->error; in imx208_init_controls()
917 dev_err(&client->dev, "%s control init failed (%d)\n", in imx208_init_controls()
922 imx208->sd.ctrl_handler = ctrl_hdlr; in imx208_init_controls()
928 mutex_destroy(&imx208->imx208_mx); in imx208_init_controls()
935 v4l2_ctrl_handler_free(imx208->sd.ctrl_handler); in imx208_free_controls()
945 device_property_read_u32(&client->dev, "clock-frequency", &val); in imx208_probe()
947 dev_err(&client->dev, in imx208_probe()
948 "Unsupported clock-frequency %u. Expected 19200000.\n", in imx208_probe()
950 return -EINVAL; in imx208_probe()
953 imx208 = devm_kzalloc(&client->dev, sizeof(*imx208), GFP_KERNEL); in imx208_probe()
955 return -ENOMEM; in imx208_probe()
958 v4l2_i2c_subdev_init(&imx208->sd, client, &imx208_subdev_ops); in imx208_probe()
960 full_power = acpi_dev_state_d0(&client->dev); in imx208_probe()
965 dev_err(&client->dev, "failed to find sensor: %d", ret); in imx208_probe()
971 imx208->cur_mode = &supported_modes[0]; in imx208_probe()
975 dev_err(&client->dev, "failed to init controls: %d", ret); in imx208_probe()
980 imx208->sd.internal_ops = &imx208_internal_ops; in imx208_probe()
981 imx208->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in imx208_probe()
982 imx208->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in imx208_probe()
985 imx208->pad.flags = MEDIA_PAD_FL_SOURCE; in imx208_probe()
986 ret = media_entity_pads_init(&imx208->sd.entity, 1, &imx208->pad); in imx208_probe()
988 dev_err(&client->dev, "%s failed:%d\n", __func__, ret); in imx208_probe()
992 ret = v4l2_async_register_subdev_sensor(&imx208->sd); in imx208_probe()
996 ret = device_create_bin_file(&client->dev, &bin_attr_otp); in imx208_probe()
998 dev_err(&client->dev, "sysfs otp creation failed\n"); in imx208_probe()
1004 pm_runtime_set_active(&client->dev); in imx208_probe()
1005 pm_runtime_enable(&client->dev); in imx208_probe()
1006 pm_runtime_idle(&client->dev); in imx208_probe()
1011 v4l2_async_unregister_subdev(&imx208->sd); in imx208_probe()
1014 media_entity_cleanup(&imx208->sd.entity); in imx208_probe()
1020 mutex_destroy(&imx208->imx208_mx); in imx208_probe()
1030 device_remove_bin_file(&client->dev, &bin_attr_otp); in imx208_remove()
1032 media_entity_cleanup(&sd->entity); in imx208_remove()
1035 pm_runtime_disable(&client->dev); in imx208_remove()
1036 pm_runtime_set_suspended(&client->dev); in imx208_remove()
1038 mutex_destroy(&imx208->imx208_mx); in imx208_remove()
1063 MODULE_AUTHOR("Chen, Ping-chung <ping-[email protected]>");