Lines Matching full:imx290
3 * Sony IMX290 CMOS Image Sensor Driver
65 struct imx290 { struct
290 static inline const s64 *imx290_link_freqs_ptr(const struct imx290 *imx290) in imx290_link_freqs_ptr() argument
292 if (imx290->nlanes == 2) in imx290_link_freqs_ptr()
298 static inline int imx290_link_freqs_num(const struct imx290 *imx290) in imx290_link_freqs_num() argument
300 if (imx290->nlanes == 2) in imx290_link_freqs_num()
345 static inline const struct imx290_mode *imx290_modes_ptr(const struct imx290 *imx290) in imx290_modes_ptr() argument
347 if (imx290->nlanes == 2) in imx290_modes_ptr()
353 static inline int imx290_modes_num(const struct imx290 *imx290) in imx290_modes_num() argument
355 if (imx290->nlanes == 2) in imx290_modes_num()
361 static inline struct imx290 *to_imx290(struct v4l2_subdev *_sd) in to_imx290()
363 return container_of(_sd, struct imx290, sd); in to_imx290()
366 static inline int imx290_read_reg(struct imx290 *imx290, u16 addr, u8 *value) in imx290_read_reg() argument
371 ret = regmap_read(imx290->regmap, addr, ®val); in imx290_read_reg()
373 dev_err(imx290->dev, "I2C read failed for addr: %x\n", addr); in imx290_read_reg()
382 static int imx290_write_reg(struct imx290 *imx290, u16 addr, u8 value) in imx290_write_reg() argument
386 ret = regmap_write(imx290->regmap, addr, value); in imx290_write_reg()
388 dev_err(imx290->dev, "I2C write failed for addr: %x\n", addr); in imx290_write_reg()
395 static int imx290_set_register_array(struct imx290 *imx290, in imx290_set_register_array() argument
403 ret = imx290_write_reg(imx290, settings->reg, settings->val); in imx290_set_register_array()
414 static int imx290_write_buffered_reg(struct imx290 *imx290, u16 address_low, in imx290_write_buffered_reg() argument
420 ret = imx290_write_reg(imx290, IMX290_REGHOLD, 0x01); in imx290_write_buffered_reg()
422 dev_err(imx290->dev, "Error setting hold register\n"); in imx290_write_buffered_reg()
427 ret = imx290_write_reg(imx290, address_low + i, in imx290_write_buffered_reg()
430 dev_err(imx290->dev, "Error writing buffered registers\n"); in imx290_write_buffered_reg()
435 ret = imx290_write_reg(imx290, IMX290_REGHOLD, 0x00); in imx290_write_buffered_reg()
437 dev_err(imx290->dev, "Error setting hold register\n"); in imx290_write_buffered_reg()
444 static int imx290_set_gain(struct imx290 *imx290, u32 value) in imx290_set_gain() argument
448 ret = imx290_write_buffered_reg(imx290, IMX290_GAIN, 1, value); in imx290_set_gain()
450 dev_err(imx290->dev, "Unable to write gain\n"); in imx290_set_gain()
456 static int imx290_stop_streaming(struct imx290 *imx290) in imx290_stop_streaming() argument
460 ret = imx290_write_reg(imx290, IMX290_STANDBY, 0x01); in imx290_stop_streaming()
466 return imx290_write_reg(imx290, IMX290_XMSTA, 0x01); in imx290_stop_streaming()
471 struct imx290 *imx290 = container_of(ctrl->handler, in imx290_set_ctrl() local
472 struct imx290, ctrls); in imx290_set_ctrl()
476 if (!pm_runtime_get_if_in_use(imx290->dev)) in imx290_set_ctrl()
481 ret = imx290_set_gain(imx290, ctrl->val); in imx290_set_ctrl()
485 imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x00); in imx290_set_ctrl()
486 imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00); in imx290_set_ctrl()
488 imx290_write_reg(imx290, IMX290_PGCTRL, in imx290_set_ctrl()
493 imx290_write_reg(imx290, IMX290_PGCTRL, 0x00); in imx290_set_ctrl()
495 if (imx290->bpp == 10) in imx290_set_ctrl()
496 imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, in imx290_set_ctrl()
499 imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, in imx290_set_ctrl()
501 imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00); in imx290_set_ctrl()
509 pm_runtime_put(imx290->dev); in imx290_set_ctrl()
534 const struct imx290 *imx290 = to_imx290(sd); in imx290_enum_frame_size() local
535 const struct imx290_mode *imx290_modes = imx290_modes_ptr(imx290); in imx290_enum_frame_size()
541 if (fse->index >= imx290_modes_num(imx290)) in imx290_enum_frame_size()
556 struct imx290 *imx290 = to_imx290(sd); in imx290_get_fmt() local
559 mutex_lock(&imx290->lock); in imx290_get_fmt()
562 framefmt = v4l2_subdev_get_try_format(&imx290->sd, cfg, in imx290_get_fmt()
565 framefmt = &imx290->current_format; in imx290_get_fmt()
569 mutex_unlock(&imx290->lock); in imx290_get_fmt()
574 static inline u8 imx290_get_link_freq_index(struct imx290 *imx290) in imx290_get_link_freq_index() argument
576 return imx290->current_mode->link_freq_index; in imx290_get_link_freq_index()
579 static s64 imx290_get_link_freq(struct imx290 *imx290) in imx290_get_link_freq() argument
581 u8 index = imx290_get_link_freq_index(imx290); in imx290_get_link_freq()
583 return *(imx290_link_freqs_ptr(imx290) + index); in imx290_get_link_freq()
586 static u64 imx290_calc_pixel_rate(struct imx290 *imx290) in imx290_calc_pixel_rate() argument
588 s64 link_freq = imx290_get_link_freq(imx290); in imx290_calc_pixel_rate()
589 u8 nlanes = imx290->nlanes; in imx290_calc_pixel_rate()
594 do_div(pixel_rate, imx290->bpp); in imx290_calc_pixel_rate()
602 struct imx290 *imx290 = to_imx290(sd); in imx290_set_fmt() local
607 mutex_lock(&imx290->lock); in imx290_set_fmt()
609 mode = v4l2_find_nearest_size(imx290_modes_ptr(imx290), in imx290_set_fmt()
610 imx290_modes_num(imx290), width, height, in imx290_set_fmt()
629 format = &imx290->current_format; in imx290_set_fmt()
630 imx290->current_mode = mode; in imx290_set_fmt()
631 imx290->bpp = imx290_formats[i].bpp; in imx290_set_fmt()
633 if (imx290->link_freq) in imx290_set_fmt()
634 __v4l2_ctrl_s_ctrl(imx290->link_freq, in imx290_set_fmt()
635 imx290_get_link_freq_index(imx290)); in imx290_set_fmt()
636 if (imx290->pixel_rate) in imx290_set_fmt()
637 __v4l2_ctrl_s_ctrl_int64(imx290->pixel_rate, in imx290_set_fmt()
638 imx290_calc_pixel_rate(imx290)); in imx290_set_fmt()
643 mutex_unlock(&imx290->lock); in imx290_set_fmt()
662 static int imx290_write_current_format(struct imx290 *imx290) in imx290_write_current_format() argument
666 switch (imx290->current_format.code) { in imx290_write_current_format()
668 ret = imx290_set_register_array(imx290, imx290_10bit_settings, in imx290_write_current_format()
672 dev_err(imx290->dev, "Could not set format registers\n"); in imx290_write_current_format()
677 ret = imx290_set_register_array(imx290, imx290_12bit_settings, in imx290_write_current_format()
681 dev_err(imx290->dev, "Could not set format registers\n"); in imx290_write_current_format()
686 dev_err(imx290->dev, "Unknown pixel format\n"); in imx290_write_current_format()
693 static int imx290_set_hmax(struct imx290 *imx290, u32 val) in imx290_set_hmax() argument
697 ret = imx290_write_reg(imx290, IMX290_HMAX_LOW, (val & 0xff)); in imx290_set_hmax()
699 dev_err(imx290->dev, "Error setting HMAX register\n"); in imx290_set_hmax()
703 ret = imx290_write_reg(imx290, IMX290_HMAX_HIGH, ((val >> 8) & 0xff)); in imx290_set_hmax()
705 dev_err(imx290->dev, "Error setting HMAX register\n"); in imx290_set_hmax()
713 static int imx290_start_streaming(struct imx290 *imx290) in imx290_start_streaming() argument
718 ret = imx290_set_register_array(imx290, imx290_global_init_settings, in imx290_start_streaming()
722 dev_err(imx290->dev, "Could not set init registers\n"); in imx290_start_streaming()
727 ret = imx290_write_current_format(imx290); in imx290_start_streaming()
729 dev_err(imx290->dev, "Could not set frame format\n"); in imx290_start_streaming()
734 ret = imx290_set_register_array(imx290, imx290->current_mode->data, in imx290_start_streaming()
735 imx290->current_mode->data_size); in imx290_start_streaming()
737 dev_err(imx290->dev, "Could not set current mode\n"); in imx290_start_streaming()
740 ret = imx290_set_hmax(imx290, imx290->current_mode->hmax); in imx290_start_streaming()
745 ret = v4l2_ctrl_handler_setup(imx290->sd.ctrl_handler); in imx290_start_streaming()
747 dev_err(imx290->dev, "Could not sync v4l2 controls\n"); in imx290_start_streaming()
751 ret = imx290_write_reg(imx290, IMX290_STANDBY, 0x00); in imx290_start_streaming()
758 return imx290_write_reg(imx290, IMX290_XMSTA, 0x00); in imx290_start_streaming()
763 struct imx290 *imx290 = to_imx290(sd); in imx290_set_stream() local
767 ret = pm_runtime_get_sync(imx290->dev); in imx290_set_stream()
769 pm_runtime_put_noidle(imx290->dev); in imx290_set_stream()
773 ret = imx290_start_streaming(imx290); in imx290_set_stream()
775 dev_err(imx290->dev, "Start stream failed\n"); in imx290_set_stream()
776 pm_runtime_put(imx290->dev); in imx290_set_stream()
780 imx290_stop_streaming(imx290); in imx290_set_stream()
781 pm_runtime_put(imx290->dev); in imx290_set_stream()
789 static int imx290_get_regulators(struct device *dev, struct imx290 *imx290) in imx290_get_regulators() argument
794 imx290->supplies[i].supply = imx290_supply_name[i]; in imx290_get_regulators()
797 imx290->supplies); in imx290_get_regulators()
800 static int imx290_set_data_lanes(struct imx290 *imx290) in imx290_set_data_lanes() argument
804 switch (imx290->nlanes) { in imx290_set_data_lanes()
818 dev_err(imx290->dev, "Lane configuration not supported\n"); in imx290_set_data_lanes()
823 ret = imx290_write_reg(imx290, IMX290_PHY_LANE_NUM, laneval); in imx290_set_data_lanes()
825 dev_err(imx290->dev, "Error setting Physical Lane number register\n"); in imx290_set_data_lanes()
829 ret = imx290_write_reg(imx290, IMX290_CSI_LANE_MODE, laneval); in imx290_set_data_lanes()
831 dev_err(imx290->dev, "Error setting CSI Lane mode register\n"); in imx290_set_data_lanes()
835 ret = imx290_write_reg(imx290, IMX290_FR_FDG_SEL, frsel); in imx290_set_data_lanes()
837 dev_err(imx290->dev, "Error setting FR/FDG SEL register\n"); in imx290_set_data_lanes()
847 struct imx290 *imx290 = to_imx290(sd); in imx290_power_on() local
850 ret = clk_prepare_enable(imx290->xclk); in imx290_power_on()
852 dev_err(imx290->dev, "Failed to enable clock\n"); in imx290_power_on()
856 ret = regulator_bulk_enable(IMX290_NUM_SUPPLIES, imx290->supplies); in imx290_power_on()
858 dev_err(imx290->dev, "Failed to enable regulators\n"); in imx290_power_on()
859 clk_disable_unprepare(imx290->xclk); in imx290_power_on()
864 gpiod_set_value_cansleep(imx290->rst_gpio, 0); in imx290_power_on()
868 imx290_set_data_lanes(imx290); in imx290_power_on()
877 struct imx290 *imx290 = to_imx290(sd); in imx290_power_off() local
879 clk_disable_unprepare(imx290->xclk); in imx290_power_off()
880 gpiod_set_value_cansleep(imx290->rst_gpio, 1); in imx290_power_off()
881 regulator_bulk_disable(IMX290_NUM_SUPPLIES, imx290->supplies); in imx290_power_off()
916 static s64 imx290_check_link_freqs(const struct imx290 *imx290, in imx290_check_link_freqs() argument
920 const s64 *freqs = imx290_link_freqs_ptr(imx290); in imx290_check_link_freqs()
921 int freqs_count = imx290_link_freqs_num(imx290); in imx290_check_link_freqs()
941 struct imx290 *imx290; in imx290_probe() local
946 imx290 = devm_kzalloc(dev, sizeof(*imx290), GFP_KERNEL); in imx290_probe()
947 if (!imx290) in imx290_probe()
950 imx290->dev = dev; in imx290_probe()
951 imx290->regmap = devm_regmap_init_i2c(client, &imx290_regmap_config); in imx290_probe()
952 if (IS_ERR(imx290->regmap)) { in imx290_probe()
974 imx290->nlanes = ep.bus.mipi_csi2.num_data_lanes; in imx290_probe()
975 if (imx290->nlanes != 2 && imx290->nlanes != 4) { in imx290_probe()
976 dev_err(dev, "Invalid data lanes: %d\n", imx290->nlanes); in imx290_probe()
981 dev_dbg(dev, "Using %u data lanes\n", imx290->nlanes); in imx290_probe()
990 fq = imx290_check_link_freqs(imx290, &ep); in imx290_probe()
998 imx290->xclk = devm_clk_get(dev, "xclk"); in imx290_probe()
999 if (IS_ERR(imx290->xclk)) { in imx290_probe()
1001 ret = PTR_ERR(imx290->xclk); in imx290_probe()
1020 ret = clk_set_rate(imx290->xclk, xclk_freq); in imx290_probe()
1026 ret = imx290_get_regulators(dev, imx290); in imx290_probe()
1032 imx290->rst_gpio = devm_gpiod_get_optional(dev, "reset", in imx290_probe()
1034 if (IS_ERR(imx290->rst_gpio)) { in imx290_probe()
1036 ret = PTR_ERR(imx290->rst_gpio); in imx290_probe()
1040 mutex_init(&imx290->lock); in imx290_probe()
1043 * Initialize the frame format. In particular, imx290->current_mode in imx290_probe()
1044 * and imx290->bpp are set to defaults: imx290_calc_pixel_rate() call in imx290_probe()
1047 imx290_entity_init_cfg(&imx290->sd, NULL); in imx290_probe()
1049 v4l2_ctrl_handler_init(&imx290->ctrls, 4); in imx290_probe()
1051 v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, in imx290_probe()
1054 imx290->link_freq = in imx290_probe()
1055 v4l2_ctrl_new_int_menu(&imx290->ctrls, &imx290_ctrl_ops, in imx290_probe()
1057 imx290_link_freqs_num(imx290) - 1, 0, in imx290_probe()
1058 imx290_link_freqs_ptr(imx290)); in imx290_probe()
1059 if (imx290->link_freq) in imx290_probe()
1060 imx290->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx290_probe()
1062 imx290->pixel_rate = v4l2_ctrl_new_std(&imx290->ctrls, &imx290_ctrl_ops, in imx290_probe()
1065 imx290_calc_pixel_rate(imx290)); in imx290_probe()
1067 v4l2_ctrl_new_std_menu_items(&imx290->ctrls, &imx290_ctrl_ops, in imx290_probe()
1072 imx290->sd.ctrl_handler = &imx290->ctrls; in imx290_probe()
1074 if (imx290->ctrls.error) { in imx290_probe()
1076 imx290->ctrls.error); in imx290_probe()
1077 ret = imx290->ctrls.error; in imx290_probe()
1081 v4l2_i2c_subdev_init(&imx290->sd, client, &imx290_subdev_ops); in imx290_probe()
1082 imx290->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in imx290_probe()
1083 imx290->sd.dev = &client->dev; in imx290_probe()
1084 imx290->sd.entity.ops = &imx290_subdev_entity_ops; in imx290_probe()
1085 imx290->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in imx290_probe()
1087 imx290->pad.flags = MEDIA_PAD_FL_SOURCE; in imx290_probe()
1088 ret = media_entity_pads_init(&imx290->sd.entity, 1, &imx290->pad); in imx290_probe()
1094 ret = v4l2_async_register_subdev(&imx290->sd); in imx290_probe()
1116 media_entity_cleanup(&imx290->sd.entity); in imx290_probe()
1118 v4l2_ctrl_handler_free(&imx290->ctrls); in imx290_probe()
1119 mutex_destroy(&imx290->lock); in imx290_probe()
1129 struct imx290 *imx290 = to_imx290(sd); in imx290_remove() local
1135 mutex_destroy(&imx290->lock); in imx290_remove()
1137 pm_runtime_disable(imx290->dev); in imx290_remove()
1138 if (!pm_runtime_status_suspended(imx290->dev)) in imx290_remove()
1139 imx290_power_off(imx290->dev); in imx290_remove()
1140 pm_runtime_set_suspended(imx290->dev); in imx290_remove()
1146 { .compatible = "sony,imx290" },
1155 .name = "imx290",
1163 MODULE_DESCRIPTION("Sony IMX290 CMOS Image Sensor Driver");