4 * Driver Library for Preview module in TI's OMAP3 Camera ISP
6 * Copyright (C) 2009 Texas Instruments, Inc.
9 * Senthilvadivu Guruswamy <svadivu@ti.com>
10 * Pallavi Kulkarni <p-kulkarni@ti.com>
11 * Sergio Aguirre <saaguirre@ti.com>
13 * This package is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
17 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
19 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 #include <linux/mutex.h>
23 #include <linux/module.h>
24 #include <linux/uaccess.h>
25 #include <linux/device.h>
29 #include "isppreview.h"
31 /* Structure for saving/restoring preview module registers */
32 static struct isp_reg ispprev_reg_list
[] = {
33 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_HORZ_INFO
, 0x0000},
34 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_VERT_INFO
, 0x0000},
35 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_RSDR_ADDR
, 0x0000},
36 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_RADR_OFFSET
, 0x0000},
37 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_DSDR_ADDR
, 0x0000},
38 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_DRKF_OFFSET
, 0x0000},
39 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_WSDR_ADDR
, 0x0000},
40 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_WADD_OFFSET
, 0x0000},
41 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_AVE
, 0x0000},
42 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_HMED
, 0x0000},
43 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_NF
, 0x0000},
44 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_WB_DGAIN
, 0x0000},
45 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_WBGAIN
, 0x0000},
46 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_WBSEL
, 0x0000},
47 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CFA
, 0x0000},
48 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_BLKADJOFF
, 0x0000},
49 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT1
, 0x0000},
50 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT2
, 0x0000},
51 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT3
, 0x0000},
52 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT4
, 0x0000},
53 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT5
, 0x0000},
54 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_OFF1
, 0x0000},
55 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_OFF2
, 0x0000},
56 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC0
, 0x0000},
57 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC1
, 0x0000},
58 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC2
, 0x0000},
59 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC_OFFSET
, 0x0000},
60 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CNT_BRT
, 0x0000},
61 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSUP
, 0x0000},
62 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_SETUP_YC
, 0x0000},
63 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR0
, 0x0000},
64 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR1
, 0x0000},
65 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR2
, 0x0000},
66 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR3
, 0x0000},
67 {OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
, 0x0000},
68 {0, ISP_TOK_TERM
, 0x0000}
72 /* Default values in Office Flourescent Light for RGBtoRGB Blending */
73 static struct ispprev_rgbtorgb flr_rgb2rgb
= {
74 { /* RGB-RGB Matrix */
75 {0x01E2, 0x0F30, 0x0FEE},
76 {0x0F9B, 0x01AC, 0x0FB9},
77 {0x0FE0, 0x0EC0, 0x0260}
79 {0x0000, 0x0000, 0x0000}
82 /* Default values in Office Flourescent Light for RGB to YUV Conversion*/
83 static struct ispprev_csc flr_prev_csc
[] = {
85 { /* CSC Coef Matrix */
93 { /* CSC Coef Matrix BW */
101 { /* CSC Coef Matrix Sepia */
111 /* Default values in Office Flourescent Light for CFA Gradient*/
112 #define FLR_CFA_GRADTHRS_HORZ 0x28
113 #define FLR_CFA_GRADTHRS_VERT 0x28
115 /* Default values in Office Flourescent Light for Chroma Suppression*/
116 #define FLR_CSUP_GAIN 0x0D
117 #define FLR_CSUP_THRES 0xEB
119 /* Default values in Office Flourescent Light for Noise Filter*/
120 #define FLR_NF_STRGTH 0x03
122 /* Default values in Office Flourescent Light for White Balance*/
123 #define FLR_WBAL_DGAIN 0x100
124 #define FLR_WBAL_COEF0 0x29
125 #define FLR_WBAL_COEF1 0x20
126 #define FLR_WBAL_COEF2 0x20
127 #define FLR_WBAL_COEF3 0x2d
129 #define FLR_WBAL_COEF0_ES1 0x23
130 #define FLR_WBAL_COEF1_ES1 0x20
131 #define FLR_WBAL_COEF2_ES1 0x20
132 #define FLR_WBAL_COEF3_ES1 0x39
134 /* Default values in Office Flourescent Light for Black Adjustment*/
135 #define FLR_BLKADJ_BLUE 0x0
136 #define FLR_BLKADJ_GREEN 0x0
137 #define FLR_BLKADJ_RED 0x0
140 * Coeficient Tables for the submodules in Preview.
141 * Array is initialised with the values from.the tables text file.
145 * CFA Filter Coefficient Table
148 static u32 cfa_coef_table
[] = {
149 #include "cfa_coef_table.h"
153 * Gamma Correction Table - Red
155 static u32 redgamma_table
[] = {
156 #include "redgamma_table.h"
160 * Gamma Correction Table - Green
162 static u32 greengamma_table
[] = {
163 #include "greengamma_table.h"
167 * Gamma Correction Table - Blue
169 static u32 bluegamma_table
[] = {
170 #include "bluegamma_table.h"
174 * Noise Filter Threshold table
176 static u32 noise_filter_table
[] = {
177 #include "noise_filter_table.h"
181 * Luminance Enhancement Table
183 static u32 luma_enhance_table
[] = {
184 #include "luma_enhance_table.h"
187 static int omap34xx_isp_tables_update(struct isp_prev_device
*isp_prev
,
188 struct isptables_update
*isptables_struct
);
192 * omap34xx_isp_preview_config - Abstraction layer Preview configuration.
193 * @userspace_add: Pointer from Userspace to structure with flags and data to
196 int omap34xx_isp_preview_config(struct isp_prev_device
*isp_prev
,
199 struct isp_device
*isp
=
200 container_of(isp_prev
, struct isp_device
, isp_prev
);
201 struct ispprev_hmed prev_hmed_t
;
202 struct ispprev_csup csup_t
;
203 struct ispprev_wbal prev_wbal_t
;
204 struct ispprev_blkadj prev_blkadj_t
;
205 struct ispprev_yclimit yclimit_t
;
206 struct ispprev_dcor prev_dcor_t
;
207 struct ispprv_update_config
*config
;
208 struct isptables_update isp_table_update
;
209 int yen_t
[ISPPRV_YENH_TBL_SIZE
];
212 if (userspace_add
== NULL
)
215 spin_lock_irqsave(&isp_prev
->lock
, flags
);
216 isp_prev
->shadow_update
= 1;
217 spin_unlock_irqrestore(&isp_prev
->lock
, flags
);
219 config
= userspace_add
;
221 if (isp
->running
!= ISP_STOPPED
)
222 goto out_config_shadow
;
224 if (ISP_ABS_PREV_LUMAENH
& config
->flag
) {
225 if (ISP_ABS_PREV_LUMAENH
& config
->update
) {
226 if (copy_from_user(yen_t
, config
->yen
,
228 goto err_copy_from_user
;
229 isppreview_config_luma_enhancement(isp_prev
, yen_t
);
231 isp_prev
->params
.features
|= PREV_LUMA_ENHANCE
;
232 } else if (ISP_ABS_PREV_LUMAENH
& config
->update
)
233 isp_prev
->params
.features
&= ~PREV_LUMA_ENHANCE
;
235 if (ISP_ABS_PREV_INVALAW
& config
->flag
) {
236 isppreview_enable_invalaw(isp_prev
, 1);
237 isp_prev
->params
.features
|= PREV_INVERSE_ALAW
;
239 isppreview_enable_invalaw(isp_prev
, 0);
240 isp_prev
->params
.features
&= ~PREV_INVERSE_ALAW
;
243 if (ISP_ABS_PREV_HRZ_MED
& config
->flag
) {
244 if (ISP_ABS_PREV_HRZ_MED
& config
->update
) {
245 if (copy_from_user(&prev_hmed_t
,
246 (struct ispprev_hmed
*)
248 sizeof(struct ispprev_hmed
)))
249 goto err_copy_from_user
;
250 isppreview_config_hmed(isp_prev
, prev_hmed_t
);
252 isppreview_enable_hmed(isp_prev
, 1);
253 isp_prev
->params
.features
|= PREV_HORZ_MEDIAN_FILTER
;
254 } else if (ISP_ABS_PREV_HRZ_MED
& config
->update
) {
255 isppreview_enable_hmed(isp_prev
, 0);
256 isp_prev
->params
.features
&= ~PREV_HORZ_MEDIAN_FILTER
;
259 if (ISP_ABS_PREV_CHROMA_SUPP
& config
->flag
) {
260 if (ISP_ABS_PREV_CHROMA_SUPP
& config
->update
) {
261 if (copy_from_user(&csup_t
,
262 (struct ispprev_csup
*)
264 sizeof(struct ispprev_csup
)))
265 goto err_copy_from_user
;
266 isppreview_config_chroma_suppression(isp_prev
, csup_t
);
268 isppreview_enable_chroma_suppression(isp_prev
, 1);
269 isp_prev
->params
.features
|= PREV_CHROMA_SUPPRESS
;
270 } else if (ISP_ABS_PREV_CHROMA_SUPP
& config
->update
) {
271 isppreview_enable_chroma_suppression(isp_prev
, 0);
272 isp_prev
->params
.features
&= ~PREV_CHROMA_SUPPRESS
;
275 if (ISP_ABS_PREV_WB
& config
->update
) {
276 if (copy_from_user(&prev_wbal_t
, (struct ispprev_wbal
*)
278 sizeof(struct ispprev_wbal
)))
279 goto err_copy_from_user
;
280 isppreview_config_whitebalance(isp_prev
, prev_wbal_t
);
283 if (ISP_ABS_PREV_BLKADJ
& config
->update
) {
284 if (copy_from_user(&prev_blkadj_t
, (struct ispprev_blkadjl
*)
286 sizeof(struct ispprev_blkadj
)))
287 goto err_copy_from_user
;
288 isppreview_config_blkadj(isp_prev
, prev_blkadj_t
);
291 if (ISP_ABS_PREV_YC_LIMIT
& config
->update
) {
292 if (copy_from_user(&yclimit_t
, (struct ispprev_yclimit
*)
294 sizeof(struct ispprev_yclimit
)))
295 goto err_copy_from_user
;
296 isppreview_config_yc_range(isp_prev
, yclimit_t
);
299 if (ISP_ABS_PREV_DEFECT_COR
& config
->flag
) {
300 if (ISP_ABS_PREV_DEFECT_COR
& config
->update
) {
301 if (copy_from_user(&prev_dcor_t
,
302 (struct ispprev_dcor
*)
304 sizeof(struct ispprev_dcor
)))
305 goto err_copy_from_user
;
306 isppreview_config_dcor(isp_prev
, prev_dcor_t
);
308 isppreview_enable_dcor(isp_prev
, 1);
309 isp_prev
->params
.features
|= PREV_DEFECT_COR
;
310 } else if (ISP_ABS_PREV_DEFECT_COR
& config
->update
) {
311 isppreview_enable_dcor(isp_prev
, 0);
312 isp_prev
->params
.features
&= ~PREV_DEFECT_COR
;
315 if (ISP_ABS_PREV_GAMMABYPASS
& config
->flag
) {
316 isppreview_enable_gammabypass(isp_prev
, 1);
317 isp_prev
->params
.features
|= PREV_GAMMA_BYPASS
;
319 isppreview_enable_gammabypass(isp_prev
, 0);
320 isp_prev
->params
.features
&= ~PREV_GAMMA_BYPASS
;
324 if (ISP_ABS_PREV_RGB2RGB
& config
->update
) {
325 if (copy_from_user(&isp_prev
->params
.rgb2rgb
,
326 (struct ispprev_rgbtorgb
*)
328 sizeof(struct ispprev_rgbtorgb
)))
329 goto err_copy_from_user
;
330 isppreview_config_rgb_blending(isp_prev
,
331 isp_prev
->params
.rgb2rgb
);
332 /* The function call above prevents compiler from reordering
333 * writes so that the flag below is always set after
334 * isp_prev->params.rgb2rgb is written to. */
335 isp_prev
->update_rgb_blending
= 1;
338 if (ISP_ABS_PREV_COLOR_CONV
& config
->update
) {
339 if (copy_from_user(&isp_prev
->params
.rgb2ycbcr
,
340 (struct ispprev_csc
*)
342 sizeof(struct ispprev_csc
)))
343 goto err_copy_from_user
;
344 isppreview_config_rgb_to_ycbcr(isp_prev
,
345 isp_prev
->params
.rgb2ycbcr
);
346 /* Same here... this flag has to be set after rgb2ycbcr
347 * structure is written to. */
348 isp_prev
->update_rgb_to_ycbcr
= 1;
351 isp_table_update
.update
= config
->update
;
352 isp_table_update
.flag
= config
->flag
;
353 isp_table_update
.prev_nf
= config
->prev_nf
;
354 isp_table_update
.red_gamma
= config
->red_gamma
;
355 isp_table_update
.green_gamma
= config
->green_gamma
;
356 isp_table_update
.blue_gamma
= config
->blue_gamma
;
357 isp_table_update
.prev_cfa
= config
->prev_cfa
;
359 if (omap34xx_isp_tables_update(isp_prev
, &isp_table_update
))
360 goto err_copy_from_user
;
362 spin_lock_irqsave(&isp_prev
->lock
, flags
);
363 isp_prev
->shadow_update
= 0;
364 spin_unlock_irqrestore(&isp_prev
->lock
, flags
);
369 spin_lock_irqsave(&isp_prev
->lock
, flags
);
370 isp_prev
->shadow_update
= 0;
371 spin_unlock_irqrestore(&isp_prev
->lock
, flags
);
373 dev_err(isp_prev
->dev
, "preview: Config: Copy From User Error\n");
376 EXPORT_SYMBOL_GPL(omap34xx_isp_preview_config
);
379 * omap34xx_isp_tables_update - Abstraction layer Tables update.
380 * @isptables_struct: Pointer from Userspace to structure with flags and table
383 static int omap34xx_isp_tables_update(struct isp_prev_device
*isp_prev
,
384 struct isptables_update
*isptables_struct
)
387 if (ISP_ABS_TBL_NF
& isptables_struct
->flag
) {
388 isp_prev
->nf_enable
= 1;
389 isp_prev
->params
.features
|= PREV_NOISE_FILTER
;
390 if (ISP_ABS_TBL_NF
& isptables_struct
->update
) {
391 if (copy_from_user(&isp_prev
->prev_nf_t
,
392 (struct ispprev_nf
*)
393 isptables_struct
->prev_nf
,
394 sizeof(struct ispprev_nf
)))
395 goto err_copy_from_user
;
397 isp_prev
->nf_update
= 1;
399 isp_prev
->nf_update
= 0;
401 isp_prev
->nf_enable
= 0;
402 isp_prev
->params
.features
&= ~PREV_NOISE_FILTER
;
403 if (ISP_ABS_TBL_NF
& isptables_struct
->update
)
404 isp_prev
->nf_update
= 1;
406 isp_prev
->nf_update
= 0;
409 if (ISP_ABS_TBL_REDGAMMA
& isptables_struct
->update
) {
410 if (copy_from_user(redgamma_table
, isptables_struct
->red_gamma
,
411 sizeof(redgamma_table
))) {
412 goto err_copy_from_user
;
414 isp_prev
->rg_update
= 1;
416 isp_prev
->rg_update
= 0;
418 if (ISP_ABS_TBL_GREENGAMMA
& isptables_struct
->update
) {
419 if (copy_from_user(greengamma_table
,
420 isptables_struct
->green_gamma
,
421 sizeof(greengamma_table
)))
422 goto err_copy_from_user
;
423 isp_prev
->gg_update
= 1;
425 isp_prev
->gg_update
= 0;
427 if (ISP_ABS_TBL_BLUEGAMMA
& isptables_struct
->update
) {
428 if (copy_from_user(bluegamma_table
,
429 isptables_struct
->blue_gamma
,
430 sizeof(bluegamma_table
))) {
431 goto err_copy_from_user
;
433 isp_prev
->bg_update
= 1;
435 isp_prev
->bg_update
= 0;
437 if (ISP_ABS_PREV_CFA
& isptables_struct
->update
) {
438 struct ispprev_cfa cfa
;
439 if (isptables_struct
->prev_cfa
) {
440 if (copy_from_user(&cfa
,
441 isptables_struct
->prev_cfa
,
442 sizeof(struct ispprev_cfa
)))
443 goto err_copy_from_user
;
444 if (cfa
.cfa_table
!= NULL
) {
445 if (copy_from_user(cfa_coef_table
,
447 sizeof(cfa_coef_table
)))
448 goto err_copy_from_user
;
450 cfa
.cfa_table
= cfa_coef_table
;
451 isp_prev
->params
.cfa
= cfa
;
453 if (ISP_ABS_PREV_CFA
& isptables_struct
->flag
) {
454 isp_prev
->cfa_en
= 1;
455 isp_prev
->params
.features
|= PREV_CFA
;
457 isp_prev
->cfa_en
= 0;
458 isp_prev
->params
.features
&= ~PREV_CFA
;
460 isp_prev
->cfa_update
= 1;
466 dev_err(isp_prev
->dev
, "preview tables: Copy From User Error\n");
471 * isppreview_config_shadow_registers - Program shadow registers for preview.
473 * Allows user to program shadow registers associated with preview module.
475 void isppreview_config_shadow_registers(struct isp_prev_device
*isp_prev
)
477 u8 current_brightness_contrast
;
481 spin_lock_irqsave(&isp_prev
->lock
, flags
);
482 if (isp_prev
->shadow_update
) {
483 spin_unlock_irqrestore(&isp_prev
->lock
, flags
);
487 isppreview_query_brightness(isp_prev
, ¤t_brightness_contrast
);
488 if (current_brightness_contrast
!= isp_prev
->brightness
) {
489 DPRINTK_ISPPREV(" Changing Brightness level to %d\n",
490 isp_prev
->brightness
);
491 isppreview_config_brightness(isp_prev
, isp_prev
->brightness
);
494 isppreview_query_contrast(isp_prev
, ¤t_brightness_contrast
);
495 if (current_brightness_contrast
!= isp_prev
->contrast
) {
496 DPRINTK_ISPPREV(" Changing Contrast level to %d\n",
498 isppreview_config_contrast(isp_prev
, isp_prev
->contrast
);
500 if (isp_prev
->update_color_matrix
) {
501 isppreview_config_rgb_to_ycbcr(isp_prev
,
502 flr_prev_csc
[isp_prev
->color
]);
503 isp_prev
->update_color_matrix
= 0;
505 if (isp_prev
->update_rgb_blending
) {
506 isp_prev
->update_rgb_blending
= 0;
507 isppreview_config_rgb_blending(isp_prev
,
508 isp_prev
->params
.rgb2rgb
);
510 if (isp_prev
->update_rgb_to_ycbcr
) {
511 isp_prev
->update_rgb_to_ycbcr
= 0;
512 isppreview_config_rgb_to_ycbcr(isp_prev
,
513 isp_prev
->params
.rgb2ycbcr
);
516 if (isp_prev
->gg_update
) {
517 isp_reg_writel(isp_prev
->dev
, ISPPRV_TBL_ADDR_GREEN_G_START
,
518 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
520 for (ctr
= 0; ctr
< ISP_GAMMA_TABLE_SIZE
; ctr
++) {
521 isp_reg_writel(isp_prev
->dev
, greengamma_table
[ctr
],
522 OMAP3_ISP_IOMEM_PREV
,
523 ISPPRV_SET_TBL_DATA
);
525 isp_prev
->gg_update
= 0;
528 if (isp_prev
->rg_update
) {
529 isp_reg_writel(isp_prev
->dev
, ISPPRV_TBL_ADDR_RED_G_START
,
530 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
532 for (ctr
= 0; ctr
< ISP_GAMMA_TABLE_SIZE
; ctr
++) {
533 isp_reg_writel(isp_prev
->dev
, redgamma_table
[ctr
],
534 OMAP3_ISP_IOMEM_PREV
,
535 ISPPRV_SET_TBL_DATA
);
537 isp_prev
->rg_update
= 0;
540 if (isp_prev
->bg_update
) {
541 isp_reg_writel(isp_prev
->dev
, ISPPRV_TBL_ADDR_BLUE_G_START
,
542 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
544 for (ctr
= 0; ctr
< ISP_GAMMA_TABLE_SIZE
; ctr
++) {
545 isp_reg_writel(isp_prev
->dev
, bluegamma_table
[ctr
],
546 OMAP3_ISP_IOMEM_PREV
,
547 ISPPRV_SET_TBL_DATA
);
549 isp_prev
->bg_update
= 0;
552 if (isp_prev
->cfa_update
) {
553 isp_prev
->cfa_update
= 0;
554 isppreview_config_cfa(isp_prev
, &isp_prev
->params
.cfa
);
555 isppreview_enable_cfa(isp_prev
, isp_prev
->cfa_en
);
558 if (isp_prev
->nf_update
&& isp_prev
->nf_enable
) {
559 isp_reg_writel(isp_prev
->dev
, 0xC00,
560 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
561 isp_reg_writel(isp_prev
->dev
, isp_prev
->prev_nf_t
.spread
,
562 OMAP3_ISP_IOMEM_PREV
, ISPPRV_NF
);
563 for (ctr
= 0; ctr
< ISPPRV_NF_TBL_SIZE
; ctr
++) {
564 isp_reg_writel(isp_prev
->dev
,
565 isp_prev
->prev_nf_t
.table
[ctr
],
566 OMAP3_ISP_IOMEM_PREV
,
567 ISPPRV_SET_TBL_DATA
);
569 isppreview_enable_noisefilter(isp_prev
, 1);
570 isp_prev
->nf_update
= 0;
573 if (~isp_prev
->nf_update
&& isp_prev
->nf_enable
)
574 isppreview_enable_noisefilter(isp_prev
, 1);
576 if (isp_prev
->nf_update
&& ~isp_prev
->nf_enable
)
577 isppreview_enable_noisefilter(isp_prev
, 0);
579 spin_unlock_irqrestore(&isp_prev
->lock
, flags
);
581 EXPORT_SYMBOL_GPL(isppreview_config_shadow_registers
);
584 * isppreview_request - Reserves the preview module.
586 * Returns 0 if successful, or -EBUSY if the module was already reserved.
588 int isppreview_request(struct isp_prev_device
*isp_prev
)
590 isp_reg_or(isp_prev
->dev
,
591 OMAP3_ISP_IOMEM_MAIN
, ISP_CTRL
, ISPCTRL_PREV_RAM_EN
|
592 ISPCTRL_PREV_CLK_EN
| ISPCTRL_SBL_WR1_RAM_EN
);
595 EXPORT_SYMBOL_GPL(isppreview_request
);
598 * isppreview_free - Frees the preview module.
600 * Returns 0 if successful, or -EINVAL if the module was already freed.
602 int isppreview_free(struct isp_prev_device
*isp_prev
)
604 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_MAIN
, ISP_CTRL
,
605 ~(ISPCTRL_PREV_CLK_EN
|
606 ISPCTRL_PREV_RAM_EN
|
607 ISPCTRL_SBL_WR1_RAM_EN
));
611 EXPORT_SYMBOL_GPL(isppreview_free
);
613 /** isppreview_config_datapath - Specifies input and output modules for Preview
614 * @input: Indicates the module that gives the image to preview.
615 * @output: Indicates the module to which the preview outputs to.
617 * Configures the default configuration for the CCDC to work with.
619 * The valid values for the input are PRV_RAW_CCDC (0), PRV_RAW_MEM (1),
620 * PRV_RGBBAYERCFA (2), PRV_COMPCFA (3), PRV_CCDC_DRKF (4), PRV_OTHERS (5).
622 * The valid values for the output are PREVIEW_RSZ (0), PREVIEW_MEM (1).
624 * Returns 0 if successful, or -EINVAL if wrong input or output values are
627 int isppreview_config_datapath(struct isp_prev_device
*isp_prev
,
628 struct isp_pipeline
*pipe
)
632 struct prev_params
*params
= &isp_prev
->params
;
633 struct ispprev_yclimit yclimit
;
635 pcr
= isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
);
637 switch (pipe
->prv_in
) {
639 pcr
&= ~ISPPRV_PCR_SOURCE
;
642 pcr
|= ISPPRV_PCR_SOURCE
;
645 pcr
|= ISPPRV_PCR_DRKFCAP
;
651 case PRV_RGBBAYERCFA
:
654 dev_err(isp_prev
->dev
, "preview: Wrong Input\n");
658 switch (pipe
->prv_out
) {
660 pcr
|= ISPPRV_PCR_RSZPORT
;
661 pcr
&= ~ISPPRV_PCR_SDRPORT
;
664 pcr
&= ~ISPPRV_PCR_RSZPORT
;
665 pcr
|= ISPPRV_PCR_SDRPORT
;
668 dev_err(isp_prev
->dev
, "preview: Wrong Output\n");
672 isp_reg_writel(isp_prev
->dev
, pcr
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
);
674 if (params
->csup
.hypf_en
== 1)
675 isppreview_config_chroma_suppression(isp_prev
, params
->csup
);
676 if (params
->ytable
!= NULL
)
677 isppreview_config_luma_enhancement(isp_prev
, params
->ytable
);
679 if (params
->gtable
.redtable
!= NULL
)
680 isppreview_config_gammacorrn(isp_prev
, params
->gtable
);
682 isp_prev
->cfa_update
= 0;
683 isppreview_config_cfa(isp_prev
, ¶ms
->cfa
);
684 enable
= (params
->features
& PREV_CFA
) ? 1 : 0;
685 isppreview_enable_cfa(isp_prev
, enable
);
687 enable
= (params
->features
& PREV_CHROMA_SUPPRESS
) ? 1 : 0;
688 isppreview_enable_chroma_suppression(isp_prev
, enable
);
690 enable
= (params
->features
& PREV_LUMA_ENHANCE
) ? 1 : 0;
691 isppreview_enable_luma_enhancement(isp_prev
, enable
);
693 enable
= (params
->features
& PREV_NOISE_FILTER
) ? 1 : 0;
695 isppreview_config_noisefilter(isp_prev
, params
->nf
);
696 isppreview_enable_noisefilter(isp_prev
, enable
);
698 enable
= (params
->features
& PREV_DEFECT_COR
) ? 1 : 0;
700 isppreview_config_dcor(isp_prev
, params
->dcor
);
701 isppreview_enable_dcor(isp_prev
, enable
);
703 enable
= (params
->features
& PREV_GAMMA_BYPASS
) ? 1 : 0;
704 isppreview_enable_gammabypass(isp_prev
, enable
);
706 isppreview_config_whitebalance(isp_prev
, params
->wbal
);
707 isppreview_config_blkadj(isp_prev
, params
->blk_adj
);
708 isppreview_config_rgb_blending(isp_prev
, params
->rgb2rgb
);
709 isppreview_config_rgb_to_ycbcr(isp_prev
, params
->rgb2ycbcr
);
711 isppreview_config_contrast(isp_prev
, params
->contrast
);
712 isppreview_config_brightness(isp_prev
, params
->brightness
);
714 yclimit
.minC
= ISPPRV_YC_MIN
;
715 yclimit
.maxC
= ISPPRV_YC_MAX
;
716 yclimit
.minY
= ISPPRV_YC_MIN
;
717 yclimit
.maxY
= ISPPRV_YC_MAX
;
718 isppreview_config_yc_range(isp_prev
, yclimit
);
722 EXPORT_SYMBOL_GPL(isppreview_config_datapath
);
725 * isppreview_set_skip - Set the number of rows/columns that should be skipped.
726 * h - Start Pixel Horizontal.
727 * v - Start Line Vertical.
729 void isppreview_set_skip(struct isp_prev_device
*isp_prev
, u32 h
, u32 v
)
734 EXPORT_SYMBOL_GPL(isppreview_set_skip
);
737 * isppreview_config_ycpos - Configure byte layout of YUV image.
738 * @mode: Indicates the required byte layout.
740 void isppreview_config_ycpos(struct isp_prev_device
*isp_prev
,
741 enum preview_ycpos_mode mode
)
743 u32 pcr
= isp_reg_readl(isp_prev
->dev
,
744 OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
);
745 pcr
&= ~ISPPRV_PCR_YCPOS_CrYCbY
;
746 pcr
|= (mode
<< ISPPRV_PCR_YCPOS_SHIFT
);
747 isp_reg_writel(isp_prev
->dev
, pcr
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
);
749 EXPORT_SYMBOL_GPL(isppreview_config_ycpos
);
752 * isppreview_config_averager - Enable / disable / configure averager
753 * @average: Average value to be configured.
755 void isppreview_config_averager(struct isp_prev_device
*isp_prev
, u8 average
)
759 reg
= AVE_ODD_PIXEL_DIST
| AVE_EVEN_PIXEL_DIST
| average
;
760 isp_reg_writel(isp_prev
->dev
, reg
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_AVE
);
762 EXPORT_SYMBOL_GPL(isppreview_config_averager
);
765 * isppreview_enable_invalaw - Enable/Disable Inverse A-Law module in Preview.
766 * @enable: 1 - Reverse the A-Law done in CCDC.
768 void isppreview_enable_invalaw(struct isp_prev_device
*isp_prev
, u8 enable
)
771 pcr_val
= isp_reg_readl(isp_prev
->dev
,
772 OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
);
775 isp_reg_writel(isp_prev
->dev
,
776 pcr_val
| ISPPRV_PCR_WIDTH
| ISPPRV_PCR_INVALAW
,
777 OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
);
779 isp_reg_writel(isp_prev
->dev
, pcr_val
&
780 ~(ISPPRV_PCR_WIDTH
| ISPPRV_PCR_INVALAW
),
781 OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
);
784 EXPORT_SYMBOL_GPL(isppreview_enable_invalaw
);
787 * isppreview_enable_drkframe - Enable/Disable of the darkframe subtract.
788 * @enable: 1 - Acquires memory bandwidth since the pixels in each frame is
789 * subtracted with the pixels in the current frame.
791 * The proccess is applied for each captured frame.
793 void isppreview_enable_drkframe(struct isp_prev_device
*isp_prev
, u8 enable
)
796 isp_reg_or(isp_prev
->dev
,
797 OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
, ISPPRV_PCR_DRKFEN
);
799 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
803 EXPORT_SYMBOL_GPL(isppreview_enable_drkframe
);
806 * isppreview_enable_shadcomp - Enables/Disables the shading compensation.
807 * @enable: 1 - Enables the shading compensation.
809 * If dark frame subtract won't be used, then enable this shading
812 void isppreview_enable_shadcomp(struct isp_prev_device
*isp_prev
, u8 enable
)
816 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
817 ISPPRV_PCR_SCOMP_EN
);
818 isppreview_enable_drkframe(isp_prev
, 1);
820 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
821 ~ISPPRV_PCR_SCOMP_EN
);
824 EXPORT_SYMBOL_GPL(isppreview_enable_shadcomp
);
827 * isppreview_config_drkf_shadcomp - Configures shift value in shading comp.
828 * @scomp_shtval: 3bit value of shift used in shading compensation.
830 void isppreview_config_drkf_shadcomp(struct isp_prev_device
*isp_prev
,
833 u32 pcr_val
= isp_reg_readl(isp_prev
->dev
,
834 OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
);
836 pcr_val
&= ISPPRV_PCR_SCOMP_SFT_MASK
;
837 isp_reg_writel(isp_prev
->dev
,
838 pcr_val
| (scomp_shtval
<< ISPPRV_PCR_SCOMP_SFT_SHIFT
),
839 OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
);
841 EXPORT_SYMBOL_GPL(isppreview_config_drkf_shadcomp
);
844 * isppreview_enable_hmed - Enables/Disables of the Horizontal Median Filter.
845 * @enable: 1 - Enables Horizontal Median Filter.
847 void isppreview_enable_hmed(struct isp_prev_device
*isp_prev
, u8 enable
)
850 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
853 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
856 isp_prev
->hmed_en
= enable
? 1 : 0;
858 EXPORT_SYMBOL_GPL(isppreview_enable_hmed
);
861 * isppreview_config_hmed - Configures the Horizontal Median Filter.
862 * @prev_hmed: Structure containing the odd and even distance between the
863 * pixels in the image along with the filter threshold.
865 void isppreview_config_hmed(struct isp_prev_device
*isp_prev
,
866 struct ispprev_hmed prev_hmed
)
872 if (prev_hmed
.odddist
== 1)
873 odddist
= ~ISPPRV_HMED_ODDDIST
;
875 odddist
= ISPPRV_HMED_ODDDIST
;
877 if (prev_hmed
.evendist
== 1)
878 evendist
= ~ISPPRV_HMED_EVENDIST
;
880 evendist
= ISPPRV_HMED_EVENDIST
;
882 isp_reg_writel(isp_prev
->dev
, odddist
| evendist
| (prev_hmed
.thres
<<
883 ISPPRV_HMED_THRESHOLD_SHIFT
),
884 OMAP3_ISP_IOMEM_PREV
, ISPPRV_HMED
);
887 EXPORT_SYMBOL_GPL(isppreview_config_hmed
);
890 * isppreview_config_noisefilter - Configures the Noise Filter.
891 * @prev_nf: Structure containing the noisefilter table, strength to be used
892 * for the noise filter and the defect correction enable flag.
894 void isppreview_config_noisefilter(struct isp_prev_device
*isp_prev
,
895 struct ispprev_nf prev_nf
)
899 isp_reg_writel(isp_prev
->dev
, prev_nf
.spread
, OMAP3_ISP_IOMEM_PREV
,
901 isp_reg_writel(isp_prev
->dev
, ISPPRV_NF_TABLE_ADDR
,
902 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
903 for (i
= 0; i
< ISPPRV_NF_TBL_SIZE
; i
++) {
904 isp_reg_writel(isp_prev
->dev
, prev_nf
.table
[i
],
905 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_DATA
);
908 EXPORT_SYMBOL_GPL(isppreview_config_noisefilter
);
911 * isppreview_config_dcor - Configures the defect correction
912 * @prev_nf: Structure containing the defect correction structure
914 void isppreview_config_dcor(struct isp_prev_device
*isp_prev
,
915 struct ispprev_dcor prev_dcor
)
917 if (prev_dcor
.couplet_mode_en
) {
918 isp_reg_writel(isp_prev
->dev
, prev_dcor
.detect_correct
[0],
919 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR0
);
920 isp_reg_writel(isp_prev
->dev
, prev_dcor
.detect_correct
[1],
921 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR1
);
922 isp_reg_writel(isp_prev
->dev
, prev_dcor
.detect_correct
[2],
923 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR2
);
924 isp_reg_writel(isp_prev
->dev
, prev_dcor
.detect_correct
[3],
925 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR3
);
926 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
929 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
933 EXPORT_SYMBOL_GPL(isppreview_config_dcor
);
936 * isppreview_config_cfa - Configures the CFA Interpolation parameters.
937 * @prev_cfa: Structure containing the CFA interpolation table, CFA format
938 * in the image, vertical and horizontal gradient threshold.
940 void isppreview_config_cfa(struct isp_prev_device
*isp_prev
,
941 struct ispprev_cfa
*prev_cfa
)
945 isp_prev
->cfafmt
= prev_cfa
->cfafmt
;
947 isp_reg_and_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
948 ~ISPPRV_PCR_CFAFMT_MASK
,
949 (prev_cfa
->cfafmt
<< ISPPRV_PCR_CFAFMT_SHIFT
));
951 isp_reg_writel(isp_prev
->dev
,
952 (prev_cfa
->cfa_gradthrs_vert
<< ISPPRV_CFA_GRADTH_VER_SHIFT
) |
953 (prev_cfa
->cfa_gradthrs_horz
<< ISPPRV_CFA_GRADTH_HOR_SHIFT
),
954 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CFA
);
956 isp_reg_writel(isp_prev
->dev
, ISPPRV_CFA_TABLE_ADDR
,
957 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
959 for (i
= 0; i
< ISPPRV_CFA_TBL_SIZE
; i
++) {
960 isp_reg_writel(isp_prev
->dev
, prev_cfa
->cfa_table
[i
],
961 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_DATA
);
964 EXPORT_SYMBOL_GPL(isppreview_config_cfa
);
967 * isppreview_config_gammacorrn - Configures the Gamma Correction table values
968 * @gtable: Structure containing the table for red, blue, green gamma table.
970 void isppreview_config_gammacorrn(struct isp_prev_device
*isp_prev
,
971 struct ispprev_gtable gtable
)
975 isp_reg_writel(isp_prev
->dev
, ISPPRV_REDGAMMA_TABLE_ADDR
,
976 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
977 for (i
= 0; i
< ISPPRV_GAMMA_TBL_SIZE
; i
++) {
978 isp_reg_writel(isp_prev
->dev
, gtable
.redtable
[i
],
979 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_DATA
);
982 isp_reg_writel(isp_prev
->dev
, ISPPRV_GREENGAMMA_TABLE_ADDR
,
983 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
984 for (i
= 0; i
< ISPPRV_GAMMA_TBL_SIZE
; i
++) {
985 isp_reg_writel(isp_prev
->dev
, gtable
.greentable
[i
],
986 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_DATA
);
989 isp_reg_writel(isp_prev
->dev
, ISPPRV_BLUEGAMMA_TABLE_ADDR
,
990 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
991 for (i
= 0; i
< ISPPRV_GAMMA_TBL_SIZE
; i
++) {
992 isp_reg_writel(isp_prev
->dev
, gtable
.bluetable
[i
],
993 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_DATA
);
996 EXPORT_SYMBOL_GPL(isppreview_config_gammacorrn
);
999 * isppreview_set_luma_enhancement - Stores the Luminance Enhancement table.
1000 * @ytable: Structure containing the table for Luminance Enhancement table.
1002 void isppreview_set_luma_enhancement(struct isp_prev_device
*isp_prev
,
1007 for (i
= 0; i
< ISPPRV_YENH_TBL_SIZE
; i
++)
1008 isp_prev
->params
.ytable
[i
] = ytable
[i
];
1010 EXPORT_SYMBOL_GPL(isppreview_set_luma_enhancement
);
1013 * isppreview_config_luma_enhancement - Writes the Luminance Enhancement table.
1014 * @ytable: Structure containing the table for Luminance Enhancement table.
1016 void isppreview_config_luma_enhancement(struct isp_prev_device
*isp_prev
,
1021 isp_reg_writel(isp_prev
->dev
, ISPPRV_YENH_TABLE_ADDR
,
1022 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
1023 for (i
= 0; i
< ISPPRV_YENH_TBL_SIZE
; i
++) {
1024 isp_reg_writel(isp_prev
->dev
, ytable
[i
],
1025 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_DATA
);
1028 EXPORT_SYMBOL_GPL(isppreview_config_luma_enhancement
);
1031 * isppreview_config_chroma_suppression - Configures the Chroma Suppression.
1032 * @csup: Structure containing the threshold value for suppression
1033 * and the hypass filter enable flag.
1035 void isppreview_config_chroma_suppression(struct isp_prev_device
*isp_prev
,
1036 struct ispprev_csup csup
)
1038 isp_reg_writel(isp_prev
->dev
,
1039 csup
.gain
| (csup
.thres
<< ISPPRV_CSUP_THRES_SHIFT
) |
1040 (csup
.hypf_en
<< ISPPRV_CSUP_HPYF_SHIFT
),
1041 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSUP
);
1043 EXPORT_SYMBOL_GPL(isppreview_config_chroma_suppression
);
1046 * isppreview_enable_noisefilter - Enables/Disables the Noise Filter.
1047 * @enable: 1 - Enables the Noise Filter.
1049 void isppreview_enable_noisefilter(struct isp_prev_device
*isp_prev
, u8 enable
)
1052 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1055 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1057 isp_prev
->nf_en
= enable
? 1 : 0;
1059 EXPORT_SYMBOL_GPL(isppreview_enable_noisefilter
);
1062 * isppreview_enable_dcor - Enables/Disables the defect correction.
1063 * @enable: 1 - Enables the defect correction.
1065 void isppreview_enable_dcor(struct isp_prev_device
*isp_prev
, u8 enable
)
1068 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1071 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1072 ~ISPPRV_PCR_DCOREN
);
1074 isp_prev
->dcor_en
= enable
? 1 : 0;
1076 EXPORT_SYMBOL_GPL(isppreview_enable_dcor
);
1079 * isppreview_enable_cfa - Enable/Disable the CFA Interpolation.
1080 * @enable: 1 - Enables the CFA.
1082 void isppreview_enable_cfa(struct isp_prev_device
*isp_prev
, u8 enable
)
1085 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1088 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1091 isp_prev
->cfa_en
= enable
? 1 : 0;
1093 EXPORT_SYMBOL_GPL(isppreview_enable_cfa
);
1096 * isppreview_enable_gammabypass - Enables/Disables the GammaByPass
1097 * @enable: 1 - Bypasses Gamma - 10bit input is cropped to 8MSB.
1098 * 0 - Goes through Gamma Correction. input and output is 10bit.
1100 void isppreview_enable_gammabypass(struct isp_prev_device
*isp_prev
, u8 enable
)
1103 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1104 ISPPRV_PCR_GAMMA_BYPASS
);
1106 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1107 ~ISPPRV_PCR_GAMMA_BYPASS
);
1110 EXPORT_SYMBOL_GPL(isppreview_enable_gammabypass
);
1113 * isppreview_enable_luma_enhancement - Enables/Disables Luminance Enhancement
1114 * @enable: 1 - Enable the Luminance Enhancement.
1116 void isppreview_enable_luma_enhancement(struct isp_prev_device
*isp_prev
,
1120 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1121 ISPPRV_PCR_YNENHEN
);
1123 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1124 ~ISPPRV_PCR_YNENHEN
);
1126 isp_prev
->yenh_en
= enable
? 1 : 0;
1128 EXPORT_SYMBOL_GPL(isppreview_enable_luma_enhancement
);
1131 * isppreview_enable_chroma_suppression - Enables/Disables Chrominance Suppr.
1132 * @enable: 1 - Enable the Chrominance Suppression.
1134 void isppreview_enable_chroma_suppression(struct isp_prev_device
*isp_prev
,
1138 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1141 isp_reg_and(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1144 isp_prev
->csup_en
= enable
? 1 : 0;
1146 EXPORT_SYMBOL_GPL(isppreview_enable_chroma_suppression
);
1149 * isppreview_config_whitebalance - Configures the White Balance parameters.
1150 * @prev_wbal: Structure containing the digital gain and white balance
1153 * Coefficient matrix always with default values.
1155 void isppreview_config_whitebalance(struct isp_prev_device
*isp_prev
,
1156 struct ispprev_wbal prev_wbal
)
1160 isp_reg_writel(isp_prev
->dev
, prev_wbal
.dgain
, OMAP3_ISP_IOMEM_PREV
,
1163 val
= prev_wbal
.coef0
<< ISPPRV_WBGAIN_COEF0_SHIFT
;
1164 val
|= prev_wbal
.coef1
<< ISPPRV_WBGAIN_COEF1_SHIFT
;
1165 val
|= prev_wbal
.coef2
<< ISPPRV_WBGAIN_COEF2_SHIFT
;
1166 val
|= prev_wbal
.coef3
<< ISPPRV_WBGAIN_COEF3_SHIFT
;
1167 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
,
1170 isp_reg_writel(isp_prev
->dev
,
1171 ISPPRV_WBSEL_COEF0
<< ISPPRV_WBSEL_N0_0_SHIFT
|
1172 ISPPRV_WBSEL_COEF1
<< ISPPRV_WBSEL_N0_1_SHIFT
|
1173 ISPPRV_WBSEL_COEF0
<< ISPPRV_WBSEL_N0_2_SHIFT
|
1174 ISPPRV_WBSEL_COEF1
<< ISPPRV_WBSEL_N0_3_SHIFT
|
1175 ISPPRV_WBSEL_COEF2
<< ISPPRV_WBSEL_N1_0_SHIFT
|
1176 ISPPRV_WBSEL_COEF3
<< ISPPRV_WBSEL_N1_1_SHIFT
|
1177 ISPPRV_WBSEL_COEF2
<< ISPPRV_WBSEL_N1_2_SHIFT
|
1178 ISPPRV_WBSEL_COEF3
<< ISPPRV_WBSEL_N1_3_SHIFT
|
1179 ISPPRV_WBSEL_COEF0
<< ISPPRV_WBSEL_N2_0_SHIFT
|
1180 ISPPRV_WBSEL_COEF1
<< ISPPRV_WBSEL_N2_1_SHIFT
|
1181 ISPPRV_WBSEL_COEF0
<< ISPPRV_WBSEL_N2_2_SHIFT
|
1182 ISPPRV_WBSEL_COEF1
<< ISPPRV_WBSEL_N2_3_SHIFT
|
1183 ISPPRV_WBSEL_COEF2
<< ISPPRV_WBSEL_N3_0_SHIFT
|
1184 ISPPRV_WBSEL_COEF3
<< ISPPRV_WBSEL_N3_1_SHIFT
|
1185 ISPPRV_WBSEL_COEF2
<< ISPPRV_WBSEL_N3_2_SHIFT
|
1186 ISPPRV_WBSEL_COEF3
<< ISPPRV_WBSEL_N3_3_SHIFT
,
1187 OMAP3_ISP_IOMEM_PREV
, ISPPRV_WBSEL
);
1189 EXPORT_SYMBOL_GPL(isppreview_config_whitebalance
);
1192 * isppreview_config_whitebalance2 - Configures the White Balance parameters.
1193 * @prev_wbal: Structure containing the digital gain and white balance
1196 * Coefficient matrix can be changed.
1198 void isppreview_config_whitebalance2(struct isp_prev_device
*isp_prev
,
1199 struct prev_white_balance prev_wbal
)
1201 isp_reg_writel(isp_prev
->dev
, prev_wbal
.wb_dgain
,
1202 OMAP3_ISP_IOMEM_PREV
, ISPPRV_WB_DGAIN
);
1203 isp_reg_writel(isp_prev
->dev
, prev_wbal
.wb_gain
[0] |
1204 prev_wbal
.wb_gain
[1] << ISPPRV_WBGAIN_COEF1_SHIFT
|
1205 prev_wbal
.wb_gain
[2] << ISPPRV_WBGAIN_COEF2_SHIFT
|
1206 prev_wbal
.wb_gain
[3] << ISPPRV_WBGAIN_COEF3_SHIFT
,
1207 OMAP3_ISP_IOMEM_PREV
, ISPPRV_WBGAIN
);
1209 isp_reg_writel(isp_prev
->dev
,
1210 prev_wbal
.wb_coefmatrix
[0][0] << ISPPRV_WBSEL_N0_0_SHIFT
|
1211 prev_wbal
.wb_coefmatrix
[0][1] << ISPPRV_WBSEL_N0_1_SHIFT
|
1212 prev_wbal
.wb_coefmatrix
[0][2] << ISPPRV_WBSEL_N0_2_SHIFT
|
1213 prev_wbal
.wb_coefmatrix
[0][3] << ISPPRV_WBSEL_N0_3_SHIFT
|
1214 prev_wbal
.wb_coefmatrix
[1][0] << ISPPRV_WBSEL_N1_0_SHIFT
|
1215 prev_wbal
.wb_coefmatrix
[1][1] << ISPPRV_WBSEL_N1_1_SHIFT
|
1216 prev_wbal
.wb_coefmatrix
[1][2] << ISPPRV_WBSEL_N1_2_SHIFT
|
1217 prev_wbal
.wb_coefmatrix
[1][3] << ISPPRV_WBSEL_N1_3_SHIFT
|
1218 prev_wbal
.wb_coefmatrix
[2][0] << ISPPRV_WBSEL_N2_0_SHIFT
|
1219 prev_wbal
.wb_coefmatrix
[2][1] << ISPPRV_WBSEL_N2_1_SHIFT
|
1220 prev_wbal
.wb_coefmatrix
[2][2] << ISPPRV_WBSEL_N2_2_SHIFT
|
1221 prev_wbal
.wb_coefmatrix
[2][3] << ISPPRV_WBSEL_N2_3_SHIFT
|
1222 prev_wbal
.wb_coefmatrix
[3][0] << ISPPRV_WBSEL_N3_0_SHIFT
|
1223 prev_wbal
.wb_coefmatrix
[3][1] << ISPPRV_WBSEL_N3_1_SHIFT
|
1224 prev_wbal
.wb_coefmatrix
[3][2] << ISPPRV_WBSEL_N3_2_SHIFT
|
1225 prev_wbal
.wb_coefmatrix
[3][3] << ISPPRV_WBSEL_N3_3_SHIFT
,
1226 OMAP3_ISP_IOMEM_PREV
, ISPPRV_WBSEL
);
1228 EXPORT_SYMBOL_GPL(isppreview_config_whitebalance2
);
1231 * isppreview_config_blkadj - Configures the Black Adjustment parameters.
1232 * @prev_blkadj: Structure containing the black adjustment towards red, green,
1235 void isppreview_config_blkadj(struct isp_prev_device
*isp_prev
,
1236 struct ispprev_blkadj prev_blkadj
)
1238 isp_reg_writel(isp_prev
->dev
, prev_blkadj
.blue
|
1239 (prev_blkadj
.green
<< ISPPRV_BLKADJOFF_G_SHIFT
) |
1240 (prev_blkadj
.red
<< ISPPRV_BLKADJOFF_R_SHIFT
),
1241 OMAP3_ISP_IOMEM_PREV
, ISPPRV_BLKADJOFF
);
1243 EXPORT_SYMBOL_GPL(isppreview_config_blkadj
);
1246 * isppreview_config_rgb_blending - Configures the RGB-RGB Blending matrix.
1247 * @rgb2rgb: Structure containing the rgb to rgb blending matrix and the rgb
1250 void isppreview_config_rgb_blending(struct isp_prev_device
*isp_prev
,
1251 struct ispprev_rgbtorgb rgb2rgb
)
1255 val
= (rgb2rgb
.matrix
[0][0] & 0xfff) << ISPPRV_RGB_MAT1_MTX_RR_SHIFT
;
1256 val
|= (rgb2rgb
.matrix
[0][1] & 0xfff) << ISPPRV_RGB_MAT1_MTX_GR_SHIFT
;
1257 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
,
1260 val
= (rgb2rgb
.matrix
[0][2] & 0xfff) << ISPPRV_RGB_MAT2_MTX_BR_SHIFT
;
1261 val
|= (rgb2rgb
.matrix
[1][0] & 0xfff) << ISPPRV_RGB_MAT2_MTX_RG_SHIFT
;
1262 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
,
1265 val
= (rgb2rgb
.matrix
[1][1] & 0xfff) << ISPPRV_RGB_MAT3_MTX_GG_SHIFT
;
1266 val
|= (rgb2rgb
.matrix
[1][2] & 0xfff) << ISPPRV_RGB_MAT3_MTX_BG_SHIFT
;
1267 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
,
1270 val
= (rgb2rgb
.matrix
[2][0] & 0xfff) << ISPPRV_RGB_MAT4_MTX_RB_SHIFT
;
1271 val
|= (rgb2rgb
.matrix
[2][1] & 0xfff) << ISPPRV_RGB_MAT4_MTX_GB_SHIFT
;
1272 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
,
1275 val
= (rgb2rgb
.matrix
[2][2] & 0xfff) << ISPPRV_RGB_MAT5_MTX_BB_SHIFT
;
1276 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
,
1279 val
= (rgb2rgb
.offset
[0] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT
;
1280 val
|= (rgb2rgb
.offset
[1] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT
;
1281 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
,
1284 val
= (rgb2rgb
.offset
[2] & 0x3ff) << ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT
;
1285 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
,
1288 EXPORT_SYMBOL_GPL(isppreview_config_rgb_blending
);
1291 * Configures the RGB-YCbYCr conversion matrix
1292 * @prev_csc: Structure containing the RGB to YCbYCr matrix and the
1295 void isppreview_config_rgb_to_ycbcr(struct isp_prev_device
*isp_prev
,
1296 struct ispprev_csc prev_csc
)
1300 val
= (prev_csc
.matrix
[0][0] & 0x3ff) << ISPPRV_CSC0_RY_SHIFT
;
1301 val
|= (prev_csc
.matrix
[0][1] & 0x3ff) << ISPPRV_CSC0_GY_SHIFT
;
1302 val
|= (prev_csc
.matrix
[0][2] & 0x3ff) << ISPPRV_CSC0_BY_SHIFT
;
1303 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC0
);
1305 val
= (prev_csc
.matrix
[1][0] & 0x3ff) << ISPPRV_CSC1_RCB_SHIFT
;
1306 val
|= (prev_csc
.matrix
[1][1] & 0x3ff) << ISPPRV_CSC1_GCB_SHIFT
;
1307 val
|= (prev_csc
.matrix
[1][2] & 0x3ff) << ISPPRV_CSC1_BCB_SHIFT
;
1308 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC1
);
1310 val
= (prev_csc
.matrix
[2][0] & 0x3ff) << ISPPRV_CSC2_RCR_SHIFT
;
1311 val
|= (prev_csc
.matrix
[2][1] & 0x3ff) << ISPPRV_CSC2_GCR_SHIFT
;
1312 val
|= (prev_csc
.matrix
[2][2] & 0x3ff) << ISPPRV_CSC2_BCR_SHIFT
;
1313 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC2
);
1315 val
= (prev_csc
.offset
[0] & 0xff) << ISPPRV_CSC_OFFSET_Y_SHIFT
;
1316 val
|= (prev_csc
.offset
[1] & 0xff) << ISPPRV_CSC_OFFSET_CB_SHIFT
;
1317 val
|= (prev_csc
.offset
[2] & 0xff) << ISPPRV_CSC_OFFSET_CR_SHIFT
;
1318 isp_reg_writel(isp_prev
->dev
, val
, OMAP3_ISP_IOMEM_PREV
,
1321 EXPORT_SYMBOL_GPL(isppreview_config_rgb_to_ycbcr
);
1324 * isppreview_query_contrast - Query the contrast.
1325 * @contrast: Pointer to hold the current programmed contrast value.
1327 void isppreview_query_contrast(struct isp_prev_device
*isp_prev
, u8
*contrast
)
1329 u32 brt_cnt_val
= 0;
1331 brt_cnt_val
= isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1333 *contrast
= (brt_cnt_val
>> ISPPRV_CNT_BRT_CNT_SHIFT
) & 0xff;
1334 DPRINTK_ISPPREV(" Current brt cnt value in hw is %x\n", brt_cnt_val
);
1336 EXPORT_SYMBOL_GPL(isppreview_query_contrast
);
1339 * isppreview_update_contrast - Updates the contrast.
1340 * @contrast: Pointer to hold the current programmed contrast value.
1342 * Value should be programmed before enabling the module.
1344 void isppreview_update_contrast(struct isp_prev_device
*isp_prev
, u8
*contrast
)
1346 isp_prev
->contrast
= *contrast
;
1348 EXPORT_SYMBOL_GPL(isppreview_update_contrast
);
1351 * isppreview_config_contrast - Configures the Contrast.
1352 * @contrast: 8 bit value in U8Q4 format.
1354 * Value should be programmed before enabling the module.
1356 void isppreview_config_contrast(struct isp_prev_device
*isp_prev
, u8 contrast
)
1358 u32 brt_cnt_val
= 0;
1360 brt_cnt_val
= isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1362 brt_cnt_val
&= ~(0xff << ISPPRV_CNT_BRT_CNT_SHIFT
);
1364 isp_reg_writel(isp_prev
->dev
,
1365 brt_cnt_val
| contrast
<< ISPPRV_CNT_BRT_CNT_SHIFT
,
1366 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CNT_BRT
);
1368 EXPORT_SYMBOL_GPL(isppreview_config_contrast
);
1371 * isppreview_get_contrast_range - Gets the range contrast value.
1372 * @min_contrast: Pointer to hold the minimum Contrast value.
1373 * @max_contrast: Pointer to hold the maximum Contrast value.
1375 void isppreview_get_contrast_range(u8
*min_contrast
, u8
*max_contrast
)
1377 *min_contrast
= ISPPRV_CONTRAST_MIN
;
1378 *max_contrast
= ISPPRV_CONTRAST_MAX
;
1380 EXPORT_SYMBOL_GPL(isppreview_get_contrast_range
);
1383 * isppreview_update_brightness - Updates the brightness in preview module.
1384 * @brightness: Pointer to hold the current programmed brightness value.
1387 void isppreview_update_brightness(struct isp_prev_device
*isp_prev
,
1390 isp_prev
->brightness
= *brightness
;
1392 EXPORT_SYMBOL_GPL(isppreview_update_brightness
);
1395 * isppreview_config_brightness - Configures the brightness.
1396 * @contrast: 8bitvalue in U8Q0 format.
1398 void isppreview_config_brightness(struct isp_prev_device
*isp_prev
,
1401 u32 brt_cnt_val
= 0;
1403 DPRINTK_ISPPREV("\tConfiguring brightness in ISP: %d\n", brightness
);
1404 brt_cnt_val
= isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1406 brt_cnt_val
&= ~(0xff << ISPPRV_CNT_BRT_BRT_SHIFT
);
1408 isp_reg_writel(isp_prev
->dev
,
1409 brt_cnt_val
| brightness
<< ISPPRV_CNT_BRT_BRT_SHIFT
,
1410 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CNT_BRT
);
1412 EXPORT_SYMBOL_GPL(isppreview_config_brightness
);
1415 * isppreview_query_brightness - Query the brightness.
1416 * @brightness: Pointer to hold the current programmed brightness value.
1418 void isppreview_query_brightness(struct isp_prev_device
*isp_prev
,
1421 *brightness
= isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1424 EXPORT_SYMBOL_GPL(isppreview_query_brightness
);
1427 * isppreview_get_brightness_range - Gets the range brightness value
1428 * @min_brightness: Pointer to hold the minimum brightness value
1429 * @max_brightness: Pointer to hold the maximum brightness value
1431 void isppreview_get_brightness_range(u8
*min_brightness
, u8
*max_brightness
)
1433 *min_brightness
= ISPPRV_BRIGHT_MIN
;
1434 *max_brightness
= ISPPRV_BRIGHT_MAX
;
1436 EXPORT_SYMBOL_GPL(isppreview_get_brightness_range
);
1439 * isppreview_set_color - Sets the color effect.
1440 * @mode: Indicates the required color effect.
1442 void isppreview_set_color(struct isp_prev_device
*isp_prev
, u8
*mode
)
1444 isp_prev
->color
= *mode
;
1445 isp_prev
->update_color_matrix
= 1;
1447 EXPORT_SYMBOL_GPL(isppreview_set_color
);
1450 * isppreview_get_color - Gets the current color effect.
1451 * @mode: Indicates the current color effect.
1453 void isppreview_get_color(struct isp_prev_device
*isp_prev
, u8
*mode
)
1455 *mode
= isp_prev
->color
;
1457 EXPORT_SYMBOL_GPL(isppreview_get_color
);
1460 * isppreview_config_yc_range - Configures the max and min Y and C values.
1461 * @yclimit: Structure containing the range of Y and C values.
1463 void isppreview_config_yc_range(struct isp_prev_device
*isp_prev
,
1464 struct ispprev_yclimit yclimit
)
1466 isp_reg_writel(isp_prev
->dev
,
1467 yclimit
.maxC
<< ISPPRV_SETUP_YC_MAXC_SHIFT
|
1468 yclimit
.maxY
<< ISPPRV_SETUP_YC_MAXY_SHIFT
|
1469 yclimit
.minC
<< ISPPRV_SETUP_YC_MINC_SHIFT
|
1470 yclimit
.minY
<< ISPPRV_SETUP_YC_MINY_SHIFT
,
1471 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SETUP_YC
);
1473 EXPORT_SYMBOL_GPL(isppreview_config_yc_range
);
1476 * isppreview_try_size - Calculates output dimensions with the modules enabled.
1477 * @input_w: input width for the preview in number of pixels per line
1478 * @input_h: input height for the preview in number of lines
1479 * @output_w: output width from the preview in number of pixels per line
1480 * @output_h: output height for the preview in number of lines
1482 * Calculates the number of pixels cropped in the submodules that are enabled,
1483 * Fills up the output width height variables in the isp_prev structure.
1485 int isppreview_try_pipeline(struct isp_prev_device
*isp_prev
,
1486 struct isp_pipeline
*pipe
)
1491 if (pipe
->ccdc_out_w_img
< 32 || pipe
->ccdc_out_h
< 32) {
1492 dev_err(isp_prev
->dev
, "preview does not support "
1493 "width < 16 or height < 32 \n");
1496 if (omap_rev() == OMAP3430_REV_ES1_0
)
1497 max_out
= ISPPRV_MAXOUTPUT_WIDTH
;
1499 max_out
= ISPPRV_MAXOUTPUT_WIDTH_ES2
;
1501 pipe
->prv_out_w
= pipe
->ccdc_out_w
;
1502 pipe
->prv_out_h
= pipe
->ccdc_out_h
;
1503 pipe
->prv_out_w_img
= pipe
->ccdc_out_w_img
;
1504 pipe
->prv_out_h_img
= pipe
->ccdc_out_h
;
1506 isp_prev
->fmtavg
= 0;
1508 if (pipe
->ccdc_out_w_img
> max_out
) {
1509 div
= (pipe
->ccdc_out_w_img
/max_out
);
1510 if (div
>= 2 && div
< 4) {
1511 isp_prev
->fmtavg
= 1;
1512 pipe
->prv_out_w_img
/= 2;
1513 } else if (div
>= 4 && div
< 8) {
1514 isp_prev
->fmtavg
= 2;
1515 pipe
->prv_out_w_img
/= 4;
1516 } else if (div
>= 8) {
1517 isp_prev
->fmtavg
= 3;
1518 pipe
->prv_out_w_img
/= 8;
1522 /* if (isp_prev->hmed_en) */
1523 pipe
->prv_out_w_img
-= 4;
1524 /* if (isp_prev->nf_en) */
1525 pipe
->prv_out_w_img
-= 4;
1526 pipe
->prv_out_h_img
-= 4;
1527 /* if (isp_prev->cfa_en) */
1528 switch (isp_prev
->cfafmt
) {
1530 case CFAFMT_SONYVGA
:
1531 pipe
->prv_out_w_img
-= 4;
1532 pipe
->prv_out_h_img
-= 4;
1534 case CFAFMT_RGBFOVEON
:
1535 case CFAFMT_RRGGBBFOVEON
:
1537 case CFAFMT_HONEYCOMB
:
1538 pipe
->prv_out_h_img
-= 2;
1541 /* if (isp_prev->yenh_en || isp_prev->csup_en) */
1542 pipe
->prv_out_w_img
-= 2;
1544 /* Start at the correct row/column by skipping
1545 * a Sensor specific amount.
1547 pipe
->prv_out_w_img
-= isp_prev
->sph
;
1548 pipe
->prv_out_h_img
-= isp_prev
->slv
;
1550 if (pipe
->prv_out_w_img
% 2)
1551 pipe
->prv_out_w_img
-= 1;
1553 /* FIXME: This doesn't apply for prv -> rsz. */
1554 pipe
->prv_out_w
= ALIGN(pipe
->prv_out_w_img
, 0x20);
1558 EXPORT_SYMBOL_GPL(isppreview_try_pipeline
);
1561 * isppreview_config_size - Sets the size of ISP preview output.
1562 * @pipe->ccdc_out_w: input width for the preview in number of pixels per line
1563 * @pipe->ccdc_out_h: input height for the preview in number of lines
1564 * @output_w: output width from the preview in number of pixels per line
1565 * @output_h: output height for the preview in number of lines
1567 * Configures the appropriate values stored in the isp_prev structure to
1568 * HORZ/VERT_INFO. Configures PRV_AVE if needed for downsampling as calculated
1571 int isppreview_s_pipeline(struct isp_prev_device
*isp_prev
,
1572 struct isp_pipeline
*pipe
)
1577 rval
= isppreview_config_datapath(isp_prev
, pipe
);
1581 isp_reg_writel(isp_prev
->dev
,
1582 (isp_prev
->sph
<< ISPPRV_HORZ_INFO_SPH_SHIFT
) |
1583 (pipe
->ccdc_out_w
- 1),
1584 OMAP3_ISP_IOMEM_PREV
, ISPPRV_HORZ_INFO
);
1585 isp_reg_writel(isp_prev
->dev
,
1586 (isp_prev
->slv
<< ISPPRV_VERT_INFO_SLV_SHIFT
) |
1587 (pipe
->ccdc_out_h
- 2),
1588 OMAP3_ISP_IOMEM_PREV
, ISPPRV_VERT_INFO
);
1590 if (isp_prev
->cfafmt
== CFAFMT_BAYER
)
1591 isp_reg_writel(isp_prev
->dev
, ISPPRV_AVE_EVENDIST_2
<<
1592 ISPPRV_AVE_EVENDIST_SHIFT
|
1593 ISPPRV_AVE_ODDDIST_2
<<
1594 ISPPRV_AVE_ODDDIST_SHIFT
|
1596 OMAP3_ISP_IOMEM_PREV
, ISPPRV_AVE
);
1598 if (pipe
->prv_out
== PREVIEW_MEM
) {
1599 prevsdroff
= pipe
->prv_out_w
* ISP_BYTES_PER_PIXEL
;
1600 if ((prevsdroff
& ISP_32B_BOUNDARY_OFFSET
) != prevsdroff
) {
1601 DPRINTK_ISPPREV("ISP_WARN: Preview output buffer line"
1602 " size is truncated"
1603 " to 32byte boundary\n");
1604 prevsdroff
&= ISP_32B_BOUNDARY_BUF
;
1606 isppreview_config_outlineoffset(isp_prev
, prevsdroff
);
1609 if (pipe
->pix
.pixelformat
== V4L2_PIX_FMT_UYVY
)
1610 isppreview_config_ycpos(isp_prev
, YCPOS_YCrYCb
);
1612 isppreview_config_ycpos(isp_prev
, YCPOS_CrYCbY
);
1616 EXPORT_SYMBOL_GPL(isppreview_s_pipeline
);
1619 * isppreview_config_inlineoffset - Configures the Read address line offset.
1620 * @offset: Line Offset for the input image.
1622 int isppreview_config_inlineoffset(struct isp_prev_device
*isp_prev
, u32 offset
)
1624 if ((offset
& ISP_32B_BOUNDARY_OFFSET
) == offset
) {
1625 isp_reg_writel(isp_prev
->dev
, offset
& 0xffff,
1626 OMAP3_ISP_IOMEM_PREV
, ISPPRV_RADR_OFFSET
);
1628 dev_err(isp_prev
->dev
, "preview: Offset should be in 32 byte "
1634 EXPORT_SYMBOL_GPL(isppreview_config_inlineoffset
);
1637 * isppreview_set_inaddr - Sets memory address of input frame.
1638 * @addr: 32bit memory address aligned on 32byte boundary.
1640 * Configures the memory address from which the input frame is to be read.
1642 int isppreview_set_inaddr(struct isp_prev_device
*isp_prev
, u32 addr
)
1644 if ((addr
& ISP_32B_BOUNDARY_BUF
) == addr
)
1645 isp_reg_writel(isp_prev
->dev
, addr
,
1646 OMAP3_ISP_IOMEM_PREV
, ISPPRV_RSDR_ADDR
);
1648 dev_err(isp_prev
->dev
, "preview: Address should be in 32 byte "
1654 EXPORT_SYMBOL_GPL(isppreview_set_inaddr
);
1657 * isppreview_config_outlineoffset - Configures the Write address line offset.
1658 * @offset: Line Offset for the preview output.
1660 int isppreview_config_outlineoffset(struct isp_prev_device
*isp_prev
,
1663 if ((offset
& ISP_32B_BOUNDARY_OFFSET
) != offset
) {
1664 dev_err(isp_prev
->dev
, "preview: Offset should be in 32 byte "
1668 isp_reg_writel(isp_prev
->dev
, offset
& 0xffff, OMAP3_ISP_IOMEM_PREV
,
1669 ISPPRV_WADD_OFFSET
);
1672 EXPORT_SYMBOL_GPL(isppreview_config_outlineoffset
);
1675 * isppreview_set_outaddr - Sets the memory address to store output frame
1676 * @addr: 32bit memory address aligned on 32byte boundary.
1678 * Configures the memory address to which the output frame is written.
1680 int isppreview_set_outaddr(struct isp_prev_device
*isp_prev
, u32 addr
)
1682 if ((addr
& ISP_32B_BOUNDARY_BUF
) != addr
) {
1683 dev_err(isp_prev
->dev
, "preview: Address should be in 32 byte "
1687 isp_reg_writel(isp_prev
->dev
, addr
, OMAP3_ISP_IOMEM_PREV
,
1691 EXPORT_SYMBOL_GPL(isppreview_set_outaddr
);
1694 * isppreview_config_darklineoffset - Sets the Dark frame address line offset.
1695 * @offset: Line Offset for the Darkframe.
1697 int isppreview_config_darklineoffset(struct isp_prev_device
*isp_prev
,
1700 if ((offset
& ISP_32B_BOUNDARY_OFFSET
) != offset
) {
1701 dev_err(isp_prev
->dev
, "preview: Offset should be in 32 byte "
1705 isp_reg_writel(isp_prev
->dev
, offset
& 0xffff, OMAP3_ISP_IOMEM_PREV
,
1706 ISPPRV_DRKF_OFFSET
);
1709 EXPORT_SYMBOL_GPL(isppreview_config_darklineoffset
);
1712 * isppreview_set_darkaddr - Sets the memory address to store Dark frame.
1713 * @addr: 32bit memory address aligned on 32 bit boundary.
1715 int isppreview_set_darkaddr(struct isp_prev_device
*isp_prev
, u32 addr
)
1717 if ((addr
& ISP_32B_BOUNDARY_BUF
) != addr
) {
1718 dev_err(isp_prev
->dev
, "preview: Address should be in 32 byte "
1722 isp_reg_writel(isp_prev
->dev
, addr
, OMAP3_ISP_IOMEM_PREV
,
1726 EXPORT_SYMBOL_GPL(isppreview_set_darkaddr
);
1729 * isppreview_enable - Enables the Preview module.
1730 * @enable: 1 - Enables the preview module.
1732 * Client should configure all the sub modules in Preview before this.
1734 void isppreview_enable(struct isp_prev_device
*isp_prev
)
1736 isp_reg_or(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1737 ISPPRV_PCR_EN
| ISPPRV_PCR_ONESHOT
);
1739 EXPORT_SYMBOL_GPL(isppreview_enable
);
1742 * isppreview_busy - Gets busy state of preview module.
1744 int isppreview_busy(struct isp_prev_device
*isp_prev
)
1746 return isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
)
1749 EXPORT_SYMBOL_GPL(isppreview_busy
);
1752 * isppreview_save_context - Saves the values of the preview module registers.
1754 void isppreview_save_context(struct device
*dev
)
1756 DPRINTK_ISPPREV("Saving context\n");
1757 isp_save_context(dev
, ispprev_reg_list
);
1759 EXPORT_SYMBOL_GPL(isppreview_save_context
);
1762 * isppreview_restore_context - Restores the values of preview module registers
1764 void isppreview_restore_context(struct device
*dev
)
1766 DPRINTK_ISPPREV("Restoring context\n");
1767 isp_restore_context(dev
, ispprev_reg_list
);
1769 EXPORT_SYMBOL_GPL(isppreview_restore_context
);
1772 * isppreview_print_status - Prints the values of the Preview Module registers.
1774 * Also prints other debug information stored in the preview moduel.
1776 void isppreview_print_status(struct isp_prev_device
*isp_prev
,
1777 struct isp_pipeline
*pipe
)
1779 DPRINTK_ISPPREV("Preview Input format =%d, Output Format =%d\n",
1780 pipe
->prv_inp
, pipe
->prv_out
);
1781 DPRINTK_ISPPREV("Accepted Preview Input (width = %d,Height = %d)\n",
1783 isp_prev
->previn_h
);
1784 DPRINTK_ISPPREV("Accepted Preview Output (width = %d,Height = %d)\n",
1785 isp_prev
->prevout_w
,
1786 isp_prev
->prevout_h
);
1787 DPRINTK_ISPPREV("###ISP_CTRL in preview =0x%x\n",
1788 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_MAIN
,
1790 DPRINTK_ISPPREV("###ISP_IRQ0ENABLE in preview =0x%x\n",
1791 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_MAIN
,
1793 DPRINTK_ISPPREV("###ISP_IRQ0STATUS in preview =0x%x\n",
1794 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_MAIN
,
1796 DPRINTK_ISPPREV("###PRV PCR =0x%x\n",
1797 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1799 DPRINTK_ISPPREV("###PRV HORZ_INFO =0x%x\n",
1800 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1802 DPRINTK_ISPPREV("###PRV VERT_INFO =0x%x\n",
1803 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1805 DPRINTK_ISPPREV("###PRV WSDR_ADDR =0x%x\n",
1806 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1808 DPRINTK_ISPPREV("###PRV WADD_OFFSET =0x%x\n",
1809 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1810 ISPPRV_WADD_OFFSET
));
1811 DPRINTK_ISPPREV("###PRV AVE =0x%x\n",
1812 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1814 DPRINTK_ISPPREV("###PRV HMED =0x%x\n",
1815 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1817 DPRINTK_ISPPREV("###PRV NF =0x%x\n",
1818 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1820 DPRINTK_ISPPREV("###PRV WB_DGAIN =0x%x\n",
1821 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1823 DPRINTK_ISPPREV("###PRV WBGAIN =0x%x\n",
1824 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1826 DPRINTK_ISPPREV("###PRV WBSEL =0x%x\n",
1827 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1829 DPRINTK_ISPPREV("###PRV CFA =0x%x\n",
1830 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1832 DPRINTK_ISPPREV("###PRV BLKADJOFF =0x%x\n",
1833 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1835 DPRINTK_ISPPREV("###PRV RGB_MAT1 =0x%x\n",
1836 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1838 DPRINTK_ISPPREV("###PRV RGB_MAT2 =0x%x\n",
1839 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1841 DPRINTK_ISPPREV("###PRV RGB_MAT3 =0x%x\n",
1842 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1844 DPRINTK_ISPPREV("###PRV RGB_MAT4 =0x%x\n",
1845 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1847 DPRINTK_ISPPREV("###PRV RGB_MAT5 =0x%x\n",
1848 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1850 DPRINTK_ISPPREV("###PRV RGB_OFF1 =0x%x\n",
1851 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1853 DPRINTK_ISPPREV("###PRV RGB_OFF2 =0x%x\n",
1854 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1856 DPRINTK_ISPPREV("###PRV CSC0 =0x%x\n",
1857 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1859 DPRINTK_ISPPREV("###PRV CSC1 =0x%x\n",
1860 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1862 DPRINTK_ISPPREV("###PRV CSC2 =0x%x\n",
1863 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1865 DPRINTK_ISPPREV("###PRV CSC_OFFSET =0x%x\n",
1866 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1867 ISPPRV_CSC_OFFSET
));
1868 DPRINTK_ISPPREV("###PRV CNT_BRT =0x%x\n",
1869 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1871 DPRINTK_ISPPREV("###PRV CSUP =0x%x\n",
1872 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1874 DPRINTK_ISPPREV("###PRV SETUP_YC =0x%x\n",
1875 isp_reg_readl(isp_prev
->dev
, OMAP3_ISP_IOMEM_PREV
,
1878 EXPORT_SYMBOL_GPL(isppreview_print_status
);
1881 * isp_preview_init - Module Initialization.
1883 int __init
isp_preview_init(struct device
*dev
)
1885 struct isp_device
*isp
= dev_get_drvdata(dev
);
1886 struct isp_prev_device
*isp_prev
= &isp
->isp_prev
;
1887 struct prev_params
*params
= &isp_prev
->params
;
1890 isp_prev
->dev
= dev
;
1895 isp_prev
->color
= V4L2_COLORFX_NONE
;
1896 isp_prev
->contrast
= ISPPRV_CONTRAST_DEF
;
1897 params
->contrast
= ISPPRV_CONTRAST_DEF
;
1898 isp_prev
->brightness
= ISPPRV_BRIGHT_DEF
;
1899 params
->brightness
= ISPPRV_BRIGHT_DEF
;
1900 params
->average
= NO_AVE
;
1901 params
->lens_shading_shift
= 0;
1902 params
->cfa
.cfafmt
= CFAFMT_BAYER
;
1903 params
->cfa
.cfa_table
= cfa_coef_table
;
1904 params
->cfa
.cfa_gradthrs_horz
= FLR_CFA_GRADTHRS_HORZ
;
1905 params
->cfa
.cfa_gradthrs_vert
= FLR_CFA_GRADTHRS_VERT
;
1906 params
->csup
.gain
= FLR_CSUP_GAIN
;
1907 params
->csup
.thres
= FLR_CSUP_THRES
;
1908 params
->csup
.hypf_en
= 0;
1909 params
->ytable
= kzalloc(sizeof(u32
) * ISPPRV_YENH_TBL_SIZE
,
1911 isppreview_set_luma_enhancement(isp_prev
, luma_enhance_table
);
1912 params
->nf
.spread
= FLR_NF_STRGTH
;
1913 memcpy(params
->nf
.table
, noise_filter_table
, sizeof(params
->nf
.table
));
1914 params
->dcor
.couplet_mode_en
= 1;
1915 for (i
= 0; i
< 4; i
++)
1916 params
->dcor
.detect_correct
[i
] = 0xE;
1917 params
->gtable
.bluetable
= bluegamma_table
;
1918 params
->gtable
.greentable
= greengamma_table
;
1919 params
->gtable
.redtable
= redgamma_table
;
1920 params
->wbal
.dgain
= FLR_WBAL_DGAIN
;
1921 if (omap_rev() > OMAP3430_REV_ES1_0
) {
1922 params
->wbal
.coef0
= FLR_WBAL_COEF0_ES1
;
1923 params
->wbal
.coef1
= FLR_WBAL_COEF1_ES1
;
1924 params
->wbal
.coef2
= FLR_WBAL_COEF2_ES1
;
1925 params
->wbal
.coef3
= FLR_WBAL_COEF3_ES1
;
1927 params
->wbal
.coef0
= FLR_WBAL_COEF0
;
1928 params
->wbal
.coef1
= FLR_WBAL_COEF1
;
1929 params
->wbal
.coef2
= FLR_WBAL_COEF2
;
1930 params
->wbal
.coef3
= FLR_WBAL_COEF3
;
1932 params
->blk_adj
.red
= FLR_BLKADJ_RED
;
1933 params
->blk_adj
.green
= FLR_BLKADJ_GREEN
;
1934 params
->blk_adj
.blue
= FLR_BLKADJ_BLUE
;
1935 params
->rgb2rgb
= flr_rgb2rgb
;
1936 params
->rgb2ycbcr
= flr_prev_csc
[isp_prev
->color
];
1938 params
->features
= PREV_CFA
| PREV_DEFECT_COR
| PREV_NOISE_FILTER
;
1939 params
->features
&= ~(PREV_AVERAGER
| PREV_INVERSE_ALAW
|
1940 PREV_HORZ_MEDIAN_FILTER
|
1942 PREV_DARK_FRAME_SUBTRACT
|
1944 PREV_DARK_FRAME_CAPTURE
|
1945 PREV_CHROMA_SUPPRESS
|
1948 spin_lock_init(&isp_prev
->lock
);
1954 * isp_preview_cleanup - Module Cleanup.
1956 void isp_preview_cleanup(struct device
*dev
)
1958 struct isp_device
*isp
= dev_get_drvdata(dev
);
1959 struct isp_prev_device
*isp_prev
= &isp
->isp_prev
;
1960 struct prev_params
*params
= &isp_prev
->params
;
1962 kfree(params
->ytable
);