Lines Matching +full:vdddo +full:- +full:supply
1 // SPDX-License-Identifier: GPL-2.0
3 * imx214.c - imx214 sensor driver
17 #include <media/media-entity.h>
18 #include <media/v4l2-cci.h>
19 #include <media/v4l2-ctrls.h>
20 #include <media/v4l2-fwnode.h>
21 #include <media/v4l2-subdev.h>
23 #include "ccs-pll.h"
40 /* V-TIMING internal */
46 /* HBLANK control - read only */
211 "vdddo",
220 * - no flip
221 * - h flip
222 * - v flip
223 * - h&v flips
502 /* V-timing */
536 ret = regulator_bulk_enable(IMX214_NUM_SUPPLIES, imx214->supplies);
538 dev_err(imx214->dev, "failed to enable regulators: %d\n", ret);
544 ret = clk_prepare_enable(imx214->xclk);
546 regulator_bulk_disable(IMX214_NUM_SUPPLIES, imx214->supplies);
547 dev_err(imx214->dev, "clk prepare enable failed\n");
551 gpiod_set_value_cansleep(imx214->enable_gpio, 1);
563 gpiod_set_value_cansleep(imx214->enable_gpio, 0);
565 clk_disable_unprepare(imx214->xclk);
567 regulator_bulk_disable(IMX214_NUM_SUPPLIES, imx214->supplies);
578 i = (imx214->vflip->val ? 2 : 0) | (imx214->hflip->val ? 1 : 0);
587 fmt->code = imx214_get_format_code(imx214);
588 fmt->width = mode->width;
589 fmt->height = mode->height;
590 fmt->field = V4L2_FIELD_NONE;
591 fmt->colorspace = V4L2_COLORSPACE_SRGB;
592 fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace);
593 fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true,
594 fmt->colorspace,
595 fmt->ycbcr_enc);
596 fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace);
605 if (code->index >= (ARRAY_SIZE(imx214_mbus_formats) / 4))
606 return -EINVAL;
608 code->code = imx214_get_format_code(imx214);
621 if (fse->code != code)
622 return -EINVAL;
624 if (fse->index >= ARRAY_SIZE(imx214_modes))
625 return -EINVAL;
627 fse->min_width = fse->max_width = imx214_modes[fse->index].width;
628 fse->min_height = fse->max_height = imx214_modes[fse->index].height;
639 return regmap_write(imx214->regmap, reg->reg, reg->val);
649 reg->size = 1;
650 ret = regmap_read(imx214->regmap, reg->reg, &aux);
651 reg->val = aux;
675 format->format.width,
676 format->format.height);
678 imx214_update_pad_format(imx214, mode, &format->format,
679 format->format.code);
682 *__format = format->format;
685 __crop->width = mode->width;
686 __crop->height = mode->height;
688 if (format->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
694 __v4l2_ctrl_modify_range(imx214->vblank, IMX214_VBLANK_MIN,
695 IMX214_VTS_MAX - mode->height, 2,
696 mode->vts_def - mode->height);
699 exposure_max = mode->vts_def - IMX214_EXPOSURE_OFFSET;
701 __v4l2_ctrl_modify_range(imx214->exposure,
702 imx214->exposure->minimum,
703 exposure_max, imx214->exposure->step,
708 * depends on mode->width only, and is not changeable in any
711 hblank = IMX214_PPL_DEFAULT - mode->width;
712 __v4l2_ctrl_modify_range(imx214->hblank, hblank, hblank, 1,
723 switch (sel->target) {
725 sel->r = *v4l2_subdev_state_get_crop(sd_state, 0);
729 sel->r.top = 0;
730 sel->r.left = 0;
731 sel->r.width = IMX214_NATIVE_WIDTH;
732 sel->r.height = IMX214_NATIVE_HEIGHT;
737 sel->r.top = IMX214_PIXEL_ARRAY_TOP;
738 sel->r.left = IMX214_PIXEL_ARRAY_LEFT;
739 sel->r.width = IMX214_PIXEL_ARRAY_WIDTH;
740 sel->r.height = IMX214_PIXEL_ARRAY_HEIGHT;
744 return -EINVAL;
766 cci_write(imx214->regmap, IMX214_REG_VTPXCK_DIV,
767 imx214->pll.vt_bk.pix_clk_div, &ret);
768 cci_write(imx214->regmap, IMX214_REG_VTSYCK_DIV,
769 imx214->pll.vt_bk.sys_clk_div, &ret);
770 cci_write(imx214->regmap, IMX214_REG_PREPLLCK_VT_DIV,
771 imx214->pll.vt_fr.pre_pll_clk_div, &ret);
772 cci_write(imx214->regmap, IMX214_REG_PLL_VT_MPY,
773 imx214->pll.vt_fr.pll_multiplier, &ret);
774 cci_write(imx214->regmap, IMX214_REG_OPPXCK_DIV,
775 imx214->pll.op_bk.pix_clk_div, &ret);
776 cci_write(imx214->regmap, IMX214_REG_OPSYCK_DIV,
777 imx214->pll.op_bk.sys_clk_div, &ret);
778 cci_write(imx214->regmap, IMX214_REG_PLL_MULT_DRIV,
780 cci_write(imx214->regmap, IMX214_REG_EXCK_FREQ,
781 IMX214_EXCK_FREQ(imx214->pll.ext_clk_freq_hz / 1000000), &ret);
790 cci_write(imx214->regmap, IMX214_REG_DIG_GAIN_GREENR, val, &ret);
791 cci_write(imx214->regmap, IMX214_REG_DIG_GAIN_RED, val, &ret);
792 cci_write(imx214->regmap, IMX214_REG_DIG_GAIN_BLUE, val, &ret);
793 cci_write(imx214->regmap, IMX214_REG_DIG_GAIN_GREENB, val, &ret);
800 struct imx214 *imx214 = container_of(ctrl->handler,
806 if (ctrl->id == V4L2_CID_VBLANK) {
809 state = v4l2_subdev_get_locked_active_state(&imx214->sd);
814 format->height + ctrl->val - IMX214_EXPOSURE_OFFSET;
816 __v4l2_ctrl_modify_range(imx214->exposure,
817 imx214->exposure->minimum,
818 exposure_max, imx214->exposure->step,
826 if (!pm_runtime_get_if_in_use(imx214->dev))
829 switch (ctrl->id) {
831 cci_write(imx214->regmap, IMX214_REG_ANALOG_GAIN,
832 ctrl->val, &ret);
833 cci_write(imx214->regmap, IMX214_REG_SHORT_ANALOG_GAIN,
834 ctrl->val, &ret);
837 ret = imx214_update_digital_gain(imx214, ctrl->val);
840 cci_write(imx214->regmap, IMX214_REG_EXPOSURE, ctrl->val, &ret);
844 cci_write(imx214->regmap, IMX214_REG_ORIENTATION,
845 imx214->hflip->val | imx214->vflip->val << 1, &ret);
848 cci_write(imx214->regmap, IMX214_REG_FRM_LENGTH_LINES,
849 format->height + ctrl->val, &ret);
852 cci_write(imx214->regmap, IMX214_REG_TEST_PATTERN,
853 imx214_test_pattern_val[ctrl->val], &ret);
856 cci_write(imx214->regmap, IMX214_REG_TESTP_RED,
857 ctrl->val, &ret);
860 cci_write(imx214->regmap, IMX214_REG_TESTP_GREENR,
861 ctrl->val, &ret);
864 cci_write(imx214->regmap, IMX214_REG_TESTP_BLUE,
865 ctrl->val, &ret);
868 cci_write(imx214->regmap, IMX214_REG_TESTP_GREENB,
869 ctrl->val, &ret);
872 ret = -EINVAL;
875 pm_runtime_put(imx214->dev);
897 ret = v4l2_fwnode_device_parse(imx214->dev, &props);
901 ctrl_hdlr = &imx214->ctrls;
902 ret = v4l2_ctrl_handler_init(&imx214->ctrls, 13);
906 imx214->pixel_rate =
910 imx214->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, NULL,
912 imx214->bus_cfg.nr_of_link_frequencies - 1,
913 0, imx214->bus_cfg.link_frequencies);
914 if (imx214->link_freq)
915 imx214->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
929 imx214->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
931 IMX214_VTS_MAX - mode->height, 2,
932 mode->vts_def - mode->height);
934 hblank = IMX214_PPL_DEFAULT - mode->width;
935 imx214->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
938 if (imx214->hblank)
939 imx214->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
941 exposure_max = mode->vts_def - IMX214_EXPOSURE_OFFSET;
943 imx214->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
958 imx214->hflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
960 if (imx214->hflip)
961 imx214->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
963 imx214->vflip = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
965 if (imx214->vflip)
966 imx214->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
968 v4l2_ctrl_cluster(2, &imx214->hflip);
972 ARRAY_SIZE(imx214_test_pattern_menu) - 1,
990 imx214->unit_size = v4l2_ctrl_new_std_compound(ctrl_hdlr,
999 ret = ctrl_hdlr->error;
1002 dev_err(imx214->dev, "failed to add controls: %d\n", ret);
1006 imx214->sd.ctrl_handler = ctrl_hdlr;
1019 ret = cci_multi_reg_write(imx214->regmap, mode_table_common,
1022 dev_err(imx214->dev, "could not sent common table %d\n", ret);
1028 dev_err(imx214->dev, "failed to configure PLL: %d\n", ret);
1032 bit_rate_mbps = (imx214->pll.pixel_rate_csi / 1000000)
1033 * imx214->pll.bits_per_pixel;
1034 ret = cci_write(imx214->regmap, IMX214_REG_REQ_LINK_BIT_RATE,
1037 dev_err(imx214->dev, "failed to configure link bit rate\n");
1041 ret = cci_write(imx214->regmap, IMX214_REG_CSI_LANE_MODE,
1044 dev_err(imx214->dev, "failed to configure lanes\n");
1048 state = v4l2_subdev_get_locked_active_state(&imx214->sd);
1051 width, height, fmt->width, fmt->height);
1052 ret = cci_multi_reg_write(imx214->regmap, mode->reg_table,
1053 mode->num_of_regs, NULL);
1055 dev_err(imx214->dev, "could not sent mode table %d\n", ret);
1061 cci_write(imx214->regmap, IMX214_REG_TEMP_SENSOR_CONTROL, 0x01, NULL);
1063 ret = __v4l2_ctrl_handler_setup(&imx214->ctrls);
1065 dev_err(imx214->dev, "could not sync v4l2 controls\n");
1068 ret = cci_write(imx214->regmap, IMX214_REG_MODE_SELECT,
1071 dev_err(imx214->dev, "could not sent start table %d\n", ret);
1080 ret = cci_write(imx214->regmap, IMX214_REG_MODE_SELECT,
1083 dev_err(imx214->dev, "could not sent stop table %d\n", ret);
1095 ret = pm_runtime_resume_and_get(imx214->dev);
1108 pm_runtime_put(imx214->dev);
1114 pm_runtime_put(imx214->dev);
1157 unsigned int num_lanes = imx214->bus_cfg.bus.mipi_csi2.num_data_lanes;
1181 pll->bus_type = CCS_PLL_BUS_TYPE_CSI2_DPHY;
1182 pll->op_lanes = num_lanes;
1183 pll->vt_lanes = num_lanes;
1184 pll->csi2.lanes = num_lanes;
1186 pll->binning_horizontal = 1;
1187 pll->binning_vertical = 1;
1188 pll->scale_m = 1;
1189 pll->scale_n = 1;
1190 pll->bits_per_pixel =
1192 pll->flags = CCS_PLL_FLAG_LANE_SPEED_MODEL;
1193 pll->link_freq = link_freq;
1194 pll->ext_clk_freq_hz = clk_get_rate(imx214->xclk);
1196 return ccs_pll_calculate(imx214->dev, &limits, pll);
1204 link_freq = imx214->bus_cfg.link_frequencies[imx214->link_freq->val];
1205 ret = imx214_pll_calculate(imx214, &imx214->pll, link_freq);
1207 dev_err(imx214->dev, "PLL calculations failed: %d\n", ret);
1211 ret = v4l2_ctrl_s_ctrl_int64(imx214->pixel_rate,
1212 imx214->pll.pixel_rate_pixel_array);
1214 dev_err(imx214->dev, "failed to set pixel rate\n");
1229 if (fival->which != V4L2_SUBDEV_FORMAT_ACTIVE)
1230 return -EINVAL;
1232 fival->interval.numerator = 1;
1233 fival->interval.denominator = IMX214_FPS;
1252 dev_warn_once(imx214->dev, "frame_interval functions return an unreliable value for compatibility reasons. Use the VBLANK and HBLANK controls to determine the correct frame rate.\n");
1254 if (fie->index != 0)
1255 return -EINVAL;
1259 fie->width, fie->height);
1261 fie->code = imx214_get_format_code(imx214);
1262 fie->width = mode->width;
1263 fie->height = mode->height;
1264 fie->interval.numerator = 1;
1265 fie->interval.denominator = IMX214_FPS;
1300 imx214->supplies[i].supply = imx214_supply_name[i];
1303 imx214->supplies);
1309 struct i2c_client *client = v4l2_get_subdevdata(&imx214->sd);
1313 ret = cci_read(imx214->regmap, IMX214_REG_CHIP_ID, &val, NULL);
1315 return dev_err_probe(&client->dev, ret,
1320 return dev_err_probe(&client->dev, -EIO,
1329 struct v4l2_fwnode_endpoint *bus_cfg = &imx214->bus_cfg;
1336 return dev_err_probe(dev, -EINVAL, "endpoint node not found\n");
1338 bus_cfg->bus_type = V4L2_MBUS_CSI2_DPHY;
1347 if (bus_cfg->bus.mipi_csi2.num_data_lanes != 4) {
1348 ret = dev_err_probe(dev, -EINVAL,
1353 if (bus_cfg->nr_of_link_frequencies != 1)
1354 dev_warn(dev, "Only one link-frequency supported, please review your DT. Continuing anyway\n");
1356 for (i = 0; i < bus_cfg->nr_of_link_frequencies; i++) {
1357 u64 freq = bus_cfg->link_frequencies[i];
1364 "link-frequencies %d not supported, please review your DT. Continuing anyway\n",
1369 bus_cfg->link_frequencies[i] = freq;
1374 if (i == bus_cfg->nr_of_link_frequencies)
1375 ret = dev_err_probe(dev, -EINVAL,
1376 "link-frequencies %lld not supported, please review your DT\n",
1377 bus_cfg->nr_of_link_frequencies ?
1378 bus_cfg->link_frequencies[0] : 0);
1383 v4l2_fwnode_endpoint_free(&imx214->bus_cfg);
1389 struct device *dev = &client->dev;
1395 return -ENOMEM;
1397 imx214->dev = dev;
1399 imx214->xclk = devm_clk_get(dev, NULL);
1400 if (IS_ERR(imx214->xclk))
1401 return dev_err_probe(dev, PTR_ERR(imx214->xclk),
1408 imx214->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW);
1409 if (IS_ERR(imx214->enable_gpio))
1410 return dev_err_probe(dev, PTR_ERR(imx214->enable_gpio),
1413 imx214->regmap = devm_cci_regmap_init_i2c(client, 16);
1414 if (IS_ERR(imx214->regmap))
1415 return dev_err_probe(dev, PTR_ERR(imx214->regmap),
1422 v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops);
1423 imx214->sd.internal_ops = &imx214_internal_ops;
1429 ret = imx214_power_on(imx214->dev);
1441 imx214->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1442 imx214->pad.flags = MEDIA_PAD_FL_SOURCE;
1443 imx214->sd.dev = &client->dev;
1444 imx214->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
1446 ret = media_entity_pads_init(&imx214->sd.entity, 1, &imx214->pad);
1452 imx214->sd.state_lock = imx214->ctrls.lock;
1453 ret = v4l2_subdev_init_finalize(&imx214->sd);
1459 pm_runtime_set_active(imx214->dev);
1460 pm_runtime_enable(imx214->dev);
1468 ret = v4l2_async_register_subdev_sensor(&imx214->sd);
1471 "failed to register sensor sub-device\n");
1475 pm_runtime_idle(imx214->dev);
1480 pm_runtime_disable(imx214->dev);
1481 pm_runtime_set_suspended(&client->dev);
1482 v4l2_subdev_cleanup(&imx214->sd);
1485 media_entity_cleanup(&imx214->sd.entity);
1488 v4l2_ctrl_handler_free(&imx214->ctrls);
1491 imx214_power_off(imx214->dev);
1494 v4l2_fwnode_endpoint_free(&imx214->bus_cfg);
1504 v4l2_async_unregister_subdev(&imx214->sd);
1506 media_entity_cleanup(&imx214->sd.entity);
1507 v4l2_ctrl_handler_free(&imx214->ctrls);
1508 v4l2_fwnode_endpoint_free(&imx214->bus_cfg);
1510 pm_runtime_disable(&client->dev);
1511 if (!pm_runtime_status_suspended(&client->dev)) {
1512 imx214_power_off(imx214->dev);
1513 pm_runtime_set_suspended(&client->dev);