]>
Commit | Line | Data |
---|---|---|
d2912cb1 | 1 | // SPDX-License-Identifier: GPL-2.0-only |
294781db SN |
2 | /* |
3 | * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver | |
4 | * | |
5 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | |
6 | * | |
7 | * Authors: Younghwan Joo <yhwan.joo@samsung.com> | |
8 | * Sylwester Nawrocki <s.nawrocki@samsung.com> | |
294781db SN |
9 | */ |
10 | #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__ | |
11 | ||
a6f5635e | 12 | #include <linux/bitops.h> |
294781db SN |
13 | #include <linux/bug.h> |
14 | #include <linux/device.h> | |
15 | #include <linux/errno.h> | |
16 | #include <linux/kernel.h> | |
17 | #include <linux/module.h> | |
294781db SN |
18 | #include <linux/platform_device.h> |
19 | #include <linux/slab.h> | |
a6f5635e | 20 | #include <linux/types.h> |
294781db SN |
21 | #include <linux/videodev2.h> |
22 | ||
23 | #include <media/v4l2-device.h> | |
24 | #include <media/v4l2-ioctl.h> | |
25 | ||
26 | #include "fimc-is.h" | |
27 | #include "fimc-is-command.h" | |
28 | #include "fimc-is-errno.h" | |
29 | #include "fimc-is-param.h" | |
30 | #include "fimc-is-regs.h" | |
31 | #include "fimc-is-sensor.h" | |
32 | ||
33 | static void __hw_param_copy(void *dst, void *src) | |
34 | { | |
35 | memcpy(dst, src, FIMC_IS_PARAM_MAX_SIZE); | |
36 | } | |
37 | ||
e0e9f67a | 38 | static void __fimc_is_hw_update_param_global_shotmode(struct fimc_is *is) |
294781db SN |
39 | { |
40 | struct param_global_shotmode *dst, *src; | |
41 | ||
42 | dst = &is->is_p_region->parameter.global.shotmode; | |
3530ef0a | 43 | src = &is->config[is->config_index].global.shotmode; |
294781db SN |
44 | __hw_param_copy(dst, src); |
45 | } | |
46 | ||
e0e9f67a | 47 | static void __fimc_is_hw_update_param_sensor_framerate(struct fimc_is *is) |
294781db SN |
48 | { |
49 | struct param_sensor_framerate *dst, *src; | |
50 | ||
51 | dst = &is->is_p_region->parameter.sensor.frame_rate; | |
3530ef0a | 52 | src = &is->config[is->config_index].sensor.frame_rate; |
294781db SN |
53 | __hw_param_copy(dst, src); |
54 | } | |
55 | ||
34947b8a | 56 | int __fimc_is_hw_update_param(struct fimc_is *is, u32 offset) |
294781db SN |
57 | { |
58 | struct is_param_region *par = &is->is_p_region->parameter; | |
3530ef0a | 59 | struct chain_config *cfg = &is->config[is->config_index]; |
294781db SN |
60 | |
61 | switch (offset) { | |
62 | case PARAM_ISP_CONTROL: | |
63 | __hw_param_copy(&par->isp.control, &cfg->isp.control); | |
64 | break; | |
65 | ||
66 | case PARAM_ISP_OTF_INPUT: | |
67 | __hw_param_copy(&par->isp.otf_input, &cfg->isp.otf_input); | |
68 | break; | |
69 | ||
70 | case PARAM_ISP_DMA1_INPUT: | |
71 | __hw_param_copy(&par->isp.dma1_input, &cfg->isp.dma1_input); | |
72 | break; | |
73 | ||
74 | case PARAM_ISP_DMA2_INPUT: | |
75 | __hw_param_copy(&par->isp.dma2_input, &cfg->isp.dma2_input); | |
76 | break; | |
77 | ||
78 | case PARAM_ISP_AA: | |
79 | __hw_param_copy(&par->isp.aa, &cfg->isp.aa); | |
80 | break; | |
81 | ||
82 | case PARAM_ISP_FLASH: | |
83 | __hw_param_copy(&par->isp.flash, &cfg->isp.flash); | |
84 | break; | |
85 | ||
86 | case PARAM_ISP_AWB: | |
87 | __hw_param_copy(&par->isp.awb, &cfg->isp.awb); | |
88 | break; | |
89 | ||
90 | case PARAM_ISP_IMAGE_EFFECT: | |
91 | __hw_param_copy(&par->isp.effect, &cfg->isp.effect); | |
92 | break; | |
93 | ||
94 | case PARAM_ISP_ISO: | |
95 | __hw_param_copy(&par->isp.iso, &cfg->isp.iso); | |
96 | break; | |
97 | ||
98 | case PARAM_ISP_ADJUST: | |
99 | __hw_param_copy(&par->isp.adjust, &cfg->isp.adjust); | |
100 | break; | |
101 | ||
102 | case PARAM_ISP_METERING: | |
103 | __hw_param_copy(&par->isp.metering, &cfg->isp.metering); | |
104 | break; | |
105 | ||
106 | case PARAM_ISP_AFC: | |
107 | __hw_param_copy(&par->isp.afc, &cfg->isp.afc); | |
108 | break; | |
109 | ||
110 | case PARAM_ISP_OTF_OUTPUT: | |
111 | __hw_param_copy(&par->isp.otf_output, &cfg->isp.otf_output); | |
112 | break; | |
113 | ||
114 | case PARAM_ISP_DMA1_OUTPUT: | |
115 | __hw_param_copy(&par->isp.dma1_output, &cfg->isp.dma1_output); | |
116 | break; | |
117 | ||
118 | case PARAM_ISP_DMA2_OUTPUT: | |
119 | __hw_param_copy(&par->isp.dma2_output, &cfg->isp.dma2_output); | |
120 | break; | |
121 | ||
122 | case PARAM_DRC_CONTROL: | |
123 | __hw_param_copy(&par->drc.control, &cfg->drc.control); | |
124 | break; | |
125 | ||
126 | case PARAM_DRC_OTF_INPUT: | |
127 | __hw_param_copy(&par->drc.otf_input, &cfg->drc.otf_input); | |
128 | break; | |
129 | ||
130 | case PARAM_DRC_DMA_INPUT: | |
131 | __hw_param_copy(&par->drc.dma_input, &cfg->drc.dma_input); | |
132 | break; | |
133 | ||
134 | case PARAM_DRC_OTF_OUTPUT: | |
135 | __hw_param_copy(&par->drc.otf_output, &cfg->drc.otf_output); | |
136 | break; | |
137 | ||
138 | case PARAM_FD_CONTROL: | |
139 | __hw_param_copy(&par->fd.control, &cfg->fd.control); | |
140 | break; | |
141 | ||
142 | case PARAM_FD_OTF_INPUT: | |
143 | __hw_param_copy(&par->fd.otf_input, &cfg->fd.otf_input); | |
144 | break; | |
145 | ||
146 | case PARAM_FD_DMA_INPUT: | |
147 | __hw_param_copy(&par->fd.dma_input, &cfg->fd.dma_input); | |
148 | break; | |
149 | ||
150 | case PARAM_FD_CONFIG: | |
151 | __hw_param_copy(&par->fd.config, &cfg->fd.config); | |
152 | break; | |
153 | ||
154 | default: | |
155 | return -EINVAL; | |
156 | } | |
157 | ||
158 | return 0; | |
159 | } | |
160 | ||
a6f5635e SN |
161 | unsigned int __get_pending_param_count(struct fimc_is *is) |
162 | { | |
3530ef0a | 163 | struct chain_config *config = &is->config[is->config_index]; |
a6f5635e SN |
164 | unsigned long flags; |
165 | unsigned int count; | |
166 | ||
167 | spin_lock_irqsave(&is->slock, flags); | |
0e761b21 PC |
168 | count = hweight32(config->p_region_index[0]); |
169 | count += hweight32(config->p_region_index[1]); | |
a6f5635e SN |
170 | spin_unlock_irqrestore(&is->slock, flags); |
171 | ||
172 | return count; | |
173 | } | |
174 | ||
294781db SN |
175 | int __is_hw_update_params(struct fimc_is *is) |
176 | { | |
0e761b21 | 177 | unsigned long *p_index; |
294781db SN |
178 | int i, id, ret = 0; |
179 | ||
3530ef0a | 180 | id = is->config_index; |
0e761b21 | 181 | p_index = &is->config[id].p_region_index[0]; |
294781db | 182 | |
0e761b21 | 183 | if (test_bit(PARAM_GLOBAL_SHOTMODE, p_index)) |
294781db SN |
184 | __fimc_is_hw_update_param_global_shotmode(is); |
185 | ||
0e761b21 | 186 | if (test_bit(PARAM_SENSOR_FRAME_RATE, p_index)) |
294781db SN |
187 | __fimc_is_hw_update_param_sensor_framerate(is); |
188 | ||
189 | for (i = PARAM_ISP_CONTROL; i < PARAM_DRC_CONTROL; i++) { | |
0e761b21 | 190 | if (test_bit(i, p_index)) |
294781db SN |
191 | ret = __fimc_is_hw_update_param(is, i); |
192 | } | |
193 | ||
194 | for (i = PARAM_DRC_CONTROL; i < PARAM_SCALERC_CONTROL; i++) { | |
0e761b21 | 195 | if (test_bit(i, p_index)) |
294781db SN |
196 | ret = __fimc_is_hw_update_param(is, i); |
197 | } | |
198 | ||
199 | for (i = PARAM_FD_CONTROL; i <= PARAM_FD_CONFIG; i++) { | |
0e761b21 | 200 | if (test_bit(i, p_index)) |
294781db SN |
201 | ret = __fimc_is_hw_update_param(is, i); |
202 | } | |
203 | ||
204 | return ret; | |
205 | } | |
206 | ||
207 | void __is_get_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf) | |
208 | { | |
209 | struct isp_param *isp; | |
210 | ||
3530ef0a | 211 | isp = &is->config[is->config_index].isp; |
294781db SN |
212 | mf->width = isp->otf_input.width; |
213 | mf->height = isp->otf_input.height; | |
214 | } | |
215 | ||
216 | void __is_set_frame_size(struct fimc_is *is, struct v4l2_mbus_framefmt *mf) | |
217 | { | |
3530ef0a | 218 | unsigned int index = is->config_index; |
294781db SN |
219 | struct isp_param *isp; |
220 | struct drc_param *drc; | |
221 | struct fd_param *fd; | |
294781db | 222 | |
3530ef0a SN |
223 | isp = &is->config[index].isp; |
224 | drc = &is->config[index].drc; | |
225 | fd = &is->config[index].fd; | |
294781db SN |
226 | |
227 | /* Update isp size info (OTF only) */ | |
228 | isp->otf_input.width = mf->width; | |
229 | isp->otf_input.height = mf->height; | |
230 | isp->otf_output.width = mf->width; | |
231 | isp->otf_output.height = mf->height; | |
232 | /* Update drc size info (OTF only) */ | |
233 | drc->otf_input.width = mf->width; | |
234 | drc->otf_input.height = mf->height; | |
235 | drc->otf_output.width = mf->width; | |
236 | drc->otf_output.height = mf->height; | |
237 | /* Update fd size info (OTF only) */ | |
238 | fd->otf_input.width = mf->width; | |
239 | fd->otf_input.height = mf->height; | |
240 | ||
241 | if (test_bit(PARAM_ISP_OTF_INPUT, | |
0e761b21 | 242 | &is->config[index].p_region_index[0])) |
294781db SN |
243 | return; |
244 | ||
245 | /* Update field */ | |
246 | fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT); | |
294781db | 247 | fimc_is_set_param_bit(is, PARAM_ISP_OTF_OUTPUT); |
294781db | 248 | fimc_is_set_param_bit(is, PARAM_DRC_OTF_INPUT); |
294781db | 249 | fimc_is_set_param_bit(is, PARAM_DRC_OTF_OUTPUT); |
294781db | 250 | fimc_is_set_param_bit(is, PARAM_FD_OTF_INPUT); |
294781db SN |
251 | } |
252 | ||
253 | int fimc_is_hw_get_sensor_max_framerate(struct fimc_is *is) | |
254 | { | |
255 | switch (is->sensor->drvdata->id) { | |
256 | case FIMC_IS_SENSOR_ID_S5K6A3: | |
257 | return 30; | |
258 | default: | |
259 | return 15; | |
260 | } | |
261 | } | |
262 | ||
263 | void __is_set_sensor(struct fimc_is *is, int fps) | |
264 | { | |
3530ef0a | 265 | unsigned int index = is->config_index; |
294781db SN |
266 | struct sensor_param *sensor; |
267 | struct isp_param *isp; | |
294781db | 268 | |
3530ef0a SN |
269 | sensor = &is->config[index].sensor; |
270 | isp = &is->config[index].isp; | |
294781db SN |
271 | |
272 | if (fps == 0) { | |
273 | sensor->frame_rate.frame_rate = | |
274 | fimc_is_hw_get_sensor_max_framerate(is); | |
275 | isp->otf_input.frametime_min = 0; | |
276 | isp->otf_input.frametime_max = 66666; | |
277 | } else { | |
278 | sensor->frame_rate.frame_rate = fps; | |
279 | isp->otf_input.frametime_min = 0; | |
280 | isp->otf_input.frametime_max = (u32)1000000 / fps; | |
281 | } | |
282 | ||
03385b8e SN |
283 | fimc_is_set_param_bit(is, PARAM_SENSOR_FRAME_RATE); |
284 | fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT); | |
294781db SN |
285 | } |
286 | ||
3263f741 | 287 | static void __maybe_unused __is_set_init_isp_aa(struct fimc_is *is) |
294781db SN |
288 | { |
289 | struct isp_param *isp; | |
290 | ||
3530ef0a | 291 | isp = &is->config[is->config_index].isp; |
294781db SN |
292 | |
293 | isp->aa.cmd = ISP_AA_COMMAND_START; | |
294 | isp->aa.target = ISP_AA_TARGET_AF | ISP_AA_TARGET_AE | | |
295 | ISP_AA_TARGET_AWB; | |
296 | isp->aa.mode = 0; | |
297 | isp->aa.scene = 0; | |
298 | isp->aa.sleep = 0; | |
299 | isp->aa.face = 0; | |
300 | isp->aa.touch_x = 0; | |
301 | isp->aa.touch_y = 0; | |
302 | isp->aa.manual_af_setting = 0; | |
303 | isp->aa.err = ISP_AF_ERROR_NONE; | |
304 | ||
305 | fimc_is_set_param_bit(is, PARAM_ISP_AA); | |
294781db SN |
306 | } |
307 | ||
308 | void __is_set_isp_flash(struct fimc_is *is, u32 cmd, u32 redeye) | |
309 | { | |
3530ef0a | 310 | unsigned int index = is->config_index; |
03385b8e | 311 | struct isp_param *isp = &is->config[index].isp; |
294781db SN |
312 | |
313 | isp->flash.cmd = cmd; | |
314 | isp->flash.redeye = redeye; | |
315 | isp->flash.err = ISP_FLASH_ERROR_NONE; | |
316 | ||
03385b8e | 317 | fimc_is_set_param_bit(is, PARAM_ISP_FLASH); |
294781db SN |
318 | } |
319 | ||
320 | void __is_set_isp_awb(struct fimc_is *is, u32 cmd, u32 val) | |
321 | { | |
3530ef0a | 322 | unsigned int index = is->config_index; |
294781db | 323 | struct isp_param *isp; |
294781db | 324 | |
3530ef0a | 325 | isp = &is->config[index].isp; |
294781db SN |
326 | |
327 | isp->awb.cmd = cmd; | |
328 | isp->awb.illumination = val; | |
329 | isp->awb.err = ISP_AWB_ERROR_NONE; | |
330 | ||
03385b8e | 331 | fimc_is_set_param_bit(is, PARAM_ISP_AWB); |
294781db SN |
332 | } |
333 | ||
334 | void __is_set_isp_effect(struct fimc_is *is, u32 cmd) | |
335 | { | |
3530ef0a | 336 | unsigned int index = is->config_index; |
294781db | 337 | struct isp_param *isp; |
294781db | 338 | |
3530ef0a | 339 | isp = &is->config[index].isp; |
294781db SN |
340 | |
341 | isp->effect.cmd = cmd; | |
342 | isp->effect.err = ISP_IMAGE_EFFECT_ERROR_NONE; | |
343 | ||
03385b8e | 344 | fimc_is_set_param_bit(is, PARAM_ISP_IMAGE_EFFECT); |
294781db SN |
345 | } |
346 | ||
347 | void __is_set_isp_iso(struct fimc_is *is, u32 cmd, u32 val) | |
348 | { | |
3530ef0a | 349 | unsigned int index = is->config_index; |
294781db | 350 | struct isp_param *isp; |
294781db | 351 | |
3530ef0a | 352 | isp = &is->config[index].isp; |
294781db SN |
353 | |
354 | isp->iso.cmd = cmd; | |
355 | isp->iso.value = val; | |
356 | isp->iso.err = ISP_ISO_ERROR_NONE; | |
357 | ||
03385b8e | 358 | fimc_is_set_param_bit(is, PARAM_ISP_ISO); |
294781db SN |
359 | } |
360 | ||
361 | void __is_set_isp_adjust(struct fimc_is *is, u32 cmd, u32 val) | |
362 | { | |
3530ef0a | 363 | unsigned int index = is->config_index; |
294781db SN |
364 | unsigned long *p_index; |
365 | struct isp_param *isp; | |
366 | ||
0e761b21 | 367 | p_index = &is->config[index].p_region_index[0]; |
3530ef0a | 368 | isp = &is->config[index].isp; |
294781db SN |
369 | |
370 | switch (cmd) { | |
371 | case ISP_ADJUST_COMMAND_MANUAL_CONTRAST: | |
372 | isp->adjust.contrast = val; | |
373 | break; | |
374 | case ISP_ADJUST_COMMAND_MANUAL_SATURATION: | |
375 | isp->adjust.saturation = val; | |
376 | break; | |
377 | case ISP_ADJUST_COMMAND_MANUAL_SHARPNESS: | |
378 | isp->adjust.sharpness = val; | |
379 | break; | |
380 | case ISP_ADJUST_COMMAND_MANUAL_EXPOSURE: | |
381 | isp->adjust.exposure = val; | |
382 | break; | |
383 | case ISP_ADJUST_COMMAND_MANUAL_BRIGHTNESS: | |
384 | isp->adjust.brightness = val; | |
385 | break; | |
386 | case ISP_ADJUST_COMMAND_MANUAL_HUE: | |
387 | isp->adjust.hue = val; | |
388 | break; | |
389 | case ISP_ADJUST_COMMAND_AUTO: | |
390 | isp->adjust.contrast = 0; | |
391 | isp->adjust.saturation = 0; | |
392 | isp->adjust.sharpness = 0; | |
393 | isp->adjust.exposure = 0; | |
394 | isp->adjust.brightness = 0; | |
395 | isp->adjust.hue = 0; | |
396 | break; | |
397 | } | |
398 | ||
399 | if (!test_bit(PARAM_ISP_ADJUST, p_index)) { | |
400 | isp->adjust.cmd = cmd; | |
401 | isp->adjust.err = ISP_ADJUST_ERROR_NONE; | |
402 | fimc_is_set_param_bit(is, PARAM_ISP_ADJUST); | |
294781db SN |
403 | } else { |
404 | isp->adjust.cmd |= cmd; | |
405 | } | |
406 | } | |
407 | ||
408 | void __is_set_isp_metering(struct fimc_is *is, u32 id, u32 val) | |
409 | { | |
3530ef0a | 410 | unsigned int index = is->config_index; |
294781db | 411 | struct isp_param *isp; |
3530ef0a | 412 | unsigned long *p_index; |
294781db | 413 | |
0e761b21 | 414 | p_index = &is->config[index].p_region_index[0]; |
3530ef0a | 415 | isp = &is->config[index].isp; |
294781db SN |
416 | |
417 | switch (id) { | |
418 | case IS_METERING_CONFIG_CMD: | |
419 | isp->metering.cmd = val; | |
420 | break; | |
421 | case IS_METERING_CONFIG_WIN_POS_X: | |
422 | isp->metering.win_pos_x = val; | |
423 | break; | |
424 | case IS_METERING_CONFIG_WIN_POS_Y: | |
425 | isp->metering.win_pos_y = val; | |
426 | break; | |
427 | case IS_METERING_CONFIG_WIN_WIDTH: | |
428 | isp->metering.win_width = val; | |
429 | break; | |
430 | case IS_METERING_CONFIG_WIN_HEIGHT: | |
431 | isp->metering.win_height = val; | |
432 | break; | |
433 | default: | |
434 | return; | |
435 | } | |
436 | ||
437 | if (!test_bit(PARAM_ISP_METERING, p_index)) { | |
438 | isp->metering.err = ISP_METERING_ERROR_NONE; | |
439 | fimc_is_set_param_bit(is, PARAM_ISP_METERING); | |
294781db SN |
440 | } |
441 | } | |
442 | ||
443 | void __is_set_isp_afc(struct fimc_is *is, u32 cmd, u32 val) | |
444 | { | |
3530ef0a | 445 | unsigned int index = is->config_index; |
294781db | 446 | struct isp_param *isp; |
294781db | 447 | |
3530ef0a | 448 | isp = &is->config[index].isp; |
294781db SN |
449 | |
450 | isp->afc.cmd = cmd; | |
451 | isp->afc.manual = val; | |
452 | isp->afc.err = ISP_AFC_ERROR_NONE; | |
453 | ||
03385b8e | 454 | fimc_is_set_param_bit(is, PARAM_ISP_AFC); |
294781db SN |
455 | } |
456 | ||
457 | void __is_set_drc_control(struct fimc_is *is, u32 val) | |
458 | { | |
3530ef0a | 459 | unsigned int index = is->config_index; |
294781db | 460 | struct drc_param *drc; |
294781db | 461 | |
3530ef0a | 462 | drc = &is->config[index].drc; |
294781db SN |
463 | |
464 | drc->control.bypass = val; | |
465 | ||
03385b8e | 466 | fimc_is_set_param_bit(is, PARAM_DRC_CONTROL); |
294781db SN |
467 | } |
468 | ||
469 | void __is_set_fd_control(struct fimc_is *is, u32 val) | |
470 | { | |
3530ef0a | 471 | unsigned int index = is->config_index; |
294781db | 472 | struct fd_param *fd; |
3530ef0a | 473 | unsigned long *p_index; |
294781db | 474 | |
0e761b21 | 475 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 476 | fd = &is->config[index].fd; |
294781db SN |
477 | |
478 | fd->control.cmd = val; | |
479 | ||
a6f5635e | 480 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) |
294781db | 481 | fimc_is_set_param_bit(is, PARAM_FD_CONTROL); |
294781db SN |
482 | } |
483 | ||
484 | void __is_set_fd_config_maxface(struct fimc_is *is, u32 val) | |
485 | { | |
3530ef0a | 486 | unsigned int index = is->config_index; |
294781db | 487 | struct fd_param *fd; |
3530ef0a | 488 | unsigned long *p_index; |
294781db | 489 | |
0e761b21 | 490 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 491 | fd = &is->config[index].fd; |
294781db SN |
492 | |
493 | fd->config.max_number = val; | |
494 | ||
495 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) { | |
496 | fd->config.cmd = FD_CONFIG_COMMAND_MAXIMUM_NUMBER; | |
497 | fd->config.err = ERROR_FD_NONE; | |
498 | fimc_is_set_param_bit(is, PARAM_FD_CONFIG); | |
294781db SN |
499 | } else { |
500 | fd->config.cmd |= FD_CONFIG_COMMAND_MAXIMUM_NUMBER; | |
501 | } | |
502 | } | |
503 | ||
504 | void __is_set_fd_config_rollangle(struct fimc_is *is, u32 val) | |
505 | { | |
3530ef0a | 506 | unsigned int index = is->config_index; |
294781db | 507 | struct fd_param *fd; |
3530ef0a | 508 | unsigned long *p_index; |
294781db | 509 | |
0e761b21 | 510 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 511 | fd = &is->config[index].fd; |
294781db SN |
512 | |
513 | fd->config.roll_angle = val; | |
514 | ||
515 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) { | |
516 | fd->config.cmd = FD_CONFIG_COMMAND_ROLL_ANGLE; | |
517 | fd->config.err = ERROR_FD_NONE; | |
518 | fimc_is_set_param_bit(is, PARAM_FD_CONFIG); | |
294781db SN |
519 | } else { |
520 | fd->config.cmd |= FD_CONFIG_COMMAND_ROLL_ANGLE; | |
521 | } | |
522 | } | |
523 | ||
524 | void __is_set_fd_config_yawangle(struct fimc_is *is, u32 val) | |
525 | { | |
3530ef0a | 526 | unsigned int index = is->config_index; |
294781db | 527 | struct fd_param *fd; |
3530ef0a | 528 | unsigned long *p_index; |
294781db | 529 | |
0e761b21 | 530 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 531 | fd = &is->config[index].fd; |
294781db SN |
532 | |
533 | fd->config.yaw_angle = val; | |
534 | ||
535 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) { | |
536 | fd->config.cmd = FD_CONFIG_COMMAND_YAW_ANGLE; | |
537 | fd->config.err = ERROR_FD_NONE; | |
538 | fimc_is_set_param_bit(is, PARAM_FD_CONFIG); | |
294781db SN |
539 | } else { |
540 | fd->config.cmd |= FD_CONFIG_COMMAND_YAW_ANGLE; | |
541 | } | |
542 | } | |
543 | ||
544 | void __is_set_fd_config_smilemode(struct fimc_is *is, u32 val) | |
545 | { | |
3530ef0a | 546 | unsigned int index = is->config_index; |
294781db | 547 | struct fd_param *fd; |
3530ef0a | 548 | unsigned long *p_index; |
294781db | 549 | |
0e761b21 | 550 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 551 | fd = &is->config[index].fd; |
294781db SN |
552 | |
553 | fd->config.smile_mode = val; | |
554 | ||
555 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) { | |
556 | fd->config.cmd = FD_CONFIG_COMMAND_SMILE_MODE; | |
557 | fd->config.err = ERROR_FD_NONE; | |
558 | fimc_is_set_param_bit(is, PARAM_FD_CONFIG); | |
294781db SN |
559 | } else { |
560 | fd->config.cmd |= FD_CONFIG_COMMAND_SMILE_MODE; | |
561 | } | |
562 | } | |
563 | ||
564 | void __is_set_fd_config_blinkmode(struct fimc_is *is, u32 val) | |
565 | { | |
3530ef0a | 566 | unsigned int index = is->config_index; |
294781db | 567 | struct fd_param *fd; |
3530ef0a | 568 | unsigned long *p_index; |
294781db | 569 | |
0e761b21 | 570 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 571 | fd = &is->config[index].fd; |
294781db SN |
572 | |
573 | fd->config.blink_mode = val; | |
574 | ||
575 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) { | |
576 | fd->config.cmd = FD_CONFIG_COMMAND_BLINK_MODE; | |
577 | fd->config.err = ERROR_FD_NONE; | |
578 | fimc_is_set_param_bit(is, PARAM_FD_CONFIG); | |
294781db SN |
579 | } else { |
580 | fd->config.cmd |= FD_CONFIG_COMMAND_BLINK_MODE; | |
581 | } | |
582 | } | |
583 | ||
584 | void __is_set_fd_config_eyedetect(struct fimc_is *is, u32 val) | |
585 | { | |
3530ef0a | 586 | unsigned int index = is->config_index; |
294781db | 587 | struct fd_param *fd; |
3530ef0a | 588 | unsigned long *p_index; |
294781db | 589 | |
0e761b21 | 590 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 591 | fd = &is->config[index].fd; |
294781db SN |
592 | |
593 | fd->config.eye_detect = val; | |
594 | ||
595 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) { | |
596 | fd->config.cmd = FD_CONFIG_COMMAND_EYES_DETECT; | |
597 | fd->config.err = ERROR_FD_NONE; | |
598 | fimc_is_set_param_bit(is, PARAM_FD_CONFIG); | |
294781db SN |
599 | } else { |
600 | fd->config.cmd |= FD_CONFIG_COMMAND_EYES_DETECT; | |
601 | } | |
602 | } | |
603 | ||
604 | void __is_set_fd_config_mouthdetect(struct fimc_is *is, u32 val) | |
605 | { | |
3530ef0a | 606 | unsigned int index = is->config_index; |
294781db | 607 | struct fd_param *fd; |
3530ef0a | 608 | unsigned long *p_index; |
294781db | 609 | |
0e761b21 | 610 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 611 | fd = &is->config[index].fd; |
294781db SN |
612 | |
613 | fd->config.mouth_detect = val; | |
614 | ||
615 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) { | |
616 | fd->config.cmd = FD_CONFIG_COMMAND_MOUTH_DETECT; | |
617 | fd->config.err = ERROR_FD_NONE; | |
618 | fimc_is_set_param_bit(is, PARAM_FD_CONFIG); | |
294781db SN |
619 | } else { |
620 | fd->config.cmd |= FD_CONFIG_COMMAND_MOUTH_DETECT; | |
621 | } | |
622 | } | |
623 | ||
624 | void __is_set_fd_config_orientation(struct fimc_is *is, u32 val) | |
625 | { | |
3530ef0a | 626 | unsigned int index = is->config_index; |
294781db | 627 | struct fd_param *fd; |
3530ef0a | 628 | unsigned long *p_index; |
294781db | 629 | |
0e761b21 | 630 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 631 | fd = &is->config[index].fd; |
294781db SN |
632 | |
633 | fd->config.orientation = val; | |
634 | ||
635 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) { | |
636 | fd->config.cmd = FD_CONFIG_COMMAND_ORIENTATION; | |
637 | fd->config.err = ERROR_FD_NONE; | |
638 | fimc_is_set_param_bit(is, PARAM_FD_CONFIG); | |
294781db SN |
639 | } else { |
640 | fd->config.cmd |= FD_CONFIG_COMMAND_ORIENTATION; | |
641 | } | |
642 | } | |
643 | ||
644 | void __is_set_fd_config_orientation_val(struct fimc_is *is, u32 val) | |
645 | { | |
3530ef0a | 646 | unsigned int index = is->config_index; |
294781db | 647 | struct fd_param *fd; |
3530ef0a | 648 | unsigned long *p_index; |
294781db | 649 | |
0e761b21 | 650 | p_index = &is->config[index].p_region_index[1]; |
3530ef0a | 651 | fd = &is->config[index].fd; |
294781db SN |
652 | |
653 | fd->config.orientation_value = val; | |
654 | ||
655 | if (!test_bit((PARAM_FD_CONFIG - 32), p_index)) { | |
656 | fd->config.cmd = FD_CONFIG_COMMAND_ORIENTATION_VALUE; | |
657 | fd->config.err = ERROR_FD_NONE; | |
658 | fimc_is_set_param_bit(is, PARAM_FD_CONFIG); | |
294781db SN |
659 | } else { |
660 | fd->config.cmd |= FD_CONFIG_COMMAND_ORIENTATION_VALUE; | |
661 | } | |
662 | } | |
663 | ||
664 | void fimc_is_set_initial_params(struct fimc_is *is) | |
665 | { | |
666 | struct global_param *global; | |
294781db SN |
667 | struct isp_param *isp; |
668 | struct drc_param *drc; | |
669 | struct fd_param *fd; | |
0e761b21 | 670 | unsigned long *p_index; |
3530ef0a | 671 | unsigned int index; |
294781db | 672 | |
3530ef0a SN |
673 | index = is->config_index; |
674 | global = &is->config[index].global; | |
3530ef0a SN |
675 | isp = &is->config[index].isp; |
676 | drc = &is->config[index].drc; | |
677 | fd = &is->config[index].fd; | |
0e761b21 | 678 | p_index = &is->config[index].p_region_index[0]; |
294781db SN |
679 | |
680 | /* Global */ | |
681 | global->shotmode.cmd = 1; | |
682 | fimc_is_set_param_bit(is, PARAM_GLOBAL_SHOTMODE); | |
294781db SN |
683 | |
684 | /* ISP */ | |
685 | isp->control.cmd = CONTROL_COMMAND_START; | |
686 | isp->control.bypass = CONTROL_BYPASS_DISABLE; | |
687 | isp->control.err = CONTROL_ERROR_NONE; | |
688 | fimc_is_set_param_bit(is, PARAM_ISP_CONTROL); | |
294781db SN |
689 | |
690 | isp->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE; | |
0e761b21 | 691 | if (!test_bit(PARAM_ISP_OTF_INPUT, p_index)) { |
294781db SN |
692 | isp->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH; |
693 | isp->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT; | |
694 | fimc_is_set_param_bit(is, PARAM_ISP_OTF_INPUT); | |
294781db SN |
695 | } |
696 | if (is->sensor->test_pattern) | |
697 | isp->otf_input.format = OTF_INPUT_FORMAT_STRGEN_COLORBAR_BAYER; | |
698 | else | |
699 | isp->otf_input.format = OTF_INPUT_FORMAT_BAYER; | |
700 | isp->otf_input.bitwidth = 10; | |
701 | isp->otf_input.order = OTF_INPUT_ORDER_BAYER_GR_BG; | |
702 | isp->otf_input.crop_offset_x = 0; | |
703 | isp->otf_input.crop_offset_y = 0; | |
704 | isp->otf_input.err = OTF_INPUT_ERROR_NONE; | |
705 | ||
706 | isp->dma1_input.cmd = DMA_INPUT_COMMAND_DISABLE; | |
707 | isp->dma1_input.width = 0; | |
708 | isp->dma1_input.height = 0; | |
709 | isp->dma1_input.format = 0; | |
710 | isp->dma1_input.bitwidth = 0; | |
711 | isp->dma1_input.plane = 0; | |
712 | isp->dma1_input.order = 0; | |
713 | isp->dma1_input.buffer_number = 0; | |
714 | isp->dma1_input.width = 0; | |
715 | isp->dma1_input.err = DMA_INPUT_ERROR_NONE; | |
716 | fimc_is_set_param_bit(is, PARAM_ISP_DMA1_INPUT); | |
294781db SN |
717 | |
718 | isp->dma2_input.cmd = DMA_INPUT_COMMAND_DISABLE; | |
719 | isp->dma2_input.width = 0; | |
720 | isp->dma2_input.height = 0; | |
721 | isp->dma2_input.format = 0; | |
722 | isp->dma2_input.bitwidth = 0; | |
723 | isp->dma2_input.plane = 0; | |
724 | isp->dma2_input.order = 0; | |
725 | isp->dma2_input.buffer_number = 0; | |
726 | isp->dma2_input.width = 0; | |
727 | isp->dma2_input.err = DMA_INPUT_ERROR_NONE; | |
728 | fimc_is_set_param_bit(is, PARAM_ISP_DMA2_INPUT); | |
294781db SN |
729 | |
730 | isp->aa.cmd = ISP_AA_COMMAND_START; | |
731 | isp->aa.target = ISP_AA_TARGET_AE | ISP_AA_TARGET_AWB; | |
732 | fimc_is_set_param_bit(is, PARAM_ISP_AA); | |
294781db | 733 | |
0e761b21 | 734 | if (!test_bit(PARAM_ISP_FLASH, p_index)) |
294781db SN |
735 | __is_set_isp_flash(is, ISP_FLASH_COMMAND_DISABLE, |
736 | ISP_FLASH_REDEYE_DISABLE); | |
737 | ||
0e761b21 | 738 | if (!test_bit(PARAM_ISP_AWB, p_index)) |
294781db SN |
739 | __is_set_isp_awb(is, ISP_AWB_COMMAND_AUTO, 0); |
740 | ||
0e761b21 | 741 | if (!test_bit(PARAM_ISP_IMAGE_EFFECT, p_index)) |
294781db SN |
742 | __is_set_isp_effect(is, ISP_IMAGE_EFFECT_DISABLE); |
743 | ||
0e761b21 | 744 | if (!test_bit(PARAM_ISP_ISO, p_index)) |
294781db SN |
745 | __is_set_isp_iso(is, ISP_ISO_COMMAND_AUTO, 0); |
746 | ||
0e761b21 | 747 | if (!test_bit(PARAM_ISP_ADJUST, p_index)) { |
294781db SN |
748 | __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_CONTRAST, 0); |
749 | __is_set_isp_adjust(is, | |
750 | ISP_ADJUST_COMMAND_MANUAL_SATURATION, 0); | |
751 | __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_SHARPNESS, 0); | |
752 | __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_EXPOSURE, 0); | |
753 | __is_set_isp_adjust(is, | |
754 | ISP_ADJUST_COMMAND_MANUAL_BRIGHTNESS, 0); | |
755 | __is_set_isp_adjust(is, ISP_ADJUST_COMMAND_MANUAL_HUE, 0); | |
756 | } | |
757 | ||
0e761b21 | 758 | if (!test_bit(PARAM_ISP_METERING, p_index)) { |
294781db SN |
759 | __is_set_isp_metering(is, 0, ISP_METERING_COMMAND_CENTER); |
760 | __is_set_isp_metering(is, 1, 0); | |
761 | __is_set_isp_metering(is, 2, 0); | |
762 | __is_set_isp_metering(is, 3, 0); | |
763 | __is_set_isp_metering(is, 4, 0); | |
764 | } | |
765 | ||
0e761b21 | 766 | if (!test_bit(PARAM_ISP_AFC, p_index)) |
294781db SN |
767 | __is_set_isp_afc(is, ISP_AFC_COMMAND_AUTO, 0); |
768 | ||
769 | isp->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE; | |
0e761b21 | 770 | if (!test_bit(PARAM_ISP_OTF_OUTPUT, p_index)) { |
294781db SN |
771 | isp->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH; |
772 | isp->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT; | |
773 | fimc_is_set_param_bit(is, PARAM_ISP_OTF_OUTPUT); | |
294781db SN |
774 | } |
775 | isp->otf_output.format = OTF_OUTPUT_FORMAT_YUV444; | |
776 | isp->otf_output.bitwidth = 12; | |
777 | isp->otf_output.order = 0; | |
778 | isp->otf_output.err = OTF_OUTPUT_ERROR_NONE; | |
779 | ||
0e761b21 | 780 | if (!test_bit(PARAM_ISP_DMA1_OUTPUT, p_index)) { |
294781db SN |
781 | isp->dma1_output.cmd = DMA_OUTPUT_COMMAND_DISABLE; |
782 | isp->dma1_output.width = 0; | |
783 | isp->dma1_output.height = 0; | |
784 | isp->dma1_output.format = 0; | |
785 | isp->dma1_output.bitwidth = 0; | |
786 | isp->dma1_output.plane = 0; | |
787 | isp->dma1_output.order = 0; | |
788 | isp->dma1_output.buffer_number = 0; | |
789 | isp->dma1_output.buffer_address = 0; | |
790 | isp->dma1_output.notify_dma_done = 0; | |
791 | isp->dma1_output.dma_out_mask = 0; | |
792 | isp->dma1_output.err = DMA_OUTPUT_ERROR_NONE; | |
793 | fimc_is_set_param_bit(is, PARAM_ISP_DMA1_OUTPUT); | |
294781db SN |
794 | } |
795 | ||
0e761b21 | 796 | if (!test_bit(PARAM_ISP_DMA2_OUTPUT, p_index)) { |
294781db SN |
797 | isp->dma2_output.cmd = DMA_OUTPUT_COMMAND_DISABLE; |
798 | isp->dma2_output.width = 0; | |
799 | isp->dma2_output.height = 0; | |
800 | isp->dma2_output.format = 0; | |
801 | isp->dma2_output.bitwidth = 0; | |
802 | isp->dma2_output.plane = 0; | |
803 | isp->dma2_output.order = 0; | |
804 | isp->dma2_output.buffer_number = 0; | |
805 | isp->dma2_output.buffer_address = 0; | |
806 | isp->dma2_output.notify_dma_done = 0; | |
807 | isp->dma2_output.dma_out_mask = 0; | |
808 | isp->dma2_output.err = DMA_OUTPUT_ERROR_NONE; | |
809 | fimc_is_set_param_bit(is, PARAM_ISP_DMA2_OUTPUT); | |
294781db SN |
810 | } |
811 | ||
812 | /* Sensor */ | |
0e761b21 | 813 | if (!test_bit(PARAM_SENSOR_FRAME_RATE, p_index)) { |
3530ef0a | 814 | if (is->config_index == 0) |
294781db SN |
815 | __is_set_sensor(is, 0); |
816 | } | |
817 | ||
818 | /* DRC */ | |
819 | drc->control.cmd = CONTROL_COMMAND_START; | |
820 | __is_set_drc_control(is, CONTROL_BYPASS_ENABLE); | |
821 | ||
822 | drc->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE; | |
0e761b21 | 823 | if (!test_bit(PARAM_DRC_OTF_INPUT, p_index)) { |
294781db SN |
824 | drc->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH; |
825 | drc->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT; | |
826 | fimc_is_set_param_bit(is, PARAM_DRC_OTF_INPUT); | |
294781db SN |
827 | } |
828 | drc->otf_input.format = OTF_INPUT_FORMAT_YUV444; | |
829 | drc->otf_input.bitwidth = 12; | |
830 | drc->otf_input.order = 0; | |
831 | drc->otf_input.err = OTF_INPUT_ERROR_NONE; | |
832 | ||
833 | drc->dma_input.cmd = DMA_INPUT_COMMAND_DISABLE; | |
834 | drc->dma_input.width = 0; | |
835 | drc->dma_input.height = 0; | |
836 | drc->dma_input.format = 0; | |
837 | drc->dma_input.bitwidth = 0; | |
838 | drc->dma_input.plane = 0; | |
839 | drc->dma_input.order = 0; | |
840 | drc->dma_input.buffer_number = 0; | |
841 | drc->dma_input.width = 0; | |
842 | drc->dma_input.err = DMA_INPUT_ERROR_NONE; | |
843 | fimc_is_set_param_bit(is, PARAM_DRC_DMA_INPUT); | |
294781db SN |
844 | |
845 | drc->otf_output.cmd = OTF_OUTPUT_COMMAND_ENABLE; | |
0e761b21 | 846 | if (!test_bit(PARAM_DRC_OTF_OUTPUT, p_index)) { |
294781db SN |
847 | drc->otf_output.width = DEFAULT_PREVIEW_STILL_WIDTH; |
848 | drc->otf_output.height = DEFAULT_PREVIEW_STILL_HEIGHT; | |
849 | fimc_is_set_param_bit(is, PARAM_DRC_OTF_OUTPUT); | |
294781db SN |
850 | } |
851 | drc->otf_output.format = OTF_OUTPUT_FORMAT_YUV444; | |
852 | drc->otf_output.bitwidth = 8; | |
853 | drc->otf_output.order = 0; | |
854 | drc->otf_output.err = OTF_OUTPUT_ERROR_NONE; | |
855 | ||
856 | /* FD */ | |
857 | __is_set_fd_control(is, CONTROL_COMMAND_STOP); | |
858 | fd->control.bypass = CONTROL_BYPASS_DISABLE; | |
859 | ||
860 | fd->otf_input.cmd = OTF_INPUT_COMMAND_ENABLE; | |
0e761b21 | 861 | if (!test_bit(PARAM_FD_OTF_INPUT, p_index)) { |
294781db SN |
862 | fd->otf_input.width = DEFAULT_PREVIEW_STILL_WIDTH; |
863 | fd->otf_input.height = DEFAULT_PREVIEW_STILL_HEIGHT; | |
864 | fimc_is_set_param_bit(is, PARAM_FD_OTF_INPUT); | |
294781db | 865 | } |
a6f5635e | 866 | |
294781db SN |
867 | fd->otf_input.format = OTF_INPUT_FORMAT_YUV444; |
868 | fd->otf_input.bitwidth = 8; | |
869 | fd->otf_input.order = 0; | |
870 | fd->otf_input.err = OTF_INPUT_ERROR_NONE; | |
871 | ||
872 | fd->dma_input.cmd = DMA_INPUT_COMMAND_DISABLE; | |
873 | fd->dma_input.width = 0; | |
874 | fd->dma_input.height = 0; | |
875 | fd->dma_input.format = 0; | |
876 | fd->dma_input.bitwidth = 0; | |
877 | fd->dma_input.plane = 0; | |
878 | fd->dma_input.order = 0; | |
879 | fd->dma_input.buffer_number = 0; | |
880 | fd->dma_input.width = 0; | |
881 | fd->dma_input.err = DMA_INPUT_ERROR_NONE; | |
882 | fimc_is_set_param_bit(is, PARAM_FD_DMA_INPUT); | |
294781db SN |
883 | |
884 | __is_set_fd_config_maxface(is, 5); | |
885 | __is_set_fd_config_rollangle(is, FD_CONFIG_ROLL_ANGLE_FULL); | |
886 | __is_set_fd_config_yawangle(is, FD_CONFIG_YAW_ANGLE_45_90); | |
887 | __is_set_fd_config_smilemode(is, FD_CONFIG_SMILE_MODE_DISABLE); | |
888 | __is_set_fd_config_blinkmode(is, FD_CONFIG_BLINK_MODE_DISABLE); | |
889 | __is_set_fd_config_eyedetect(is, FD_CONFIG_EYES_DETECT_ENABLE); | |
890 | __is_set_fd_config_mouthdetect(is, FD_CONFIG_MOUTH_DETECT_DISABLE); | |
891 | __is_set_fd_config_orientation(is, FD_CONFIG_ORIENTATION_DISABLE); | |
892 | __is_set_fd_config_orientation_val(is, 0); | |
893 | } |