Lines Matching +full:hb +full:- +full:pll +full:- +full:clock
1 /*SPDX-License-Identifier: GPL-2.0 */
23 #include <linux/rk-camera-module.h>
24 #include <media/media-entity.h>
25 #include <media/v4l2-async.h>
26 #include <media/v4l2-ctrls.h>
27 #include <media/v4l2-subdev.h>
154 {0xf7, 0x19}, //19 //clk_double pll enable
155 {0xf8, 0x06}, //Pll mode 2
156 {0xf9, 0x0e}, //de//[0] pll enable
165 {0x05, 0x01}, //HB
333 dev_info(&client->dev, "%s(%d) enter!\n", __func__, __LINE__); in gc2355_write_reg()
334 dev_info(&client->dev, "gc2355 write reg(0x%x val:0x%x)!\n", reg, val); in gc2355_write_reg()
338 msg.addr = client->addr; in gc2355_write_reg()
339 msg.flags = client->flags; in gc2355_write_reg()
343 ret = i2c_transfer(client->adapter, &msg, 1); in gc2355_write_reg()
347 dev_err(&client->dev, in gc2355_write_reg()
362 msg[0].addr = client->addr; in gc2355_read_reg()
363 msg[0].flags = client->flags; in gc2355_read_reg()
367 msg[1].addr = client->addr; in gc2355_read_reg()
368 msg[1].flags = client->flags | I2C_M_RD; in gc2355_read_reg()
372 ret = i2c_transfer(client->adapter, msg, 2); in gc2355_read_reg()
378 dev_err(&client->dev, in gc2355_read_reg()
399 return abs(mode->width - framefmt->width) + in gc2355_get_reso_dist()
400 abs(mode->height - framefmt->height); in gc2355_get_reso_dist()
406 struct v4l2_mbus_framefmt *framefmt = &fmt->format; in gc2355_find_best_fit()
409 int cur_best_fit_dist = -1; in gc2355_find_best_fit()
414 if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) { in gc2355_find_best_fit()
431 mutex_lock(&gc2355->mutex); in gc2355_set_fmt()
434 fmt->format.code = MEDIA_BUS_FMT_SRGGB10_1X10; in gc2355_set_fmt()
435 fmt->format.width = mode->width; in gc2355_set_fmt()
436 fmt->format.height = mode->height; in gc2355_set_fmt()
437 fmt->format.field = V4L2_FIELD_NONE; in gc2355_set_fmt()
438 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in gc2355_set_fmt()
440 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format; in gc2355_set_fmt()
442 mutex_unlock(&gc2355->mutex); in gc2355_set_fmt()
443 return -ENOTTY; in gc2355_set_fmt()
446 gc2355->cur_mode = mode; in gc2355_set_fmt()
447 h_blank = mode->hts_def - mode->width; in gc2355_set_fmt()
448 __v4l2_ctrl_modify_range(gc2355->hblank, h_blank, in gc2355_set_fmt()
450 vblank_def = mode->vts_def - mode->height; in gc2355_set_fmt()
451 __v4l2_ctrl_modify_range(gc2355->vblank, vblank_def, in gc2355_set_fmt()
452 GC2355_VTS_MAX - mode->height, in gc2355_set_fmt()
456 mutex_unlock(&gc2355->mutex); in gc2355_set_fmt()
466 const struct gc2355_mode *mode = gc2355->cur_mode; in gc2355_get_fmt()
468 mutex_lock(&gc2355->mutex); in gc2355_get_fmt()
469 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { in gc2355_get_fmt()
471 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad); in gc2355_get_fmt()
473 mutex_unlock(&gc2355->mutex); in gc2355_get_fmt()
474 return -ENOTTY; in gc2355_get_fmt()
477 fmt->format.width = mode->width; in gc2355_get_fmt()
478 fmt->format.height = mode->height; in gc2355_get_fmt()
479 fmt->format.code = MEDIA_BUS_FMT_SRGGB10_1X10; in gc2355_get_fmt()
480 fmt->format.field = V4L2_FIELD_NONE; in gc2355_get_fmt()
482 mutex_unlock(&gc2355->mutex); in gc2355_get_fmt()
491 if (code->index != 0) in gc2355_enum_mbus_code()
492 return -EINVAL; in gc2355_enum_mbus_code()
493 code->code = MEDIA_BUS_FMT_SRGGB10_1X10; in gc2355_enum_mbus_code()
502 if (fse->index >= ARRAY_SIZE(supported_modes)) in gc2355_enum_frame_sizes()
503 return -EINVAL; in gc2355_enum_frame_sizes()
505 if (fse->code != MEDIA_BUS_FMT_SRGGB10_1X10) in gc2355_enum_frame_sizes()
506 return -EINVAL; in gc2355_enum_frame_sizes()
508 fse->min_width = supported_modes[fse->index].width; in gc2355_enum_frame_sizes()
509 fse->max_width = supported_modes[fse->index].width; in gc2355_enum_frame_sizes()
510 fse->max_height = supported_modes[fse->index].height; in gc2355_enum_frame_sizes()
511 fse->min_height = supported_modes[fse->index].height; in gc2355_enum_frame_sizes()
520 const struct gc2355_mode *mode = gc2355->cur_mode; in gc2355_g_frame_interval()
522 fi->interval = mode->max_fps; in gc2355_g_frame_interval()
531 strlcpy(inf->base.sensor, GC2355_NAME, sizeof(inf->base.sensor)); in gc2355_get_module_inf()
532 strlcpy(inf->base.module, gc2355->module_name, in gc2355_get_module_inf()
533 sizeof(inf->base.module)); in gc2355_get_module_inf()
534 strlcpy(inf->base.lens, gc2355->len_name, sizeof(inf->base.lens)); in gc2355_get_module_inf()
552 ret = gc2355_write_reg(gc2355->client, GC2355_PAGE_SELECT, 0x03); in gc2355_ioctl()
553 ret |= gc2355_write_reg(gc2355->client, GC2355_MODE_SELECT, in gc2355_ioctl()
555 ret |= gc2355_write_reg(gc2355->client, GC2355_PAGE_SELECT, 0x00); in gc2355_ioctl()
557 ret = gc2355_write_reg(gc2355->client, GC2355_PAGE_SELECT, 0x03); in gc2355_ioctl()
558 ret |= gc2355_write_reg(gc2355->client, GC2355_MODE_SELECT, in gc2355_ioctl()
560 ret |= gc2355_write_reg(gc2355->client, GC2355_PAGE_SELECT, 0x00); in gc2355_ioctl()
564 ret = -ENOIOCTLCMD; in gc2355_ioctl()
585 ret = -ENOMEM; in gc2355_compat_ioctl32()
597 ret = -ENOMEM; in gc2355_compat_ioctl32()
612 ret = -ENOIOCTLCMD; in gc2355_compat_ioctl32()
624 ret = gc2355_write_array(gc2355->client, gc2355_global_regs); in __gc2355_start_stream()
628 ret = gc2355_write_array(gc2355->client, gc2355->cur_mode->reg_list); in __gc2355_start_stream()
633 mutex_unlock(&gc2355->mutex); in __gc2355_start_stream()
634 ret = v4l2_ctrl_handler_setup(&gc2355->ctrl_handler); in __gc2355_start_stream()
635 mutex_lock(&gc2355->mutex); in __gc2355_start_stream()
639 ret = gc2355_write_reg(gc2355->client, GC2355_PAGE_SELECT, 0x03); in __gc2355_start_stream()
640 ret = gc2355_write_reg(gc2355->client, GC2355_MODE_SELECT, in __gc2355_start_stream()
642 ret = gc2355_write_reg(gc2355->client, GC2355_PAGE_SELECT, 0x00); in __gc2355_start_stream()
650 ret = gc2355_write_reg(gc2355->client, GC2355_PAGE_SELECT, 0x03); in __gc2355_stop_stream()
651 ret = gc2355_write_reg(gc2355->client, GC2355_MODE_SELECT, in __gc2355_stop_stream()
653 ret = gc2355_write_reg(gc2355->client, GC2355_PAGE_SELECT, 0x00); in __gc2355_stop_stream()
660 struct i2c_client *client = gc2355->client; in gc2355_s_stream()
663 mutex_lock(&gc2355->mutex); in gc2355_s_stream()
665 if (on == gc2355->streaming) in gc2355_s_stream()
669 ret = pm_runtime_get_sync(&client->dev); in gc2355_s_stream()
671 pm_runtime_put_noidle(&client->dev); in gc2355_s_stream()
678 pm_runtime_put(&client->dev); in gc2355_s_stream()
683 pm_runtime_put(&client->dev); in gc2355_s_stream()
686 gc2355->streaming = on; in gc2355_s_stream()
689 mutex_unlock(&gc2355->mutex); in gc2355_s_stream()
694 /* Calculate the delay in us by clock rate and clock cycles */
704 struct device *dev = &gc2355->client->dev; in __gc2355_power_on()
706 if (!IS_ERR_OR_NULL(gc2355->pins_default)) { in __gc2355_power_on()
707 ret = pinctrl_select_state(gc2355->pinctrl, in __gc2355_power_on()
708 gc2355->pins_default); in __gc2355_power_on()
712 ret = clk_set_rate(gc2355->xvclk, GC2355_XVCLK_FREQ); in __gc2355_power_on()
715 if (clk_get_rate(gc2355->xvclk) != GC2355_XVCLK_FREQ) in __gc2355_power_on()
717 ret = clk_prepare_enable(gc2355->xvclk); in __gc2355_power_on()
722 if (!IS_ERR(gc2355->reset_gpio)) in __gc2355_power_on()
723 gpiod_set_value_cansleep(gc2355->reset_gpio, 0); in __gc2355_power_on()
725 ret = regulator_bulk_enable(GC2355_NUM_SUPPLIES, gc2355->supplies); in __gc2355_power_on()
731 if (!IS_ERR(gc2355->reset_gpio)) in __gc2355_power_on()
732 gpiod_set_value_cansleep(gc2355->reset_gpio, 1); in __gc2355_power_on()
735 if (!IS_ERR(gc2355->pwdn_gpio)) in __gc2355_power_on()
736 gpiod_set_value_cansleep(gc2355->pwdn_gpio, 1); in __gc2355_power_on()
745 clk_disable_unprepare(gc2355->xvclk); in __gc2355_power_on()
753 struct device *dev = &gc2355->client->dev; in __gc2355_power_off()
755 if (!IS_ERR(gc2355->pwdn_gpio)) in __gc2355_power_off()
756 gpiod_set_value_cansleep(gc2355->pwdn_gpio, 0); in __gc2355_power_off()
757 clk_disable_unprepare(gc2355->xvclk); in __gc2355_power_off()
758 if (!IS_ERR(gc2355->reset_gpio)) in __gc2355_power_off()
759 gpiod_set_value_cansleep(gc2355->reset_gpio, 0); in __gc2355_power_off()
760 if (!IS_ERR_OR_NULL(gc2355->pins_sleep)) { in __gc2355_power_off()
761 ret = pinctrl_select_state(gc2355->pinctrl, in __gc2355_power_off()
762 gc2355->pins_sleep); in __gc2355_power_off()
766 regulator_bulk_disable(GC2355_NUM_SUPPLIES, gc2355->supplies); in __gc2355_power_off()
794 v4l2_subdev_get_try_format(sd, fh->pad, 0); in gc2355_open()
797 mutex_lock(&gc2355->mutex); in gc2355_open()
799 try_fmt->width = def_mode->width; in gc2355_open()
800 try_fmt->height = def_mode->height; in gc2355_open()
801 try_fmt->code = MEDIA_BUS_FMT_SRGGB10_1X10; in gc2355_open()
802 try_fmt->field = V4L2_FIELD_NONE; in gc2355_open()
804 mutex_unlock(&gc2355->mutex); in gc2355_open()
815 if (fie->index >= ARRAY_SIZE(supported_modes)) in gc2355_enum_frame_interval()
816 return -EINVAL; in gc2355_enum_frame_interval()
818 fie->code = MEDIA_BUS_FMT_SRGGB10_1X10; in gc2355_enum_frame_interval()
819 fie->width = supported_modes[fie->index].width; in gc2355_enum_frame_interval()
820 fie->height = supported_modes[fie->index].height; in gc2355_enum_frame_interval()
821 fie->interval = supported_modes[fie->index].max_fps; in gc2355_enum_frame_interval()
830 val = 1 << (GC2355_LANES - 1) | in gc2355_g_mbus_config()
833 config->type = V4L2_MBUS_CSI2; in gc2355_g_mbus_config()
834 config->flags = val; in gc2355_g_mbus_config()
879 struct gc2355 *gc2355 = container_of(ctrl->handler, in gc2355_set_ctrl()
881 struct i2c_client *client = gc2355->client; in gc2355_set_ctrl()
887 switch (ctrl->id) { in gc2355_set_ctrl()
890 max = gc2355->cur_mode->height + ctrl->val - 4; in gc2355_set_ctrl()
891 __v4l2_ctrl_modify_range(gc2355->exposure, in gc2355_set_ctrl()
892 gc2355->exposure->minimum, max, in gc2355_set_ctrl()
893 gc2355->exposure->step, in gc2355_set_ctrl()
894 gc2355->exposure->default_value); in gc2355_set_ctrl()
898 if (!pm_runtime_get_if_in_use(&client->dev)) in gc2355_set_ctrl()
901 switch (ctrl->id) { in gc2355_set_ctrl()
904 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
907 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
909 (ctrl->val >> 8) & 0x3f); in gc2355_set_ctrl()
910 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
912 ctrl->val & 0xff); in gc2355_set_ctrl()
915 usGain = ctrl->val; in gc2355_set_ctrl()
916 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
921 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
925 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
928 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
933 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
937 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
940 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
945 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
949 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
952 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
956 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
960 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
963 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
969 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
972 ret = gc2355_write_reg(gc2355->client, in gc2355_set_ctrl()
974 ((ctrl->val + gc2355->cur_mode->height) >> 8) & 0x3f); in gc2355_set_ctrl()
975 ret = gc2355_write_reg(gc2355->client, GC2355_REG_VTS_L, in gc2355_set_ctrl()
976 (ctrl->val + gc2355->cur_mode->height) & in gc2355_set_ctrl()
981 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n", in gc2355_set_ctrl()
982 __func__, ctrl->id, ctrl->val); in gc2355_set_ctrl()
986 pm_runtime_put(&client->dev); in gc2355_set_ctrl()
1003 struct device *dev = &gc2355->client->dev; in gc2355_initialize_controls()
1006 handler = &gc2355->ctrl_handler; in gc2355_initialize_controls()
1007 mode = gc2355->cur_mode; in gc2355_initialize_controls()
1011 handler->lock = &gc2355->mutex; in gc2355_initialize_controls()
1016 ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in gc2355_initialize_controls()
1021 h_blank = mode->hts_def - mode->width; in gc2355_initialize_controls()
1022 gc2355->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, in gc2355_initialize_controls()
1024 if (gc2355->hblank) in gc2355_initialize_controls()
1025 gc2355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in gc2355_initialize_controls()
1027 vblank_def = mode->vts_def - mode->height; in gc2355_initialize_controls()
1028 gc2355->vblank = v4l2_ctrl_new_std(handler, &gc2355_ctrl_ops, in gc2355_initialize_controls()
1030 GC2355_VTS_MAX - mode->height, in gc2355_initialize_controls()
1033 exposure_max = mode->vts_def - 4; in gc2355_initialize_controls()
1034 gc2355->exposure = v4l2_ctrl_new_std(handler, &gc2355_ctrl_ops, in gc2355_initialize_controls()
1037 mode->exp_def); in gc2355_initialize_controls()
1039 gc2355->anal_gain = v4l2_ctrl_new_std(handler, &gc2355_ctrl_ops, in gc2355_initialize_controls()
1044 if (handler->error) { in gc2355_initialize_controls()
1045 ret = handler->error; in gc2355_initialize_controls()
1046 dev_err(&gc2355->client->dev, in gc2355_initialize_controls()
1051 gc2355->subdev.ctrl_handler = handler; in gc2355_initialize_controls()
1064 struct device *dev = &gc2355->client->dev; in gc2355_check_sensor_id()
1097 gc2355->supplies[i].supply = gc2355_supply_names[i]; in gc2355_configure_regulators()
1099 return devm_regulator_bulk_get(&gc2355->client->dev, in gc2355_configure_regulators()
1101 gc2355->supplies); in gc2355_configure_regulators()
1107 struct device *dev = &client->dev; in gc2355_probe()
1108 struct device_node *node = dev->of_node; in gc2355_probe()
1121 return -ENOMEM; in gc2355_probe()
1124 &gc2355->module_index); in gc2355_probe()
1126 &gc2355->module_facing); in gc2355_probe()
1128 &gc2355->module_name); in gc2355_probe()
1130 &gc2355->len_name); in gc2355_probe()
1133 return -EINVAL; in gc2355_probe()
1136 gc2355->client = client; in gc2355_probe()
1137 gc2355->cur_mode = &supported_modes[0]; in gc2355_probe()
1139 gc2355->xvclk = devm_clk_get(dev, "xvclk"); in gc2355_probe()
1140 if (IS_ERR(gc2355->xvclk)) { in gc2355_probe()
1142 return -EINVAL; in gc2355_probe()
1145 gc2355->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); in gc2355_probe()
1146 if (IS_ERR(gc2355->reset_gpio)) in gc2355_probe()
1147 dev_warn(dev, "Failed to get reset-gpios\n"); in gc2355_probe()
1149 gc2355->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); in gc2355_probe()
1150 if (IS_ERR(gc2355->pwdn_gpio)) in gc2355_probe()
1151 dev_warn(dev, "Failed to get pwdn-gpios\n"); in gc2355_probe()
1153 gc2355->pinctrl = devm_pinctrl_get(dev); in gc2355_probe()
1154 if (!IS_ERR(gc2355->pinctrl)) { in gc2355_probe()
1155 gc2355->pins_default = in gc2355_probe()
1156 pinctrl_lookup_state(gc2355->pinctrl, in gc2355_probe()
1158 if (IS_ERR(gc2355->pins_default)) in gc2355_probe()
1161 gc2355->pins_sleep = in gc2355_probe()
1162 pinctrl_lookup_state(gc2355->pinctrl, in gc2355_probe()
1164 if (IS_ERR(gc2355->pins_sleep)) in gc2355_probe()
1176 mutex_init(&gc2355->mutex); in gc2355_probe()
1178 sd = &gc2355->subdev; in gc2355_probe()
1193 sd->internal_ops = &gc2355_internal_ops; in gc2355_probe()
1194 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in gc2355_probe()
1198 gc2355->pad.flags = MEDIA_PAD_FL_SOURCE; in gc2355_probe()
1199 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; in gc2355_probe()
1200 ret = media_entity_pads_init(&sd->entity, 1, &gc2355->pad); in gc2355_probe()
1206 if (strcmp(gc2355->module_facing, "back") == 0) in gc2355_probe()
1211 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s", in gc2355_probe()
1212 gc2355->module_index, facing, in gc2355_probe()
1213 GC2355_NAME, dev_name(sd->dev)); in gc2355_probe()
1228 media_entity_cleanup(&sd->entity); in gc2355_probe()
1233 v4l2_ctrl_handler_free(&gc2355->ctrl_handler); in gc2355_probe()
1235 mutex_destroy(&gc2355->mutex); in gc2355_probe()
1247 media_entity_cleanup(&sd->entity); in gc2355_remove()
1249 v4l2_ctrl_handler_free(&gc2355->ctrl_handler); in gc2355_remove()
1250 mutex_destroy(&gc2355->mutex); in gc2355_remove()
1252 pm_runtime_disable(&client->dev); in gc2355_remove()
1253 if (!pm_runtime_status_suspended(&client->dev)) in gc2355_remove()
1255 pm_runtime_set_suspended(&client->dev); in gc2355_remove()