• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2   * sensor_helper.c: helper function for sensors.
3   *
4   * Copyright (c) 2017 by Allwinnertech Co., Ltd.  http://www.allwinnertech.com
5   *
6   * Authors:  Zhao Wei <zhaowei@allwinnertech.com>
7   *
8   * This program is free software; you can redistribute it and/or modify
9   * it under the terms of the GNU General Public License version 2 as
10   * published by the Free Software Foundation.
11   */
12 
13 #include <linux/module.h>
14 #include <linux/videodev2.h>
15 #include <linux/v4l2-subdev.h>
16 #include <media/v4l2-dev.h>
17 
18 #include "camera.h"
19 #include "sensor_helper.h"
20 #include "../../vin-cci/sunxi_cci.h"
21 
22 char ccm0[I2C_NAME_SIZE] = "";
23 char ccm1[I2C_NAME_SIZE] = "";
24 
25 #define SENSOR_MODULE_NAME "vin_sensor_helper"
26 
27 struct sensor_helper_dev *glb_sensor_helper[VIN_MAX_CSI];
28 
29 module_param_string(ccm0, ccm0, sizeof(ccm0), S_IRUGO | S_IWUSR);
30 module_param_string(ccm1, ccm1, sizeof(ccm1), S_IRUGO | S_IWUSR);
31 
to_state(struct v4l2_subdev * sd)32 struct sensor_info *to_state(struct v4l2_subdev *sd)
33 {
34 	return container_of(sd, struct sensor_info, sd);
35 }
36 EXPORT_SYMBOL_GPL(to_state);
37 
sensor_cfg_req(struct v4l2_subdev * sd,struct sensor_config * cfg)38 void sensor_cfg_req(struct v4l2_subdev *sd, struct sensor_config *cfg)
39 {
40 	struct sensor_info *info = to_state(sd);
41 
42 	if (info == NULL) {
43 		pr_err("%s is not initialized\n", sd->name);
44 		return;
45 	}
46 	if (info->current_wins == NULL) {
47 		pr_err("%s format is not initialized\n", sd->name);
48 		return;
49 	}
50 
51 	cfg->width = info->current_wins->width_input;
52 	cfg->height = info->current_wins->height_input;
53 	cfg->hoffset = info->current_wins->hoffset;
54 	cfg->voffset = info->current_wins->voffset;
55 	cfg->hts = info->current_wins->hts;
56 	cfg->vts = info->current_wins->vts;
57 	cfg->pclk = info->current_wins->pclk;
58 	cfg->fps_fixed = info->current_wins->fps_fixed;
59 	cfg->bin_factor = info->current_wins->bin_factor;
60 	cfg->intg_min = info->current_wins->intg_min;
61 	cfg->intg_max = info->current_wins->intg_max;
62 	cfg->gain_min = info->current_wins->gain_min;
63 	cfg->gain_max = info->current_wins->gain_max;
64 	cfg->mbus_code = info->fmt->mbus_code;
65 	cfg->wdr_mode = info->current_wins->wdr_mode;
66 }
67 EXPORT_SYMBOL_GPL(sensor_cfg_req);
68 
sensor_isp_input(struct v4l2_subdev * sd,struct v4l2_mbus_framefmt * mf)69 void sensor_isp_input(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
70 {
71 	struct sensor_info *info = to_state(sd);
72 
73 	if (info == NULL) {
74 		pr_err("%s is not initialized\n", sd->name);
75 		return;
76 	}
77 	if (info->current_wins == NULL) {
78 		pr_err("%s format is not initialized\n", sd->name);
79 		return;
80 	}
81 
82 	info->current_wins->width_input = mf->width;
83 	info->current_wins->height_input = mf->height;
84 }
85 EXPORT_SYMBOL_GPL(sensor_isp_input);
86 
sensor_get_exp(struct v4l2_subdev * sd)87 unsigned int sensor_get_exp(struct v4l2_subdev *sd)
88 {
89 	struct sensor_info *info = to_state(sd);
90 	unsigned int exp_us = 0;
91 	if (info == NULL) {
92 		pr_err("%s is not initialized\n", sd->name);
93 		return -1;
94 	}
95 	if (info->exp == 0) {
96 		return -1;
97 	}
98 	exp_us = info->exp/16*info->current_wins->hts/(info->current_wins->pclk/1000000);
99 	return exp_us;
100 }
101 EXPORT_SYMBOL_GPL(sensor_get_exp);
102 
103 #if defined CONFIG_ARCH_SUN8IW16P1
__sensor_get_parameter(struct v4l2_subdev * sd,struct v4l2_mbus_config * cfg)104 static unsigned int __sensor_get_parameter(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg)
105 {
106 	struct sensor_info *info = to_state(sd);
107 	unsigned flags = cfg->flags & 0xf;
108 
109 	switch (flags) {
110 	case V4L2_MBUS_CSI2_1_LANE:
111 		info->lane_num = 1;
112 		break;
113 	case V4L2_MBUS_CSI2_2_LANE:
114 		info->lane_num = 2;
115 		break;
116 	case V4L2_MBUS_CSI2_3_LANE:
117 		info->lane_num = 3;
118 		break;
119 	case V4L2_MBUS_CSI2_4_LANE:
120 		info->lane_num = 4;
121 		break;
122 	default:
123 		return -1;
124 	}
125 
126 	switch (info->fmt->mbus_code) {
127 	case MEDIA_BUS_FMT_SBGGR8_1X8:
128 	case MEDIA_BUS_FMT_SGBRG8_1X8:
129 	case MEDIA_BUS_FMT_SGRBG8_1X8:
130 	case MEDIA_BUS_FMT_SRGGB8_1X8:
131 		info->bit_width = 8;
132 		break;
133 	case MEDIA_BUS_FMT_SBGGR10_1X10:
134 	case MEDIA_BUS_FMT_SGBRG10_1X10:
135 	case MEDIA_BUS_FMT_SGRBG10_1X10:
136 	case MEDIA_BUS_FMT_SRGGB10_1X10:
137 		info->bit_width = 10;
138 		break;
139 	case MEDIA_BUS_FMT_SBGGR12_1X12:
140 	case MEDIA_BUS_FMT_SGBRG12_1X12:
141 	case MEDIA_BUS_FMT_SGRBG12_1X12:
142 	case MEDIA_BUS_FMT_SRGGB12_1X12:
143 		info->bit_width = 12;
144 		break;
145 	default:
146 		return -1;
147 	}
148 
149 	return 0;
150 }
151 
sensor_get_clk(struct v4l2_subdev * sd,struct v4l2_mbus_config * cfg,unsigned long * top_clk,unsigned long * isp_clk)152 unsigned int sensor_get_clk(struct v4l2_subdev *sd, struct v4l2_mbus_config *cfg,
153 				unsigned long *top_clk, unsigned long *isp_clk)
154 {
155 	struct sensor_info *info = to_state(sd);
156 	unsigned long topclk_theory, ispclk_theory;
157 	unsigned long topclk_max = 432*1000*1000;
158 	unsigned long ispclk_max = 432*1000*1000;
159 	unsigned int hblank;
160 	unsigned int hblank_cmp = 128;
161 	int ret;
162 
163 	if (info->current_wins->top_clk && info->current_wins->isp_clk) {
164 		*top_clk = info->current_wins->top_clk;
165 		*isp_clk = info->current_wins->isp_clk;
166 	} else if (info->current_wins->mipi_bps && info->current_wins->hts && info->current_wins->pclk) {
167 		ret = __sensor_get_parameter(sd, cfg);
168 		if (ret) {
169 			vin_warn("__sensor_get_parameter warning! sensor is not mipi or raw sensor!\n");
170 			return -1;
171 		}
172 
173 		if (info->current_wins->hts <= info->current_wins->width) {
174 			vin_warn("%s warning! hts must be greater than width!\n", __func__);
175 			return -1;
176 		}
177 		hblank = info->current_wins->hts - info->current_wins->width;
178 		topclk_theory = info->current_wins->mipi_bps * info->lane_num / info->bit_width;
179 		ispclk_theory = max(topclk_theory, (unsigned long)info->current_wins->pclk) /
180 				info->current_wins->hts *
181 				(info->current_wins->width + max(hblank_cmp, hblank/10));
182 
183 		*top_clk = min(topclk_max, roundup(topclk_theory + topclk_theory*5/100, 1000000));
184 		*isp_clk = min(ispclk_max, roundup(ispclk_theory + ispclk_theory*5/100, 1000000));
185 		if (!(*top_clk) || !(*isp_clk)) {
186 			vin_warn("%s warning! top_clk = %ld, isp_clk = %ld\n", __func__, *top_clk, *isp_clk);
187 			return -1;
188 		}
189 	}  else
190 		return -1;
191 
192 	return 0;
193 }
194 EXPORT_SYMBOL_GPL(sensor_get_clk);
195 #endif
196 
sensor_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)197 int sensor_enum_mbus_code(struct v4l2_subdev *sd,
198 				struct v4l2_subdev_pad_config *cfg,
199 				struct v4l2_subdev_mbus_code_enum *code)
200 {
201 	struct sensor_info *info = to_state(sd);
202 
203 	if (code->index >= info->fmt_num)
204 		return -EINVAL;
205 	code->code = info->fmt_pt[code->index].mbus_code;
206 	return 0;
207 }
208 EXPORT_SYMBOL_GPL(sensor_enum_mbus_code);
209 
sensor_enum_frame_size(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)210 int sensor_enum_frame_size(struct v4l2_subdev *sd,
211 			struct v4l2_subdev_pad_config *cfg,
212 			struct v4l2_subdev_frame_size_enum *fse)
213 {
214 	struct sensor_info *info = to_state(sd);
215 
216 	if (fse->index >= info->win_size_num)
217 		return -EINVAL;
218 	fse->min_width = info->win_pt[fse->index].width;
219 	fse->max_width = fse->min_width;
220 	fse->max_height = info->win_pt[fse->index].height;
221 	fse->min_height = fse->max_height;
222 	return 0;
223 }
224 EXPORT_SYMBOL_GPL(sensor_enum_frame_size);
225 
sensor_find_mbus_code(struct v4l2_subdev * sd,struct v4l2_mbus_framefmt * fmt)226 static struct sensor_format_struct *sensor_find_mbus_code(struct v4l2_subdev *sd,
227 			struct v4l2_mbus_framefmt *fmt)
228 {
229 	struct sensor_info *info = to_state(sd);
230 	int i;
231 
232 	for (i = 0; i < info->fmt_num; ++i) {
233 		if (info->fmt_pt[i].mbus_code == fmt->code)
234 			break;
235 	}
236 	if (i >= info->fmt_num)
237 		return info->fmt_pt;
238 	return &info->fmt_pt[i];
239 }
240 
sensor_find_frame_size(struct v4l2_subdev * sd,struct v4l2_mbus_framefmt * fmt)241 static struct sensor_win_size *sensor_find_frame_size(struct v4l2_subdev *sd,
242 		struct v4l2_mbus_framefmt *fmt)
243 {
244 	struct sensor_info *info = to_state(sd);
245 	struct sensor_win_size *ws = info->win_pt;
246 	struct sensor_win_size *best_ws = &ws[0];
247 	int best_dist = INT_MAX;
248 	int fps_flag = 0;
249 	int i;
250 
251 	/*judge if sensor have wdr command win*/
252 	if (info->isp_wdr_mode == ISP_COMANDING_MODE) {
253 		for (i = 0; i < info->win_size_num; ++i) {
254 			if (ws->wdr_mode == ISP_COMANDING_MODE) {
255 				best_ws = ws;
256 				break;
257 			}
258 			++ws;
259 		}
260 		if (i == info->win_size_num)
261 			info->isp_wdr_mode = 0;
262 	}
263 
264 	/*judge if sensor have wdr dol win*/
265 	ws = info->win_pt;
266 	if (info->isp_wdr_mode == ISP_DOL_WDR_MODE) {
267 		for (i = 0; i < info->win_size_num; ++i) {
268 			if (ws->wdr_mode == ISP_DOL_WDR_MODE) {
269 				best_ws = ws;
270 				break;
271 			}
272 			++ws;
273 		}
274 		if (i == info->win_size_num)
275 			info->isp_wdr_mode = 0;
276 	}
277 
278 	/*judge if sensor have the right fps win*/
279 	ws = info->win_pt;
280 	if (info->isp_wdr_mode == ISP_COMANDING_MODE) {
281 		for (i = 0; i < info->win_size_num; ++i) {
282 			if ((ws->fps_fixed == info->tpf.denominator) &&
283 			   (ws->wdr_mode == ISP_COMANDING_MODE)) {
284 				best_ws = ws;
285 				fps_flag = 1;
286 				break;
287 			}
288 			++ws;
289 		}
290 	} else if (info->isp_wdr_mode == ISP_DOL_WDR_MODE) {
291 		for (i = 0; i < info->win_size_num; ++i) {
292 			if ((ws->fps_fixed == info->tpf.denominator) &&
293 			   (ws->wdr_mode == ISP_DOL_WDR_MODE)) {
294 				best_ws = ws;
295 				fps_flag = 1;
296 				break;
297 			}
298 			++ws;
299 		}
300 	} else {
301 		for (i = 0; i < info->win_size_num; ++i) {
302 			if ((ws->fps_fixed == info->tpf.denominator) &&
303 			   (ws->wdr_mode == ISP_NORMAL_MODE)) {
304 				best_ws = ws;
305 				fps_flag = 1;
306 				break;
307 			}
308 			++ws;
309 		}
310 	}
311 
312 	/*judge if sensor have the right resoulution win*/
313 	ws = info->win_pt;
314 	if (info->isp_wdr_mode == ISP_COMANDING_MODE) {
315 		if (fps_flag) {
316 			for (i = 0; i < info->win_size_num; ++i) {
317 				int dist = abs(ws->width - fmt->width) +
318 				    abs(ws->height - fmt->height);
319 
320 				if ((dist < best_dist) &&
321 				    (ws->width >= fmt->width) &&
322 				    (ws->height >= fmt->height) &&
323 				    (ws->wdr_mode == ISP_COMANDING_MODE) &&
324 				    (ws->fps_fixed == info->tpf.denominator)) {
325 					best_dist = dist;
326 					best_ws = ws;
327 				}
328 				++ws;
329 			}
330 		} else {
331 			for (i = 0; i < info->win_size_num; ++i) {
332 				int dist = abs(ws->width - fmt->width) +
333 				    abs(ws->height - fmt->height);
334 
335 				if ((dist < best_dist) &&
336 				    (ws->width >= fmt->width) &&
337 				    (ws->height >= fmt->height) &&
338 				    (ws->wdr_mode == ISP_COMANDING_MODE)) {
339 					best_dist = dist;
340 					best_ws = ws;
341 				}
342 				++ws;
343 			}
344 		}
345 	} else if (info->isp_wdr_mode == ISP_DOL_WDR_MODE) {
346 		if (fps_flag) {
347 			for (i = 0; i < info->win_size_num; ++i) {
348 				int dist = abs(ws->width - fmt->width) +
349 				    abs(ws->height - fmt->height);
350 
351 				if ((dist < best_dist) &&
352 				    (ws->width >= fmt->width) &&
353 				    (ws->height >= fmt->height) &&
354 				    (ws->wdr_mode == ISP_DOL_WDR_MODE) &&
355 				    (ws->fps_fixed == info->tpf.denominator)) {
356 					best_dist = dist;
357 					best_ws = ws;
358 				}
359 				++ws;
360 			}
361 		} else {
362 			for (i = 0; i < info->win_size_num; ++i) {
363 				int dist = abs(ws->width - fmt->width) +
364 				    abs(ws->height - fmt->height);
365 
366 				if ((dist < best_dist) &&
367 				    (ws->width >= fmt->width) &&
368 				    (ws->height >= fmt->height) &&
369 				    (ws->wdr_mode == ISP_DOL_WDR_MODE)) {
370 					best_dist = dist;
371 					best_ws = ws;
372 				}
373 				++ws;
374 			}
375 		}
376 	} else {
377 		if (fps_flag) {
378 			for (i = 0; i < info->win_size_num; ++i) {
379 				int dist = abs(ws->width - fmt->width) +
380 				    abs(ws->height - fmt->height);
381 
382 				if ((dist < best_dist) &&
383 				    (ws->width >= fmt->width) &&
384 				    (ws->height >= fmt->height) &&
385 				    (ws->wdr_mode == ISP_NORMAL_MODE) &&
386 				    (ws->fps_fixed == info->tpf.denominator)) {
387 					best_dist = dist;
388 					best_ws = ws;
389 				}
390 				++ws;
391 			}
392 		} else {
393 			for (i = 0; i < info->win_size_num; ++i) {
394 				int dist = abs(ws->width - fmt->width) +
395 				    abs(ws->height - fmt->height);
396 
397 				if ((dist < best_dist) &&
398 				    (ws->width >= fmt->width) &&
399 				    (ws->height >= fmt->height) &&
400 				    (ws->wdr_mode == ISP_NORMAL_MODE)) {
401 					best_dist = dist;
402 					best_ws = ws;
403 				}
404 				++ws;
405 			}
406 		}
407 	}
408 
409 	info->isp_wdr_mode = best_ws->wdr_mode;
410 
411 	return best_ws;
412 }
413 
sensor_fill_mbus_fmt(struct v4l2_subdev * sd,struct v4l2_mbus_framefmt * mf,const struct sensor_win_size * ws,u32 code)414 static void sensor_fill_mbus_fmt(struct v4l2_subdev *sd,
415 				struct v4l2_mbus_framefmt *mf,
416 				const struct sensor_win_size *ws, u32 code)
417 {
418 	struct sensor_info *info = to_state(sd);
419 	struct mbus_framefmt_res *res = (void *)mf->reserved;
420 
421 	mf->width = ws->width;
422 	mf->height = ws->height;
423 	mf->code = code;
424 	mf->field = info->sensor_field;
425 	res->res_mipi_bps = ws->mipi_bps;
426 	res->res_combo_mode = info->combo_mode | ws->if_mode;
427 	res->res_wdr_mode = ws->wdr_mode;
428 	res->res_lp_mode = ws->lp_mode;
429 	res->res_time_hs = info->time_hs;
430 	res->fps = ws->fps_fixed;
431 }
432 
sensor_try_format(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt,struct sensor_win_size ** ws,struct sensor_format_struct ** sf)433 static void sensor_try_format(struct v4l2_subdev *sd,
434 				struct v4l2_subdev_pad_config *cfg,
435 				struct v4l2_subdev_format *fmt,
436 				struct sensor_win_size **ws,
437 				struct sensor_format_struct **sf)
438 {
439 	struct sensor_info *info = to_state(sd);
440 	u32 code = MEDIA_BUS_FMT_YUYV8_2X8;
441 
442 	if (fmt->pad == SENSOR_PAD_SOURCE) {
443 		if ((sd->entity.stream_count > 0 || info->use_current_win) &&
444 		    info->current_wins != NULL) {
445 			code = info->fmt->mbus_code;
446 			*ws = info->current_wins;
447 			*sf = info->fmt;
448 			info->isp_wdr_mode = info->current_wins->wdr_mode;
449 		} else {
450 			*ws = sensor_find_frame_size(sd, &fmt->format);
451 			*sf = sensor_find_mbus_code(sd, &fmt->format);
452 			code = (*sf)->mbus_code;
453 		}
454 	}
455 	sensor_fill_mbus_fmt(sd, &fmt->format, *ws, code);
456 }
457 
sensor_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)458 int sensor_get_fmt(struct v4l2_subdev *sd,
459 			struct v4l2_subdev_pad_config *cfg,
460 			struct v4l2_subdev_format *fmt)
461 {
462 	struct sensor_info *info = to_state(sd);
463 	const struct sensor_win_size *ws;
464 	u32 code;
465 
466 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
467 		if (cfg == NULL) {
468 			pr_err("%s cfg is NULL!\n", sd->name);
469 			return -EINVAL;
470 		}
471 		fmt->format = cfg->try_fmt;
472 		return 0;
473 	}
474 	mutex_lock(&info->lock);
475 	switch (fmt->pad) {
476 	case SENSOR_PAD_SOURCE:
477 		code = info->fmt->mbus_code;
478 		ws = info->current_wins;
479 		break;
480 	default:
481 		mutex_unlock(&info->lock);
482 		return -EINVAL;
483 	}
484 	sensor_fill_mbus_fmt(sd, &fmt->format, ws, code);
485 	mutex_unlock(&info->lock);
486 	return 0;
487 }
488 EXPORT_SYMBOL_GPL(sensor_get_fmt);
489 
sensor_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)490 int sensor_set_fmt(struct v4l2_subdev *sd,
491 			struct v4l2_subdev_pad_config *cfg,
492 			struct v4l2_subdev_format *fmt)
493 {
494 	struct sensor_info *info = to_state(sd);
495 	struct sensor_win_size *ws = NULL;
496 	struct sensor_format_struct *sf = NULL;
497 	struct v4l2_mbus_framefmt *mf;
498 	int ret = 0;
499 
500 	mutex_lock(&info->lock);
501 	vin_log(VIN_LOG_FMT, "%s %s %d*%d 0x%x 0x%x\n", sd->name, __func__,
502 		fmt->format.width, fmt->format.height,
503 		fmt->format.code, fmt->format.field);
504 	sensor_try_format(sd, cfg, fmt, &ws, &sf);
505 	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
506 		if (cfg == NULL) {
507 			pr_err("%s cfg is NULL!\n", sd->name);
508 			mutex_unlock(&info->lock);
509 			return -EINVAL;
510 		}
511 		mf = &cfg->try_fmt;
512 		*mf = fmt->format;
513 	} else {
514 		switch (fmt->pad) {
515 		case SENSOR_PAD_SOURCE:
516 			info->current_wins = ws;
517 			info->fmt = sf;
518 			break;
519 		default:
520 			ret = -EBUSY;
521 		}
522 	}
523 	mutex_unlock(&info->lock);
524 	return ret;
525 }
526 EXPORT_SYMBOL_GPL(sensor_set_fmt);
527 
sensor_g_parm(struct v4l2_subdev * sd,struct v4l2_streamparm * parms)528 int sensor_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
529 {
530 	struct v4l2_captureparm *cp = &parms->parm.capture;
531 	struct sensor_info *info = to_state(sd);
532 
533 	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
534 		return -EINVAL;
535 	memset(cp, 0, sizeof(struct v4l2_captureparm));
536 	cp->capability = V4L2_CAP_TIMEPERFRAME;
537 	cp->capturemode = info->capture_mode;
538 	if (info->current_wins && info->current_wins->fps_fixed)
539 		cp->timeperframe.denominator = info->current_wins->fps_fixed;
540 	else
541 		cp->timeperframe.denominator = info->tpf.denominator;
542 	cp->timeperframe.numerator = 1;
543 	return 0;
544 }
545 EXPORT_SYMBOL_GPL(sensor_g_parm);
546 
sensor_s_parm(struct v4l2_subdev * sd,struct v4l2_streamparm * parms)547 int sensor_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
548 {
549 	struct v4l2_captureparm *cp = &parms->parm.capture;
550 	struct sensor_info *info = to_state(sd);
551 
552 	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
553 		return -EINVAL;
554 	if (info->tpf.numerator == 0)
555 		return -EINVAL;
556 	info->capture_mode = cp->capturemode;
557 	info->tpf = cp->timeperframe;
558 	info->use_current_win = cp->reserved[0];
559 	info->isp_wdr_mode = cp->reserved[1];
560 	return 0;
561 }
562 EXPORT_SYMBOL_GPL(sensor_s_parm);
563 
sensor_try_ctrl(struct v4l2_ctrl * ctrl)564 int sensor_try_ctrl(struct v4l2_ctrl *ctrl)
565 {
566 	/*
567 	 * to cheat control framework, because of  when ctrl->cur.val == ctrl->val
568 	 * s_ctrl would not be called
569 	 */
570 	if ((ctrl->minimum == 0) && (ctrl->maximum == 1)) {
571 		if (ctrl->val)
572 			ctrl->cur.val = 0;
573 		else
574 			ctrl->cur.val = 1;
575 	} else {
576 		if (ctrl->val == ctrl->maximum)
577 			ctrl->cur.val = ctrl->val - 1;
578 		else
579 			ctrl->cur.val = ctrl->val + 1;
580 	}
581 
582 	/*
583 	 * to cheat control framework, because of  when ctrl->flags is
584 	 * V4L2_CTRL_FLAG_VOLATILE, s_ctrl would not be called
585 	 */
586 	switch (ctrl->id) {
587 	case V4L2_CID_EXPOSURE:
588 	case V4L2_CID_EXPOSURE_ABSOLUTE:
589 	case V4L2_CID_GAIN:
590 		if (ctrl->val != ctrl->cur.val)
591 			ctrl->flags &= ~V4L2_CTRL_FLAG_VOLATILE;
592 		break;
593 	default:
594 		break;
595 	}
596 	return 0;
597 }
598 EXPORT_SYMBOL_GPL(sensor_try_ctrl);
599 
actuator_init(struct v4l2_subdev * sd,struct actuator_para * range)600 int actuator_init(struct v4l2_subdev *sd, struct actuator_para *range)
601 {
602 #ifdef CONFIG_ACTUATOR_MODULE
603 	struct modules_config *modules = sd_to_modules(sd);
604 	struct v4l2_subdev *act_sd = NULL;
605 	struct actuator_para_t vcm_para;
606 
607 	if (modules == NULL)
608 		return -EINVAL;
609 
610 	act_sd = modules->modules.act[modules->sensors.valid_idx].sd;
611 	if (act_sd == NULL)
612 		return 0;
613 
614 	if (act_sd->entity.use_count > 0)
615 		return 0;
616 
617 	vcm_para.active_min = range->code_min;
618 	vcm_para.active_max = range->code_max;
619 	return v4l2_subdev_call(act_sd, core, ioctl, ACT_INIT, &vcm_para);
620 #else
621 	return 0;
622 #endif
623 }
624 EXPORT_SYMBOL_GPL(actuator_init);
625 
actuator_set_code(struct v4l2_subdev * sd,struct actuator_ctrl * pos)626 int actuator_set_code(struct v4l2_subdev *sd, struct actuator_ctrl *pos)
627 {
628 #ifdef CONFIG_ACTUATOR_MODULE
629 	struct modules_config *modules = sd_to_modules(sd);
630 	struct v4l2_subdev *act_sd = NULL;
631 	struct actuator_ctrl_word_t vcm_ctrl;
632 
633 	if (modules == NULL)
634 		return -EINVAL;
635 
636 	act_sd = modules->modules.act[modules->sensors.valid_idx].sd;
637 	if (act_sd == NULL)
638 		return 0;
639 
640 	vcm_ctrl.code = pos->code;
641 	vcm_ctrl.sr = 0x0;
642 	return v4l2_subdev_call(act_sd, core, ioctl, ACT_SET_CODE, &vcm_ctrl);
643 #else
644 	return 0;
645 #endif
646 }
647 EXPORT_SYMBOL_GPL(actuator_set_code);
648 
flash_en(struct v4l2_subdev * sd,struct flash_para * para)649 int flash_en(struct v4l2_subdev *sd, struct flash_para *para)
650 {
651 #ifdef CONFIG_FLASH_MODULE
652 	struct modules_config *modules = sd_to_modules(sd);
653 	struct v4l2_subdev *flash_sd = NULL;
654 	int ret = 0;
655 
656 	if (modules == NULL)
657 		return -EINVAL;
658 
659 	flash_sd = modules->modules.flash.sd;
660 	if (flash_sd == NULL)
661 		return 0;
662 
663 	switch (para->mode) {
664 	case V4L2_FLASH_LED_MODE_NONE:
665 		ret = io_set_flash_ctrl(flash_sd, SW_CTRL_FLASH_OFF);
666 		break;
667 	case V4L2_FLASH_LED_MODE_FLASH:
668 		ret = io_set_flash_ctrl(flash_sd, SW_CTRL_FLASH_ON);
669 		break;
670 	case V4L2_FLASH_LED_MODE_TORCH:
671 		ret = io_set_flash_ctrl(flash_sd, SW_CTRL_TORCH_ON);
672 		break;
673 	default:
674 		ret = -1;
675 		break;
676 	}
677 
678 	return ret;
679 #else
680 	return 0;
681 #endif
682 }
683 EXPORT_SYMBOL_GPL(flash_en);
684 
685 #if !defined SENSOR_POER_BEFORE_VIN
sensor_helper_probe(struct platform_device * pdev)686 static int sensor_helper_probe(struct platform_device *pdev)
687 {
688 	struct device_node *np = pdev->dev.of_node;
689 	struct device *dev = &pdev->dev;
690 	struct sensor_helper_dev *sensor_helper = NULL;
691 	char power_supply[20] = {0};
692 	char property_name[16] = {0};
693 	const char *ccm_name;
694 	int ret;
695 
696 	if (np == NULL) {
697 		vin_err("sensor_helper failed to get of node\n");
698 		return -ENODEV;
699 	}
700 	sensor_helper = kzalloc(sizeof(struct sensor_helper_dev), GFP_KERNEL);
701 	if (!sensor_helper) {
702 		ret = -ENOMEM;
703 		goto ekzalloc;
704 	}
705 
706 	of_property_read_u32(np, "device_id", &pdev->id);
707 	if (pdev->id < 0) {
708 		vin_err("sensor_helper failed to get device id\n");
709 		ret = -EINVAL;
710 		goto freedev;
711 	}
712 	sensor_helper->id = pdev->id;
713 
714 #ifndef FPGA_VER
715 	if (sensor_helper->id == 0)
716 		strcpy(sensor_helper->name, ccm0);
717 	else if (sensor_helper->id == 1)
718 		strcpy(sensor_helper->name, ccm1);
719 
720 	if (!strcmp(sensor_helper->name, "")) {
721 		snprintf(property_name, sizeof(property_name), "sensor%d_mname", pdev->id);
722 		ret = of_property_read_string(np, property_name, &ccm_name);
723 		if (ret) {
724 			vin_warn("fetch %s from device_tree failed\n", property_name);
725 			return -EINVAL;
726 		} else
727 			strcpy(sensor_helper->name, ccm_name);
728 	}
729 		vin_log(VIN_LOG_POWER, "sensor_helper get name is %s\n", sensor_helper->name);
730 
731 	snprintf(power_supply, sizeof(power_supply), "sensor%d_cameravdd", pdev->id);
732 	sensor_helper->pmic[CAMERAVDD] = regulator_get_optional(dev, power_supply);
733 	if (IS_ERR(sensor_helper->pmic[CAMERAVDD])) {
734 		vin_warn("%s: cannot get %s supply, setting it to NULL!\n", __func__, power_supply);
735 		sensor_helper->pmic[CAMERAVDD] = NULL;
736 	}
737 
738 	snprintf(power_supply, sizeof(power_supply), "sensor%d_iovdd", pdev->id);
739 	sensor_helper->pmic[IOVDD] = regulator_get_optional(dev, power_supply);
740 	if (IS_ERR(sensor_helper->pmic[IOVDD])) {
741 		vin_warn("%s: cannot get %s supply, setting it to NULL!\n", __func__, power_supply);
742 		sensor_helper->pmic[IOVDD] = NULL;
743 	}
744 
745 	snprintf(power_supply, sizeof(power_supply), "sensor%d_avdd", pdev->id);
746 	sensor_helper->pmic[AVDD] = regulator_get_optional(dev, power_supply);
747 	if (IS_ERR(sensor_helper->pmic[AVDD])) {
748 		vin_warn("%s: cannot get %s supply, setting it to NULL!\n", __func__, power_supply);
749 		sensor_helper->pmic[AVDD] = NULL;
750 	}
751 
752 	snprintf(power_supply, sizeof(power_supply), "sensor%d_dvdd", pdev->id);
753 	sensor_helper->pmic[DVDD] = regulator_get_optional(dev, power_supply);
754 	if (IS_ERR(sensor_helper->pmic[DVDD])) {
755 		vin_warn("%s: cannot get %s supply, setting it to NULL!\n", __func__, power_supply);
756 		sensor_helper->pmic[DVDD] = NULL;
757 	}
758 #endif
759 	glb_sensor_helper[pdev->id] = sensor_helper;
760 
761 	platform_set_drvdata(pdev, sensor_helper);
762 
763 	vin_log(VIN_LOG_POWER, "sensor_helper probe end sensor_sel = %d!\n", sensor_helper->id);
764 
765 	return 0;
766 freedev:
767 	kfree(sensor_helper);
768 ekzalloc:
769 	vin_err("sensor_helper probe err!\n");
770 	return ret;
771 }
772 
sensor_helper_remove(struct platform_device * pdev)773 static int sensor_helper_remove(struct platform_device *pdev)
774 {
775 	struct sensor_helper_dev *sensor_helper = platform_get_drvdata(pdev);
776 
777 	platform_set_drvdata(pdev, NULL);
778 #ifndef FPGA_VER
779 	regulator_put(sensor_helper->pmic[CAMERAVDD]);
780 	sensor_helper->pmic[CAMERAVDD] = NULL;
781 	regulator_put(sensor_helper->pmic[IOVDD]);
782 	sensor_helper->pmic[IOVDD] = NULL;
783 	regulator_put(sensor_helper->pmic[AVDD]);
784 	sensor_helper->pmic[AVDD] = NULL;
785 	regulator_put(sensor_helper->pmic[DVDD]);
786 	sensor_helper->pmic[DVDD] = NULL;
787 #endif
788 	kfree(sensor_helper);
789 	return 0;
790 }
791 
792 static const struct of_device_id sunxi_sensor_helper_match[] = {
793 	{.compatible = "allwinner,sunxi-sensor",},
794 	{},
795 };
796 
797 static struct platform_driver sensor_helper_platform_driver = {
798 	.probe = sensor_helper_probe,
799 	.remove = sensor_helper_remove,
800 	.driver = {
801 		   .name = SENSOR_MODULE_NAME,
802 		   .owner = THIS_MODULE,
803 		   .of_match_table = sunxi_sensor_helper_match,
804 		   },
805 };
806 #endif
vin_io_init(void)807 static int __init vin_io_init(void)
808 {
809 	int ret;
810 
811 	ret = sunxi_cci_platform_register();
812 	if (ret)
813 		return ret;
814 
815 #if !defined SENSOR_POER_BEFORE_VIN
816 	ret = platform_driver_register(&sensor_helper_platform_driver);
817 	if (ret) {
818 		vin_err("sensor helper platform driver register failed\n");
819 		return ret;
820 	}
821 	vin_log(VIN_LOG_POWER, "sensor_helper_init end\n");
822 #endif
823 
824 	return 0;
825 }
826 
vin_io_exit(void)827 static void __exit vin_io_exit(void)
828 {
829 	sunxi_cci_platform_unregister();
830 
831 #if !defined SENSOR_POER_BEFORE_VIN
832 	platform_driver_unregister(&sensor_helper_platform_driver);
833 #endif
834 
835 	vin_log(VIN_LOG_POWER, "sensor_helper_exit end\n");
836 }
837 
838 #ifdef CONFIG_VIDEO_SUNXI_VIN_SPECIAL
839 subsys_initcall_sync(vin_io_init);
840 #else
841 module_init(vin_io_init);
842 #endif
843 module_exit(vin_io_exit);
844 
845 MODULE_AUTHOR("zhengzequn");
846 MODULE_LICENSE("Dual BSD/GPL");
847 MODULE_DESCRIPTION("Camera and CCI DRIVER for sunxi");
848 
849 
850