Lines Matching defs:imx290

228 struct imx290 {
255 static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd)
257 return container_of(_sd, struct imx290, sd);
441 static inline const s64 *imx290_link_freqs_ptr(const struct imx290 *imx290)
443 if (imx290->nlanes == 2)
449 static inline int imx290_link_freqs_num(const struct imx290 *imx290)
451 if (imx290->nlanes == 2)
550 static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290)
552 if (imx290->nlanes == 2)
558 static inline int imx290_modes_num(const struct imx290 *imx290)
560 if (imx290->nlanes == 2)
594 imx290_format_info(const struct imx290 *imx290, u32 code)
601 if (info->code[imx290->model->colour_variant] == code)
608 static int imx290_set_register_array(struct imx290 *imx290,
614 ret = cci_multi_reg_write(imx290->regmap, settings, num_settings, NULL);
624 static int imx290_set_clock(struct imx290 *imx290)
626 const struct imx290_mode *mode = imx290->current_mode;
627 enum imx290_clk_freq clk_idx = imx290->xclk_idx;
631 ret = imx290_set_register_array(imx290, xclk_regs[clk_idx],
634 cci_write(imx290->regmap, IMX290_INCKSEL1, clk_cfg->incksel1, &ret);
635 cci_write(imx290->regmap, IMX290_INCKSEL2, clk_cfg->incksel2, &ret);
636 cci_write(imx290->regmap, IMX290_INCKSEL3, clk_cfg->incksel3, &ret);
637 cci_write(imx290->regmap, IMX290_INCKSEL4, clk_cfg->incksel4, &ret);
638 cci_write(imx290->regmap, IMX290_INCKSEL5, clk_cfg->incksel5, &ret);
639 cci_write(imx290->regmap, IMX290_INCKSEL6, clk_cfg->incksel6, &ret);
644 static int imx290_set_data_lanes(struct imx290 *imx290)
648 cci_write(imx290->regmap, IMX290_PHY_LANE_NUM, imx290->nlanes - 1,
650 cci_write(imx290->regmap, IMX290_CSI_LANE_MODE, imx290->nlanes - 1,
652 cci_write(imx290->regmap, IMX290_FR_FDG_SEL, 0x01, &ret);
657 static int imx290_set_black_level(struct imx290 *imx290,
661 unsigned int bpp = imx290_format_info(imx290, format->code)->bpp;
663 return cci_write(imx290->regmap, IMX290_BLKLEVEL,
667 static int imx290_set_csi_config(struct imx290 *imx290)
669 const s64 *link_freqs = imx290_link_freqs_ptr(imx290);
673 switch (link_freqs[imx290->current_mode->link_freq_index]) {
690 cci_write(imx290->regmap, IMX290_REPETITION, csi_cfg->repetition, &ret);
691 cci_write(imx290->regmap, IMX290_TCLKPOST, csi_cfg->tclkpost, &ret);
692 cci_write(imx290->regmap, IMX290_THSZERO, csi_cfg->thszero, &ret);
693 cci_write(imx290->regmap, IMX290_THSPREPARE, csi_cfg->thsprepare, &ret);
694 cci_write(imx290->regmap, IMX290_TCLKTRAIL, csi_cfg->tclktrail, &ret);
695 cci_write(imx290->regmap, IMX290_THSTRAIL, csi_cfg->thstrail, &ret);
696 cci_write(imx290->regmap, IMX290_TCLKZERO, csi_cfg->tclkzero, &ret);
697 cci_write(imx290->regmap, IMX290_TCLKPREPARE, csi_cfg->tclkprepare,
699 cci_write(imx290->regmap, IMX290_TLPX, csi_cfg->tlpx, &ret);
704 static int imx290_setup_format(struct imx290 *imx290,
710 info = imx290_format_info(imx290, format->code);
712 ret = imx290_set_register_array(imx290, info->regs, info->num_regs);
714 dev_err(imx290->dev, "Could not set format registers\n");
718 return imx290_set_black_level(imx290, format,
725 static void imx290_exposure_update(struct imx290 *imx290,
730 exposure_max = imx290->vblank->val + mode->height -
732 __v4l2_ctrl_modify_range(imx290->exposure, 1, exposure_max, 1,
738 struct imx290 *imx290 = container_of(ctrl->handler,
739 struct imx290, ctrls);
753 imx290_exposure_update(imx290, imx290->current_mode);
757 if (!pm_runtime_get_if_in_use(imx290->dev))
760 state = v4l2_subdev_get_locked_active_state(&imx290->sd);
761 format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0);
765 ret = cci_write(imx290->regmap, IMX290_GAIN, ctrl->val, NULL);
769 ret = cci_write(imx290->regmap, IMX290_VMAX,
770 ctrl->val + imx290->current_mode->height, NULL);
778 ctrl = imx290->exposure;
781 vmax = imx290->vblank->val + imx290->current_mode->height;
782 ret = cci_write(imx290->regmap, IMX290_SHS1,
788 imx290_set_black_level(imx290, format, 0, &ret);
790 cci_write(imx290->regmap, IMX290_PGCTRL,
795 cci_write(imx290->regmap, IMX290_PGCTRL, 0x00, &ret);
797 imx290_set_black_level(imx290, format,
803 ret = cci_write(imx290->regmap, IMX290_HMAX,
804 ctrl->val + imx290->current_mode->width, NULL);
812 reg = imx290->current_mode->ctrl_07;
813 if (imx290->hflip->val)
815 if (imx290->vflip->val)
817 ret = cci_write(imx290->regmap, IMX290_CTRL_07, reg, NULL);
826 pm_runtime_mark_last_busy(imx290->dev);
827 pm_runtime_put_autosuspend(imx290->dev);
847 static void imx290_ctrl_update(struct imx290 *imx290,
855 __v4l2_ctrl_s_ctrl(imx290->link_freq, mode->link_freq_index);
857 __v4l2_ctrl_modify_range(imx290->hblank, hblank_min, hblank_max, 1,
859 __v4l2_ctrl_modify_range(imx290->vblank, vblank_min, vblank_max, 1,
863 static int imx290_ctrl_init(struct imx290 *imx290)
868 ret = v4l2_fwnode_device_parse(imx290->dev, &props);
872 v4l2_ctrl_handler_init(&imx290->ctrls, 11);
887 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
894 imx290->exposure = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
903 imx290->link_freq =
904 v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops,
906 imx290_link_freqs_num(imx290) - 1, 0,
907 imx290_link_freqs_ptr(imx290));
908 if (imx290->link_freq)
909 imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
911 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, V4L2_CID_PIXEL_RATE,
915 v4l2_ctrl_new_std_menu_items(&imx290->ctrls, &imx290_ctrl_ops,
923 imx290->hblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
926 imx290->vblank = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
929 imx290->hflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
931 imx290->vflip = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops,
933 v4l2_ctrl_cluster(2, &imx290->hflip);
935 v4l2_ctrl_new_fwnode_properties(&imx290->ctrls, &imx290_ctrl_ops,
938 imx290->sd.ctrl_handler = &imx290->ctrls;
940 if (imx290->ctrls.error) {
941 ret = imx290->ctrls.error;
942 v4l2_ctrl_handler_free(&imx290->ctrls);
954 static int imx290_start_streaming(struct imx290 *imx290,
961 ret = imx290_set_register_array(imx290, imx290_global_init_settings,
964 dev_err(imx290->dev, "Could not set init registers\n");
969 ret = imx290_set_register_array(imx290, imx290->model->init_regs,
970 imx290->model->init_regs_num);
972 dev_err(imx290->dev, "Could not set model specific init registers\n");
977 ret = imx290_set_clock(imx290);
979 dev_err(imx290->dev, "Could not set clocks - %d\n", ret);
984 ret = imx290_set_data_lanes(imx290);
986 dev_err(imx290->dev, "Could not set data lanes - %d\n", ret);
990 ret = imx290_set_csi_config(imx290);
992 dev_err(imx290->dev, "Could not set csi cfg - %d\n", ret);
997 format = v4l2_subdev_get_pad_format(&imx290->sd, state, 0);
998 ret = imx290_setup_format(imx290, format);
1000 dev_err(imx290->dev, "Could not set frame format - %d\n", ret);
1005 ret = imx290_set_register_array(imx290, imx290->current_mode->data,
1006 imx290->current_mode->data_size);
1008 dev_err(imx290->dev, "Could not set current mode - %d\n", ret);
1013 ret = __v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler);
1015 dev_err(imx290->dev, "Could not sync v4l2 controls - %d\n", ret);
1019 cci_write(imx290->regmap, IMX290_STANDBY, 0x00, &ret);
1024 return cci_write(imx290->regmap, IMX290_XMSTA, 0x00, &ret);
1028 static int imx290_stop_streaming(struct imx290 *imx290)
1032 cci_write(imx290->regmap, IMX290_STANDBY, 0x01, &ret);
1036 return cci_write(imx290->regmap, IMX290_XMSTA, 0x01, &ret);
1041 struct imx290 *imx290 = to_imx290(sd);
1048 ret = pm_runtime_resume_and_get(imx290->dev);
1052 ret = imx290_start_streaming(imx290, state);
1054 dev_err(imx290->dev, "Start stream failed\n");
1055 pm_runtime_put_sync(imx290->dev);
1059 imx290_stop_streaming(imx290);
1060 pm_runtime_mark_last_busy(imx290->dev);
1061 pm_runtime_put_autosuspend(imx290->dev);
1068 __v4l2_ctrl_grab(imx290->vflip, enable);
1069 __v4l2_ctrl_grab(imx290->hflip, enable);
1080 const struct imx290 *imx290 = to_imx290(sd);
1085 code->code = imx290_formats[code->index].code[imx290->model->colour_variant];
1094 const struct imx290 *imx290 = to_imx290(sd);
1095 const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290);
1097 if (!imx290_format_info(imx290, fse->code))
1100 if (fse->index >= imx290_modes_num(imx290))
1115 struct imx290 *imx290 = to_imx290(sd);
1119 mode = v4l2_find_nearest_size(imx290_modes_ptr(imx290),
1120 imx290_modes_num(imx290), width, height,
1126 if (!imx290_format_info(imx290, fmt->format.code))
1127 fmt->format.code = imx290_formats[0].code[imx290->model->colour_variant];
1138 imx290->current_mode = mode;
1140 imx290_ctrl_update(imx290, mode);
1141 imx290_exposure_update(imx290, mode);
1153 struct imx290 *imx290 = to_imx290(sd);
1166 + imx290->vflip->val;
1169 + imx290->hflip->val;
1242 static int imx290_subdev_init(struct imx290 *imx290)
1244 struct i2c_client *client = to_i2c_client(imx290->dev);
1248 imx290->current_mode = &imx290_modes_ptr(imx290)[0];
1250 v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops);
1251 imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1253 imx290->sd.dev = imx290->dev;
1254 imx290->sd.entity.ops = &imx290_subdev_entity_ops;
1255 imx290->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1257 imx290->pad.flags = MEDIA_PAD_FL_SOURCE;
1258 ret = media_entity_pads_init(&imx290->sd.entity, 1, &imx290->pad);
1260 dev_err(imx290->dev, "Could not register media entity\n");
1264 ret = imx290_ctrl_init(imx290);
1266 dev_err(imx290->dev, "Control initialization error %d\n", ret);
1270 imx290->sd.state_lock = imx290->ctrls.lock;
1272 ret = v4l2_subdev_init_finalize(&imx290->sd);
1274 dev_err(imx290->dev, "subdev initialization error %d\n", ret);
1278 state = v4l2_subdev_lock_and_get_active_state(&imx290->sd);
1279 imx290_ctrl_update(imx290, imx290->current_mode);
1285 v4l2_ctrl_handler_free(&imx290->ctrls);
1287 media_entity_cleanup(&imx290->sd.entity);
1291 static void imx290_subdev_cleanup(struct imx290 *imx290)
1293 v4l2_subdev_cleanup(&imx290->sd);
1294 media_entity_cleanup(&imx290->sd.entity);
1295 v4l2_ctrl_handler_free(&imx290->ctrls);
1302 static int imx290_power_on(struct imx290 *imx290)
1306 ret = clk_prepare_enable(imx290->xclk);
1308 dev_err(imx290->dev, "Failed to enable clock\n");
1312 ret = regulator_bulk_enable(ARRAY_SIZE(imx290->supplies),
1313 imx290->supplies);
1315 dev_err(imx290->dev, "Failed to enable regulators\n");
1316 clk_disable_unprepare(imx290->xclk);
1321 gpiod_set_value_cansleep(imx290->rst_gpio, 0);
1327 static void imx290_power_off(struct imx290 *imx290)
1329 clk_disable_unprepare(imx290->xclk);
1330 gpiod_set_value_cansleep(imx290->rst_gpio, 1);
1331 regulator_bulk_disable(ARRAY_SIZE(imx290->supplies), imx290->supplies);
1337 struct imx290 *imx290 = to_imx290(sd);
1339 return imx290_power_on(imx290);
1345 struct imx290 *imx290 = to_imx290(sd);
1347 imx290_power_off(imx290);
1366 static int imx290_get_regulators(struct device *dev, struct imx290 *imx290)
1370 for (i = 0; i < ARRAY_SIZE(imx290->supplies); i++)
1371 imx290->supplies[i].supply = imx290_supply_name[i];
1373 return devm_regulator_bulk_get(dev, ARRAY_SIZE(imx290->supplies),
1374 imx290->supplies);
1377 static int imx290_init_clk(struct imx290 *imx290)
1382 ret = device_property_read_u32(imx290->dev, "clock-frequency",
1385 dev_err(imx290->dev, "Could not get xclk frequency\n");
1392 imx290->xclk_idx = IMX290_CLK_37_125;
1395 imx290->xclk_idx = IMX290_CLK_74_25;
1398 dev_err(imx290->dev, "External clock frequency %u is not supported\n",
1403 ret = clk_set_rate(imx290->xclk, xclk_freq);
1405 dev_err(imx290->dev, "Could not set xclk frequency\n");
1417 static s64 imx290_check_link_freqs(const struct imx290 *imx290,
1421 const s64 *freqs = imx290_link_freqs_ptr(imx290);
1422 int freqs_count = imx290_link_freqs_num(imx290);
1439 .name = "imx290",
1445 .name = "imx290",
1455 static int imx290_parse_dt(struct imx290 *imx290)
1465 imx290->model = of_device_get_match_data(imx290->dev);
1467 endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(imx290->dev), NULL);
1469 dev_err(imx290->dev, "Endpoint node not found\n");
1476 dev_err(imx290->dev, "Unsupported bus type, should be CSI2\n");
1479 dev_err(imx290->dev, "Parsing endpoint node failed\n");
1484 imx290->nlanes = ep.bus.mipi_csi2.num_data_lanes;
1485 if (imx290->nlanes != 2 && imx290->nlanes != 4) {
1486 dev_err(imx290->dev, "Invalid data lanes: %d\n", imx290->nlanes);
1491 dev_dbg(imx290->dev, "Using %u data lanes\n", imx290->nlanes);
1494 dev_err(imx290->dev, "link-frequency property not found in DT\n");
1500 fq = imx290_check_link_freqs(imx290, &ep);
1502 dev_err(imx290->dev, "Link frequency of %lld is not supported\n",
1518 struct imx290 *imx290;
1521 imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL);
1522 if (!imx290)
1525 imx290->dev = dev;
1526 imx290->regmap = devm_cci_regmap_init_i2c(client, 16);
1527 if (IS_ERR(imx290->regmap)) {
1532 ret = imx290_parse_dt(imx290);
1537 imx290->xclk = devm_clk_get(dev, "xclk");
1538 if (IS_ERR(imx290->xclk))
1539 return dev_err_probe(dev, PTR_ERR(imx290->xclk),
1542 ret = imx290_get_regulators(dev, imx290);
1546 imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset",
1548 if (IS_ERR(imx290->rst_gpio))
1549 return dev_err_probe(dev, PTR_ERR(imx290->rst_gpio),
1553 ret = imx290_init_clk(imx290);
1562 ret = imx290_power_on(imx290);
1580 ret = imx290_subdev_init(imx290);
1584 v4l2_i2c_subdev_set_name(&imx290->sd, client,
1585 imx290->model->name, NULL);
1592 ret = v4l2_async_register_subdev(&imx290->sd);
1608 imx290_subdev_cleanup(imx290);
1612 imx290_power_off(imx290);
1619 struct imx290 *imx290 = to_imx290(sd);
1622 imx290_subdev_cleanup(imx290);
1628 pm_runtime_disable(imx290->dev);
1629 if (!pm_runtime_status_suspended(imx290->dev))
1630 imx290_power_off(imx290);
1631 pm_runtime_set_suspended(imx290->dev);
1637 .compatible = "sony,imx290",
1657 .name = "imx290",