Lines Matching full:imx412
3 * Sony imx412 Camera Sensor Driver
60 * struct imx412_reg - imx412 sensor register
70 * struct imx412_reg_list - imx412 sensor register list
80 * struct imx412_mode - imx412 sensor mode structure
112 * struct imx412 - imx412 sensor device structure
132 struct imx412 { struct
412 * to_imx412() - imx412 V4L2 sub-device to imx412 device.
413 * @subdev: pointer to imx412 V4L2 sub-device
415 * Return: pointer to imx412 device
417 static inline struct imx412 *to_imx412(struct v4l2_subdev *subdev) in to_imx412()
419 return container_of(subdev, struct imx412, sd); in to_imx412()
424 * @imx412: pointer to imx412 device
431 static int imx412_read_reg(struct imx412 *imx412, u16 reg, u32 len, u32 *val) in imx412_read_reg() argument
433 struct i2c_client *client = v4l2_get_subdevdata(&imx412->sd); in imx412_read_reg()
467 * @imx412: pointer to imx412 device
474 static int imx412_write_reg(struct imx412 *imx412, u16 reg, u32 len, u32 val) in imx412_write_reg() argument
476 struct i2c_client *client = v4l2_get_subdevdata(&imx412->sd); in imx412_write_reg()
492 * @imx412: pointer to imx412 device
498 static int imx412_write_regs(struct imx412 *imx412, in imx412_write_regs() argument
505 ret = imx412_write_reg(imx412, regs[i].address, 1, regs[i].val); in imx412_write_regs()
515 * @imx412: pointer to imx412 device
520 static int imx412_update_controls(struct imx412 *imx412, in imx412_update_controls() argument
525 ret = __v4l2_ctrl_s_ctrl(imx412->link_freq_ctrl, mode->link_freq_idx); in imx412_update_controls()
529 ret = __v4l2_ctrl_s_ctrl(imx412->hblank_ctrl, mode->hblank); in imx412_update_controls()
533 return __v4l2_ctrl_modify_range(imx412->vblank_ctrl, mode->vblank_min, in imx412_update_controls()
539 * @imx412: pointer to imx412 device
545 static int imx412_update_exp_gain(struct imx412 *imx412, u32 exposure, u32 gain) in imx412_update_exp_gain() argument
550 lpfr = imx412->vblank + imx412->cur_mode->height; in imx412_update_exp_gain()
552 dev_dbg(imx412->dev, "Set exp %u, analog gain %u, lpfr %u\n", in imx412_update_exp_gain()
555 ret = imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 1); in imx412_update_exp_gain()
559 ret = imx412_write_reg(imx412, IMX412_REG_LPFR, 2, lpfr); in imx412_update_exp_gain()
563 ret = imx412_write_reg(imx412, IMX412_REG_EXPOSURE_CIT, 2, exposure); in imx412_update_exp_gain()
567 ret = imx412_write_reg(imx412, IMX412_REG_AGAIN, 2, gain); in imx412_update_exp_gain()
570 imx412_write_reg(imx412, IMX412_REG_HOLD, 1, 0); in imx412_update_exp_gain()
589 struct imx412 *imx412 = in imx412_set_ctrl() local
590 container_of(ctrl->handler, struct imx412, ctrl_handler); in imx412_set_ctrl()
597 imx412->vblank = imx412->vblank_ctrl->val; in imx412_set_ctrl()
599 dev_dbg(imx412->dev, "Received vblank %u, new lpfr %u\n", in imx412_set_ctrl()
600 imx412->vblank, in imx412_set_ctrl()
601 imx412->vblank + imx412->cur_mode->height); in imx412_set_ctrl()
603 ret = __v4l2_ctrl_modify_range(imx412->exp_ctrl, in imx412_set_ctrl()
605 imx412->vblank + in imx412_set_ctrl()
606 imx412->cur_mode->height - in imx412_set_ctrl()
612 if (!pm_runtime_get_if_in_use(imx412->dev)) in imx412_set_ctrl()
616 analog_gain = imx412->again_ctrl->val; in imx412_set_ctrl()
618 dev_dbg(imx412->dev, "Received exp %u, analog gain %u\n", in imx412_set_ctrl()
621 ret = imx412_update_exp_gain(imx412, exposure, analog_gain); in imx412_set_ctrl()
623 pm_runtime_put(imx412->dev); in imx412_set_ctrl()
627 dev_err(imx412->dev, "Invalid control %d\n", ctrl->id); in imx412_set_ctrl()
641 * @sd: pointer to imx412 V4L2 sub-device structure
661 * @sd: pointer to imx412 V4L2 sub-device structure
688 * @imx412: pointer to imx412 device
692 static void imx412_fill_pad_format(struct imx412 *imx412, in imx412_fill_pad_format() argument
708 * @sd: pointer to imx412 V4L2 sub-device structure
718 struct imx412 *imx412 = to_imx412(sd); in imx412_get_pad_format() local
720 mutex_lock(&imx412->mutex); in imx412_get_pad_format()
728 imx412_fill_pad_format(imx412, imx412->cur_mode, fmt); in imx412_get_pad_format()
731 mutex_unlock(&imx412->mutex); in imx412_get_pad_format()
738 * @sd: pointer to imx412 V4L2 sub-device structure
748 struct imx412 *imx412 = to_imx412(sd); in imx412_set_pad_format() local
752 mutex_lock(&imx412->mutex); in imx412_set_pad_format()
755 imx412_fill_pad_format(imx412, mode, fmt); in imx412_set_pad_format()
763 ret = imx412_update_controls(imx412, mode); in imx412_set_pad_format()
765 imx412->cur_mode = mode; in imx412_set_pad_format()
768 mutex_unlock(&imx412->mutex); in imx412_set_pad_format()
775 * @sd: pointer to imx412 V4L2 sub-device structure
783 struct imx412 *imx412 = to_imx412(sd); in imx412_init_pad_cfg() local
787 imx412_fill_pad_format(imx412, &supported_mode, &fmt); in imx412_init_pad_cfg()
794 * @imx412: pointer to imx412 device
798 static int imx412_start_streaming(struct imx412 *imx412) in imx412_start_streaming() argument
804 reg_list = &imx412->cur_mode->reg_list; in imx412_start_streaming()
805 ret = imx412_write_regs(imx412, reg_list->regs, in imx412_start_streaming()
808 dev_err(imx412->dev, "fail to write initial registers\n"); in imx412_start_streaming()
813 ret = __v4l2_ctrl_handler_setup(imx412->sd.ctrl_handler); in imx412_start_streaming()
815 dev_err(imx412->dev, "fail to setup handler\n"); in imx412_start_streaming()
823 ret = imx412_write_reg(imx412, IMX412_REG_MODE_SELECT, in imx412_start_streaming()
826 dev_err(imx412->dev, "fail to start streaming\n"); in imx412_start_streaming()
835 * @imx412: pointer to imx412 device
839 static int imx412_stop_streaming(struct imx412 *imx412) in imx412_stop_streaming() argument
841 return imx412_write_reg(imx412, IMX412_REG_MODE_SELECT, in imx412_stop_streaming()
847 * @sd: pointer to imx412 subdevice
854 struct imx412 *imx412 = to_imx412(sd); in imx412_set_stream() local
857 mutex_lock(&imx412->mutex); in imx412_set_stream()
859 if (imx412->streaming == enable) { in imx412_set_stream()
860 mutex_unlock(&imx412->mutex); in imx412_set_stream()
865 ret = pm_runtime_resume_and_get(imx412->dev); in imx412_set_stream()
869 ret = imx412_start_streaming(imx412); in imx412_set_stream()
873 imx412_stop_streaming(imx412); in imx412_set_stream()
874 pm_runtime_put(imx412->dev); in imx412_set_stream()
877 imx412->streaming = enable; in imx412_set_stream()
879 mutex_unlock(&imx412->mutex); in imx412_set_stream()
884 pm_runtime_put(imx412->dev); in imx412_set_stream()
886 mutex_unlock(&imx412->mutex); in imx412_set_stream()
892 * imx412_detect() - Detect imx412 sensor
893 * @imx412: pointer to imx412 device
897 static int imx412_detect(struct imx412 *imx412) in imx412_detect() argument
902 ret = imx412_read_reg(imx412, IMX412_REG_ID, 2, &val); in imx412_detect()
907 dev_err(imx412->dev, "chip id mismatch: %x!=%x\n", in imx412_detect()
917 * @imx412: pointer to imx412 device
921 static int imx412_parse_hw_config(struct imx412 *imx412) in imx412_parse_hw_config() argument
923 struct fwnode_handle *fwnode = dev_fwnode(imx412->dev); in imx412_parse_hw_config()
936 imx412->reset_gpio = devm_gpiod_get_optional(imx412->dev, "reset", in imx412_parse_hw_config()
938 if (IS_ERR(imx412->reset_gpio)) { in imx412_parse_hw_config()
939 dev_err(imx412->dev, "failed to get reset gpio %ld\n", in imx412_parse_hw_config()
940 PTR_ERR(imx412->reset_gpio)); in imx412_parse_hw_config()
941 return PTR_ERR(imx412->reset_gpio); in imx412_parse_hw_config()
945 imx412->inclk = devm_clk_get(imx412->dev, NULL); in imx412_parse_hw_config()
946 if (IS_ERR(imx412->inclk)) { in imx412_parse_hw_config()
947 dev_err(imx412->dev, "could not get inclk\n"); in imx412_parse_hw_config()
948 return PTR_ERR(imx412->inclk); in imx412_parse_hw_config()
951 rate = clk_get_rate(imx412->inclk); in imx412_parse_hw_config()
953 dev_err(imx412->dev, "inclk frequency mismatch\n"); in imx412_parse_hw_config()
959 imx412->supplies[i].supply = imx412_supply_names[i]; in imx412_parse_hw_config()
961 ret = devm_regulator_bulk_get(imx412->dev, in imx412_parse_hw_config()
963 imx412->supplies); in imx412_parse_hw_config()
977 dev_err(imx412->dev, in imx412_parse_hw_config()
985 dev_err(imx412->dev, "no link frequencies defined\n"); in imx412_parse_hw_config()
1029 struct imx412 *imx412 = to_imx412(sd); in imx412_power_on() local
1033 imx412->supplies); in imx412_power_on()
1039 gpiod_set_value_cansleep(imx412->reset_gpio, 0); in imx412_power_on()
1041 ret = clk_prepare_enable(imx412->inclk); in imx412_power_on()
1043 dev_err(imx412->dev, "fail to enable inclk\n"); in imx412_power_on()
1052 gpiod_set_value_cansleep(imx412->reset_gpio, 1); in imx412_power_on()
1054 imx412->supplies); in imx412_power_on()
1068 struct imx412 *imx412 = to_imx412(sd); in imx412_power_off() local
1070 clk_disable_unprepare(imx412->inclk); in imx412_power_off()
1072 gpiod_set_value_cansleep(imx412->reset_gpio, 1); in imx412_power_off()
1075 imx412->supplies); in imx412_power_off()
1082 * @imx412: pointer to imx412 device
1086 static int imx412_init_controls(struct imx412 *imx412) in imx412_init_controls() argument
1088 struct v4l2_ctrl_handler *ctrl_hdlr = &imx412->ctrl_handler; in imx412_init_controls()
1089 const struct imx412_mode *mode = imx412->cur_mode; in imx412_init_controls()
1098 ctrl_hdlr->lock = &imx412->mutex; in imx412_init_controls()
1102 imx412->exp_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx412_init_controls()
1110 imx412->again_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx412_init_controls()
1118 v4l2_ctrl_cluster(2, &imx412->exp_ctrl); in imx412_init_controls()
1120 imx412->vblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx412_init_controls()
1128 imx412->pclk_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx412_init_controls()
1134 imx412->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr, in imx412_init_controls()
1141 if (imx412->link_freq_ctrl) in imx412_init_controls()
1142 imx412->link_freq_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx412_init_controls()
1144 imx412->hblank_ctrl = v4l2_ctrl_new_std(ctrl_hdlr, in imx412_init_controls()
1150 if (imx412->hblank_ctrl) in imx412_init_controls()
1151 imx412->hblank_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; in imx412_init_controls()
1154 dev_err(imx412->dev, "control init failed: %d\n", in imx412_init_controls()
1160 imx412->sd.ctrl_handler = ctrl_hdlr; in imx412_init_controls()
1173 struct imx412 *imx412; in imx412_probe() local
1177 imx412 = devm_kzalloc(&client->dev, sizeof(*imx412), GFP_KERNEL); in imx412_probe()
1178 if (!imx412) in imx412_probe()
1181 imx412->dev = &client->dev; in imx412_probe()
1187 v4l2_i2c_subdev_init(&imx412->sd, client, &imx412_subdev_ops); in imx412_probe()
1189 ret = imx412_parse_hw_config(imx412); in imx412_probe()
1191 dev_err(imx412->dev, "HW configuration is not supported\n"); in imx412_probe()
1195 mutex_init(&imx412->mutex); in imx412_probe()
1197 ret = imx412_power_on(imx412->dev); in imx412_probe()
1199 dev_err(imx412->dev, "failed to power-on the sensor\n"); in imx412_probe()
1204 ret = imx412_detect(imx412); in imx412_probe()
1206 dev_err(imx412->dev, "failed to find sensor: %d\n", ret); in imx412_probe()
1211 imx412->cur_mode = &supported_mode; in imx412_probe()
1212 imx412->vblank = imx412->cur_mode->vblank; in imx412_probe()
1214 ret = imx412_init_controls(imx412); in imx412_probe()
1216 dev_err(imx412->dev, "failed to init controls: %d\n", ret); in imx412_probe()
1221 imx412->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in imx412_probe()
1222 imx412->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; in imx412_probe()
1224 v4l2_i2c_subdev_set_name(&imx412->sd, client, name, NULL); in imx412_probe()
1227 imx412->pad.flags = MEDIA_PAD_FL_SOURCE; in imx412_probe()
1228 ret = media_entity_pads_init(&imx412->sd.entity, 1, &imx412->pad); in imx412_probe()
1230 dev_err(imx412->dev, "failed to init entity pads: %d\n", ret); in imx412_probe()
1234 ret = v4l2_async_register_subdev_sensor(&imx412->sd); in imx412_probe()
1236 dev_err(imx412->dev, in imx412_probe()
1241 pm_runtime_set_active(imx412->dev); in imx412_probe()
1242 pm_runtime_enable(imx412->dev); in imx412_probe()
1243 pm_runtime_idle(imx412->dev); in imx412_probe()
1248 media_entity_cleanup(&imx412->sd.entity); in imx412_probe()
1250 v4l2_ctrl_handler_free(imx412->sd.ctrl_handler); in imx412_probe()
1252 imx412_power_off(imx412->dev); in imx412_probe()
1254 mutex_destroy(&imx412->mutex); in imx412_probe()
1268 struct imx412 *imx412 = to_imx412(sd); in imx412_remove() local
1279 mutex_destroy(&imx412->mutex); in imx412_remove()
1287 { .compatible = "sony,imx412", .data = "imx412" },
1298 .name = "imx412",
1306 MODULE_DESCRIPTION("Sony imx412 sensor driver");