4 * TI OMAP3 ISP driver - Preview module
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 #include <linux/device.h>
29 #include <linux/module.h>
30 #include <linux/mutex.h>
31 #include <linux/uaccess.h>
35 #include "isppreview.h"
37 /* Default values in Office Fluorescent Light for RGBtoRGB Blending */
38 static struct omap3isp_prev_rgbtorgb flr_rgb2rgb
= {
39 { /* RGB-RGB Matrix */
40 {0x01E2, 0x0F30, 0x0FEE},
41 {0x0F9B, 0x01AC, 0x0FB9},
42 {0x0FE0, 0x0EC0, 0x0260}
44 {0x0000, 0x0000, 0x0000}
47 /* Default values in Office Fluorescent Light for RGB to YUV Conversion*/
48 static struct omap3isp_prev_csc flr_prev_csc
= {
49 { /* CSC Coef Matrix */
57 /* Default values in Office Fluorescent Light for CFA Gradient*/
58 #define FLR_CFA_GRADTHRS_HORZ 0x28
59 #define FLR_CFA_GRADTHRS_VERT 0x28
61 /* Default values in Office Fluorescent Light for Chroma Suppression*/
62 #define FLR_CSUP_GAIN 0x0D
63 #define FLR_CSUP_THRES 0xEB
65 /* Default values in Office Fluorescent Light for Noise Filter*/
66 #define FLR_NF_STRGTH 0x03
68 /* Default values for White Balance */
69 #define FLR_WBAL_DGAIN 0x100
70 #define FLR_WBAL_COEF 0x20
72 /* Default values in Office Fluorescent Light for Black Adjustment*/
73 #define FLR_BLKADJ_BLUE 0x0
74 #define FLR_BLKADJ_GREEN 0x0
75 #define FLR_BLKADJ_RED 0x0
77 #define DEF_DETECT_CORRECT_VAL 0xe
79 #define PREV_MIN_WIDTH 64
80 #define PREV_MIN_HEIGHT 8
81 #define PREV_MAX_HEIGHT 16384
84 * Coeficient Tables for the submodules in Preview.
85 * Array is initialised with the values from.the tables text file.
89 * CFA Filter Coefficient Table
92 static u32 cfa_coef_table
[] = {
93 #include "cfa_coef_table.h"
97 * Default Gamma Correction Table - All components
99 static u32 gamma_table
[] = {
100 #include "gamma_table.h"
104 * Noise Filter Threshold table
106 static u32 noise_filter_table
[] = {
107 #include "noise_filter_table.h"
111 * Luminance Enhancement Table
113 static u32 luma_enhance_table
[] = {
114 #include "luma_enhance_table.h"
118 * preview_enable_invalaw - Enable/Disable Inverse A-Law module in Preview.
119 * @enable: 1 - Reverse the A-Law done in CCDC.
122 preview_enable_invalaw(struct isp_prev_device
*prev
, u8 enable
)
124 struct isp_device
*isp
= to_isp_device(prev
);
127 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
128 ISPPRV_PCR_WIDTH
| ISPPRV_PCR_INVALAW
);
130 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
131 ISPPRV_PCR_WIDTH
| ISPPRV_PCR_INVALAW
);
135 * preview_enable_drkframe_capture - Enable/Disable of the darkframe capture.
137 * @enable: 1 - Enable, 0 - Disable
139 * NOTE: PRV_WSDR_ADDR and PRV_WADD_OFFSET must be set also
140 * The process is applied for each captured frame.
143 preview_enable_drkframe_capture(struct isp_prev_device
*prev
, u8 enable
)
145 struct isp_device
*isp
= to_isp_device(prev
);
148 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
151 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
156 * preview_enable_drkframe - Enable/Disable of the darkframe subtract.
157 * @enable: 1 - Acquires memory bandwidth since the pixels in each frame is
158 * subtracted with the pixels in the current frame.
160 * The process is applied for each captured frame.
163 preview_enable_drkframe(struct isp_prev_device
*prev
, u8 enable
)
165 struct isp_device
*isp
= to_isp_device(prev
);
168 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
171 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
176 * preview_config_drkf_shadcomp - Configures shift value in shading comp.
177 * @scomp_shtval: 3bit value of shift used in shading compensation.
180 preview_config_drkf_shadcomp(struct isp_prev_device
*prev
,
181 const void *scomp_shtval
)
183 struct isp_device
*isp
= to_isp_device(prev
);
184 const u32
*shtval
= scomp_shtval
;
186 isp_reg_clr_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
187 ISPPRV_PCR_SCOMP_SFT_MASK
,
188 *shtval
<< ISPPRV_PCR_SCOMP_SFT_SHIFT
);
192 * preview_enable_hmed - Enables/Disables of the Horizontal Median Filter.
193 * @enable: 1 - Enables Horizontal Median Filter.
196 preview_enable_hmed(struct isp_prev_device
*prev
, u8 enable
)
198 struct isp_device
*isp
= to_isp_device(prev
);
201 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
204 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
209 * preview_config_hmed - Configures the Horizontal Median Filter.
210 * @prev_hmed: Structure containing the odd and even distance between the
211 * pixels in the image along with the filter threshold.
214 preview_config_hmed(struct isp_prev_device
*prev
, const void *prev_hmed
)
216 struct isp_device
*isp
= to_isp_device(prev
);
217 const struct omap3isp_prev_hmed
*hmed
= prev_hmed
;
219 isp_reg_writel(isp
, (hmed
->odddist
== 1 ? 0 : ISPPRV_HMED_ODDDIST
) |
220 (hmed
->evendist
== 1 ? 0 : ISPPRV_HMED_EVENDIST
) |
221 (hmed
->thres
<< ISPPRV_HMED_THRESHOLD_SHIFT
),
222 OMAP3_ISP_IOMEM_PREV
, ISPPRV_HMED
);
226 * preview_config_noisefilter - Configures the Noise Filter.
227 * @prev_nf: Structure containing the noisefilter table, strength to be used
228 * for the noise filter and the defect correction enable flag.
231 preview_config_noisefilter(struct isp_prev_device
*prev
, const void *prev_nf
)
233 struct isp_device
*isp
= to_isp_device(prev
);
234 const struct omap3isp_prev_nf
*nf
= prev_nf
;
237 isp_reg_writel(isp
, nf
->spread
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_NF
);
238 isp_reg_writel(isp
, ISPPRV_NF_TABLE_ADDR
,
239 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
240 for (i
= 0; i
< OMAP3ISP_PREV_NF_TBL_SIZE
; i
++) {
241 isp_reg_writel(isp
, nf
->table
[i
],
242 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_DATA
);
247 * preview_config_dcor - Configures the defect correction
248 * @prev_dcor: Structure containing the defect correct thresholds
251 preview_config_dcor(struct isp_prev_device
*prev
, const void *prev_dcor
)
253 struct isp_device
*isp
= to_isp_device(prev
);
254 const struct omap3isp_prev_dcor
*dcor
= prev_dcor
;
256 isp_reg_writel(isp
, dcor
->detect_correct
[0],
257 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR0
);
258 isp_reg_writel(isp
, dcor
->detect_correct
[1],
259 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR1
);
260 isp_reg_writel(isp
, dcor
->detect_correct
[2],
261 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR2
);
262 isp_reg_writel(isp
, dcor
->detect_correct
[3],
263 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CDC_THR3
);
264 isp_reg_clr_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
266 dcor
->couplet_mode_en
? ISPPRV_PCR_DCCOUP
: 0);
270 * preview_config_cfa - Configures the CFA Interpolation parameters.
271 * @prev_cfa: Structure containing the CFA interpolation table, CFA format
272 * in the image, vertical and horizontal gradient threshold.
275 preview_config_cfa(struct isp_prev_device
*prev
, const void *prev_cfa
)
277 struct isp_device
*isp
= to_isp_device(prev
);
278 const struct omap3isp_prev_cfa
*cfa
= prev_cfa
;
281 isp_reg_clr_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
282 ISPPRV_PCR_CFAFMT_MASK
,
283 cfa
->format
<< ISPPRV_PCR_CFAFMT_SHIFT
);
286 (cfa
->gradthrs_vert
<< ISPPRV_CFA_GRADTH_VER_SHIFT
) |
287 (cfa
->gradthrs_horz
<< ISPPRV_CFA_GRADTH_HOR_SHIFT
),
288 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CFA
);
290 isp_reg_writel(isp
, ISPPRV_CFA_TABLE_ADDR
,
291 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
293 for (i
= 0; i
< OMAP3ISP_PREV_CFA_TBL_SIZE
; i
++) {
294 isp_reg_writel(isp
, cfa
->table
[i
],
295 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_DATA
);
300 * preview_config_gammacorrn - Configures the Gamma Correction table values
301 * @gtable: Structure containing the table for red, blue, green gamma table.
304 preview_config_gammacorrn(struct isp_prev_device
*prev
, const void *gtable
)
306 struct isp_device
*isp
= to_isp_device(prev
);
307 const struct omap3isp_prev_gtables
*gt
= gtable
;
310 isp_reg_writel(isp
, ISPPRV_REDGAMMA_TABLE_ADDR
,
311 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
312 for (i
= 0; i
< OMAP3ISP_PREV_GAMMA_TBL_SIZE
; i
++)
313 isp_reg_writel(isp
, gt
->red
[i
], OMAP3_ISP_IOMEM_PREV
,
314 ISPPRV_SET_TBL_DATA
);
316 isp_reg_writel(isp
, ISPPRV_GREENGAMMA_TABLE_ADDR
,
317 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
318 for (i
= 0; i
< OMAP3ISP_PREV_GAMMA_TBL_SIZE
; i
++)
319 isp_reg_writel(isp
, gt
->green
[i
], OMAP3_ISP_IOMEM_PREV
,
320 ISPPRV_SET_TBL_DATA
);
322 isp_reg_writel(isp
, ISPPRV_BLUEGAMMA_TABLE_ADDR
,
323 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
324 for (i
= 0; i
< OMAP3ISP_PREV_GAMMA_TBL_SIZE
; i
++)
325 isp_reg_writel(isp
, gt
->blue
[i
], OMAP3_ISP_IOMEM_PREV
,
326 ISPPRV_SET_TBL_DATA
);
330 * preview_config_luma_enhancement - Sets the Luminance Enhancement table.
331 * @ytable: Structure containing the table for Luminance Enhancement table.
334 preview_config_luma_enhancement(struct isp_prev_device
*prev
,
337 struct isp_device
*isp
= to_isp_device(prev
);
338 const struct omap3isp_prev_luma
*yt
= ytable
;
341 isp_reg_writel(isp
, ISPPRV_YENH_TABLE_ADDR
,
342 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_ADDR
);
343 for (i
= 0; i
< OMAP3ISP_PREV_YENH_TBL_SIZE
; i
++) {
344 isp_reg_writel(isp
, yt
->table
[i
],
345 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SET_TBL_DATA
);
350 * preview_config_chroma_suppression - Configures the Chroma Suppression.
351 * @csup: Structure containing the threshold value for suppression
352 * and the hypass filter enable flag.
355 preview_config_chroma_suppression(struct isp_prev_device
*prev
,
358 struct isp_device
*isp
= to_isp_device(prev
);
359 const struct omap3isp_prev_csup
*cs
= csup
;
362 cs
->gain
| (cs
->thres
<< ISPPRV_CSUP_THRES_SHIFT
) |
363 (cs
->hypf_en
<< ISPPRV_CSUP_HPYF_SHIFT
),
364 OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSUP
);
368 * preview_enable_noisefilter - Enables/Disables the Noise Filter.
369 * @enable: 1 - Enables the Noise Filter.
372 preview_enable_noisefilter(struct isp_prev_device
*prev
, u8 enable
)
374 struct isp_device
*isp
= to_isp_device(prev
);
377 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
380 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
385 * preview_enable_dcor - Enables/Disables the defect correction.
386 * @enable: 1 - Enables the defect correction.
389 preview_enable_dcor(struct isp_prev_device
*prev
, u8 enable
)
391 struct isp_device
*isp
= to_isp_device(prev
);
394 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
397 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
402 * preview_enable_cfa - Enable/Disable the CFA Interpolation.
403 * @enable: 1 - Enables the CFA.
406 preview_enable_cfa(struct isp_prev_device
*prev
, u8 enable
)
408 struct isp_device
*isp
= to_isp_device(prev
);
411 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
414 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
419 * preview_enable_gammabypass - Enables/Disables the GammaByPass
420 * @enable: 1 - Bypasses Gamma - 10bit input is cropped to 8MSB.
421 * 0 - Goes through Gamma Correction. input and output is 10bit.
424 preview_enable_gammabypass(struct isp_prev_device
*prev
, u8 enable
)
426 struct isp_device
*isp
= to_isp_device(prev
);
429 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
430 ISPPRV_PCR_GAMMA_BYPASS
);
432 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
433 ISPPRV_PCR_GAMMA_BYPASS
);
437 * preview_enable_luma_enhancement - Enables/Disables Luminance Enhancement
438 * @enable: 1 - Enable the Luminance Enhancement.
441 preview_enable_luma_enhancement(struct isp_prev_device
*prev
, u8 enable
)
443 struct isp_device
*isp
= to_isp_device(prev
);
446 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
449 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
454 * preview_enable_chroma_suppression - Enables/Disables Chrominance Suppr.
455 * @enable: 1 - Enable the Chrominance Suppression.
458 preview_enable_chroma_suppression(struct isp_prev_device
*prev
, u8 enable
)
460 struct isp_device
*isp
= to_isp_device(prev
);
463 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
466 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
471 * preview_config_whitebalance - Configures the White Balance parameters.
472 * @prev_wbal: Structure containing the digital gain and white balance
475 * Coefficient matrix always with default values.
478 preview_config_whitebalance(struct isp_prev_device
*prev
, const void *prev_wbal
)
480 struct isp_device
*isp
= to_isp_device(prev
);
481 const struct omap3isp_prev_wbal
*wbal
= prev_wbal
;
484 isp_reg_writel(isp
, wbal
->dgain
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_WB_DGAIN
);
486 val
= wbal
->coef0
<< ISPPRV_WBGAIN_COEF0_SHIFT
;
487 val
|= wbal
->coef1
<< ISPPRV_WBGAIN_COEF1_SHIFT
;
488 val
|= wbal
->coef2
<< ISPPRV_WBGAIN_COEF2_SHIFT
;
489 val
|= wbal
->coef3
<< ISPPRV_WBGAIN_COEF3_SHIFT
;
490 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_WBGAIN
);
493 ISPPRV_WBSEL_COEF0
<< ISPPRV_WBSEL_N0_0_SHIFT
|
494 ISPPRV_WBSEL_COEF1
<< ISPPRV_WBSEL_N0_1_SHIFT
|
495 ISPPRV_WBSEL_COEF0
<< ISPPRV_WBSEL_N0_2_SHIFT
|
496 ISPPRV_WBSEL_COEF1
<< ISPPRV_WBSEL_N0_3_SHIFT
|
497 ISPPRV_WBSEL_COEF2
<< ISPPRV_WBSEL_N1_0_SHIFT
|
498 ISPPRV_WBSEL_COEF3
<< ISPPRV_WBSEL_N1_1_SHIFT
|
499 ISPPRV_WBSEL_COEF2
<< ISPPRV_WBSEL_N1_2_SHIFT
|
500 ISPPRV_WBSEL_COEF3
<< ISPPRV_WBSEL_N1_3_SHIFT
|
501 ISPPRV_WBSEL_COEF0
<< ISPPRV_WBSEL_N2_0_SHIFT
|
502 ISPPRV_WBSEL_COEF1
<< ISPPRV_WBSEL_N2_1_SHIFT
|
503 ISPPRV_WBSEL_COEF0
<< ISPPRV_WBSEL_N2_2_SHIFT
|
504 ISPPRV_WBSEL_COEF1
<< ISPPRV_WBSEL_N2_3_SHIFT
|
505 ISPPRV_WBSEL_COEF2
<< ISPPRV_WBSEL_N3_0_SHIFT
|
506 ISPPRV_WBSEL_COEF3
<< ISPPRV_WBSEL_N3_1_SHIFT
|
507 ISPPRV_WBSEL_COEF2
<< ISPPRV_WBSEL_N3_2_SHIFT
|
508 ISPPRV_WBSEL_COEF3
<< ISPPRV_WBSEL_N3_3_SHIFT
,
509 OMAP3_ISP_IOMEM_PREV
, ISPPRV_WBSEL
);
513 * preview_config_blkadj - Configures the Black Adjustment parameters.
514 * @prev_blkadj: Structure containing the black adjustment towards red, green,
518 preview_config_blkadj(struct isp_prev_device
*prev
, const void *prev_blkadj
)
520 struct isp_device
*isp
= to_isp_device(prev
);
521 const struct omap3isp_prev_blkadj
*blkadj
= prev_blkadj
;
523 isp_reg_writel(isp
, (blkadj
->blue
<< ISPPRV_BLKADJOFF_B_SHIFT
) |
524 (blkadj
->green
<< ISPPRV_BLKADJOFF_G_SHIFT
) |
525 (blkadj
->red
<< ISPPRV_BLKADJOFF_R_SHIFT
),
526 OMAP3_ISP_IOMEM_PREV
, ISPPRV_BLKADJOFF
);
530 * preview_config_rgb_blending - Configures the RGB-RGB Blending matrix.
531 * @rgb2rgb: Structure containing the rgb to rgb blending matrix and the rgb
535 preview_config_rgb_blending(struct isp_prev_device
*prev
, const void *rgb2rgb
)
537 struct isp_device
*isp
= to_isp_device(prev
);
538 const struct omap3isp_prev_rgbtorgb
*rgbrgb
= rgb2rgb
;
541 val
= (rgbrgb
->matrix
[0][0] & 0xfff) << ISPPRV_RGB_MAT1_MTX_RR_SHIFT
;
542 val
|= (rgbrgb
->matrix
[0][1] & 0xfff) << ISPPRV_RGB_MAT1_MTX_GR_SHIFT
;
543 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT1
);
545 val
= (rgbrgb
->matrix
[0][2] & 0xfff) << ISPPRV_RGB_MAT2_MTX_BR_SHIFT
;
546 val
|= (rgbrgb
->matrix
[1][0] & 0xfff) << ISPPRV_RGB_MAT2_MTX_RG_SHIFT
;
547 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT2
);
549 val
= (rgbrgb
->matrix
[1][1] & 0xfff) << ISPPRV_RGB_MAT3_MTX_GG_SHIFT
;
550 val
|= (rgbrgb
->matrix
[1][2] & 0xfff) << ISPPRV_RGB_MAT3_MTX_BG_SHIFT
;
551 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT3
);
553 val
= (rgbrgb
->matrix
[2][0] & 0xfff) << ISPPRV_RGB_MAT4_MTX_RB_SHIFT
;
554 val
|= (rgbrgb
->matrix
[2][1] & 0xfff) << ISPPRV_RGB_MAT4_MTX_GB_SHIFT
;
555 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT4
);
557 val
= (rgbrgb
->matrix
[2][2] & 0xfff) << ISPPRV_RGB_MAT5_MTX_BB_SHIFT
;
558 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_MAT5
);
560 val
= (rgbrgb
->offset
[0] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT
;
561 val
|= (rgbrgb
->offset
[1] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT
;
562 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_OFF1
);
564 val
= (rgbrgb
->offset
[2] & 0x3ff) << ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT
;
565 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_RGB_OFF2
);
569 * Configures the RGB-YCbYCr conversion matrix
570 * @prev_csc: Structure containing the RGB to YCbYCr matrix and the
574 preview_config_rgb_to_ycbcr(struct isp_prev_device
*prev
, const void *prev_csc
)
576 struct isp_device
*isp
= to_isp_device(prev
);
577 const struct omap3isp_prev_csc
*csc
= prev_csc
;
580 val
= (csc
->matrix
[0][0] & 0x3ff) << ISPPRV_CSC0_RY_SHIFT
;
581 val
|= (csc
->matrix
[0][1] & 0x3ff) << ISPPRV_CSC0_GY_SHIFT
;
582 val
|= (csc
->matrix
[0][2] & 0x3ff) << ISPPRV_CSC0_BY_SHIFT
;
583 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC0
);
585 val
= (csc
->matrix
[1][0] & 0x3ff) << ISPPRV_CSC1_RCB_SHIFT
;
586 val
|= (csc
->matrix
[1][1] & 0x3ff) << ISPPRV_CSC1_GCB_SHIFT
;
587 val
|= (csc
->matrix
[1][2] & 0x3ff) << ISPPRV_CSC1_BCB_SHIFT
;
588 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC1
);
590 val
= (csc
->matrix
[2][0] & 0x3ff) << ISPPRV_CSC2_RCR_SHIFT
;
591 val
|= (csc
->matrix
[2][1] & 0x3ff) << ISPPRV_CSC2_GCR_SHIFT
;
592 val
|= (csc
->matrix
[2][2] & 0x3ff) << ISPPRV_CSC2_BCR_SHIFT
;
593 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC2
);
595 val
= (csc
->offset
[0] & 0xff) << ISPPRV_CSC_OFFSET_Y_SHIFT
;
596 val
|= (csc
->offset
[1] & 0xff) << ISPPRV_CSC_OFFSET_CB_SHIFT
;
597 val
|= (csc
->offset
[2] & 0xff) << ISPPRV_CSC_OFFSET_CR_SHIFT
;
598 isp_reg_writel(isp
, val
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_CSC_OFFSET
);
602 * preview_update_contrast - Updates the contrast.
603 * @contrast: Pointer to hold the current programmed contrast value.
605 * Value should be programmed before enabling the module.
608 preview_update_contrast(struct isp_prev_device
*prev
, u8 contrast
)
610 struct prev_params
*params
= &prev
->params
;
612 if (params
->contrast
!= (contrast
* ISPPRV_CONTRAST_UNITS
)) {
613 params
->contrast
= contrast
* ISPPRV_CONTRAST_UNITS
;
614 prev
->update
|= PREV_CONTRAST
;
619 * preview_config_contrast - Configures the Contrast.
620 * @params: Contrast value (u8 pointer, U8Q0 format).
622 * Value should be programmed before enabling the module.
625 preview_config_contrast(struct isp_prev_device
*prev
, const void *params
)
627 struct isp_device
*isp
= to_isp_device(prev
);
629 isp_reg_clr_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_CNT_BRT
,
630 0xff << ISPPRV_CNT_BRT_CNT_SHIFT
,
631 *(u8
*)params
<< ISPPRV_CNT_BRT_CNT_SHIFT
);
635 * preview_update_brightness - Updates the brightness in preview module.
636 * @brightness: Pointer to hold the current programmed brightness value.
640 preview_update_brightness(struct isp_prev_device
*prev
, u8 brightness
)
642 struct prev_params
*params
= &prev
->params
;
644 if (params
->brightness
!= (brightness
* ISPPRV_BRIGHT_UNITS
)) {
645 params
->brightness
= brightness
* ISPPRV_BRIGHT_UNITS
;
646 prev
->update
|= PREV_BRIGHTNESS
;
651 * preview_config_brightness - Configures the brightness.
652 * @params: Brightness value (u8 pointer, U8Q0 format).
655 preview_config_brightness(struct isp_prev_device
*prev
, const void *params
)
657 struct isp_device
*isp
= to_isp_device(prev
);
659 isp_reg_clr_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_CNT_BRT
,
660 0xff << ISPPRV_CNT_BRT_BRT_SHIFT
,
661 *(u8
*)params
<< ISPPRV_CNT_BRT_BRT_SHIFT
);
665 * preview_config_yc_range - Configures the max and min Y and C values.
666 * @yclimit: Structure containing the range of Y and C values.
669 preview_config_yc_range(struct isp_prev_device
*prev
, const void *yclimit
)
671 struct isp_device
*isp
= to_isp_device(prev
);
672 const struct omap3isp_prev_yclimit
*yc
= yclimit
;
675 yc
->maxC
<< ISPPRV_SETUP_YC_MAXC_SHIFT
|
676 yc
->maxY
<< ISPPRV_SETUP_YC_MAXY_SHIFT
|
677 yc
->minC
<< ISPPRV_SETUP_YC_MINC_SHIFT
|
678 yc
->minY
<< ISPPRV_SETUP_YC_MINY_SHIFT
,
679 OMAP3_ISP_IOMEM_PREV
, ISPPRV_SETUP_YC
);
682 /* preview parameters update structure */
683 struct preview_update
{
686 void (*config
)(struct isp_prev_device
*, const void *);
687 void (*enable
)(struct isp_prev_device
*, u8
);
690 static struct preview_update update_attrs
[] = {
691 {OMAP3ISP_PREV_LUMAENH
, PREV_LUMA_ENHANCE
,
692 preview_config_luma_enhancement
,
693 preview_enable_luma_enhancement
},
694 {OMAP3ISP_PREV_INVALAW
, PREV_INVERSE_ALAW
,
696 preview_enable_invalaw
},
697 {OMAP3ISP_PREV_HRZ_MED
, PREV_HORZ_MEDIAN_FILTER
,
699 preview_enable_hmed
},
700 {OMAP3ISP_PREV_CFA
, PREV_CFA
,
703 {OMAP3ISP_PREV_CHROMA_SUPP
, PREV_CHROMA_SUPPRESS
,
704 preview_config_chroma_suppression
,
705 preview_enable_chroma_suppression
},
706 {OMAP3ISP_PREV_WB
, PREV_WB
,
707 preview_config_whitebalance
,
709 {OMAP3ISP_PREV_BLKADJ
, PREV_BLKADJ
,
710 preview_config_blkadj
,
712 {OMAP3ISP_PREV_RGB2RGB
, PREV_RGB2RGB
,
713 preview_config_rgb_blending
,
715 {OMAP3ISP_PREV_COLOR_CONV
, PREV_COLOR_CONV
,
716 preview_config_rgb_to_ycbcr
,
718 {OMAP3ISP_PREV_YC_LIMIT
, PREV_YCLIMITS
,
719 preview_config_yc_range
,
721 {OMAP3ISP_PREV_DEFECT_COR
, PREV_DEFECT_COR
,
723 preview_enable_dcor
},
724 {OMAP3ISP_PREV_GAMMABYPASS
, PREV_GAMMA_BYPASS
,
726 preview_enable_gammabypass
},
727 {OMAP3ISP_PREV_DRK_FRM_CAPTURE
, PREV_DARK_FRAME_CAPTURE
,
729 preview_enable_drkframe_capture
},
730 {OMAP3ISP_PREV_DRK_FRM_SUBTRACT
, PREV_DARK_FRAME_SUBTRACT
,
732 preview_enable_drkframe
},
733 {OMAP3ISP_PREV_LENS_SHADING
, PREV_LENS_SHADING
,
734 preview_config_drkf_shadcomp
,
735 preview_enable_drkframe
},
736 {OMAP3ISP_PREV_NF
, PREV_NOISE_FILTER
,
737 preview_config_noisefilter
,
738 preview_enable_noisefilter
},
739 {OMAP3ISP_PREV_GAMMA
, PREV_GAMMA
,
740 preview_config_gammacorrn
,
743 preview_config_contrast
,
745 {-1, PREV_BRIGHTNESS
,
746 preview_config_brightness
,
751 * __preview_get_ptrs - helper function which return pointers to members
752 * of params and config structures.
753 * @params - pointer to preview_params structure.
754 * @param - return pointer to appropriate structure field.
755 * @configs - pointer to update config structure.
756 * @config - return pointer to appropriate structure field.
757 * @bit - for which feature to return pointers.
758 * Return size of coresponding prev_params member
761 __preview_get_ptrs(struct prev_params
*params
, void **param
,
762 struct omap3isp_prev_update_config
*configs
,
763 void __user
**config
, u32 bit
)
765 #define CHKARG(cfgs, cfg, field) \
767 *(cfg) = (cfgs)->field; \
771 case PREV_HORZ_MEDIAN_FILTER
:
772 *param
= ¶ms
->hmed
;
773 CHKARG(configs
, config
, hmed
)
774 return sizeof(params
->hmed
);
775 case PREV_NOISE_FILTER
:
776 *param
= ¶ms
->nf
;
777 CHKARG(configs
, config
, nf
)
778 return sizeof(params
->nf
);
781 *param
= ¶ms
->cfa
;
782 CHKARG(configs
, config
, cfa
)
783 return sizeof(params
->cfa
);
784 case PREV_LUMA_ENHANCE
:
785 *param
= ¶ms
->luma
;
786 CHKARG(configs
, config
, luma
)
787 return sizeof(params
->luma
);
788 case PREV_CHROMA_SUPPRESS
:
789 *param
= ¶ms
->csup
;
790 CHKARG(configs
, config
, csup
)
791 return sizeof(params
->csup
);
792 case PREV_DEFECT_COR
:
793 *param
= ¶ms
->dcor
;
794 CHKARG(configs
, config
, dcor
)
795 return sizeof(params
->dcor
);
797 *param
= ¶ms
->blk_adj
;
798 CHKARG(configs
, config
, blkadj
)
799 return sizeof(params
->blk_adj
);
801 *param
= ¶ms
->yclimit
;
802 CHKARG(configs
, config
, yclimit
)
803 return sizeof(params
->yclimit
);
805 *param
= ¶ms
->rgb2rgb
;
806 CHKARG(configs
, config
, rgb2rgb
)
807 return sizeof(params
->rgb2rgb
);
808 case PREV_COLOR_CONV
:
809 *param
= ¶ms
->rgb2ycbcr
;
810 CHKARG(configs
, config
, csc
)
811 return sizeof(params
->rgb2ycbcr
);
813 *param
= ¶ms
->wbal
;
814 CHKARG(configs
, config
, wbal
)
815 return sizeof(params
->wbal
);
817 *param
= ¶ms
->gamma
;
818 CHKARG(configs
, config
, gamma
)
819 return sizeof(params
->gamma
);
821 *param
= ¶ms
->contrast
;
823 case PREV_BRIGHTNESS
:
824 *param
= ¶ms
->brightness
;
835 * preview_config - Copy and update local structure with userspace preview
837 * @prev: ISP preview engine
838 * @cfg: Configuration
840 * Return zero if success or -EFAULT if the configuration can't be copied from
843 static int preview_config(struct isp_prev_device
*prev
,
844 struct omap3isp_prev_update_config
*cfg
)
846 struct prev_params
*params
;
847 struct preview_update
*attr
;
848 int i
, bit
, rval
= 0;
850 params
= &prev
->params
;
852 if (prev
->state
!= ISP_PIPELINE_STREAM_STOPPED
) {
855 spin_lock_irqsave(&prev
->lock
, flags
);
856 prev
->shadow_update
= 1;
857 spin_unlock_irqrestore(&prev
->lock
, flags
);
860 for (i
= 0; i
< ARRAY_SIZE(update_attrs
); i
++) {
861 attr
= &update_attrs
[i
];
864 if (!(cfg
->update
& attr
->cfg_bit
))
867 bit
= cfg
->flag
& attr
->cfg_bit
;
869 void *to
= NULL
, __user
*from
= NULL
;
870 unsigned long sz
= 0;
872 sz
= __preview_get_ptrs(params
, &to
, cfg
, &from
,
874 if (to
&& from
&& sz
) {
875 if (copy_from_user(to
, from
, sz
)) {
880 params
->features
|= attr
->feature_bit
;
882 params
->features
&= ~attr
->feature_bit
;
885 prev
->update
|= attr
->feature_bit
;
888 prev
->shadow_update
= 0;
893 * preview_setup_hw - Setup preview registers and/or internal memory
894 * @prev: pointer to preview private structure
895 * Note: can be called from interrupt context
898 static void preview_setup_hw(struct isp_prev_device
*prev
)
900 struct prev_params
*params
= &prev
->params
;
901 struct preview_update
*attr
;
905 for (i
= 0; i
< ARRAY_SIZE(update_attrs
); i
++) {
906 attr
= &update_attrs
[i
];
908 if (!(prev
->update
& attr
->feature_bit
))
910 bit
= params
->features
& attr
->feature_bit
;
913 __preview_get_ptrs(params
, ¶m_ptr
, NULL
,
915 attr
->config(prev
, param_ptr
);
918 attr
->enable(prev
, 1);
921 attr
->enable(prev
, 0);
923 prev
->update
&= ~attr
->feature_bit
;
928 * preview_config_ycpos - Configure byte layout of YUV image.
929 * @mode: Indicates the required byte layout.
932 preview_config_ycpos(struct isp_prev_device
*prev
,
933 enum v4l2_mbus_pixelcode pixelcode
)
935 struct isp_device
*isp
= to_isp_device(prev
);
936 enum preview_ycpos_mode mode
;
939 case V4L2_MBUS_FMT_YUYV8_1X16
:
942 case V4L2_MBUS_FMT_UYVY8_1X16
:
949 isp_reg_clr_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
950 ISPPRV_PCR_YCPOS_CrYCbY
,
951 mode
<< ISPPRV_PCR_YCPOS_SHIFT
);
955 * preview_config_averager - Enable / disable / configure averager
956 * @average: Average value to be configured.
958 static void preview_config_averager(struct isp_prev_device
*prev
, u8 average
)
960 struct isp_device
*isp
= to_isp_device(prev
);
963 if (prev
->params
.cfa
.format
== OMAP3ISP_CFAFMT_BAYER
)
964 reg
= ISPPRV_AVE_EVENDIST_2
<< ISPPRV_AVE_EVENDIST_SHIFT
|
965 ISPPRV_AVE_ODDDIST_2
<< ISPPRV_AVE_ODDDIST_SHIFT
|
967 else if (prev
->params
.cfa
.format
== OMAP3ISP_CFAFMT_RGBFOVEON
)
968 reg
= ISPPRV_AVE_EVENDIST_3
<< ISPPRV_AVE_EVENDIST_SHIFT
|
969 ISPPRV_AVE_ODDDIST_3
<< ISPPRV_AVE_ODDDIST_SHIFT
|
971 isp_reg_writel(isp
, reg
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_AVE
);
975 * preview_config_input_size - Configure the input frame size
977 * The preview engine crops several rows and columns internally depending on
978 * which processing blocks are enabled. The driver assumes all those blocks are
979 * enabled when reporting source pad formats to userspace. If this assumption is
980 * not true, rows and columns must be manually cropped at the preview engine
981 * input to avoid overflows at the end of lines and frames.
983 static void preview_config_input_size(struct isp_prev_device
*prev
)
985 struct isp_device
*isp
= to_isp_device(prev
);
986 struct prev_params
*params
= &prev
->params
;
987 struct v4l2_mbus_framefmt
*format
= &prev
->formats
[PREV_PAD_SINK
];
988 unsigned int sph
= 0;
989 unsigned int eph
= format
->width
- 1;
990 unsigned int slv
= 0;
991 unsigned int elv
= format
->height
- 1;
993 if (prev
->input
== PREVIEW_INPUT_CCDC
) {
999 * Median filter 4 pixels
1000 * Noise filter 4 pixels, 4 lines
1001 * or faulty pixels correction
1002 * CFA filter 4 pixels, 4 lines in Bayer mode
1003 * 2 lines in other modes
1004 * Color suppression 2 pixels
1005 * or luma enhancement
1006 * -------------------------------------------------------------
1007 * Maximum total 14 pixels, 8 lines
1010 if (!(params
->features
& PREV_CFA
)) {
1016 if (!(params
->features
& (PREV_DEFECT_COR
| PREV_NOISE_FILTER
))) {
1022 if (!(params
->features
& PREV_HORZ_MEDIAN_FILTER
)) {
1026 if (!(params
->features
& (PREV_CHROMA_SUPPRESS
| PREV_LUMA_ENHANCE
)))
1029 isp_reg_writel(isp
, (sph
<< ISPPRV_HORZ_INFO_SPH_SHIFT
) | eph
,
1030 OMAP3_ISP_IOMEM_PREV
, ISPPRV_HORZ_INFO
);
1031 isp_reg_writel(isp
, (slv
<< ISPPRV_VERT_INFO_SLV_SHIFT
) | elv
,
1032 OMAP3_ISP_IOMEM_PREV
, ISPPRV_VERT_INFO
);
1036 * preview_config_inlineoffset - Configures the Read address line offset.
1037 * @prev: Preview module
1038 * @offset: Line offset
1040 * According to the TRM, the line offset must be aligned on a 32 bytes boundary.
1041 * However, a hardware bug requires the memory start address to be aligned on a
1042 * 64 bytes boundary, so the offset probably should be aligned on 64 bytes as
1046 preview_config_inlineoffset(struct isp_prev_device
*prev
, u32 offset
)
1048 struct isp_device
*isp
= to_isp_device(prev
);
1050 isp_reg_writel(isp
, offset
& 0xffff, OMAP3_ISP_IOMEM_PREV
,
1051 ISPPRV_RADR_OFFSET
);
1055 * preview_set_inaddr - Sets memory address of input frame.
1056 * @addr: 32bit memory address aligned on 32byte boundary.
1058 * Configures the memory address from which the input frame is to be read.
1060 static void preview_set_inaddr(struct isp_prev_device
*prev
, u32 addr
)
1062 struct isp_device
*isp
= to_isp_device(prev
);
1064 isp_reg_writel(isp
, addr
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_RSDR_ADDR
);
1068 * preview_config_outlineoffset - Configures the Write address line offset.
1069 * @offset: Line Offset for the preview output.
1071 * The offset must be a multiple of 32 bytes.
1073 static void preview_config_outlineoffset(struct isp_prev_device
*prev
,
1076 struct isp_device
*isp
= to_isp_device(prev
);
1078 isp_reg_writel(isp
, offset
& 0xffff, OMAP3_ISP_IOMEM_PREV
,
1079 ISPPRV_WADD_OFFSET
);
1083 * preview_set_outaddr - Sets the memory address to store output frame
1084 * @addr: 32bit memory address aligned on 32byte boundary.
1086 * Configures the memory address to which the output frame is written.
1088 static void preview_set_outaddr(struct isp_prev_device
*prev
, u32 addr
)
1090 struct isp_device
*isp
= to_isp_device(prev
);
1092 isp_reg_writel(isp
, addr
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_WSDR_ADDR
);
1095 static void preview_adjust_bandwidth(struct isp_prev_device
*prev
)
1097 struct isp_pipeline
*pipe
= to_isp_pipeline(&prev
->subdev
.entity
);
1098 struct isp_device
*isp
= to_isp_device(prev
);
1099 const struct v4l2_mbus_framefmt
*ifmt
= &prev
->formats
[PREV_PAD_SINK
];
1100 unsigned long l3_ick
= pipe
->l3_ick
;
1101 struct v4l2_fract
*timeperframe
;
1102 unsigned int cycles_per_frame
;
1103 unsigned int requests_per_frame
;
1104 unsigned int cycles_per_request
;
1105 unsigned int minimum
;
1106 unsigned int maximum
;
1109 if (prev
->input
!= PREVIEW_INPUT_MEMORY
) {
1110 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_SBL
, ISPSBL_SDR_REQ_EXP
,
1111 ISPSBL_SDR_REQ_PRV_EXP_MASK
);
1115 /* Compute the minimum number of cycles per request, based on the
1116 * pipeline maximum data rate. This is an absolute lower bound if we
1117 * don't want SBL overflows, so round the value up.
1119 cycles_per_request
= div_u64((u64
)l3_ick
/ 2 * 256 + pipe
->max_rate
- 1,
1121 minimum
= DIV_ROUND_UP(cycles_per_request
, 32);
1123 /* Compute the maximum number of cycles per request, based on the
1124 * requested frame rate. This is a soft upper bound to achieve a frame
1125 * rate equal or higher than the requested value, so round the value
1128 timeperframe
= &pipe
->max_timeperframe
;
1130 requests_per_frame
= DIV_ROUND_UP(ifmt
->width
* 2, 256) * ifmt
->height
;
1131 cycles_per_frame
= div_u64((u64
)l3_ick
* timeperframe
->numerator
,
1132 timeperframe
->denominator
);
1133 cycles_per_request
= cycles_per_frame
/ requests_per_frame
;
1135 maximum
= cycles_per_request
/ 32;
1137 value
= max(minimum
, maximum
);
1139 dev_dbg(isp
->dev
, "%s: cycles per request = %u\n", __func__
, value
);
1140 isp_reg_clr_set(isp
, OMAP3_ISP_IOMEM_SBL
, ISPSBL_SDR_REQ_EXP
,
1141 ISPSBL_SDR_REQ_PRV_EXP_MASK
,
1142 value
<< ISPSBL_SDR_REQ_PRV_EXP_SHIFT
);
1146 * omap3isp_preview_busy - Gets busy state of preview module.
1148 int omap3isp_preview_busy(struct isp_prev_device
*prev
)
1150 struct isp_device
*isp
= to_isp_device(prev
);
1152 return isp_reg_readl(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
)
1157 * omap3isp_preview_restore_context - Restores the values of preview registers
1159 void omap3isp_preview_restore_context(struct isp_device
*isp
)
1161 isp
->isp_prev
.update
= PREV_FEATURES_END
- 1;
1162 preview_setup_hw(&isp
->isp_prev
);
1166 * preview_print_status - Dump preview module registers to the kernel log
1168 #define PREV_PRINT_REGISTER(isp, name)\
1169 dev_dbg(isp->dev, "###PRV " #name "=0x%08x\n", \
1170 isp_reg_readl(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_##name))
1172 static void preview_print_status(struct isp_prev_device
*prev
)
1174 struct isp_device
*isp
= to_isp_device(prev
);
1176 dev_dbg(isp
->dev
, "-------------Preview Register dump----------\n");
1178 PREV_PRINT_REGISTER(isp
, PCR
);
1179 PREV_PRINT_REGISTER(isp
, HORZ_INFO
);
1180 PREV_PRINT_REGISTER(isp
, VERT_INFO
);
1181 PREV_PRINT_REGISTER(isp
, RSDR_ADDR
);
1182 PREV_PRINT_REGISTER(isp
, RADR_OFFSET
);
1183 PREV_PRINT_REGISTER(isp
, DSDR_ADDR
);
1184 PREV_PRINT_REGISTER(isp
, DRKF_OFFSET
);
1185 PREV_PRINT_REGISTER(isp
, WSDR_ADDR
);
1186 PREV_PRINT_REGISTER(isp
, WADD_OFFSET
);
1187 PREV_PRINT_REGISTER(isp
, AVE
);
1188 PREV_PRINT_REGISTER(isp
, HMED
);
1189 PREV_PRINT_REGISTER(isp
, NF
);
1190 PREV_PRINT_REGISTER(isp
, WB_DGAIN
);
1191 PREV_PRINT_REGISTER(isp
, WBGAIN
);
1192 PREV_PRINT_REGISTER(isp
, WBSEL
);
1193 PREV_PRINT_REGISTER(isp
, CFA
);
1194 PREV_PRINT_REGISTER(isp
, BLKADJOFF
);
1195 PREV_PRINT_REGISTER(isp
, RGB_MAT1
);
1196 PREV_PRINT_REGISTER(isp
, RGB_MAT2
);
1197 PREV_PRINT_REGISTER(isp
, RGB_MAT3
);
1198 PREV_PRINT_REGISTER(isp
, RGB_MAT4
);
1199 PREV_PRINT_REGISTER(isp
, RGB_MAT5
);
1200 PREV_PRINT_REGISTER(isp
, RGB_OFF1
);
1201 PREV_PRINT_REGISTER(isp
, RGB_OFF2
);
1202 PREV_PRINT_REGISTER(isp
, CSC0
);
1203 PREV_PRINT_REGISTER(isp
, CSC1
);
1204 PREV_PRINT_REGISTER(isp
, CSC2
);
1205 PREV_PRINT_REGISTER(isp
, CSC_OFFSET
);
1206 PREV_PRINT_REGISTER(isp
, CNT_BRT
);
1207 PREV_PRINT_REGISTER(isp
, CSUP
);
1208 PREV_PRINT_REGISTER(isp
, SETUP_YC
);
1209 PREV_PRINT_REGISTER(isp
, SET_TBL_ADDR
);
1210 PREV_PRINT_REGISTER(isp
, CDC_THR0
);
1211 PREV_PRINT_REGISTER(isp
, CDC_THR1
);
1212 PREV_PRINT_REGISTER(isp
, CDC_THR2
);
1213 PREV_PRINT_REGISTER(isp
, CDC_THR3
);
1215 dev_dbg(isp
->dev
, "--------------------------------------------\n");
1219 * preview_init_params - init image processing parameters.
1220 * @prev: pointer to previewer private structure
1223 static void preview_init_params(struct isp_prev_device
*prev
)
1225 struct prev_params
*params
= &prev
->params
;
1229 params
->contrast
= ISPPRV_CONTRAST_DEF
* ISPPRV_CONTRAST_UNITS
;
1230 params
->brightness
= ISPPRV_BRIGHT_DEF
* ISPPRV_BRIGHT_UNITS
;
1231 params
->average
= NO_AVE
;
1232 params
->cfa
.format
= OMAP3ISP_CFAFMT_BAYER
;
1233 memcpy(params
->cfa
.table
, cfa_coef_table
,
1234 sizeof(params
->cfa
.table
));
1235 params
->cfa
.gradthrs_horz
= FLR_CFA_GRADTHRS_HORZ
;
1236 params
->cfa
.gradthrs_vert
= FLR_CFA_GRADTHRS_VERT
;
1237 params
->csup
.gain
= FLR_CSUP_GAIN
;
1238 params
->csup
.thres
= FLR_CSUP_THRES
;
1239 params
->csup
.hypf_en
= 0;
1240 memcpy(params
->luma
.table
, luma_enhance_table
,
1241 sizeof(params
->luma
.table
));
1242 params
->nf
.spread
= FLR_NF_STRGTH
;
1243 memcpy(params
->nf
.table
, noise_filter_table
, sizeof(params
->nf
.table
));
1244 params
->dcor
.couplet_mode_en
= 1;
1245 for (i
= 0; i
< OMAP3ISP_PREV_DETECT_CORRECT_CHANNELS
; i
++)
1246 params
->dcor
.detect_correct
[i
] = DEF_DETECT_CORRECT_VAL
;
1247 memcpy(params
->gamma
.blue
, gamma_table
, sizeof(params
->gamma
.blue
));
1248 memcpy(params
->gamma
.green
, gamma_table
, sizeof(params
->gamma
.green
));
1249 memcpy(params
->gamma
.red
, gamma_table
, sizeof(params
->gamma
.red
));
1250 params
->wbal
.dgain
= FLR_WBAL_DGAIN
;
1251 params
->wbal
.coef0
= FLR_WBAL_COEF
;
1252 params
->wbal
.coef1
= FLR_WBAL_COEF
;
1253 params
->wbal
.coef2
= FLR_WBAL_COEF
;
1254 params
->wbal
.coef3
= FLR_WBAL_COEF
;
1255 params
->blk_adj
.red
= FLR_BLKADJ_RED
;
1256 params
->blk_adj
.green
= FLR_BLKADJ_GREEN
;
1257 params
->blk_adj
.blue
= FLR_BLKADJ_BLUE
;
1258 params
->rgb2rgb
= flr_rgb2rgb
;
1259 params
->rgb2ycbcr
= flr_prev_csc
;
1260 params
->yclimit
.minC
= ISPPRV_YC_MIN
;
1261 params
->yclimit
.maxC
= ISPPRV_YC_MAX
;
1262 params
->yclimit
.minY
= ISPPRV_YC_MIN
;
1263 params
->yclimit
.maxY
= ISPPRV_YC_MAX
;
1265 params
->features
= PREV_CFA
| PREV_DEFECT_COR
| PREV_NOISE_FILTER
1266 | PREV_GAMMA
| PREV_BLKADJ
| PREV_YCLIMITS
1267 | PREV_RGB2RGB
| PREV_COLOR_CONV
| PREV_WB
1268 | PREV_BRIGHTNESS
| PREV_CONTRAST
;
1270 prev
->update
= PREV_FEATURES_END
- 1;
1274 * preview_max_out_width - Handle previewer hardware ouput limitations
1275 * @isp_revision : ISP revision
1276 * returns maximum width output for current isp revision
1278 static unsigned int preview_max_out_width(struct isp_prev_device
*prev
)
1280 struct isp_device
*isp
= to_isp_device(prev
);
1282 switch (isp
->revision
) {
1283 case ISP_REVISION_1_0
:
1284 return ISPPRV_MAXOUTPUT_WIDTH
;
1286 case ISP_REVISION_2_0
:
1288 return ISPPRV_MAXOUTPUT_WIDTH_ES2
;
1290 case ISP_REVISION_15_0
:
1291 return ISPPRV_MAXOUTPUT_WIDTH_3630
;
1295 static void preview_configure(struct isp_prev_device
*prev
)
1297 struct isp_device
*isp
= to_isp_device(prev
);
1298 struct v4l2_mbus_framefmt
*format
;
1299 unsigned int max_out_width
;
1300 unsigned int format_avg
;
1302 preview_setup_hw(prev
);
1304 if (prev
->output
& PREVIEW_OUTPUT_MEMORY
)
1305 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1306 ISPPRV_PCR_SDRPORT
);
1308 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1309 ISPPRV_PCR_SDRPORT
);
1311 if (prev
->output
& PREVIEW_OUTPUT_RESIZER
)
1312 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1313 ISPPRV_PCR_RSZPORT
);
1315 isp_reg_clr(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1316 ISPPRV_PCR_RSZPORT
);
1319 format
= &prev
->formats
[PREV_PAD_SINK
];
1321 preview_adjust_bandwidth(prev
);
1323 preview_config_input_size(prev
);
1325 if (prev
->input
== PREVIEW_INPUT_CCDC
)
1326 preview_config_inlineoffset(prev
, 0);
1328 preview_config_inlineoffset(prev
,
1329 ALIGN(format
->width
, 0x20) * 2);
1331 /* PREV_PAD_SOURCE */
1332 format
= &prev
->formats
[PREV_PAD_SOURCE
];
1334 if (prev
->output
& PREVIEW_OUTPUT_MEMORY
)
1335 preview_config_outlineoffset(prev
,
1336 ALIGN(format
->width
, 0x10) * 2);
1338 max_out_width
= preview_max_out_width(prev
);
1340 format_avg
= fls(DIV_ROUND_UP(format
->width
, max_out_width
) - 1);
1341 preview_config_averager(prev
, format_avg
);
1342 preview_config_ycpos(prev
, format
->code
);
1345 /* -----------------------------------------------------------------------------
1346 * Interrupt handling
1349 static void preview_enable_oneshot(struct isp_prev_device
*prev
)
1351 struct isp_device
*isp
= to_isp_device(prev
);
1353 /* The PCR.SOURCE bit is automatically reset to 0 when the PCR.ENABLE
1354 * bit is set. As the preview engine is used in single-shot mode, we
1355 * need to set PCR.SOURCE before enabling the preview engine.
1357 if (prev
->input
== PREVIEW_INPUT_MEMORY
)
1358 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1361 isp_reg_set(isp
, OMAP3_ISP_IOMEM_PREV
, ISPPRV_PCR
,
1362 ISPPRV_PCR_EN
| ISPPRV_PCR_ONESHOT
);
1365 void omap3isp_preview_isr_frame_sync(struct isp_prev_device
*prev
)
1368 * If ISP_VIDEO_DMAQUEUE_QUEUED is set, DMA queue had an underrun
1369 * condition, the module was paused and now we have a buffer queued
1370 * on the output again. Restart the pipeline if running in continuous
1373 if (prev
->state
== ISP_PIPELINE_STREAM_CONTINUOUS
&&
1374 prev
->video_out
.dmaqueue_flags
& ISP_VIDEO_DMAQUEUE_QUEUED
) {
1375 preview_enable_oneshot(prev
);
1376 isp_video_dmaqueue_flags_clr(&prev
->video_out
);
1380 static void preview_isr_buffer(struct isp_prev_device
*prev
)
1382 struct isp_pipeline
*pipe
= to_isp_pipeline(&prev
->subdev
.entity
);
1383 struct isp_buffer
*buffer
;
1386 if (prev
->input
== PREVIEW_INPUT_MEMORY
) {
1387 buffer
= omap3isp_video_buffer_next(&prev
->video_in
,
1390 preview_set_inaddr(prev
, buffer
->isp_addr
);
1391 pipe
->state
|= ISP_PIPELINE_IDLE_INPUT
;
1394 if (prev
->output
& PREVIEW_OUTPUT_MEMORY
) {
1395 buffer
= omap3isp_video_buffer_next(&prev
->video_out
,
1397 if (buffer
!= NULL
) {
1398 preview_set_outaddr(prev
, buffer
->isp_addr
);
1401 pipe
->state
|= ISP_PIPELINE_IDLE_OUTPUT
;
1404 switch (prev
->state
) {
1405 case ISP_PIPELINE_STREAM_SINGLESHOT
:
1406 if (isp_pipeline_ready(pipe
))
1407 omap3isp_pipeline_set_stream(pipe
,
1408 ISP_PIPELINE_STREAM_SINGLESHOT
);
1411 case ISP_PIPELINE_STREAM_CONTINUOUS
:
1412 /* If an underrun occurs, the video queue operation handler will
1413 * restart the preview engine. Otherwise restart it immediately.
1416 preview_enable_oneshot(prev
);
1419 case ISP_PIPELINE_STREAM_STOPPED
:
1428 * omap3isp_preview_isr - ISP preview engine interrupt handler
1430 * Manage the preview engine video buffers and configure shadowed registers.
1432 void omap3isp_preview_isr(struct isp_prev_device
*prev
)
1434 unsigned long flags
;
1436 if (omap3isp_module_sync_is_stopping(&prev
->wait
, &prev
->stopping
))
1439 spin_lock_irqsave(&prev
->lock
, flags
);
1440 if (prev
->shadow_update
)
1443 preview_setup_hw(prev
);
1444 preview_config_input_size(prev
);
1447 spin_unlock_irqrestore(&prev
->lock
, flags
);
1449 if (prev
->input
== PREVIEW_INPUT_MEMORY
||
1450 prev
->output
& PREVIEW_OUTPUT_MEMORY
)
1451 preview_isr_buffer(prev
);
1452 else if (prev
->state
== ISP_PIPELINE_STREAM_CONTINUOUS
)
1453 preview_enable_oneshot(prev
);
1456 /* -----------------------------------------------------------------------------
1457 * ISP video operations
1460 static int preview_video_queue(struct isp_video
*video
,
1461 struct isp_buffer
*buffer
)
1463 struct isp_prev_device
*prev
= &video
->isp
->isp_prev
;
1465 if (video
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT
)
1466 preview_set_inaddr(prev
, buffer
->isp_addr
);
1468 if (video
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1469 preview_set_outaddr(prev
, buffer
->isp_addr
);
1474 static const struct isp_video_operations preview_video_ops
= {
1475 .queue
= preview_video_queue
,
1478 /* -----------------------------------------------------------------------------
1479 * V4L2 subdev operations
1483 * preview_s_ctrl - Handle set control subdev method
1484 * @ctrl: pointer to v4l2 control structure
1486 static int preview_s_ctrl(struct v4l2_ctrl
*ctrl
)
1488 struct isp_prev_device
*prev
=
1489 container_of(ctrl
->handler
, struct isp_prev_device
, ctrls
);
1492 case V4L2_CID_BRIGHTNESS
:
1493 preview_update_brightness(prev
, ctrl
->val
);
1495 case V4L2_CID_CONTRAST
:
1496 preview_update_contrast(prev
, ctrl
->val
);
1503 static const struct v4l2_ctrl_ops preview_ctrl_ops
= {
1504 .s_ctrl
= preview_s_ctrl
,
1508 * preview_ioctl - Handle preview module private ioctl's
1509 * @prev: pointer to preview context structure
1510 * @cmd: configuration command
1511 * @arg: configuration argument
1512 * return -EINVAL or zero on success
1514 static long preview_ioctl(struct v4l2_subdev
*sd
, unsigned int cmd
, void *arg
)
1516 struct isp_prev_device
*prev
= v4l2_get_subdevdata(sd
);
1519 case VIDIOC_OMAP3ISP_PRV_CFG
:
1520 return preview_config(prev
, arg
);
1523 return -ENOIOCTLCMD
;
1528 * preview_set_stream - Enable/Disable streaming on preview subdev
1529 * @sd : pointer to v4l2 subdev structure
1530 * @enable: 1 == Enable, 0 == Disable
1531 * return -EINVAL or zero on success
1533 static int preview_set_stream(struct v4l2_subdev
*sd
, int enable
)
1535 struct isp_prev_device
*prev
= v4l2_get_subdevdata(sd
);
1536 struct isp_video
*video_out
= &prev
->video_out
;
1537 struct isp_device
*isp
= to_isp_device(prev
);
1538 struct device
*dev
= to_device(prev
);
1539 unsigned long flags
;
1541 if (prev
->state
== ISP_PIPELINE_STREAM_STOPPED
) {
1542 if (enable
== ISP_PIPELINE_STREAM_STOPPED
)
1545 omap3isp_subclk_enable(isp
, OMAP3_ISP_SUBCLK_PREVIEW
);
1546 preview_configure(prev
);
1547 atomic_set(&prev
->stopping
, 0);
1549 preview_print_status(prev
);
1553 case ISP_PIPELINE_STREAM_CONTINUOUS
:
1554 if (prev
->output
& PREVIEW_OUTPUT_MEMORY
)
1555 omap3isp_sbl_enable(isp
, OMAP3_ISP_SBL_PREVIEW_WRITE
);
1557 if (video_out
->dmaqueue_flags
& ISP_VIDEO_DMAQUEUE_QUEUED
||
1558 !(prev
->output
& PREVIEW_OUTPUT_MEMORY
))
1559 preview_enable_oneshot(prev
);
1561 isp_video_dmaqueue_flags_clr(video_out
);
1564 case ISP_PIPELINE_STREAM_SINGLESHOT
:
1565 if (prev
->input
== PREVIEW_INPUT_MEMORY
)
1566 omap3isp_sbl_enable(isp
, OMAP3_ISP_SBL_PREVIEW_READ
);
1567 if (prev
->output
& PREVIEW_OUTPUT_MEMORY
)
1568 omap3isp_sbl_enable(isp
, OMAP3_ISP_SBL_PREVIEW_WRITE
);
1570 preview_enable_oneshot(prev
);
1573 case ISP_PIPELINE_STREAM_STOPPED
:
1574 if (omap3isp_module_sync_idle(&sd
->entity
, &prev
->wait
,
1576 dev_dbg(dev
, "%s: stop timeout.\n", sd
->name
);
1577 spin_lock_irqsave(&prev
->lock
, flags
);
1578 omap3isp_sbl_disable(isp
, OMAP3_ISP_SBL_PREVIEW_READ
);
1579 omap3isp_sbl_disable(isp
, OMAP3_ISP_SBL_PREVIEW_WRITE
);
1580 omap3isp_subclk_disable(isp
, OMAP3_ISP_SUBCLK_PREVIEW
);
1581 spin_unlock_irqrestore(&prev
->lock
, flags
);
1582 isp_video_dmaqueue_flags_clr(video_out
);
1586 prev
->state
= enable
;
1590 static struct v4l2_mbus_framefmt
*
1591 __preview_get_format(struct isp_prev_device
*prev
, struct v4l2_subdev_fh
*fh
,
1592 unsigned int pad
, enum v4l2_subdev_format_whence which
)
1594 if (which
== V4L2_SUBDEV_FORMAT_TRY
)
1595 return v4l2_subdev_get_try_format(fh
, pad
);
1597 return &prev
->formats
[pad
];
1600 /* previewer format descriptions */
1601 static const unsigned int preview_input_fmts
[] = {
1602 V4L2_MBUS_FMT_SGRBG10_1X10
,
1603 V4L2_MBUS_FMT_SRGGB10_1X10
,
1604 V4L2_MBUS_FMT_SBGGR10_1X10
,
1605 V4L2_MBUS_FMT_SGBRG10_1X10
,
1608 static const unsigned int preview_output_fmts
[] = {
1609 V4L2_MBUS_FMT_UYVY8_1X16
,
1610 V4L2_MBUS_FMT_YUYV8_1X16
,
1614 * preview_try_format - Handle try format by pad subdev method
1615 * @prev: ISP preview device
1616 * @fh : V4L2 subdev file handle
1618 * @fmt: pointer to v4l2 format structure
1620 static void preview_try_format(struct isp_prev_device
*prev
,
1621 struct v4l2_subdev_fh
*fh
, unsigned int pad
,
1622 struct v4l2_mbus_framefmt
*fmt
,
1623 enum v4l2_subdev_format_whence which
)
1625 struct v4l2_mbus_framefmt
*format
;
1626 unsigned int max_out_width
;
1627 enum v4l2_mbus_pixelcode pixelcode
;
1630 max_out_width
= preview_max_out_width(prev
);
1634 /* When reading data from the CCDC, the input size has already
1635 * been mangled by the CCDC output pad so it can be accepted
1638 * When reading data from memory, clamp the requested width and
1639 * height. The TRM doesn't specify a minimum input height, make
1640 * sure we got enough lines to enable the noise filter and color
1641 * filter array interpolation.
1643 if (prev
->input
== PREVIEW_INPUT_MEMORY
) {
1644 fmt
->width
= clamp_t(u32
, fmt
->width
, PREV_MIN_WIDTH
,
1646 fmt
->height
= clamp_t(u32
, fmt
->height
, PREV_MIN_HEIGHT
,
1650 fmt
->colorspace
= V4L2_COLORSPACE_SRGB
;
1652 for (i
= 0; i
< ARRAY_SIZE(preview_input_fmts
); i
++) {
1653 if (fmt
->code
== preview_input_fmts
[i
])
1657 /* If not found, use SGRBG10 as default */
1658 if (i
>= ARRAY_SIZE(preview_input_fmts
))
1659 fmt
->code
= V4L2_MBUS_FMT_SGRBG10_1X10
;
1662 case PREV_PAD_SOURCE
:
1663 pixelcode
= fmt
->code
;
1664 format
= __preview_get_format(prev
, fh
, PREV_PAD_SINK
, which
);
1665 memcpy(fmt
, format
, sizeof(*fmt
));
1667 /* The preview module output size is configurable through the
1668 * input interface (horizontal and vertical cropping) and the
1669 * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). In
1670 * spite of this, hardcode the output size to the biggest
1671 * possible value for simplicity reasons.
1673 switch (pixelcode
) {
1674 case V4L2_MBUS_FMT_YUYV8_1X16
:
1675 case V4L2_MBUS_FMT_UYVY8_1X16
:
1676 fmt
->code
= pixelcode
;
1680 fmt
->code
= V4L2_MBUS_FMT_YUYV8_1X16
;
1684 /* The TRM states (12.1.4.7.1.2) that 2 pixels must be cropped
1685 * from the left and right sides when the input source is the
1686 * CCDC. This seems not to be needed in practice, investigation
1689 if (prev
->input
== PREVIEW_INPUT_CCDC
)
1692 /* The preview module can output a maximum of 3312 pixels
1693 * horizontally due to fixed memory-line sizes. Compute the
1694 * horizontal averaging factor accordingly. Note that the limit
1695 * applies to the noise filter and CFA interpolation blocks, so
1696 * it doesn't take cropping by further blocks into account.
1698 * ES 1.0 hardware revision is limited to 1280 pixels
1701 fmt
->width
>>= fls(DIV_ROUND_UP(fmt
->width
, max_out_width
) - 1);
1703 /* Assume that all blocks are enabled and crop pixels and lines
1704 * accordingly. See preview_config_input_size() for more
1710 fmt
->colorspace
= V4L2_COLORSPACE_JPEG
;
1714 fmt
->field
= V4L2_FIELD_NONE
;
1718 * preview_enum_mbus_code - Handle pixel format enumeration
1719 * @sd : pointer to v4l2 subdev structure
1720 * @fh : V4L2 subdev file handle
1721 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1722 * return -EINVAL or zero on success
1724 static int preview_enum_mbus_code(struct v4l2_subdev
*sd
,
1725 struct v4l2_subdev_fh
*fh
,
1726 struct v4l2_subdev_mbus_code_enum
*code
)
1728 switch (code
->pad
) {
1730 if (code
->index
>= ARRAY_SIZE(preview_input_fmts
))
1733 code
->code
= preview_input_fmts
[code
->index
];
1735 case PREV_PAD_SOURCE
:
1736 if (code
->index
>= ARRAY_SIZE(preview_output_fmts
))
1739 code
->code
= preview_output_fmts
[code
->index
];
1748 static int preview_enum_frame_size(struct v4l2_subdev
*sd
,
1749 struct v4l2_subdev_fh
*fh
,
1750 struct v4l2_subdev_frame_size_enum
*fse
)
1752 struct isp_prev_device
*prev
= v4l2_get_subdevdata(sd
);
1753 struct v4l2_mbus_framefmt format
;
1755 if (fse
->index
!= 0)
1758 format
.code
= fse
->code
;
1761 preview_try_format(prev
, fh
, fse
->pad
, &format
, V4L2_SUBDEV_FORMAT_TRY
);
1762 fse
->min_width
= format
.width
;
1763 fse
->min_height
= format
.height
;
1765 if (format
.code
!= fse
->code
)
1768 format
.code
= fse
->code
;
1771 preview_try_format(prev
, fh
, fse
->pad
, &format
, V4L2_SUBDEV_FORMAT_TRY
);
1772 fse
->max_width
= format
.width
;
1773 fse
->max_height
= format
.height
;
1779 * preview_get_format - Handle get format by pads subdev method
1780 * @sd : pointer to v4l2 subdev structure
1781 * @fh : V4L2 subdev file handle
1782 * @fmt: pointer to v4l2 subdev format structure
1783 * return -EINVAL or zero on success
1785 static int preview_get_format(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
,
1786 struct v4l2_subdev_format
*fmt
)
1788 struct isp_prev_device
*prev
= v4l2_get_subdevdata(sd
);
1789 struct v4l2_mbus_framefmt
*format
;
1791 format
= __preview_get_format(prev
, fh
, fmt
->pad
, fmt
->which
);
1795 fmt
->format
= *format
;
1800 * preview_set_format - Handle set format by pads subdev method
1801 * @sd : pointer to v4l2 subdev structure
1802 * @fh : V4L2 subdev file handle
1803 * @fmt: pointer to v4l2 subdev format structure
1804 * return -EINVAL or zero on success
1806 static int preview_set_format(struct v4l2_subdev
*sd
, struct v4l2_subdev_fh
*fh
,
1807 struct v4l2_subdev_format
*fmt
)
1809 struct isp_prev_device
*prev
= v4l2_get_subdevdata(sd
);
1810 struct v4l2_mbus_framefmt
*format
;
1812 format
= __preview_get_format(prev
, fh
, fmt
->pad
, fmt
->which
);
1816 preview_try_format(prev
, fh
, fmt
->pad
, &fmt
->format
, fmt
->which
);
1817 *format
= fmt
->format
;
1819 /* Propagate the format from sink to source */
1820 if (fmt
->pad
== PREV_PAD_SINK
) {
1821 format
= __preview_get_format(prev
, fh
, PREV_PAD_SOURCE
,
1823 *format
= fmt
->format
;
1824 preview_try_format(prev
, fh
, PREV_PAD_SOURCE
, format
,
1832 * preview_init_formats - Initialize formats on all pads
1833 * @sd: ISP preview V4L2 subdevice
1834 * @fh: V4L2 subdev file handle
1836 * Initialize all pad formats with default values. If fh is not NULL, try
1837 * formats are initialized on the file handle. Otherwise active formats are
1838 * initialized on the device.
1840 static int preview_init_formats(struct v4l2_subdev
*sd
,
1841 struct v4l2_subdev_fh
*fh
)
1843 struct v4l2_subdev_format format
;
1845 memset(&format
, 0, sizeof(format
));
1846 format
.pad
= PREV_PAD_SINK
;
1847 format
.which
= fh
? V4L2_SUBDEV_FORMAT_TRY
: V4L2_SUBDEV_FORMAT_ACTIVE
;
1848 format
.format
.code
= V4L2_MBUS_FMT_SGRBG10_1X10
;
1849 format
.format
.width
= 4096;
1850 format
.format
.height
= 4096;
1851 preview_set_format(sd
, fh
, &format
);
1856 /* subdev core operations */
1857 static const struct v4l2_subdev_core_ops preview_v4l2_core_ops
= {
1858 .ioctl
= preview_ioctl
,
1861 /* subdev video operations */
1862 static const struct v4l2_subdev_video_ops preview_v4l2_video_ops
= {
1863 .s_stream
= preview_set_stream
,
1866 /* subdev pad operations */
1867 static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops
= {
1868 .enum_mbus_code
= preview_enum_mbus_code
,
1869 .enum_frame_size
= preview_enum_frame_size
,
1870 .get_fmt
= preview_get_format
,
1871 .set_fmt
= preview_set_format
,
1874 /* subdev operations */
1875 static const struct v4l2_subdev_ops preview_v4l2_ops
= {
1876 .core
= &preview_v4l2_core_ops
,
1877 .video
= &preview_v4l2_video_ops
,
1878 .pad
= &preview_v4l2_pad_ops
,
1881 /* subdev internal operations */
1882 static const struct v4l2_subdev_internal_ops preview_v4l2_internal_ops
= {
1883 .open
= preview_init_formats
,
1886 /* -----------------------------------------------------------------------------
1887 * Media entity operations
1891 * preview_link_setup - Setup previewer connections.
1892 * @entity : Pointer to media entity structure
1893 * @local : Pointer to local pad array
1894 * @remote : Pointer to remote pad array
1895 * @flags : Link flags
1896 * return -EINVAL or zero on success
1898 static int preview_link_setup(struct media_entity
*entity
,
1899 const struct media_pad
*local
,
1900 const struct media_pad
*remote
, u32 flags
)
1902 struct v4l2_subdev
*sd
= media_entity_to_v4l2_subdev(entity
);
1903 struct isp_prev_device
*prev
= v4l2_get_subdevdata(sd
);
1905 switch (local
->index
| media_entity_type(remote
->entity
)) {
1906 case PREV_PAD_SINK
| MEDIA_ENT_T_DEVNODE
:
1907 /* read from memory */
1908 if (flags
& MEDIA_LNK_FL_ENABLED
) {
1909 if (prev
->input
== PREVIEW_INPUT_CCDC
)
1911 prev
->input
= PREVIEW_INPUT_MEMORY
;
1913 if (prev
->input
== PREVIEW_INPUT_MEMORY
)
1914 prev
->input
= PREVIEW_INPUT_NONE
;
1918 case PREV_PAD_SINK
| MEDIA_ENT_T_V4L2_SUBDEV
:
1919 /* read from ccdc */
1920 if (flags
& MEDIA_LNK_FL_ENABLED
) {
1921 if (prev
->input
== PREVIEW_INPUT_MEMORY
)
1923 prev
->input
= PREVIEW_INPUT_CCDC
;
1925 if (prev
->input
== PREVIEW_INPUT_CCDC
)
1926 prev
->input
= PREVIEW_INPUT_NONE
;
1931 * The ISP core doesn't support pipelines with multiple video outputs.
1932 * Revisit this when it will be implemented, and return -EBUSY for now.
1935 case PREV_PAD_SOURCE
| MEDIA_ENT_T_DEVNODE
:
1936 /* write to memory */
1937 if (flags
& MEDIA_LNK_FL_ENABLED
) {
1938 if (prev
->output
& ~PREVIEW_OUTPUT_MEMORY
)
1940 prev
->output
|= PREVIEW_OUTPUT_MEMORY
;
1942 prev
->output
&= ~PREVIEW_OUTPUT_MEMORY
;
1946 case PREV_PAD_SOURCE
| MEDIA_ENT_T_V4L2_SUBDEV
:
1947 /* write to resizer */
1948 if (flags
& MEDIA_LNK_FL_ENABLED
) {
1949 if (prev
->output
& ~PREVIEW_OUTPUT_RESIZER
)
1951 prev
->output
|= PREVIEW_OUTPUT_RESIZER
;
1953 prev
->output
&= ~PREVIEW_OUTPUT_RESIZER
;
1964 /* media operations */
1965 static const struct media_entity_operations preview_media_ops
= {
1966 .link_setup
= preview_link_setup
,
1970 * review_init_entities - Initialize subdev and media entity.
1971 * @prev : Pointer to preview structure
1972 * return -ENOMEM or zero on success
1974 static int preview_init_entities(struct isp_prev_device
*prev
)
1976 struct v4l2_subdev
*sd
= &prev
->subdev
;
1977 struct media_pad
*pads
= prev
->pads
;
1978 struct media_entity
*me
= &sd
->entity
;
1981 prev
->input
= PREVIEW_INPUT_NONE
;
1983 v4l2_subdev_init(sd
, &preview_v4l2_ops
);
1984 sd
->internal_ops
= &preview_v4l2_internal_ops
;
1985 strlcpy(sd
->name
, "OMAP3 ISP preview", sizeof(sd
->name
));
1986 sd
->grp_id
= 1 << 16; /* group ID for isp subdevs */
1987 v4l2_set_subdevdata(sd
, prev
);
1988 sd
->flags
|= V4L2_SUBDEV_FL_HAS_DEVNODE
;
1990 v4l2_ctrl_handler_init(&prev
->ctrls
, 2);
1991 v4l2_ctrl_new_std(&prev
->ctrls
, &preview_ctrl_ops
, V4L2_CID_BRIGHTNESS
,
1992 ISPPRV_BRIGHT_LOW
, ISPPRV_BRIGHT_HIGH
,
1993 ISPPRV_BRIGHT_STEP
, ISPPRV_BRIGHT_DEF
);
1994 v4l2_ctrl_new_std(&prev
->ctrls
, &preview_ctrl_ops
, V4L2_CID_CONTRAST
,
1995 ISPPRV_CONTRAST_LOW
, ISPPRV_CONTRAST_HIGH
,
1996 ISPPRV_CONTRAST_STEP
, ISPPRV_CONTRAST_DEF
);
1997 v4l2_ctrl_handler_setup(&prev
->ctrls
);
1998 sd
->ctrl_handler
= &prev
->ctrls
;
2000 pads
[PREV_PAD_SINK
].flags
= MEDIA_PAD_FL_SINK
;
2001 pads
[PREV_PAD_SOURCE
].flags
= MEDIA_PAD_FL_SOURCE
;
2003 me
->ops
= &preview_media_ops
;
2004 ret
= media_entity_init(me
, PREV_PADS_NUM
, pads
, 0);
2008 preview_init_formats(sd
, NULL
);
2010 /* According to the OMAP34xx TRM, video buffers need to be aligned on a
2011 * 32 bytes boundary. However, an undocumented hardware bug requires a
2012 * 64 bytes boundary at the preview engine input.
2014 prev
->video_in
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT
;
2015 prev
->video_in
.ops
= &preview_video_ops
;
2016 prev
->video_in
.isp
= to_isp_device(prev
);
2017 prev
->video_in
.capture_mem
= PAGE_ALIGN(4096 * 4096) * 2 * 3;
2018 prev
->video_in
.bpl_alignment
= 64;
2019 prev
->video_out
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
2020 prev
->video_out
.ops
= &preview_video_ops
;
2021 prev
->video_out
.isp
= to_isp_device(prev
);
2022 prev
->video_out
.capture_mem
= PAGE_ALIGN(4096 * 4096) * 2 * 3;
2023 prev
->video_out
.bpl_alignment
= 32;
2025 ret
= omap3isp_video_init(&prev
->video_in
, "preview");
2029 ret
= omap3isp_video_init(&prev
->video_out
, "preview");
2033 /* Connect the video nodes to the previewer subdev. */
2034 ret
= media_entity_create_link(&prev
->video_in
.video
.entity
, 0,
2035 &prev
->subdev
.entity
, PREV_PAD_SINK
, 0);
2039 ret
= media_entity_create_link(&prev
->subdev
.entity
, PREV_PAD_SOURCE
,
2040 &prev
->video_out
.video
.entity
, 0, 0);
2047 void omap3isp_preview_unregister_entities(struct isp_prev_device
*prev
)
2049 media_entity_cleanup(&prev
->subdev
.entity
);
2051 v4l2_device_unregister_subdev(&prev
->subdev
);
2052 v4l2_ctrl_handler_free(&prev
->ctrls
);
2053 omap3isp_video_unregister(&prev
->video_in
);
2054 omap3isp_video_unregister(&prev
->video_out
);
2057 int omap3isp_preview_register_entities(struct isp_prev_device
*prev
,
2058 struct v4l2_device
*vdev
)
2062 /* Register the subdev and video nodes. */
2063 ret
= v4l2_device_register_subdev(vdev
, &prev
->subdev
);
2067 ret
= omap3isp_video_register(&prev
->video_in
, vdev
);
2071 ret
= omap3isp_video_register(&prev
->video_out
, vdev
);
2078 omap3isp_preview_unregister_entities(prev
);
2082 /* -----------------------------------------------------------------------------
2083 * ISP previewer initialisation and cleanup
2086 void omap3isp_preview_cleanup(struct isp_device
*isp
)
2091 * isp_preview_init - Previewer initialization.
2092 * @dev : Pointer to ISP device
2093 * return -ENOMEM or zero on success
2095 int omap3isp_preview_init(struct isp_device
*isp
)
2097 struct isp_prev_device
*prev
= &isp
->isp_prev
;
2100 spin_lock_init(&prev
->lock
);
2101 init_waitqueue_head(&prev
->wait
);
2102 preview_init_params(prev
);
2104 ret
= preview_init_entities(prev
);
2110 omap3isp_preview_cleanup(isp
);