Lines Matching full:imx219
3 * A V4L2 driver for Sony IMX219 cameras.
113 /* IMX219 native and active pixel array size. */
539 struct imx219 { struct
545 struct clk *xclk; /* system clock to IMX219 */
574 static inline struct imx219 *to_imx219(struct v4l2_subdev *_sd) in to_imx219() argument
576 return container_of(_sd, struct imx219, sd); in to_imx219()
580 static int imx219_read_reg(struct imx219 *imx219, u16 reg, u32 len, u32 *val) in imx219_read_reg() argument
582 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_read_reg()
613 static int imx219_write_reg(struct imx219 *imx219, u16 reg, u32 len, u32 val) in imx219_write_reg() argument
615 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_write_reg()
630 static int imx219_write_regs(struct imx219 *imx219, in imx219_write_regs() argument
633 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_write_regs()
638 ret = imx219_write_reg(imx219, regs[i].address, 1, regs[i].val); in imx219_write_regs()
652 static u32 imx219_get_format_code(struct imx219 *imx219, u32 code) in imx219_get_format_code() argument
656 lockdep_assert_held(&imx219->mutex); in imx219_get_format_code()
665 i = (i & ~3) | (imx219->vflip->val ? 2 : 0) | in imx219_get_format_code()
666 (imx219->hflip->val ? 1 : 0); in imx219_get_format_code()
671 static void imx219_set_default_format(struct imx219 *imx219) in imx219_set_default_format() argument
675 fmt = &imx219->fmt; in imx219_set_default_format()
690 struct imx219 *imx219 = to_imx219(sd); in imx219_open() local
695 mutex_lock(&imx219->mutex); in imx219_open()
700 try_fmt->code = imx219_get_format_code(imx219, in imx219_open()
711 mutex_unlock(&imx219->mutex); in imx219_open()
718 struct imx219 *imx219 = in imx219_set_ctrl() local
719 container_of(ctrl->handler, struct imx219, ctrl_handler); in imx219_set_ctrl()
720 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_set_ctrl()
727 exposure_max = imx219->mode->height + ctrl->val - 4; in imx219_set_ctrl()
730 __v4l2_ctrl_modify_range(imx219->exposure, in imx219_set_ctrl()
731 imx219->exposure->minimum, in imx219_set_ctrl()
732 exposure_max, imx219->exposure->step, in imx219_set_ctrl()
745 ret = imx219_write_reg(imx219, IMX219_REG_ANALOG_GAIN, in imx219_set_ctrl()
749 ret = imx219_write_reg(imx219, IMX219_REG_EXPOSURE, in imx219_set_ctrl()
753 ret = imx219_write_reg(imx219, IMX219_REG_DIGITAL_GAIN, in imx219_set_ctrl()
757 ret = imx219_write_reg(imx219, IMX219_REG_TEST_PATTERN, in imx219_set_ctrl()
763 ret = imx219_write_reg(imx219, IMX219_REG_ORIENTATION, 1, in imx219_set_ctrl()
764 imx219->hflip->val | in imx219_set_ctrl()
765 imx219->vflip->val << 1); in imx219_set_ctrl()
768 ret = imx219_write_reg(imx219, IMX219_REG_VTS, in imx219_set_ctrl()
770 imx219->mode->height + ctrl->val); in imx219_set_ctrl()
773 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_RED, in imx219_set_ctrl()
777 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENR, in imx219_set_ctrl()
781 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_BLUE, in imx219_set_ctrl()
785 ret = imx219_write_reg(imx219, IMX219_REG_TESTP_GREENB, in imx219_set_ctrl()
809 struct imx219 *imx219 = to_imx219(sd); in imx219_enum_mbus_code() local
814 mutex_lock(&imx219->mutex); in imx219_enum_mbus_code()
815 code->code = imx219_get_format_code(imx219, codes[code->index * 4]); in imx219_enum_mbus_code()
816 mutex_unlock(&imx219->mutex); in imx219_enum_mbus_code()
825 struct imx219 *imx219 = to_imx219(sd); in imx219_enum_frame_size() local
831 mutex_lock(&imx219->mutex); in imx219_enum_frame_size()
832 code = imx219_get_format_code(imx219, fse->code); in imx219_enum_frame_size()
833 mutex_unlock(&imx219->mutex); in imx219_enum_frame_size()
855 static void imx219_update_pad_format(struct imx219 *imx219, in imx219_update_pad_format() argument
865 static int __imx219_get_pad_format(struct imx219 *imx219, in __imx219_get_pad_format() argument
871 v4l2_subdev_get_try_format(&imx219->sd, sd_state, in __imx219_get_pad_format()
874 try_fmt->code = imx219_get_format_code(imx219, try_fmt->code); in __imx219_get_pad_format()
877 imx219_update_pad_format(imx219, imx219->mode, fmt); in __imx219_get_pad_format()
878 fmt->format.code = imx219_get_format_code(imx219, in __imx219_get_pad_format()
879 imx219->fmt.code); in __imx219_get_pad_format()
889 struct imx219 *imx219 = to_imx219(sd); in imx219_get_pad_format() local
892 mutex_lock(&imx219->mutex); in imx219_get_pad_format()
893 ret = __imx219_get_pad_format(imx219, sd_state, fmt); in imx219_get_pad_format()
894 mutex_unlock(&imx219->mutex); in imx219_get_pad_format()
903 struct imx219 *imx219 = to_imx219(sd); in imx219_set_pad_format() local
909 mutex_lock(&imx219->mutex); in imx219_set_pad_format()
918 fmt->format.code = imx219_get_format_code(imx219, codes[i]); in imx219_set_pad_format()
924 imx219_update_pad_format(imx219, mode, fmt); in imx219_set_pad_format()
928 } else if (imx219->mode != mode || in imx219_set_pad_format()
929 imx219->fmt.code != fmt->format.code) { in imx219_set_pad_format()
930 imx219->fmt = fmt->format; in imx219_set_pad_format()
931 imx219->mode = mode; in imx219_set_pad_format()
933 __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN, in imx219_set_pad_format()
936 __v4l2_ctrl_s_ctrl(imx219->vblank, in imx219_set_pad_format()
942 __v4l2_ctrl_modify_range(imx219->exposure, in imx219_set_pad_format()
943 imx219->exposure->minimum, in imx219_set_pad_format()
944 exposure_max, imx219->exposure->step, in imx219_set_pad_format()
952 __v4l2_ctrl_modify_range(imx219->hblank, hblank, hblank, 1, in imx219_set_pad_format()
956 mutex_unlock(&imx219->mutex); in imx219_set_pad_format()
961 static int imx219_set_framefmt(struct imx219 *imx219) in imx219_set_framefmt() argument
963 switch (imx219->fmt.code) { in imx219_set_framefmt()
968 return imx219_write_regs(imx219, raw8_framefmt_regs, in imx219_set_framefmt()
975 return imx219_write_regs(imx219, raw10_framefmt_regs, in imx219_set_framefmt()
983 __imx219_get_pad_crop(struct imx219 *imx219, in __imx219_get_pad_crop() argument
989 return v4l2_subdev_get_try_crop(&imx219->sd, sd_state, pad); in __imx219_get_pad_crop()
991 return &imx219->mode->crop; in __imx219_get_pad_crop()
1003 struct imx219 *imx219 = to_imx219(sd); in imx219_get_selection() local
1005 mutex_lock(&imx219->mutex); in imx219_get_selection()
1006 sel->r = *__imx219_get_pad_crop(imx219, sd_state, sel->pad, in imx219_get_selection()
1008 mutex_unlock(&imx219->mutex); in imx219_get_selection()
1034 static int imx219_start_streaming(struct imx219 *imx219) in imx219_start_streaming() argument
1036 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_start_streaming()
1045 reg_list = &imx219->mode->reg_list; in imx219_start_streaming()
1046 ret = imx219_write_regs(imx219, reg_list->regs, reg_list->num_of_regs); in imx219_start_streaming()
1052 ret = imx219_set_framefmt(imx219); in imx219_start_streaming()
1060 ret = __v4l2_ctrl_handler_setup(imx219->sd.ctrl_handler); in imx219_start_streaming()
1065 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, in imx219_start_streaming()
1071 __v4l2_ctrl_grab(imx219->vflip, true); in imx219_start_streaming()
1072 __v4l2_ctrl_grab(imx219->hflip, true); in imx219_start_streaming()
1081 static void imx219_stop_streaming(struct imx219 *imx219) in imx219_stop_streaming() argument
1083 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_stop_streaming()
1087 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, in imx219_stop_streaming()
1092 __v4l2_ctrl_grab(imx219->vflip, false); in imx219_stop_streaming()
1093 __v4l2_ctrl_grab(imx219->hflip, false); in imx219_stop_streaming()
1100 struct imx219 *imx219 = to_imx219(sd); in imx219_set_stream() local
1103 mutex_lock(&imx219->mutex); in imx219_set_stream()
1104 if (imx219->streaming == enable) { in imx219_set_stream()
1105 mutex_unlock(&imx219->mutex); in imx219_set_stream()
1114 ret = imx219_start_streaming(imx219); in imx219_set_stream()
1118 imx219_stop_streaming(imx219); in imx219_set_stream()
1121 imx219->streaming = enable; in imx219_set_stream()
1123 mutex_unlock(&imx219->mutex); in imx219_set_stream()
1128 mutex_unlock(&imx219->mutex); in imx219_set_stream()
1137 struct imx219 *imx219 = to_imx219(sd); in imx219_power_on() local
1141 imx219->supplies); in imx219_power_on()
1148 ret = clk_prepare_enable(imx219->xclk); in imx219_power_on()
1155 gpiod_set_value_cansleep(imx219->reset_gpio, 1); in imx219_power_on()
1162 regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); in imx219_power_on()
1170 struct imx219 *imx219 = to_imx219(sd); in imx219_power_off() local
1172 gpiod_set_value_cansleep(imx219->reset_gpio, 0); in imx219_power_off()
1173 regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies); in imx219_power_off()
1174 clk_disable_unprepare(imx219->xclk); in imx219_power_off()
1182 struct imx219 *imx219 = to_imx219(sd); in imx219_suspend() local
1184 if (imx219->streaming) in imx219_suspend()
1185 imx219_stop_streaming(imx219); in imx219_suspend()
1193 struct imx219 *imx219 = to_imx219(sd); in imx219_resume() local
1196 if (imx219->streaming) { in imx219_resume()
1197 ret = imx219_start_streaming(imx219); in imx219_resume()
1205 imx219_stop_streaming(imx219); in imx219_resume()
1206 imx219->streaming = false; in imx219_resume()
1211 static int imx219_get_regulators(struct imx219 *imx219) in imx219_get_regulators() argument
1213 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_get_regulators()
1217 imx219->supplies[i].supply = imx219_supply_name[i]; in imx219_get_regulators()
1221 imx219->supplies); in imx219_get_regulators()
1225 static int imx219_identify_module(struct imx219 *imx219) in imx219_identify_module() argument
1227 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_identify_module()
1231 ret = imx219_read_reg(imx219, IMX219_REG_CHIP_ID, in imx219_identify_module()
1276 static int imx219_init_controls(struct imx219 *imx219) in imx219_init_controls() argument
1278 struct i2c_client *client = v4l2_get_subdevdata(&imx219->sd); in imx219_init_controls()
1280 unsigned int height = imx219->mode->height; in imx219_init_controls()
1285 ctrl_hdlr = &imx219->ctrl_handler; in imx219_init_controls()
1290 mutex_init(&imx219->mutex); in imx219_init_controls()
1291 ctrl_hdlr->lock = &imx219->mutex; in imx219_init_controls()
1294 imx219->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1300 imx219->link_freq = in imx219_init_controls()
1305 if (imx219->link_freq) in imx219_init_controls()
1306 imx219->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx219_init_controls()
1309 imx219->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1312 imx219->mode->vts_def - height); in imx219_init_controls()
1313 hblank = IMX219_PPL_DEFAULT - imx219->mode->width; in imx219_init_controls()
1314 imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1317 if (imx219->hblank) in imx219_init_controls()
1318 imx219->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx219_init_controls()
1319 exposure_max = imx219->mode->vts_def - 4; in imx219_init_controls()
1322 imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1336 imx219->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1338 if (imx219->hflip) in imx219_init_controls()
1339 imx219->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; in imx219_init_controls()
1341 imx219->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops, in imx219_init_controls()
1343 if (imx219->vflip) in imx219_init_controls()
1344 imx219->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT; in imx219_init_controls()
1382 imx219->sd.ctrl_handler = ctrl_hdlr; in imx219_init_controls()
1388 mutex_destroy(&imx219->mutex); in imx219_init_controls()
1393 static void imx219_free_controls(struct imx219 *imx219) in imx219_free_controls() argument
1395 v4l2_ctrl_handler_free(imx219->sd.ctrl_handler); in imx219_free_controls()
1396 mutex_destroy(&imx219->mutex); in imx219_free_controls()
1449 struct imx219 *imx219; in imx219_probe() local
1452 imx219 = devm_kzalloc(&client->dev, sizeof(*imx219), GFP_KERNEL); in imx219_probe()
1453 if (!imx219) in imx219_probe()
1456 v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops); in imx219_probe()
1463 imx219->xclk = devm_clk_get(dev, NULL); in imx219_probe()
1464 if (IS_ERR(imx219->xclk)) { in imx219_probe()
1466 return PTR_ERR(imx219->xclk); in imx219_probe()
1469 imx219->xclk_freq = clk_get_rate(imx219->xclk); in imx219_probe()
1470 if (imx219->xclk_freq != IMX219_XCLK_FREQ) { in imx219_probe()
1472 imx219->xclk_freq); in imx219_probe()
1476 ret = imx219_get_regulators(imx219); in imx219_probe()
1483 imx219->reset_gpio = devm_gpiod_get_optional(dev, "reset", in imx219_probe()
1494 ret = imx219_identify_module(imx219); in imx219_probe()
1499 imx219->mode = &supported_modes[0]; in imx219_probe()
1505 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, in imx219_probe()
1512 ret = imx219_write_reg(imx219, IMX219_REG_MODE_SELECT, in imx219_probe()
1518 ret = imx219_init_controls(imx219); in imx219_probe()
1523 imx219->sd.internal_ops = &imx219_internal_ops; in imx219_probe()
1524 imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | in imx219_probe()
1526 imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in imx219_probe()
1529 imx219->pad.flags = MEDIA_PAD_FL_SOURCE; in imx219_probe()
1532 imx219_set_default_format(imx219); in imx219_probe()
1534 ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad); in imx219_probe()
1540 ret = v4l2_async_register_subdev_sensor(&imx219->sd); in imx219_probe()
1554 media_entity_cleanup(&imx219->sd.entity); in imx219_probe()
1557 imx219_free_controls(imx219); in imx219_probe()
1568 struct imx219 *imx219 = to_imx219(sd); in imx219_remove() local
1572 imx219_free_controls(imx219); in imx219_remove()
1583 { .compatible = "sony,imx219" },
1595 .name = "imx219",
1606 MODULE_DESCRIPTION("Sony IMX219 sensor driver");