diff options
| author | Bhanu Murthy V <bmurthyv@nvidia.com> | 2017-12-05 20:56:46 -0500 |
|---|---|---|
| committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-12-13 20:20:49 -0500 |
| commit | 07857ffeb5a350e6d5fc9d5c4b3d56ff4434d7ab (patch) | |
| tree | 1dc3fb7db0008f8ec82f52b9f417219dc0850e03 | |
| parent | d00c9880a68fb83d1696e74f841d8226681ce586 (diff) | |
drivers: media: tegra: Tegra Camera framework
Tegra camera device register - Takes care of
necessary initialization to work with common
framework for tegra
Tegra camera v4l2device register - Takes care of
v4l2 subdevice initialization and Async framework
initialization to bind with v4l2device.
In addition, tegra camera control layer is setup
for the sensor drivers to add controls selectively.
As next step all the v4l2 controls in tegra camera
drivers will be added here.
The common framework initializes the drivers based
on the device tree properties to setup for each
sensor mode.
Bug 1946718
Change-Id: I1f8dbce452248e9749c473bb83c4ea86e42ef531
Signed-off-by: Bhanu Murthy V <bmurthyv@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1611726
Reviewed-by: Frank Chen <frankc@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Jihoon Bang <jbang@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
| -rw-r--r-- | drivers/media/platform/tegra/camera/Makefile | 3 | ||||
| -rw-r--r-- | drivers/media/platform/tegra/camera/camera_common.c | 20 | ||||
| -rw-r--r-- | drivers/media/platform/tegra/camera/sensor_common.c | 34 | ||||
| -rw-r--r-- | drivers/media/platform/tegra/camera/tegracam_core.c | 203 | ||||
| -rw-r--r-- | drivers/media/platform/tegra/camera/tegracam_ctrls.c | 335 | ||||
| -rw-r--r-- | include/media/camera_common.h | 42 | ||||
| -rw-r--r-- | include/media/tegra-v4l2-camera.h | 13 | ||||
| -rw-r--r-- | include/media/tegracam_core.h | 49 |
8 files changed, 695 insertions, 4 deletions
diff --git a/drivers/media/platform/tegra/camera/Makefile b/drivers/media/platform/tegra/camera/Makefile index cf95f283f..e89cffc4e 100644 --- a/drivers/media/platform/tegra/camera/Makefile +++ b/drivers/media/platform/tegra/camera/Makefile | |||
| @@ -7,7 +7,8 @@ ccflags-y += -Werror | |||
| 7 | 7 | ||
| 8 | obj-y += vi/ | 8 | obj-y += vi/ |
| 9 | obj-y += csi/ | 9 | obj-y += csi/ |
| 10 | obj-y += camera_common.o camera_gpio.o sensor_common.o camera_version_utils.o | 10 | obj-y += camera_common.o camera_gpio.o sensor_common.o camera_version_utils.o \ |
| 11 | tegracam_ctrls.o tegracam_core.o | ||
| 11 | obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += capture_common.o | 12 | obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += capture_common.o |
| 12 | obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += isp/isp_channel.o | 13 | obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += isp/isp_channel.o |
| 13 | obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += isp/capture_isp.o | 14 | obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += isp/capture_isp.o |
diff --git a/drivers/media/platform/tegra/camera/camera_common.c b/drivers/media/platform/tegra/camera/camera_common.c index 71763d124..7584f5b46 100644 --- a/drivers/media/platform/tegra/camera/camera_common.c +++ b/drivers/media/platform/tegra/camera/camera_common.c | |||
| @@ -392,6 +392,20 @@ const struct camera_common_colorfmt *camera_common_find_datafmt( | |||
| 392 | } | 392 | } |
| 393 | EXPORT_SYMBOL_GPL(camera_common_find_datafmt); | 393 | EXPORT_SYMBOL_GPL(camera_common_find_datafmt); |
| 394 | 394 | ||
| 395 | /* Find a data format by pixel format in an array*/ | ||
| 396 | const struct camera_common_colorfmt *camera_common_find_pixelfmt( | ||
| 397 | unsigned int pix_fmt) | ||
| 398 | { | ||
| 399 | int i; | ||
| 400 | |||
| 401 | for (i = 0; i < ARRAY_SIZE(camera_common_color_fmts); i++) | ||
| 402 | if (camera_common_color_fmts[i].pix_fmt == pix_fmt) | ||
| 403 | return camera_common_color_fmts + i; | ||
| 404 | |||
| 405 | return NULL; | ||
| 406 | } | ||
| 407 | EXPORT_SYMBOL_GPL(camera_common_find_pixelfmt); | ||
| 408 | |||
| 395 | /* Filters for the sensor's supported colors */ | 409 | /* Filters for the sensor's supported colors */ |
| 396 | static const struct camera_common_colorfmt *find_matching_color_fmt( | 410 | static const struct camera_common_colorfmt *find_matching_color_fmt( |
| 397 | const struct camera_common_data *s_data, | 411 | const struct camera_common_data *s_data, |
| @@ -693,7 +707,7 @@ int camera_common_enum_frameintervals(struct v4l2_subdev *sd, | |||
| 693 | } | 707 | } |
| 694 | EXPORT_SYMBOL_GPL(camera_common_enum_frameintervals); | 708 | EXPORT_SYMBOL_GPL(camera_common_enum_frameintervals); |
| 695 | 709 | ||
| 696 | static void camera_common_mclk_disable(struct camera_common_data *s_data) | 710 | void camera_common_mclk_disable(struct camera_common_data *s_data) |
| 697 | { | 711 | { |
| 698 | struct camera_common_power_rail *pw = s_data->power; | 712 | struct camera_common_power_rail *pw = s_data->power; |
| 699 | 713 | ||
| @@ -706,8 +720,9 @@ static void camera_common_mclk_disable(struct camera_common_data *s_data) | |||
| 706 | dev_dbg(s_data->dev, "%s: disable MCLK\n", __func__); | 720 | dev_dbg(s_data->dev, "%s: disable MCLK\n", __func__); |
| 707 | clk_disable_unprepare(pw->mclk); | 721 | clk_disable_unprepare(pw->mclk); |
| 708 | } | 722 | } |
| 723 | EXPORT_SYMBOL_GPL(camera_common_mclk_disable); | ||
| 709 | 724 | ||
| 710 | static int camera_common_mclk_enable(struct camera_common_data *s_data) | 725 | int camera_common_mclk_enable(struct camera_common_data *s_data) |
| 711 | { | 726 | { |
| 712 | int err; | 727 | int err; |
| 713 | struct camera_common_power_rail *pw = s_data->power; | 728 | struct camera_common_power_rail *pw = s_data->power; |
| @@ -728,6 +743,7 @@ static int camera_common_mclk_enable(struct camera_common_data *s_data) | |||
| 728 | 743 | ||
| 729 | return err; | 744 | return err; |
| 730 | } | 745 | } |
| 746 | EXPORT_SYMBOL_GPL(camera_common_mclk_enable); | ||
| 731 | 747 | ||
| 732 | void camera_common_dpd_disable(struct camera_common_data *s_data) | 748 | void camera_common_dpd_disable(struct camera_common_data *s_data) |
| 733 | { | 749 | { |
diff --git a/drivers/media/platform/tegra/camera/sensor_common.c b/drivers/media/platform/tegra/camera/sensor_common.c index 16ecd9976..a5482e7c0 100644 --- a/drivers/media/platform/tegra/camera/sensor_common.c +++ b/drivers/media/platform/tegra/camera/sensor_common.c | |||
| @@ -327,6 +327,14 @@ static int sensor_common_parse_control_props( | |||
| 327 | } else | 327 | } else |
| 328 | control->framerate_factor = value; | 328 | control->framerate_factor = value; |
| 329 | 329 | ||
| 330 | err = read_property_u32(node, "exposure_factor", &value); | ||
| 331 | if (err) { | ||
| 332 | dev_err(dev, "%s:%s:property missing\n", | ||
| 333 | __func__, "framerate_factor"); | ||
| 334 | control->exposure_factor = 1; | ||
| 335 | } else | ||
| 336 | control->exposure_factor = value; | ||
| 337 | |||
| 330 | /* ignore err for this prop */ | 338 | /* ignore err for this prop */ |
| 331 | err = read_property_u32(node, "inherent_gain", &value); | 339 | err = read_property_u32(node, "inherent_gain", &value); |
| 332 | if (err) | 340 | if (err) |
| @@ -350,6 +358,14 @@ static int sensor_common_parse_control_props( | |||
| 350 | } else | 358 | } else |
| 351 | control->max_gain_val = value; | 359 | control->max_gain_val = value; |
| 352 | 360 | ||
| 361 | err = read_property_u32(node, "step_gain_val", &value); | ||
| 362 | if (err) { | ||
| 363 | dev_err(dev, "%s:%s:property missing\n", | ||
| 364 | __func__, "step_gain_val"); | ||
| 365 | control->step_gain_val = 0; | ||
| 366 | } else | ||
| 367 | control->step_gain_val = value; | ||
| 368 | |||
| 353 | /* ignore err for this prop */ | 369 | /* ignore err for this prop */ |
| 354 | err = read_property_u32(node, "min_hdr_ratio", &value); | 370 | err = read_property_u32(node, "min_hdr_ratio", &value); |
| 355 | if (err) | 371 | if (err) |
| @@ -379,6 +395,14 @@ static int sensor_common_parse_control_props( | |||
| 379 | } else | 395 | } else |
| 380 | control->max_framerate = value; | 396 | control->max_framerate = value; |
| 381 | 397 | ||
| 398 | err = read_property_u32(node, "step_framerate", &value); | ||
| 399 | if (err) { | ||
| 400 | dev_err(dev, "%s:%s:property missing\n", | ||
| 401 | __func__, "step_framerate"); | ||
| 402 | control->step_framerate = 0; | ||
| 403 | } else | ||
| 404 | control->step_framerate = value; | ||
| 405 | |||
| 382 | err = read_property_u64(node, "min_exp_time", &val64); | 406 | err = read_property_u64(node, "min_exp_time", &val64); |
| 383 | if (err) { | 407 | if (err) { |
| 384 | dev_err(dev, "%s:%s:property missing\n", | 408 | dev_err(dev, "%s:%s:property missing\n", |
| @@ -395,7 +419,15 @@ static int sensor_common_parse_control_props( | |||
| 395 | } else | 419 | } else |
| 396 | control->max_exp_time.val = val64; | 420 | control->max_exp_time.val = val64; |
| 397 | 421 | ||
| 398 | return err; | 422 | err = read_property_u64(node, "step_exp_time", &val64); |
| 423 | if (err) { | ||
| 424 | dev_err(dev, "%s:%s:property missing\n", | ||
| 425 | __func__, "step_exp_time"); | ||
| 426 | control->step_exp_time.val = 0; | ||
| 427 | } else | ||
| 428 | control->step_exp_time.val = val64; | ||
| 429 | |||
| 430 | return 0; | ||
| 399 | } | 431 | } |
| 400 | 432 | ||
| 401 | int sensor_common_init_sensor_properties( | 433 | int sensor_common_init_sensor_properties( |
diff --git a/drivers/media/platform/tegra/camera/tegracam_core.c b/drivers/media/platform/tegra/camera/tegracam_core.c new file mode 100644 index 000000000..25a1593be --- /dev/null +++ b/drivers/media/platform/tegra/camera/tegracam_core.c | |||
| @@ -0,0 +1,203 @@ | |||
| 1 | /* | ||
| 2 | * tegracam_core - tegra camera framework initialization | ||
| 3 | * | ||
| 4 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | #include <linux/types.h> | ||
| 19 | #include <media/tegra-v4l2-camera.h> | ||
| 20 | #include <media/tegracam_core.h> | ||
| 21 | |||
| 22 | |||
| 23 | void tegracam_set_privdata(struct tegracam_device *tc_dev, void *priv) | ||
| 24 | { | ||
| 25 | tc_dev->s_data->priv = priv; | ||
| 26 | } | ||
| 27 | EXPORT_SYMBOL_GPL(tegracam_set_privdata); | ||
| 28 | |||
| 29 | void *tegracam_get_privdata(struct tegracam_device *tc_dev) | ||
| 30 | { | ||
| 31 | return tc_dev->s_data->priv; | ||
| 32 | } | ||
| 33 | EXPORT_SYMBOL_GPL(tegracam_get_privdata); | ||
| 34 | |||
| 35 | int tegracam_device_register(struct tegracam_device *tc_dev) | ||
| 36 | { | ||
| 37 | struct device *dev = tc_dev->dev; | ||
| 38 | struct tegracam_ctrl_handler *ctrl_hdl = NULL; | ||
| 39 | struct camera_common_power_rail *pw_rail = NULL; | ||
| 40 | struct camera_common_data *s_data = NULL; | ||
| 41 | struct sensor_mode_properties *sensor_mode = NULL; | ||
| 42 | struct sensor_signal_properties *signal_props = NULL; | ||
| 43 | struct sensor_image_properties *image_props = NULL; | ||
| 44 | u32 mode_idx = 0; | ||
| 45 | int err = 0; | ||
| 46 | |||
| 47 | s_data = devm_kzalloc(dev, | ||
| 48 | sizeof(struct camera_common_data), GFP_KERNEL); | ||
| 49 | s_data->dev = dev; | ||
| 50 | |||
| 51 | ctrl_hdl = devm_kzalloc(dev, | ||
| 52 | sizeof(struct tegracam_ctrl_handler), GFP_KERNEL); | ||
| 53 | ctrl_hdl->s_data = s_data; | ||
| 54 | s_data->tegracam_ctrl_hdl = ctrl_hdl; | ||
| 55 | |||
| 56 | pw_rail = devm_kzalloc(dev, | ||
| 57 | sizeof(struct camera_common_power_rail), GFP_KERNEL); | ||
| 58 | s_data->power = pw_rail; | ||
| 59 | |||
| 60 | s_data->regmap = devm_regmap_init_i2c(tc_dev->client, | ||
| 61 | tc_dev->dev_regmap_config); | ||
| 62 | if (IS_ERR(s_data->regmap)) { | ||
| 63 | dev_err(dev, | ||
| 64 | "regmap init failed: %ld\n", PTR_ERR(s_data->regmap)); | ||
| 65 | return -ENODEV; | ||
| 66 | } | ||
| 67 | |||
| 68 | if (!tc_dev->sensor_ops) { | ||
| 69 | dev_err(dev, "sensor ops not initialized\n"); | ||
| 70 | return -EINVAL; | ||
| 71 | } | ||
| 72 | s_data->ops = tc_dev->sensor_ops; | ||
| 73 | |||
| 74 | s_data->pdata = tc_dev->sensor_ops->parse_dt(dev); | ||
| 75 | if (!s_data->pdata) { | ||
| 76 | dev_err(dev, "unable to get platform data\n"); | ||
| 77 | return -EFAULT; | ||
| 78 | } | ||
| 79 | |||
| 80 | err = tc_dev->sensor_ops->power_get(s_data); | ||
| 81 | if (err) { | ||
| 82 | dev_err(dev, "unable to power get\n"); | ||
| 83 | return -EFAULT; | ||
| 84 | } | ||
| 85 | |||
| 86 | err = camera_common_initialize(s_data, tc_dev->name); | ||
| 87 | if (err) { | ||
| 88 | dev_err(dev, "Failed to initialize %s\n", tc_dev->name); | ||
| 89 | return err; | ||
| 90 | } | ||
| 91 | |||
| 92 | /* TODO: updated default mode from DT ?? */ | ||
| 93 | mode_idx = s_data->mode_prop_idx = 0; | ||
| 94 | /* init format context */ | ||
| 95 | /*TODO: compile frmfmt array from DT */ | ||
| 96 | s_data->frmfmt = tc_dev->sensor_ops->frmfmt_table; | ||
| 97 | s_data->numfmts = tc_dev->sensor_ops->numfrmfmts; | ||
| 98 | sensor_mode = &s_data->sensor_props.sensor_modes[mode_idx]; | ||
| 99 | signal_props = &sensor_mode->signal_properties; | ||
| 100 | image_props = &sensor_mode->image_properties; | ||
| 101 | |||
| 102 | s_data->def_mode = s_data->frmfmt[mode_idx].mode; | ||
| 103 | s_data->colorfmt = | ||
| 104 | camera_common_find_pixelfmt(image_props->pixel_format); | ||
| 105 | s_data->def_width = s_data->fmt_width = | ||
| 106 | s_data->frmfmt[mode_idx].size.width; | ||
| 107 | s_data->def_height = s_data->fmt_height = | ||
| 108 | s_data->frmfmt[mode_idx].size.height; | ||
| 109 | s_data->def_clk_freq = signal_props->mclk_freq * 1000; | ||
| 110 | |||
| 111 | tc_dev->s_data = s_data; | ||
| 112 | |||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | EXPORT_SYMBOL_GPL(tegracam_device_register); | ||
| 116 | |||
| 117 | int tegracam_v4l2subdev_register(struct tegracam_device *tc_dev, | ||
| 118 | bool is_sensor) | ||
| 119 | { | ||
| 120 | struct camera_common_data *s_data = tc_dev->s_data; | ||
| 121 | struct tegracam_ctrl_handler *ctrl_hdl = s_data->tegracam_ctrl_hdl; | ||
| 122 | struct v4l2_subdev *sd = NULL; | ||
| 123 | struct device *dev = tc_dev->dev; | ||
| 124 | int err = 0; | ||
| 125 | |||
| 126 | /* init v4l2 subdevice for registration */ | ||
| 127 | sd = &s_data->subdev; | ||
| 128 | if (!sd || !tc_dev->client) { | ||
| 129 | dev_err(dev, "Invalid subdev context\n"); | ||
| 130 | return -ENODEV; | ||
| 131 | } | ||
| 132 | |||
| 133 | if (!tc_dev->v4l2sd_ops || !tc_dev->v4l2sd_internal_ops) { | ||
| 134 | dev_err(dev, "uninitialized v4l2 subdev ops\n"); | ||
| 135 | return -EINVAL; | ||
| 136 | } | ||
| 137 | |||
| 138 | if (!tc_dev->media_ops) { | ||
| 139 | dev_err(dev, "uninitialized media entiry ops\n"); | ||
| 140 | return -EINVAL; | ||
| 141 | } | ||
| 142 | |||
| 143 | if (!tc_dev->tcctrl_ops) { | ||
| 144 | dev_err(dev, "uninitialized control ops\n"); | ||
| 145 | return -EINVAL; | ||
| 146 | } | ||
| 147 | |||
| 148 | v4l2_i2c_subdev_init(sd, tc_dev->client, tc_dev->v4l2sd_ops); | ||
| 149 | |||
| 150 | ctrl_hdl->ctrl_ops = tc_dev->tcctrl_ops; | ||
| 151 | err = tegracam_ctrl_handler_init(ctrl_hdl); | ||
| 152 | if (err) { | ||
| 153 | dev_err(dev, "Failed to init ctrls %s\n", tc_dev->name); | ||
| 154 | return err; | ||
| 155 | } | ||
| 156 | s_data->numctrls = tc_dev->numctrls; | ||
| 157 | sd->ctrl_handler = s_data->ctrl_handler = &ctrl_hdl->ctrl_handler; | ||
| 158 | s_data->ctrls = ctrl_hdl->ctrls; | ||
| 159 | |||
| 160 | sd->internal_ops = tc_dev->v4l2sd_internal_ops; | ||
| 161 | sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | | ||
| 162 | V4L2_SUBDEV_FL_HAS_EVENTS; | ||
| 163 | |||
| 164 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
| 165 | tc_dev->pad.flags = MEDIA_PAD_FL_SOURCE; | ||
| 166 | sd->entity.ops = tc_dev->media_ops; | ||
| 167 | err = tegra_media_entity_init(&sd->entity, | ||
| 168 | 1, &tc_dev->pad, true, is_sensor); | ||
| 169 | if (err < 0) { | ||
| 170 | dev_err(dev, "unable to init media entity\n"); | ||
| 171 | return err; | ||
| 172 | } | ||
| 173 | #endif | ||
| 174 | |||
| 175 | err = v4l2_async_register_subdev(sd); | ||
| 176 | if (err) | ||
| 177 | return err; | ||
| 178 | |||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | EXPORT_SYMBOL_GPL(tegracam_v4l2subdev_register); | ||
| 182 | |||
| 183 | void tegracam_device_unregister(struct tegracam_device *tc_dev) | ||
| 184 | { | ||
| 185 | struct camera_common_data *s_data = tc_dev->s_data; | ||
| 186 | |||
| 187 | tc_dev->sensor_ops->power_put(s_data); | ||
| 188 | camera_common_cleanup(s_data); | ||
| 189 | } | ||
| 190 | EXPORT_SYMBOL_GPL(tegracam_device_unregister); | ||
| 191 | |||
| 192 | void tegracam_v4l2subdev_unregister(struct tegracam_device *tc_dev) | ||
| 193 | { | ||
| 194 | struct camera_common_data *s_data = tc_dev->s_data; | ||
| 195 | struct v4l2_subdev *sd = &s_data->subdev; | ||
| 196 | |||
| 197 | v4l2_ctrl_handler_free(s_data->ctrl_handler); | ||
| 198 | v4l2_async_unregister_subdev(sd); | ||
| 199 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
| 200 | media_entity_cleanup(&sd->entity); | ||
| 201 | #endif | ||
| 202 | } | ||
| 203 | EXPORT_SYMBOL_GPL(tegracam_v4l2subdev_unregister); | ||
diff --git a/drivers/media/platform/tegra/camera/tegracam_ctrls.c b/drivers/media/platform/tegra/camera/tegracam_ctrls.c new file mode 100644 index 000000000..b87570d3e --- /dev/null +++ b/drivers/media/platform/tegra/camera/tegracam_ctrls.c | |||
| @@ -0,0 +1,335 @@ | |||
| 1 | /* | ||
| 2 | * tegracam_ctrls - control framework for tegra camera drivers | ||
| 3 | * | ||
| 4 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | #include <linux/types.h> | ||
| 19 | #include <media/tegra-v4l2-camera.h> | ||
| 20 | #include <media/camera_common.h> | ||
| 21 | |||
| 22 | #define CTRL_U32_MIN 0 | ||
| 23 | #define CTRL_U32_MAX 0x7FFFFFFF | ||
| 24 | #define CTRL_U64_MIN 0 | ||
| 25 | #define CTRL_U64_MAX 0x7FFFFFFFFFFFFFFFLL | ||
| 26 | #define CTRL_S32_MIN 0x80000000 | ||
| 27 | #define CTRL_S32_MAX 0x7FFFFFFF | ||
| 28 | #define CTRL_S64_MIN 0x8000000000000000LL | ||
| 29 | #define CTRL_S64_MAX 0x7FFFFFFFFFFFFFFFLL | ||
| 30 | #define CTRL_MAX_STR_SIZE 4096 | ||
| 31 | |||
| 32 | static int tegracam_s_ctrl(struct v4l2_ctrl *ctrl); | ||
| 33 | static const struct v4l2_ctrl_ops tegracam_ctrl_ops = { | ||
| 34 | .s_ctrl = tegracam_s_ctrl, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static struct v4l2_ctrl_config ctrl_cfg_list[] = { | ||
| 38 | /* Do not change the name field for the controls! */ | ||
| 39 | { | ||
| 40 | .ops = &tegracam_ctrl_ops, | ||
| 41 | .id = TEGRA_CAMERA_CID_GAIN, | ||
| 42 | .name = "Gain", | ||
| 43 | .type = V4L2_CTRL_TYPE_INTEGER64, | ||
| 44 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
| 45 | .min = CTRL_U64_MIN, | ||
| 46 | .max = CTRL_U64_MAX, | ||
| 47 | .def = CTRL_U64_MIN, | ||
| 48 | .step = 1, | ||
| 49 | }, | ||
| 50 | { | ||
| 51 | .ops = &tegracam_ctrl_ops, | ||
| 52 | .id = TEGRA_CAMERA_CID_EXPOSURE, | ||
| 53 | .name = "Exposure", | ||
| 54 | .type = V4L2_CTRL_TYPE_INTEGER64, | ||
| 55 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
| 56 | .min = CTRL_U64_MIN, | ||
| 57 | .max = CTRL_U64_MAX, | ||
| 58 | .def = CTRL_U64_MIN, | ||
| 59 | .step = 1, | ||
| 60 | }, | ||
| 61 | { | ||
| 62 | .ops = &tegracam_ctrl_ops, | ||
| 63 | .id = TEGRA_CAMERA_CID_FRAME_RATE, | ||
| 64 | .name = "Frame Rate", | ||
| 65 | .type = V4L2_CTRL_TYPE_INTEGER64, | ||
| 66 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
| 67 | .min = CTRL_U64_MIN, | ||
| 68 | .max = CTRL_U64_MAX, | ||
| 69 | .def = CTRL_U64_MIN, | ||
| 70 | .step = 1, | ||
| 71 | }, | ||
| 72 | { | ||
| 73 | .ops = &tegracam_ctrl_ops, | ||
| 74 | .id = TEGRA_CAMERA_CID_GROUP_HOLD, | ||
| 75 | .name = "Group Hold", | ||
| 76 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
| 77 | .min = 0, | ||
| 78 | .max = 1, | ||
| 79 | .def = 0, | ||
| 80 | .step = 1, | ||
| 81 | }, | ||
| 82 | { | ||
| 83 | .ops = &tegracam_ctrl_ops, | ||
| 84 | .id = TEGRA_CAMERA_CID_EEPROM_DATA, | ||
| 85 | .name = "EEPROM Data", | ||
| 86 | .type = V4L2_CTRL_TYPE_STRING, | ||
| 87 | .flags = V4L2_CTRL_FLAG_READ_ONLY, | ||
| 88 | .min = 0, | ||
| 89 | .max = CTRL_MAX_STR_SIZE, | ||
| 90 | .step = 2, | ||
| 91 | }, | ||
| 92 | { | ||
| 93 | .ops = &tegracam_ctrl_ops, | ||
| 94 | .id = TEGRA_CAMERA_CID_FUSE_ID, | ||
| 95 | .name = "Fuse ID", | ||
| 96 | .type = V4L2_CTRL_TYPE_STRING, | ||
| 97 | .flags = V4L2_CTRL_FLAG_READ_ONLY, | ||
| 98 | .min = 0, | ||
| 99 | .max = CTRL_MAX_STR_SIZE, | ||
| 100 | .step = 2, | ||
| 101 | }, | ||
| 102 | }; | ||
| 103 | |||
| 104 | static int tegracam_get_ctrl_index(u32 cid) | ||
| 105 | { | ||
| 106 | int i; | ||
| 107 | |||
| 108 | for (i = 0; i < ARRAY_SIZE(ctrl_cfg_list); i++) { | ||
| 109 | if (ctrl_cfg_list[i].id == cid) | ||
| 110 | return i; | ||
| 111 | } | ||
| 112 | |||
| 113 | return -EINVAL; | ||
| 114 | } | ||
| 115 | |||
| 116 | static int tegracam_get_string_ctrl_size(u32 cid, | ||
| 117 | const struct tegracam_ctrl_ops *ops) | ||
| 118 | { | ||
| 119 | u32 index = 0; | ||
| 120 | |||
| 121 | switch (cid) { | ||
| 122 | case TEGRA_CAMERA_CID_EEPROM_DATA: | ||
| 123 | index = TEGRA_CAM_STRING_CTRL_EEPROM_INDEX; | ||
| 124 | break; | ||
| 125 | case TEGRA_CAMERA_CID_FUSE_ID: | ||
| 126 | index = TEGRA_CAM_STRING_CTRL_FUSEID_INDEX; | ||
| 127 | break; | ||
| 128 | case TEGRA_CAMERA_CID_OTP_DATA: | ||
| 129 | index = TEGRA_CAM_STRING_CTRL_OTP_INDEX; | ||
| 130 | break; | ||
| 131 | default: | ||
| 132 | return -EINVAL; | ||
| 133 | } | ||
| 134 | |||
| 135 | return ops->string_ctrl_size[index]; | ||
| 136 | } | ||
| 137 | |||
| 138 | static int tegracam_setup_string_ctrls(struct camera_common_data *s_data, | ||
| 139 | struct tegracam_ctrl_handler *handler) | ||
| 140 | { | ||
| 141 | const struct tegracam_ctrl_ops *ops = handler->ctrl_ops; | ||
| 142 | u32 numctrls = ops->numctrls; | ||
| 143 | int i; | ||
| 144 | int err = 0; | ||
| 145 | |||
| 146 | for (i = 0; i < numctrls; i++) { | ||
| 147 | struct v4l2_ctrl *ctrl = handler->ctrls[i]; | ||
| 148 | |||
| 149 | if (ctrl->type == V4L2_CTRL_TYPE_STRING) { | ||
| 150 | err = ops->fill_string_ctrl(s_data, ctrl); | ||
| 151 | if (err) | ||
| 152 | return err; | ||
| 153 | } | ||
| 154 | } | ||
| 155 | |||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | static int tegracam_s_ctrl(struct v4l2_ctrl *ctrl) | ||
| 160 | { | ||
| 161 | struct tegracam_ctrl_handler *handler = | ||
| 162 | container_of(ctrl->handler, | ||
| 163 | struct tegracam_ctrl_handler, ctrl_handler); | ||
| 164 | const struct tegracam_ctrl_ops *ops = handler->ctrl_ops; | ||
| 165 | struct camera_common_data *s_data = handler->s_data; | ||
| 166 | int err = 0; | ||
| 167 | u32 status = 0; | ||
| 168 | |||
| 169 | if (v4l2_subdev_call(&s_data->subdev, video, g_input_status, &status)) { | ||
| 170 | dev_err(s_data->dev, "power status query unsupported\n"); | ||
| 171 | return -ENOTTY; | ||
| 172 | } | ||
| 173 | |||
| 174 | /* power state is turned off, do not program sensor now */ | ||
| 175 | if (!status) | ||
| 176 | return 0; | ||
| 177 | |||
| 178 | switch (ctrl->id) { | ||
| 179 | case TEGRA_CAMERA_CID_GAIN: | ||
| 180 | err = ops->set_gain(s_data, *ctrl->p_new.p_s64); | ||
| 181 | break; | ||
| 182 | case TEGRA_CAMERA_CID_FRAME_RATE: | ||
| 183 | err = ops->set_frame_rate(s_data, *ctrl->p_new.p_s64); | ||
| 184 | break; | ||
| 185 | case TEGRA_CAMERA_CID_EXPOSURE: | ||
| 186 | err = ops->set_exposure(s_data, *ctrl->p_new.p_s64); | ||
| 187 | break; | ||
| 188 | case TEGRA_CAMERA_CID_GROUP_HOLD: | ||
| 189 | err = ops->set_group_hold(s_data, ctrl->val); | ||
| 190 | break; | ||
| 191 | default: | ||
| 192 | pr_err("%s: unknown ctrl id.\n", __func__); | ||
| 193 | return -EINVAL; | ||
| 194 | } | ||
| 195 | |||
| 196 | return err; | ||
| 197 | } | ||
| 198 | |||
| 199 | int tegracam_init_ctrl_ranges_by_mode( | ||
| 200 | struct tegracam_ctrl_handler *handler, | ||
| 201 | u32 modeidx) | ||
| 202 | { | ||
| 203 | struct camera_common_data *s_data = handler->s_data; | ||
| 204 | struct sensor_control_properties *ctrlprops = NULL; | ||
| 205 | int i; | ||
| 206 | |||
| 207 | if (modeidx >= s_data->sensor_props.num_modes) | ||
| 208 | return -EINVAL; | ||
| 209 | |||
| 210 | ctrlprops = | ||
| 211 | &s_data->sensor_props.sensor_modes[modeidx].control_properties; | ||
| 212 | |||
| 213 | for (i = 0; i < handler->numctrls; i++) { | ||
| 214 | struct v4l2_ctrl *ctrl = handler->ctrls[i]; | ||
| 215 | int err = 0; | ||
| 216 | |||
| 217 | switch (ctrl->id) { | ||
| 218 | case TEGRA_CAMERA_CID_GAIN: | ||
| 219 | err = v4l2_ctrl_modify_range(ctrl, | ||
| 220 | ctrlprops->min_gain_val, | ||
| 221 | ctrlprops->max_gain_val, | ||
| 222 | ctrlprops->step_gain_val, | ||
| 223 | ctrlprops->min_gain_val); | ||
| 224 | break; | ||
| 225 | case TEGRA_CAMERA_CID_FRAME_RATE: | ||
| 226 | err = v4l2_ctrl_modify_range(ctrl, | ||
| 227 | ctrlprops->min_framerate, | ||
| 228 | ctrlprops->max_framerate, | ||
| 229 | ctrlprops->step_framerate, | ||
| 230 | ctrlprops->max_framerate); | ||
| 231 | break; | ||
| 232 | case TEGRA_CAMERA_CID_EXPOSURE: | ||
| 233 | err = v4l2_ctrl_modify_range(ctrl, | ||
| 234 | ctrlprops->min_exp_time.val, | ||
| 235 | ctrlprops->max_exp_time.val, | ||
| 236 | ctrlprops->step_exp_time.val, | ||
| 237 | ctrlprops->max_exp_time.val); | ||
| 238 | break; | ||
| 239 | default: | ||
| 240 | /* Not required to modify these control ranges */ | ||
| 241 | break; | ||
| 242 | } | ||
| 243 | |||
| 244 | if (err) { | ||
| 245 | dev_err(s_data->dev, | ||
| 246 | "ctrl %s range update failed\n", ctrl->name); | ||
| 247 | return err; | ||
| 248 | } | ||
| 249 | } | ||
| 250 | |||
| 251 | return 0; | ||
| 252 | } | ||
| 253 | EXPORT_SYMBOL_GPL(tegracam_init_ctrl_ranges_by_mode); | ||
| 254 | |||
| 255 | int tegracam_ctrl_handler_init(struct tegracam_ctrl_handler *handler) | ||
| 256 | { | ||
| 257 | struct camera_common_data *s_data = handler->s_data; | ||
| 258 | struct v4l2_ctrl *ctrl; | ||
| 259 | struct v4l2_ctrl_config *ctrl_cfg; | ||
| 260 | struct device *dev = s_data->dev; | ||
| 261 | const struct tegracam_ctrl_ops *ops = handler->ctrl_ops; | ||
| 262 | const u32 *cids = ops->ctrl_cid_list; | ||
| 263 | u32 numctrls = ops->numctrls; | ||
| 264 | int i; | ||
| 265 | int err = 0; | ||
| 266 | |||
| 267 | v4l2_ctrl_handler_init(&handler->ctrl_handler, numctrls); | ||
| 268 | |||
| 269 | for (i = 0; i < numctrls; i++) { | ||
| 270 | int index = tegracam_get_ctrl_index(cids[i]); | ||
| 271 | int size = 0; | ||
| 272 | |||
| 273 | if (index >= ARRAY_SIZE(ctrl_cfg_list)) { | ||
| 274 | dev_err(dev, "unsupported control in the list\n"); | ||
| 275 | return -ENOTTY; | ||
| 276 | } | ||
| 277 | |||
| 278 | ctrl_cfg = &ctrl_cfg_list[index]; | ||
| 279 | if (ctrl_cfg->type == V4L2_CTRL_TYPE_STRING) { | ||
| 280 | size = tegracam_get_string_ctrl_size(ctrl_cfg->id, ops); | ||
| 281 | if (size < 0) { | ||
| 282 | dev_err(dev, "Invalid string ctrl size\n"); | ||
| 283 | return -EINVAL; | ||
| 284 | } | ||
| 285 | ctrl_cfg->max = size; | ||
| 286 | } | ||
| 287 | |||
| 288 | ctrl = v4l2_ctrl_new_custom(&handler->ctrl_handler, | ||
| 289 | ctrl_cfg, NULL); | ||
| 290 | if (ctrl == NULL) { | ||
| 291 | dev_err(dev, "Failed to init %s ctrl\n", | ||
| 292 | ctrl_cfg->name); | ||
| 293 | return -EINVAL; | ||
| 294 | } | ||
| 295 | |||
| 296 | if (ctrl_cfg->type == V4L2_CTRL_TYPE_STRING && | ||
| 297 | ctrl_cfg->flags & V4L2_CTRL_FLAG_READ_ONLY) { | ||
| 298 | ctrl->p_new.p_char = devm_kzalloc(s_data->dev, | ||
| 299 | size + 1, GFP_KERNEL); | ||
| 300 | } | ||
| 301 | handler->ctrls[i] = ctrl; | ||
| 302 | }; | ||
| 303 | |||
| 304 | handler->numctrls = numctrls; | ||
| 305 | err = v4l2_ctrl_handler_setup(&handler->ctrl_handler); | ||
| 306 | if (err) { | ||
| 307 | dev_err(dev, "Error %d in control hdl setup\n", err); | ||
| 308 | goto error; | ||
| 309 | } | ||
| 310 | |||
| 311 | err = handler->ctrl_handler.error; | ||
| 312 | if (err) { | ||
| 313 | dev_err(dev, "Error %d adding controls\n", err); | ||
| 314 | goto error; | ||
| 315 | } | ||
| 316 | |||
| 317 | err = tegracam_setup_string_ctrls(s_data, handler); | ||
| 318 | if (err) { | ||
| 319 | dev_err(dev, "setup string controls failed\n"); | ||
| 320 | goto error; | ||
| 321 | } | ||
| 322 | |||
| 323 | err = tegracam_init_ctrl_ranges_by_mode(handler, | ||
| 324 | s_data->mode_prop_idx); | ||
| 325 | if (err) { | ||
| 326 | dev_err(dev, "Error %d updating control ranges\n", err); | ||
| 327 | goto error; | ||
| 328 | } | ||
| 329 | |||
| 330 | return 0; | ||
| 331 | error: | ||
| 332 | v4l2_ctrl_handler_free(&handler->ctrl_handler); | ||
| 333 | return err; | ||
| 334 | } | ||
| 335 | EXPORT_SYMBOL_GPL(tegracam_ctrl_handler_init); | ||
diff --git a/include/media/camera_common.h b/include/media/camera_common.h index 674a29e6c..6c3ae9531 100644 --- a/include/media/camera_common.h +++ b/include/media/camera_common.h | |||
| @@ -158,16 +158,42 @@ struct camera_common_framesync { | |||
| 158 | struct camera_common_data; | 158 | struct camera_common_data; |
| 159 | 159 | ||
| 160 | struct camera_common_sensor_ops { | 160 | struct camera_common_sensor_ops { |
| 161 | u32 numfrmfmts; | ||
| 162 | const struct camera_common_frmfmt *frmfmt_table; | ||
| 161 | int (*power_on)(struct camera_common_data *s_data); | 163 | int (*power_on)(struct camera_common_data *s_data); |
| 162 | int (*power_off)(struct camera_common_data *s_data); | 164 | int (*power_off)(struct camera_common_data *s_data); |
| 163 | int (*write_reg)(struct camera_common_data *s_data, | 165 | int (*write_reg)(struct camera_common_data *s_data, |
| 164 | u16 addr, u8 val); | 166 | u16 addr, u8 val); |
| 165 | int (*read_reg)(struct camera_common_data *s_data, | 167 | int (*read_reg)(struct camera_common_data *s_data, |
| 166 | u16 addr, u8 *val); | 168 | u16 addr, u8 *val); |
| 169 | struct camera_common_pdata *(*parse_dt)(struct device *dev); | ||
| 170 | int (*power_get)(struct camera_common_data *s_data); | ||
| 171 | int (*power_put)(struct camera_common_data *s_data); | ||
| 167 | int (*get_framesync)(struct camera_common_data *s_data, | 172 | int (*get_framesync)(struct camera_common_data *s_data, |
| 168 | struct camera_common_framesync *vshs); | 173 | struct camera_common_framesync *vshs); |
| 169 | }; | 174 | }; |
| 170 | 175 | ||
| 176 | struct tegracam_ctrl_ops { | ||
| 177 | u32 numctrls; | ||
| 178 | u32 string_ctrl_size[TEGRA_CAM_MAX_STRING_CONTROLS]; | ||
| 179 | const u32 *ctrl_cid_list; | ||
| 180 | int (*set_gain)(struct camera_common_data *s_data, s64 val); | ||
| 181 | int (*set_exposure)(struct camera_common_data *s_data, s64 val); | ||
| 182 | int (*set_frame_rate)(struct camera_common_data *s_data, s64 val); | ||
| 183 | int (*set_group_hold)(struct camera_common_data *s_data, bool val); | ||
| 184 | int (*fill_string_ctrl)(struct camera_common_data *s_data, | ||
| 185 | struct v4l2_ctrl *ctrl); | ||
| 186 | }; | ||
| 187 | |||
| 188 | struct tegracam_ctrl_handler { | ||
| 189 | struct v4l2_ctrl_handler ctrl_handler; | ||
| 190 | const struct tegracam_ctrl_ops *ctrl_ops; | ||
| 191 | struct camera_common_data *s_data; | ||
| 192 | |||
| 193 | int numctrls; | ||
| 194 | struct v4l2_ctrl *ctrls[MAX_CID_CONTROLS]; | ||
| 195 | }; | ||
| 196 | |||
| 171 | struct camera_common_data { | 197 | struct camera_common_data { |
| 172 | struct camera_common_sensor_ops *ops; | 198 | struct camera_common_sensor_ops *ops; |
| 173 | struct v4l2_ctrl_handler *ctrl_handler; | 199 | struct v4l2_ctrl_handler *ctrl_handler; |
| @@ -181,6 +207,10 @@ struct camera_common_data { | |||
| 181 | struct v4l2_ctrl **ctrls; | 207 | struct v4l2_ctrl **ctrls; |
| 182 | 208 | ||
| 183 | struct sensor_properties sensor_props; | 209 | struct sensor_properties sensor_props; |
| 210 | /* TODO: cleanup neeeded once all the sensors adapt new framework */ | ||
| 211 | struct tegracam_ctrl_handler *tegracam_ctrl_hdl; | ||
| 212 | struct regmap *regmap; | ||
| 213 | struct camera_common_pdata *pdata; | ||
| 184 | 214 | ||
| 185 | void *priv; | 215 | void *priv; |
| 186 | int numctrls; | 216 | int numctrls; |
| @@ -247,6 +277,9 @@ int camera_common_parse_clocks(struct device *dev, | |||
| 247 | struct camera_common_pdata *pdata); | 277 | struct camera_common_pdata *pdata); |
| 248 | int camera_common_parse_ports(struct device *dev, | 278 | int camera_common_parse_ports(struct device *dev, |
| 249 | struct camera_common_data *s_data); | 279 | struct camera_common_data *s_data); |
| 280 | int camera_common_mclk_enable(struct camera_common_data *s_data); | ||
| 281 | void camera_common_mclk_disable(struct camera_common_data *s_data); | ||
| 282 | |||
| 250 | 283 | ||
| 251 | int camera_common_debugfs_show(struct seq_file *s, void *unused); | 284 | int camera_common_debugfs_show(struct seq_file *s, void *unused); |
| 252 | ssize_t camera_common_debugfs_write( | 285 | ssize_t camera_common_debugfs_write( |
| @@ -294,6 +327,15 @@ void camera_common_cleanup(struct camera_common_data *s_data); | |||
| 294 | int camera_common_focuser_init(struct camera_common_focuser_data *s_data); | 327 | int camera_common_focuser_init(struct camera_common_focuser_data *s_data); |
| 295 | int camera_common_focuser_s_power(struct v4l2_subdev *sd, int on); | 328 | int camera_common_focuser_s_power(struct v4l2_subdev *sd, int on); |
| 296 | 329 | ||
| 330 | const struct camera_common_colorfmt *camera_common_find_pixelfmt( | ||
| 331 | unsigned int pix_fmt); | ||
| 332 | |||
| 333 | /* common control layer init */ | ||
| 334 | int tegracam_ctrl_handler_init(struct tegracam_ctrl_handler *handler); | ||
| 335 | int tegracam_init_ctrl_ranges_by_mode( | ||
| 336 | struct tegracam_ctrl_handler *handler, | ||
| 337 | u32 modeidx); | ||
| 338 | |||
| 297 | /* Regmap / RTCPU I2C driver interface */ | 339 | /* Regmap / RTCPU I2C driver interface */ |
| 298 | struct tegra_i2c_rtcpu_sensor; | 340 | struct tegra_i2c_rtcpu_sensor; |
| 299 | struct tegra_i2c_rtcpu_config; | 341 | struct tegra_i2c_rtcpu_config; |
diff --git a/include/media/tegra-v4l2-camera.h b/include/media/tegra-v4l2-camera.h index 5c5e2da75..4b6b54e47 100644 --- a/include/media/tegra-v4l2-camera.h +++ b/include/media/tegra-v4l2-camera.h | |||
| @@ -67,6 +67,11 @@ | |||
| 67 | */ | 67 | */ |
| 68 | #define FIXED_POINT_SCALING_FACTOR (1ULL << 22) | 68 | #define FIXED_POINT_SCALING_FACTOR (1ULL << 22) |
| 69 | 69 | ||
| 70 | #define TEGRA_CAM_MAX_STRING_CONTROLS 8 | ||
| 71 | #define TEGRA_CAM_STRING_CTRL_EEPROM_INDEX 0 | ||
| 72 | #define TEGRA_CAM_STRING_CTRL_FUSEID_INDEX 1 | ||
| 73 | #define TEGRA_CAM_STRING_CTRL_OTP_INDEX 2 | ||
| 74 | |||
| 70 | struct unpackedU64 { | 75 | struct unpackedU64 { |
| 71 | __u32 high; | 76 | __u32 high; |
| 72 | __u32 low; | 77 | __u32 low; |
| @@ -86,6 +91,7 @@ struct sensor_signal_properties { | |||
| 86 | __u32 discontinuous_clk; | 91 | __u32 discontinuous_clk; |
| 87 | __u32 dpcm_enable; | 92 | __u32 dpcm_enable; |
| 88 | __u32 tegra_sinterface; | 93 | __u32 tegra_sinterface; |
| 94 | __u32 reserved[7]; | ||
| 89 | }; | 95 | }; |
| 90 | 96 | ||
| 91 | struct sensor_image_properties { | 97 | struct sensor_image_properties { |
| @@ -94,6 +100,7 @@ struct sensor_image_properties { | |||
| 94 | __u32 line_length; | 100 | __u32 line_length; |
| 95 | __u32 pixel_format; | 101 | __u32 pixel_format; |
| 96 | __u32 embedded_metadata_height; | 102 | __u32 embedded_metadata_height; |
| 103 | __u32 reserved[11]; | ||
| 97 | }; | 104 | }; |
| 98 | 105 | ||
| 99 | struct sensor_dv_timings { | 106 | struct sensor_dv_timings { |
| @@ -103,6 +110,7 @@ struct sensor_dv_timings { | |||
| 103 | __u32 vfrontporch; | 110 | __u32 vfrontporch; |
| 104 | __u32 vsync; | 111 | __u32 vsync; |
| 105 | __u32 vbackporch; | 112 | __u32 vbackporch; |
| 113 | __u32 reserved[10]; | ||
| 106 | }; | 114 | }; |
| 107 | 115 | ||
| 108 | struct sensor_control_properties { | 116 | struct sensor_control_properties { |
| @@ -117,6 +125,11 @@ struct sensor_control_properties { | |||
| 117 | __u32 max_framerate; | 125 | __u32 max_framerate; |
| 118 | union __u64val min_exp_time; | 126 | union __u64val min_exp_time; |
| 119 | union __u64val max_exp_time; | 127 | union __u64val max_exp_time; |
| 128 | __u32 step_gain_val; | ||
| 129 | __u32 step_framerate; | ||
| 130 | __u32 exposure_factor; | ||
| 131 | union __u64val step_exp_time; | ||
| 132 | __u32 reserved[14]; | ||
| 120 | }; | 133 | }; |
| 121 | 134 | ||
| 122 | struct sensor_mode_properties { | 135 | struct sensor_mode_properties { |
diff --git a/include/media/tegracam_core.h b/include/media/tegracam_core.h new file mode 100644 index 000000000..1a1e8a2f5 --- /dev/null +++ b/include/media/tegracam_core.h | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | /** | ||
| 2 | * tegracam_core.h - tegra camera framework core utilities | ||
| 3 | * | ||
| 4 | * Copyright (c) 2017, NVIDIA Corporation. All rights reserved. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef __TEGRACAM_CORE_H__ | ||
| 20 | #define __TEGRACAM_CORE_H__ | ||
| 21 | |||
| 22 | #include <media/camera_common.h> | ||
| 23 | |||
| 24 | struct tegracam_device { | ||
| 25 | struct camera_common_data *s_data; | ||
| 26 | struct media_pad pad; | ||
| 27 | /* variables to be filled by the driver to register */ | ||
| 28 | char name[32]; | ||
| 29 | struct i2c_client *client; | ||
| 30 | struct device *dev; | ||
| 31 | u32 numctrls; | ||
| 32 | const u32 *ctrl_cid_list; | ||
| 33 | const struct regmap_config *dev_regmap_config; | ||
| 34 | struct camera_common_sensor_ops *sensor_ops; | ||
| 35 | const struct v4l2_subdev_ops *v4l2sd_ops; | ||
| 36 | const struct v4l2_subdev_internal_ops *v4l2sd_internal_ops; | ||
| 37 | const struct media_entity_operations *media_ops; | ||
| 38 | const struct tegracam_ctrl_ops *tcctrl_ops; | ||
| 39 | }; | ||
| 40 | |||
| 41 | void tegracam_set_privdata(struct tegracam_device *tc_dev, void *priv); | ||
| 42 | void *tegracam_get_privdata(struct tegracam_device *tc_dev); | ||
| 43 | |||
| 44 | int tegracam_v4l2subdev_register(struct tegracam_device *tc_dev, | ||
| 45 | bool is_sensor); | ||
| 46 | void tegracam_v4l2subdev_unregister(struct tegracam_device *tc_dev); | ||
| 47 | int tegracam_device_register(struct tegracam_device *tc_dev); | ||
| 48 | void tegracam_device_unregister(struct tegracam_device *tc_dev); | ||
| 49 | #endif | ||
