Lines Matching +full:ddr +full:- +full:sel

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 */
343 * These values are not well documented and are semi-arbitrary. The pixel array
358 /* -----------------------------------------------------------------------------
416 /* -----------------------------------------------------------------------------
424 * CSI-2 buses respectively. Keep them in that order.
476 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) in mt9m114_default_format_info()
491 return &mt9m114_format_infos[num_formats - 1]; in mt9m114_format_info()
494 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) in mt9m114_format_info()
503 if (info->code == code && info->flags & flag) in mt9m114_format_info()
514 /* -----------------------------------------------------------------------------
594 /* Low-Light Image Enhancements */
632 /* Auto-Exposure */
653 /* -----------------------------------------------------------------------------
665 ret = cci_read(sensor->regmap, MT9M114_COMMAND_REGISTER, &value, in mt9m114_poll_command()
677 dev_err(&sensor->client->dev, "Command %u completion timeout\n", in mt9m114_poll_command()
679 return -ETIMEDOUT; in mt9m114_poll_command()
683 dev_err(&sensor->client->dev, "Command %u failed\n", command); in mt9m114_poll_command()
684 return -EIO; in mt9m114_poll_command()
698 ret = cci_read(sensor->regmap, MT9M114_SYSMGR_CURRENT_STATE, in mt9m114_poll_state()
709 dev_err(&sensor->client->dev, "Timeout waiting for state 0x%02x\n", in mt9m114_poll_state()
711 return -ETIMEDOUT; in mt9m114_poll_state()
719 cci_write(sensor->regmap, MT9M114_SYSMGR_NEXT_STATE, next_state, &ret); in mt9m114_set_state()
720 cci_write(sensor->regmap, MT9M114_COMMAND_REGISTER, in mt9m114_set_state()
739 ret = cci_multi_reg_write(sensor->regmap, mt9m114_init, in mt9m114_initialize()
742 dev_err(&sensor->client->dev, in mt9m114_initialize()
748 if (sensor->bypass_pll) { in mt9m114_initialize()
749 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE, in mt9m114_initialize()
752 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_ENABLE, in mt9m114_initialize()
754 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_M_N, in mt9m114_initialize()
755 MT9M114_CAM_SYSCTL_PLL_DIVIDER_VALUE(sensor->pll.m, in mt9m114_initialize()
756 sensor->pll.n), in mt9m114_initialize()
758 cci_write(sensor->regmap, MT9M114_CAM_SYSCTL_PLL_DIVIDER_P, in mt9m114_initialize()
759 MT9M114_CAM_SYSCTL_PLL_DIVIDER_P_VALUE(sensor->pll.p), in mt9m114_initialize()
763 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_PIXCLK, in mt9m114_initialize()
764 sensor->pixrate, &ret); in mt9m114_initialize()
767 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) { in mt9m114_initialize()
771 if (!(sensor->bus_cfg.bus.mipi_csi2.flags & in mt9m114_initialize()
778 cci_write(sensor->regmap, MT9M114_CAM_PORT_OUTPUT_CONTROL, value, &ret); in mt9m114_initialize()
805 ret = cci_read(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, in mt9m114_configure_pa()
810 hratio = crop->width / format->width; in mt9m114_configure_pa()
811 vratio = crop->height / format->height; in mt9m114_configure_pa()
819 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_START, in mt9m114_configure_pa()
820 crop->left, &ret); in mt9m114_configure_pa()
821 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_START, in mt9m114_configure_pa()
822 crop->top, &ret); in mt9m114_configure_pa()
823 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_X_ADDR_END, in mt9m114_configure_pa()
824 crop->width + crop->left - 1, &ret); in mt9m114_configure_pa()
825 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_Y_ADDR_END, in mt9m114_configure_pa()
826 crop->height + crop->top - 1, &ret); in mt9m114_configure_pa()
827 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_CPIPE_LAST_ROW, in mt9m114_configure_pa()
828 (crop->height - 4) / vratio - 1, &ret); in mt9m114_configure_pa()
838 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_READ_MODE, in mt9m114_configure_pa()
855 info = mt9m114_format_info(sensor, 1, format->code); in mt9m114_configure_ifp()
859 ret = cci_read(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, in mt9m114_configure_ifp()
870 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_XOFFSET, in mt9m114_configure_ifp()
871 crop->left - 4, &ret); in mt9m114_configure_ifp()
872 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_YOFFSET, in mt9m114_configure_ifp()
873 crop->top - 4, &ret); in mt9m114_configure_ifp()
874 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_WIDTH, in mt9m114_configure_ifp()
875 crop->width, &ret); in mt9m114_configure_ifp()
876 cci_write(sensor->regmap, MT9M114_CAM_CROP_WINDOW_HEIGHT, in mt9m114_configure_ifp()
877 crop->height, &ret); in mt9m114_configure_ifp()
879 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_WIDTH, in mt9m114_configure_ifp()
880 compose->width, &ret); in mt9m114_configure_ifp()
881 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_HEIGHT, in mt9m114_configure_ifp()
882 compose->height, &ret); in mt9m114_configure_ifp()
885 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XSTART, in mt9m114_configure_ifp()
887 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YSTART, in mt9m114_configure_ifp()
889 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_XEND, in mt9m114_configure_ifp()
890 compose->width - 1, &ret); in mt9m114_configure_ifp()
891 cci_write(sensor->regmap, MT9M114_CAM_STAT_AWB_CLIP_WINDOW_YEND, in mt9m114_configure_ifp()
892 compose->height - 1, &ret); in mt9m114_configure_ifp()
894 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XSTART, in mt9m114_configure_ifp()
896 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YSTART, in mt9m114_configure_ifp()
898 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_XEND, in mt9m114_configure_ifp()
899 compose->width / 5 - 1, &ret); in mt9m114_configure_ifp()
900 cci_write(sensor->regmap, MT9M114_CAM_STAT_AE_INITIAL_WINDOW_YEND, in mt9m114_configure_ifp()
901 compose->height / 5 - 1, &ret); in mt9m114_configure_ifp()
903 cci_write(sensor->regmap, MT9M114_CAM_CROP_CROPMODE, in mt9m114_configure_ifp()
913 output_format |= info->output_format; in mt9m114_configure_ifp()
915 cci_write(sensor->regmap, MT9M114_CAM_OUTPUT_FORMAT, in mt9m114_configure_ifp()
923 u16 frame_rate = sensor->ifp.frame_rate << 8; in mt9m114_set_frame_rate()
926 cci_write(sensor->regmap, MT9M114_CAM_AET_MIN_FRAME_RATE, in mt9m114_set_frame_rate()
928 cci_write(sensor->regmap, MT9M114_CAM_AET_MAX_FRAME_RATE, in mt9m114_set_frame_rate()
940 ret = pm_runtime_resume_and_get(&sensor->client->dev); in mt9m114_start_streaming()
956 ret = __v4l2_ctrl_handler_setup(&sensor->pa.hdl); in mt9m114_start_streaming()
960 ret = __v4l2_ctrl_handler_setup(&sensor->ifp.hdl); in mt9m114_start_streaming()
965 * The Change-Config state is transient and moves to the streaming in mt9m114_start_streaming()
972 sensor->streaming = true; in mt9m114_start_streaming()
977 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_start_streaming()
986 sensor->streaming = false; in mt9m114_stop_streaming()
990 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_stop_streaming()
995 /* -----------------------------------------------------------------------------
1003 /* -----------------------------------------------------------------------------
1009 return container_of(ctrl->handler, struct mt9m114, pa.hdl); in pa_ctrl_to_mt9m114()
1018 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) in mt9m114_pa_g_ctrl()
1021 switch (ctrl->id) { in mt9m114_pa_g_ctrl()
1023 ret = cci_read(sensor->regmap, in mt9m114_pa_g_ctrl()
1029 ctrl->val = value; in mt9m114_pa_g_ctrl()
1033 ret = cci_read(sensor->regmap, in mt9m114_pa_g_ctrl()
1039 ctrl->val = value; in mt9m114_pa_g_ctrl()
1043 ret = -EINVAL; in mt9m114_pa_g_ctrl()
1047 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_pa_g_ctrl()
1061 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) in mt9m114_pa_s_ctrl()
1064 state = v4l2_subdev_get_locked_active_state(&sensor->pa.sd); in mt9m114_pa_s_ctrl()
1067 switch (ctrl->id) { in mt9m114_pa_s_ctrl()
1069 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_LINE_LENGTH_PCK, in mt9m114_pa_s_ctrl()
1070 ctrl->val + format->width, &ret); in mt9m114_pa_s_ctrl()
1074 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CFG_FRAME_LENGTH_LINES, in mt9m114_pa_s_ctrl()
1075 ctrl->val + format->height, &ret); in mt9m114_pa_s_ctrl()
1079 cci_write(sensor->regmap, in mt9m114_pa_s_ctrl()
1081 ctrl->val, &ret); in mt9m114_pa_s_ctrl()
1090 cci_write(sensor->regmap, MT9M114_CAM_SENSOR_CONTROL_ANALOG_GAIN, in mt9m114_pa_s_ctrl()
1091 ctrl->val, &ret); in mt9m114_pa_s_ctrl()
1096 ret = cci_update_bits(sensor->regmap, in mt9m114_pa_s_ctrl()
1098 mask, ctrl->val ? mask : 0, NULL); in mt9m114_pa_s_ctrl()
1103 ret = cci_update_bits(sensor->regmap, in mt9m114_pa_s_ctrl()
1105 mask, ctrl->val ? mask : 0, NULL); in mt9m114_pa_s_ctrl()
1109 ret = -EINVAL; in mt9m114_pa_s_ctrl()
1113 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_pa_s_ctrl()
1132 mt9m114_pa_g_ctrl(sensor->pa.exposure); in mt9m114_pa_ctrl_update_exposure()
1133 sensor->pa.exposure->cur.val = sensor->pa.exposure->val; in mt9m114_pa_ctrl_update_exposure()
1134 sensor->pa.exposure->flags &= ~V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1136 mt9m114_pa_g_ctrl(sensor->pa.gain); in mt9m114_pa_ctrl_update_exposure()
1137 sensor->pa.gain->cur.val = sensor->pa.gain->val; in mt9m114_pa_ctrl_update_exposure()
1138 sensor->pa.gain->flags &= ~V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1140 sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1141 sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_ctrl_update_exposure()
1152 - format->width; in mt9m114_pa_ctrl_update_blanking()
1153 __v4l2_ctrl_modify_range(sensor->pa.hblank, MT9M114_MIN_HBLANK, in mt9m114_pa_ctrl_update_blanking()
1157 - format->height; in mt9m114_pa_ctrl_update_blanking()
1158 __v4l2_ctrl_modify_range(sensor->pa.vblank, MT9M114_MIN_VBLANK, in mt9m114_pa_ctrl_update_blanking()
1162 /* -----------------------------------------------------------------------------
1179 crop->left = 0; in mt9m114_pa_init_state()
1180 crop->top = 0; in mt9m114_pa_init_state()
1181 crop->width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_pa_init_state()
1182 crop->height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_pa_init_state()
1186 format->width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_pa_init_state()
1187 format->height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_pa_init_state()
1188 format->code = MEDIA_BUS_FMT_SGRBG10_1X10; in mt9m114_pa_init_state()
1189 format->field = V4L2_FIELD_NONE; in mt9m114_pa_init_state()
1190 format->colorspace = V4L2_COLORSPACE_RAW; in mt9m114_pa_init_state()
1191 format->ycbcr_enc = V4L2_YCBCR_ENC_601; in mt9m114_pa_init_state()
1192 format->quantization = V4L2_QUANTIZATION_FULL_RANGE; in mt9m114_pa_init_state()
1193 format->xfer_func = V4L2_XFER_FUNC_NONE; in mt9m114_pa_init_state()
1202 if (code->index > 0) in mt9m114_pa_enum_mbus_code()
1203 return -EINVAL; in mt9m114_pa_enum_mbus_code()
1205 code->code = MEDIA_BUS_FMT_SGRBG10_1X10; in mt9m114_pa_enum_mbus_code()
1214 if (fse->index > 1) in mt9m114_pa_enum_framesizes()
1215 return -EINVAL; in mt9m114_pa_enum_framesizes()
1217 if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) in mt9m114_pa_enum_framesizes()
1218 return -EINVAL; in mt9m114_pa_enum_framesizes()
1221 fse->min_width = MT9M114_PIXEL_ARRAY_WIDTH / (fse->index + 1); in mt9m114_pa_enum_framesizes()
1222 fse->max_width = MT9M114_PIXEL_ARRAY_WIDTH / (fse->index + 1); in mt9m114_pa_enum_framesizes()
1223 fse->min_height = MT9M114_PIXEL_ARRAY_HEIGHT / (fse->index + 1); in mt9m114_pa_enum_framesizes()
1224 fse->max_height = MT9M114_PIXEL_ARRAY_HEIGHT / (fse->index + 1); in mt9m114_pa_enum_framesizes()
1239 crop = v4l2_subdev_state_get_crop(state, fmt->pad); in mt9m114_pa_set_fmt()
1240 format = v4l2_subdev_state_get_format(state, fmt->pad); in mt9m114_pa_set_fmt()
1243 hscale = DIV_ROUND_CLOSEST(crop->width, fmt->format.width ? : 1); in mt9m114_pa_set_fmt()
1244 vscale = DIV_ROUND_CLOSEST(crop->height, fmt->format.height ? : 1); in mt9m114_pa_set_fmt()
1245 format->width = crop->width / clamp(hscale, 1U, 2U); in mt9m114_pa_set_fmt()
1246 format->height = crop->height / clamp(vscale, 1U, 2U); in mt9m114_pa_set_fmt()
1248 fmt->format = *format; in mt9m114_pa_set_fmt()
1250 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) in mt9m114_pa_set_fmt()
1258 struct v4l2_subdev_selection *sel) in mt9m114_pa_get_selection() argument
1260 switch (sel->target) { in mt9m114_pa_get_selection()
1262 sel->r = *v4l2_subdev_state_get_crop(state, sel->pad); in mt9m114_pa_get_selection()
1268 sel->r.left = 0; in mt9m114_pa_get_selection()
1269 sel->r.top = 0; in mt9m114_pa_get_selection()
1270 sel->r.width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_pa_get_selection()
1271 sel->r.height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_pa_get_selection()
1275 return -EINVAL; in mt9m114_pa_get_selection()
1281 struct v4l2_subdev_selection *sel) in mt9m114_pa_set_selection() argument
1287 if (sel->target != V4L2_SEL_TGT_CROP) in mt9m114_pa_set_selection()
1288 return -EINVAL; in mt9m114_pa_set_selection()
1290 crop = v4l2_subdev_state_get_crop(state, sel->pad); in mt9m114_pa_set_selection()
1291 format = v4l2_subdev_state_get_format(state, sel->pad); in mt9m114_pa_set_selection()
1301 crop->left = ALIGN(sel->r.left, 4); in mt9m114_pa_set_selection()
1302 crop->top = ALIGN(sel->r.top, 2); in mt9m114_pa_set_selection()
1303 crop->width = clamp_t(unsigned int, ALIGN(sel->r.width, 4), in mt9m114_pa_set_selection()
1305 MT9M114_PIXEL_ARRAY_WIDTH - crop->left); in mt9m114_pa_set_selection()
1306 crop->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), in mt9m114_pa_set_selection()
1308 MT9M114_PIXEL_ARRAY_HEIGHT - crop->top); in mt9m114_pa_set_selection()
1310 sel->r = *crop; in mt9m114_pa_set_selection()
1313 format->width = crop->width; in mt9m114_pa_set_selection()
1314 format->height = crop->height; in mt9m114_pa_set_selection()
1316 if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) in mt9m114_pa_set_selection()
1341 struct v4l2_ctrl_handler *hdl = &sensor->pa.hdl; in mt9m114_pa_init()
1342 struct v4l2_subdev *sd = &sensor->pa.sd; in mt9m114_pa_init()
1343 struct media_pad *pads = &sensor->pa.pad; in mt9m114_pa_init()
1351 sd->internal_ops = &mt9m114_pa_internal_ops; in mt9m114_pa_init()
1352 v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " pixel array"); in mt9m114_pa_init()
1354 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in mt9m114_pa_init()
1355 sd->owner = THIS_MODULE; in mt9m114_pa_init()
1356 sd->dev = &sensor->client->dev; in mt9m114_pa_init()
1357 v4l2_set_subdevdata(sd, sensor->client); in mt9m114_pa_init()
1360 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; in mt9m114_pa_init()
1361 sd->entity.ops = &mt9m114_entity_ops; in mt9m114_pa_init()
1363 ret = media_entity_pads_init(&sd->entity, 1, pads); in mt9m114_pa_init()
1371 sensor->pa.hblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1376 sensor->pa.vblank = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1385 * makes little sense as auto-exposure is enabled by default. in mt9m114_pa_init()
1387 max_exposure = MT9M114_PIXEL_ARRAY_HEIGHT + MT9M114_MIN_VBLANK - 2; in mt9m114_pa_init()
1388 sensor->pa.exposure = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1391 if (sensor->pa.exposure) in mt9m114_pa_init()
1392 sensor->pa.exposure->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_init()
1394 sensor->pa.gain = v4l2_ctrl_new_std(hdl, &mt9m114_pa_ctrl_ops, in mt9m114_pa_init()
1397 if (sensor->pa.gain) in mt9m114_pa_init()
1398 sensor->pa.gain->flags |= V4L2_CTRL_FLAG_VOLATILE; in mt9m114_pa_init()
1402 sensor->pixrate, sensor->pixrate, 1, in mt9m114_pa_init()
1403 sensor->pixrate); in mt9m114_pa_init()
1412 if (hdl->error) { in mt9m114_pa_init()
1413 ret = hdl->error; in mt9m114_pa_init()
1417 sd->state_lock = hdl->lock; in mt9m114_pa_init()
1429 sd->ctrl_handler = hdl; in mt9m114_pa_init()
1434 v4l2_ctrl_handler_free(&sensor->pa.hdl); in mt9m114_pa_init()
1435 media_entity_cleanup(&sensor->pa.sd.entity); in mt9m114_pa_init()
1441 v4l2_ctrl_handler_free(&sensor->pa.hdl); in mt9m114_pa_cleanup()
1442 media_entity_cleanup(&sensor->pa.sd.entity); in mt9m114_pa_cleanup()
1445 /* -----------------------------------------------------------------------------
1453 "Pseudo-Random",
1454 "Fade-to-Gray Color Bars",
1455 "Walking Ones 10-bit",
1456 "Walking Ones 8-bit",
1471 return container_of(ctrl->handler, struct mt9m114, ifp.hdl); in ifp_ctrl_to_mt9m114()
1480 if (ctrl->id == V4L2_CID_EXPOSURE_AUTO) in mt9m114_ifp_s_ctrl()
1482 ctrl->val != V4L2_EXPOSURE_AUTO); in mt9m114_ifp_s_ctrl()
1485 if (!pm_runtime_get_if_in_use(&sensor->client->dev)) in mt9m114_ifp_s_ctrl()
1488 switch (ctrl->id) { in mt9m114_ifp_s_ctrl()
1491 if (ctrl->val) in mt9m114_ifp_s_ctrl()
1497 cci_write(sensor->regmap, MT9M114_CAM_AWB_AWBMODE, value, &ret); in mt9m114_ifp_s_ctrl()
1499 if (ctrl->val) in mt9m114_ifp_s_ctrl()
1504 cci_write(sensor->regmap, MT9M114_CCM_ALGO, value, &ret); in mt9m114_ifp_s_ctrl()
1508 if (ctrl->val == V4L2_EXPOSURE_AUTO) in mt9m114_ifp_s_ctrl()
1514 cci_write(sensor->regmap, MT9M114_AE_TRACK_ALGO, value, &ret); in mt9m114_ifp_s_ctrl()
1524 unsigned int pattern = sensor->ifp.tpg[MT9M114_TPG_PATTERN]->val; in mt9m114_ifp_s_ctrl()
1527 cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, in mt9m114_ifp_s_ctrl()
1529 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1531 mt9m114_test_pattern_value[pattern - 1], &ret); in mt9m114_ifp_s_ctrl()
1532 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1534 sensor->ifp.tpg[MT9M114_TPG_RED]->val, &ret); in mt9m114_ifp_s_ctrl()
1535 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1537 sensor->ifp.tpg[MT9M114_TPG_GREEN]->val, &ret); in mt9m114_ifp_s_ctrl()
1538 cci_write(sensor->regmap, in mt9m114_ifp_s_ctrl()
1540 sensor->ifp.tpg[MT9M114_TPG_BLUE]->val, &ret); in mt9m114_ifp_s_ctrl()
1542 cci_write(sensor->regmap, MT9M114_CAM_MODE_SELECT, in mt9m114_ifp_s_ctrl()
1547 * A Config-Change needs to be issued for the change to take in mt9m114_ifp_s_ctrl()
1551 if (ret || !sensor->streaming) in mt9m114_ifp_s_ctrl()
1560 ret = -EINVAL; in mt9m114_ifp_s_ctrl()
1564 pm_runtime_put_autosuspend(&sensor->client->dev); in mt9m114_ifp_s_ctrl()
1573 /* -----------------------------------------------------------------------------
1592 ifp_state = v4l2_subdev_lock_and_get_active_state(&sensor->ifp.sd); in mt9m114_ifp_s_stream()
1593 pa_state = v4l2_subdev_lock_and_get_active_state(&sensor->pa.sd); in mt9m114_ifp_s_stream()
1607 struct v4l2_fract *ival = &interval->interval; in mt9m114_ifp_get_frame_interval()
1614 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) in mt9m114_ifp_get_frame_interval()
1615 return -EINVAL; in mt9m114_ifp_get_frame_interval()
1617 ival->numerator = 1; in mt9m114_ifp_get_frame_interval()
1618 ival->denominator = sensor->ifp.frame_rate; in mt9m114_ifp_get_frame_interval()
1627 struct v4l2_fract *ival = &interval->interval; in mt9m114_ifp_set_frame_interval()
1635 if (interval->which != V4L2_SUBDEV_FORMAT_ACTIVE) in mt9m114_ifp_set_frame_interval()
1636 return -EINVAL; in mt9m114_ifp_set_frame_interval()
1638 if (ival->numerator != 0 && ival->denominator != 0) in mt9m114_ifp_set_frame_interval()
1639 sensor->ifp.frame_rate = min_t(unsigned int, in mt9m114_ifp_set_frame_interval()
1640 ival->denominator / ival->numerator, in mt9m114_ifp_set_frame_interval()
1643 sensor->ifp.frame_rate = MT9M114_MAX_FRAME_RATE; in mt9m114_ifp_set_frame_interval()
1645 ival->numerator = 1; in mt9m114_ifp_set_frame_interval()
1646 ival->denominator = sensor->ifp.frame_rate; in mt9m114_ifp_set_frame_interval()
1648 if (sensor->streaming) in mt9m114_ifp_set_frame_interval()
1664 format->width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_ifp_init_state()
1665 format->height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_ifp_init_state()
1666 format->code = MEDIA_BUS_FMT_SGRBG10_1X10; in mt9m114_ifp_init_state()
1667 format->field = V4L2_FIELD_NONE; in mt9m114_ifp_init_state()
1668 format->colorspace = V4L2_COLORSPACE_RAW; in mt9m114_ifp_init_state()
1669 format->ycbcr_enc = V4L2_YCBCR_ENC_601; in mt9m114_ifp_init_state()
1670 format->quantization = V4L2_QUANTIZATION_FULL_RANGE; in mt9m114_ifp_init_state()
1671 format->xfer_func = V4L2_XFER_FUNC_NONE; in mt9m114_ifp_init_state()
1675 crop->left = 4; in mt9m114_ifp_init_state()
1676 crop->top = 4; in mt9m114_ifp_init_state()
1677 crop->width = format->width - 8; in mt9m114_ifp_init_state()
1678 crop->height = format->height - 8; in mt9m114_ifp_init_state()
1682 compose->left = 0; in mt9m114_ifp_init_state()
1683 compose->top = 0; in mt9m114_ifp_init_state()
1684 compose->width = crop->width; in mt9m114_ifp_init_state()
1685 compose->height = crop->height; in mt9m114_ifp_init_state()
1689 format->width = compose->width; in mt9m114_ifp_init_state()
1690 format->height = compose->height; in mt9m114_ifp_init_state()
1691 format->code = mt9m114_default_format_info(sensor)->code; in mt9m114_ifp_init_state()
1692 format->field = V4L2_FIELD_NONE; in mt9m114_ifp_init_state()
1693 format->colorspace = V4L2_COLORSPACE_SRGB; in mt9m114_ifp_init_state()
1694 format->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; in mt9m114_ifp_init_state()
1695 format->quantization = V4L2_QUANTIZATION_DEFAULT; in mt9m114_ifp_init_state()
1696 format->xfer_func = V4L2_XFER_FUNC_DEFAULT; in mt9m114_ifp_init_state()
1711 switch (code->pad) { in mt9m114_ifp_enum_mbus_code()
1713 if (code->index != 0) in mt9m114_ifp_enum_mbus_code()
1714 return -EINVAL; in mt9m114_ifp_enum_mbus_code()
1716 code->code = mt9m114_format_infos[num_formats - 1].code; in mt9m114_ifp_enum_mbus_code()
1720 if (sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY) in mt9m114_ifp_enum_mbus_code()
1729 if (info->flags & flag) { in mt9m114_ifp_enum_mbus_code()
1730 if (index == code->index) { in mt9m114_ifp_enum_mbus_code()
1731 code->code = info->code; in mt9m114_ifp_enum_mbus_code()
1739 return -EINVAL; in mt9m114_ifp_enum_mbus_code()
1742 return -EINVAL; in mt9m114_ifp_enum_mbus_code()
1753 if (fse->index > 0) in mt9m114_ifp_enum_framesizes()
1754 return -EINVAL; in mt9m114_ifp_enum_framesizes()
1756 info = mt9m114_format_info(sensor, fse->pad, fse->code); in mt9m114_ifp_enum_framesizes()
1757 if (!info || info->code != fse->code) in mt9m114_ifp_enum_framesizes()
1758 return -EINVAL; in mt9m114_ifp_enum_framesizes()
1760 if (fse->pad == 0) { in mt9m114_ifp_enum_framesizes()
1761 fse->min_width = MT9M114_PIXEL_ARRAY_MIN_OUTPUT_WIDTH; in mt9m114_ifp_enum_framesizes()
1762 fse->max_width = MT9M114_PIXEL_ARRAY_WIDTH; in mt9m114_ifp_enum_framesizes()
1763 fse->min_height = MT9M114_PIXEL_ARRAY_MIN_OUTPUT_HEIGHT; in mt9m114_ifp_enum_framesizes()
1764 fse->max_height = MT9M114_PIXEL_ARRAY_HEIGHT; in mt9m114_ifp_enum_framesizes()
1770 fse->max_width = crop->width; in mt9m114_ifp_enum_framesizes()
1771 fse->max_height = crop->height; in mt9m114_ifp_enum_framesizes()
1773 fse->min_width = fse->max_width / 4; in mt9m114_ifp_enum_framesizes()
1774 fse->min_height = fse->max_height / 4; in mt9m114_ifp_enum_framesizes()
1787 if (fie->index > 0) in mt9m114_ifp_enum_frameintervals()
1788 return -EINVAL; in mt9m114_ifp_enum_frameintervals()
1790 info = mt9m114_format_info(sensor, fie->pad, fie->code); in mt9m114_ifp_enum_frameintervals()
1791 if (!info || info->code != fie->code) in mt9m114_ifp_enum_frameintervals()
1792 return -EINVAL; in mt9m114_ifp_enum_frameintervals()
1794 fie->interval.numerator = 1; in mt9m114_ifp_enum_frameintervals()
1795 fie->interval.denominator = MT9M114_MAX_FRAME_RATE; in mt9m114_ifp_enum_frameintervals()
1807 format = v4l2_subdev_state_get_format(state, fmt->pad); in mt9m114_ifp_set_fmt()
1809 if (fmt->pad == 0) { in mt9m114_ifp_set_fmt()
1811 format->width = clamp(ALIGN(fmt->format.width, 8), in mt9m114_ifp_set_fmt()
1814 format->height = clamp(ALIGN(fmt->format.height, 8), in mt9m114_ifp_set_fmt()
1821 info = mt9m114_format_info(sensor, 1, fmt->format.code); in mt9m114_ifp_set_fmt()
1823 format->code = info->code; in mt9m114_ifp_set_fmt()
1826 if (format->code == MEDIA_BUS_FMT_SGRBG10_1X10) in mt9m114_ifp_set_fmt()
1830 fmt->format = *format; in mt9m114_ifp_set_fmt()
1837 struct v4l2_subdev_selection *sel) in mt9m114_ifp_get_selection() argument
1844 if (sel->pad != 0) in mt9m114_ifp_get_selection()
1845 return -EINVAL; in mt9m114_ifp_get_selection()
1847 switch (sel->target) { in mt9m114_ifp_get_selection()
1849 sel->r = *v4l2_subdev_state_get_crop(state, 0); in mt9m114_ifp_get_selection()
1860 sel->r.left = 4; in mt9m114_ifp_get_selection()
1861 sel->r.top = 4; in mt9m114_ifp_get_selection()
1862 sel->r.width = format->width - 8; in mt9m114_ifp_get_selection()
1863 sel->r.height = format->height - 8; in mt9m114_ifp_get_selection()
1867 sel->r = *v4l2_subdev_state_get_compose(state, 0); in mt9m114_ifp_get_selection()
1877 sel->r.left = 0; in mt9m114_ifp_get_selection()
1878 sel->r.top = 0; in mt9m114_ifp_get_selection()
1879 sel->r.width = crop->width; in mt9m114_ifp_get_selection()
1880 sel->r.height = crop->height; in mt9m114_ifp_get_selection()
1884 ret = -EINVAL; in mt9m114_ifp_get_selection()
1893 struct v4l2_subdev_selection *sel) in mt9m114_ifp_set_selection() argument
1899 if (sel->target != V4L2_SEL_TGT_CROP && in mt9m114_ifp_set_selection()
1900 sel->target != V4L2_SEL_TGT_COMPOSE) in mt9m114_ifp_set_selection()
1901 return -EINVAL; in mt9m114_ifp_set_selection()
1904 if (sel->pad != 0) in mt9m114_ifp_set_selection()
1905 return -EINVAL; in mt9m114_ifp_set_selection()
1911 if (sel->target == V4L2_SEL_TGT_CROP) { in mt9m114_ifp_set_selection()
1916 crop->left = clamp_t(unsigned int, ALIGN(sel->r.left, 2), 4, in mt9m114_ifp_set_selection()
1917 format->width - 4 - in mt9m114_ifp_set_selection()
1919 crop->top = clamp_t(unsigned int, ALIGN(sel->r.top, 2), 4, in mt9m114_ifp_set_selection()
1920 format->height - 4 - in mt9m114_ifp_set_selection()
1922 crop->width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), in mt9m114_ifp_set_selection()
1924 format->width - 4 - crop->left); in mt9m114_ifp_set_selection()
1925 crop->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), in mt9m114_ifp_set_selection()
1927 format->height - 4 - crop->top); in mt9m114_ifp_set_selection()
1929 sel->r = *crop; in mt9m114_ifp_set_selection()
1932 compose->width = crop->width; in mt9m114_ifp_set_selection()
1933 compose->height = crop->height; in mt9m114_ifp_set_selection()
1938 compose->left = 0; in mt9m114_ifp_set_selection()
1939 compose->top = 0; in mt9m114_ifp_set_selection()
1940 compose->width = clamp_t(unsigned int, ALIGN(sel->r.width, 2), in mt9m114_ifp_set_selection()
1942 crop->width); in mt9m114_ifp_set_selection()
1943 compose->height = clamp_t(unsigned int, ALIGN(sel->r.height, 2), in mt9m114_ifp_set_selection()
1945 crop->height); in mt9m114_ifp_set_selection()
1947 sel->r = *compose; in mt9m114_ifp_set_selection()
1952 format->width = compose->width; in mt9m114_ifp_set_selection()
1953 format->height = compose->height; in mt9m114_ifp_set_selection()
1962 v4l2_device_unregister_subdev(&sensor->pa.sd); in mt9m114_ifp_unregistered()
1970 ret = v4l2_device_register_subdev(sd->v4l2_dev, &sensor->pa.sd); in mt9m114_ifp_registered()
1972 dev_err(&sensor->client->dev, in mt9m114_ifp_registered()
1977 ret = media_create_pad_link(&sensor->pa.sd.entity, 0, in mt9m114_ifp_registered()
1978 &sensor->ifp.sd.entity, 0, in mt9m114_ifp_registered()
1982 dev_err(&sensor->client->dev, in mt9m114_ifp_registered()
1984 v4l2_device_unregister_subdev(&sensor->pa.sd); in mt9m114_ifp_registered()
2020 struct v4l2_subdev *sd = &sensor->ifp.sd; in mt9m114_ifp_init()
2021 struct media_pad *pads = sensor->ifp.pads; in mt9m114_ifp_init()
2022 struct v4l2_ctrl_handler *hdl = &sensor->ifp.hdl; in mt9m114_ifp_init()
2027 v4l2_i2c_subdev_init(sd, sensor->client, &mt9m114_ifp_ops); in mt9m114_ifp_init()
2028 v4l2_i2c_subdev_set_name(sd, sensor->client, NULL, " ifp"); in mt9m114_ifp_init()
2030 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; in mt9m114_ifp_init()
2031 sd->internal_ops = &mt9m114_ifp_internal_ops; in mt9m114_ifp_init()
2034 sd->entity.function = MEDIA_ENT_F_PROC_VIDEO_ISP; in mt9m114_ifp_init()
2035 sd->entity.ops = &mt9m114_entity_ops; in mt9m114_ifp_init()
2038 ret = media_entity_pads_init(&sd->entity, 2, pads); in mt9m114_ifp_init()
2042 sensor->ifp.frame_rate = MT9M114_DEF_FRAME_RATE; in mt9m114_ifp_init()
2056 sensor->bus_cfg.nr_of_link_frequencies - 1, in mt9m114_ifp_init()
2057 0, sensor->bus_cfg.link_frequencies); in mt9m114_ifp_init()
2059 link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; in mt9m114_ifp_init()
2063 sensor->pixrate, sensor->pixrate, 1, in mt9m114_ifp_init()
2064 sensor->pixrate); in mt9m114_ifp_init()
2066 sensor->ifp.tpg[MT9M114_TPG_PATTERN] = in mt9m114_ifp_init()
2069 ARRAY_SIZE(mt9m114_test_pattern_menu) - 1, in mt9m114_ifp_init()
2071 sensor->ifp.tpg[MT9M114_TPG_RED] = in mt9m114_ifp_init()
2075 sensor->ifp.tpg[MT9M114_TPG_GREEN] = in mt9m114_ifp_init()
2079 sensor->ifp.tpg[MT9M114_TPG_BLUE] = in mt9m114_ifp_init()
2084 v4l2_ctrl_cluster(ARRAY_SIZE(sensor->ifp.tpg), sensor->ifp.tpg); in mt9m114_ifp_init()
2086 if (hdl->error) { in mt9m114_ifp_init()
2087 ret = hdl->error; in mt9m114_ifp_init()
2091 sd->ctrl_handler = hdl; in mt9m114_ifp_init()
2092 sd->state_lock = hdl->lock; in mt9m114_ifp_init()
2101 v4l2_ctrl_handler_free(&sensor->ifp.hdl); in mt9m114_ifp_init()
2102 media_entity_cleanup(&sensor->ifp.sd.entity); in mt9m114_ifp_init()
2108 v4l2_ctrl_handler_free(&sensor->ifp.hdl); in mt9m114_ifp_cleanup()
2109 media_entity_cleanup(&sensor->ifp.sd.entity); in mt9m114_ifp_cleanup()
2112 /* -----------------------------------------------------------------------------
2121 ret = regulator_bulk_enable(ARRAY_SIZE(sensor->supplies), in mt9m114_power_on()
2122 sensor->supplies); in mt9m114_power_on()
2126 ret = clk_prepare_enable(sensor->clk); in mt9m114_power_on()
2131 if (sensor->reset) { in mt9m114_power_on()
2132 long freq = clk_get_rate(sensor->clk); in mt9m114_power_on()
2141 gpiod_set_value(sensor->reset, 1); in mt9m114_power_on()
2143 gpiod_set_value(sensor->reset, 0); in mt9m114_power_on()
2151 cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, in mt9m114_power_on()
2153 cci_write(sensor->regmap, MT9M114_RESET_AND_MISC_CONTROL, 0, in mt9m114_power_on()
2157 dev_err(&sensor->client->dev, "Soft reset failed\n"); in mt9m114_power_on()
2172 if (sensor->bus_cfg.bus_type == V4L2_MBUS_PARALLEL) { in mt9m114_power_on()
2185 * Before issuing any Set-State command, we must ensure that the sensor in mt9m114_power_on()
2196 clk_disable_unprepare(sensor->clk); in mt9m114_power_on()
2198 regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); in mt9m114_power_on()
2204 clk_disable_unprepare(sensor->clk); in mt9m114_power_off()
2205 regulator_bulk_disable(ARRAY_SIZE(sensor->supplies), sensor->supplies); in mt9m114_power_off()
2241 /* -----------------------------------------------------------------------------
2248 unsigned int link_freq = sensor->bus_cfg.bus_type == V4L2_MBUS_CSI2_DPHY in mt9m114_verify_link_frequency()
2251 if (sensor->bus_cfg.nr_of_link_frequencies != 1 || in mt9m114_verify_link_frequency()
2252 sensor->bus_cfg.link_frequencies[0] != link_freq) in mt9m114_verify_link_frequency()
2253 return -EINVAL; in mt9m114_verify_link_frequency()
2263 sensor->pll.m = 32; in mt9m114_clk_init()
2264 sensor->pll.n = 1; in mt9m114_clk_init()
2265 sensor->pll.p = 7; in mt9m114_clk_init()
2268 * Calculate the pixel rate and link frequency. The CSI-2 bus is clocked in mt9m114_clk_init()
2269 * for 16-bit per pixel, transmitted in DDR over a single lane. For in mt9m114_clk_init()
2277 pixrate = clk_get_rate(sensor->clk) / 2; in mt9m114_clk_init()
2279 sensor->pixrate = pixrate; in mt9m114_clk_init()
2280 sensor->bypass_pll = true; in mt9m114_clk_init()
2285 pixrate = clk_get_rate(sensor->clk) * sensor->pll.m in mt9m114_clk_init()
2286 / ((sensor->pll.n + 1) * (sensor->pll.p + 1)); in mt9m114_clk_init()
2288 sensor->pixrate = pixrate; in mt9m114_clk_init()
2289 sensor->bypass_pll = false; in mt9m114_clk_init()
2293 dev_err(&sensor->client->dev, "Unsupported DT link-frequencies\n"); in mt9m114_clk_init()
2294 return -EINVAL; in mt9m114_clk_init()
2303 ret = cci_read(sensor->regmap, MT9M114_CHIP_ID, &value, NULL); in mt9m114_identify()
2305 dev_err(&sensor->client->dev, "Failed to read chip ID\n"); in mt9m114_identify()
2306 return -ENXIO; in mt9m114_identify()
2310 dev_err(&sensor->client->dev, "Invalid chip ID 0x%04llx\n", in mt9m114_identify()
2312 return -ENXIO; in mt9m114_identify()
2315 cci_read(sensor->regmap, MT9M114_MON_MAJOR_VERSION, &major, &ret); in mt9m114_identify()
2316 cci_read(sensor->regmap, MT9M114_MON_MINOR_VERSION, &minor, &ret); in mt9m114_identify()
2317 cci_read(sensor->regmap, MT9M114_MON_RELEASE_VERSION, &release, &ret); in mt9m114_identify()
2318 cci_read(sensor->regmap, MT9M114_CUSTOMER_REV, &customer, &ret); in mt9m114_identify()
2320 dev_err(&sensor->client->dev, "Failed to read version\n"); in mt9m114_identify()
2321 return -ENXIO; in mt9m114_identify()
2324 dev_dbg(&sensor->client->dev, in mt9m114_identify()
2333 struct fwnode_handle *fwnode = dev_fwnode(&sensor->client->dev); in mt9m114_parse_dt()
2339 dev_err(&sensor->client->dev, "No endpoint found\n"); in mt9m114_parse_dt()
2340 return -EINVAL; in mt9m114_parse_dt()
2343 sensor->bus_cfg.bus_type = V4L2_MBUS_UNKNOWN; in mt9m114_parse_dt()
2344 ret = v4l2_fwnode_endpoint_alloc_parse(ep, &sensor->bus_cfg); in mt9m114_parse_dt()
2347 dev_err(&sensor->client->dev, "Failed to parse endpoint\n"); in mt9m114_parse_dt()
2351 switch (sensor->bus_cfg.bus_type) { in mt9m114_parse_dt()
2357 dev_err(&sensor->client->dev, "unsupported bus type %u\n", in mt9m114_parse_dt()
2358 sensor->bus_cfg.bus_type); in mt9m114_parse_dt()
2359 ret = -EINVAL; in mt9m114_parse_dt()
2366 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); in mt9m114_parse_dt()
2372 struct device *dev = &client->dev; in mt9m114_probe()
2378 return -ENOMEM; in mt9m114_probe()
2380 sensor->client = client; in mt9m114_probe()
2382 sensor->regmap = devm_cci_regmap_init_i2c(client, 16); in mt9m114_probe()
2383 if (IS_ERR(sensor->regmap)) { in mt9m114_probe()
2385 return -ENODEV; in mt9m114_probe()
2393 sensor->clk = devm_clk_get(dev, NULL); in mt9m114_probe()
2394 if (IS_ERR(sensor->clk)) { in mt9m114_probe()
2395 ret = PTR_ERR(sensor->clk); in mt9m114_probe()
2400 sensor->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); in mt9m114_probe()
2401 if (IS_ERR(sensor->reset)) { in mt9m114_probe()
2402 ret = PTR_ERR(sensor->reset); in mt9m114_probe()
2407 sensor->supplies[0].supply = "vddio"; in mt9m114_probe()
2408 sensor->supplies[1].supply = "vdd"; in mt9m114_probe()
2409 sensor->supplies[2].supply = "vaa"; in mt9m114_probe()
2411 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sensor->supplies), in mt9m114_probe()
2412 sensor->supplies); in mt9m114_probe()
2462 ret = v4l2_async_register_subdev(&sensor->ifp.sd); in mt9m114_probe()
2484 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); in mt9m114_probe()
2492 struct device *dev = &client->dev; in mt9m114_remove()
2494 v4l2_async_unregister_subdev(&sensor->ifp.sd); in mt9m114_remove()
2498 v4l2_fwnode_endpoint_free(&sensor->bus_cfg); in mt9m114_remove()