Lines Matching +full:media +full:- +full:blk +full:- +full:ctrl
1 // SPDX-License-Identifier: GPL-2.0
20 #include <media/mipi-csi2.h>
21 #include <media/v4l2-cci.h>
22 #include <media/v4l2-ctrls.h>
23 #include <media/v4l2-device.h>
24 #include <media/v4l2-fwnode.h>
25 #include <media/v4l2-mediabus.h>
103 * struct gc2145_mode - GC2145 mode description
151 /* BLK */
375 /* Row/Col start - 0/0 */
383 /* Crop 640-480@0-0 */
395 /* AEC anti-flicker */
397 /* AEC exposure level 1-5 */
414 /* Row/Col start - 240/160 */
420 /* Crop 1280-720@0-0 */
427 /* AEC anti-flicker */
429 /* AEC exposure level 1-5 */
446 /* Row/Col start - 0/0 */
452 /* Crop 1600-1200@0-0 */
459 /* AEC anti-flicker */
461 /* AEC exposure level 1-5 */
474 "iovdd", /* Digital I/O (1.7-3V) suppply */
475 "avdd", /* Analog (2.7-3V) supply */
476 "dvdd", /* Digital Core (1.7-1.9V) supply */
540 * struct gc2145_format - GC2145 pixel format description
541 * @code: media bus (MBUS) associated code
654 static inline struct v4l2_subdev *gc2145_ctrl_to_sd(struct v4l2_ctrl *ctrl) in gc2145_ctrl_to_sd() argument
656 return &container_of(ctrl->handler, struct gc2145, in gc2145_ctrl_to_sd()
657 ctrls.handler)->sd; in gc2145_ctrl_to_sd()
681 fmt->code = code; in gc2145_update_pad_format()
682 fmt->width = mode->width; in gc2145_update_pad_format()
683 fmt->height = mode->height; in gc2145_update_pad_format()
684 fmt->field = V4L2_FIELD_NONE; in gc2145_update_pad_format()
685 fmt->colorspace = V4L2_COLORSPACE_SRGB; in gc2145_update_pad_format()
686 fmt->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in gc2145_update_pad_format()
687 fmt->quantization = V4L2_QUANTIZATION_DEFAULT; in gc2145_update_pad_format()
688 fmt->xfer_func = V4L2_XFER_FUNC_DEFAULT; in gc2145_update_pad_format()
715 switch (sel->target) { in gc2145_get_selection()
717 sel->r = *v4l2_subdev_state_get_crop(sd_state, 0); in gc2145_get_selection()
721 sel->r.top = 0; in gc2145_get_selection()
722 sel->r.left = 0; in gc2145_get_selection()
723 sel->r.width = GC2145_NATIVE_WIDTH; in gc2145_get_selection()
724 sel->r.height = GC2145_NATIVE_HEIGHT; in gc2145_get_selection()
730 sel->r.top = 0; in gc2145_get_selection()
731 sel->r.left = 0; in gc2145_get_selection()
732 sel->r.width = 1600; in gc2145_get_selection()
733 sel->r.height = 1200; in gc2145_get_selection()
738 return -EINVAL; in gc2145_get_selection()
745 if (code->index >= ARRAY_SIZE(supported_formats)) in gc2145_enum_mbus_code()
746 return -EINVAL; in gc2145_enum_mbus_code()
748 code->code = supported_formats[code->index].code; in gc2145_enum_mbus_code()
760 if (fse->index >= ARRAY_SIZE(supported_modes)) in gc2145_enum_frame_size()
761 return -EINVAL; in gc2145_enum_frame_size()
763 gc2145_format = gc2145_get_format_code(gc2145, fse->code); in gc2145_enum_frame_size()
764 code = gc2145_format->code; in gc2145_enum_frame_size()
765 if (fse->code != code) in gc2145_enum_frame_size()
766 return -EINVAL; in gc2145_enum_frame_size()
768 fse->min_width = supported_modes[fse->index].width; in gc2145_enum_frame_size()
769 fse->max_width = fse->min_width; in gc2145_enum_frame_size()
770 fse->min_height = supported_modes[fse->index].height; in gc2145_enum_frame_size()
771 fse->max_height = fse->min_height; in gc2145_enum_frame_size()
784 struct gc2145_ctrls *ctrls = &gc2145->ctrls; in gc2145_set_pad_format()
787 gc2145_fmt = gc2145_get_format_code(gc2145, fmt->format.code); in gc2145_set_pad_format()
791 fmt->format.width, fmt->format.height); in gc2145_set_pad_format()
794 if (gc2145_fmt->colorspace == V4L2_COLORSPACE_RAW && in gc2145_set_pad_format()
798 gc2145_update_pad_format(gc2145, mode, &fmt->format, gc2145_fmt->code, in gc2145_set_pad_format()
799 gc2145_fmt->colorspace); in gc2145_set_pad_format()
800 framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); in gc2145_set_pad_format()
801 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) { in gc2145_set_pad_format()
802 gc2145->mode = mode; in gc2145_set_pad_format()
804 __v4l2_ctrl_s_ctrl_int64(ctrls->pixel_rate, mode->pixel_rate); in gc2145_set_pad_format()
806 __v4l2_ctrl_s_ctrl(ctrls->link_freq, mode->link_freq_index); in gc2145_set_pad_format()
808 __v4l2_ctrl_s_ctrl(ctrls->hblank, mode->hblank); in gc2145_set_pad_format()
809 __v4l2_ctrl_s_ctrl(ctrls->vblank, mode->vblank); in gc2145_set_pad_format()
811 *framefmt = fmt->format; in gc2145_set_pad_format()
812 crop = v4l2_subdev_state_get_crop(sd_state, fmt->pad); in gc2145_set_pad_format()
813 *crop = mode->crop; in gc2145_set_pad_format()
847 cci_multi_reg_write(gc2145->regmap, gc2145_common_mipi_regs, in gc2145_config_mipi_mode()
856 if (gc2145_format->colorspace != V4L2_COLORSPACE_RAW) in gc2145_config_mipi_mode()
857 lwc = gc2145->mode->width * 2; in gc2145_config_mipi_mode()
859 lwc = gc2145->mode->width; in gc2145_config_mipi_mode()
861 cci_write(gc2145->regmap, GC2145_REG_LWC, lwc, &ret); in gc2145_config_mipi_mode()
869 if (gc2145_format->colorspace != V4L2_COLORSPACE_RAW) { in gc2145_config_mipi_mode()
870 if (gc2145->mode->width == 1280 || gc2145->mode->width == 1600) in gc2145_config_mipi_mode()
878 cci_write(gc2145->regmap, GC2145_REG_FIFO_FULL_LVL, in gc2145_config_mipi_mode()
885 cci_write(gc2145->regmap, GC2145_REG_FIFO_GATE_MODE, in gc2145_config_mipi_mode()
886 gc2145_format->colorspace == V4L2_COLORSPACE_RAW ? in gc2145_config_mipi_mode()
890 cci_write(gc2145->regmap, GC2145_REG_MIPI_DT, in gc2145_config_mipi_mode()
891 gc2145_format->datatype, &ret); in gc2145_config_mipi_mode()
894 cci_write(gc2145->regmap, GC2145_REG_BUF_CSI2_MODE, in gc2145_config_mipi_mode()
906 struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd); in gc2145_enable_streams()
911 ret = pm_runtime_resume_and_get(&client->dev); in gc2145_enable_streams()
916 cci_multi_reg_write(gc2145->regmap, gc2145->mode->reg_seq, in gc2145_enable_streams()
917 gc2145->mode->reg_seq_size, &ret); in gc2145_enable_streams()
918 cci_multi_reg_write(gc2145->regmap, gc2145_common_regs, in gc2145_enable_streams()
921 dev_err(&client->dev, "%s failed to write regs\n", __func__); in gc2145_enable_streams()
926 gc2145_format = gc2145_get_format_code(gc2145, fmt->code); in gc2145_enable_streams()
929 cci_write(gc2145->regmap, GC2145_REG_PAGE_SELECT, 0x00, &ret); in gc2145_enable_streams()
931 cci_write(gc2145->regmap, GC2145_REG_OUTPUT_FMT, in gc2145_enable_streams()
932 gc2145_format->output_fmt, &ret); in gc2145_enable_streams()
933 cci_update_bits(gc2145->regmap, GC2145_REG_BYPASS_MODE, in gc2145_enable_streams()
935 gc2145_format->switch_bit ? GC2145_BYPASS_MODE_SWITCH in gc2145_enable_streams()
937 cci_update_bits(gc2145->regmap, GC2145_REG_SYNC_MODE, in gc2145_enable_streams()
940 gc2145_format->row_col_switch, &ret); in gc2145_enable_streams()
942 dev_err(&client->dev, "%s failed to write regs\n", __func__); in gc2145_enable_streams()
947 ret = __v4l2_ctrl_handler_setup(&gc2145->ctrls.handler); in gc2145_enable_streams()
949 dev_err(&client->dev, "%s failed to apply ctrls\n", __func__); in gc2145_enable_streams()
956 dev_err(&client->dev, "%s failed to write mipi conf\n", in gc2145_enable_streams()
961 cci_write(gc2145->regmap, GC2145_REG_PAGE_SELECT, 0x00, &ret); in gc2145_enable_streams()
966 pm_runtime_mark_last_busy(&client->dev); in gc2145_enable_streams()
967 pm_runtime_put_autosuspend(&client->dev); in gc2145_enable_streams()
976 struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd); in gc2145_disable_streams()
980 cci_write(gc2145->regmap, GC2145_REG_PAGE_SELECT, 0x03, &ret); in gc2145_disable_streams()
981 cci_update_bits(gc2145->regmap, GC2145_REG_BUF_CSI2_MODE, in gc2145_disable_streams()
984 cci_write(gc2145->regmap, GC2145_REG_PAGE_SELECT, 0x00, &ret); in gc2145_disable_streams()
986 dev_err(&client->dev, "%s failed to write regs\n", __func__); in gc2145_disable_streams()
988 pm_runtime_mark_last_busy(&client->dev); in gc2145_disable_streams()
989 pm_runtime_put_autosuspend(&client->dev); in gc2145_disable_streams()
1001 ret = regulator_bulk_enable(GC2145_NUM_SUPPLIES, gc2145->supplies); in gc2145_power_on()
1007 ret = clk_prepare_enable(gc2145->xclk); in gc2145_power_on()
1013 gpiod_set_value_cansleep(gc2145->powerdown_gpio, 0); in gc2145_power_on()
1014 gpiod_set_value_cansleep(gc2145->reset_gpio, 0); in gc2145_power_on()
1026 regulator_bulk_disable(GC2145_NUM_SUPPLIES, gc2145->supplies); in gc2145_power_on()
1036 gpiod_set_value_cansleep(gc2145->powerdown_gpio, 1); in gc2145_power_off()
1037 gpiod_set_value_cansleep(gc2145->reset_gpio, 1); in gc2145_power_off()
1038 clk_disable_unprepare(gc2145->xclk); in gc2145_power_off()
1039 regulator_bulk_disable(GC2145_NUM_SUPPLIES, gc2145->supplies); in gc2145_power_off()
1046 struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd); in gc2145_get_regulators()
1050 gc2145->supplies[i].supply = gc2145_supply_name[i]; in gc2145_get_regulators()
1052 return devm_regulator_bulk_get(&client->dev, GC2145_NUM_SUPPLIES, in gc2145_get_regulators()
1053 gc2145->supplies); in gc2145_get_regulators()
1059 struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd); in gc2145_identify_module()
1063 ret = cci_read(gc2145->regmap, GC2145_REG_CHIP_ID, &chip_id, NULL); in gc2145_identify_module()
1065 dev_err(&client->dev, "failed to read chip id (%d)\n", ret); in gc2145_identify_module()
1070 dev_err(&client->dev, "chip id mismatch: %x!=%llx\n", in gc2145_identify_module()
1072 return -EIO; in gc2145_identify_module()
1143 cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE2, 0, &ret); in gc2145_set_ctrl_test_pattern()
1144 return cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE3, 0, in gc2145_set_ctrl_test_pattern()
1149 cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE2, in gc2145_set_ctrl_test_pattern()
1153 return cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE3, 0, in gc2145_set_ctrl_test_pattern()
1157 return cci_write(gc2145->regmap, GC2145_REG_DEBUG_MODE3, in gc2145_set_ctrl_test_pattern()
1161 static int gc2145_s_ctrl(struct v4l2_ctrl *ctrl) in gc2145_s_ctrl() argument
1163 struct v4l2_subdev *sd = gc2145_ctrl_to_sd(ctrl); in gc2145_s_ctrl()
1168 if (pm_runtime_get_if_in_use(&client->dev) == 0) in gc2145_s_ctrl()
1171 switch (ctrl->id) { in gc2145_s_ctrl()
1173 ret = cci_write(gc2145->regmap, GC2145_REG_HBLANK, ctrl->val, in gc2145_s_ctrl()
1177 ret = cci_write(gc2145->regmap, GC2145_REG_VBLANK, ctrl->val, in gc2145_s_ctrl()
1181 ret = gc2145_set_ctrl_test_pattern(gc2145, ctrl->val); in gc2145_s_ctrl()
1184 ret = cci_update_bits(gc2145->regmap, GC2145_REG_ANALOG_MODE1, in gc2145_s_ctrl()
1185 BIT(0), (ctrl->val ? BIT(0) : 0), NULL); in gc2145_s_ctrl()
1188 ret = cci_update_bits(gc2145->regmap, GC2145_REG_ANALOG_MODE1, in gc2145_s_ctrl()
1189 BIT(1), (ctrl->val ? BIT(1) : 0), NULL); in gc2145_s_ctrl()
1192 ret = -EINVAL; in gc2145_s_ctrl()
1196 pm_runtime_mark_last_busy(&client->dev); in gc2145_s_ctrl()
1197 pm_runtime_put_autosuspend(&client->dev); in gc2145_s_ctrl()
1209 struct i2c_client *client = v4l2_get_subdevdata(&gc2145->sd); in gc2145_init_controls()
1211 struct gc2145_ctrls *ctrls = &gc2145->ctrls; in gc2145_init_controls()
1212 struct v4l2_ctrl_handler *hdl = &ctrls->handler; in gc2145_init_controls()
1220 ctrls->pixel_rate = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_PIXEL_RATE, in gc2145_init_controls()
1225 ctrls->link_freq = v4l2_ctrl_new_int_menu(hdl, ops, V4L2_CID_LINK_FREQ, in gc2145_init_controls()
1226 ARRAY_SIZE(gc2145_link_freq_menu) - 1, in gc2145_init_controls()
1228 if (ctrls->link_freq) in gc2145_init_controls()
1229 ctrls->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in gc2145_init_controls()
1231 ctrls->hblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HBLANK, in gc2145_init_controls()
1234 ctrls->vblank = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VBLANK, in gc2145_init_controls()
1237 ctrls->test_pattern = in gc2145_init_controls()
1239 ARRAY_SIZE(test_pattern_menu) - 1, in gc2145_init_controls()
1241 ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, in gc2145_init_controls()
1243 ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, in gc2145_init_controls()
1246 if (hdl->error) { in gc2145_init_controls()
1247 ret = hdl->error; in gc2145_init_controls()
1248 dev_err(&client->dev, "control init failed (%d)\n", ret); in gc2145_init_controls()
1252 ret = v4l2_fwnode_device_parse(&client->dev, &props); in gc2145_init_controls()
1261 gc2145->sd.ctrl_handler = hdl; in gc2145_init_controls()
1282 return -EINVAL; in gc2145_check_hwcfg()
1293 ret = -EINVAL; in gc2145_check_hwcfg()
1299 dev_err(dev, "link-frequency property not found in DT\n"); in gc2145_check_hwcfg()
1300 ret = -EINVAL; in gc2145_check_hwcfg()
1308 dev_err(dev, "Invalid link-frequencies provided\n"); in gc2145_check_hwcfg()
1309 ret = -EINVAL; in gc2145_check_hwcfg()
1320 struct device *dev = &client->dev; in gc2145_probe()
1325 gc2145 = devm_kzalloc(&client->dev, sizeof(*gc2145), GFP_KERNEL); in gc2145_probe()
1327 return -ENOMEM; in gc2145_probe()
1329 v4l2_i2c_subdev_init(&gc2145->sd, client, &gc2145_subdev_ops); in gc2145_probe()
1330 gc2145->sd.internal_ops = &gc2145_subdev_internal_ops; in gc2145_probe()
1334 return -EINVAL; in gc2145_probe()
1337 gc2145->xclk = devm_clk_get(dev, NULL); in gc2145_probe()
1338 if (IS_ERR(gc2145->xclk)) in gc2145_probe()
1339 return dev_err_probe(dev, PTR_ERR(gc2145->xclk), in gc2145_probe()
1342 xclk_freq = clk_get_rate(gc2145->xclk); in gc2145_probe()
1346 return -EINVAL; in gc2145_probe()
1355 gc2145->reset_gpio = devm_gpiod_get_optional(dev, "reset", in gc2145_probe()
1357 if (IS_ERR(gc2145->reset_gpio)) in gc2145_probe()
1358 return dev_err_probe(dev, PTR_ERR(gc2145->reset_gpio), in gc2145_probe()
1362 gc2145->powerdown_gpio = devm_gpiod_get_optional(dev, "powerdown", in gc2145_probe()
1364 if (IS_ERR(gc2145->powerdown_gpio)) in gc2145_probe()
1365 return dev_err_probe(dev, PTR_ERR(gc2145->powerdown_gpio), in gc2145_probe()
1369 gc2145->regmap = devm_cci_regmap_init_i2c(client, 8); in gc2145_probe()
1370 if (IS_ERR(gc2145->regmap)) in gc2145_probe()
1371 return dev_err_probe(dev, PTR_ERR(gc2145->regmap), in gc2145_probe()
1387 gc2145->mode = &supported_modes[0]; in gc2145_probe()
1394 gc2145->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in gc2145_probe()
1395 gc2145->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in gc2145_probe()
1398 gc2145->pad.flags = MEDIA_PAD_FL_SOURCE; in gc2145_probe()
1400 ret = media_entity_pads_init(&gc2145->sd.entity, 1, &gc2145->pad); in gc2145_probe()
1406 gc2145->sd.state_lock = gc2145->ctrls.handler.lock; in gc2145_probe()
1407 ret = v4l2_subdev_init_finalize(&gc2145->sd); in gc2145_probe()
1415 pm_runtime_get_noresume(&client->dev); in gc2145_probe()
1418 pm_runtime_set_autosuspend_delay(&client->dev, 1000); in gc2145_probe()
1419 pm_runtime_use_autosuspend(&client->dev); in gc2145_probe()
1420 pm_runtime_put_autosuspend(&client->dev); in gc2145_probe()
1422 ret = v4l2_async_register_subdev_sensor(&gc2145->sd); in gc2145_probe()
1424 dev_err(dev, "failed to register sensor sub-device: %d\n", ret); in gc2145_probe()
1431 v4l2_subdev_cleanup(&gc2145->sd); in gc2145_probe()
1432 pm_runtime_disable(&client->dev); in gc2145_probe()
1433 pm_runtime_set_suspended(&client->dev); in gc2145_probe()
1436 media_entity_cleanup(&gc2145->sd.entity); in gc2145_probe()
1439 v4l2_ctrl_handler_free(&gc2145->ctrls.handler); in gc2145_probe()
1454 media_entity_cleanup(&sd->entity); in gc2145_remove()
1455 v4l2_ctrl_handler_free(&gc2145->ctrls.handler); in gc2145_remove()
1457 pm_runtime_disable(&client->dev); in gc2145_remove()
1458 if (!pm_runtime_status_suspended(&client->dev)) in gc2145_remove()
1459 gc2145_power_off(&client->dev); in gc2145_remove()
1460 pm_runtime_set_suspended(&client->dev); in gc2145_remove()