Lines Matching full:imx290
3 * Sony IMX290 CMOS Image Sensor Driver
115 * The IMX290 pixel array is organized as follows:
228 struct imx290 { struct
255 static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd) in to_imx290() argument
257 return container_of(_sd, struct imx290, sd); in to_imx290()
442 static inline const s64 *imx290_link_freqs_ptr(const struct imx290 *imx290) in imx290_link_freqs_ptr() argument
444 if (imx290->nlanes == 2) in imx290_link_freqs_ptr()
450 static inline int imx290_link_freqs_num(const struct imx290 *imx290) in imx290_link_freqs_num() argument
452 if (imx290->nlanes == 2) in imx290_link_freqs_num()
551 static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290) in imx290_modes_ptr() argument
553 if (imx290->nlanes == 2) in imx290_modes_ptr()
559 static inline int imx290_modes_num(const struct imx290 *imx290) in imx290_modes_num() argument
561 if (imx290->nlanes == 2) in imx290_modes_num()
595 imx290_format_info(const struct imx290 *imx290, u32 code) in imx290_format_info() argument
602 if (info->code[imx290->model->colour_variant] == code) in imx290_format_info()
609 static int imx290_set_register_array(struct imx290 *imx290, in imx290_set_register_array() argument
615 ret = cci_multi_reg_write(imx290->regmap, settings, num_settings, NULL); in imx290_set_register_array()
625 static int imx290_set_clock(struct imx290 *imx290) in imx290_set_clock() argument
627 const struct imx290_mode *mode = imx290->current_mode; in imx290_set_clock()
628 enum imx290_clk_freq clk_idx = imx290->xclk_idx; in imx290_set_clock()
632 ret = imx290_set_register_array(imx290, xclk_regs[clk_idx], in imx290_set_clock()
635 cci_write(imx290->regmap, IMX290_INCKSEL1, clk_cfg->incksel1, &ret); in imx290_set_clock()
636 cci_write(imx290->regmap, IMX290_INCKSEL2, clk_cfg->incksel2, &ret); in imx290_set_clock()
637 cci_write(imx290->regmap, IMX290_INCKSEL3, clk_cfg->incksel3, &ret); in imx290_set_clock()
638 cci_write(imx290->regmap, IMX290_INCKSEL4, clk_cfg->incksel4, &ret); in imx290_set_clock()
639 cci_write(imx290->regmap, IMX290_INCKSEL5, clk_cfg->incksel5, &ret); in imx290_set_clock()
640 cci_write(imx290->regmap, IMX290_INCKSEL6, clk_cfg->incksel6, &ret); in imx290_set_clock()
645 static int imx290_set_data_lanes(struct imx290 *imx290) in imx290_set_data_lanes() argument
649 cci_write(imx290->regmap, IMX290_PHY_LANE_NUM, imx290->nlanes - 1, in imx290_set_data_lanes()
651 cci_write(imx290->regmap, IMX290_CSI_LANE_MODE, imx290->nlanes - 1, in imx290_set_data_lanes()
653 cci_write(imx290->regmap, IMX290_FR_FDG_SEL, 0x01, &ret); in imx290_set_data_lanes()
658 static int imx290_set_black_level(struct imx290 *imx290, in imx290_set_black_level() argument
662 unsigned int bpp = imx290_format_info(imx290, format->code)->bpp; in imx290_set_black_level()
664 return cci_write(imx290->regmap, IMX290_BLKLEVEL, in imx290_set_black_level()
668 static int imx290_set_csi_config(struct imx290 *imx290) in imx290_set_csi_config() argument
670 const s64 *link_freqs = imx290_link_freqs_ptr(imx290); in imx290_set_csi_config()
674 switch (link_freqs[imx290->current_mode->link_freq_index]) { in imx290_set_csi_config()
691 cci_write(imx290->regmap, IMX290_REPETITION, csi_cfg->repetition, &ret); in imx290_set_csi_config()
692 cci_write(imx290->regmap, IMX290_TCLKPOST, csi_cfg->tclkpost, &ret); in imx290_set_csi_config()
693 cci_write(imx290->regmap, IMX290_THSZERO, csi_cfg->thszero, &ret); in imx290_set_csi_config()
694 cci_write(imx290->regmap, IMX290_THSPREPARE, csi_cfg->thsprepare, &ret); in imx290_set_csi_config()
695 cci_write(imx290->regmap, IMX290_TCLKTRAIL, csi_cfg->tclktrail, &ret); in imx290_set_csi_config()
696 cci_write(imx290->regmap, IMX290_THSTRAIL, csi_cfg->thstrail, &ret); in imx290_set_csi_config()
697 cci_write(imx290->regmap, IMX290_TCLKZERO, csi_cfg->tclkzero, &ret); in imx290_set_csi_config()
698 cci_write(imx290->regmap, IMX290_TCLKPREPARE, csi_cfg->tclkprepare, in imx290_set_csi_config()
700 cci_write(imx290->regmap, IMX290_TLPX, csi_cfg->tlpx, &ret); in imx290_set_csi_config()
705 static int imx290_setup_format(struct imx290 *imx290, in imx290_setup_format() argument
711 info = imx290_format_info(imx290, format->code); in imx290_setup_format()
713 ret = imx290_set_register_array(imx290, info->regs, info->num_regs); in imx290_setup_format()
715 dev_err(imx290->dev, "Could not set format registers\n"); in imx290_setup_format()
719 return imx290_set_black_level(imx290, format, in imx290_setup_format()
726 static void imx290_exposure_update(struct imx290 *imx290, in imx290_exposure_update() argument
731 exposure_max = imx290->vblank->val + mode->height - in imx290_exposure_update()
733 __v4l2_ctrl_modify_range(imx290->exposure, 1, exposure_max, 1, in imx290_exposure_update()
739 struct imx290 *imx290 = container_of(ctrl->handler, in imx290_set_ctrl() local
740 struct imx290, ctrls); in imx290_set_ctrl()
754 imx290_exposure_update(imx290, imx290->current_mode); in imx290_set_ctrl()
758 if (!pm_runtime_get_if_in_use(imx290->dev)) in imx290_set_ctrl()
761 state = v4l2_subdev_get_locked_active_state(&imx290->sd); in imx290_set_ctrl()
762 format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0); in imx290_set_ctrl()
766 ret = cci_write(imx290->regmap, IMX290_GAIN, ctrl->val, NULL); in imx290_set_ctrl()
770 ret = cci_write(imx290->regmap, IMX290_VMAX, in imx290_set_ctrl()
771 ctrl->val + imx290->current_mode->height, NULL); in imx290_set_ctrl()
779 ctrl = imx290->exposure; in imx290_set_ctrl()
782 vmax = imx290->vblank->val + imx290->current_mode->height; in imx290_set_ctrl()
783 ret = cci_write(imx290->regmap, IMX290_SHS1, in imx290_set_ctrl()
789 imx290_set_black_level(imx290, format, 0, &ret); in imx290_set_ctrl()
791 cci_write(imx290->regmap, IMX290_PGCTRL, in imx290_set_ctrl()
796 cci_write(imx290->regmap, IMX290_PGCTRL, 0x00, &ret); in imx290_set_ctrl()
798 imx290_set_black_level(imx290, format, in imx290_set_ctrl()
804 ret = cci_write(imx290->regmap, IMX290_HMAX, in imx290_set_ctrl()
805 ctrl->val + imx290->current_mode->width, NULL); in imx290_set_ctrl()
813 reg = imx290->current_mode->ctrl_07; in imx290_set_ctrl()
814 if (imx290->hflip->val) in imx290_set_ctrl()
816 if (imx290->vflip->val) in imx290_set_ctrl()
818 ret = cci_write(imx290->regmap, IMX290_CTRL_07, reg, NULL); in imx290_set_ctrl()
827 pm_runtime_mark_last_busy(imx290->dev); in imx290_set_ctrl()
828 pm_runtime_put_autosuspend(imx290->dev); in imx290_set_ctrl()
848 static void imx290_ctrl_update(struct imx290 *imx290, in imx290_ctrl_update() argument
856 __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index); in imx290_ctrl_update()
858 __v4l2_ctrl_modify_range(imx290->hblank, hblank_min, hblank_max, 1, in imx290_ctrl_update()
860 __v4l2_ctrl_modify_range(imx290->vblank, vblank_min, vblank_max, 1, in imx290_ctrl_update()
864 static int imx290_ctrl_init(struct imx290 *imx290) in imx290_ctrl_init() argument
869 ret = v4l2_fwnode_device_parse(imx290->dev, &props); in imx290_ctrl_init()
873 v4l2_ctrl_handler_init(&imx290->ctrls, 11); in imx290_ctrl_init()
883 * The IMX327 and IMX462 are largely compatible with the IMX290, but in imx290_ctrl_init()
888 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, in imx290_ctrl_init()
895 imx290->exposure = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, in imx290_ctrl_init()
904 imx290->link_freq = in imx290_ctrl_init()
905 v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, in imx290_ctrl_init()
907 imx290_link_freqs_num(imx290) - 1, 0, in imx290_ctrl_init()
908 imx290_link_freqs_ptr(imx290)); in imx290_ctrl_init()
909 if (imx290->link_freq) in imx290_ctrl_init()
910 imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx290_ctrl_init()
912 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, V4L2_CID_PIXEL_RATE, in imx290_ctrl_init()
916 v4l2_ctrl_new_std_menu_items(&imx290->ctrls, &imx290_ctrl_ops, in imx290_ctrl_init()
924 imx290->hblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, in imx290_ctrl_init()
927 imx290->vblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, in imx290_ctrl_init()
930 imx290->hflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, in imx290_ctrl_init()
932 imx290->vflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, in imx290_ctrl_init()
934 v4l2_ctrl_cluster(2, &imx290->hflip); in imx290_ctrl_init()
936 v4l2_ctrl_new_fwnode_properties(&imx290->ctrls, &imx290_ctrl_ops, in imx290_ctrl_init()
939 imx290->sd.ctrl_handler = &imx290->ctrls; in imx290_ctrl_init()
941 if (imx290->ctrls.error) { in imx290_ctrl_init()
942 ret = imx290->ctrls.error; in imx290_ctrl_init()
943 v4l2_ctrl_handler_free(&imx290->ctrls); in imx290_ctrl_init()
955 static int imx290_start_streaming(struct imx290 *imx290, in imx290_start_streaming() argument
962 ret = imx290_set_register_array(imx290, imx290_global_init_settings, in imx290_start_streaming()
965 dev_err(imx290->dev, "Could not set init registers\n"); in imx290_start_streaming()
970 ret = imx290_set_register_array(imx290, imx290->model->init_regs, in imx290_start_streaming()
971 imx290->model->init_regs_num); in imx290_start_streaming()
973 dev_err(imx290->dev, "Could not set model specific init registers\n"); in imx290_start_streaming()
978 ret = imx290_set_clock(imx290); in imx290_start_streaming()
980 dev_err(imx290->dev, "Could not set clocks - %d\n", ret); in imx290_start_streaming()
985 ret = imx290_set_data_lanes(imx290); in imx290_start_streaming()
987 dev_err(imx290->dev, "Could not set data lanes - %d\n", ret); in imx290_start_streaming()
991 ret = imx290_set_csi_config(imx290); in imx290_start_streaming()
993 dev_err(imx290->dev, "Could not set csi cfg - %d\n", ret); in imx290_start_streaming()
998 format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0); in imx290_start_streaming()
999 ret = imx290_setup_format(imx290, format); in imx290_start_streaming()
1001 dev_err(imx290->dev, "Could not set frame format - %d\n", ret); in imx290_start_streaming()
1006 ret = imx290_set_register_array(imx290, imx290->current_mode->data, in imx290_start_streaming()
1007 imx290->current_mode->data_size); in imx290_start_streaming()
1009 dev_err(imx290->dev, "Could not set current mode - %d\n", ret); in imx290_start_streaming()
1014 ret = __v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler); in imx290_start_streaming()
1016 dev_err(imx290->dev, "Could not sync v4l2 controls - %d\n", ret); in imx290_start_streaming()
1020 cci_write(imx290->regmap, IMX290_STANDBY, 0x00, &ret); in imx290_start_streaming()
1025 return cci_write(imx290->regmap, IMX290_XMSTA, 0x00, &ret); in imx290_start_streaming()
1029 static int imx290_stop_streaming(struct imx290 *imx290) in imx290_stop_streaming() argument
1033 cci_write(imx290->regmap, IMX290_STANDBY, 0x01, &ret); in imx290_stop_streaming()
1037 return cci_write(imx290->regmap, IMX290_XMSTA, 0x01, &ret); in imx290_stop_streaming()
1042 struct imx290 *imx290 = to_imx290(sd); in imx290_set_stream() local
1049 ret = pm_runtime_resume_and_get(imx290->dev); in imx290_set_stream()
1053 ret = imx290_start_streaming(imx290, state); in imx290_set_stream()
1055 dev_err(imx290->dev, "Start stream failed\n"); in imx290_set_stream()
1056 pm_runtime_put_sync(imx290->dev); in imx290_set_stream()
1060 imx290_stop_streaming(imx290); in imx290_set_stream()
1061 pm_runtime_mark_last_busy(imx290->dev); in imx290_set_stream()
1062 pm_runtime_put_autosuspend(imx290->dev); in imx290_set_stream()
1069 __v4l2_ctrl_grab(imx290->vflip, enable); in imx290_set_stream()
1070 __v4l2_ctrl_grab(imx290->hflip, enable); in imx290_set_stream()
1081 const struct imx290 *imx290 = to_imx290(sd); in imx290_enum_mbus_code() local
1086 code->code = imx290_formats[code->index].code[imx290->model->colour_variant]; in imx290_enum_mbus_code()
1095 const struct imx290 *imx290 = to_imx290(sd); in imx290_enum_frame_size() local
1096 const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290); in imx290_enum_frame_size()
1098 if (!imx290_format_info(imx290, fse->code)) in imx290_enum_frame_size()
1101 if (fse->index >= imx290_modes_num(imx290)) in imx290_enum_frame_size()
1116 struct imx290 *imx290 = to_imx290(sd); in imx290_set_fmt() local
1120 mode = v4l2_find_nearest_size(imx290_modes_ptr(imx290), in imx290_set_fmt()
1121 imx290_modes_num(imx290), width, height, in imx290_set_fmt()
1127 if (!imx290_format_info(imx290, fmt->format.code)) in imx290_set_fmt()
1128 fmt->format.code = imx290_formats[0].code[imx290->model->colour_variant]; in imx290_set_fmt()
1139 imx290->current_mode = mode; in imx290_set_fmt()
1141 imx290_ctrl_update(imx290, mode); in imx290_set_fmt()
1142 imx290_exposure_update(imx290, mode); in imx290_set_fmt()
1154 struct imx290 *imx290 = to_imx290(sd); in imx290_get_selection() local
1167 + imx290->vflip->val; in imx290_get_selection()
1170 + imx290->hflip->val; in imx290_get_selection()
1243 static int imx290_subdev_init(struct imx290 *imx290) in imx290_subdev_init() argument
1245 struct i2c_client *client = to_i2c_client(imx290->dev); in imx290_subdev_init()
1249 imx290->current_mode = &imx290_modes_ptr(imx290)[0]; in imx290_subdev_init()
1251 v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops); in imx290_subdev_init()
1252 imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in imx290_subdev_init()
1254 imx290->sd.dev = imx290->dev; in imx290_subdev_init()
1255 imx290->sd.entity.ops = &imx290_subdev_entity_ops; in imx290_subdev_init()
1256 imx290->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in imx290_subdev_init()
1258 imx290->pad.flags = MEDIA_PAD_FL_SOURCE; in imx290_subdev_init()
1259 ret = media_entity_pads_init(&imx290->sd.entity, 1, &imx290->pad); in imx290_subdev_init()
1261 dev_err(imx290->dev, "Could not register media entity\n"); in imx290_subdev_init()
1265 ret = imx290_ctrl_init(imx290); in imx290_subdev_init()
1267 dev_err(imx290->dev, "Control initialization error %d\n", ret); in imx290_subdev_init()
1271 imx290->sd.state_lock = imx290->ctrls.lock; in imx290_subdev_init()
1273 ret = v4l2_subdev_init_finalize(&imx290->sd); in imx290_subdev_init()
1275 dev_err(imx290->dev, "subdev initialization error %d\n", ret); in imx290_subdev_init()
1279 state = v4l2_subdev_lock_and_get_active_state(&imx290->sd); in imx290_subdev_init()
1280 imx290_ctrl_update(imx290, imx290->current_mode); in imx290_subdev_init()
1286 v4l2_ctrl_handler_free(&imx290->ctrls); in imx290_subdev_init()
1288 media_entity_cleanup(&imx290->sd.entity); in imx290_subdev_init()
1292 static void imx290_subdev_cleanup(struct imx290 *imx290) in imx290_subdev_cleanup() argument
1294 v4l2_subdev_cleanup(&imx290->sd); in imx290_subdev_cleanup()
1295 media_entity_cleanup(&imx290->sd.entity); in imx290_subdev_cleanup()
1296 v4l2_ctrl_handler_free(&imx290->ctrls); in imx290_subdev_cleanup()
1303 static int imx290_power_on(struct imx290 *imx290) in imx290_power_on() argument
1307 ret = clk_prepare_enable(imx290->xclk); in imx290_power_on()
1309 dev_err(imx290->dev, "Failed to enable clock\n"); in imx290_power_on()
1313 ret = regulator_bulk_enable(ARRAY_SIZE(imx290->supplies), in imx290_power_on()
1314 imx290->supplies); in imx290_power_on()
1316 dev_err(imx290->dev, "Failed to enable regulators\n"); in imx290_power_on()
1317 clk_disable_unprepare(imx290->xclk); in imx290_power_on()
1322 gpiod_set_value_cansleep(imx290->rst_gpio, 0); in imx290_power_on()
1328 static void imx290_power_off(struct imx290 *imx290) in imx290_power_off() argument
1330 clk_disable_unprepare(imx290->xclk); in imx290_power_off()
1331 gpiod_set_value_cansleep(imx290->rst_gpio, 1); in imx290_power_off()
1332 regulator_bulk_disable(ARRAY_SIZE(imx290->supplies), imx290->supplies); in imx290_power_off()
1338 struct imx290 *imx290 = to_imx290(sd); in imx290_runtime_resume() local
1340 return imx290_power_on(imx290); in imx290_runtime_resume()
1346 struct imx290 *imx290 = to_imx290(sd); in imx290_runtime_suspend() local
1348 imx290_power_off(imx290); in imx290_runtime_suspend()
1367 static int imx290_get_regulators(struct device *dev, struct imx290 *imx290) in imx290_get_regulators() argument
1371 for (i = 0; i < ARRAY_SIZE(imx290->supplies); i++) in imx290_get_regulators()
1372 imx290->supplies[i].supply = imx290_supply_name[i]; in imx290_get_regulators()
1374 return devm_regulator_bulk_get(dev, ARRAY_SIZE(imx290->supplies), in imx290_get_regulators()
1375 imx290->supplies); in imx290_get_regulators()
1378 static int imx290_init_clk(struct imx290 *imx290) in imx290_init_clk() argument
1383 ret = device_property_read_u32(imx290->dev, "clock-frequency", in imx290_init_clk()
1386 dev_err(imx290->dev, "Could not get xclk frequency\n"); in imx290_init_clk()
1393 imx290->xclk_idx = IMX290_CLK_37_125; in imx290_init_clk()
1396 imx290->xclk_idx = IMX290_CLK_74_25; in imx290_init_clk()
1399 dev_err(imx290->dev, "External clock frequency %u is not supported\n", in imx290_init_clk()
1404 ret = clk_set_rate(imx290->xclk, xclk_freq); in imx290_init_clk()
1406 dev_err(imx290->dev, "Could not set xclk frequency\n"); in imx290_init_clk()
1418 static s64 imx290_check_link_freqs(const struct imx290 *imx290, in imx290_check_link_freqs() argument
1422 const s64 *freqs = imx290_link_freqs_ptr(imx290); in imx290_check_link_freqs()
1423 int freqs_count = imx290_link_freqs_num(imx290); in imx290_check_link_freqs()
1440 .name = "imx290",
1446 .name = "imx290",
1456 static int imx290_parse_dt(struct imx290 *imx290) in imx290_parse_dt() argument
1466 imx290->model = of_device_get_match_data(imx290->dev); in imx290_parse_dt()
1468 endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(imx290->dev), NULL); in imx290_parse_dt()
1470 dev_err(imx290->dev, "Endpoint node not found\n"); in imx290_parse_dt()
1477 dev_err(imx290->dev, "Unsupported bus type, should be CSI2\n"); in imx290_parse_dt()
1480 dev_err(imx290->dev, "Parsing endpoint node failed\n"); in imx290_parse_dt()
1485 imx290->nlanes = ep.bus.mipi_csi2.num_data_lanes; in imx290_parse_dt()
1486 if (imx290->nlanes != 2 && imx290->nlanes != 4) { in imx290_parse_dt()
1487 dev_err(imx290->dev, "Invalid data lanes: %d\n", imx290->nlanes); in imx290_parse_dt()
1492 dev_dbg(imx290->dev, "Using %u data lanes\n", imx290->nlanes); in imx290_parse_dt()
1495 dev_err(imx290->dev, "link-frequency property not found in DT\n"); in imx290_parse_dt()
1501 fq = imx290_check_link_freqs(imx290, &ep); in imx290_parse_dt()
1503 dev_err(imx290->dev, "Link frequency of %lld is not supported\n", in imx290_parse_dt()
1519 struct imx290 *imx290; in imx290_probe() local
1522 imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL); in imx290_probe()
1523 if (!imx290) in imx290_probe()
1526 imx290->dev = dev; in imx290_probe()
1527 imx290->regmap = devm_cci_regmap_init_i2c(client, 16); in imx290_probe()
1528 if (IS_ERR(imx290->regmap)) { in imx290_probe()
1533 ret = imx290_parse_dt(imx290); in imx290_probe()
1538 imx290->xclk = devm_clk_get(dev, "xclk"); in imx290_probe()
1539 if (IS_ERR(imx290->xclk)) in imx290_probe()
1540 return dev_err_probe(dev, PTR_ERR(imx290->xclk), in imx290_probe()
1543 ret = imx290_get_regulators(dev, imx290); in imx290_probe()
1547 imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset", in imx290_probe()
1549 if (IS_ERR(imx290->rst_gpio)) in imx290_probe()
1550 return dev_err_probe(dev, PTR_ERR(imx290->rst_gpio), in imx290_probe()
1554 ret = imx290_init_clk(imx290); in imx290_probe()
1563 ret = imx290_power_on(imx290); in imx290_probe()
1581 ret = imx290_subdev_init(imx290); in imx290_probe()
1585 v4l2_i2c_subdev_set_name(&imx290->sd, client, in imx290_probe()
1586 imx290->model->name, NULL); in imx290_probe()
1593 ret = v4l2_async_register_subdev(&imx290->sd); in imx290_probe()
1609 imx290_subdev_cleanup(imx290); in imx290_probe()
1613 imx290_power_off(imx290); in imx290_probe()
1620 struct imx290 *imx290 = to_imx290(sd); in imx290_remove() local
1623 imx290_subdev_cleanup(imx290); in imx290_remove()
1629 pm_runtime_disable(imx290->dev); in imx290_remove()
1630 if (!pm_runtime_status_suspended(imx290->dev)) in imx290_remove()
1631 imx290_power_off(imx290); in imx290_remove()
1632 pm_runtime_set_suspended(imx290->dev); in imx290_remove()
1638 .compatible = "sony,imx290",
1658 .name = "imx290",
1666 MODULE_DESCRIPTION("Sony IMX290 CMOS Image Sensor Driver");