diff options
-rw-r--r-- | drivers/media/video/davinci/dm355_ccdc.c | 978 | ||||
-rw-r--r-- | drivers/media/video/davinci/dm355_ccdc_regs.h | 310 | ||||
-rw-r--r-- | include/media/davinci/dm355_ccdc.h | 321 |
3 files changed, 1609 insertions, 0 deletions
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c new file mode 100644 index 000000000000..4629cabe3f28 --- /dev/null +++ b/drivers/media/video/davinci/dm355_ccdc.c | |||
@@ -0,0 +1,978 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005-2009 Texas Instruments Inc | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | * | ||
18 | * CCDC hardware module for DM355 | ||
19 | * ------------------------------ | ||
20 | * | ||
21 | * This module is for configuring DM355 CCD controller of VPFE to capture | ||
22 | * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules | ||
23 | * such as Defect Pixel Correction, Color Space Conversion etc to | ||
24 | * pre-process the Bayer RGB data, before writing it to SDRAM. This | ||
25 | * module also allows application to configure individual | ||
26 | * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL. | ||
27 | * To do so, application include dm355_ccdc.h and vpfe_capture.h header | ||
28 | * files. The setparams() API is called by vpfe_capture driver | ||
29 | * to configure module parameters | ||
30 | * | ||
31 | * TODO: 1) Raw bayer parameter settings and bayer capture | ||
32 | * 2) Split module parameter structure to module specific ioctl structs | ||
33 | * 3) add support for lense shading correction | ||
34 | * 4) investigate if enum used for user space type definition | ||
35 | * to be replaced by #defines or integer | ||
36 | */ | ||
37 | #include <linux/platform_device.h> | ||
38 | #include <linux/uaccess.h> | ||
39 | #include <linux/videodev2.h> | ||
40 | #include <media/davinci/dm355_ccdc.h> | ||
41 | #include <media/davinci/vpss.h> | ||
42 | #include "dm355_ccdc_regs.h" | ||
43 | #include "ccdc_hw_device.h" | ||
44 | |||
45 | MODULE_LICENSE("GPL"); | ||
46 | MODULE_DESCRIPTION("CCDC Driver for DM355"); | ||
47 | MODULE_AUTHOR("Texas Instruments"); | ||
48 | |||
49 | static struct device *dev; | ||
50 | |||
51 | /* Object for CCDC raw mode */ | ||
52 | static struct ccdc_params_raw ccdc_hw_params_raw = { | ||
53 | .pix_fmt = CCDC_PIXFMT_RAW, | ||
54 | .frm_fmt = CCDC_FRMFMT_PROGRESSIVE, | ||
55 | .win = CCDC_WIN_VGA, | ||
56 | .fid_pol = VPFE_PINPOL_POSITIVE, | ||
57 | .vd_pol = VPFE_PINPOL_POSITIVE, | ||
58 | .hd_pol = VPFE_PINPOL_POSITIVE, | ||
59 | .gain = { | ||
60 | .r_ye = 256, | ||
61 | .gb_g = 256, | ||
62 | .gr_cy = 256, | ||
63 | .b_mg = 256 | ||
64 | }, | ||
65 | .config_params = { | ||
66 | .datasft = 2, | ||
67 | .data_sz = CCDC_DATA_10BITS, | ||
68 | .mfilt1 = CCDC_NO_MEDIAN_FILTER1, | ||
69 | .mfilt2 = CCDC_NO_MEDIAN_FILTER2, | ||
70 | .alaw = { | ||
71 | .gama_wd = 2, | ||
72 | }, | ||
73 | .blk_clamp = { | ||
74 | .sample_pixel = 1, | ||
75 | .dc_sub = 25 | ||
76 | }, | ||
77 | .col_pat_field0 = { | ||
78 | .olop = CCDC_GREEN_BLUE, | ||
79 | .olep = CCDC_BLUE, | ||
80 | .elop = CCDC_RED, | ||
81 | .elep = CCDC_GREEN_RED | ||
82 | }, | ||
83 | .col_pat_field1 = { | ||
84 | .olop = CCDC_GREEN_BLUE, | ||
85 | .olep = CCDC_BLUE, | ||
86 | .elop = CCDC_RED, | ||
87 | .elep = CCDC_GREEN_RED | ||
88 | }, | ||
89 | }, | ||
90 | }; | ||
91 | |||
92 | |||
93 | /* Object for CCDC ycbcr mode */ | ||
94 | static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = { | ||
95 | .win = CCDC_WIN_PAL, | ||
96 | .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT, | ||
97 | .frm_fmt = CCDC_FRMFMT_INTERLACED, | ||
98 | .fid_pol = VPFE_PINPOL_POSITIVE, | ||
99 | .vd_pol = VPFE_PINPOL_POSITIVE, | ||
100 | .hd_pol = VPFE_PINPOL_POSITIVE, | ||
101 | .bt656_enable = 1, | ||
102 | .pix_order = CCDC_PIXORDER_CBYCRY, | ||
103 | .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED | ||
104 | }; | ||
105 | |||
106 | static enum vpfe_hw_if_type ccdc_if_type; | ||
107 | static void *__iomem ccdc_base_addr; | ||
108 | static int ccdc_addr_size; | ||
109 | |||
110 | /* Raw Bayer formats */ | ||
111 | static u32 ccdc_raw_bayer_pix_formats[] = | ||
112 | {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16}; | ||
113 | |||
114 | /* Raw YUV formats */ | ||
115 | static u32 ccdc_raw_yuv_pix_formats[] = | ||
116 | {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV}; | ||
117 | |||
118 | /* register access routines */ | ||
119 | static inline u32 regr(u32 offset) | ||
120 | { | ||
121 | return __raw_readl(ccdc_base_addr + offset); | ||
122 | } | ||
123 | |||
124 | static inline void regw(u32 val, u32 offset) | ||
125 | { | ||
126 | __raw_writel(val, ccdc_base_addr + offset); | ||
127 | } | ||
128 | |||
129 | static void ccdc_set_ccdc_base(void *addr, int size) | ||
130 | { | ||
131 | ccdc_base_addr = addr; | ||
132 | ccdc_addr_size = size; | ||
133 | } | ||
134 | |||
135 | static void ccdc_enable(int en) | ||
136 | { | ||
137 | unsigned int temp; | ||
138 | temp = regr(SYNCEN); | ||
139 | temp &= (~CCDC_SYNCEN_VDHDEN_MASK); | ||
140 | temp |= (en & CCDC_SYNCEN_VDHDEN_MASK); | ||
141 | regw(temp, SYNCEN); | ||
142 | } | ||
143 | |||
144 | static void ccdc_enable_output_to_sdram(int en) | ||
145 | { | ||
146 | unsigned int temp; | ||
147 | temp = regr(SYNCEN); | ||
148 | temp &= (~(CCDC_SYNCEN_WEN_MASK)); | ||
149 | temp |= ((en << CCDC_SYNCEN_WEN_SHIFT) & CCDC_SYNCEN_WEN_MASK); | ||
150 | regw(temp, SYNCEN); | ||
151 | } | ||
152 | |||
153 | static void ccdc_config_gain_offset(void) | ||
154 | { | ||
155 | /* configure gain */ | ||
156 | regw(ccdc_hw_params_raw.gain.r_ye, RYEGAIN); | ||
157 | regw(ccdc_hw_params_raw.gain.gr_cy, GRCYGAIN); | ||
158 | regw(ccdc_hw_params_raw.gain.gb_g, GBGGAIN); | ||
159 | regw(ccdc_hw_params_raw.gain.b_mg, BMGGAIN); | ||
160 | /* configure offset */ | ||
161 | regw(ccdc_hw_params_raw.ccdc_offset, OFFSET); | ||
162 | } | ||
163 | |||
164 | /* | ||
165 | * ccdc_restore_defaults() | ||
166 | * This function restore power on defaults in the ccdc registers | ||
167 | */ | ||
168 | static int ccdc_restore_defaults(void) | ||
169 | { | ||
170 | int i; | ||
171 | |||
172 | dev_dbg(dev, "\nstarting ccdc_restore_defaults..."); | ||
173 | /* set all registers to zero */ | ||
174 | for (i = 0; i <= CCDC_REG_LAST; i += 4) | ||
175 | regw(0, i); | ||
176 | |||
177 | /* now override the values with power on defaults in registers */ | ||
178 | regw(MODESET_DEFAULT, MODESET); | ||
179 | /* no culling support */ | ||
180 | regw(CULH_DEFAULT, CULH); | ||
181 | regw(CULV_DEFAULT, CULV); | ||
182 | /* Set default Gain and Offset */ | ||
183 | ccdc_hw_params_raw.gain.r_ye = GAIN_DEFAULT; | ||
184 | ccdc_hw_params_raw.gain.gb_g = GAIN_DEFAULT; | ||
185 | ccdc_hw_params_raw.gain.gr_cy = GAIN_DEFAULT; | ||
186 | ccdc_hw_params_raw.gain.b_mg = GAIN_DEFAULT; | ||
187 | ccdc_config_gain_offset(); | ||
188 | regw(OUTCLIP_DEFAULT, OUTCLIP); | ||
189 | regw(LSCCFG2_DEFAULT, LSCCFG2); | ||
190 | /* select ccdc input */ | ||
191 | if (vpss_select_ccdc_source(VPSS_CCDCIN)) { | ||
192 | dev_dbg(dev, "\ncouldn't select ccdc input source"); | ||
193 | return -EFAULT; | ||
194 | } | ||
195 | /* select ccdc clock */ | ||
196 | if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) { | ||
197 | dev_dbg(dev, "\ncouldn't enable ccdc clock"); | ||
198 | return -EFAULT; | ||
199 | } | ||
200 | dev_dbg(dev, "\nEnd of ccdc_restore_defaults..."); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int ccdc_open(struct device *device) | ||
205 | { | ||
206 | dev = device; | ||
207 | return ccdc_restore_defaults(); | ||
208 | } | ||
209 | |||
210 | static int ccdc_close(struct device *device) | ||
211 | { | ||
212 | /* disable clock */ | ||
213 | vpss_enable_clock(VPSS_CCDC_CLOCK, 0); | ||
214 | /* do nothing for now */ | ||
215 | return 0; | ||
216 | } | ||
217 | /* | ||
218 | * ccdc_setwin() | ||
219 | * This function will configure the window size to | ||
220 | * be capture in CCDC reg. | ||
221 | */ | ||
222 | static void ccdc_setwin(struct v4l2_rect *image_win, | ||
223 | enum ccdc_frmfmt frm_fmt, int ppc) | ||
224 | { | ||
225 | int horz_start, horz_nr_pixels; | ||
226 | int vert_start, vert_nr_lines; | ||
227 | int mid_img = 0; | ||
228 | |||
229 | dev_dbg(dev, "\nStarting ccdc_setwin..."); | ||
230 | |||
231 | /* | ||
232 | * ppc - per pixel count. indicates how many pixels per cell | ||
233 | * output to SDRAM. example, for ycbcr, it is one y and one c, so 2. | ||
234 | * raw capture this is 1 | ||
235 | */ | ||
236 | horz_start = image_win->left << (ppc - 1); | ||
237 | horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1; | ||
238 | |||
239 | /* Writing the horizontal info into the registers */ | ||
240 | regw(horz_start, SPH); | ||
241 | regw(horz_nr_pixels, NPH); | ||
242 | vert_start = image_win->top; | ||
243 | |||
244 | if (frm_fmt == CCDC_FRMFMT_INTERLACED) { | ||
245 | vert_nr_lines = (image_win->height >> 1) - 1; | ||
246 | vert_start >>= 1; | ||
247 | /* Since first line doesn't have any data */ | ||
248 | vert_start += 1; | ||
249 | /* configure VDINT0 and VDINT1 */ | ||
250 | regw(vert_start, VDINT0); | ||
251 | } else { | ||
252 | /* Since first line doesn't have any data */ | ||
253 | vert_start += 1; | ||
254 | vert_nr_lines = image_win->height - 1; | ||
255 | /* configure VDINT0 and VDINT1 */ | ||
256 | mid_img = vert_start + (image_win->height / 2); | ||
257 | regw(vert_start, VDINT0); | ||
258 | regw(mid_img, VDINT1); | ||
259 | } | ||
260 | regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0); | ||
261 | regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1); | ||
262 | regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV); | ||
263 | dev_dbg(dev, "\nEnd of ccdc_setwin..."); | ||
264 | } | ||
265 | |||
266 | static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) | ||
267 | { | ||
268 | if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT || | ||
269 | ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) { | ||
270 | dev_dbg(dev, "Invalid value of data shift\n"); | ||
271 | return -EINVAL; | ||
272 | } | ||
273 | |||
274 | if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 || | ||
275 | ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) { | ||
276 | dev_dbg(dev, "Invalid value of median filter1\n"); | ||
277 | return -EINVAL; | ||
278 | } | ||
279 | |||
280 | if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 || | ||
281 | ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) { | ||
282 | dev_dbg(dev, "Invalid value of median filter2\n"); | ||
283 | return -EINVAL; | ||
284 | } | ||
285 | |||
286 | if ((ccdcparam->med_filt_thres < 0) || | ||
287 | (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) { | ||
288 | dev_dbg(dev, "Invalid value of median filter thresold\n"); | ||
289 | return -EINVAL; | ||
290 | } | ||
291 | |||
292 | if (ccdcparam->data_sz < CCDC_DATA_16BITS || | ||
293 | ccdcparam->data_sz > CCDC_DATA_8BITS) { | ||
294 | dev_dbg(dev, "Invalid value of data size\n"); | ||
295 | return -EINVAL; | ||
296 | } | ||
297 | |||
298 | if (ccdcparam->alaw.enable) { | ||
299 | if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 || | ||
300 | ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) { | ||
301 | dev_dbg(dev, "Invalid value of ALAW\n"); | ||
302 | return -EINVAL; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | if (ccdcparam->blk_clamp.b_clamp_enable) { | ||
307 | if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS || | ||
308 | ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) { | ||
309 | dev_dbg(dev, "Invalid value of sample pixel\n"); | ||
310 | return -EINVAL; | ||
311 | } | ||
312 | if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES || | ||
313 | ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) { | ||
314 | dev_dbg(dev, "Invalid value of sample lines\n"); | ||
315 | return -EINVAL; | ||
316 | } | ||
317 | } | ||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | /* Parameter operations */ | ||
322 | static int ccdc_set_params(void __user *params) | ||
323 | { | ||
324 | struct ccdc_config_params_raw ccdc_raw_params; | ||
325 | int x; | ||
326 | |||
327 | /* only raw module parameters can be set through the IOCTL */ | ||
328 | if (ccdc_if_type != VPFE_RAW_BAYER) | ||
329 | return -EINVAL; | ||
330 | |||
331 | x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); | ||
332 | if (x) { | ||
333 | dev_dbg(dev, "ccdc_set_params: error in copying ccdc" | ||
334 | "params, %d\n", x); | ||
335 | return -EFAULT; | ||
336 | } | ||
337 | |||
338 | if (!validate_ccdc_param(&ccdc_raw_params)) { | ||
339 | memcpy(&ccdc_hw_params_raw.config_params, | ||
340 | &ccdc_raw_params, | ||
341 | sizeof(ccdc_raw_params)); | ||
342 | return 0; | ||
343 | } | ||
344 | return -EINVAL; | ||
345 | } | ||
346 | |||
347 | /* This function will configure CCDC for YCbCr video capture */ | ||
348 | static void ccdc_config_ycbcr(void) | ||
349 | { | ||
350 | struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr; | ||
351 | u32 temp; | ||
352 | |||
353 | /* first set the CCDC power on defaults values in all registers */ | ||
354 | dev_dbg(dev, "\nStarting ccdc_config_ycbcr..."); | ||
355 | ccdc_restore_defaults(); | ||
356 | |||
357 | /* configure pixel format & video frame format */ | ||
358 | temp = (((params->pix_fmt & CCDC_INPUT_MODE_MASK) << | ||
359 | CCDC_INPUT_MODE_SHIFT) | | ||
360 | ((params->frm_fmt & CCDC_FRM_FMT_MASK) << | ||
361 | CCDC_FRM_FMT_SHIFT)); | ||
362 | |||
363 | /* setup BT.656 sync mode */ | ||
364 | if (params->bt656_enable) { | ||
365 | regw(CCDC_REC656IF_BT656_EN, REC656IF); | ||
366 | /* | ||
367 | * configure the FID, VD, HD pin polarity fld,hd pol positive, | ||
368 | * vd negative, 8-bit pack mode | ||
369 | */ | ||
370 | temp |= CCDC_VD_POL_NEGATIVE; | ||
371 | } else { /* y/c external sync mode */ | ||
372 | temp |= (((params->fid_pol & CCDC_FID_POL_MASK) << | ||
373 | CCDC_FID_POL_SHIFT) | | ||
374 | ((params->hd_pol & CCDC_HD_POL_MASK) << | ||
375 | CCDC_HD_POL_SHIFT) | | ||
376 | ((params->vd_pol & CCDC_VD_POL_MASK) << | ||
377 | CCDC_VD_POL_SHIFT)); | ||
378 | } | ||
379 | |||
380 | /* pack the data to 8-bit */ | ||
381 | temp |= CCDC_DATA_PACK_ENABLE; | ||
382 | |||
383 | regw(temp, MODESET); | ||
384 | |||
385 | /* configure video window */ | ||
386 | ccdc_setwin(¶ms->win, params->frm_fmt, 2); | ||
387 | |||
388 | /* configure the order of y cb cr in SD-RAM */ | ||
389 | temp = (params->pix_order << CCDC_Y8POS_SHIFT); | ||
390 | temp |= CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC; | ||
391 | regw(temp, CCDCFG); | ||
392 | |||
393 | /* | ||
394 | * configure the horizontal line offset. This is done by rounding up | ||
395 | * width to a multiple of 16 pixels and multiply by two to account for | ||
396 | * y:cb:cr 4:2:2 data | ||
397 | */ | ||
398 | regw(((params->win.width * 2 + 31) >> 5), HSIZE); | ||
399 | |||
400 | /* configure the memory line offset */ | ||
401 | if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) { | ||
402 | /* two fields are interleaved in memory */ | ||
403 | regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST); | ||
404 | } | ||
405 | |||
406 | dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n"); | ||
407 | } | ||
408 | |||
409 | /* | ||
410 | * ccdc_config_black_clamp() | ||
411 | * configure parameters for Optical Black Clamp | ||
412 | */ | ||
413 | static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp) | ||
414 | { | ||
415 | u32 val; | ||
416 | |||
417 | if (!bclamp->b_clamp_enable) { | ||
418 | /* configure DCSub */ | ||
419 | regw(bclamp->dc_sub & CCDC_BLK_DC_SUB_MASK, DCSUB); | ||
420 | regw(0x0000, CLAMP); | ||
421 | return; | ||
422 | } | ||
423 | /* Enable the Black clamping, set sample lines and pixels */ | ||
424 | val = (bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) | | ||
425 | ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) << | ||
426 | CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE; | ||
427 | regw(val, CLAMP); | ||
428 | |||
429 | /* If Black clamping is enable then make dcsub 0 */ | ||
430 | val = (bclamp->sample_ln & CCDC_NUM_LINE_CALC_MASK) | ||
431 | << CCDC_NUM_LINE_CALC_SHIFT; | ||
432 | regw(val, DCSUB); | ||
433 | } | ||
434 | |||
435 | /* | ||
436 | * ccdc_config_black_compense() | ||
437 | * configure parameters for Black Compensation | ||
438 | */ | ||
439 | static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp) | ||
440 | { | ||
441 | u32 val; | ||
442 | |||
443 | val = (bcomp->b & CCDC_BLK_COMP_MASK) | | ||
444 | ((bcomp->gb & CCDC_BLK_COMP_MASK) << | ||
445 | CCDC_BLK_COMP_GB_COMP_SHIFT); | ||
446 | regw(val, BLKCMP1); | ||
447 | |||
448 | val = ((bcomp->gr & CCDC_BLK_COMP_MASK) << | ||
449 | CCDC_BLK_COMP_GR_COMP_SHIFT) | | ||
450 | ((bcomp->r & CCDC_BLK_COMP_MASK) << | ||
451 | CCDC_BLK_COMP_R_COMP_SHIFT); | ||
452 | regw(val, BLKCMP0); | ||
453 | } | ||
454 | |||
455 | /* | ||
456 | * ccdc_write_dfc_entry() | ||
457 | * write an entry in the dfc table. | ||
458 | */ | ||
459 | int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc) | ||
460 | { | ||
461 | /* TODO This is to be re-visited and adjusted */ | ||
462 | #define DFC_WRITE_WAIT_COUNT 1000 | ||
463 | u32 val, count = DFC_WRITE_WAIT_COUNT; | ||
464 | |||
465 | regw(dfc->dft_corr_vert[index], DFCMEM0); | ||
466 | regw(dfc->dft_corr_horz[index], DFCMEM1); | ||
467 | regw(dfc->dft_corr_sub1[index], DFCMEM2); | ||
468 | regw(dfc->dft_corr_sub2[index], DFCMEM3); | ||
469 | regw(dfc->dft_corr_sub3[index], DFCMEM4); | ||
470 | /* set WR bit to write */ | ||
471 | val = regr(DFCMEMCTL) | CCDC_DFCMEMCTL_DFCMWR_MASK; | ||
472 | regw(val, DFCMEMCTL); | ||
473 | |||
474 | /* | ||
475 | * Assume, it is very short. If we get an error, we need to | ||
476 | * adjust this value | ||
477 | */ | ||
478 | while (regr(DFCMEMCTL) & CCDC_DFCMEMCTL_DFCMWR_MASK) | ||
479 | count--; | ||
480 | /* | ||
481 | * TODO We expect the count to be non-zero to be successful. Adjust | ||
482 | * the count if write requires more time | ||
483 | */ | ||
484 | |||
485 | if (count) { | ||
486 | dev_err(dev, "defect table write timeout !!!\n"); | ||
487 | return -1; | ||
488 | } | ||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | /* | ||
493 | * ccdc_config_vdfc() | ||
494 | * configure parameters for Vertical Defect Correction | ||
495 | */ | ||
496 | static int ccdc_config_vdfc(struct ccdc_vertical_dft *dfc) | ||
497 | { | ||
498 | u32 val; | ||
499 | int i; | ||
500 | |||
501 | /* Configure General Defect Correction. The table used is from IPIPE */ | ||
502 | val = dfc->gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK; | ||
503 | |||
504 | /* Configure Vertical Defect Correction if needed */ | ||
505 | if (!dfc->ver_dft_en) { | ||
506 | /* Enable only General Defect Correction */ | ||
507 | regw(val, DFCCTL); | ||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | if (dfc->table_size > CCDC_DFT_TABLE_SIZE) | ||
512 | return -EINVAL; | ||
513 | |||
514 | val |= CCDC_DFCCTL_VDFC_DISABLE; | ||
515 | val |= (dfc->dft_corr_ctl.vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) << | ||
516 | CCDC_DFCCTL_VDFCSL_SHIFT; | ||
517 | val |= (dfc->dft_corr_ctl.vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) << | ||
518 | CCDC_DFCCTL_VDFCUDA_SHIFT; | ||
519 | val |= (dfc->dft_corr_ctl.vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) << | ||
520 | CCDC_DFCCTL_VDFLSFT_SHIFT; | ||
521 | regw(val , DFCCTL); | ||
522 | |||
523 | /* clear address ptr to offset 0 */ | ||
524 | val = CCDC_DFCMEMCTL_DFCMARST_MASK << CCDC_DFCMEMCTL_DFCMARST_SHIFT; | ||
525 | |||
526 | /* write defect table entries */ | ||
527 | for (i = 0; i < dfc->table_size; i++) { | ||
528 | /* increment address for non zero index */ | ||
529 | if (i != 0) | ||
530 | val = CCDC_DFCMEMCTL_INC_ADDR; | ||
531 | regw(val, DFCMEMCTL); | ||
532 | if (ccdc_write_dfc_entry(i, dfc) < 0) | ||
533 | return -EFAULT; | ||
534 | } | ||
535 | |||
536 | /* update saturation level and enable dfc */ | ||
537 | regw(dfc->saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT); | ||
538 | val = regr(DFCCTL) | (CCDC_DFCCTL_VDFCEN_MASK << | ||
539 | CCDC_DFCCTL_VDFCEN_SHIFT); | ||
540 | regw(val, DFCCTL); | ||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | /* | ||
545 | * ccdc_config_csc() | ||
546 | * configure parameters for color space conversion | ||
547 | * Each register CSCM0-7 has two values in S8Q5 format. | ||
548 | */ | ||
549 | static void ccdc_config_csc(struct ccdc_csc *csc) | ||
550 | { | ||
551 | u32 val1, val2; | ||
552 | int i; | ||
553 | |||
554 | if (!csc->enable) | ||
555 | return; | ||
556 | |||
557 | /* Enable the CSC sub-module */ | ||
558 | regw(CCDC_CSC_ENABLE, CSCCTL); | ||
559 | |||
560 | /* Converting the co-eff as per the format of the register */ | ||
561 | for (i = 0; i < CCDC_CSC_COEFF_TABLE_SIZE; i++) { | ||
562 | if ((i % 2) == 0) { | ||
563 | /* CSCM - LSB */ | ||
564 | val1 = (csc->coeff[i].integer & | ||
565 | CCDC_CSC_COEF_INTEG_MASK) | ||
566 | << CCDC_CSC_COEF_INTEG_SHIFT; | ||
567 | /* | ||
568 | * convert decimal part to binary. Use 2 decimal | ||
569 | * precision, user values range from .00 - 0.99 | ||
570 | */ | ||
571 | val1 |= (((csc->coeff[i].decimal & | ||
572 | CCDC_CSC_COEF_DECIMAL_MASK) * | ||
573 | CCDC_CSC_DEC_MAX) / 100); | ||
574 | } else { | ||
575 | |||
576 | /* CSCM - MSB */ | ||
577 | val2 = (csc->coeff[i].integer & | ||
578 | CCDC_CSC_COEF_INTEG_MASK) | ||
579 | << CCDC_CSC_COEF_INTEG_SHIFT; | ||
580 | val2 |= (((csc->coeff[i].decimal & | ||
581 | CCDC_CSC_COEF_DECIMAL_MASK) * | ||
582 | CCDC_CSC_DEC_MAX) / 100); | ||
583 | val2 <<= CCDC_CSCM_MSB_SHIFT; | ||
584 | val2 |= val1; | ||
585 | regw(val2, (CSCM0 + ((i - 1) << 1))); | ||
586 | } | ||
587 | } | ||
588 | } | ||
589 | |||
590 | /* | ||
591 | * ccdc_config_color_patterns() | ||
592 | * configure parameters for color patterns | ||
593 | */ | ||
594 | static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0, | ||
595 | struct ccdc_col_pat *pat1) | ||
596 | { | ||
597 | u32 val; | ||
598 | |||
599 | val = (pat0->olop | (pat0->olep << 2) | (pat0->elop << 4) | | ||
600 | (pat0->elep << 6) | (pat1->olop << 8) | (pat1->olep << 10) | | ||
601 | (pat1->elop << 12) | (pat1->elep << 14)); | ||
602 | regw(val, COLPTN); | ||
603 | } | ||
604 | |||
605 | /* This function will configure CCDC for Raw mode image capture */ | ||
606 | static int ccdc_config_raw(void) | ||
607 | { | ||
608 | struct ccdc_params_raw *params = &ccdc_hw_params_raw; | ||
609 | struct ccdc_config_params_raw *config_params = | ||
610 | &ccdc_hw_params_raw.config_params; | ||
611 | unsigned int val; | ||
612 | |||
613 | dev_dbg(dev, "\nStarting ccdc_config_raw..."); | ||
614 | |||
615 | /* restore power on defaults to register */ | ||
616 | ccdc_restore_defaults(); | ||
617 | |||
618 | /* CCDCFG register: | ||
619 | * set CCD Not to swap input since input is RAW data | ||
620 | * set FID detection function to Latch at V-Sync | ||
621 | * set WENLOG - ccdc valid area to AND | ||
622 | * set TRGSEL to WENBIT | ||
623 | * set EXTRG to DISABLE | ||
624 | * disable latching function on VSYNC - shadowed registers | ||
625 | */ | ||
626 | regw(CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC | | ||
627 | CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN | | ||
628 | CCDC_CCDCFG_EXTRG_DISABLE | CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG); | ||
629 | |||
630 | /* | ||
631 | * Set VDHD direction to input, input type to raw input | ||
632 | * normal data polarity, do not use external WEN | ||
633 | */ | ||
634 | val = (CCDC_VDHDOUT_INPUT | CCDC_RAW_IP_MODE | CCDC_DATAPOL_NORMAL | | ||
635 | CCDC_EXWEN_DISABLE); | ||
636 | |||
637 | /* | ||
638 | * Configure the vertical sync polarity (MODESET.VDPOL), horizontal | ||
639 | * sync polarity (MODESET.HDPOL), field id polarity (MODESET.FLDPOL), | ||
640 | * frame format(progressive or interlace), & pixel format (Input mode) | ||
641 | */ | ||
642 | val |= (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) | | ||
643 | ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) | | ||
644 | ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) | | ||
645 | ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) | | ||
646 | ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT)); | ||
647 | |||
648 | /* set pack for alaw compression */ | ||
649 | if ((config_params->data_sz == CCDC_DATA_8BITS) || | ||
650 | config_params->alaw.enable) | ||
651 | val |= CCDC_DATA_PACK_ENABLE; | ||
652 | |||
653 | /* Configure for LPF */ | ||
654 | if (config_params->lpf_enable) | ||
655 | val |= (config_params->lpf_enable & CCDC_LPF_MASK) << | ||
656 | CCDC_LPF_SHIFT; | ||
657 | |||
658 | /* Configure the data shift */ | ||
659 | val |= (config_params->datasft & CCDC_DATASFT_MASK) << | ||
660 | CCDC_DATASFT_SHIFT; | ||
661 | regw(val , MODESET); | ||
662 | dev_dbg(dev, "\nWriting 0x%x to MODESET...\n", val); | ||
663 | |||
664 | /* Configure the Median Filter threshold */ | ||
665 | regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT); | ||
666 | |||
667 | /* Configure GAMMAWD register. defaur 11-2, and Mosaic cfa pattern */ | ||
668 | val = CCDC_GAMMA_BITS_11_2 << CCDC_GAMMAWD_INPUT_SHIFT | | ||
669 | CCDC_CFA_MOSAIC; | ||
670 | |||
671 | /* Enable and configure aLaw register if needed */ | ||
672 | if (config_params->alaw.enable) { | ||
673 | val |= (CCDC_ALAW_ENABLE | | ||
674 | ((config_params->alaw.gama_wd & | ||
675 | CCDC_ALAW_GAMA_WD_MASK) << | ||
676 | CCDC_GAMMAWD_INPUT_SHIFT)); | ||
677 | } | ||
678 | |||
679 | /* Configure Median filter1 & filter2 */ | ||
680 | val |= ((config_params->mfilt1 << CCDC_MFILT1_SHIFT) | | ||
681 | (config_params->mfilt2 << CCDC_MFILT2_SHIFT)); | ||
682 | |||
683 | regw(val, GAMMAWD); | ||
684 | dev_dbg(dev, "\nWriting 0x%x to GAMMAWD...\n", val); | ||
685 | |||
686 | /* configure video window */ | ||
687 | ccdc_setwin(¶ms->win, params->frm_fmt, 1); | ||
688 | |||
689 | /* Optical Clamp Averaging */ | ||
690 | ccdc_config_black_clamp(&config_params->blk_clamp); | ||
691 | |||
692 | /* Black level compensation */ | ||
693 | ccdc_config_black_compense(&config_params->blk_comp); | ||
694 | |||
695 | /* Vertical Defect Correction if needed */ | ||
696 | if (ccdc_config_vdfc(&config_params->vertical_dft) < 0) | ||
697 | return -EFAULT; | ||
698 | |||
699 | /* color space conversion */ | ||
700 | ccdc_config_csc(&config_params->csc); | ||
701 | |||
702 | /* color pattern */ | ||
703 | ccdc_config_color_patterns(&config_params->col_pat_field0, | ||
704 | &config_params->col_pat_field1); | ||
705 | |||
706 | /* Configure the Gain & offset control */ | ||
707 | ccdc_config_gain_offset(); | ||
708 | |||
709 | dev_dbg(dev, "\nWriting %x to COLPTN...\n", val); | ||
710 | |||
711 | /* Configure DATAOFST register */ | ||
712 | val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) << | ||
713 | CCDC_DATAOFST_H_SHIFT; | ||
714 | val |= (config_params->data_offset.vert_offset & CCDC_DATAOFST_MASK) << | ||
715 | CCDC_DATAOFST_V_SHIFT; | ||
716 | regw(val, DATAOFST); | ||
717 | |||
718 | /* configuring HSIZE register */ | ||
719 | val = (params->horz_flip_enable & CCDC_HSIZE_FLIP_MASK) << | ||
720 | CCDC_HSIZE_FLIP_SHIFT; | ||
721 | |||
722 | /* If pack 8 is enable then 1 pixel will take 1 byte */ | ||
723 | if ((config_params->data_sz == CCDC_DATA_8BITS) || | ||
724 | config_params->alaw.enable) { | ||
725 | val |= (((params->win.width) + 31) >> 5) & | ||
726 | CCDC_HSIZE_VAL_MASK; | ||
727 | |||
728 | /* adjust to multiple of 32 */ | ||
729 | dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n", | ||
730 | (((params->win.width) + 31) >> 5) & | ||
731 | CCDC_HSIZE_VAL_MASK); | ||
732 | } else { | ||
733 | /* else one pixel will take 2 byte */ | ||
734 | val |= (((params->win.width * 2) + 31) >> 5) & | ||
735 | CCDC_HSIZE_VAL_MASK; | ||
736 | |||
737 | dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n", | ||
738 | (((params->win.width * 2) + 31) >> 5) & | ||
739 | CCDC_HSIZE_VAL_MASK); | ||
740 | } | ||
741 | regw(val, HSIZE); | ||
742 | |||
743 | /* Configure SDOFST register */ | ||
744 | if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) { | ||
745 | if (params->image_invert_enable) { | ||
746 | /* For interlace inverse mode */ | ||
747 | regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST); | ||
748 | dev_dbg(dev, "\nWriting %x to SDOFST...\n", | ||
749 | CCDC_SDOFST_INTERLACE_INVERSE); | ||
750 | } else { | ||
751 | /* For interlace non inverse mode */ | ||
752 | regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST); | ||
753 | dev_dbg(dev, "\nWriting %x to SDOFST...\n", | ||
754 | CCDC_SDOFST_INTERLACE_NORMAL); | ||
755 | } | ||
756 | } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) { | ||
757 | if (params->image_invert_enable) { | ||
758 | /* For progessive inverse mode */ | ||
759 | regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST); | ||
760 | dev_dbg(dev, "\nWriting %x to SDOFST...\n", | ||
761 | CCDC_SDOFST_PROGRESSIVE_INVERSE); | ||
762 | } else { | ||
763 | /* For progessive non inverse mode */ | ||
764 | regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST); | ||
765 | dev_dbg(dev, "\nWriting %x to SDOFST...\n", | ||
766 | CCDC_SDOFST_PROGRESSIVE_NORMAL); | ||
767 | } | ||
768 | } | ||
769 | dev_dbg(dev, "\nend of ccdc_config_raw..."); | ||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static int ccdc_configure(void) | ||
774 | { | ||
775 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
776 | return ccdc_config_raw(); | ||
777 | else | ||
778 | ccdc_config_ycbcr(); | ||
779 | return 0; | ||
780 | } | ||
781 | |||
782 | static int ccdc_set_buftype(enum ccdc_buftype buf_type) | ||
783 | { | ||
784 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
785 | ccdc_hw_params_raw.buf_type = buf_type; | ||
786 | else | ||
787 | ccdc_hw_params_ycbcr.buf_type = buf_type; | ||
788 | return 0; | ||
789 | } | ||
790 | static enum ccdc_buftype ccdc_get_buftype(void) | ||
791 | { | ||
792 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
793 | return ccdc_hw_params_raw.buf_type; | ||
794 | return ccdc_hw_params_ycbcr.buf_type; | ||
795 | } | ||
796 | |||
797 | static int ccdc_enum_pix(u32 *pix, int i) | ||
798 | { | ||
799 | int ret = -EINVAL; | ||
800 | if (ccdc_if_type == VPFE_RAW_BAYER) { | ||
801 | if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) { | ||
802 | *pix = ccdc_raw_bayer_pix_formats[i]; | ||
803 | ret = 0; | ||
804 | } | ||
805 | } else { | ||
806 | if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) { | ||
807 | *pix = ccdc_raw_yuv_pix_formats[i]; | ||
808 | ret = 0; | ||
809 | } | ||
810 | } | ||
811 | return ret; | ||
812 | } | ||
813 | |||
814 | static int ccdc_set_pixel_format(u32 pixfmt) | ||
815 | { | ||
816 | struct ccdc_a_law *alaw = | ||
817 | &ccdc_hw_params_raw.config_params.alaw; | ||
818 | |||
819 | if (ccdc_if_type == VPFE_RAW_BAYER) { | ||
820 | ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW; | ||
821 | if (pixfmt == V4L2_PIX_FMT_SBGGR8) | ||
822 | alaw->enable = 1; | ||
823 | else if (pixfmt != V4L2_PIX_FMT_SBGGR16) | ||
824 | return -EINVAL; | ||
825 | } else { | ||
826 | if (pixfmt == V4L2_PIX_FMT_YUYV) | ||
827 | ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR; | ||
828 | else if (pixfmt == V4L2_PIX_FMT_UYVY) | ||
829 | ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY; | ||
830 | else | ||
831 | return -EINVAL; | ||
832 | } | ||
833 | return 0; | ||
834 | } | ||
835 | static u32 ccdc_get_pixel_format(void) | ||
836 | { | ||
837 | struct ccdc_a_law *alaw = | ||
838 | &ccdc_hw_params_raw.config_params.alaw; | ||
839 | u32 pixfmt; | ||
840 | |||
841 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
842 | if (alaw->enable) | ||
843 | pixfmt = V4L2_PIX_FMT_SBGGR8; | ||
844 | else | ||
845 | pixfmt = V4L2_PIX_FMT_SBGGR16; | ||
846 | else { | ||
847 | if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR) | ||
848 | pixfmt = V4L2_PIX_FMT_YUYV; | ||
849 | else | ||
850 | pixfmt = V4L2_PIX_FMT_UYVY; | ||
851 | } | ||
852 | return pixfmt; | ||
853 | } | ||
854 | static int ccdc_set_image_window(struct v4l2_rect *win) | ||
855 | { | ||
856 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
857 | ccdc_hw_params_raw.win = *win; | ||
858 | else | ||
859 | ccdc_hw_params_ycbcr.win = *win; | ||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | static void ccdc_get_image_window(struct v4l2_rect *win) | ||
864 | { | ||
865 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
866 | *win = ccdc_hw_params_raw.win; | ||
867 | else | ||
868 | *win = ccdc_hw_params_ycbcr.win; | ||
869 | } | ||
870 | |||
871 | static unsigned int ccdc_get_line_length(void) | ||
872 | { | ||
873 | struct ccdc_config_params_raw *config_params = | ||
874 | &ccdc_hw_params_raw.config_params; | ||
875 | unsigned int len; | ||
876 | |||
877 | if (ccdc_if_type == VPFE_RAW_BAYER) { | ||
878 | if ((config_params->alaw.enable) || | ||
879 | (config_params->data_sz == CCDC_DATA_8BITS)) | ||
880 | len = ccdc_hw_params_raw.win.width; | ||
881 | else | ||
882 | len = ccdc_hw_params_raw.win.width * 2; | ||
883 | } else | ||
884 | len = ccdc_hw_params_ycbcr.win.width * 2; | ||
885 | return ALIGN(len, 32); | ||
886 | } | ||
887 | |||
888 | static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt) | ||
889 | { | ||
890 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
891 | ccdc_hw_params_raw.frm_fmt = frm_fmt; | ||
892 | else | ||
893 | ccdc_hw_params_ycbcr.frm_fmt = frm_fmt; | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | static enum ccdc_frmfmt ccdc_get_frame_format(void) | ||
898 | { | ||
899 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
900 | return ccdc_hw_params_raw.frm_fmt; | ||
901 | else | ||
902 | return ccdc_hw_params_ycbcr.frm_fmt; | ||
903 | } | ||
904 | |||
905 | static int ccdc_getfid(void) | ||
906 | { | ||
907 | return (regr(MODESET) >> 15) & 1; | ||
908 | } | ||
909 | |||
910 | /* misc operations */ | ||
911 | static inline void ccdc_setfbaddr(unsigned long addr) | ||
912 | { | ||
913 | regw((addr >> 21) & 0x007f, STADRH); | ||
914 | regw((addr >> 5) & 0x0ffff, STADRL); | ||
915 | } | ||
916 | |||
917 | static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params) | ||
918 | { | ||
919 | ccdc_if_type = params->if_type; | ||
920 | |||
921 | switch (params->if_type) { | ||
922 | case VPFE_BT656: | ||
923 | case VPFE_YCBCR_SYNC_16: | ||
924 | case VPFE_YCBCR_SYNC_8: | ||
925 | ccdc_hw_params_ycbcr.vd_pol = params->vdpol; | ||
926 | ccdc_hw_params_ycbcr.hd_pol = params->hdpol; | ||
927 | break; | ||
928 | default: | ||
929 | /* TODO add support for raw bayer here */ | ||
930 | return -EINVAL; | ||
931 | } | ||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | static struct ccdc_hw_device ccdc_hw_dev = { | ||
936 | .name = "DM355 CCDC", | ||
937 | .owner = THIS_MODULE, | ||
938 | .hw_ops = { | ||
939 | .open = ccdc_open, | ||
940 | .close = ccdc_close, | ||
941 | .set_ccdc_base = ccdc_set_ccdc_base, | ||
942 | .enable = ccdc_enable, | ||
943 | .enable_out_to_sdram = ccdc_enable_output_to_sdram, | ||
944 | .set_hw_if_params = ccdc_set_hw_if_params, | ||
945 | .set_params = ccdc_set_params, | ||
946 | .configure = ccdc_configure, | ||
947 | .set_buftype = ccdc_set_buftype, | ||
948 | .get_buftype = ccdc_get_buftype, | ||
949 | .enum_pix = ccdc_enum_pix, | ||
950 | .set_pixel_format = ccdc_set_pixel_format, | ||
951 | .get_pixel_format = ccdc_get_pixel_format, | ||
952 | .set_frame_format = ccdc_set_frame_format, | ||
953 | .get_frame_format = ccdc_get_frame_format, | ||
954 | .set_image_window = ccdc_set_image_window, | ||
955 | .get_image_window = ccdc_get_image_window, | ||
956 | .get_line_length = ccdc_get_line_length, | ||
957 | .setfbaddr = ccdc_setfbaddr, | ||
958 | .getfid = ccdc_getfid, | ||
959 | }, | ||
960 | }; | ||
961 | |||
962 | static int dm355_ccdc_init(void) | ||
963 | { | ||
964 | printk(KERN_NOTICE "dm355_ccdc_init\n"); | ||
965 | if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) | ||
966 | return -1; | ||
967 | printk(KERN_NOTICE "%s is registered with vpfe.\n", | ||
968 | ccdc_hw_dev.name); | ||
969 | return 0; | ||
970 | } | ||
971 | |||
972 | static void dm355_ccdc_exit(void) | ||
973 | { | ||
974 | vpfe_unregister_ccdc_device(&ccdc_hw_dev); | ||
975 | } | ||
976 | |||
977 | module_init(dm355_ccdc_init); | ||
978 | module_exit(dm355_ccdc_exit); | ||
diff --git a/drivers/media/video/davinci/dm355_ccdc_regs.h b/drivers/media/video/davinci/dm355_ccdc_regs.h new file mode 100644 index 000000000000..d6d2ef0533b5 --- /dev/null +++ b/drivers/media/video/davinci/dm355_ccdc_regs.h | |||
@@ -0,0 +1,310 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005-2009 Texas Instruments Inc | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | #ifndef _DM355_CCDC_REGS_H | ||
19 | #define _DM355_CCDC_REGS_H | ||
20 | |||
21 | /**************************************************************************\ | ||
22 | * Register OFFSET Definitions | ||
23 | \**************************************************************************/ | ||
24 | #define SYNCEN 0x00 | ||
25 | #define MODESET 0x04 | ||
26 | #define HDWIDTH 0x08 | ||
27 | #define VDWIDTH 0x0c | ||
28 | #define PPLN 0x10 | ||
29 | #define LPFR 0x14 | ||
30 | #define SPH 0x18 | ||
31 | #define NPH 0x1c | ||
32 | #define SLV0 0x20 | ||
33 | #define SLV1 0x24 | ||
34 | #define NLV 0x28 | ||
35 | #define CULH 0x2c | ||
36 | #define CULV 0x30 | ||
37 | #define HSIZE 0x34 | ||
38 | #define SDOFST 0x38 | ||
39 | #define STADRH 0x3c | ||
40 | #define STADRL 0x40 | ||
41 | #define CLAMP 0x44 | ||
42 | #define DCSUB 0x48 | ||
43 | #define COLPTN 0x4c | ||
44 | #define BLKCMP0 0x50 | ||
45 | #define BLKCMP1 0x54 | ||
46 | #define MEDFILT 0x58 | ||
47 | #define RYEGAIN 0x5c | ||
48 | #define GRCYGAIN 0x60 | ||
49 | #define GBGGAIN 0x64 | ||
50 | #define BMGGAIN 0x68 | ||
51 | #define OFFSET 0x6c | ||
52 | #define OUTCLIP 0x70 | ||
53 | #define VDINT0 0x74 | ||
54 | #define VDINT1 0x78 | ||
55 | #define RSV0 0x7c | ||
56 | #define GAMMAWD 0x80 | ||
57 | #define REC656IF 0x84 | ||
58 | #define CCDCFG 0x88 | ||
59 | #define FMTCFG 0x8c | ||
60 | #define FMTPLEN 0x90 | ||
61 | #define FMTSPH 0x94 | ||
62 | #define FMTLNH 0x98 | ||
63 | #define FMTSLV 0x9c | ||
64 | #define FMTLNV 0xa0 | ||
65 | #define FMTRLEN 0xa4 | ||
66 | #define FMTHCNT 0xa8 | ||
67 | #define FMT_ADDR_PTR_B 0xac | ||
68 | #define FMT_ADDR_PTR(i) (FMT_ADDR_PTR_B + (i * 4)) | ||
69 | #define FMTPGM_VF0 0xcc | ||
70 | #define FMTPGM_VF1 0xd0 | ||
71 | #define FMTPGM_AP0 0xd4 | ||
72 | #define FMTPGM_AP1 0xd8 | ||
73 | #define FMTPGM_AP2 0xdc | ||
74 | #define FMTPGM_AP3 0xe0 | ||
75 | #define FMTPGM_AP4 0xe4 | ||
76 | #define FMTPGM_AP5 0xe8 | ||
77 | #define FMTPGM_AP6 0xec | ||
78 | #define FMTPGM_AP7 0xf0 | ||
79 | #define LSCCFG1 0xf4 | ||
80 | #define LSCCFG2 0xf8 | ||
81 | #define LSCH0 0xfc | ||
82 | #define LSCV0 0x100 | ||
83 | #define LSCKH 0x104 | ||
84 | #define LSCKV 0x108 | ||
85 | #define LSCMEMCTL 0x10c | ||
86 | #define LSCMEMD 0x110 | ||
87 | #define LSCMEMQ 0x114 | ||
88 | #define DFCCTL 0x118 | ||
89 | #define DFCVSAT 0x11c | ||
90 | #define DFCMEMCTL 0x120 | ||
91 | #define DFCMEM0 0x124 | ||
92 | #define DFCMEM1 0x128 | ||
93 | #define DFCMEM2 0x12c | ||
94 | #define DFCMEM3 0x130 | ||
95 | #define DFCMEM4 0x134 | ||
96 | #define CSCCTL 0x138 | ||
97 | #define CSCM0 0x13c | ||
98 | #define CSCM1 0x140 | ||
99 | #define CSCM2 0x144 | ||
100 | #define CSCM3 0x148 | ||
101 | #define CSCM4 0x14c | ||
102 | #define CSCM5 0x150 | ||
103 | #define CSCM6 0x154 | ||
104 | #define CSCM7 0x158 | ||
105 | #define DATAOFST 0x15c | ||
106 | #define CCDC_REG_LAST DATAOFST | ||
107 | /************************************************************** | ||
108 | * Define for various register bit mask and shifts for CCDC | ||
109 | * | ||
110 | **************************************************************/ | ||
111 | #define CCDC_RAW_IP_MODE 0 | ||
112 | #define CCDC_VDHDOUT_INPUT 0 | ||
113 | #define CCDC_YCINSWP_RAW (0 << 4) | ||
114 | #define CCDC_EXWEN_DISABLE 0 | ||
115 | #define CCDC_DATAPOL_NORMAL 0 | ||
116 | #define CCDC_CCDCFG_FIDMD_LATCH_VSYNC 0 | ||
117 | #define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC (1 << 6) | ||
118 | #define CCDC_CCDCFG_WENLOG_AND 0 | ||
119 | #define CCDC_CCDCFG_TRGSEL_WEN 0 | ||
120 | #define CCDC_CCDCFG_EXTRG_DISABLE 0 | ||
121 | #define CCDC_CFA_MOSAIC 0 | ||
122 | #define CCDC_Y8POS_SHIFT 11 | ||
123 | |||
124 | #define CCDC_VDC_DFCVSAT_MASK 0x3fff | ||
125 | #define CCDC_DATAOFST_MASK 0x0ff | ||
126 | #define CCDC_DATAOFST_H_SHIFT 0 | ||
127 | #define CCDC_DATAOFST_V_SHIFT 8 | ||
128 | #define CCDC_GAMMAWD_CFA_MASK 1 | ||
129 | #define CCDC_GAMMAWD_CFA_SHIFT 5 | ||
130 | #define CCDC_GAMMAWD_INPUT_SHIFT 2 | ||
131 | #define CCDC_FID_POL_MASK 1 | ||
132 | #define CCDC_FID_POL_SHIFT 4 | ||
133 | #define CCDC_HD_POL_MASK 1 | ||
134 | #define CCDC_HD_POL_SHIFT 3 | ||
135 | #define CCDC_VD_POL_MASK 1 | ||
136 | #define CCDC_VD_POL_SHIFT 2 | ||
137 | #define CCDC_VD_POL_NEGATIVE (1 << 2) | ||
138 | #define CCDC_FRM_FMT_MASK 1 | ||
139 | #define CCDC_FRM_FMT_SHIFT 7 | ||
140 | #define CCDC_DATA_SZ_MASK 7 | ||
141 | #define CCDC_DATA_SZ_SHIFT 8 | ||
142 | #define CCDC_VDHDOUT_MASK 1 | ||
143 | #define CCDC_VDHDOUT_SHIFT 0 | ||
144 | #define CCDC_EXWEN_MASK 1 | ||
145 | #define CCDC_EXWEN_SHIFT 5 | ||
146 | #define CCDC_INPUT_MODE_MASK 3 | ||
147 | #define CCDC_INPUT_MODE_SHIFT 12 | ||
148 | #define CCDC_PIX_FMT_MASK 3 | ||
149 | #define CCDC_PIX_FMT_SHIFT 12 | ||
150 | #define CCDC_DATAPOL_MASK 1 | ||
151 | #define CCDC_DATAPOL_SHIFT 6 | ||
152 | #define CCDC_WEN_ENABLE (1 << 1) | ||
153 | #define CCDC_VDHDEN_ENABLE (1 << 16) | ||
154 | #define CCDC_LPF_ENABLE (1 << 14) | ||
155 | #define CCDC_ALAW_ENABLE 1 | ||
156 | #define CCDC_ALAW_GAMA_WD_MASK 7 | ||
157 | #define CCDC_REC656IF_BT656_EN 3 | ||
158 | |||
159 | #define CCDC_FMTCFG_FMTMODE_MASK 3 | ||
160 | #define CCDC_FMTCFG_FMTMODE_SHIFT 1 | ||
161 | #define CCDC_FMTCFG_LNUM_MASK 3 | ||
162 | #define CCDC_FMTCFG_LNUM_SHIFT 4 | ||
163 | #define CCDC_FMTCFG_ADDRINC_MASK 7 | ||
164 | #define CCDC_FMTCFG_ADDRINC_SHIFT 8 | ||
165 | |||
166 | #define CCDC_CCDCFG_FIDMD_SHIFT 6 | ||
167 | #define CCDC_CCDCFG_WENLOG_SHIFT 8 | ||
168 | #define CCDC_CCDCFG_TRGSEL_SHIFT 9 | ||
169 | #define CCDC_CCDCFG_EXTRG_SHIFT 10 | ||
170 | #define CCDC_CCDCFG_MSBINVI_SHIFT 13 | ||
171 | |||
172 | #define CCDC_HSIZE_FLIP_SHIFT 12 | ||
173 | #define CCDC_HSIZE_FLIP_MASK 1 | ||
174 | #define CCDC_HSIZE_VAL_MASK 0xFFF | ||
175 | #define CCDC_SDOFST_FIELD_INTERLEAVED 0x249 | ||
176 | #define CCDC_SDOFST_INTERLACE_INVERSE 0x4B6D | ||
177 | #define CCDC_SDOFST_INTERLACE_NORMAL 0x0B6D | ||
178 | #define CCDC_SDOFST_PROGRESSIVE_INVERSE 0x4000 | ||
179 | #define CCDC_SDOFST_PROGRESSIVE_NORMAL 0 | ||
180 | #define CCDC_START_PX_HOR_MASK 0x7FFF | ||
181 | #define CCDC_NUM_PX_HOR_MASK 0x7FFF | ||
182 | #define CCDC_START_VER_ONE_MASK 0x7FFF | ||
183 | #define CCDC_START_VER_TWO_MASK 0x7FFF | ||
184 | #define CCDC_NUM_LINES_VER 0x7FFF | ||
185 | |||
186 | #define CCDC_BLK_CLAMP_ENABLE (1 << 15) | ||
187 | #define CCDC_BLK_SGAIN_MASK 0x1F | ||
188 | #define CCDC_BLK_ST_PXL_MASK 0x1FFF | ||
189 | #define CCDC_BLK_SAMPLE_LN_MASK 3 | ||
190 | #define CCDC_BLK_SAMPLE_LN_SHIFT 13 | ||
191 | |||
192 | #define CCDC_NUM_LINE_CALC_MASK 3 | ||
193 | #define CCDC_NUM_LINE_CALC_SHIFT 14 | ||
194 | |||
195 | #define CCDC_BLK_DC_SUB_MASK 0x3FFF | ||
196 | #define CCDC_BLK_COMP_MASK 0xFF | ||
197 | #define CCDC_BLK_COMP_GB_COMP_SHIFT 8 | ||
198 | #define CCDC_BLK_COMP_GR_COMP_SHIFT 0 | ||
199 | #define CCDC_BLK_COMP_R_COMP_SHIFT 8 | ||
200 | #define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15) | ||
201 | #define CCDC_LATCH_ON_VSYNC_ENABLE (0 << 15) | ||
202 | #define CCDC_FPC_ENABLE (1 << 15) | ||
203 | #define CCDC_FPC_FPC_NUM_MASK 0x7FFF | ||
204 | #define CCDC_DATA_PACK_ENABLE (1 << 11) | ||
205 | #define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF | ||
206 | #define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF | ||
207 | #define CCDC_FMT_HORZ_FMTSPH_SHIFT 16 | ||
208 | #define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF | ||
209 | #define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF | ||
210 | #define CCDC_FMT_VERT_FMTSLV_SHIFT 16 | ||
211 | #define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF | ||
212 | #define CCDC_VP_OUT_VERT_NUM_SHIFT 17 | ||
213 | #define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF | ||
214 | #define CCDC_VP_OUT_HORZ_NUM_SHIFT 4 | ||
215 | #define CCDC_VP_OUT_HORZ_ST_MASK 0xF | ||
216 | |||
217 | #define CCDC_CSC_COEF_INTEG_MASK 7 | ||
218 | #define CCDC_CSC_COEF_DECIMAL_MASK 0x1f | ||
219 | #define CCDC_CSC_COEF_INTEG_SHIFT 5 | ||
220 | #define CCDC_CSCM_MSB_SHIFT 8 | ||
221 | #define CCDC_CSC_ENABLE 1 | ||
222 | #define CCDC_CSC_DEC_MAX 32 | ||
223 | |||
224 | #define CCDC_MFILT1_SHIFT 10 | ||
225 | #define CCDC_MFILT2_SHIFT 8 | ||
226 | #define CCDC_MED_FILT_THRESH 0x3FFF | ||
227 | #define CCDC_LPF_MASK 1 | ||
228 | #define CCDC_LPF_SHIFT 14 | ||
229 | #define CCDC_OFFSET_MASK 0x3FF | ||
230 | #define CCDC_DATASFT_MASK 7 | ||
231 | #define CCDC_DATASFT_SHIFT 8 | ||
232 | |||
233 | #define CCDC_DF_ENABLE 1 | ||
234 | |||
235 | #define CCDC_FMTPLEN_P0_MASK 0xF | ||
236 | #define CCDC_FMTPLEN_P1_MASK 0xF | ||
237 | #define CCDC_FMTPLEN_P2_MASK 7 | ||
238 | #define CCDC_FMTPLEN_P3_MASK 7 | ||
239 | #define CCDC_FMTPLEN_P0_SHIFT 0 | ||
240 | #define CCDC_FMTPLEN_P1_SHIFT 4 | ||
241 | #define CCDC_FMTPLEN_P2_SHIFT 8 | ||
242 | #define CCDC_FMTPLEN_P3_SHIFT 12 | ||
243 | |||
244 | #define CCDC_FMTSPH_MASK 0x1FFF | ||
245 | #define CCDC_FMTLNH_MASK 0x1FFF | ||
246 | #define CCDC_FMTSLV_MASK 0x1FFF | ||
247 | #define CCDC_FMTLNV_MASK 0x7FFF | ||
248 | #define CCDC_FMTRLEN_MASK 0x1FFF | ||
249 | #define CCDC_FMTHCNT_MASK 0x1FFF | ||
250 | |||
251 | #define CCDC_ADP_INIT_MASK 0x1FFF | ||
252 | #define CCDC_ADP_LINE_SHIFT 13 | ||
253 | #define CCDC_ADP_LINE_MASK 3 | ||
254 | #define CCDC_FMTPGN_APTR_MASK 7 | ||
255 | |||
256 | #define CCDC_DFCCTL_GDFCEN_MASK 1 | ||
257 | #define CCDC_DFCCTL_VDFCEN_MASK 1 | ||
258 | #define CCDC_DFCCTL_VDFC_DISABLE (0 << 4) | ||
259 | #define CCDC_DFCCTL_VDFCEN_SHIFT 4 | ||
260 | #define CCDC_DFCCTL_VDFCSL_MASK 3 | ||
261 | #define CCDC_DFCCTL_VDFCSL_SHIFT 5 | ||
262 | #define CCDC_DFCCTL_VDFCUDA_MASK 1 | ||
263 | #define CCDC_DFCCTL_VDFCUDA_SHIFT 7 | ||
264 | #define CCDC_DFCCTL_VDFLSFT_MASK 3 | ||
265 | #define CCDC_DFCCTL_VDFLSFT_SHIFT 8 | ||
266 | #define CCDC_DFCMEMCTL_DFCMARST_MASK 1 | ||
267 | #define CCDC_DFCMEMCTL_DFCMARST_SHIFT 2 | ||
268 | #define CCDC_DFCMEMCTL_DFCMWR_MASK 1 | ||
269 | #define CCDC_DFCMEMCTL_DFCMWR_SHIFT 0 | ||
270 | #define CCDC_DFCMEMCTL_INC_ADDR (0 << 2) | ||
271 | |||
272 | #define CCDC_LSCCFG_GFTSF_MASK 7 | ||
273 | #define CCDC_LSCCFG_GFTSF_SHIFT 1 | ||
274 | #define CCDC_LSCCFG_GFTINV_MASK 0xf | ||
275 | #define CCDC_LSCCFG_GFTINV_SHIFT 4 | ||
276 | #define CCDC_LSC_GFTABLE_SEL_MASK 3 | ||
277 | #define CCDC_LSC_GFTABLE_EPEL_SHIFT 8 | ||
278 | #define CCDC_LSC_GFTABLE_OPEL_SHIFT 10 | ||
279 | #define CCDC_LSC_GFTABLE_EPOL_SHIFT 12 | ||
280 | #define CCDC_LSC_GFTABLE_OPOL_SHIFT 14 | ||
281 | #define CCDC_LSC_GFMODE_MASK 3 | ||
282 | #define CCDC_LSC_GFMODE_SHIFT 4 | ||
283 | #define CCDC_LSC_DISABLE 0 | ||
284 | #define CCDC_LSC_ENABLE 1 | ||
285 | #define CCDC_LSC_TABLE1_SLC 0 | ||
286 | #define CCDC_LSC_TABLE2_SLC 1 | ||
287 | #define CCDC_LSC_TABLE3_SLC 2 | ||
288 | #define CCDC_LSC_MEMADDR_RESET (1 << 2) | ||
289 | #define CCDC_LSC_MEMADDR_INCR (0 << 2) | ||
290 | #define CCDC_LSC_FRAC_MASK_T1 0xFF | ||
291 | #define CCDC_LSC_INT_MASK 3 | ||
292 | #define CCDC_LSC_FRAC_MASK 0x3FFF | ||
293 | #define CCDC_LSC_CENTRE_MASK 0x3FFF | ||
294 | #define CCDC_LSC_COEF_MASK 0xff | ||
295 | #define CCDC_LSC_COEFL_SHIFT 0 | ||
296 | #define CCDC_LSC_COEFU_SHIFT 8 | ||
297 | #define CCDC_GAIN_MASK 0x7FF | ||
298 | #define CCDC_SYNCEN_VDHDEN_MASK (1 << 0) | ||
299 | #define CCDC_SYNCEN_WEN_MASK (1 << 1) | ||
300 | #define CCDC_SYNCEN_WEN_SHIFT 1 | ||
301 | |||
302 | /* Power on Defaults in hardware */ | ||
303 | #define MODESET_DEFAULT 0x200 | ||
304 | #define CULH_DEFAULT 0xFFFF | ||
305 | #define CULV_DEFAULT 0xFF | ||
306 | #define GAIN_DEFAULT 256 | ||
307 | #define OUTCLIP_DEFAULT 0x3FFF | ||
308 | #define LSCCFG2_DEFAULT 0xE | ||
309 | |||
310 | #endif | ||
diff --git a/include/media/davinci/dm355_ccdc.h b/include/media/davinci/dm355_ccdc.h new file mode 100644 index 000000000000..df8a7b107477 --- /dev/null +++ b/include/media/davinci/dm355_ccdc.h | |||
@@ -0,0 +1,321 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005-2009 Texas Instruments Inc | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | #ifndef _DM355_CCDC_H | ||
19 | #define _DM355_CCDC_H | ||
20 | #include <media/davinci/ccdc_types.h> | ||
21 | #include <media/davinci/vpfe_types.h> | ||
22 | |||
23 | /* enum for No of pixel per line to be avg. in Black Clamping */ | ||
24 | enum ccdc_sample_length { | ||
25 | CCDC_SAMPLE_1PIXELS, | ||
26 | CCDC_SAMPLE_2PIXELS, | ||
27 | CCDC_SAMPLE_4PIXELS, | ||
28 | CCDC_SAMPLE_8PIXELS, | ||
29 | CCDC_SAMPLE_16PIXELS | ||
30 | }; | ||
31 | |||
32 | /* enum for No of lines in Black Clamping */ | ||
33 | enum ccdc_sample_line { | ||
34 | CCDC_SAMPLE_1LINES, | ||
35 | CCDC_SAMPLE_2LINES, | ||
36 | CCDC_SAMPLE_4LINES, | ||
37 | CCDC_SAMPLE_8LINES, | ||
38 | CCDC_SAMPLE_16LINES | ||
39 | }; | ||
40 | |||
41 | /* enum for Alaw gama width */ | ||
42 | enum ccdc_gamma_width { | ||
43 | CCDC_GAMMA_BITS_13_4, | ||
44 | CCDC_GAMMA_BITS_12_3, | ||
45 | CCDC_GAMMA_BITS_11_2, | ||
46 | CCDC_GAMMA_BITS_10_1, | ||
47 | CCDC_GAMMA_BITS_09_0 | ||
48 | }; | ||
49 | |||
50 | enum ccdc_colpats { | ||
51 | CCDC_RED, | ||
52 | CCDC_GREEN_RED, | ||
53 | CCDC_GREEN_BLUE, | ||
54 | CCDC_BLUE | ||
55 | }; | ||
56 | |||
57 | struct ccdc_col_pat { | ||
58 | enum ccdc_colpats olop; | ||
59 | enum ccdc_colpats olep; | ||
60 | enum ccdc_colpats elop; | ||
61 | enum ccdc_colpats elep; | ||
62 | }; | ||
63 | |||
64 | enum ccdc_datasft { | ||
65 | CCDC_DATA_NO_SHIFT, | ||
66 | CCDC_DATA_SHIFT_1BIT, | ||
67 | CCDC_DATA_SHIFT_2BIT, | ||
68 | CCDC_DATA_SHIFT_3BIT, | ||
69 | CCDC_DATA_SHIFT_4BIT, | ||
70 | CCDC_DATA_SHIFT_5BIT, | ||
71 | CCDC_DATA_SHIFT_6BIT | ||
72 | }; | ||
73 | |||
74 | enum ccdc_data_size { | ||
75 | CCDC_DATA_16BITS, | ||
76 | CCDC_DATA_15BITS, | ||
77 | CCDC_DATA_14BITS, | ||
78 | CCDC_DATA_13BITS, | ||
79 | CCDC_DATA_12BITS, | ||
80 | CCDC_DATA_11BITS, | ||
81 | CCDC_DATA_10BITS, | ||
82 | CCDC_DATA_8BITS | ||
83 | }; | ||
84 | enum ccdc_mfilt1 { | ||
85 | CCDC_NO_MEDIAN_FILTER1, | ||
86 | CCDC_AVERAGE_FILTER1, | ||
87 | CCDC_MEDIAN_FILTER1 | ||
88 | }; | ||
89 | |||
90 | enum ccdc_mfilt2 { | ||
91 | CCDC_NO_MEDIAN_FILTER2, | ||
92 | CCDC_AVERAGE_FILTER2, | ||
93 | CCDC_MEDIAN_FILTER2 | ||
94 | }; | ||
95 | |||
96 | /* structure for ALaw */ | ||
97 | struct ccdc_a_law { | ||
98 | /* Enable/disable A-Law */ | ||
99 | unsigned char enable; | ||
100 | /* Gama Width Input */ | ||
101 | enum ccdc_gamma_width gama_wd; | ||
102 | }; | ||
103 | |||
104 | /* structure for Black Clamping */ | ||
105 | struct ccdc_black_clamp { | ||
106 | /* only if bClampEnable is TRUE */ | ||
107 | unsigned char b_clamp_enable; | ||
108 | /* only if bClampEnable is TRUE */ | ||
109 | enum ccdc_sample_length sample_pixel; | ||
110 | /* only if bClampEnable is TRUE */ | ||
111 | enum ccdc_sample_line sample_ln; | ||
112 | /* only if bClampEnable is TRUE */ | ||
113 | unsigned short start_pixel; | ||
114 | /* only if bClampEnable is FALSE */ | ||
115 | unsigned short sgain; | ||
116 | unsigned short dc_sub; | ||
117 | }; | ||
118 | |||
119 | /* structure for Black Level Compensation */ | ||
120 | struct ccdc_black_compensation { | ||
121 | /* Constant value to subtract from Red component */ | ||
122 | unsigned char r; | ||
123 | /* Constant value to subtract from Gr component */ | ||
124 | unsigned char gr; | ||
125 | /* Constant value to subtract from Blue component */ | ||
126 | unsigned char b; | ||
127 | /* Constant value to subtract from Gb component */ | ||
128 | unsigned char gb; | ||
129 | }; | ||
130 | |||
131 | struct ccdc_float { | ||
132 | int integer; | ||
133 | unsigned int decimal; | ||
134 | }; | ||
135 | |||
136 | #define CCDC_CSC_COEFF_TABLE_SIZE 16 | ||
137 | /* structure for color space converter */ | ||
138 | struct ccdc_csc { | ||
139 | unsigned char enable; | ||
140 | /* | ||
141 | * S8Q5. Use 2 decimal precision, user values range from -3.00 to 3.99. | ||
142 | * example - to use 1.03, set integer part as 1, and decimal part as 3 | ||
143 | * to use -1.03, set integer part as -1 and decimal part as 3 | ||
144 | */ | ||
145 | struct ccdc_float coeff[CCDC_CSC_COEFF_TABLE_SIZE]; | ||
146 | }; | ||
147 | |||
148 | /* Structures for Vertical Defect Correction*/ | ||
149 | enum ccdc_vdf_csl { | ||
150 | CCDC_VDF_NORMAL, | ||
151 | CCDC_VDF_HORZ_INTERPOL_SAT, | ||
152 | CCDC_VDF_HORZ_INTERPOL | ||
153 | }; | ||
154 | |||
155 | enum ccdc_vdf_cuda { | ||
156 | CCDC_VDF_WHOLE_LINE_CORRECT, | ||
157 | CCDC_VDF_UPPER_DISABLE | ||
158 | }; | ||
159 | |||
160 | enum ccdc_dfc_mwr { | ||
161 | CCDC_DFC_MWR_WRITE_COMPLETE, | ||
162 | CCDC_DFC_WRITE_REG | ||
163 | }; | ||
164 | |||
165 | enum ccdc_dfc_mrd { | ||
166 | CCDC_DFC_READ_COMPLETE, | ||
167 | CCDC_DFC_READ_REG | ||
168 | }; | ||
169 | |||
170 | enum ccdc_dfc_ma_rst { | ||
171 | CCDC_DFC_INCR_ADDR, | ||
172 | CCDC_DFC_CLR_ADDR | ||
173 | }; | ||
174 | |||
175 | enum ccdc_dfc_mclr { | ||
176 | CCDC_DFC_CLEAR_COMPLETE, | ||
177 | CCDC_DFC_CLEAR | ||
178 | }; | ||
179 | |||
180 | struct ccdc_dft_corr_ctl { | ||
181 | enum ccdc_vdf_csl vdfcsl; | ||
182 | enum ccdc_vdf_cuda vdfcuda; | ||
183 | unsigned int vdflsft; | ||
184 | }; | ||
185 | |||
186 | struct ccdc_dft_corr_mem_ctl { | ||
187 | enum ccdc_dfc_mwr dfcmwr; | ||
188 | enum ccdc_dfc_mrd dfcmrd; | ||
189 | enum ccdc_dfc_ma_rst dfcmarst; | ||
190 | enum ccdc_dfc_mclr dfcmclr; | ||
191 | }; | ||
192 | |||
193 | #define CCDC_DFT_TABLE_SIZE 16 | ||
194 | /* | ||
195 | * Main Structure for vertical defect correction. Vertical defect | ||
196 | * correction can correct upto 16 defects if defects less than 16 | ||
197 | * then pad the rest with 0 | ||
198 | */ | ||
199 | struct ccdc_vertical_dft { | ||
200 | unsigned char ver_dft_en; | ||
201 | unsigned char gen_dft_en; | ||
202 | unsigned int saturation_ctl; | ||
203 | struct ccdc_dft_corr_ctl dft_corr_ctl; | ||
204 | struct ccdc_dft_corr_mem_ctl dft_corr_mem_ctl; | ||
205 | int table_size; | ||
206 | unsigned int dft_corr_horz[CCDC_DFT_TABLE_SIZE]; | ||
207 | unsigned int dft_corr_vert[CCDC_DFT_TABLE_SIZE]; | ||
208 | unsigned int dft_corr_sub1[CCDC_DFT_TABLE_SIZE]; | ||
209 | unsigned int dft_corr_sub2[CCDC_DFT_TABLE_SIZE]; | ||
210 | unsigned int dft_corr_sub3[CCDC_DFT_TABLE_SIZE]; | ||
211 | }; | ||
212 | |||
213 | struct ccdc_data_offset { | ||
214 | unsigned char horz_offset; | ||
215 | unsigned char vert_offset; | ||
216 | }; | ||
217 | |||
218 | /* | ||
219 | * Structure for CCDC configuration parameters for raw capture mode passed | ||
220 | * by application | ||
221 | */ | ||
222 | struct ccdc_config_params_raw { | ||
223 | /* data shift to be applied before storing */ | ||
224 | enum ccdc_datasft datasft; | ||
225 | /* data size value from 8 to 16 bits */ | ||
226 | enum ccdc_data_size data_sz; | ||
227 | /* median filter for sdram */ | ||
228 | enum ccdc_mfilt1 mfilt1; | ||
229 | enum ccdc_mfilt2 mfilt2; | ||
230 | /* low pass filter enable/disable */ | ||
231 | unsigned char lpf_enable; | ||
232 | /* Threshold of median filter */ | ||
233 | int med_filt_thres; | ||
234 | /* | ||
235 | * horz and vertical data offset. Appliable for defect correction | ||
236 | * and lsc | ||
237 | */ | ||
238 | struct ccdc_data_offset data_offset; | ||
239 | /* Structure for Optional A-Law */ | ||
240 | struct ccdc_a_law alaw; | ||
241 | /* Structure for Optical Black Clamp */ | ||
242 | struct ccdc_black_clamp blk_clamp; | ||
243 | /* Structure for Black Compensation */ | ||
244 | struct ccdc_black_compensation blk_comp; | ||
245 | /* struture for vertical Defect Correction Module Configuration */ | ||
246 | struct ccdc_vertical_dft vertical_dft; | ||
247 | /* structure for color space converter Module Configuration */ | ||
248 | struct ccdc_csc csc; | ||
249 | /* color patters for bayer capture */ | ||
250 | struct ccdc_col_pat col_pat_field0; | ||
251 | struct ccdc_col_pat col_pat_field1; | ||
252 | }; | ||
253 | |||
254 | #ifdef __KERNEL__ | ||
255 | #include <linux/io.h> | ||
256 | |||
257 | #define CCDC_WIN_PAL {0, 0, 720, 576} | ||
258 | #define CCDC_WIN_VGA {0, 0, 640, 480} | ||
259 | |||
260 | struct ccdc_params_ycbcr { | ||
261 | /* pixel format */ | ||
262 | enum ccdc_pixfmt pix_fmt; | ||
263 | /* progressive or interlaced frame */ | ||
264 | enum ccdc_frmfmt frm_fmt; | ||
265 | /* video window */ | ||
266 | struct v4l2_rect win; | ||
267 | /* field id polarity */ | ||
268 | enum vpfe_pin_pol fid_pol; | ||
269 | /* vertical sync polarity */ | ||
270 | enum vpfe_pin_pol vd_pol; | ||
271 | /* horizontal sync polarity */ | ||
272 | enum vpfe_pin_pol hd_pol; | ||
273 | /* enable BT.656 embedded sync mode */ | ||
274 | int bt656_enable; | ||
275 | /* cb:y:cr:y or y:cb:y:cr in memory */ | ||
276 | enum ccdc_pixorder pix_order; | ||
277 | /* interleaved or separated fields */ | ||
278 | enum ccdc_buftype buf_type; | ||
279 | }; | ||
280 | |||
281 | /* Gain applied to Raw Bayer data */ | ||
282 | struct ccdc_gain { | ||
283 | unsigned short r_ye; | ||
284 | unsigned short gr_cy; | ||
285 | unsigned short gb_g; | ||
286 | unsigned short b_mg; | ||
287 | }; | ||
288 | |||
289 | /* Structure for CCDC configuration parameters for raw capture mode */ | ||
290 | struct ccdc_params_raw { | ||
291 | /* pixel format */ | ||
292 | enum ccdc_pixfmt pix_fmt; | ||
293 | /* progressive or interlaced frame */ | ||
294 | enum ccdc_frmfmt frm_fmt; | ||
295 | /* video window */ | ||
296 | struct v4l2_rect win; | ||
297 | /* field id polarity */ | ||
298 | enum vpfe_pin_pol fid_pol; | ||
299 | /* vertical sync polarity */ | ||
300 | enum vpfe_pin_pol vd_pol; | ||
301 | /* horizontal sync polarity */ | ||
302 | enum vpfe_pin_pol hd_pol; | ||
303 | /* interleaved or separated fields */ | ||
304 | enum ccdc_buftype buf_type; | ||
305 | /* Gain values */ | ||
306 | struct ccdc_gain gain; | ||
307 | /* offset */ | ||
308 | unsigned int ccdc_offset; | ||
309 | /* horizontal flip enable */ | ||
310 | unsigned char horz_flip_enable; | ||
311 | /* | ||
312 | * enable to store the image in inverse order in memory | ||
313 | * (bottom to top) | ||
314 | */ | ||
315 | unsigned char image_invert_enable; | ||
316 | /* Configurable part of raw data */ | ||
317 | struct ccdc_config_params_raw config_params; | ||
318 | }; | ||
319 | |||
320 | #endif | ||
321 | #endif /* DM355_CCDC_H */ | ||