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 */
78 * struct imx334_reg - imx334 sensor register
88 * struct imx334_reg_list - imx334 sensor register list
98 * struct imx334_mode - imx334 sensor mode structure
101 * @hblank: Horizontal blanking in lines
102 * @vblank: Vertical blanking in lines
103 * @vblank_min: Minimal vertical blanking in lines
104 * @vblank_max: Maximum vertical blanking in lines
122 * struct imx334 - imx334 sensor device structure
125 * @sd: V4L2 sub-device
136 * @vblank: Vertical blanking in lines
145 struct v4l2_subdev sd; member
512 * to_imx334() - imv334 V4L2 sub-device to imx334 device.
513 * @subdev: pointer to imx334 V4L2 sub-device
519 return container_of(subdev, struct imx334, sd); in to_imx334()
523 * imx334_read_reg() - Read registers.
535 struct i2c_client *client = v4l2_get_subdevdata(&imx334->sd); in imx334_read_reg()
542 return -EINVAL; in imx334_read_reg()
547 msgs[0].addr = client->addr; in imx334_read_reg()
553 msgs[1].addr = client->addr; in imx334_read_reg()
558 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in imx334_read_reg()
560 return -EIO; in imx334_read_reg()
568 * imx334_write_reg() - Write register
580 struct i2c_client *client = v4l2_get_subdevdata(&imx334->sd); in imx334_write_reg()
584 return -EINVAL; in imx334_write_reg()
589 return -EIO; in imx334_write_reg()
595 * imx334_write_regs() - Write a list of registers
618 * imx334_update_controls() - Update control ranges based on streaming mode
629 ret = __v4l2_ctrl_s_ctrl(imx334->link_freq_ctrl, mode->link_freq_idx); in imx334_update_controls()
633 ret = __v4l2_ctrl_modify_range(imx334->pclk_ctrl, mode->pclk, in imx334_update_controls()
634 mode->pclk, 1, mode->pclk); in imx334_update_controls()
638 ret = __v4l2_ctrl_modify_range(imx334->hblank_ctrl, mode->hblank, in imx334_update_controls()
639 mode->hblank, 1, mode->hblank); in imx334_update_controls()
643 ret = __v4l2_ctrl_modify_range(imx334->vblank_ctrl, mode->vblank_min, in imx334_update_controls()
644 mode->vblank_max, 1, mode->vblank); in imx334_update_controls()
648 return __v4l2_ctrl_s_ctrl(imx334->vblank_ctrl, mode->vblank); in imx334_update_controls()
652 * imx334_update_exp_gain() - Set updated exposure and gain
664 lpfr = imx334->vblank + imx334->cur_mode->height; in imx334_update_exp_gain()
665 shutter = lpfr - exposure; in imx334_update_exp_gain()
667 dev_dbg(imx334->dev, "Set long exp %u analog gain %u sh0 %u lpfr %u", in imx334_update_exp_gain()
691 * imx334_set_ctrl() - Set subdevice control
695 * - V4L2_CID_VBLANK
696 * - cluster controls:
697 * - V4L2_CID_ANALOGUE_GAIN
698 * - V4L2_CID_EXPOSURE
705 container_of(ctrl->handler, struct imx334, ctrl_handler); in imx334_set_ctrl()
710 switch (ctrl->id) { in imx334_set_ctrl()
712 imx334->vblank = imx334->vblank_ctrl->val; in imx334_set_ctrl()
714 dev_dbg(imx334->dev, "Received vblank %u, new lpfr %u", in imx334_set_ctrl()
715 imx334->vblank, in imx334_set_ctrl()
716 imx334->vblank + imx334->cur_mode->height); in imx334_set_ctrl()
718 ret = __v4l2_ctrl_modify_range(imx334->exp_ctrl, in imx334_set_ctrl()
720 imx334->vblank + in imx334_set_ctrl()
721 imx334->cur_mode->height - in imx334_set_ctrl()
728 if (!pm_runtime_get_if_in_use(imx334->dev)) in imx334_set_ctrl()
731 exposure = ctrl->val; in imx334_set_ctrl()
732 analog_gain = imx334->again_ctrl->val; in imx334_set_ctrl()
734 dev_dbg(imx334->dev, "Received exp %u analog gain %u", in imx334_set_ctrl()
739 pm_runtime_put(imx334->dev); in imx334_set_ctrl()
748 if (ctrl->val) { in imx334_set_ctrl()
755 imx334_test_pattern_val[ctrl->val]); in imx334_set_ctrl()
768 dev_err(imx334->dev, "Invalid control %d", ctrl->id); in imx334_set_ctrl()
769 ret = -EINVAL; in imx334_set_ctrl()
793 * imx334_enum_mbus_code() - Enumerate V4L2 sub-device mbus codes
794 * @sd: pointer to imx334 V4L2 sub-device structure
795 * @sd_state: V4L2 sub-device state
796 * @code: V4L2 sub-device code enumeration need to be filled
800 static int imx334_enum_mbus_code(struct v4l2_subdev *sd, in imx334_enum_mbus_code() argument
804 if (code->index >= ARRAY_SIZE(imx334_mbus_codes)) in imx334_enum_mbus_code()
805 return -EINVAL; in imx334_enum_mbus_code()
807 code->code = imx334_mbus_codes[code->index]; in imx334_enum_mbus_code()
813 * imx334_enum_frame_size() - Enumerate V4L2 sub-device frame sizes
814 * @sd: pointer to imx334 V4L2 sub-device structure
815 * @sd_state: V4L2 sub-device state
816 * @fsize: V4L2 sub-device size enumeration need to be filled
820 static int imx334_enum_frame_size(struct v4l2_subdev *sd, in imx334_enum_frame_size() argument
824 struct imx334 *imx334 = to_imx334(sd); in imx334_enum_frame_size()
827 if (fsize->index >= ARRAY_SIZE(supported_modes)) in imx334_enum_frame_size()
828 return -EINVAL; in imx334_enum_frame_size()
830 code = imx334_get_format_code(imx334, fsize->code); in imx334_enum_frame_size()
832 if (fsize->code != code) in imx334_enum_frame_size()
833 return -EINVAL; in imx334_enum_frame_size()
835 fsize->min_width = supported_modes[fsize->index].width; in imx334_enum_frame_size()
836 fsize->max_width = fsize->min_width; in imx334_enum_frame_size()
837 fsize->min_height = supported_modes[fsize->index].height; in imx334_enum_frame_size()
838 fsize->max_height = fsize->min_height; in imx334_enum_frame_size()
844 * imx334_fill_pad_format() - Fill subdevice pad format
848 * @fmt: V4L2 sub-device format need to be filled
854 fmt->format.width = mode->width; in imx334_fill_pad_format()
855 fmt->format.height = mode->height; in imx334_fill_pad_format()
856 fmt->format.field = V4L2_FIELD_NONE; in imx334_fill_pad_format()
857 fmt->format.colorspace = V4L2_COLORSPACE_RAW; in imx334_fill_pad_format()
858 fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in imx334_fill_pad_format()
859 fmt->format.quantization = V4L2_QUANTIZATION_DEFAULT; in imx334_fill_pad_format()
860 fmt->format.xfer_func = V4L2_XFER_FUNC_NONE; in imx334_fill_pad_format()
864 * imx334_get_pad_format() - Get subdevice pad format
865 * @sd: pointer to imx334 V4L2 sub-device structure
866 * @sd_state: V4L2 sub-device state
867 * @fmt: V4L2 sub-device format need to be set
871 static int imx334_get_pad_format(struct v4l2_subdev *sd, in imx334_get_pad_format() argument
875 struct imx334 *imx334 = to_imx334(sd); in imx334_get_pad_format()
877 mutex_lock(&imx334->mutex); in imx334_get_pad_format()
879 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in imx334_get_pad_format()
882 framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); in imx334_get_pad_format()
883 fmt->format = *framefmt; in imx334_get_pad_format()
885 fmt->format.code = imx334->cur_code; in imx334_get_pad_format()
886 imx334_fill_pad_format(imx334, imx334->cur_mode, fmt); in imx334_get_pad_format()
889 mutex_unlock(&imx334->mutex); in imx334_get_pad_format()
895 * imx334_set_pad_format() - Set subdevice pad format
896 * @sd: pointer to imx334 V4L2 sub-device structure
897 * @sd_state: V4L2 sub-device state
898 * @fmt: V4L2 sub-device format need to be set
902 static int imx334_set_pad_format(struct v4l2_subdev *sd, in imx334_set_pad_format() argument
906 struct imx334 *imx334 = to_imx334(sd); in imx334_set_pad_format()
910 mutex_lock(&imx334->mutex); in imx334_set_pad_format()
915 fmt->format.width, fmt->format.height); in imx334_set_pad_format()
918 fmt->format.code = imx334_get_format_code(imx334, fmt->format.code); in imx334_set_pad_format()
920 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in imx334_set_pad_format()
923 framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); in imx334_set_pad_format()
924 *framefmt = fmt->format; in imx334_set_pad_format()
925 } else if (imx334->cur_mode != mode || imx334->cur_code != fmt->format.code) { in imx334_set_pad_format()
926 imx334->cur_code = fmt->format.code; in imx334_set_pad_format()
929 imx334->cur_mode = mode; in imx334_set_pad_format()
932 mutex_unlock(&imx334->mutex); in imx334_set_pad_format()
938 * imx334_init_state() - Initialize sub-device state
939 * @sd: pointer to imx334 V4L2 sub-device structure
940 * @sd_state: V4L2 sub-device state
944 static int imx334_init_state(struct v4l2_subdev *sd, in imx334_init_state() argument
947 struct imx334 *imx334 = to_imx334(sd); in imx334_init_state()
952 mutex_lock(&imx334->mutex); in imx334_init_state()
954 imx334_fill_pad_format(imx334, imx334->cur_mode, &fmt); in imx334_init_state()
956 __v4l2_ctrl_modify_range(imx334->link_freq_ctrl, 0, in imx334_init_state()
957 __fls(imx334->link_freq_bitmap), in imx334_init_state()
958 ~(imx334->link_freq_bitmap), in imx334_init_state()
959 __ffs(imx334->link_freq_bitmap)); in imx334_init_state()
961 mutex_unlock(&imx334->mutex); in imx334_init_state()
963 return imx334_set_pad_format(sd, sd_state, &fmt); in imx334_init_state()
968 switch (imx334->cur_code) { in imx334_set_framefmt()
978 return -EINVAL; in imx334_set_framefmt()
982 * imx334_start_streaming() - Start sensor stream
993 reg_list = &imx334->cur_mode->reg_list; in imx334_start_streaming()
994 ret = imx334_write_regs(imx334, reg_list->regs, in imx334_start_streaming()
995 reg_list->num_of_regs); in imx334_start_streaming()
997 dev_err(imx334->dev, "fail to write initial registers"); in imx334_start_streaming()
1003 dev_err(imx334->dev, "%s failed to set frame format: %d\n", in imx334_start_streaming()
1009 ret = __v4l2_ctrl_handler_setup(imx334->sd.ctrl_handler); in imx334_start_streaming()
1011 dev_err(imx334->dev, "fail to setup handler"); in imx334_start_streaming()
1019 dev_err(imx334->dev, "fail to start streaming"); in imx334_start_streaming()
1027 * imx334_stop_streaming() - Stop sensor stream
1039 * imx334_set_stream() - Enable sensor streaming
1040 * @sd: pointer to imx334 subdevice
1045 static int imx334_set_stream(struct v4l2_subdev *sd, int enable) in imx334_set_stream() argument
1047 struct imx334 *imx334 = to_imx334(sd); in imx334_set_stream()
1050 mutex_lock(&imx334->mutex); in imx334_set_stream()
1053 ret = pm_runtime_resume_and_get(imx334->dev); in imx334_set_stream()
1062 pm_runtime_put(imx334->dev); in imx334_set_stream()
1065 mutex_unlock(&imx334->mutex); in imx334_set_stream()
1070 pm_runtime_put(imx334->dev); in imx334_set_stream()
1072 mutex_unlock(&imx334->mutex); in imx334_set_stream()
1078 * imx334_detect() - Detect imx334 sensor
1081 * Return: 0 if successful, -EIO if sensor id does not match
1093 dev_err(imx334->dev, "chip id mismatch: %x!=%x", in imx334_detect()
1095 return -ENXIO; in imx334_detect()
1102 * imx334_parse_hw_config() - Parse HW configuration and check if supported
1109 struct fwnode_handle *fwnode = dev_fwnode(imx334->dev); in imx334_parse_hw_config()
1118 return -ENXIO; in imx334_parse_hw_config()
1121 imx334->reset_gpio = devm_gpiod_get_optional(imx334->dev, "reset", in imx334_parse_hw_config()
1123 if (IS_ERR(imx334->reset_gpio)) { in imx334_parse_hw_config()
1124 dev_err(imx334->dev, "failed to get reset gpio %ld", in imx334_parse_hw_config()
1125 PTR_ERR(imx334->reset_gpio)); in imx334_parse_hw_config()
1126 return PTR_ERR(imx334->reset_gpio); in imx334_parse_hw_config()
1130 imx334->inclk = devm_clk_get(imx334->dev, NULL); in imx334_parse_hw_config()
1131 if (IS_ERR(imx334->inclk)) { in imx334_parse_hw_config()
1132 dev_err(imx334->dev, "could not get inclk"); in imx334_parse_hw_config()
1133 return PTR_ERR(imx334->inclk); in imx334_parse_hw_config()
1136 rate = clk_get_rate(imx334->inclk); in imx334_parse_hw_config()
1138 dev_err(imx334->dev, "inclk frequency mismatch"); in imx334_parse_hw_config()
1139 return -EINVAL; in imx334_parse_hw_config()
1144 return -ENXIO; in imx334_parse_hw_config()
1152 dev_err(imx334->dev, in imx334_parse_hw_config()
1155 ret = -EINVAL; in imx334_parse_hw_config()
1159 ret = v4l2_link_freq_to_bitmap(imx334->dev, bus_cfg.link_frequencies, in imx334_parse_hw_config()
1162 &imx334->link_freq_bitmap); in imx334_parse_hw_config()
1192 * imx334_power_on() - Sensor power on sequence
1199 struct v4l2_subdev *sd = dev_get_drvdata(dev); in imx334_power_on() local
1200 struct imx334 *imx334 = to_imx334(sd); in imx334_power_on()
1203 gpiod_set_value_cansleep(imx334->reset_gpio, 1); in imx334_power_on()
1205 ret = clk_prepare_enable(imx334->inclk); in imx334_power_on()
1207 dev_err(imx334->dev, "fail to enable inclk"); in imx334_power_on()
1216 gpiod_set_value_cansleep(imx334->reset_gpio, 0); in imx334_power_on()
1222 * imx334_power_off() - Sensor power off sequence
1229 struct v4l2_subdev *sd = dev_get_drvdata(dev); in imx334_power_off() local
1230 struct imx334 *imx334 = to_imx334(sd); in imx334_power_off()
1232 gpiod_set_value_cansleep(imx334->reset_gpio, 0); in imx334_power_off()
1234 clk_disable_unprepare(imx334->inclk); in imx334_power_off()
1240 * imx334_init_controls() - Initialize sensor subdevice controls
1247 struct v4l2_ctrl_handler *ctrl_hdlr = &imx334->ctrl_handler; in imx334_init_controls()
1248 const struct imx334_mode *mode = imx334->cur_mode; in imx334_init_controls()
1257 ctrl_hdlr->lock = &imx334->mutex; in imx334_init_controls()
1260 lpfr = mode->vblank + mode->height; in imx334_init_controls()
1261 imx334->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx334_init_controls()
1265 lpfr - IMX334_EXPOSURE_OFFSET, in imx334_init_controls()
1269 imx334->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx334_init_controls()
1277 v4l2_ctrl_cluster(2, &imx334->exp_ctrl); in imx334_init_controls()
1279 imx334->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx334_init_controls()
1282 mode->vblank_min, in imx334_init_controls()
1283 mode->vblank_max, in imx334_init_controls()
1284 1, mode->vblank); in imx334_init_controls()
1287 imx334->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx334_init_controls()
1290 mode->pclk, mode->pclk, in imx334_init_controls()
1291 1, mode->pclk); in imx334_init_controls()
1293 imx334->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr, in imx334_init_controls()
1296 __fls(imx334->link_freq_bitmap), in imx334_init_controls()
1297 __ffs(imx334->link_freq_bitmap), in imx334_init_controls()
1300 if (imx334->link_freq_ctrl) in imx334_init_controls()
1301 imx334->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx334_init_controls()
1303 imx334->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx334_init_controls()
1308 1, mode->hblank); in imx334_init_controls()
1309 if (imx334->hblank_ctrl) in imx334_init_controls()
1310 imx334->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx334_init_controls()
1314 ARRAY_SIZE(imx334_test_pattern_menu) - 1, in imx334_init_controls()
1317 if (ctrl_hdlr->error) { in imx334_init_controls()
1318 dev_err(imx334->dev, "control init failed: %d", in imx334_init_controls()
1319 ctrl_hdlr->error); in imx334_init_controls()
1321 return ctrl_hdlr->error; in imx334_init_controls()
1324 imx334->sd.ctrl_handler = ctrl_hdlr; in imx334_init_controls()
1330 * imx334_probe() - I2C client device binding
1340 imx334 = devm_kzalloc(&client->dev, sizeof(*imx334), GFP_KERNEL); in imx334_probe()
1342 return -ENOMEM; in imx334_probe()
1344 imx334->dev = &client->dev; in imx334_probe()
1347 v4l2_i2c_subdev_init(&imx334->sd, client, &imx334_subdev_ops); in imx334_probe()
1348 imx334->sd.internal_ops = &imx334_internal_ops; in imx334_probe()
1352 dev_err(imx334->dev, "HW configuration is not supported"); in imx334_probe()
1356 mutex_init(&imx334->mutex); in imx334_probe()
1358 ret = imx334_power_on(imx334->dev); in imx334_probe()
1360 dev_err(imx334->dev, "failed to power-on the sensor"); in imx334_probe()
1367 dev_err(imx334->dev, "failed to find sensor: %d", ret); in imx334_probe()
1372 imx334->cur_mode = &supported_modes[__ffs(imx334->link_freq_bitmap)]; in imx334_probe()
1373 imx334->cur_code = imx334_mbus_codes[0]; in imx334_probe()
1374 imx334->vblank = imx334->cur_mode->vblank; in imx334_probe()
1378 dev_err(imx334->dev, "failed to init controls: %d", ret); in imx334_probe()
1383 imx334->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in imx334_probe()
1384 imx334->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in imx334_probe()
1387 imx334->pad.flags = MEDIA_PAD_FL_SOURCE; in imx334_probe()
1388 ret = media_entity_pads_init(&imx334->sd.entity, 1, &imx334->pad); in imx334_probe()
1390 dev_err(imx334->dev, "failed to init entity pads: %d", ret); in imx334_probe()
1394 ret = v4l2_async_register_subdev_sensor(&imx334->sd); in imx334_probe()
1396 dev_err(imx334->dev, in imx334_probe()
1401 pm_runtime_set_active(imx334->dev); in imx334_probe()
1402 pm_runtime_enable(imx334->dev); in imx334_probe()
1403 pm_runtime_idle(imx334->dev); in imx334_probe()
1408 media_entity_cleanup(&imx334->sd.entity); in imx334_probe()
1410 v4l2_ctrl_handler_free(imx334->sd.ctrl_handler); in imx334_probe()
1412 imx334_power_off(imx334->dev); in imx334_probe()
1414 mutex_destroy(&imx334->mutex); in imx334_probe()
1420 * imx334_remove() - I2C client device unbinding
1427 struct v4l2_subdev *sd = i2c_get_clientdata(client); in imx334_remove() local
1428 struct imx334 *imx334 = to_imx334(sd); in imx334_remove()
1430 v4l2_async_unregister_subdev(sd); in imx334_remove()
1431 media_entity_cleanup(&sd->entity); in imx334_remove()
1432 v4l2_ctrl_handler_free(sd->ctrl_handler); in imx334_remove()
1434 pm_runtime_disable(&client->dev); in imx334_remove()
1435 pm_runtime_suspended(&client->dev); in imx334_remove()
1437 mutex_destroy(&imx334->mutex); in imx334_remove()