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