Lines Matching refs:sc210iot
89 #define to_sc210iot(sd) container_of(sd, struct sc210iot, subdev)
121 struct sc210iot { struct
268 static inline int sc210iot_read_reg(struct sc210iot *sc210iot, u16 addr, u8 *value) in sc210iot_read_reg() argument
273 ret = regmap_read(sc210iot->regmap, addr, &val); in sc210iot_read_reg()
275 dev_err(sc210iot->dev, "i2c read failed at addr: %x\n", addr); in sc210iot_read_reg()
282 static int __sc210iot_power_on(struct sc210iot *sc210iot);
284 static inline int sc210iot_write_reg(struct sc210iot *sc210iot, u16 addr, u8 value) in sc210iot_write_reg() argument
288 ret = regmap_write(sc210iot->regmap, addr, value); in sc210iot_write_reg()
290 dev_err(sc210iot->dev, "i2c write failed at addr: %x\n", addr); in sc210iot_write_reg()
308 static int sc210iot_set_gain(struct sc210iot *sc210iot, u32 gain) in sc210iot_set_gain() argument
314 dev_dbg(sc210iot->dev, "%s: gain : %d\n", __func__, gain); in sc210iot_set_gain()
315 if (sc210iot->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) { in sc210iot_set_gain()
316 sc210iot->is_thunderboot = false; in sc210iot_set_gain()
317 sc210iot->is_thunderboot_ng = true; in sc210iot_set_gain()
318 __sc210iot_power_on(sc210iot); in sc210iot_set_gain()
345 dev_dbg(sc210iot->dev, "%s: a_gain: 0x%x d_gain: 0x%x\n", __func__, a_gain, d_gain); in sc210iot_set_gain()
347 ret = sc210iot_write_reg(sc210iot, SC210IOT_REG_GAIN_LONG_1, a_gain >> 8); in sc210iot_set_gain()
348 ret |= sc210iot_write_reg(sc210iot, SC210IOT_REG_GAIN_LONG_0, a_gain & 0xff); in sc210iot_set_gain()
349 ret |= sc210iot_write_reg(sc210iot, SC210IOT_REG_GAIN_LONG_3, d_gain >> 8); in sc210iot_set_gain()
350 ret |= sc210iot_write_reg(sc210iot, SC210IOT_REG_GAIN_LONG_2, d_gain & 0xff); in sc210iot_set_gain()
354 static int sc210iot_set_exp(struct sc210iot *sc210iot, u32 exp) in sc210iot_set_exp() argument
358 dev_dbg(sc210iot->dev, "%s: exp : %d\n", __func__, exp); in sc210iot_set_exp()
359 ret = sc210iot_write_reg(sc210iot, SC210IOT_REG_EXP_LONG_H, in sc210iot_set_exp()
361 ret |= sc210iot_write_reg(sc210iot, SC210IOT_REG_EXP_LONG_M, in sc210iot_set_exp()
363 ret |= sc210iot_write_reg(sc210iot, SC210IOT_REG_EXP_LONG_L, in sc210iot_set_exp()
368 static void sc210iot_modify_fps_info(struct sc210iot *sc210iot) in sc210iot_modify_fps_info() argument
370 const struct sc210iot_mode *mode = sc210iot->cur_mode; in sc210iot_modify_fps_info()
372 sc210iot->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def / in sc210iot_modify_fps_info()
373 sc210iot->cur_vts; in sc210iot_modify_fps_info()
378 struct sc210iot *sc210iot = container_of(ctrl->handler, in sc210iot_set_ctrl() local
379 struct sc210iot, ctrl_handler); in sc210iot_set_ctrl()
387 max = sc210iot->cur_mode->height + ctrl->val - 4; in sc210iot_set_ctrl()
388 __v4l2_ctrl_modify_range(sc210iot->exposure, in sc210iot_set_ctrl()
389 sc210iot->exposure->minimum, max, in sc210iot_set_ctrl()
390 sc210iot->exposure->step, in sc210iot_set_ctrl()
391 sc210iot->exposure->default_value); in sc210iot_set_ctrl()
394 if (!pm_runtime_get_if_in_use(sc210iot->dev)) in sc210iot_set_ctrl()
398 ret = sc210iot_set_exp(sc210iot, ctrl->val << 1); in sc210iot_set_ctrl()
401 ret = sc210iot_set_gain(sc210iot, ctrl->val); in sc210iot_set_ctrl()
404 dev_dbg(sc210iot->dev, "set vblank 0x%x\n", ctrl->val); in sc210iot_set_ctrl()
405 ret = sc210iot_write_reg(sc210iot, SC210IOT_REG_VTS_H, in sc210iot_set_ctrl()
406 (ctrl->val + sc210iot->cur_mode->height) >> 8); in sc210iot_set_ctrl()
407 ret |= sc210iot_write_reg(sc210iot, SC210IOT_REG_VTS_L, in sc210iot_set_ctrl()
408 (ctrl->val + sc210iot->cur_mode->height) & 0xff); in sc210iot_set_ctrl()
410 sc210iot->cur_vts = ctrl->val + sc210iot->cur_mode->height; in sc210iot_set_ctrl()
411 sc210iot_modify_fps_info(sc210iot); in sc210iot_set_ctrl()
414 regmap_update_bits(sc210iot->regmap, SC210IOT_REG_MIRROR_FLIP, in sc210iot_set_ctrl()
418 regmap_update_bits(sc210iot->regmap, SC210IOT_REG_MIRROR_FLIP, in sc210iot_set_ctrl()
422 dev_warn(sc210iot->dev, "%s Unhandled id:0x%x, val:0x%x\n", in sc210iot_set_ctrl()
426 pm_runtime_put(sc210iot->dev); in sc210iot_set_ctrl()
434 static int sc210iot_get_regulators(struct sc210iot *sc210iot) in sc210iot_get_regulators() argument
439 sc210iot->supplies[i].supply = sc210iot_supply_names[i]; in sc210iot_get_regulators()
440 return devm_regulator_bulk_get(sc210iot->dev, in sc210iot_get_regulators()
442 sc210iot->supplies); in sc210iot_get_regulators()
445 static int sc210iot_initialize_controls(struct sc210iot *sc210iot) in sc210iot_initialize_controls() argument
453 handler = &sc210iot->ctrl_handler; in sc210iot_initialize_controls()
454 mode = sc210iot->cur_mode; in sc210iot_initialize_controls()
458 handler->lock = &sc210iot->lock; in sc210iot_initialize_controls()
459 sc210iot->link_freq = v4l2_ctrl_new_int_menu(handler, NULL, V4L2_CID_LINK_FREQ, in sc210iot_initialize_controls()
462 sc210iot->pixel_rate = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_PIXEL_RATE, in sc210iot_initialize_controls()
466 sc210iot->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, in sc210iot_initialize_controls()
468 if (sc210iot->hblank) in sc210iot_initialize_controls()
469 sc210iot->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in sc210iot_initialize_controls()
471 sc210iot->vblank = v4l2_ctrl_new_std(handler, &sc210iot_ctrl_ops, in sc210iot_initialize_controls()
476 sc210iot->exposure = v4l2_ctrl_new_std(handler, &sc210iot_ctrl_ops, in sc210iot_initialize_controls()
480 sc210iot->anal_gain = v4l2_ctrl_new_std(handler, &sc210iot_ctrl_ops, in sc210iot_initialize_controls()
484 sc210iot->h_flip = v4l2_ctrl_new_std(handler, &sc210iot_ctrl_ops, in sc210iot_initialize_controls()
486 sc210iot->v_flip = v4l2_ctrl_new_std(handler, &sc210iot_ctrl_ops, in sc210iot_initialize_controls()
490 dev_err(sc210iot->dev, "Failed to init controls(%d)\n", ret); in sc210iot_initialize_controls()
493 sc210iot->subdev.ctrl_handler = handler; in sc210iot_initialize_controls()
494 sc210iot->has_init_exp = false; in sc210iot_initialize_controls()
495 sc210iot->cur_fps = mode->max_fps; in sc210iot_initialize_controls()
496 sc210iot->cur_vts = mode->vts_def; in sc210iot_initialize_controls()
503 static int __sc210iot_power_on(struct sc210iot *sc210iot) in __sc210iot_power_on() argument
506 struct device *dev = sc210iot->dev; in __sc210iot_power_on()
508 if (sc210iot->is_thunderboot) in __sc210iot_power_on()
511 if (!IS_ERR_OR_NULL(sc210iot->pins_default)) { in __sc210iot_power_on()
512 ret = pinctrl_select_state(sc210iot->pinctrl, in __sc210iot_power_on()
513 sc210iot->pins_default); in __sc210iot_power_on()
517 ret = clk_set_rate(sc210iot->xvclk, SC210IOT_XVCLK_FREQ); in __sc210iot_power_on()
520 if (clk_get_rate(sc210iot->xvclk) != SC210IOT_XVCLK_FREQ) in __sc210iot_power_on()
522 ret = clk_prepare_enable(sc210iot->xvclk); in __sc210iot_power_on()
527 ret = regulator_bulk_enable(SC210IOT_NUM_SUPPLIES, sc210iot->supplies); in __sc210iot_power_on()
532 if (!IS_ERR(sc210iot->reset_gpio)) in __sc210iot_power_on()
533 gpiod_direction_output(sc210iot->reset_gpio, 1); in __sc210iot_power_on()
535 if (!IS_ERR(sc210iot->pwdn_gpio)) in __sc210iot_power_on()
536 gpiod_direction_output(sc210iot->pwdn_gpio, 1); in __sc210iot_power_on()
537 if (!IS_ERR(sc210iot->reset_gpio)) in __sc210iot_power_on()
538 gpiod_direction_output(sc210iot->reset_gpio, 0); in __sc210iot_power_on()
542 clk_disable_unprepare(sc210iot->xvclk); in __sc210iot_power_on()
544 if (!IS_ERR_OR_NULL(sc210iot->pins_sleep)) in __sc210iot_power_on()
545 pinctrl_select_state(sc210iot->pinctrl, sc210iot->pins_sleep); in __sc210iot_power_on()
550 static void __sc210iot_power_off(struct sc210iot *sc210iot) in __sc210iot_power_off() argument
553 struct device *dev = sc210iot->dev; in __sc210iot_power_off()
555 if (sc210iot->is_thunderboot) { in __sc210iot_power_off()
556 if (sc210iot->is_first_streamoff) { in __sc210iot_power_off()
557 sc210iot->is_thunderboot = false; in __sc210iot_power_off()
558 sc210iot->is_first_streamoff = false; in __sc210iot_power_off()
563 if (!IS_ERR_OR_NULL(sc210iot->pins_sleep)) { in __sc210iot_power_off()
564 ret = pinctrl_select_state(sc210iot->pinctrl, in __sc210iot_power_off()
565 sc210iot->pins_sleep); in __sc210iot_power_off()
569 if (!IS_ERR(sc210iot->reset_gpio)) in __sc210iot_power_off()
570 gpiod_direction_output(sc210iot->reset_gpio, 1); in __sc210iot_power_off()
571 if (!IS_ERR(sc210iot->pwdn_gpio)) in __sc210iot_power_off()
572 gpiod_direction_output(sc210iot->pwdn_gpio, 0); in __sc210iot_power_off()
573 if (sc210iot->is_thunderboot_ng) { in __sc210iot_power_off()
574 sc210iot->is_thunderboot_ng = false; in __sc210iot_power_off()
575 regulator_bulk_disable(SC210IOT_NUM_SUPPLIES, sc210iot->supplies); in __sc210iot_power_off()
577 clk_disable_unprepare(sc210iot->xvclk); in __sc210iot_power_off()
580 static int sc210iot_check_sensor_id(struct sc210iot *sc210iot) in sc210iot_check_sensor_id() argument
586 if (sc210iot->is_thunderboot) { in sc210iot_check_sensor_id()
587 dev_info(sc210iot->dev, "Enable thunderboot mode, skip sensor id check\n"); in sc210iot_check_sensor_id()
591 ret = sc210iot_read_reg(sc210iot, SC210IOT_REG_CHIP_ID_H, &id_h); in sc210iot_check_sensor_id()
592 ret |= sc210iot_read_reg(sc210iot, SC210IOT_REG_CHIP_ID_L, &id_l); in sc210iot_check_sensor_id()
594 dev_err(sc210iot->dev, "Failed to read sensor id, (%d)\n", ret); in sc210iot_check_sensor_id()
599 dev_err(sc210iot->dev, "sensor id: %04X mismatched\n", id); in sc210iot_check_sensor_id()
602 dev_info(sc210iot->dev, "Detected SC210IOT sensor\n"); in sc210iot_check_sensor_id()
606 static void sc210iot_get_module_inf(struct sc210iot *sc210iot, in sc210iot_get_module_inf() argument
610 strlcpy(inf->base.lens, sc210iot->len_name, sizeof(inf->base.lens)); in sc210iot_get_module_inf()
612 strlcpy(inf->base.module, sc210iot->module_name, sizeof(inf->base.module)); in sc210iot_get_module_inf()
617 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_ioctl() local
626 hdr_cfg->hdr_mode = sc210iot->cur_mode->hdr_mode; in sc210iot_ioctl()
629 sc210iot_get_module_inf(sc210iot, (struct rkmodule_inf *)arg); in sc210iot_ioctl()
638 ret = sc210iot_write_reg(sc210iot, in sc210iot_ioctl()
642 ret = sc210iot_write_reg(sc210iot, in sc210iot_ioctl()
653 static int __sc210iot_start_stream(struct sc210iot *sc210iot) in __sc210iot_start_stream() argument
657 if (!sc210iot->is_thunderboot) { in __sc210iot_start_stream()
658 ret = regmap_multi_reg_write(sc210iot->regmap, in __sc210iot_start_stream()
659 sc210iot->cur_mode->reg_list, in __sc210iot_start_stream()
660 sc210iot->cur_mode->reg_num); in __sc210iot_start_stream()
664 __v4l2_ctrl_handler_setup(&sc210iot->ctrl_handler); in __sc210iot_start_stream()
665 return sc210iot_write_reg(sc210iot, in __sc210iot_start_stream()
670 static int __sc210iot_stop_stream(struct sc210iot *sc210iot) in __sc210iot_stop_stream() argument
672 sc210iot->has_init_exp = false; in __sc210iot_stop_stream()
673 if (sc210iot->is_thunderboot) in __sc210iot_stop_stream()
674 sc210iot->is_first_streamoff = true; in __sc210iot_stop_stream()
675 return sc210iot_write_reg(sc210iot, SC210IOT_REG_CTRL_MODE, in __sc210iot_stop_stream()
735 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_s_stream() local
738 mutex_lock(&sc210iot->lock); in sc210iot_s_stream()
740 if (on == sc210iot->streaming) in sc210iot_s_stream()
743 if (sc210iot->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) { in sc210iot_s_stream()
744 sc210iot->is_thunderboot = false; in sc210iot_s_stream()
745 __sc210iot_power_on(sc210iot); in sc210iot_s_stream()
747 ret = pm_runtime_get_sync(sc210iot->dev); in sc210iot_s_stream()
749 pm_runtime_put_noidle(sc210iot->dev); in sc210iot_s_stream()
752 ret = __sc210iot_start_stream(sc210iot); in sc210iot_s_stream()
754 dev_err(sc210iot->dev, "Failed to start sc210iot stream\n"); in sc210iot_s_stream()
755 pm_runtime_put(sc210iot->dev); in sc210iot_s_stream()
759 __sc210iot_stop_stream(sc210iot); in sc210iot_s_stream()
760 pm_runtime_put(sc210iot->dev); in sc210iot_s_stream()
762 sc210iot->streaming = on; in sc210iot_s_stream()
764 mutex_unlock(&sc210iot->lock); in sc210iot_s_stream()
771 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_g_frame_interval() local
772 const struct sc210iot_mode *mode = sc210iot->cur_mode; in sc210iot_g_frame_interval()
774 if (sc210iot->streaming) in sc210iot_g_frame_interval()
775 fi->interval = sc210iot->cur_fps; in sc210iot_g_frame_interval()
784 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_g_mbus_config() local
789 config->flags = (sc210iot->cur_mode->hdr_mode == NO_HDR) ? in sc210iot_g_mbus_config()
808 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_enum_frame_sizes() local
810 if (fse->index >= sc210iot->cfg_num) in sc210iot_enum_frame_sizes()
825 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_enum_frame_interval() local
827 if (fie->index >= sc210iot->cfg_num) in sc210iot_enum_frame_interval()
841 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_set_fmt() local
845 mutex_lock(&sc210iot->lock); in sc210iot_set_fmt()
858 mutex_unlock(&sc210iot->lock); in sc210iot_set_fmt()
862 sc210iot->cur_mode = mode; in sc210iot_set_fmt()
863 __v4l2_ctrl_s_ctrl(sc210iot->link_freq, mode->link_freq_index); in sc210iot_set_fmt()
864 __v4l2_ctrl_s_ctrl_int64(sc210iot->pixel_rate, in sc210iot_set_fmt()
867 __v4l2_ctrl_modify_range(sc210iot->hblank, h_blank, in sc210iot_set_fmt()
870 __v4l2_ctrl_modify_range(sc210iot->vblank, vblank_def, in sc210iot_set_fmt()
873 sc210iot->cur_fps = mode->max_fps; in sc210iot_set_fmt()
874 sc210iot->cur_vts = mode->vts_def; in sc210iot_set_fmt()
876 mutex_unlock(&sc210iot->lock); in sc210iot_set_fmt()
884 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_get_fmt() local
885 const struct sc210iot_mode *mode = sc210iot->cur_mode; in sc210iot_get_fmt()
887 mutex_lock(&sc210iot->lock); in sc210iot_get_fmt()
892 mutex_unlock(&sc210iot->lock); in sc210iot_get_fmt()
902 mutex_unlock(&sc210iot->lock); in sc210iot_get_fmt()
909 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_open() local
914 mutex_lock(&sc210iot->lock); in sc210iot_open()
920 mutex_unlock(&sc210iot->lock); in sc210iot_open()
932 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_s_power() local
935 mutex_lock(&sc210iot->lock); in sc210iot_s_power()
936 if (sc210iot->power_on == !!on) in sc210iot_s_power()
939 ret = pm_runtime_get_sync(sc210iot->dev); in sc210iot_s_power()
941 pm_runtime_put_noidle(sc210iot->dev); in sc210iot_s_power()
944 if (!sc210iot->is_thunderboot) { in sc210iot_s_power()
945 ret |= sc210iot_write_reg(sc210iot, in sc210iot_s_power()
949 sc210iot->power_on = true; in sc210iot_s_power()
951 pm_runtime_put(sc210iot->dev); in sc210iot_s_power()
952 sc210iot->power_on = false; in sc210iot_s_power()
955 mutex_unlock(&sc210iot->lock); in sc210iot_s_power()
991 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_runtime_resume() local
993 __sc210iot_power_on(sc210iot); in sc210iot_runtime_resume()
1001 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_runtime_suspend() local
1003 __sc210iot_power_off(sc210iot); in sc210iot_runtime_suspend()
1017 struct sc210iot *sc210iot; in sc210iot_probe() local
1026 sc210iot = devm_kzalloc(dev, sizeof(*sc210iot), GFP_KERNEL); in sc210iot_probe()
1027 if (!sc210iot) in sc210iot_probe()
1029 sc210iot->dev = dev; in sc210iot_probe()
1030 sc210iot->regmap = devm_regmap_init_i2c(client, &sc210iot_regmap_config); in sc210iot_probe()
1031 if (IS_ERR(sc210iot->regmap)) { in sc210iot_probe()
1036 &sc210iot->module_index); in sc210iot_probe()
1038 &sc210iot->module_facing); in sc210iot_probe()
1040 &sc210iot->module_name); in sc210iot_probe()
1042 &sc210iot->len_name); in sc210iot_probe()
1048 sc210iot->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP); in sc210iot_probe()
1050 sc210iot->xvclk = devm_clk_get(sc210iot->dev, "xvclk"); in sc210iot_probe()
1051 if (IS_ERR(sc210iot->xvclk)) { in sc210iot_probe()
1052 dev_err(sc210iot->dev, "Failed to get xvclk\n"); in sc210iot_probe()
1055 sc210iot->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS); in sc210iot_probe()
1056 if (IS_ERR(sc210iot->reset_gpio)) in sc210iot_probe()
1058 sc210iot->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS); in sc210iot_probe()
1059 if (IS_ERR(sc210iot->pwdn_gpio)) in sc210iot_probe()
1061 ret = sc210iot_get_regulators(sc210iot); in sc210iot_probe()
1066 sc210iot->pinctrl = devm_pinctrl_get(dev); in sc210iot_probe()
1067 if (!IS_ERR(sc210iot->pinctrl)) { in sc210iot_probe()
1068 sc210iot->pins_default = in sc210iot_probe()
1069 pinctrl_lookup_state(sc210iot->pinctrl, in sc210iot_probe()
1071 if (IS_ERR(sc210iot->pins_default)) in sc210iot_probe()
1074 sc210iot->pins_sleep = in sc210iot_probe()
1075 pinctrl_lookup_state(sc210iot->pinctrl, in sc210iot_probe()
1077 if (IS_ERR(sc210iot->pins_sleep)) in sc210iot_probe()
1082 mutex_init(&sc210iot->lock); in sc210iot_probe()
1084 sc210iot->cur_mode = &supported_modes[0]; in sc210iot_probe()
1085 sc210iot->cfg_num = ARRAY_SIZE(supported_modes); in sc210iot_probe()
1086 sd = &sc210iot->subdev; in sc210iot_probe()
1088 ret = sc210iot_initialize_controls(sc210iot); in sc210iot_probe()
1091 ret = __sc210iot_power_on(sc210iot); in sc210iot_probe()
1094 ret = sc210iot_check_sensor_id(sc210iot); in sc210iot_probe()
1102 sc210iot->pad.flags = MEDIA_PAD_FL_SOURCE; in sc210iot_probe()
1104 ret = media_entity_pads_init(&sd->entity, 1, &sc210iot->pad); in sc210iot_probe()
1109 if (strcmp(sc210iot->module_facing, "back") == 0) in sc210iot_probe()
1114 sc210iot->module_index, facing, in sc210iot_probe()
1131 __sc210iot_power_off(sc210iot); in sc210iot_probe()
1133 v4l2_ctrl_handler_free(&sc210iot->ctrl_handler); in sc210iot_probe()
1135 mutex_destroy(&sc210iot->lock); in sc210iot_probe()
1142 struct sc210iot *sc210iot = to_sc210iot(sd); in sc210iot_remove() local
1148 v4l2_ctrl_handler_free(&sc210iot->ctrl_handler); in sc210iot_remove()
1149 mutex_destroy(&sc210iot->lock); in sc210iot_remove()
1152 __sc210iot_power_off(sc210iot); in sc210iot_remove()