Lines Matching +full:colour +full:- +full:sensor
1 // SPDX-License-Identifier: GPL-2.0
13 #include <media/v4l2-ctrls.h>
14 #include <media/v4l2-device.h>
15 #include <media/v4l2-fwnode.h>
33 /* vertical-timings from sensor */
39 /* horizontal-timings from sensor */
42 /* Exposure controls from sensor */
48 /* Analog gain controls from sensor */
54 /* Digital gain controls from sensor */
117 /* Sensor register settings for this resolution */
529 "Solid Colour",
530 "100% Colour Bars",
531 "Fade To Grey Colour Bars",
665 struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); in hi556_read_reg()
672 return -EINVAL; in hi556_read_reg()
675 msgs[0].addr = client->addr; in hi556_read_reg()
679 msgs[1].addr = client->addr; in hi556_read_reg()
682 msgs[1].buf = &data_buf[4 - len]; in hi556_read_reg()
684 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); in hi556_read_reg()
686 return -EIO; in hi556_read_reg()
695 struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); in hi556_write_reg()
699 return -EINVAL; in hi556_write_reg()
702 put_unaligned_be32(val << 8 * (4 - len), buf + 2); in hi556_write_reg()
704 return -EIO; in hi556_write_reg()
712 struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); in hi556_write_reg_list()
716 for (i = 0; i < r_list->num_of_regs; i++) { in hi556_write_reg_list()
717 ret = hi556_write_reg(hi556, r_list->regs[i].address, in hi556_write_reg_list()
719 r_list->regs[i].val); in hi556_write_reg_list()
721 dev_err_ratelimited(&client->dev, in hi556_write_reg_list()
723 r_list->regs[i].address, ret); in hi556_write_reg_list()
778 struct hi556 *hi556 = container_of(ctrl->handler, in hi556_set_ctrl()
780 struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); in hi556_set_ctrl()
785 if (ctrl->id == V4L2_CID_VBLANK) { in hi556_set_ctrl()
787 exposure_max = hi556->cur_mode->height + ctrl->val - in hi556_set_ctrl()
789 __v4l2_ctrl_modify_range(hi556->exposure, in hi556_set_ctrl()
790 hi556->exposure->minimum, in hi556_set_ctrl()
791 exposure_max, hi556->exposure->step, in hi556_set_ctrl()
796 if (!pm_runtime_get_if_in_use(&client->dev)) in hi556_set_ctrl()
799 switch (ctrl->id) { in hi556_set_ctrl()
802 HI556_REG_VALUE_16BIT, ctrl->val); in hi556_set_ctrl()
806 ret = hi556_update_digital_gain(hi556, ctrl->val); in hi556_set_ctrl()
811 HI556_REG_VALUE_16BIT, ctrl->val); in hi556_set_ctrl()
818 hi556->cur_mode->height + ctrl->val); in hi556_set_ctrl()
822 ret = hi556_test_pattern(hi556, ctrl->val); in hi556_set_ctrl()
826 ret = -EINVAL; in hi556_set_ctrl()
830 pm_runtime_put(&client->dev); in hi556_set_ctrl()
845 ctrl_hdlr = &hi556->ctrl_handler; in hi556_init_controls()
850 ctrl_hdlr->lock = &hi556->mutex; in hi556_init_controls()
851 hi556->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &hi556_ctrl_ops, in hi556_init_controls()
853 ARRAY_SIZE(link_freq_menu_items) - 1, in hi556_init_controls()
855 if (hi556->link_freq) in hi556_init_controls()
856 hi556->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in hi556_init_controls()
858 hi556->pixel_rate = v4l2_ctrl_new_std in hi556_init_controls()
864 hi556->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops, in hi556_init_controls()
866 hi556->cur_mode->fll_min - in hi556_init_controls()
867 hi556->cur_mode->height, in hi556_init_controls()
868 HI556_FLL_MAX - in hi556_init_controls()
869 hi556->cur_mode->height, 1, in hi556_init_controls()
870 hi556->cur_mode->fll_def - in hi556_init_controls()
871 hi556->cur_mode->height); in hi556_init_controls()
873 h_blank = hi556->cur_mode->llp - hi556->cur_mode->width; in hi556_init_controls()
875 hi556->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops, in hi556_init_controls()
878 if (hi556->hblank) in hi556_init_controls()
879 hi556->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in hi556_init_controls()
887 exposure_max = hi556->cur_mode->fll_def - HI556_EXPOSURE_MAX_MARGIN; in hi556_init_controls()
888 hi556->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &hi556_ctrl_ops, in hi556_init_controls()
895 ARRAY_SIZE(hi556_test_pattern_menu) - 1, in hi556_init_controls()
897 if (ctrl_hdlr->error) in hi556_init_controls()
898 return ctrl_hdlr->error; in hi556_init_controls()
900 hi556->sd.ctrl_handler = ctrl_hdlr; in hi556_init_controls()
908 fmt->width = mode->width; in hi556_assign_pad_format()
909 fmt->height = mode->height; in hi556_assign_pad_format()
910 fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; in hi556_assign_pad_format()
911 fmt->field = V4L2_FIELD_NONE; in hi556_assign_pad_format()
916 struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); in hi556_identify_module()
920 if (hi556->identified) in hi556_identify_module()
929 dev_err(&client->dev, "chip id mismatch: %x!=%x", in hi556_identify_module()
931 return -ENXIO; in hi556_identify_module()
934 hi556->identified = true; in hi556_identify_module()
948 return &hi556->cur_mode->crop; in __hi556_get_pad_crop()
958 switch (sel->target) { in hi556_get_selection()
962 mutex_lock(&hi556->mutex); in hi556_get_selection()
963 sel->r = *__hi556_get_pad_crop(hi556, sd_state, sel->pad, in hi556_get_selection()
964 sel->which); in hi556_get_selection()
965 mutex_unlock(&hi556->mutex); in hi556_get_selection()
971 sel->r.top = 0; in hi556_get_selection()
972 sel->r.left = 0; in hi556_get_selection()
973 sel->r.width = HI556_NATIVE_WIDTH; in hi556_get_selection()
974 sel->r.height = HI556_NATIVE_HEIGHT; in hi556_get_selection()
980 sel->r.top = HI556_PIXEL_ARRAY_TOP; in hi556_get_selection()
981 sel->r.left = HI556_PIXEL_ARRAY_LEFT; in hi556_get_selection()
982 sel->r.width = HI556_PIXEL_ARRAY_WIDTH; in hi556_get_selection()
983 sel->r.height = HI556_PIXEL_ARRAY_HEIGHT; in hi556_get_selection()
988 return -EINVAL; in hi556_get_selection()
993 struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); in hi556_start_streaming()
1001 link_freq_index = hi556->cur_mode->link_freq_index; in hi556_start_streaming()
1005 dev_err(&client->dev, "failed to set plls"); in hi556_start_streaming()
1009 reg_list = &hi556->cur_mode->reg_list; in hi556_start_streaming()
1012 dev_err(&client->dev, "failed to set mode"); in hi556_start_streaming()
1016 ret = __v4l2_ctrl_handler_setup(hi556->sd.ctrl_handler); in hi556_start_streaming()
1024 dev_err(&client->dev, "failed to set stream"); in hi556_start_streaming()
1033 struct i2c_client *client = v4l2_get_subdevdata(&hi556->sd); in hi556_stop_streaming()
1037 dev_err(&client->dev, "failed to set stream"); in hi556_stop_streaming()
1046 mutex_lock(&hi556->mutex); in hi556_set_stream()
1048 ret = pm_runtime_resume_and_get(&client->dev); in hi556_set_stream()
1050 mutex_unlock(&hi556->mutex); in hi556_set_stream()
1058 pm_runtime_put(&client->dev); in hi556_set_stream()
1062 pm_runtime_put(&client->dev); in hi556_set_stream()
1065 mutex_unlock(&hi556->mutex); in hi556_set_stream()
1080 height, fmt->format.width, in hi556_set_format()
1081 fmt->format.height); in hi556_set_format()
1083 mutex_lock(&hi556->mutex); in hi556_set_format()
1084 hi556_assign_pad_format(mode, &fmt->format); in hi556_set_format()
1085 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in hi556_set_format()
1086 *v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format; in hi556_set_format()
1088 hi556->cur_mode = mode; in hi556_set_format()
1089 __v4l2_ctrl_s_ctrl(hi556->link_freq, mode->link_freq_index); in hi556_set_format()
1090 __v4l2_ctrl_s_ctrl_int64(hi556->pixel_rate, in hi556_set_format()
1091 to_pixel_rate(mode->link_freq_index)); in hi556_set_format()
1094 vblank_def = mode->fll_def - mode->height; in hi556_set_format()
1095 __v4l2_ctrl_modify_range(hi556->vblank, in hi556_set_format()
1096 mode->fll_min - mode->height, in hi556_set_format()
1097 HI556_FLL_MAX - mode->height, 1, in hi556_set_format()
1099 __v4l2_ctrl_s_ctrl(hi556->vblank, vblank_def); in hi556_set_format()
1101 h_blank = hi556->cur_mode->llp - hi556->cur_mode->width; in hi556_set_format()
1103 __v4l2_ctrl_modify_range(hi556->hblank, h_blank, h_blank, 1, in hi556_set_format()
1107 mutex_unlock(&hi556->mutex); in hi556_set_format()
1118 mutex_lock(&hi556->mutex); in hi556_get_format()
1119 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) in hi556_get_format()
1120 fmt->format = *v4l2_subdev_state_get_format(sd_state, in hi556_get_format()
1121 fmt->pad); in hi556_get_format()
1123 hi556_assign_pad_format(hi556->cur_mode, &fmt->format); in hi556_get_format()
1125 mutex_unlock(&hi556->mutex); in hi556_get_format()
1134 if (code->index > 0) in hi556_enum_mbus_code()
1135 return -EINVAL; in hi556_enum_mbus_code()
1137 code->code = MEDIA_BUS_FMT_SGRBG10_1X10; in hi556_enum_mbus_code()
1146 if (fse->index >= ARRAY_SIZE(supported_modes)) in hi556_enum_frame_size()
1147 return -EINVAL; in hi556_enum_frame_size()
1149 if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) in hi556_enum_frame_size()
1150 return -EINVAL; in hi556_enum_frame_size()
1152 fse->min_width = supported_modes[fse->index].width; in hi556_enum_frame_size()
1153 fse->max_width = fse->min_width; in hi556_enum_frame_size()
1154 fse->min_height = supported_modes[fse->index].height; in hi556_enum_frame_size()
1155 fse->max_height = fse->min_height; in hi556_enum_frame_size()
1165 mutex_lock(&hi556->mutex); in hi556_open()
1167 v4l2_subdev_state_get_format(fh->state, 0)); in hi556_open()
1170 try_crop = v4l2_subdev_state_get_crop(fh->state, 0); in hi556_open()
1171 try_crop->top = HI556_PIXEL_ARRAY_TOP; in hi556_open()
1172 try_crop->left = HI556_PIXEL_ARRAY_LEFT; in hi556_open()
1173 try_crop->width = HI556_PIXEL_ARRAY_WIDTH; in hi556_open()
1174 try_crop->height = HI556_PIXEL_ARRAY_HEIGHT; in hi556_open()
1176 mutex_unlock(&hi556->mutex); in hi556_open()
1223 return -EPROBE_DEFER; in hi556_check_hwcfg()
1230 ret = fwnode_property_read_u32(fwnode, "clock-frequency", &mclk); in hi556_check_hwcfg()
1238 ret = -EINVAL; in hi556_check_hwcfg()
1245 ret = -EINVAL; in hi556_check_hwcfg()
1251 ret = -EINVAL; in hi556_check_hwcfg()
1265 ret = -EINVAL; in hi556_check_hwcfg()
1282 media_entity_cleanup(&sd->entity); in hi556_remove()
1283 v4l2_ctrl_handler_free(sd->ctrl_handler); in hi556_remove()
1284 pm_runtime_disable(&client->dev); in hi556_remove()
1285 mutex_destroy(&hi556->mutex); in hi556_remove()
1294 gpiod_set_value_cansleep(hi556->reset_gpio, 1); in hi556_suspend()
1296 ret = regulator_disable(hi556->avdd); in hi556_suspend()
1299 gpiod_set_value_cansleep(hi556->reset_gpio, 0); in hi556_suspend()
1303 clk_disable_unprepare(hi556->clk); in hi556_suspend()
1313 ret = clk_prepare_enable(hi556->clk); in hi556_resume()
1317 ret = regulator_enable(hi556->avdd); in hi556_resume()
1320 clk_disable_unprepare(hi556->clk); in hi556_resume()
1324 gpiod_set_value_cansleep(hi556->reset_gpio, 0); in hi556_resume()
1335 ret = hi556_check_hwcfg(&client->dev); in hi556_probe()
1337 dev_err(&client->dev, "failed to check HW configuration: %d", in hi556_probe()
1342 hi556 = devm_kzalloc(&client->dev, sizeof(*hi556), GFP_KERNEL); in hi556_probe()
1344 return -ENOMEM; in hi556_probe()
1346 v4l2_i2c_subdev_init(&hi556->sd, client, &hi556_subdev_ops); in hi556_probe()
1348 hi556->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", in hi556_probe()
1350 if (IS_ERR(hi556->reset_gpio)) in hi556_probe()
1351 return dev_err_probe(&client->dev, PTR_ERR(hi556->reset_gpio), in hi556_probe()
1354 hi556->clk = devm_clk_get_optional(&client->dev, "clk"); in hi556_probe()
1355 if (IS_ERR(hi556->clk)) in hi556_probe()
1356 return dev_err_probe(&client->dev, PTR_ERR(hi556->clk), in hi556_probe()
1360 hi556->avdd = devm_regulator_get(&client->dev, "avdd"); in hi556_probe()
1361 if (IS_ERR(hi556->avdd)) in hi556_probe()
1362 return dev_err_probe(&client->dev, PTR_ERR(hi556->avdd), in hi556_probe()
1365 full_power = acpi_dev_state_d0(&client->dev); in hi556_probe()
1368 ret = hi556_resume(&client->dev); in hi556_probe()
1370 return dev_err_probe(&client->dev, ret, in hi556_probe()
1371 "failed to power on sensor\n"); in hi556_probe()
1375 dev_err(&client->dev, "failed to find sensor: %d", ret); in hi556_probe()
1380 mutex_init(&hi556->mutex); in hi556_probe()
1381 hi556->cur_mode = &supported_modes[0]; in hi556_probe()
1384 dev_err(&client->dev, "failed to init controls: %d", ret); in hi556_probe()
1388 hi556->sd.internal_ops = &hi556_internal_ops; in hi556_probe()
1389 hi556->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in hi556_probe()
1390 hi556->sd.entity.ops = &hi556_subdev_entity_ops; in hi556_probe()
1391 hi556->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in hi556_probe()
1392 hi556->pad.flags = MEDIA_PAD_FL_SOURCE; in hi556_probe()
1393 ret = media_entity_pads_init(&hi556->sd.entity, 1, &hi556->pad); in hi556_probe()
1395 dev_err(&client->dev, "failed to init entity pads: %d", ret); in hi556_probe()
1399 ret = v4l2_async_register_subdev_sensor(&hi556->sd); in hi556_probe()
1401 dev_err(&client->dev, "failed to register V4L2 subdev: %d", in hi556_probe()
1408 pm_runtime_set_active(&client->dev); in hi556_probe()
1409 pm_runtime_enable(&client->dev); in hi556_probe()
1410 pm_runtime_idle(&client->dev); in hi556_probe()
1415 media_entity_cleanup(&hi556->sd.entity); in hi556_probe()
1418 v4l2_ctrl_handler_free(hi556->sd.ctrl_handler); in hi556_probe()
1419 mutex_destroy(&hi556->mutex); in hi556_probe()
1423 hi556_suspend(&client->dev); in hi556_probe()
1454 MODULE_DESCRIPTION("Hynix HI556 sensor driver");