Lines Matching refs:sc501ai

118 struct sc501ai {  struct
152 #define to_sc501ai(sd) container_of(sd, struct sc501ai, subdev) argument
401 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_set_fmt() local
405 mutex_lock(&sc501ai->mutex); in sc501ai_set_fmt()
416 mutex_unlock(&sc501ai->mutex); in sc501ai_set_fmt()
420 sc501ai->cur_mode = mode; in sc501ai_set_fmt()
422 __v4l2_ctrl_modify_range(sc501ai->hblank, h_blank, in sc501ai_set_fmt()
425 __v4l2_ctrl_modify_range(sc501ai->vblank, vblank_def, in sc501ai_set_fmt()
428 sc501ai->cur_fps = mode->max_fps; in sc501ai_set_fmt()
431 mutex_unlock(&sc501ai->mutex); in sc501ai_set_fmt()
440 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_get_fmt() local
441 const struct sc501ai_mode *mode = sc501ai->cur_mode; in sc501ai_get_fmt()
443 mutex_lock(&sc501ai->mutex); in sc501ai_get_fmt()
448 mutex_unlock(&sc501ai->mutex); in sc501ai_get_fmt()
459 mutex_unlock(&sc501ai->mutex); in sc501ai_get_fmt()
468 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_enum_mbus_code() local
472 code->code = sc501ai->cur_mode->bus_fmt; in sc501ai_enum_mbus_code()
498 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_g_frame_interval() local
499 const struct sc501ai_mode *mode = sc501ai->cur_mode; in sc501ai_g_frame_interval()
501 if (sc501ai->streaming) in sc501ai_g_frame_interval()
502 fi->interval = sc501ai->cur_fps; in sc501ai_g_frame_interval()
522 static void sc501ai_get_module_inf(struct sc501ai *sc501ai, in sc501ai_get_module_inf() argument
527 strscpy(inf->base.module, sc501ai->module_name, in sc501ai_get_module_inf()
529 strscpy(inf->base.lens, sc501ai->len_name, sizeof(inf->base.lens)); in sc501ai_get_module_inf()
614 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_ioctl() local
621 sc501ai_get_module_inf(sc501ai, (struct rkmodule_inf *)arg); in sc501ai_ioctl()
626 ret = sc501ai_write_reg(sc501ai->client, SC501AI_REG_CTRL_MODE, in sc501ai_ioctl()
629 ret = sc501ai_write_reg(sc501ai->client, SC501AI_REG_CTRL_MODE, in sc501ai_ioctl()
680 static int __sc501ai_start_stream(struct sc501ai *sc501ai) in __sc501ai_start_stream() argument
684 if (!sc501ai->is_thunderboot) { in __sc501ai_start_stream()
685 ret = sc501ai_write_array(sc501ai->client, sc501ai->cur_mode->reg_list); in __sc501ai_start_stream()
690 ret = __v4l2_ctrl_handler_setup(&sc501ai->ctrl_handler); in __sc501ai_start_stream()
695 return sc501ai_write_reg(sc501ai->client, SC501AI_REG_CTRL_MODE, in __sc501ai_start_stream()
699 static int __sc501ai_stop_stream(struct sc501ai *sc501ai) in __sc501ai_stop_stream() argument
701 sc501ai->has_init_exp = false; in __sc501ai_stop_stream()
702 if (sc501ai->is_thunderboot) { in __sc501ai_stop_stream()
703 sc501ai->is_first_streamoff = true; in __sc501ai_stop_stream()
704 pm_runtime_put(&sc501ai->client->dev); in __sc501ai_stop_stream()
706 return sc501ai_write_reg(sc501ai->client, SC501AI_REG_CTRL_MODE, in __sc501ai_stop_stream()
710 static int __sc501ai_power_on(struct sc501ai *sc501ai);
713 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_s_stream() local
714 struct i2c_client *client = sc501ai->client; in sc501ai_s_stream()
717 mutex_lock(&sc501ai->mutex); in sc501ai_s_stream()
719 if (on == sc501ai->streaming) in sc501ai_s_stream()
723 if (sc501ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) { in sc501ai_s_stream()
724 sc501ai->is_thunderboot = false; in sc501ai_s_stream()
725 __sc501ai_power_on(sc501ai); in sc501ai_s_stream()
733 ret = __sc501ai_start_stream(sc501ai); in sc501ai_s_stream()
740 __sc501ai_stop_stream(sc501ai); in sc501ai_s_stream()
744 sc501ai->streaming = on; in sc501ai_s_stream()
747 mutex_unlock(&sc501ai->mutex); in sc501ai_s_stream()
754 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_s_power() local
755 struct i2c_client *client = sc501ai->client; in sc501ai_s_power()
758 mutex_lock(&sc501ai->mutex); in sc501ai_s_power()
761 if (sc501ai->power_on == !!on) in sc501ai_s_power()
771 sc501ai->power_on = true; in sc501ai_s_power()
774 sc501ai->power_on = false; in sc501ai_s_power()
778 mutex_unlock(&sc501ai->mutex); in sc501ai_s_power()
783 static int __sc501ai_power_on(struct sc501ai *sc501ai) in __sc501ai_power_on() argument
786 struct device *dev = &sc501ai->client->dev; in __sc501ai_power_on()
788 if (!IS_ERR_OR_NULL(sc501ai->pins_default)) { in __sc501ai_power_on()
789 ret = pinctrl_select_state(sc501ai->pinctrl, in __sc501ai_power_on()
790 sc501ai->pins_default); in __sc501ai_power_on()
794 ret = clk_set_rate(sc501ai->xvclk, SC501AI_XVCLK_FREQ); in __sc501ai_power_on()
797 if (clk_get_rate(sc501ai->xvclk) != SC501AI_XVCLK_FREQ) in __sc501ai_power_on()
799 ret = clk_prepare_enable(sc501ai->xvclk); in __sc501ai_power_on()
805 if (sc501ai->is_thunderboot) in __sc501ai_power_on()
808 if (!IS_ERR(sc501ai->reset_gpio)) in __sc501ai_power_on()
809 gpiod_set_value_cansleep(sc501ai->reset_gpio, 0); in __sc501ai_power_on()
811 ret = regulator_bulk_enable(sc501ai_NUM_SUPPLIES, sc501ai->supplies); in __sc501ai_power_on()
817 if (!IS_ERR(sc501ai->reset_gpio)) in __sc501ai_power_on()
818 gpiod_set_value_cansleep(sc501ai->reset_gpio, 1); in __sc501ai_power_on()
821 if (!IS_ERR(sc501ai->pwdn_gpio)) in __sc501ai_power_on()
822 gpiod_set_value_cansleep(sc501ai->pwdn_gpio, 1); in __sc501ai_power_on()
828 clk_disable_unprepare(sc501ai->xvclk); in __sc501ai_power_on()
833 static void __sc501ai_power_off(struct sc501ai *sc501ai) in __sc501ai_power_off() argument
836 struct device *dev = &sc501ai->client->dev; in __sc501ai_power_off()
838 clk_disable_unprepare(sc501ai->xvclk); in __sc501ai_power_off()
839 if (sc501ai->is_thunderboot) { in __sc501ai_power_off()
840 if (sc501ai->is_first_streamoff) { in __sc501ai_power_off()
841 sc501ai->is_thunderboot = false; in __sc501ai_power_off()
842 sc501ai->is_first_streamoff = false; in __sc501ai_power_off()
848 if (!IS_ERR(sc501ai->pwdn_gpio)) in __sc501ai_power_off()
849 gpiod_set_value_cansleep(sc501ai->pwdn_gpio, 0); in __sc501ai_power_off()
850 clk_disable_unprepare(sc501ai->xvclk); in __sc501ai_power_off()
851 if (!IS_ERR(sc501ai->reset_gpio)) in __sc501ai_power_off()
852 gpiod_set_value_cansleep(sc501ai->reset_gpio, 0); in __sc501ai_power_off()
853 if (!IS_ERR_OR_NULL(sc501ai->pins_sleep)) { in __sc501ai_power_off()
854 ret = pinctrl_select_state(sc501ai->pinctrl, in __sc501ai_power_off()
855 sc501ai->pins_sleep); in __sc501ai_power_off()
859 regulator_bulk_disable(sc501ai_NUM_SUPPLIES, sc501ai->supplies); in __sc501ai_power_off()
866 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_runtime_resume() local
868 return __sc501ai_power_on(sc501ai); in sc501ai_runtime_resume()
875 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_runtime_suspend() local
877 __sc501ai_power_off(sc501ai); in sc501ai_runtime_suspend()
885 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_open() local
890 mutex_lock(&sc501ai->mutex); in sc501ai_open()
897 mutex_unlock(&sc501ai->mutex); in sc501ai_open()
958 static void sc501ai_modify_fps_info(struct sc501ai *sc501ai) in sc501ai_modify_fps_info() argument
960 const struct sc501ai_mode *mode = sc501ai->cur_mode; in sc501ai_modify_fps_info()
962 sc501ai->cur_fps.denominator = mode->max_fps.denominator * sc501ai->cur_vts / in sc501ai_modify_fps_info()
967 struct sc501ai *sc501ai = container_of(ctrl->handler, in sc501ai_set_ctrl() local
968 struct sc501ai, ctrl_handler); in sc501ai_set_ctrl()
969 struct i2c_client *client = sc501ai->client; in sc501ai_set_ctrl()
984 max = sc501ai->cur_mode->height + ctrl->val - 10; in sc501ai_set_ctrl()
985 __v4l2_ctrl_modify_range(sc501ai->exposure, in sc501ai_set_ctrl()
986 sc501ai->exposure->minimum, max, in sc501ai_set_ctrl()
987 sc501ai->exposure->step, in sc501ai_set_ctrl()
988 sc501ai->exposure->default_value); in sc501ai_set_ctrl()
998 ret = sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1002 ret |= sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1006 ret |= sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1015 ret = sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1019 ret |= sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1023 ret |= sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1027 ret |= sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1032 dev_dbg(&sc501ai->client->dev, in sc501ai_set_ctrl()
1037 vts = ctrl->val + sc501ai->cur_mode->height; in sc501ai_set_ctrl()
1038 ret = sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1042 ret |= sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1046 sc501ai->cur_vts = vts; in sc501ai_set_ctrl()
1047 sc501ai_modify_fps_info(sc501ai); in sc501ai_set_ctrl()
1050 ret = sc501ai_read_reg(sc501ai->client, SC501AI_FLIP_MIRROR_REG, in sc501ai_set_ctrl()
1058 ret |= sc501ai_write_reg(sc501ai->client, SC501AI_FLIP_MIRROR_REG, in sc501ai_set_ctrl()
1062 ret = sc501ai_read_reg(sc501ai->client, in sc501ai_set_ctrl()
1067 denominator = sc501ai->cur_mode->max_fps.denominator; in sc501ai_set_ctrl()
1068 numerator = sc501ai->cur_mode->max_fps.numerator; in sc501ai_set_ctrl()
1070 cur_fps = def_fps * sc501ai->cur_mode->vts_def / sc501ai->cur_vts; in sc501ai_set_ctrl()
1072 vts = def_fps * sc501ai->cur_mode->vts_def / 25; in sc501ai_set_ctrl()
1073 ret = sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1077 ret |= sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1091 ret |= sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1097 vts = sc501ai->cur_vts; in sc501ai_set_ctrl()
1098 ret = sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1102 ret |= sc501ai_write_reg(sc501ai->client, in sc501ai_set_ctrl()
1123 static int sc501ai_initialize_controls(struct sc501ai *sc501ai) in sc501ai_initialize_controls() argument
1132 handler = &sc501ai->ctrl_handler; in sc501ai_initialize_controls()
1133 mode = sc501ai->cur_mode; in sc501ai_initialize_controls()
1137 handler->lock = &sc501ai->mutex; in sc501ai_initialize_controls()
1146 sc501ai->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK, in sc501ai_initialize_controls()
1148 if (sc501ai->hblank) in sc501ai_initialize_controls()
1149 sc501ai->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in sc501ai_initialize_controls()
1151 sc501ai->cur_vts = mode->vts_def; in sc501ai_initialize_controls()
1153 sc501ai->vblank = v4l2_ctrl_new_std(handler, &sc501ai_ctrl_ops, in sc501ai_initialize_controls()
1158 sc501ai->exposure = v4l2_ctrl_new_std(handler, &sc501ai_ctrl_ops, in sc501ai_initialize_controls()
1162 sc501ai->anal_gain = v4l2_ctrl_new_std(handler, &sc501ai_ctrl_ops, in sc501ai_initialize_controls()
1174 dev_err(&sc501ai->client->dev, in sc501ai_initialize_controls()
1178 sc501ai->subdev.ctrl_handler = handler; in sc501ai_initialize_controls()
1179 sc501ai->has_init_exp = false; in sc501ai_initialize_controls()
1180 sc501ai->cur_fps = mode->max_fps; in sc501ai_initialize_controls()
1189 static int sc501ai_check_sensor_id(struct sc501ai *sc501ai, in sc501ai_check_sensor_id() argument
1192 struct device *dev = &sc501ai->client->dev; in sc501ai_check_sensor_id()
1196 if (sc501ai->is_thunderboot) { in sc501ai_check_sensor_id()
1213 static int sc501ai_configure_regulators(struct sc501ai *sc501ai) in sc501ai_configure_regulators() argument
1218 sc501ai->supplies[i].supply = sc501ai_supply_names[i]; in sc501ai_configure_regulators()
1220 return devm_regulator_bulk_get(&sc501ai->client->dev, in sc501ai_configure_regulators()
1222 sc501ai->supplies); in sc501ai_configure_regulators()
1230 struct sc501ai *sc501ai; in sc501ai_probe() local
1240 sc501ai = devm_kzalloc(dev, sizeof(*sc501ai), GFP_KERNEL); in sc501ai_probe()
1241 if (!sc501ai) in sc501ai_probe()
1245 &sc501ai->module_index); in sc501ai_probe()
1247 &sc501ai->module_facing); in sc501ai_probe()
1249 &sc501ai->module_name); in sc501ai_probe()
1251 &sc501ai->len_name); in sc501ai_probe()
1257 sc501ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP); in sc501ai_probe()
1259 sc501ai->client = client; in sc501ai_probe()
1260 sc501ai->cur_mode = &supported_modes[0]; in sc501ai_probe()
1262 sc501ai->xvclk = devm_clk_get(dev, "xvclk"); in sc501ai_probe()
1263 if (IS_ERR(sc501ai->xvclk)) { in sc501ai_probe()
1268 if (sc501ai->is_thunderboot) { in sc501ai_probe()
1269 sc501ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS); in sc501ai_probe()
1270 if (IS_ERR(sc501ai->reset_gpio)) in sc501ai_probe()
1273 sc501ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS); in sc501ai_probe()
1274 if (IS_ERR(sc501ai->pwdn_gpio)) in sc501ai_probe()
1277 sc501ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); in sc501ai_probe()
1278 if (IS_ERR(sc501ai->reset_gpio)) in sc501ai_probe()
1281 sc501ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW); in sc501ai_probe()
1282 if (IS_ERR(sc501ai->pwdn_gpio)) in sc501ai_probe()
1286 sc501ai->pinctrl = devm_pinctrl_get(dev); in sc501ai_probe()
1287 if (!IS_ERR(sc501ai->pinctrl)) { in sc501ai_probe()
1288 sc501ai->pins_default = in sc501ai_probe()
1289 pinctrl_lookup_state(sc501ai->pinctrl, in sc501ai_probe()
1291 if (IS_ERR(sc501ai->pins_default)) in sc501ai_probe()
1294 sc501ai->pins_sleep = in sc501ai_probe()
1295 pinctrl_lookup_state(sc501ai->pinctrl, in sc501ai_probe()
1297 if (IS_ERR(sc501ai->pins_sleep)) in sc501ai_probe()
1303 ret = sc501ai_configure_regulators(sc501ai); in sc501ai_probe()
1309 mutex_init(&sc501ai->mutex); in sc501ai_probe()
1311 sd = &sc501ai->subdev; in sc501ai_probe()
1313 ret = sc501ai_initialize_controls(sc501ai); in sc501ai_probe()
1317 ret = __sc501ai_power_on(sc501ai); in sc501ai_probe()
1321 ret = sc501ai_check_sensor_id(sc501ai, client); in sc501ai_probe()
1331 sc501ai->pad.flags = MEDIA_PAD_FL_SOURCE; in sc501ai_probe()
1333 ret = media_entity_pads_init(&sd->entity, 1, &sc501ai->pad); in sc501ai_probe()
1339 if (strcmp(sc501ai->module_facing, "back") == 0) in sc501ai_probe()
1345 sc501ai->module_index, facing, in sc501ai_probe()
1355 if (sc501ai->is_thunderboot) in sc501ai_probe()
1367 __sc501ai_power_off(sc501ai); in sc501ai_probe()
1369 v4l2_ctrl_handler_free(&sc501ai->ctrl_handler); in sc501ai_probe()
1371 mutex_destroy(&sc501ai->mutex); in sc501ai_probe()
1379 struct sc501ai *sc501ai = to_sc501ai(sd); in sc501ai_remove() local
1385 v4l2_ctrl_handler_free(&sc501ai->ctrl_handler); in sc501ai_remove()
1386 mutex_destroy(&sc501ai->mutex); in sc501ai_remove()
1390 __sc501ai_power_off(sc501ai); in sc501ai_remove()