summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBhanu Murthy V <bmurthyv@nvidia.com>2017-12-05 20:56:46 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-12-13 20:20:49 -0500
commit07857ffeb5a350e6d5fc9d5c4b3d56ff4434d7ab (patch)
tree1dc3fb7db0008f8ec82f52b9f417219dc0850e03
parentd00c9880a68fb83d1696e74f841d8226681ce586 (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/Makefile3
-rw-r--r--drivers/media/platform/tegra/camera/camera_common.c20
-rw-r--r--drivers/media/platform/tegra/camera/sensor_common.c34
-rw-r--r--drivers/media/platform/tegra/camera/tegracam_core.c203
-rw-r--r--drivers/media/platform/tegra/camera/tegracam_ctrls.c335
-rw-r--r--include/media/camera_common.h42
-rw-r--r--include/media/tegra-v4l2-camera.h13
-rw-r--r--include/media/tegracam_core.h49
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
8obj-y += vi/ 8obj-y += vi/
9obj-y += csi/ 9obj-y += csi/
10obj-y += camera_common.o camera_gpio.o sensor_common.o camera_version_utils.o 10obj-y += camera_common.o camera_gpio.o sensor_common.o camera_version_utils.o \
11 tegracam_ctrls.o tegracam_core.o
11obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += capture_common.o 12obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += capture_common.o
12obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += isp/isp_channel.o 13obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += isp/isp_channel.o
13obj-$(CONFIG_TEGRA_CAMERA_RTCPU) += isp/capture_isp.o 14obj-$(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}
393EXPORT_SYMBOL_GPL(camera_common_find_datafmt); 393EXPORT_SYMBOL_GPL(camera_common_find_datafmt);
394 394
395/* Find a data format by pixel format in an array*/
396const 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}
407EXPORT_SYMBOL_GPL(camera_common_find_pixelfmt);
408
395/* Filters for the sensor's supported colors */ 409/* Filters for the sensor's supported colors */
396static const struct camera_common_colorfmt *find_matching_color_fmt( 410static 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}
694EXPORT_SYMBOL_GPL(camera_common_enum_frameintervals); 708EXPORT_SYMBOL_GPL(camera_common_enum_frameintervals);
695 709
696static void camera_common_mclk_disable(struct camera_common_data *s_data) 710void 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}
723EXPORT_SYMBOL_GPL(camera_common_mclk_disable);
709 724
710static int camera_common_mclk_enable(struct camera_common_data *s_data) 725int 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}
746EXPORT_SYMBOL_GPL(camera_common_mclk_enable);
731 747
732void camera_common_dpd_disable(struct camera_common_data *s_data) 748void 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
401int sensor_common_init_sensor_properties( 433int 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
23void tegracam_set_privdata(struct tegracam_device *tc_dev, void *priv)
24{
25 tc_dev->s_data->priv = priv;
26}
27EXPORT_SYMBOL_GPL(tegracam_set_privdata);
28
29void *tegracam_get_privdata(struct tegracam_device *tc_dev)
30{
31 return tc_dev->s_data->priv;
32}
33EXPORT_SYMBOL_GPL(tegracam_get_privdata);
34
35int 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}
115EXPORT_SYMBOL_GPL(tegracam_device_register);
116
117int 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}
181EXPORT_SYMBOL_GPL(tegracam_v4l2subdev_register);
182
183void 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}
190EXPORT_SYMBOL_GPL(tegracam_device_unregister);
191
192void 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}
203EXPORT_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
32static int tegracam_s_ctrl(struct v4l2_ctrl *ctrl);
33static const struct v4l2_ctrl_ops tegracam_ctrl_ops = {
34 .s_ctrl = tegracam_s_ctrl,
35};
36
37static 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
104static 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
116static 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
138static 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
159static 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
199int 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}
253EXPORT_SYMBOL_GPL(tegracam_init_ctrl_ranges_by_mode);
254
255int 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;
331error:
332 v4l2_ctrl_handler_free(&handler->ctrl_handler);
333 return err;
334}
335EXPORT_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 {
158struct camera_common_data; 158struct camera_common_data;
159 159
160struct camera_common_sensor_ops { 160struct 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
176struct 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
188struct 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
171struct camera_common_data { 197struct 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);
248int camera_common_parse_ports(struct device *dev, 278int camera_common_parse_ports(struct device *dev,
249 struct camera_common_data *s_data); 279 struct camera_common_data *s_data);
280int camera_common_mclk_enable(struct camera_common_data *s_data);
281void camera_common_mclk_disable(struct camera_common_data *s_data);
282
250 283
251int camera_common_debugfs_show(struct seq_file *s, void *unused); 284int camera_common_debugfs_show(struct seq_file *s, void *unused);
252ssize_t camera_common_debugfs_write( 285ssize_t camera_common_debugfs_write(
@@ -294,6 +327,15 @@ void camera_common_cleanup(struct camera_common_data *s_data);
294int camera_common_focuser_init(struct camera_common_focuser_data *s_data); 327int camera_common_focuser_init(struct camera_common_focuser_data *s_data);
295int camera_common_focuser_s_power(struct v4l2_subdev *sd, int on); 328int camera_common_focuser_s_power(struct v4l2_subdev *sd, int on);
296 329
330const struct camera_common_colorfmt *camera_common_find_pixelfmt(
331 unsigned int pix_fmt);
332
333/* common control layer init */
334int tegracam_ctrl_handler_init(struct tegracam_ctrl_handler *handler);
335int 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 */
298struct tegra_i2c_rtcpu_sensor; 340struct tegra_i2c_rtcpu_sensor;
299struct tegra_i2c_rtcpu_config; 341struct 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
70struct unpackedU64 { 75struct 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
91struct sensor_image_properties { 97struct 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
99struct sensor_dv_timings { 106struct 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
108struct sensor_control_properties { 116struct 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
122struct sensor_mode_properties { 135struct 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
24struct 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
41void tegracam_set_privdata(struct tegracam_device *tc_dev, void *priv);
42void *tegracam_get_privdata(struct tegracam_device *tc_dev);
43
44int tegracam_v4l2subdev_register(struct tegracam_device *tc_dev,
45 bool is_sensor);
46void tegracam_v4l2subdev_unregister(struct tegracam_device *tc_dev);
47int tegracam_device_register(struct tegracam_device *tc_dev);
48void tegracam_device_unregister(struct tegracam_device *tc_dev);
49#endif