Lines Matching +full:sd +full:- +full:lines
1 // SPDX-License-Identifier: GPL-2.0-only
15 #include <media/v4l2-ctrls.h>
16 #include <media/v4l2-fwnode.h>
17 #include <media/v4l2-subdev.h>
24 /* Lines per frame */
59 * struct imx335_reg - imx335 sensor register
69 * struct imx335_reg_list - imx335 sensor register list
85 * struct imx335_mode - imx335 sensor mode structure
89 * @hblank: Horizontal blanking in lines
90 * @vblank: Vertical blanking in lines
91 * @vblank_min: Minimum vertical blanking in lines
92 * @vblank_max: Maximum vertical blanking in lines
111 * struct imx335 - imx335 sensor device structure
114 * @sd: V4L2 sub-device
126 * @vblank: Vertical blanking in lines
134 struct v4l2_subdev sd; member
265 * to_imx335() - imx335 V4L2 sub-device to imx335 device.
266 * @subdev: pointer to imx335 V4L2 sub-device
272 return container_of(subdev, struct imx335, sd); in to_imx335()
276 * imx335_read_reg() - Read registers.
288 struct i2c_client *client = v4l2_get_subdevdata(&imx335->sd); in imx335_read_reg()
295 return -EINVAL; in imx335_read_reg()
300 msgs[0].addr = client->addr; in imx335_read_reg()
306 msgs[1].addr = client->addr; in imx335_read_reg()
311 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in imx335_read_reg()
313 return -EIO; in imx335_read_reg()
321 * imx335_write_reg() - Write register
333 struct i2c_client *client = v4l2_get_subdevdata(&imx335->sd); in imx335_write_reg()
337 return -EINVAL; in imx335_write_reg()
342 return -EIO; in imx335_write_reg()
348 * imx335_write_regs() - Write a list of registers
371 * imx335_update_controls() - Update control ranges based on streaming mode
382 ret = __v4l2_ctrl_s_ctrl(imx335->link_freq_ctrl, mode->link_freq_idx); in imx335_update_controls()
386 ret = __v4l2_ctrl_s_ctrl(imx335->hblank_ctrl, mode->hblank); in imx335_update_controls()
390 return __v4l2_ctrl_modify_range(imx335->vblank_ctrl, mode->vblank_min, in imx335_update_controls()
391 mode->vblank_max, 1, mode->vblank); in imx335_update_controls()
395 * imx335_update_exp_gain() - Set updated exposure and gain
407 lpfr = imx335->vblank + imx335->cur_mode->height; in imx335_update_exp_gain()
408 shutter = lpfr - exposure; in imx335_update_exp_gain()
410 dev_dbg(imx335->dev, "Set exp %u, analog gain %u, shutter %u, lpfr %u", in imx335_update_exp_gain()
434 * imx335_set_ctrl() - Set subdevice control
438 * - V4L2_CID_VBLANK
439 * - cluster controls:
440 * - V4L2_CID_ANALOGUE_GAIN
441 * - V4L2_CID_EXPOSURE
448 container_of(ctrl->handler, struct imx335, ctrl_handler); in imx335_set_ctrl()
453 switch (ctrl->id) { in imx335_set_ctrl()
455 imx335->vblank = imx335->vblank_ctrl->val; in imx335_set_ctrl()
457 dev_dbg(imx335->dev, "Received vblank %u, new lpfr %u", in imx335_set_ctrl()
458 imx335->vblank, in imx335_set_ctrl()
459 imx335->vblank + imx335->cur_mode->height); in imx335_set_ctrl()
461 ret = __v4l2_ctrl_modify_range(imx335->exp_ctrl, in imx335_set_ctrl()
463 imx335->vblank + in imx335_set_ctrl()
464 imx335->cur_mode->height - in imx335_set_ctrl()
470 if (!pm_runtime_get_if_in_use(imx335->dev)) in imx335_set_ctrl()
473 exposure = ctrl->val; in imx335_set_ctrl()
474 analog_gain = imx335->again_ctrl->val; in imx335_set_ctrl()
476 dev_dbg(imx335->dev, "Received exp %u, analog gain %u", in imx335_set_ctrl()
481 pm_runtime_put(imx335->dev); in imx335_set_ctrl()
485 dev_err(imx335->dev, "Invalid control %d", ctrl->id); in imx335_set_ctrl()
486 ret = -EINVAL; in imx335_set_ctrl()
498 * imx335_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
499 * @sd: pointer to imx335 V4L2 sub-device structure
500 * @sd_state: V4L2 sub-device configuration
501 * @code: V4L2 sub-device code enumeration need to be filled
505 static int imx335_enum_mbus_code(struct v4l2_subdev *sd, in imx335_enum_mbus_code() argument
509 if (code->index > 0) in imx335_enum_mbus_code()
510 return -EINVAL; in imx335_enum_mbus_code()
512 code->code = supported_mode.code; in imx335_enum_mbus_code()
518 * imx335_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
519 * @sd: pointer to imx335 V4L2 sub-device structure
520 * @sd_state: V4L2 sub-device configuration
521 * @fsize: V4L2 sub-device size enumeration need to be filled
525 static int imx335_enum_frame_size(struct v4l2_subdev *sd, in imx335_enum_frame_size() argument
529 if (fsize->index > 0) in imx335_enum_frame_size()
530 return -EINVAL; in imx335_enum_frame_size()
532 if (fsize->code != supported_mode.code) in imx335_enum_frame_size()
533 return -EINVAL; in imx335_enum_frame_size()
535 fsize->min_width = supported_mode.width; in imx335_enum_frame_size()
536 fsize->max_width = fsize->min_width; in imx335_enum_frame_size()
537 fsize->min_height = supported_mode.height; in imx335_enum_frame_size()
538 fsize->max_height = fsize->min_height; in imx335_enum_frame_size()
544 * imx335_fill_pad_format() - Fill subdevice pad format
548 * @fmt: V4L2 sub-device format need to be filled
554 fmt->format.width = mode->width; in imx335_fill_pad_format()
555 fmt->format.height = mode->height; in imx335_fill_pad_format()
556 fmt->format.code = mode->code; in imx335_fill_pad_format()
557 fmt->format.field = V4L2_FIELD_NONE; in imx335_fill_pad_format()
558 fmt->format.colorspace = V4L2_COLORSPACE_RAW; in imx335_fill_pad_format()
559 fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in imx335_fill_pad_format()
560 fmt->format.quantization = V4L2_QUANTIZATION_DEFAULT; in imx335_fill_pad_format()
561 fmt->format.xfer_func = V4L2_XFER_FUNC_NONE; in imx335_fill_pad_format()
565 * imx335_get_pad_format() - Get subdevice pad format
566 * @sd: pointer to imx335 V4L2 sub-device structure
567 * @sd_state: V4L2 sub-device configuration
568 * @fmt: V4L2 sub-device format need to be set
572 static int imx335_get_pad_format(struct v4l2_subdev *sd, in imx335_get_pad_format() argument
576 struct imx335 *imx335 = to_imx335(sd); in imx335_get_pad_format()
578 mutex_lock(&imx335->mutex); in imx335_get_pad_format()
580 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in imx335_get_pad_format()
583 framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); in imx335_get_pad_format()
584 fmt->format = *framefmt; in imx335_get_pad_format()
586 imx335_fill_pad_format(imx335, imx335->cur_mode, fmt); in imx335_get_pad_format()
589 mutex_unlock(&imx335->mutex); in imx335_get_pad_format()
595 * imx335_set_pad_format() - Set subdevice pad format
596 * @sd: pointer to imx335 V4L2 sub-device structure
597 * @sd_state: V4L2 sub-device configuration
598 * @fmt: V4L2 sub-device format need to be set
602 static int imx335_set_pad_format(struct v4l2_subdev *sd, in imx335_set_pad_format() argument
606 struct imx335 *imx335 = to_imx335(sd); in imx335_set_pad_format()
610 mutex_lock(&imx335->mutex); in imx335_set_pad_format()
615 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in imx335_set_pad_format()
618 framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad); in imx335_set_pad_format()
619 *framefmt = fmt->format; in imx335_set_pad_format()
623 imx335->cur_mode = mode; in imx335_set_pad_format()
626 mutex_unlock(&imx335->mutex); in imx335_set_pad_format()
632 * imx335_init_pad_cfg() - Initialize sub-device pad configuration
633 * @sd: pointer to imx335 V4L2 sub-device structure
634 * @sd_state: V4L2 sub-device configuration
638 static int imx335_init_pad_cfg(struct v4l2_subdev *sd, in imx335_init_pad_cfg() argument
641 struct imx335 *imx335 = to_imx335(sd); in imx335_init_pad_cfg()
647 return imx335_set_pad_format(sd, sd_state, &fmt); in imx335_init_pad_cfg()
651 * imx335_start_streaming() - Start sensor stream
662 reg_list = &imx335->cur_mode->reg_list; in imx335_start_streaming()
663 ret = imx335_write_regs(imx335, reg_list->regs, in imx335_start_streaming()
664 reg_list->num_of_regs); in imx335_start_streaming()
666 dev_err(imx335->dev, "fail to write initial registers"); in imx335_start_streaming()
671 ret = __v4l2_ctrl_handler_setup(imx335->sd.ctrl_handler); in imx335_start_streaming()
673 dev_err(imx335->dev, "fail to setup handler"); in imx335_start_streaming()
681 dev_err(imx335->dev, "fail to start streaming"); in imx335_start_streaming()
692 * imx335_stop_streaming() - Stop sensor stream
704 * imx335_set_stream() - Enable sensor streaming
705 * @sd: pointer to imx335 subdevice
710 static int imx335_set_stream(struct v4l2_subdev *sd, int enable) in imx335_set_stream() argument
712 struct imx335 *imx335 = to_imx335(sd); in imx335_set_stream()
715 mutex_lock(&imx335->mutex); in imx335_set_stream()
717 if (imx335->streaming == enable) { in imx335_set_stream()
718 mutex_unlock(&imx335->mutex); in imx335_set_stream()
723 ret = pm_runtime_resume_and_get(imx335->dev); in imx335_set_stream()
732 pm_runtime_put(imx335->dev); in imx335_set_stream()
735 imx335->streaming = enable; in imx335_set_stream()
737 mutex_unlock(&imx335->mutex); in imx335_set_stream()
742 pm_runtime_put(imx335->dev); in imx335_set_stream()
744 mutex_unlock(&imx335->mutex); in imx335_set_stream()
750 * imx335_detect() - Detect imx335 sensor
753 * Return: 0 if successful, -EIO if sensor id does not match
765 dev_err(imx335->dev, "chip id mismatch: %x!=%x", in imx335_detect()
767 return -ENXIO; in imx335_detect()
774 * imx335_parse_hw_config() - Parse HW configuration and check if supported
781 struct fwnode_handle *fwnode = dev_fwnode(imx335->dev); in imx335_parse_hw_config()
791 return -ENXIO; in imx335_parse_hw_config()
794 imx335->reset_gpio = devm_gpiod_get_optional(imx335->dev, "reset", in imx335_parse_hw_config()
796 if (IS_ERR(imx335->reset_gpio)) { in imx335_parse_hw_config()
797 dev_err(imx335->dev, "failed to get reset gpio %ld", in imx335_parse_hw_config()
798 PTR_ERR(imx335->reset_gpio)); in imx335_parse_hw_config()
799 return PTR_ERR(imx335->reset_gpio); in imx335_parse_hw_config()
803 imx335->supplies[i].supply = imx335_supply_name[i]; in imx335_parse_hw_config()
805 ret = devm_regulator_bulk_get(imx335->dev, in imx335_parse_hw_config()
807 imx335->supplies); in imx335_parse_hw_config()
809 dev_err(imx335->dev, "Failed to get regulators\n"); in imx335_parse_hw_config()
814 imx335->inclk = devm_clk_get(imx335->dev, NULL); in imx335_parse_hw_config()
815 if (IS_ERR(imx335->inclk)) { in imx335_parse_hw_config()
816 dev_err(imx335->dev, "could not get inclk"); in imx335_parse_hw_config()
817 return PTR_ERR(imx335->inclk); in imx335_parse_hw_config()
820 rate = clk_get_rate(imx335->inclk); in imx335_parse_hw_config()
822 dev_err(imx335->dev, "inclk frequency mismatch"); in imx335_parse_hw_config()
823 return -EINVAL; in imx335_parse_hw_config()
828 return -ENXIO; in imx335_parse_hw_config()
836 dev_err(imx335->dev, in imx335_parse_hw_config()
839 ret = -EINVAL; in imx335_parse_hw_config()
844 dev_err(imx335->dev, "no link frequencies defined"); in imx335_parse_hw_config()
845 ret = -EINVAL; in imx335_parse_hw_config()
853 ret = -EINVAL; in imx335_parse_hw_config()
880 * imx335_power_on() - Sensor power on sequence
887 struct v4l2_subdev *sd = dev_get_drvdata(dev); in imx335_power_on() local
888 struct imx335 *imx335 = to_imx335(sd); in imx335_power_on()
892 imx335->supplies); in imx335_power_on()
901 gpiod_set_value_cansleep(imx335->reset_gpio, 0); in imx335_power_on()
903 ret = clk_prepare_enable(imx335->inclk); in imx335_power_on()
905 dev_err(imx335->dev, "fail to enable inclk"); in imx335_power_on()
914 gpiod_set_value_cansleep(imx335->reset_gpio, 1); in imx335_power_on()
915 regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies); in imx335_power_on()
921 * imx335_power_off() - Sensor power off sequence
928 struct v4l2_subdev *sd = dev_get_drvdata(dev); in imx335_power_off() local
929 struct imx335 *imx335 = to_imx335(sd); in imx335_power_off()
931 gpiod_set_value_cansleep(imx335->reset_gpio, 1); in imx335_power_off()
932 clk_disable_unprepare(imx335->inclk); in imx335_power_off()
933 regulator_bulk_disable(ARRAY_SIZE(imx335_supply_name), imx335->supplies); in imx335_power_off()
939 * imx335_init_controls() - Initialize sensor subdevice controls
946 struct v4l2_ctrl_handler *ctrl_hdlr = &imx335->ctrl_handler; in imx335_init_controls()
947 const struct imx335_mode *mode = imx335->cur_mode; in imx335_init_controls()
956 ctrl_hdlr->lock = &imx335->mutex; in imx335_init_controls()
959 lpfr = mode->vblank + mode->height; in imx335_init_controls()
960 imx335->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx335_init_controls()
964 lpfr - IMX335_EXPOSURE_OFFSET, in imx335_init_controls()
968 imx335->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx335_init_controls()
976 v4l2_ctrl_cluster(2, &imx335->exp_ctrl); in imx335_init_controls()
978 imx335->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx335_init_controls()
981 mode->vblank_min, in imx335_init_controls()
982 mode->vblank_max, in imx335_init_controls()
983 1, mode->vblank); in imx335_init_controls()
986 imx335->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx335_init_controls()
989 mode->pclk, mode->pclk, in imx335_init_controls()
990 1, mode->pclk); in imx335_init_controls()
992 imx335->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr, in imx335_init_controls()
995 ARRAY_SIZE(link_freq) - in imx335_init_controls()
997 mode->link_freq_idx, in imx335_init_controls()
999 if (imx335->link_freq_ctrl) in imx335_init_controls()
1000 imx335->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx335_init_controls()
1002 imx335->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx335_init_controls()
1005 mode->hblank, in imx335_init_controls()
1006 mode->hblank, in imx335_init_controls()
1007 1, mode->hblank); in imx335_init_controls()
1008 if (imx335->hblank_ctrl) in imx335_init_controls()
1009 imx335->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx335_init_controls()
1011 if (ctrl_hdlr->error) { in imx335_init_controls()
1012 dev_err(imx335->dev, "control init failed: %d", in imx335_init_controls()
1013 ctrl_hdlr->error); in imx335_init_controls()
1015 return ctrl_hdlr->error; in imx335_init_controls()
1018 imx335->sd.ctrl_handler = ctrl_hdlr; in imx335_init_controls()
1024 * imx335_probe() - I2C client device binding
1034 imx335 = devm_kzalloc(&client->dev, sizeof(*imx335), GFP_KERNEL); in imx335_probe()
1036 return -ENOMEM; in imx335_probe()
1038 imx335->dev = &client->dev; in imx335_probe()
1041 v4l2_i2c_subdev_init(&imx335->sd, client, &imx335_subdev_ops); in imx335_probe()
1045 dev_err(imx335->dev, "HW configuration is not supported"); in imx335_probe()
1049 mutex_init(&imx335->mutex); in imx335_probe()
1051 ret = imx335_power_on(imx335->dev); in imx335_probe()
1053 dev_err(imx335->dev, "failed to power-on the sensor"); in imx335_probe()
1060 dev_err(imx335->dev, "failed to find sensor: %d", ret); in imx335_probe()
1065 imx335->cur_mode = &supported_mode; in imx335_probe()
1066 imx335->vblank = imx335->cur_mode->vblank; in imx335_probe()
1070 dev_err(imx335->dev, "failed to init controls: %d", ret); in imx335_probe()
1075 imx335->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in imx335_probe()
1076 imx335->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in imx335_probe()
1079 imx335->pad.flags = MEDIA_PAD_FL_SOURCE; in imx335_probe()
1080 ret = media_entity_pads_init(&imx335->sd.entity, 1, &imx335->pad); in imx335_probe()
1082 dev_err(imx335->dev, "failed to init entity pads: %d", ret); in imx335_probe()
1086 ret = v4l2_async_register_subdev_sensor(&imx335->sd); in imx335_probe()
1088 dev_err(imx335->dev, in imx335_probe()
1093 pm_runtime_set_active(imx335->dev); in imx335_probe()
1094 pm_runtime_enable(imx335->dev); in imx335_probe()
1095 pm_runtime_idle(imx335->dev); in imx335_probe()
1100 media_entity_cleanup(&imx335->sd.entity); in imx335_probe()
1102 v4l2_ctrl_handler_free(imx335->sd.ctrl_handler); in imx335_probe()
1104 imx335_power_off(imx335->dev); in imx335_probe()
1106 mutex_destroy(&imx335->mutex); in imx335_probe()
1112 * imx335_remove() - I2C client device unbinding
1119 struct v4l2_subdev *sd = i2c_get_clientdata(client); in imx335_remove() local
1120 struct imx335 *imx335 = to_imx335(sd); in imx335_remove()
1122 v4l2_async_unregister_subdev(sd); in imx335_remove()
1123 media_entity_cleanup(&sd->entity); in imx335_remove()
1124 v4l2_ctrl_handler_free(sd->ctrl_handler); in imx335_remove()
1126 pm_runtime_disable(&client->dev); in imx335_remove()
1127 if (!pm_runtime_status_suspended(&client->dev)) in imx335_remove()
1128 imx335_power_off(&client->dev); in imx335_remove()
1129 pm_runtime_set_suspended(&client->dev); in imx335_remove()
1131 mutex_destroy(&imx335->mutex); in imx335_remove()