Lines Matching full:imx219

3  * A V4L2 driver for Sony IMX219 cameras.
113 /* IMX219 native and active pixel array size. */
537 struct imx219 { struct
543 struct clk *xclk; /* system clock to IMX219 */
571 static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd) in to_imx219() argument
573 return container_of(_sd, struct imx219, sd); in to_imx219()
577 static int imx219_read_reg(struct imx219 *imx219, u16 reg, u32 len, u32 *val) in imx219_read_reg() argument
579 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_read_reg()
610 static int imx219_write_reg(struct imx219 *imx219, u16 reg, u32 len, u32 val) in imx219_write_reg() argument
612 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_write_reg()
627 static int imx219_write_regs(struct imx219 *imx219, in imx219_write_regs() argument
630 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_write_regs()
635 ret = imx219_write_reg(imx219, regs[i].address, 1, regs[i].val); in imx219_write_regs()
649 static u32 imx219_get_format_code(struct imx219 *imx219, u32 code) in imx219_get_format_code() argument
653 lockdep_assert_held(&imx219->mutex); in imx219_get_format_code()
662 i = (i & ~3) | (imx219->vflip->val ? 2 : 0) | in imx219_get_format_code()
663 (imx219->hflip->val ? 1 : 0); in imx219_get_format_code()
668 static void imx219_set_default_format(struct imx219 *imx219) in imx219_set_default_format() argument
672 fmt = &imx219->fmt; in imx219_set_default_format()
687 struct imx219 *imx219 = to_imx219(sd); in imx219_open() local
692 mutex_lock(&imx219->mutex); in imx219_open()
697 try_fmt->code = imx219_get_format_code(imx219, in imx219_open()
708 mutex_unlock(&imx219->mutex); in imx219_open()
715 struct imx219 *imx219 = in imx219_set_ctrl() local
716 container_of(ctrl->handler, struct imx219, ctrl_handler); in imx219_set_ctrl()
717 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_set_ctrl()
724 exposure_max = imx219->mode->height + ctrl->val - 4; in imx219_set_ctrl()
727 __v4l2_ctrl_modify_range(imx219->exposure, in imx219_set_ctrl()
728 imx219->exposure->minimum, in imx219_set_ctrl()
729 exposure_max, imx219->exposure->step, in imx219_set_ctrl()
742 ret = imx219_write_reg(imx219, IMX219_REG_ANALOG_GAIN, in imx219_set_ctrl()
746 ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE, in imx219_set_ctrl()
750 ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN, in imx219_set_ctrl()
754 ret = imx219_write_reg(imx219, IMX219_REG_TEST_PATTERN, in imx219_set_ctrl()
760 ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1, in imx219_set_ctrl()
761 imx219->hflip->val | in imx219_set_ctrl()
762 imx219->vflip->val << 1); in imx219_set_ctrl()
765 ret = imx219_write_reg(imx219, IMX219_REG_VTS, in imx219_set_ctrl()
767 imx219->mode->height + ctrl->val); in imx219_set_ctrl()
770 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED, in imx219_set_ctrl()
774 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR, in imx219_set_ctrl()
778 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE, in imx219_set_ctrl()
782 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB, in imx219_set_ctrl()
806 struct imx219 *imx219 = to_imx219(sd); in imx219_enum_mbus_code() local
811 code->code = imx219_get_format_code(imx219, codes[code->index * 4]); in imx219_enum_mbus_code()
820 struct imx219 *imx219 = to_imx219(sd); in imx219_enum_frame_size() local
825 if (fse->code != imx219_get_format_code(imx219, fse->code)) in imx219_enum_frame_size()
846 static void imx219_update_pad_format(struct imx219 *imx219, in imx219_update_pad_format() argument
856 static int __imx219_get_pad_format(struct imx219 *imx219, in __imx219_get_pad_format() argument
862 v4l2_subdev_get_try_format(&imx219->sd, cfg, fmt->pad); in __imx219_get_pad_format()
864 try_fmt->code = imx219_get_format_code(imx219, try_fmt->code); in __imx219_get_pad_format()
867 imx219_update_pad_format(imx219, imx219->mode, fmt); in __imx219_get_pad_format()
868 fmt->format.code = imx219_get_format_code(imx219, in __imx219_get_pad_format()
869 imx219->fmt.code); in __imx219_get_pad_format()
879 struct imx219 *imx219 = to_imx219(sd); in imx219_get_pad_format() local
882 mutex_lock(&imx219->mutex); in imx219_get_pad_format()
883 ret = __imx219_get_pad_format(imx219, cfg, fmt); in imx219_get_pad_format()
884 mutex_unlock(&imx219->mutex); in imx219_get_pad_format()
893 struct imx219 *imx219 = to_imx219(sd); in imx219_set_pad_format() local
899 mutex_lock(&imx219->mutex); in imx219_set_pad_format()
908 fmt->format.code = imx219_get_format_code(imx219, codes[i]); in imx219_set_pad_format()
914 imx219_update_pad_format(imx219, mode, fmt); in imx219_set_pad_format()
918 } else if (imx219->mode != mode || in imx219_set_pad_format()
919 imx219->fmt.code != fmt->format.code) { in imx219_set_pad_format()
920 imx219->fmt = fmt->format; in imx219_set_pad_format()
921 imx219->mode = mode; in imx219_set_pad_format()
923 __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN, in imx219_set_pad_format()
926 __v4l2_ctrl_s_ctrl(imx219->vblank, in imx219_set_pad_format()
932 __v4l2_ctrl_modify_range(imx219->exposure, in imx219_set_pad_format()
933 imx219->exposure->minimum, in imx219_set_pad_format()
934 exposure_max, imx219->exposure->step, in imx219_set_pad_format()
942 __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, in imx219_set_pad_format()
946 mutex_unlock(&imx219->mutex); in imx219_set_pad_format()
951 static int imx219_set_framefmt(struct imx219 *imx219) in imx219_set_framefmt() argument
953 switch (imx219->fmt.code) { in imx219_set_framefmt()
958 return imx219_write_regs(imx219, raw8_framefmt_regs, in imx219_set_framefmt()
965 return imx219_write_regs(imx219, raw10_framefmt_regs, in imx219_set_framefmt()
973 __imx219_get_pad_crop(struct imx219 *imx219, struct v4l2_subdev_pad_config *cfg, in __imx219_get_pad_crop() argument
978 return v4l2_subdev_get_try_crop(&imx219->sd, cfg, pad); in __imx219_get_pad_crop()
980 return &imx219->mode->crop; in __imx219_get_pad_crop()
992 struct imx219 *imx219 = to_imx219(sd); in imx219_get_selection() local
994 mutex_lock(&imx219->mutex); in imx219_get_selection()
995 sel->r = *__imx219_get_pad_crop(imx219, cfg, sel->pad, in imx219_get_selection()
997 mutex_unlock(&imx219->mutex); in imx219_get_selection()
1022 static int imx219_start_streaming(struct imx219 *imx219) in imx219_start_streaming() argument
1024 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_start_streaming()
1029 reg_list = &imx219->mode->reg_list; in imx219_start_streaming()
1030 ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs); in imx219_start_streaming()
1036 ret = imx219_set_framefmt(imx219); in imx219_start_streaming()
1044 ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); in imx219_start_streaming()
1049 return imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, in imx219_start_streaming()
1053 static void imx219_stop_streaming(struct imx219 *imx219) in imx219_stop_streaming() argument
1055 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_stop_streaming()
1059 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, in imx219_stop_streaming()
1067 struct imx219 *imx219 = to_imx219(sd); in imx219_set_stream() local
1071 mutex_lock(&imx219->mutex); in imx219_set_stream()
1072 if (imx219->streaming == enable) { in imx219_set_stream()
1073 mutex_unlock(&imx219->mutex); in imx219_set_stream()
1088 ret = imx219_start_streaming(imx219); in imx219_set_stream()
1092 imx219_stop_streaming(imx219); in imx219_set_stream()
1096 imx219->streaming = enable; in imx219_set_stream()
1099 __v4l2_ctrl_grab(imx219->vflip, enable); in imx219_set_stream()
1100 __v4l2_ctrl_grab(imx219->hflip, enable); in imx219_set_stream()
1102 mutex_unlock(&imx219->mutex); in imx219_set_stream()
1109 mutex_unlock(&imx219->mutex); in imx219_set_stream()
1119 struct imx219 *imx219 = to_imx219(sd); in imx219_power_on() local
1123 imx219->supplies); in imx219_power_on()
1130 ret = clk_prepare_enable(imx219->xclk); in imx219_power_on()
1137 gpiod_set_value_cansleep(imx219->reset_gpio, 1); in imx219_power_on()
1144 regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); in imx219_power_on()
1153 struct imx219 *imx219 = to_imx219(sd); in imx219_power_off() local
1155 gpiod_set_value_cansleep(imx219->reset_gpio, 0); in imx219_power_off()
1156 regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); in imx219_power_off()
1157 clk_disable_unprepare(imx219->xclk); in imx219_power_off()
1166 struct imx219 *imx219 = to_imx219(sd); in imx219_suspend() local
1168 if (imx219->streaming) in imx219_suspend()
1169 imx219_stop_streaming(imx219); in imx219_suspend()
1178 struct imx219 *imx219 = to_imx219(sd); in imx219_resume() local
1181 if (imx219->streaming) { in imx219_resume()
1182 ret = imx219_start_streaming(imx219); in imx219_resume()
1190 imx219_stop_streaming(imx219); in imx219_resume()
1191 imx219->streaming = false; in imx219_resume()
1196 static int imx219_get_regulators(struct imx219 *imx219) in imx219_get_regulators() argument
1198 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_get_regulators()
1202 imx219->supplies[i].supply = imx219_supply_name[i]; in imx219_get_regulators()
1206 imx219->supplies); in imx219_get_regulators()
1210 static int imx219_identify_module(struct imx219 *imx219) in imx219_identify_module() argument
1212 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_identify_module()
1216 ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID, in imx219_identify_module()
1261 static int imx219_init_controls(struct imx219 *imx219) in imx219_init_controls() argument
1263 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_init_controls()
1265 unsigned int height = imx219->mode->height; in imx219_init_controls()
1270 ctrl_hdlr = &imx219->ctrl_handler; in imx219_init_controls()
1275 mutex_init(&imx219->mutex); in imx219_init_controls()
1276 ctrl_hdlr->lock = &imx219->mutex; in imx219_init_controls()
1279 imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1286 imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1289 imx219->mode->vts_def - height); in imx219_init_controls()
1290 hblank = IMX219_PPL_DEFAULT - imx219->mode->width; in imx219_init_controls()
1291 imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1294 if (imx219->hblank) in imx219_init_controls()
1295 imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx219_init_controls()
1296 exposure_max = imx219->mode->vts_def - 4; in imx219_init_controls()
1299 imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1313 imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1315 if (imx219->hflip) in imx219_init_controls()
1316 imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; in imx219_init_controls()
1318 imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1320 if (imx219->vflip) in imx219_init_controls()
1321 imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; in imx219_init_controls()
1359 imx219->sd.ctrl_handler = ctrl_hdlr; in imx219_init_controls()
1365 mutex_destroy(&imx219->mutex); in imx219_init_controls()
1370 static void imx219_free_controls(struct imx219 *imx219) in imx219_free_controls() argument
1372 v4l2_ctrl_handler_free(imx219->sd.ctrl_handler); in imx219_free_controls()
1373 mutex_destroy(&imx219->mutex); in imx219_free_controls()
1426 struct imx219 *imx219; in imx219_probe() local
1429 imx219 = devm_kzalloc(&client->dev, sizeof(*imx219), GFP_KERNEL); in imx219_probe()
1430 if (!imx219) in imx219_probe()
1433 v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops); in imx219_probe()
1440 imx219->xclk = devm_clk_get(dev, NULL); in imx219_probe()
1441 if (IS_ERR(imx219->xclk)) { in imx219_probe()
1443 return PTR_ERR(imx219->xclk); in imx219_probe()
1446 imx219->xclk_freq = clk_get_rate(imx219->xclk); in imx219_probe()
1447 if (imx219->xclk_freq != IMX219_XCLK_FREQ) { in imx219_probe()
1449 imx219->xclk_freq); in imx219_probe()
1453 ret = imx219_get_regulators(imx219); in imx219_probe()
1460 imx219->reset_gpio = devm_gpiod_get_optional(dev, "reset", in imx219_probe()
1471 ret = imx219_identify_module(imx219); in imx219_probe()
1476 imx219->mode = &supported_modes[0]; in imx219_probe()
1482 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, in imx219_probe()
1489 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, in imx219_probe()
1495 ret = imx219_init_controls(imx219); in imx219_probe()
1500 imx219->sd.internal_ops = &imx219_internal_ops; in imx219_probe()
1501 imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in imx219_probe()
1502 imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in imx219_probe()
1505 imx219->pad.flags = MEDIA_PAD_FL_SOURCE; in imx219_probe()
1508 imx219_set_default_format(imx219); in imx219_probe()
1510 ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad); in imx219_probe()
1516 ret = v4l2_async_register_subdev_sensor_common(&imx219->sd); in imx219_probe()
1530 media_entity_cleanup(&imx219->sd.entity); in imx219_probe()
1533 imx219_free_controls(imx219); in imx219_probe()
1544 struct imx219 *imx219 = to_imx219(sd); in imx219_remove() local
1548 imx219_free_controls(imx219); in imx219_remove()
1559 { .compatible = "sony,imx219" },
1571 .name = "imx219",
1582 MODULE_DESCRIPTION("Sony IMX219 sensor driver");