2 * sensor_common.c - utilities for tegra sensor drivers
4 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
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.
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
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/>.
19 #include <media/sensor_common.h>
20 #include <linux/of_graph.h>
21 #include <linux/string.h>
23 static int read_property_u32(
24 struct device_node *node, const char *name, u32 *value)
29 err = of_property_read_string(node, name, &str);
33 err = kstrtou32(str, 10, value);
40 static int read_property_u64(
41 struct device_node *node, const char *name, u64 *value)
46 err = of_property_read_string(node, name, &str);
50 err = kstrtou64(str, 10, value);
57 static int sensor_common_parse_signal_props(
58 struct device *dev, struct device_node *node,
59 struct sensor_signal_properties *signal)
64 /* Do not report error for these properties yet */
65 read_property_u32(node, "readout_orientation",
66 &signal->readout_orientation);
67 read_property_u32(node, "num_lanes",
69 read_property_u32(node, "mclk_khz",
71 read_property_u64(node, "pix_clk_hz",
72 &signal->pixel_clock.val);
73 read_property_u32(node, "cil_settletime",
74 &signal->cil_settletime);
75 /* initialize default if this prop not available */
76 err = of_property_read_string(node, "discontinuous_clk",
79 signal->discontinuous_clk =
80 !strncmp(temp_str, "yes", sizeof("yes"));
82 signal->discontinuous_clk = 1;
83 /* initialize default if this prop not available */
84 err = of_property_read_string(node, "dpcm_enable",
88 !strncmp(temp_str, "true", sizeof("true"));
90 signal->dpcm_enable = 0;
95 static int extract_pixel_format(
96 const char *pixel_t, u32 *format)
98 size_t size = strnlen(pixel_t, OF_MAX_STR_LEN);
100 if (strncmp(pixel_t, "bayer_bggr10", size) == 0)
101 *format = V4L2_PIX_FMT_SBGGR10;
102 else if (strncmp(pixel_t, "bayer_rggb10", size) == 0)
103 *format = V4L2_PIX_FMT_SRGGB10;
104 else if (strncmp(pixel_t, "bayer_bggr12", size) == 0)
105 *format = V4L2_PIX_FMT_SBGGR12;
106 else if (strncmp(pixel_t, "bayer_rggb12", size) == 0)
107 *format = V4L2_PIX_FMT_SRGGB12;
108 else if (strncmp(pixel_t, "bayer_wdr_pwl_rggb12", size) == 0)
109 *format = V4L2_PIX_FMT_SRGGB12;
110 else if (strncmp(pixel_t, "bayer_xbggr10p", size) == 0)
111 *format = V4L2_PIX_FMT_XBGGR10P;
112 else if (strncmp(pixel_t, "bayer_xrggb10p", size) == 0)
113 *format = V4L2_PIX_FMT_XRGGB10P;
115 pr_err("%s: Need to extend format%s\n", __func__, pixel_t);
122 static int sensor_common_parse_image_props(
123 struct device *dev, struct device_node *node,
124 struct sensor_image_properties *image)
126 const char *temp_str;
128 const char *phase_str, *mode_str;
132 err = read_property_u32(node, "active_w",
135 dev_err(dev, "%s:active_w property missing\n", __func__);
139 err = read_property_u32(node, "active_h",
142 dev_err(dev, "%s:active_h property missing\n", __func__);
146 err = read_property_u32(node, "line_length",
147 &image->line_length);
149 dev_err(dev, "%s:Line length property missing\n", __func__);
153 /* embedded_metadata_height is optional */
154 read_property_u32(node, "embedded_metadata_height",
155 &image->embedded_metadata_height);
157 err = of_property_read_string(node, "pixel_t", &temp_str);
159 dev_err(dev, "%s:pixel_t property missing\n", __func__);
161 /* check for alternative format string */
162 err = of_property_read_string(node, "pixel_phase", &phase_str);
165 "%s:pixel_phase property missing\n",
169 err = of_property_read_string(node, "mode_type", &mode_str);
172 "%s:mode_type property missing\n",
176 err = read_property_u32(node, "csi_pixel_bit_depth", &depth);
179 "%s:csi_pixel_bit_depth property missing\n",
183 sprintf(pix_format, "%s_%s%d", mode_str, phase_str, depth);
184 temp_str = pix_format;
186 err = extract_pixel_format(temp_str, &image->pixel_format);
188 dev_err(dev, "Unsupported pixel format\n");
196 static int sensor_common_parse_dv_timings(
197 struct device *dev, struct device_node *node,
198 struct sensor_dv_timings *timings)
200 /* Do not report error for these properties yet */
201 read_property_u32(node, "horz_front_porch",
202 &timings->hfrontporch);
203 read_property_u32(node, "horz_sync",
205 read_property_u32(node, "horz_back_porch",
206 &timings->hbackporch);
207 read_property_u32(node, "vert_front_porch",
208 &timings->vfrontporch);
209 read_property_u32(node, "vert_sync",
211 read_property_u32(node, "vert_back_porch",
212 &timings->vbackporch);
217 static int sensor_common_parse_control_props(
218 struct device *dev, struct device_node *node,
219 struct sensor_control_properties *control)
223 err = read_property_u32(node, "gain_factor",
224 &control->gain_factor);
226 dev_dbg(dev, "%s:%s:property missing\n",
227 __func__, "gain_factor");
231 err = read_property_u32(node, "framerate_factor",
232 &control->framerate_factor);
234 dev_err(dev, "%s:%s:property missing\n",
235 __func__, "framerate_factor");
237 /* ignore err for this prop */
238 err = read_property_u32(node, "inherent_gain",
239 &control->inherent_gain);
241 err = read_property_u32(node, "min_gain_val",
242 &control->min_gain_val);
244 dev_err(dev, "%s:%s:property missing\n",
245 __func__, "min_gain_val");
247 err = read_property_u32(node, "max_gain_val",
248 &control->max_gain_val);
250 dev_err(dev, "%s:%s:property missing\n",
251 __func__, "max_gain_val");
253 /* ignore err for this prop */
254 err = read_property_u32(node, "min_hdr_ratio",
255 &control->min_hdr_ratio);
256 err = read_property_u32(node, "max_hdr_ratio",
257 &control->max_hdr_ratio);
259 err = read_property_u32(node, "min_framerate",
260 &control->min_framerate);
262 dev_err(dev, "%s:%s:property missing\n",
263 __func__, "min_framerate");
265 err = read_property_u32(node, "max_framerate",
266 &control->max_framerate);
268 dev_err(dev, "%s:%s:property missing\n",
269 __func__, "max_framerate");
271 err = read_property_u64(node, "min_exp_time",
272 &control->min_exp_time.val);
274 dev_err(dev, "%s:%s:property missing\n",
275 __func__, "min_exp_time");
277 err = read_property_u64(node, "max_exp_time",
278 &control->max_exp_time.val);
280 dev_err(dev, "%s:%s:property missing\n",
281 __func__, "max_exp_time");
286 int sensor_common_init_sensor_properties(
287 struct device *dev, struct device_node *np,
288 struct sensor_properties *sensor)
290 char temp_str[OF_MAX_STR_LEN];
291 struct device_node *node = NULL;
295 /* get number of modes */
296 for (i = 0; num_modes < MAX_NUM_SENSOR_MODES; i++) {
297 snprintf(temp_str, sizeof(temp_str), "%s%d",
298 OF_SENSORMODE_PREFIX, i);
300 node = of_get_child_by_name(np, temp_str);
306 sensor->num_modes = num_modes;
313 sensor->sensor_modes = devm_kzalloc(dev,
314 num_modes * sizeof(struct sensor_mode_properties),
316 if (!sensor->sensor_modes) {
317 dev_err(dev, "Failed to allocate memory for sensor modes\n");
321 memset(sensor->sensor_modes, 0, num_modes *
322 sizeof(struct sensor_mode_properties));
324 for (i = 0; i < num_modes; i++) {
325 snprintf(temp_str, sizeof(temp_str), "%s%d",
326 OF_SENSORMODE_PREFIX, i);
328 node = of_get_child_by_name(np, temp_str);
330 dev_err(dev, "Failed to find mode\n");
335 err = sensor_common_parse_signal_props(dev, node,
336 &sensor->sensor_modes[i].signal_properties);
338 dev_err(dev, "Failed to read signal properties\n");
342 err = sensor_common_parse_image_props(dev, node,
343 &sensor->sensor_modes[i].image_properties);
345 dev_err(dev, "Failed to read image properties\n");
349 err = sensor_common_parse_dv_timings(dev, node,
350 &sensor->sensor_modes[i].dv_timings);
352 dev_err(dev, "Failed to read DV timings\n");
356 err = sensor_common_parse_control_props(dev, node,
357 &sensor->sensor_modes[i].control_properties);
359 dev_err(dev, "Failed to read control properties\n");
371 EXPORT_SYMBOL(sensor_common_init_sensor_properties);