Lines Matching +full:vaa +full:- +full:supply

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (c) 2020-2023 Laurent Pinchart <laurent.pinchart@ideasonboard.com>
26 #include <media/v4l2-async.h>
27 #include <media/v4l2-cci.h>
28 #include <media/v4l2-ctrls.h>
29 #include <media/v4l2-device.h>
30 #include <media/v4l2-fwnode.h>
31 #include <media/v4l2-mediabus.h>
32 #include <media/v4l2-subdev.h>
75 /* Auto-Exposure Track registers */
342 * These values are not well documented and are semi-arbitrary. The pixel array
357 /* -----------------------------------------------------------------------------
414 /* -----------------------------------------------------------------------------
422 * CSI-2 buses respectively. Keep them in that order.
474 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) in mt9m114_default_format_info()
489 return &mt9m114_format_infos[num_formats - 1]; in mt9m114_format_info()
492 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) in mt9m114_format_info()
501 if (info->code == code && info->flags & flag) in mt9m114_format_info()
512 /* -----------------------------------------------------------------------------
592 /* Low-Light Image Enhancements */
630 /* Auto-Exposure */
651 /* -----------------------------------------------------------------------------
663 ret = cci_read(sensor->regmap, MT9M114_COMMAND_REGISTER, &value, in mt9m114_poll_command()
675 dev_err(&sensor->client->dev, "Command %u completion timeout\n", in mt9m114_poll_command()
677 return -ETIMEDOUT; in mt9m114_poll_command()
681 dev_err(&sensor->client->dev, "Command %u failed\n", command); in mt9m114_poll_command()
682 return -EIO; in mt9m114_poll_command()
696 ret = cci_read(sensor->regmap, MT9M114_SYSMGR_CURRENT_STATE, in mt9m114_poll_state()
707 dev_err(&sensor->client->dev, "Timeout waiting for state 0x%02x\n", in mt9m114_poll_state()
709 return -ETIMEDOUT; in mt9m114_poll_state()
717 cci_write(sensor->regmap, MT9M114_SYSMGR_NEXT_STATE, next_state, &ret); in mt9m114_set_state()
718 cci_write(sensor->regmap, MT9M114_COMMAND_REGISTER, in mt9m114_set_state()
737 ret = cci_multi_reg_write(sensor->regmap, mt9m114_init, in mt9m114_initialize()
740 dev_err(&sensor->client->dev, in mt9m114_initialize()
746 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE, in mt9m114_initialize()
748 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N, in mt9m114_initialize()
749 MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m, in mt9m114_initialize()
750 sensor->pll.n), in mt9m114_initialize()
752 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P, in mt9m114_initialize()
753 MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p), &ret); in mt9m114_initialize()
754 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_PIXCLK, in mt9m114_initialize()
755 sensor->pixrate, &ret); in mt9m114_initialize()
758 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) { in mt9m114_initialize()
762 if (!(sensor->bus_cfg.bus.mipi_csi2.flags & in mt9m114_initialize()
769 cci_write(sensor->regmap, MT9M114_CAM_PORT_OUTPUT_CONTROL, value, &ret); in mt9m114_initialize()
803 ifp_info = mt9m114_format_info(sensor, 1, ifp_format->code); in mt9m114_configure()
807 ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, in mt9m114_configure()
812 ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, in mt9m114_configure()
817 hratio = pa_crop->width / pa_format->width; in mt9m114_configure()
818 vratio = pa_crop->height / pa_format->height; in mt9m114_configure()
826 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_START, in mt9m114_configure()
827 pa_crop->left, &ret); in mt9m114_configure()
828 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START, in mt9m114_configure()
829 pa_crop->top, &ret); in mt9m114_configure()
830 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_END, in mt9m114_configure()
831 pa_crop->width + pa_crop->left - 1, &ret); in mt9m114_configure()
832 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_END, in mt9m114_configure()
833 pa_crop->height + pa_crop->top - 1, &ret); in mt9m114_configure()
834 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW, in mt9m114_configure()
835 (pa_crop->height - 4) / vratio - 1, &ret); in mt9m114_configure()
845 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, in mt9m114_configure()
854 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_XOFFSET, in mt9m114_configure()
855 ifp_crop->left - 4, &ret); in mt9m114_configure()
856 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_YOFFSET, in mt9m114_configure()
857 ifp_crop->top - 4, &ret); in mt9m114_configure()
858 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_WIDTH, in mt9m114_configure()
859 ifp_crop->width, &ret); in mt9m114_configure()
860 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_HEIGHT, in mt9m114_configure()
861 ifp_crop->height, &ret); in mt9m114_configure()
863 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_WIDTH, in mt9m114_configure()
864 ifp_compose->width, &ret); in mt9m114_configure()
865 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_HEIGHT, in mt9m114_configure()
866 ifp_compose->height, &ret); in mt9m114_configure()
869 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART, in mt9m114_configure()
871 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART, in mt9m114_configure()
873 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND, in mt9m114_configure()
874 ifp_compose->width - 1, &ret); in mt9m114_configure()
875 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND, in mt9m114_configure()
876 ifp_compose->height - 1, &ret); in mt9m114_configure()
878 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART, in mt9m114_configure()
880 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART, in mt9m114_configure()
882 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND, in mt9m114_configure()
883 ifp_compose->width / 5 - 1, &ret); in mt9m114_configure()
884 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND, in mt9m114_configure()
885 ifp_compose->height / 5 - 1, &ret); in mt9m114_configure()
887 cci_write(sensor->regmap, MT9M114_CAM_CROP_CROPMODE, in mt9m114_configure()
897 output_format |= ifp_info->output_format; in mt9m114_configure()
899 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, in mt9m114_configure()
907 u16 frame_rate = sensor->ifp.frame_rate << 8; in mt9m114_set_frame_rate()
910 cci_write(sensor->regmap, MT9M114_CAM_AET_MIN_FRAME_RATE, in mt9m114_set_frame_rate()
912 cci_write(sensor->regmap, MT9M114_CAM_AET_MAX_FRAME_RATE, in mt9m114_set_frame_rate()
924 ret = pm_runtime_resume_and_get(&sensor->client->dev); in mt9m114_start_streaming()
936 ret = __v4l2_ctrl_handler_setup(&sensor->pa.hdl); in mt9m114_start_streaming()
940 ret = __v4l2_ctrl_handler_setup(&sensor->ifp.hdl); in mt9m114_start_streaming()
945 * The Change-Config state is transient and moves to the streaming in mt9m114_start_streaming()
952 sensor->streaming = true; in mt9m114_start_streaming()
957 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_start_streaming()
958 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_start_streaming()
967 sensor->streaming = false; in mt9m114_stop_streaming()
971 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_stop_streaming()
972 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_stop_streaming()
977 /* -----------------------------------------------------------------------------
985 /* -----------------------------------------------------------------------------
991 return container_of(ctrl->handler, struct mt9m114, pa.hdl); in pa_ctrl_to_mt9m114()
1000 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) in mt9m114_pa_g_ctrl()
1003 switch (ctrl->id) { in mt9m114_pa_g_ctrl()
1005 ret = cci_read(sensor->regmap, in mt9m114_pa_g_ctrl()
1011 ctrl->val = value; in mt9m114_pa_g_ctrl()
1015 ret = cci_read(sensor->regmap, in mt9m114_pa_g_ctrl()
1021 ctrl->val = value; in mt9m114_pa_g_ctrl()
1025 ret = -EINVAL; in mt9m114_pa_g_ctrl()
1029 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_pa_g_ctrl()
1030 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_pa_g_ctrl()
1044 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) in mt9m114_pa_s_ctrl()
1047 state = v4l2_subdev_get_locked_active_state(&sensor->pa.sd); in mt9m114_pa_s_ctrl()
1050 switch (ctrl->id) { in mt9m114_pa_s_ctrl()
1052 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK, in mt9m114_pa_s_ctrl()
1053 ctrl->val + format->width, &ret); in mt9m114_pa_s_ctrl()
1057 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES, in mt9m114_pa_s_ctrl()
1058 ctrl->val + format->height, &ret); in mt9m114_pa_s_ctrl()
1062 cci_write(sensor->regmap, in mt9m114_pa_s_ctrl()
1064 ctrl->val, &ret); in mt9m114_pa_s_ctrl()
1073 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN, in mt9m114_pa_s_ctrl()
1074 ctrl->val, &ret); in mt9m114_pa_s_ctrl()
1079 ret = cci_update_bits(sensor->regmap, in mt9m114_pa_s_ctrl()
1081 mask, ctrl->val ? mask : 0, NULL); in mt9m114_pa_s_ctrl()
1086 ret = cci_update_bits(sensor->regmap, in mt9m114_pa_s_ctrl()
1088 mask, ctrl->val ? mask : 0, NULL); in mt9m114_pa_s_ctrl()
1092 ret = -EINVAL; in mt9m114_pa_s_ctrl()
1096 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_pa_s_ctrl()
1097 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_pa_s_ctrl()
1116 mt9m114_pa_g_ctrl(sensor->pa.exposure); in mt9m114_pa_ctrl_update_exposure()
1117 sensor->pa.exposure->cur.val = sensor->pa.exposure->val; in mt9m114_pa_ctrl_update_exposure()
1118 sensor->pa.exposure->flags &= ~V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1120 mt9m114_pa_g_ctrl(sensor->pa.gain); in mt9m114_pa_ctrl_update_exposure()
1121 sensor->pa.gain->cur.val = sensor->pa.gain->val; in mt9m114_pa_ctrl_update_exposure()
1122 sensor->pa.gain->flags &= ~V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1124 sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1125 sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1136 - format->width; in mt9m114_pa_ctrl_update_blanking()
1137 __v4l2_ctrl_modify_range(sensor->pa.hblank, MT9M114_MIN_HBLANK, in mt9m114_pa_ctrl_update_blanking()
1141 - format->height; in mt9m114_pa_ctrl_update_blanking()
1142 __v4l2_ctrl_modify_range(sensor->pa.vblank, MT9M114_MIN_VBLANK, in mt9m114_pa_ctrl_update_blanking()
1146 /* -----------------------------------------------------------------------------
1163 crop->left = 0; in mt9m114_pa_init_state()
1164 crop->top = 0; in mt9m114_pa_init_state()
1165 crop->width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_pa_init_state()
1166 crop->height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_pa_init_state()
1170 format->width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_pa_init_state()
1171 format->height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_pa_init_state()
1172 format->code = MEDIA_BUS_FMT_SGRBG10_1X10; in mt9m114_pa_init_state()
1173 format->field = V4L2_FIELD_NONE; in mt9m114_pa_init_state()
1174 format->colorspace = V4L2_COLORSPACE_RAW; in mt9m114_pa_init_state()
1175 format->ycbcr_enc = V4L2_YCBCR_ENC_601; in mt9m114_pa_init_state()
1176 format->quantization = V4L2_QUANTIZATION_FULL_RANGE; in mt9m114_pa_init_state()
1177 format->xfer_func = V4L2_XFER_FUNC_NONE; in mt9m114_pa_init_state()
1186 if (code->index > 0) in mt9m114_pa_enum_mbus_code()
1187 return -EINVAL; in mt9m114_pa_enum_mbus_code()
1189 code->code = MEDIA_BUS_FMT_SGRBG10_1X10; in mt9m114_pa_enum_mbus_code()
1198 if (fse->index > 1) in mt9m114_pa_enum_framesizes()
1199 return -EINVAL; in mt9m114_pa_enum_framesizes()
1201 if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) in mt9m114_pa_enum_framesizes()
1202 return -EINVAL; in mt9m114_pa_enum_framesizes()
1205 fse->min_width = MT9M114_PIXEL_ARRAY_WIDTH / (fse->index + 1); in mt9m114_pa_enum_framesizes()
1206 fse->max_width = MT9M114_PIXEL_ARRAY_WIDTH / (fse->index + 1); in mt9m114_pa_enum_framesizes()
1207 fse->min_height = MT9M114_PIXEL_ARRAY_HEIGHT / (fse->index + 1); in mt9m114_pa_enum_framesizes()
1208 fse->max_height = MT9M114_PIXEL_ARRAY_HEIGHT / (fse->index + 1); in mt9m114_pa_enum_framesizes()
1223 crop = v4l2_subdev_state_get_crop(state, fmt->pad); in mt9m114_pa_set_fmt()
1224 format = v4l2_subdev_state_get_format(state, fmt->pad); in mt9m114_pa_set_fmt()
1227 hscale = DIV_ROUND_CLOSEST(crop->width, fmt->format.width ? : 1); in mt9m114_pa_set_fmt()
1228 vscale = DIV_ROUND_CLOSEST(crop->height, fmt->format.height ? : 1); in mt9m114_pa_set_fmt()
1229 format->width = crop->width / clamp(hscale, 1U, 2U); in mt9m114_pa_set_fmt()
1230 format->height = crop->height / clamp(vscale, 1U, 2U); in mt9m114_pa_set_fmt()
1232 fmt->format = *format; in mt9m114_pa_set_fmt()
1234 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) in mt9m114_pa_set_fmt()
1244 switch (sel->target) { in mt9m114_pa_get_selection()
1246 sel->r = *v4l2_subdev_state_get_crop(state, sel->pad); in mt9m114_pa_get_selection()
1252 sel->r.left = 0; in mt9m114_pa_get_selection()
1253 sel->r.top = 0; in mt9m114_pa_get_selection()
1254 sel->r.width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_pa_get_selection()
1255 sel->r.height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_pa_get_selection()
1259 return -EINVAL; in mt9m114_pa_get_selection()
1271 if (sel->target != V4L2_SEL_TGT_CROP) in mt9m114_pa_set_selection()
1272 return -EINVAL; in mt9m114_pa_set_selection()
1274 crop = v4l2_subdev_state_get_crop(state, sel->pad); in mt9m114_pa_set_selection()
1275 format = v4l2_subdev_state_get_format(state, sel->pad); in mt9m114_pa_set_selection()
1285 crop->left = ALIGN(sel->r.left, 4); in mt9m114_pa_set_selection()
1286 crop->top = ALIGN(sel->r.top, 2); in mt9m114_pa_set_selection()
1287 crop->width = clamp_t(unsigned int, ALIGN(sel->r.width, 4), in mt9m114_pa_set_selection()
1289 MT9M114_PIXEL_ARRAY_WIDTH - crop->left); in mt9m114_pa_set_selection()
1290 crop->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), in mt9m114_pa_set_selection()
1292 MT9M114_PIXEL_ARRAY_HEIGHT - crop->top); in mt9m114_pa_set_selection()
1294 sel->r = *crop; in mt9m114_pa_set_selection()
1297 format->width = crop->width; in mt9m114_pa_set_selection()
1298 format->height = crop->height; in mt9m114_pa_set_selection()
1300 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) in mt9m114_pa_set_selection()
1325 struct v4l2_ctrl_handler *hdl = &sensor->pa.hdl; in mt9m114_pa_init()
1326 struct v4l2_subdev *sd = &sensor->pa.sd; in mt9m114_pa_init()
1327 struct media_pad *pads = &sensor->pa.pad; in mt9m114_pa_init()
1335 sd->internal_ops = &mt9m114_pa_internal_ops; in mt9m114_pa_init()
1336 v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " pixel array"); in mt9m114_pa_init()
1338 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in mt9m114_pa_init()
1339 sd->owner = THIS_MODULE; in mt9m114_pa_init()
1340 sd->dev = &sensor->client->dev; in mt9m114_pa_init()
1341 v4l2_set_subdevdata(sd, sensor->client); in mt9m114_pa_init()
1344 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; in mt9m114_pa_init()
1345 sd->entity.ops = &mt9m114_entity_ops; in mt9m114_pa_init()
1347 ret = media_entity_pads_init(&sd->entity, 1, pads); in mt9m114_pa_init()
1355 sensor->pa.hblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1360 sensor->pa.vblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1369 * makes little sense as auto-exposure is enabled by default. in mt9m114_pa_init()
1371 max_exposure = MT9M114_PIXEL_ARRAY_HEIGHT + MT9M114_MIN_VBLANK - 2; in mt9m114_pa_init()
1372 sensor->pa.exposure = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1375 if (sensor->pa.exposure) in mt9m114_pa_init()
1376 sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_init()
1378 sensor->pa.gain = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1381 if (sensor->pa.gain) in mt9m114_pa_init()
1382 sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_init()
1386 sensor->pixrate, sensor->pixrate, 1, in mt9m114_pa_init()
1387 sensor->pixrate); in mt9m114_pa_init()
1396 if (hdl->error) { in mt9m114_pa_init()
1397 ret = hdl->error; in mt9m114_pa_init()
1401 sd->state_lock = hdl->lock; in mt9m114_pa_init()
1413 sd->ctrl_handler = hdl; in mt9m114_pa_init()
1418 v4l2_ctrl_handler_free(&sensor->pa.hdl); in mt9m114_pa_init()
1419 media_entity_cleanup(&sensor->pa.sd.entity); in mt9m114_pa_init()
1425 v4l2_ctrl_handler_free(&sensor->pa.hdl); in mt9m114_pa_cleanup()
1426 media_entity_cleanup(&sensor->pa.sd.entity); in mt9m114_pa_cleanup()
1429 /* -----------------------------------------------------------------------------
1437 "Pseudo-Random",
1438 "Fade-to-Gray Color Bars",
1439 "Walking Ones 10-bit",
1440 "Walking Ones 8-bit",
1455 return container_of(ctrl->handler, struct mt9m114, ifp.hdl); in ifp_ctrl_to_mt9m114()
1464 if (ctrl->id == V4L2_CID_EXPOSURE_AUTO) in mt9m114_ifp_s_ctrl()
1466 ctrl->val != V4L2_EXPOSURE_AUTO); in mt9m114_ifp_s_ctrl()
1469 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) in mt9m114_ifp_s_ctrl()
1472 switch (ctrl->id) { in mt9m114_ifp_s_ctrl()
1475 if (ctrl->val) in mt9m114_ifp_s_ctrl()
1481 cci_write(sensor->regmap, MT9M114_CAM_AWB_AWBMODE, value, &ret); in mt9m114_ifp_s_ctrl()
1483 if (ctrl->val) in mt9m114_ifp_s_ctrl()
1488 cci_write(sensor->regmap, MT9M114_CCM_ALGO, value, &ret); in mt9m114_ifp_s_ctrl()
1492 if (ctrl->val == V4L2_EXPOSURE_AUTO) in mt9m114_ifp_s_ctrl()
1498 cci_write(sensor->regmap, MT9M114_AE_TRACK_ALGO, value, &ret); in mt9m114_ifp_s_ctrl()
1508 unsigned int pattern = sensor->ifp.tpg[MT9M114_TPG_PATTERN]->val; in mt9m114_ifp_s_ctrl()
1511 cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, in mt9m114_ifp_s_ctrl()
1513 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1515 mt9m114_test_pattern_value[pattern - 1], &ret); in mt9m114_ifp_s_ctrl()
1516 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1518 sensor->ifp.tpg[MT9M114_TPG_RED]->val, &ret); in mt9m114_ifp_s_ctrl()
1519 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1521 sensor->ifp.tpg[MT9M114_TPG_GREEN]->val, &ret); in mt9m114_ifp_s_ctrl()
1522 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1524 sensor->ifp.tpg[MT9M114_TPG_BLUE]->val, &ret); in mt9m114_ifp_s_ctrl()
1526 cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, in mt9m114_ifp_s_ctrl()
1531 * A Config-Change needs to be issued for the change to take in mt9m114_ifp_s_ctrl()
1535 if (ret || !sensor->streaming) in mt9m114_ifp_s_ctrl()
1544 ret = -EINVAL; in mt9m114_ifp_s_ctrl()
1548 pm_runtime_mark_last_busy(&sensor->client->dev); in mt9m114_ifp_s_ctrl()
1549 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_ifp_s_ctrl()
1558 /* -----------------------------------------------------------------------------
1577 ifp_state = v4l2_subdev_lock_and_get_active_state(&sensor->ifp.sd); in mt9m114_ifp_s_stream()
1578 pa_state = v4l2_subdev_lock_and_get_active_state(&sensor->pa.sd); in mt9m114_ifp_s_stream()
1592 struct v4l2_fract *ival = &interval->interval; in mt9m114_ifp_get_frame_interval()
1599 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) in mt9m114_ifp_get_frame_interval()
1600 return -EINVAL; in mt9m114_ifp_get_frame_interval()
1602 mutex_lock(sensor->ifp.hdl.lock); in mt9m114_ifp_get_frame_interval()
1604 ival->numerator = 1; in mt9m114_ifp_get_frame_interval()
1605 ival->denominator = sensor->ifp.frame_rate; in mt9m114_ifp_get_frame_interval()
1607 mutex_unlock(sensor->ifp.hdl.lock); in mt9m114_ifp_get_frame_interval()
1616 struct v4l2_fract *ival = &interval->interval; in mt9m114_ifp_set_frame_interval()
1624 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) in mt9m114_ifp_set_frame_interval()
1625 return -EINVAL; in mt9m114_ifp_set_frame_interval()
1627 mutex_lock(sensor->ifp.hdl.lock); in mt9m114_ifp_set_frame_interval()
1629 if (ival->numerator != 0 && ival->denominator != 0) in mt9m114_ifp_set_frame_interval()
1630 sensor->ifp.frame_rate = min_t(unsigned int, in mt9m114_ifp_set_frame_interval()
1631 ival->denominator / ival->numerator, in mt9m114_ifp_set_frame_interval()
1634 sensor->ifp.frame_rate = MT9M114_MAX_FRAME_RATE; in mt9m114_ifp_set_frame_interval()
1636 ival->numerator = 1; in mt9m114_ifp_set_frame_interval()
1637 ival->denominator = sensor->ifp.frame_rate; in mt9m114_ifp_set_frame_interval()
1639 if (sensor->streaming) in mt9m114_ifp_set_frame_interval()
1642 mutex_unlock(sensor->ifp.hdl.lock); in mt9m114_ifp_set_frame_interval()
1657 format->width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_ifp_init_state()
1658 format->height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_ifp_init_state()
1659 format->code = MEDIA_BUS_FMT_SGRBG10_1X10; in mt9m114_ifp_init_state()
1660 format->field = V4L2_FIELD_NONE; in mt9m114_ifp_init_state()
1661 format->colorspace = V4L2_COLORSPACE_RAW; in mt9m114_ifp_init_state()
1662 format->ycbcr_enc = V4L2_YCBCR_ENC_601; in mt9m114_ifp_init_state()
1663 format->quantization = V4L2_QUANTIZATION_FULL_RANGE; in mt9m114_ifp_init_state()
1664 format->xfer_func = V4L2_XFER_FUNC_NONE; in mt9m114_ifp_init_state()
1668 crop->left = 4; in mt9m114_ifp_init_state()
1669 crop->top = 4; in mt9m114_ifp_init_state()
1670 crop->width = format->width - 8; in mt9m114_ifp_init_state()
1671 crop->height = format->height - 8; in mt9m114_ifp_init_state()
1675 compose->left = 0; in mt9m114_ifp_init_state()
1676 compose->top = 0; in mt9m114_ifp_init_state()
1677 compose->width = crop->width; in mt9m114_ifp_init_state()
1678 compose->height = crop->height; in mt9m114_ifp_init_state()
1682 format->width = compose->width; in mt9m114_ifp_init_state()
1683 format->height = compose->height; in mt9m114_ifp_init_state()
1684 format->code = mt9m114_default_format_info(sensor)->code; in mt9m114_ifp_init_state()
1685 format->field = V4L2_FIELD_NONE; in mt9m114_ifp_init_state()
1686 format->colorspace = V4L2_COLORSPACE_SRGB; in mt9m114_ifp_init_state()
1687 format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in mt9m114_ifp_init_state()
1688 format->quantization = V4L2_QUANTIZATION_DEFAULT; in mt9m114_ifp_init_state()
1689 format->xfer_func = V4L2_XFER_FUNC_DEFAULT; in mt9m114_ifp_init_state()
1704 switch (code->pad) { in mt9m114_ifp_enum_mbus_code()
1706 if (code->index != 0) in mt9m114_ifp_enum_mbus_code()
1707 return -EINVAL; in mt9m114_ifp_enum_mbus_code()
1709 code->code = mt9m114_format_infos[num_formats - 1].code; in mt9m114_ifp_enum_mbus_code()
1713 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) in mt9m114_ifp_enum_mbus_code()
1722 if (info->flags & flag) { in mt9m114_ifp_enum_mbus_code()
1723 if (index == code->index) { in mt9m114_ifp_enum_mbus_code()
1724 code->code = info->code; in mt9m114_ifp_enum_mbus_code()
1732 return -EINVAL; in mt9m114_ifp_enum_mbus_code()
1735 return -EINVAL; in mt9m114_ifp_enum_mbus_code()
1746 if (fse->index > 0) in mt9m114_ifp_enum_framesizes()
1747 return -EINVAL; in mt9m114_ifp_enum_framesizes()
1749 info = mt9m114_format_info(sensor, fse->pad, fse->code); in mt9m114_ifp_enum_framesizes()
1750 if (!info || info->code != fse->code) in mt9m114_ifp_enum_framesizes()
1751 return -EINVAL; in mt9m114_ifp_enum_framesizes()
1753 if (fse->pad == 0) { in mt9m114_ifp_enum_framesizes()
1754 fse->min_width = MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH; in mt9m114_ifp_enum_framesizes()
1755 fse->max_width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_ifp_enum_framesizes()
1756 fse->min_height = MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT; in mt9m114_ifp_enum_framesizes()
1757 fse->max_height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_ifp_enum_framesizes()
1763 fse->max_width = crop->width; in mt9m114_ifp_enum_framesizes()
1764 fse->max_height = crop->height; in mt9m114_ifp_enum_framesizes()
1766 fse->min_width = fse->max_width / 4; in mt9m114_ifp_enum_framesizes()
1767 fse->min_height = fse->max_height / 4; in mt9m114_ifp_enum_framesizes()
1780 if (fie->index > 0) in mt9m114_ifp_enum_frameintervals()
1781 return -EINVAL; in mt9m114_ifp_enum_frameintervals()
1783 info = mt9m114_format_info(sensor, fie->pad, fie->code); in mt9m114_ifp_enum_frameintervals()
1784 if (!info || info->code != fie->code) in mt9m114_ifp_enum_frameintervals()
1785 return -EINVAL; in mt9m114_ifp_enum_frameintervals()
1787 fie->interval.numerator = 1; in mt9m114_ifp_enum_frameintervals()
1788 fie->interval.denominator = MT9M114_MAX_FRAME_RATE; in mt9m114_ifp_enum_frameintervals()
1800 format = v4l2_subdev_state_get_format(state, fmt->pad); in mt9m114_ifp_set_fmt()
1802 if (fmt->pad == 0) { in mt9m114_ifp_set_fmt()
1804 format->width = clamp(ALIGN(fmt->format.width, 8), in mt9m114_ifp_set_fmt()
1807 format->height = clamp(ALIGN(fmt->format.height, 8), in mt9m114_ifp_set_fmt()
1814 info = mt9m114_format_info(sensor, 1, fmt->format.code); in mt9m114_ifp_set_fmt()
1816 format->code = info->code; in mt9m114_ifp_set_fmt()
1819 if (format->code == MEDIA_BUS_FMT_SGRBG10_1X10) in mt9m114_ifp_set_fmt()
1823 fmt->format = *format; in mt9m114_ifp_set_fmt()
1837 if (sel->pad != 0) in mt9m114_ifp_get_selection()
1838 return -EINVAL; in mt9m114_ifp_get_selection()
1840 switch (sel->target) { in mt9m114_ifp_get_selection()
1842 sel->r = *v4l2_subdev_state_get_crop(state, 0); in mt9m114_ifp_get_selection()
1853 sel->r.left = 4; in mt9m114_ifp_get_selection()
1854 sel->r.top = 4; in mt9m114_ifp_get_selection()
1855 sel->r.width = format->width - 8; in mt9m114_ifp_get_selection()
1856 sel->r.height = format->height - 8; in mt9m114_ifp_get_selection()
1860 sel->r = *v4l2_subdev_state_get_compose(state, 0); in mt9m114_ifp_get_selection()
1870 sel->r.left = 0; in mt9m114_ifp_get_selection()
1871 sel->r.top = 0; in mt9m114_ifp_get_selection()
1872 sel->r.width = crop->width; in mt9m114_ifp_get_selection()
1873 sel->r.height = crop->height; in mt9m114_ifp_get_selection()
1877 ret = -EINVAL; in mt9m114_ifp_get_selection()
1892 if (sel->target != V4L2_SEL_TGT_CROP && in mt9m114_ifp_set_selection()
1893 sel->target != V4L2_SEL_TGT_COMPOSE) in mt9m114_ifp_set_selection()
1894 return -EINVAL; in mt9m114_ifp_set_selection()
1897 if (sel->pad != 0) in mt9m114_ifp_set_selection()
1898 return -EINVAL; in mt9m114_ifp_set_selection()
1904 if (sel->target == V4L2_SEL_TGT_CROP) { in mt9m114_ifp_set_selection()
1909 crop->left = clamp_t(unsigned int, ALIGN(sel->r.left, 2), 4, in mt9m114_ifp_set_selection()
1910 format->width - 4 - in mt9m114_ifp_set_selection()
1912 crop->top = clamp_t(unsigned int, ALIGN(sel->r.top, 2), 4, in mt9m114_ifp_set_selection()
1913 format->height - 4 - in mt9m114_ifp_set_selection()
1915 crop->width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), in mt9m114_ifp_set_selection()
1917 format->width - 4 - crop->left); in mt9m114_ifp_set_selection()
1918 crop->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), in mt9m114_ifp_set_selection()
1920 format->height - 4 - crop->top); in mt9m114_ifp_set_selection()
1922 sel->r = *crop; in mt9m114_ifp_set_selection()
1925 compose->width = crop->width; in mt9m114_ifp_set_selection()
1926 compose->height = crop->height; in mt9m114_ifp_set_selection()
1931 compose->left = 0; in mt9m114_ifp_set_selection()
1932 compose->top = 0; in mt9m114_ifp_set_selection()
1933 compose->width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), in mt9m114_ifp_set_selection()
1935 crop->width); in mt9m114_ifp_set_selection()
1936 compose->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), in mt9m114_ifp_set_selection()
1938 crop->height); in mt9m114_ifp_set_selection()
1940 sel->r = *compose; in mt9m114_ifp_set_selection()
1945 format->width = compose->width; in mt9m114_ifp_set_selection()
1946 format->height = compose->height; in mt9m114_ifp_set_selection()
1955 v4l2_device_unregister_subdev(&sensor->pa.sd); in mt9m114_ifp_unregistered()
1963 ret = v4l2_device_register_subdev(sd->v4l2_dev, &sensor->pa.sd); in mt9m114_ifp_registered()
1965 dev_err(&sensor->client->dev, in mt9m114_ifp_registered()
1970 ret = media_create_pad_link(&sensor->pa.sd.entity, 0, in mt9m114_ifp_registered()
1971 &sensor->ifp.sd.entity, 0, in mt9m114_ifp_registered()
1975 dev_err(&sensor->client->dev, in mt9m114_ifp_registered()
1977 v4l2_device_unregister_subdev(&sensor->pa.sd); in mt9m114_ifp_registered()
2013 struct v4l2_subdev *sd = &sensor->ifp.sd; in mt9m114_ifp_init()
2014 struct media_pad *pads = sensor->ifp.pads; in mt9m114_ifp_init()
2015 struct v4l2_ctrl_handler *hdl = &sensor->ifp.hdl; in mt9m114_ifp_init()
2020 v4l2_i2c_subdev_init(sd, sensor->client, &mt9m114_ifp_ops); in mt9m114_ifp_init()
2021 v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " ifp"); in mt9m114_ifp_init()
2023 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in mt9m114_ifp_init()
2024 sd->internal_ops = &mt9m114_ifp_internal_ops; in mt9m114_ifp_init()
2027 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_ISP; in mt9m114_ifp_init()
2028 sd->entity.ops = &mt9m114_entity_ops; in mt9m114_ifp_init()
2031 ret = media_entity_pads_init(&sd->entity, 2, pads); in mt9m114_ifp_init()
2035 sensor->ifp.frame_rate = MT9M114_DEF_FRAME_RATE; in mt9m114_ifp_init()
2049 sensor->bus_cfg.nr_of_link_frequencies - 1, in mt9m114_ifp_init()
2050 0, sensor->bus_cfg.link_frequencies); in mt9m114_ifp_init()
2052 link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in mt9m114_ifp_init()
2056 sensor->pixrate, sensor->pixrate, 1, in mt9m114_ifp_init()
2057 sensor->pixrate); in mt9m114_ifp_init()
2059 sensor->ifp.tpg[MT9M114_TPG_PATTERN] = in mt9m114_ifp_init()
2062 ARRAY_SIZE(mt9m114_test_pattern_menu) - 1, in mt9m114_ifp_init()
2064 sensor->ifp.tpg[MT9M114_TPG_RED] = in mt9m114_ifp_init()
2068 sensor->ifp.tpg[MT9M114_TPG_GREEN] = in mt9m114_ifp_init()
2072 sensor->ifp.tpg[MT9M114_TPG_BLUE] = in mt9m114_ifp_init()
2077 v4l2_ctrl_cluster(ARRAY_SIZE(sensor->ifp.tpg), sensor->ifp.tpg); in mt9m114_ifp_init()
2079 if (hdl->error) { in mt9m114_ifp_init()
2080 ret = hdl->error; in mt9m114_ifp_init()
2084 sd->ctrl_handler = hdl; in mt9m114_ifp_init()
2085 sd->state_lock = hdl->lock; in mt9m114_ifp_init()
2094 v4l2_ctrl_handler_free(&sensor->ifp.hdl); in mt9m114_ifp_init()
2095 media_entity_cleanup(&sensor->ifp.sd.entity); in mt9m114_ifp_init()
2101 v4l2_ctrl_handler_free(&sensor->ifp.hdl); in mt9m114_ifp_cleanup()
2102 media_entity_cleanup(&sensor->ifp.sd.entity); in mt9m114_ifp_cleanup()
2105 /* -----------------------------------------------------------------------------
2114 ret = regulator_bulk_enable(ARRAY_SIZE(sensor->supplies), in mt9m114_power_on()
2115 sensor->supplies); in mt9m114_power_on()
2119 ret = clk_prepare_enable(sensor->clk); in mt9m114_power_on()
2124 if (sensor->reset) { in mt9m114_power_on()
2125 long freq = clk_get_rate(sensor->clk); in mt9m114_power_on()
2134 gpiod_set_value(sensor->reset, 1); in mt9m114_power_on()
2136 gpiod_set_value(sensor->reset, 0); in mt9m114_power_on()
2144 cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, in mt9m114_power_on()
2146 cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, 0, in mt9m114_power_on()
2150 dev_err(&sensor->client->dev, "Soft reset failed\n"); in mt9m114_power_on()
2165 if (sensor->bus_cfg.bus_type == V4L2_MBUS_PARALLEL) { in mt9m114_power_on()
2178 * Before issuing any Set-State command, we must ensure that the sensor in mt9m114_power_on()
2189 clk_disable_unprepare(sensor->clk); in mt9m114_power_on()
2191 regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); in mt9m114_power_on()
2197 clk_disable_unprepare(sensor->clk); in mt9m114_power_off()
2198 regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); in mt9m114_power_off()
2234 /* -----------------------------------------------------------------------------
2243 sensor->pll.m = 32; in mt9m114_clk_init()
2244 sensor->pll.n = 1; in mt9m114_clk_init()
2245 sensor->pll.p = 7; in mt9m114_clk_init()
2248 * Calculate the pixel rate and link frequency. The CSI-2 bus is clocked in mt9m114_clk_init()
2249 * for 16-bit per pixel, transmitted in DDR over a single lane. For in mt9m114_clk_init()
2252 sensor->pixrate = clk_get_rate(sensor->clk) * sensor->pll.m in mt9m114_clk_init()
2253 / ((sensor->pll.n + 1) * (sensor->pll.p + 1)); in mt9m114_clk_init()
2255 link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY in mt9m114_clk_init()
2256 ? sensor->pixrate * 8 : sensor->pixrate * 2; in mt9m114_clk_init()
2258 if (sensor->bus_cfg.nr_of_link_frequencies != 1 || in mt9m114_clk_init()
2259 sensor->bus_cfg.link_frequencies[0] != link_freq) { in mt9m114_clk_init()
2260 dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n"); in mt9m114_clk_init()
2261 return -EINVAL; in mt9m114_clk_init()
2273 ret = cci_read(sensor->regmap, MT9M114_CHIP_ID, &value, NULL); in mt9m114_identify()
2275 dev_err(&sensor->client->dev, "Failed to read chip ID\n"); in mt9m114_identify()
2276 return -ENXIO; in mt9m114_identify()
2280 dev_err(&sensor->client->dev, "Invalid chip ID 0x%04llx\n", in mt9m114_identify()
2282 return -ENXIO; in mt9m114_identify()
2285 cci_read(sensor->regmap, MT9M114_MON_MAJOR_VERSION, &major, &ret); in mt9m114_identify()
2286 cci_read(sensor->regmap, MT9M114_MON_MINOR_VERSION, &minor, &ret); in mt9m114_identify()
2287 cci_read(sensor->regmap, MT9M114_MON_RELEASE_VERSION, &release, &ret); in mt9m114_identify()
2288 cci_read(sensor->regmap, MT9M114_CUSTOMER_REV, &customer, &ret); in mt9m114_identify()
2290 dev_err(&sensor->client->dev, "Failed to read version\n"); in mt9m114_identify()
2291 return -ENXIO; in mt9m114_identify()
2294 dev_dbg(&sensor->client->dev, in mt9m114_identify()
2303 struct fwnode_handle *fwnode = dev_fwnode(&sensor->client->dev); in mt9m114_parse_dt()
2309 dev_err(&sensor->client->dev, "No endpoint found\n"); in mt9m114_parse_dt()
2310 return -EINVAL; in mt9m114_parse_dt()
2313 sensor->bus_cfg.bus_type = V4L2_MBUS_UNKNOWN; in mt9m114_parse_dt()
2314 ret = v4l2_fwnode_endpoint_alloc_parse(ep, &sensor->bus_cfg); in mt9m114_parse_dt()
2317 dev_err(&sensor->client->dev, "Failed to parse endpoint\n"); in mt9m114_parse_dt()
2321 switch (sensor->bus_cfg.bus_type) { in mt9m114_parse_dt()
2327 dev_err(&sensor->client->dev, "unsupported bus type %u\n", in mt9m114_parse_dt()
2328 sensor->bus_cfg.bus_type); in mt9m114_parse_dt()
2329 ret = -EINVAL; in mt9m114_parse_dt()
2336 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); in mt9m114_parse_dt()
2342 struct device *dev = &client->dev; in mt9m114_probe()
2348 return -ENOMEM; in mt9m114_probe()
2350 sensor->client = client; in mt9m114_probe()
2352 sensor->regmap = devm_cci_regmap_init_i2c(client, 16); in mt9m114_probe()
2353 if (IS_ERR(sensor->regmap)) { in mt9m114_probe()
2355 return -ENODEV; in mt9m114_probe()
2363 sensor->clk = devm_clk_get(dev, NULL); in mt9m114_probe()
2364 if (IS_ERR(sensor->clk)) { in mt9m114_probe()
2365 ret = PTR_ERR(sensor->clk); in mt9m114_probe()
2370 sensor->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in mt9m114_probe()
2371 if (IS_ERR(sensor->reset)) { in mt9m114_probe()
2372 ret = PTR_ERR(sensor->reset); in mt9m114_probe()
2377 sensor->supplies[0].supply = "vddio"; in mt9m114_probe()
2378 sensor->supplies[1].supply = "vdd"; in mt9m114_probe()
2379 sensor->supplies[2].supply = "vaa"; in mt9m114_probe()
2381 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sensor->supplies), in mt9m114_probe()
2382 sensor->supplies); in mt9m114_probe()
2432 ret = v4l2_async_register_subdev(&sensor->ifp.sd); in mt9m114_probe()
2455 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); in mt9m114_probe()
2463 struct device *dev = &client->dev; in mt9m114_remove()
2465 v4l2_async_unregister_subdev(&sensor->ifp.sd); in mt9m114_remove()
2469 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); in mt9m114_remove()