diff options
author | Muralidharan Karicheri <m-karicheri2@ti.com> | 2009-06-19 08:18:14 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-09-18 23:18:16 -0400 |
commit | 5f15fbb68fd774780a7fa8fe25a88e4c9e518109 (patch) | |
tree | 9c079fb9fd519173eb8e001f802837fdefbd859c | |
parent | dd2ceb1a4028dc9644ed4df80cea9c05ca0b5f6d (diff) |
V4L/DVB (12251): v4l: dm644x ccdc module for vpfe capture driver
This is the hw module for DM644x CCDC. This registers with the
vpfe capture driver and provides a set of hw_ops to configure
CCDC for a specific decoder device connected to the VPFE.
Reviewed by: Hans Verkuil <hverkuil@xs4all.nl>
Reviewed by: Laurent Pinchart <laurent.pinchart@skynet.be>
Signed-off-by: Muralidharan Karicheri <m-karicheri2@ti.com>
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/davinci/dm644x_ccdc.c | 878 | ||||
-rw-r--r-- | drivers/media/video/davinci/dm644x_ccdc_regs.h | 145 | ||||
-rw-r--r-- | include/media/davinci/dm644x_ccdc.h | 184 |
3 files changed, 1207 insertions, 0 deletions
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c new file mode 100644 index 000000000000..2f19a919f477 --- /dev/null +++ b/drivers/media/video/davinci/dm644x_ccdc.c | |||
@@ -0,0 +1,878 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006-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 DM6446 | ||
19 | * ------------------------------ | ||
20 | * | ||
21 | * This module is for configuring CCD controller of DM6446 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 Raw 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 includes dm644x_ccdc.h and vpfe_capture.h header | ||
28 | * files. The setparams() API is called by vpfe_capture driver | ||
29 | * to configure module parameters. This file is named DM644x so that other | ||
30 | * variants such DM6443 may be supported using the same module. | ||
31 | * | ||
32 | * TODO: Test Raw bayer parameter settings and bayer capture | ||
33 | * Split module parameter structure to module specific ioctl structs | ||
34 | * 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/dm644x_ccdc.h> | ||
41 | #include <media/davinci/vpss.h> | ||
42 | #include "dm644x_ccdc_regs.h" | ||
43 | #include "ccdc_hw_device.h" | ||
44 | |||
45 | MODULE_LICENSE("GPL"); | ||
46 | MODULE_DESCRIPTION("CCDC Driver for DM6446"); | ||
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 | .config_params = { | ||
60 | .data_sz = CCDC_DATA_10BITS, | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | /* Object for CCDC ycbcr mode */ | ||
65 | static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = { | ||
66 | .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT, | ||
67 | .frm_fmt = CCDC_FRMFMT_INTERLACED, | ||
68 | .win = CCDC_WIN_PAL, | ||
69 | .fid_pol = VPFE_PINPOL_POSITIVE, | ||
70 | .vd_pol = VPFE_PINPOL_POSITIVE, | ||
71 | .hd_pol = VPFE_PINPOL_POSITIVE, | ||
72 | .bt656_enable = 1, | ||
73 | .pix_order = CCDC_PIXORDER_CBYCRY, | ||
74 | .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED | ||
75 | }; | ||
76 | |||
77 | #define CCDC_MAX_RAW_YUV_FORMATS 2 | ||
78 | |||
79 | /* Raw Bayer formats */ | ||
80 | static u32 ccdc_raw_bayer_pix_formats[] = | ||
81 | {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16}; | ||
82 | |||
83 | /* Raw YUV formats */ | ||
84 | static u32 ccdc_raw_yuv_pix_formats[] = | ||
85 | {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV}; | ||
86 | |||
87 | static void *__iomem ccdc_base_addr; | ||
88 | static int ccdc_addr_size; | ||
89 | static enum vpfe_hw_if_type ccdc_if_type; | ||
90 | |||
91 | /* register access routines */ | ||
92 | static inline u32 regr(u32 offset) | ||
93 | { | ||
94 | return __raw_readl(ccdc_base_addr + offset); | ||
95 | } | ||
96 | |||
97 | static inline void regw(u32 val, u32 offset) | ||
98 | { | ||
99 | __raw_writel(val, ccdc_base_addr + offset); | ||
100 | } | ||
101 | |||
102 | static void ccdc_set_ccdc_base(void *addr, int size) | ||
103 | { | ||
104 | ccdc_base_addr = addr; | ||
105 | ccdc_addr_size = size; | ||
106 | } | ||
107 | |||
108 | static void ccdc_enable(int flag) | ||
109 | { | ||
110 | regw(flag, CCDC_PCR); | ||
111 | } | ||
112 | |||
113 | static void ccdc_enable_vport(int flag) | ||
114 | { | ||
115 | if (flag) | ||
116 | /* enable video port */ | ||
117 | regw(CCDC_ENABLE_VIDEO_PORT, CCDC_FMTCFG); | ||
118 | else | ||
119 | regw(CCDC_DISABLE_VIDEO_PORT, CCDC_FMTCFG); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * ccdc_setwin() | ||
124 | * This function will configure the window size | ||
125 | * to be capture in CCDC reg | ||
126 | */ | ||
127 | void ccdc_setwin(struct v4l2_rect *image_win, | ||
128 | enum ccdc_frmfmt frm_fmt, | ||
129 | int ppc) | ||
130 | { | ||
131 | int horz_start, horz_nr_pixels; | ||
132 | int vert_start, vert_nr_lines; | ||
133 | int val = 0, mid_img = 0; | ||
134 | |||
135 | dev_dbg(dev, "\nStarting ccdc_setwin..."); | ||
136 | /* | ||
137 | * ppc - per pixel count. indicates how many pixels per cell | ||
138 | * output to SDRAM. example, for ycbcr, it is one y and one c, so 2. | ||
139 | * raw capture this is 1 | ||
140 | */ | ||
141 | horz_start = image_win->left << (ppc - 1); | ||
142 | horz_nr_pixels = (image_win->width << (ppc - 1)) - 1; | ||
143 | regw((horz_start << CCDC_HORZ_INFO_SPH_SHIFT) | horz_nr_pixels, | ||
144 | CCDC_HORZ_INFO); | ||
145 | |||
146 | vert_start = image_win->top; | ||
147 | |||
148 | if (frm_fmt == CCDC_FRMFMT_INTERLACED) { | ||
149 | vert_nr_lines = (image_win->height >> 1) - 1; | ||
150 | vert_start >>= 1; | ||
151 | /* Since first line doesn't have any data */ | ||
152 | vert_start += 1; | ||
153 | /* configure VDINT0 */ | ||
154 | val = (vert_start << CCDC_VDINT_VDINT0_SHIFT); | ||
155 | regw(val, CCDC_VDINT); | ||
156 | |||
157 | } else { | ||
158 | /* Since first line doesn't have any data */ | ||
159 | vert_start += 1; | ||
160 | vert_nr_lines = image_win->height - 1; | ||
161 | /* | ||
162 | * configure VDINT0 and VDINT1. VDINT1 will be at half | ||
163 | * of image height | ||
164 | */ | ||
165 | mid_img = vert_start + (image_win->height / 2); | ||
166 | val = (vert_start << CCDC_VDINT_VDINT0_SHIFT) | | ||
167 | (mid_img & CCDC_VDINT_VDINT1_MASK); | ||
168 | regw(val, CCDC_VDINT); | ||
169 | |||
170 | } | ||
171 | regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start, | ||
172 | CCDC_VERT_START); | ||
173 | regw(vert_nr_lines, CCDC_VERT_LINES); | ||
174 | dev_dbg(dev, "\nEnd of ccdc_setwin..."); | ||
175 | } | ||
176 | |||
177 | static void ccdc_readregs(void) | ||
178 | { | ||
179 | unsigned int val = 0; | ||
180 | |||
181 | val = regr(CCDC_ALAW); | ||
182 | dev_notice(dev, "\nReading 0x%x to ALAW...\n", val); | ||
183 | val = regr(CCDC_CLAMP); | ||
184 | dev_notice(dev, "\nReading 0x%x to CLAMP...\n", val); | ||
185 | val = regr(CCDC_DCSUB); | ||
186 | dev_notice(dev, "\nReading 0x%x to DCSUB...\n", val); | ||
187 | val = regr(CCDC_BLKCMP); | ||
188 | dev_notice(dev, "\nReading 0x%x to BLKCMP...\n", val); | ||
189 | val = regr(CCDC_FPC_ADDR); | ||
190 | dev_notice(dev, "\nReading 0x%x to FPC_ADDR...\n", val); | ||
191 | val = regr(CCDC_FPC); | ||
192 | dev_notice(dev, "\nReading 0x%x to FPC...\n", val); | ||
193 | val = regr(CCDC_FMTCFG); | ||
194 | dev_notice(dev, "\nReading 0x%x to FMTCFG...\n", val); | ||
195 | val = regr(CCDC_COLPTN); | ||
196 | dev_notice(dev, "\nReading 0x%x to COLPTN...\n", val); | ||
197 | val = regr(CCDC_FMT_HORZ); | ||
198 | dev_notice(dev, "\nReading 0x%x to FMT_HORZ...\n", val); | ||
199 | val = regr(CCDC_FMT_VERT); | ||
200 | dev_notice(dev, "\nReading 0x%x to FMT_VERT...\n", val); | ||
201 | val = regr(CCDC_HSIZE_OFF); | ||
202 | dev_notice(dev, "\nReading 0x%x to HSIZE_OFF...\n", val); | ||
203 | val = regr(CCDC_SDOFST); | ||
204 | dev_notice(dev, "\nReading 0x%x to SDOFST...\n", val); | ||
205 | val = regr(CCDC_VP_OUT); | ||
206 | dev_notice(dev, "\nReading 0x%x to VP_OUT...\n", val); | ||
207 | val = regr(CCDC_SYN_MODE); | ||
208 | dev_notice(dev, "\nReading 0x%x to SYN_MODE...\n", val); | ||
209 | val = regr(CCDC_HORZ_INFO); | ||
210 | dev_notice(dev, "\nReading 0x%x to HORZ_INFO...\n", val); | ||
211 | val = regr(CCDC_VERT_START); | ||
212 | dev_notice(dev, "\nReading 0x%x to VERT_START...\n", val); | ||
213 | val = regr(CCDC_VERT_LINES); | ||
214 | dev_notice(dev, "\nReading 0x%x to VERT_LINES...\n", val); | ||
215 | } | ||
216 | |||
217 | static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) | ||
218 | { | ||
219 | if (ccdcparam->alaw.enable) { | ||
220 | if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) || | ||
221 | (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) || | ||
222 | (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) { | ||
223 | dev_dbg(dev, "\nInvalid data line select"); | ||
224 | return -1; | ||
225 | } | ||
226 | } | ||
227 | return 0; | ||
228 | } | ||
229 | |||
230 | static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params) | ||
231 | { | ||
232 | struct ccdc_config_params_raw *config_params = | ||
233 | &ccdc_hw_params_raw.config_params; | ||
234 | unsigned int *fpc_virtaddr = NULL; | ||
235 | unsigned int *fpc_physaddr = NULL; | ||
236 | |||
237 | memcpy(config_params, raw_params, sizeof(*raw_params)); | ||
238 | /* | ||
239 | * allocate memory for fault pixel table and copy the user | ||
240 | * values to the table | ||
241 | */ | ||
242 | if (!config_params->fault_pxl.enable) | ||
243 | return 0; | ||
244 | |||
245 | fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr; | ||
246 | fpc_virtaddr = (unsigned int *)phys_to_virt( | ||
247 | (unsigned long)fpc_physaddr); | ||
248 | /* | ||
249 | * Allocate memory for FPC table if current | ||
250 | * FPC table buffer is not big enough to | ||
251 | * accomodate FPC Number requested | ||
252 | */ | ||
253 | if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) { | ||
254 | if (fpc_physaddr != NULL) { | ||
255 | free_pages((unsigned long)fpc_physaddr, | ||
256 | get_order | ||
257 | (config_params->fault_pxl.fp_num * | ||
258 | FP_NUM_BYTES)); | ||
259 | } | ||
260 | |||
261 | /* Allocate memory for FPC table */ | ||
262 | fpc_virtaddr = | ||
263 | (unsigned int *)__get_free_pages(GFP_KERNEL | GFP_DMA, | ||
264 | get_order(raw_params-> | ||
265 | fault_pxl.fp_num * | ||
266 | FP_NUM_BYTES)); | ||
267 | |||
268 | if (fpc_virtaddr == NULL) { | ||
269 | dev_dbg(dev, | ||
270 | "\nUnable to allocate memory for FPC"); | ||
271 | return -EFAULT; | ||
272 | } | ||
273 | fpc_physaddr = | ||
274 | (unsigned int *)virt_to_phys((void *)fpc_virtaddr); | ||
275 | } | ||
276 | |||
277 | /* Copy number of fault pixels and FPC table */ | ||
278 | config_params->fault_pxl.fp_num = raw_params->fault_pxl.fp_num; | ||
279 | if (copy_from_user(fpc_virtaddr, | ||
280 | (void __user *)raw_params->fault_pxl.fpc_table_addr, | ||
281 | config_params->fault_pxl.fp_num * FP_NUM_BYTES)) { | ||
282 | dev_dbg(dev, "\n copy_from_user failed"); | ||
283 | return -EFAULT; | ||
284 | } | ||
285 | config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr; | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static int ccdc_close(struct device *dev) | ||
290 | { | ||
291 | struct ccdc_config_params_raw *config_params = | ||
292 | &ccdc_hw_params_raw.config_params; | ||
293 | unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL; | ||
294 | |||
295 | fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr; | ||
296 | |||
297 | if (fpc_physaddr != NULL) { | ||
298 | fpc_virtaddr = (unsigned int *) | ||
299 | phys_to_virt((unsigned long)fpc_physaddr); | ||
300 | free_pages((unsigned long)fpc_virtaddr, | ||
301 | get_order(config_params->fault_pxl.fp_num * | ||
302 | FP_NUM_BYTES)); | ||
303 | } | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | /* | ||
308 | * ccdc_restore_defaults() | ||
309 | * This function will write defaults to all CCDC registers | ||
310 | */ | ||
311 | static void ccdc_restore_defaults(void) | ||
312 | { | ||
313 | int i; | ||
314 | |||
315 | /* disable CCDC */ | ||
316 | ccdc_enable(0); | ||
317 | /* set all registers to default value */ | ||
318 | for (i = 4; i <= 0x94; i += 4) | ||
319 | regw(0, i); | ||
320 | regw(CCDC_NO_CULLING, CCDC_CULLING); | ||
321 | regw(CCDC_GAMMA_BITS_11_2, CCDC_ALAW); | ||
322 | } | ||
323 | |||
324 | static int ccdc_open(struct device *device) | ||
325 | { | ||
326 | dev = device; | ||
327 | ccdc_restore_defaults(); | ||
328 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
329 | ccdc_enable_vport(1); | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static void ccdc_sbl_reset(void) | ||
334 | { | ||
335 | vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O); | ||
336 | } | ||
337 | |||
338 | /* Parameter operations */ | ||
339 | static int ccdc_set_params(void __user *params) | ||
340 | { | ||
341 | struct ccdc_config_params_raw ccdc_raw_params; | ||
342 | int x; | ||
343 | |||
344 | if (ccdc_if_type != VPFE_RAW_BAYER) | ||
345 | return -EINVAL; | ||
346 | |||
347 | x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); | ||
348 | if (x) { | ||
349 | dev_dbg(dev, "ccdc_set_params: error in copying" | ||
350 | "ccdc params, %d\n", x); | ||
351 | return -EFAULT; | ||
352 | } | ||
353 | |||
354 | if (!validate_ccdc_param(&ccdc_raw_params)) { | ||
355 | if (!ccdc_update_raw_params(&ccdc_raw_params)) | ||
356 | return 0; | ||
357 | } | ||
358 | return -EINVAL; | ||
359 | } | ||
360 | |||
361 | /* | ||
362 | * ccdc_config_ycbcr() | ||
363 | * This function will configure CCDC for YCbCr video capture | ||
364 | */ | ||
365 | void ccdc_config_ycbcr(void) | ||
366 | { | ||
367 | struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr; | ||
368 | u32 syn_mode; | ||
369 | |||
370 | dev_dbg(dev, "\nStarting ccdc_config_ycbcr..."); | ||
371 | /* | ||
372 | * first restore the CCDC registers to default values | ||
373 | * This is important since we assume default values to be set in | ||
374 | * a lot of registers that we didn't touch | ||
375 | */ | ||
376 | ccdc_restore_defaults(); | ||
377 | |||
378 | /* | ||
379 | * configure pixel format, frame format, configure video frame | ||
380 | * format, enable output to SDRAM, enable internal timing generator | ||
381 | * and 8bit pack mode | ||
382 | */ | ||
383 | syn_mode = (((params->pix_fmt & CCDC_SYN_MODE_INPMOD_MASK) << | ||
384 | CCDC_SYN_MODE_INPMOD_SHIFT) | | ||
385 | ((params->frm_fmt & CCDC_SYN_FLDMODE_MASK) << | ||
386 | CCDC_SYN_FLDMODE_SHIFT) | CCDC_VDHDEN_ENABLE | | ||
387 | CCDC_WEN_ENABLE | CCDC_DATA_PACK_ENABLE); | ||
388 | |||
389 | /* setup BT.656 sync mode */ | ||
390 | if (params->bt656_enable) { | ||
391 | regw(CCDC_REC656IF_BT656_EN, CCDC_REC656IF); | ||
392 | |||
393 | /* | ||
394 | * configure the FID, VD, HD pin polarity, | ||
395 | * fld,hd pol positive, vd negative, 8-bit data | ||
396 | */ | ||
397 | syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE | CCDC_SYN_MODE_8BITS; | ||
398 | } else { | ||
399 | /* y/c external sync mode */ | ||
400 | syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) << | ||
401 | CCDC_FID_POL_SHIFT) | | ||
402 | ((params->hd_pol & CCDC_HD_POL_MASK) << | ||
403 | CCDC_HD_POL_SHIFT) | | ||
404 | ((params->vd_pol & CCDC_VD_POL_MASK) << | ||
405 | CCDC_VD_POL_SHIFT)); | ||
406 | } | ||
407 | regw(syn_mode, CCDC_SYN_MODE); | ||
408 | |||
409 | /* configure video window */ | ||
410 | ccdc_setwin(¶ms->win, params->frm_fmt, 2); | ||
411 | |||
412 | /* | ||
413 | * configure the order of y cb cr in SDRAM, and disable latch | ||
414 | * internal register on vsync | ||
415 | */ | ||
416 | regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) | | ||
417 | CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG); | ||
418 | |||
419 | /* | ||
420 | * configure the horizontal line offset. This should be a | ||
421 | * on 32 byte bondary. So clear LSB 5 bits | ||
422 | */ | ||
423 | regw(((params->win.width * 2 + 31) & ~0x1f), CCDC_HSIZE_OFF); | ||
424 | |||
425 | /* configure the memory line offset */ | ||
426 | if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) | ||
427 | /* two fields are interleaved in memory */ | ||
428 | regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST); | ||
429 | |||
430 | ccdc_sbl_reset(); | ||
431 | dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n"); | ||
432 | ccdc_readregs(); | ||
433 | } | ||
434 | |||
435 | static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp) | ||
436 | { | ||
437 | u32 val; | ||
438 | |||
439 | if (!bclamp->enable) { | ||
440 | /* configure DCSub */ | ||
441 | val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK; | ||
442 | regw(val, CCDC_DCSUB); | ||
443 | dev_dbg(dev, "\nWriting 0x%x to DCSUB...\n", val); | ||
444 | regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP); | ||
445 | dev_dbg(dev, "\nWriting 0x0000 to CLAMP...\n"); | ||
446 | return; | ||
447 | } | ||
448 | /* | ||
449 | * Configure gain, Start pixel, No of line to be avg, | ||
450 | * No of pixel/line to be avg, & Enable the Black clamping | ||
451 | */ | ||
452 | val = ((bclamp->sgain & CCDC_BLK_SGAIN_MASK) | | ||
453 | ((bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) << | ||
454 | CCDC_BLK_ST_PXL_SHIFT) | | ||
455 | ((bclamp->sample_ln & CCDC_BLK_SAMPLE_LINE_MASK) << | ||
456 | CCDC_BLK_SAMPLE_LINE_SHIFT) | | ||
457 | ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) << | ||
458 | CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE); | ||
459 | regw(val, CCDC_CLAMP); | ||
460 | dev_dbg(dev, "\nWriting 0x%x to CLAMP...\n", val); | ||
461 | /* If Black clamping is enable then make dcsub 0 */ | ||
462 | regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB); | ||
463 | dev_dbg(dev, "\nWriting 0x00000000 to DCSUB...\n"); | ||
464 | } | ||
465 | |||
466 | static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp) | ||
467 | { | ||
468 | u32 val; | ||
469 | |||
470 | val = ((bcomp->b & CCDC_BLK_COMP_MASK) | | ||
471 | ((bcomp->gb & CCDC_BLK_COMP_MASK) << | ||
472 | CCDC_BLK_COMP_GB_COMP_SHIFT) | | ||
473 | ((bcomp->gr & CCDC_BLK_COMP_MASK) << | ||
474 | CCDC_BLK_COMP_GR_COMP_SHIFT) | | ||
475 | ((bcomp->r & CCDC_BLK_COMP_MASK) << | ||
476 | CCDC_BLK_COMP_R_COMP_SHIFT)); | ||
477 | regw(val, CCDC_BLKCMP); | ||
478 | } | ||
479 | |||
480 | static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc) | ||
481 | { | ||
482 | u32 val; | ||
483 | |||
484 | /* Initially disable FPC */ | ||
485 | val = CCDC_FPC_DISABLE; | ||
486 | regw(val, CCDC_FPC); | ||
487 | |||
488 | if (!fpc->enable) | ||
489 | return; | ||
490 | |||
491 | /* Configure Fault pixel if needed */ | ||
492 | regw(fpc->fpc_table_addr, CCDC_FPC_ADDR); | ||
493 | dev_dbg(dev, "\nWriting 0x%x to FPC_ADDR...\n", | ||
494 | (fpc->fpc_table_addr)); | ||
495 | /* Write the FPC params with FPC disable */ | ||
496 | val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK; | ||
497 | regw(val, CCDC_FPC); | ||
498 | |||
499 | dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val); | ||
500 | /* read the FPC register */ | ||
501 | val = regr(CCDC_FPC) | CCDC_FPC_ENABLE; | ||
502 | regw(val, CCDC_FPC); | ||
503 | dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val); | ||
504 | } | ||
505 | |||
506 | /* | ||
507 | * ccdc_config_raw() | ||
508 | * This function will configure CCDC for Raw capture mode | ||
509 | */ | ||
510 | void ccdc_config_raw(void) | ||
511 | { | ||
512 | struct ccdc_params_raw *params = &ccdc_hw_params_raw; | ||
513 | struct ccdc_config_params_raw *config_params = | ||
514 | &ccdc_hw_params_raw.config_params; | ||
515 | unsigned int syn_mode = 0; | ||
516 | unsigned int val; | ||
517 | |||
518 | dev_dbg(dev, "\nStarting ccdc_config_raw..."); | ||
519 | |||
520 | /* Reset CCDC */ | ||
521 | ccdc_restore_defaults(); | ||
522 | |||
523 | /* Disable latching function registers on VSYNC */ | ||
524 | regw(CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG); | ||
525 | |||
526 | /* | ||
527 | * Configure the vertical sync polarity(SYN_MODE.VDPOL), | ||
528 | * horizontal sync polarity (SYN_MODE.HDPOL), frame id polarity | ||
529 | * (SYN_MODE.FLDPOL), frame format(progressive or interlace), | ||
530 | * data size(SYNMODE.DATSIZ), &pixel format (Input mode), output | ||
531 | * SDRAM, enable internal timing generator | ||
532 | */ | ||
533 | syn_mode = | ||
534 | (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) | | ||
535 | ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) | | ||
536 | ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) | | ||
537 | ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) | | ||
538 | ((config_params->data_sz & CCDC_DATA_SZ_MASK) << | ||
539 | CCDC_DATA_SZ_SHIFT) | | ||
540 | ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT) | | ||
541 | CCDC_WEN_ENABLE | CCDC_VDHDEN_ENABLE); | ||
542 | |||
543 | /* Enable and configure aLaw register if needed */ | ||
544 | if (config_params->alaw.enable) { | ||
545 | val = ((config_params->alaw.gama_wd & | ||
546 | CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE); | ||
547 | regw(val, CCDC_ALAW); | ||
548 | dev_dbg(dev, "\nWriting 0x%x to ALAW...\n", val); | ||
549 | } | ||
550 | |||
551 | /* Configure video window */ | ||
552 | ccdc_setwin(¶ms->win, params->frm_fmt, CCDC_PPC_RAW); | ||
553 | |||
554 | /* Configure Black Clamp */ | ||
555 | ccdc_config_black_clamp(&config_params->blk_clamp); | ||
556 | |||
557 | /* Configure Black level compensation */ | ||
558 | ccdc_config_black_compense(&config_params->blk_comp); | ||
559 | |||
560 | /* Configure Fault Pixel Correction */ | ||
561 | ccdc_config_fpc(&config_params->fault_pxl); | ||
562 | |||
563 | /* If data size is 8 bit then pack the data */ | ||
564 | if ((config_params->data_sz == CCDC_DATA_8BITS) || | ||
565 | config_params->alaw.enable) | ||
566 | syn_mode |= CCDC_DATA_PACK_ENABLE; | ||
567 | |||
568 | #ifdef CONFIG_DM644X_VIDEO_PORT_ENABLE | ||
569 | /* enable video port */ | ||
570 | val = CCDC_ENABLE_VIDEO_PORT; | ||
571 | #else | ||
572 | /* disable video port */ | ||
573 | val = CCDC_DISABLE_VIDEO_PORT; | ||
574 | #endif | ||
575 | |||
576 | if (config_params->data_sz == CCDC_DATA_8BITS) | ||
577 | val |= (CCDC_DATA_10BITS & CCDC_FMTCFG_VPIN_MASK) | ||
578 | << CCDC_FMTCFG_VPIN_SHIFT; | ||
579 | else | ||
580 | val |= (config_params->data_sz & CCDC_FMTCFG_VPIN_MASK) | ||
581 | << CCDC_FMTCFG_VPIN_SHIFT; | ||
582 | /* Write value in FMTCFG */ | ||
583 | regw(val, CCDC_FMTCFG); | ||
584 | |||
585 | dev_dbg(dev, "\nWriting 0x%x to FMTCFG...\n", val); | ||
586 | /* Configure the color pattern according to mt9t001 sensor */ | ||
587 | regw(CCDC_COLPTN_VAL, CCDC_COLPTN); | ||
588 | |||
589 | dev_dbg(dev, "\nWriting 0xBB11BB11 to COLPTN...\n"); | ||
590 | /* | ||
591 | * Configure Data formatter(Video port) pixel selection | ||
592 | * (FMT_HORZ, FMT_VERT) | ||
593 | */ | ||
594 | val = ((params->win.left & CCDC_FMT_HORZ_FMTSPH_MASK) << | ||
595 | CCDC_FMT_HORZ_FMTSPH_SHIFT) | | ||
596 | (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK); | ||
597 | regw(val, CCDC_FMT_HORZ); | ||
598 | |||
599 | dev_dbg(dev, "\nWriting 0x%x to FMT_HORZ...\n", val); | ||
600 | val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK) | ||
601 | << CCDC_FMT_VERT_FMTSLV_SHIFT; | ||
602 | if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) | ||
603 | val |= (params->win.height) & CCDC_FMT_VERT_FMTLNV_MASK; | ||
604 | else | ||
605 | val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK; | ||
606 | |||
607 | dev_dbg(dev, "\nparams->win.height 0x%x ...\n", | ||
608 | params->win.height); | ||
609 | regw(val, CCDC_FMT_VERT); | ||
610 | |||
611 | dev_dbg(dev, "\nWriting 0x%x to FMT_VERT...\n", val); | ||
612 | |||
613 | dev_dbg(dev, "\nbelow regw(val, FMT_VERT)..."); | ||
614 | |||
615 | /* | ||
616 | * Configure Horizontal offset register. If pack 8 is enabled then | ||
617 | * 1 pixel will take 1 byte | ||
618 | */ | ||
619 | if ((config_params->data_sz == CCDC_DATA_8BITS) || | ||
620 | config_params->alaw.enable) | ||
621 | regw((params->win.width + CCDC_32BYTE_ALIGN_VAL) & | ||
622 | CCDC_HSIZE_OFF_MASK, CCDC_HSIZE_OFF); | ||
623 | else | ||
624 | /* else one pixel will take 2 byte */ | ||
625 | regw(((params->win.width * CCDC_TWO_BYTES_PER_PIXEL) + | ||
626 | CCDC_32BYTE_ALIGN_VAL) & CCDC_HSIZE_OFF_MASK, | ||
627 | CCDC_HSIZE_OFF); | ||
628 | |||
629 | /* Set value for SDOFST */ | ||
630 | if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) { | ||
631 | if (params->image_invert_enable) { | ||
632 | /* For intelace inverse mode */ | ||
633 | regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST); | ||
634 | dev_dbg(dev, "\nWriting 0x4B6D to SDOFST...\n"); | ||
635 | } | ||
636 | |||
637 | else { | ||
638 | /* For intelace non inverse mode */ | ||
639 | regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST); | ||
640 | dev_dbg(dev, "\nWriting 0x0249 to SDOFST...\n"); | ||
641 | } | ||
642 | } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) { | ||
643 | regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST); | ||
644 | dev_dbg(dev, "\nWriting 0x0000 to SDOFST...\n"); | ||
645 | } | ||
646 | |||
647 | /* | ||
648 | * Configure video port pixel selection (VPOUT) | ||
649 | * Here -1 is to make the height value less than FMT_VERT.FMTLNV | ||
650 | */ | ||
651 | if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) | ||
652 | val = (((params->win.height - 1) & CCDC_VP_OUT_VERT_NUM_MASK)) | ||
653 | << CCDC_VP_OUT_VERT_NUM_SHIFT; | ||
654 | else | ||
655 | val = | ||
656 | ((((params->win.height >> CCDC_INTERLACED_HEIGHT_SHIFT) - | ||
657 | 1) & CCDC_VP_OUT_VERT_NUM_MASK)) << | ||
658 | CCDC_VP_OUT_VERT_NUM_SHIFT; | ||
659 | |||
660 | val |= ((((params->win.width))) & CCDC_VP_OUT_HORZ_NUM_MASK) | ||
661 | << CCDC_VP_OUT_HORZ_NUM_SHIFT; | ||
662 | val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK; | ||
663 | regw(val, CCDC_VP_OUT); | ||
664 | |||
665 | dev_dbg(dev, "\nWriting 0x%x to VP_OUT...\n", val); | ||
666 | regw(syn_mode, CCDC_SYN_MODE); | ||
667 | dev_dbg(dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode); | ||
668 | |||
669 | ccdc_sbl_reset(); | ||
670 | dev_dbg(dev, "\nend of ccdc_config_raw..."); | ||
671 | ccdc_readregs(); | ||
672 | } | ||
673 | |||
674 | static int ccdc_configure(void) | ||
675 | { | ||
676 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
677 | ccdc_config_raw(); | ||
678 | else | ||
679 | ccdc_config_ycbcr(); | ||
680 | return 0; | ||
681 | } | ||
682 | |||
683 | static int ccdc_set_buftype(enum ccdc_buftype buf_type) | ||
684 | { | ||
685 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
686 | ccdc_hw_params_raw.buf_type = buf_type; | ||
687 | else | ||
688 | ccdc_hw_params_ycbcr.buf_type = buf_type; | ||
689 | return 0; | ||
690 | } | ||
691 | |||
692 | static enum ccdc_buftype ccdc_get_buftype(void) | ||
693 | { | ||
694 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
695 | return ccdc_hw_params_raw.buf_type; | ||
696 | return ccdc_hw_params_ycbcr.buf_type; | ||
697 | } | ||
698 | |||
699 | static int ccdc_enum_pix(u32 *pix, int i) | ||
700 | { | ||
701 | int ret = -EINVAL; | ||
702 | if (ccdc_if_type == VPFE_RAW_BAYER) { | ||
703 | if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) { | ||
704 | *pix = ccdc_raw_bayer_pix_formats[i]; | ||
705 | ret = 0; | ||
706 | } | ||
707 | } else { | ||
708 | if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) { | ||
709 | *pix = ccdc_raw_yuv_pix_formats[i]; | ||
710 | ret = 0; | ||
711 | } | ||
712 | } | ||
713 | return ret; | ||
714 | } | ||
715 | |||
716 | static int ccdc_set_pixel_format(u32 pixfmt) | ||
717 | { | ||
718 | if (ccdc_if_type == VPFE_RAW_BAYER) { | ||
719 | ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW; | ||
720 | if (pixfmt == V4L2_PIX_FMT_SBGGR8) | ||
721 | ccdc_hw_params_raw.config_params.alaw.enable = 1; | ||
722 | else if (pixfmt != V4L2_PIX_FMT_SBGGR16) | ||
723 | return -EINVAL; | ||
724 | } else { | ||
725 | if (pixfmt == V4L2_PIX_FMT_YUYV) | ||
726 | ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR; | ||
727 | else if (pixfmt == V4L2_PIX_FMT_UYVY) | ||
728 | ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY; | ||
729 | else | ||
730 | return -EINVAL; | ||
731 | } | ||
732 | return 0; | ||
733 | } | ||
734 | |||
735 | static u32 ccdc_get_pixel_format(void) | ||
736 | { | ||
737 | struct ccdc_a_law *alaw = | ||
738 | &ccdc_hw_params_raw.config_params.alaw; | ||
739 | u32 pixfmt; | ||
740 | |||
741 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
742 | if (alaw->enable) | ||
743 | pixfmt = V4L2_PIX_FMT_SBGGR8; | ||
744 | else | ||
745 | pixfmt = V4L2_PIX_FMT_SBGGR16; | ||
746 | else { | ||
747 | if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR) | ||
748 | pixfmt = V4L2_PIX_FMT_YUYV; | ||
749 | else | ||
750 | pixfmt = V4L2_PIX_FMT_UYVY; | ||
751 | } | ||
752 | return pixfmt; | ||
753 | } | ||
754 | |||
755 | static int ccdc_set_image_window(struct v4l2_rect *win) | ||
756 | { | ||
757 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
758 | ccdc_hw_params_raw.win = *win; | ||
759 | else | ||
760 | ccdc_hw_params_ycbcr.win = *win; | ||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static void ccdc_get_image_window(struct v4l2_rect *win) | ||
765 | { | ||
766 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
767 | *win = ccdc_hw_params_raw.win; | ||
768 | else | ||
769 | *win = ccdc_hw_params_ycbcr.win; | ||
770 | } | ||
771 | |||
772 | static unsigned int ccdc_get_line_length(void) | ||
773 | { | ||
774 | struct ccdc_config_params_raw *config_params = | ||
775 | &ccdc_hw_params_raw.config_params; | ||
776 | unsigned int len; | ||
777 | |||
778 | if (ccdc_if_type == VPFE_RAW_BAYER) { | ||
779 | if ((config_params->alaw.enable) || | ||
780 | (config_params->data_sz == CCDC_DATA_8BITS)) | ||
781 | len = ccdc_hw_params_raw.win.width; | ||
782 | else | ||
783 | len = ccdc_hw_params_raw.win.width * 2; | ||
784 | } else | ||
785 | len = ccdc_hw_params_ycbcr.win.width * 2; | ||
786 | return ALIGN(len, 32); | ||
787 | } | ||
788 | |||
789 | static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt) | ||
790 | { | ||
791 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
792 | ccdc_hw_params_raw.frm_fmt = frm_fmt; | ||
793 | else | ||
794 | ccdc_hw_params_ycbcr.frm_fmt = frm_fmt; | ||
795 | return 0; | ||
796 | } | ||
797 | |||
798 | static enum ccdc_frmfmt ccdc_get_frame_format(void) | ||
799 | { | ||
800 | if (ccdc_if_type == VPFE_RAW_BAYER) | ||
801 | return ccdc_hw_params_raw.frm_fmt; | ||
802 | else | ||
803 | return ccdc_hw_params_ycbcr.frm_fmt; | ||
804 | } | ||
805 | |||
806 | static int ccdc_getfid(void) | ||
807 | { | ||
808 | return (regr(CCDC_SYN_MODE) >> 15) & 1; | ||
809 | } | ||
810 | |||
811 | /* misc operations */ | ||
812 | static inline void ccdc_setfbaddr(unsigned long addr) | ||
813 | { | ||
814 | regw(addr & 0xffffffe0, CCDC_SDR_ADDR); | ||
815 | } | ||
816 | |||
817 | static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params) | ||
818 | { | ||
819 | ccdc_if_type = params->if_type; | ||
820 | |||
821 | switch (params->if_type) { | ||
822 | case VPFE_BT656: | ||
823 | case VPFE_YCBCR_SYNC_16: | ||
824 | case VPFE_YCBCR_SYNC_8: | ||
825 | ccdc_hw_params_ycbcr.vd_pol = params->vdpol; | ||
826 | ccdc_hw_params_ycbcr.hd_pol = params->hdpol; | ||
827 | break; | ||
828 | default: | ||
829 | /* TODO add support for raw bayer here */ | ||
830 | return -EINVAL; | ||
831 | } | ||
832 | return 0; | ||
833 | } | ||
834 | |||
835 | static struct ccdc_hw_device ccdc_hw_dev = { | ||
836 | .name = "DM6446 CCDC", | ||
837 | .owner = THIS_MODULE, | ||
838 | .hw_ops = { | ||
839 | .open = ccdc_open, | ||
840 | .close = ccdc_close, | ||
841 | .set_ccdc_base = ccdc_set_ccdc_base, | ||
842 | .reset = ccdc_sbl_reset, | ||
843 | .enable = ccdc_enable, | ||
844 | .set_hw_if_params = ccdc_set_hw_if_params, | ||
845 | .set_params = ccdc_set_params, | ||
846 | .configure = ccdc_configure, | ||
847 | .set_buftype = ccdc_set_buftype, | ||
848 | .get_buftype = ccdc_get_buftype, | ||
849 | .enum_pix = ccdc_enum_pix, | ||
850 | .set_pixel_format = ccdc_set_pixel_format, | ||
851 | .get_pixel_format = ccdc_get_pixel_format, | ||
852 | .set_frame_format = ccdc_set_frame_format, | ||
853 | .get_frame_format = ccdc_get_frame_format, | ||
854 | .set_image_window = ccdc_set_image_window, | ||
855 | .get_image_window = ccdc_get_image_window, | ||
856 | .get_line_length = ccdc_get_line_length, | ||
857 | .setfbaddr = ccdc_setfbaddr, | ||
858 | .getfid = ccdc_getfid, | ||
859 | }, | ||
860 | }; | ||
861 | |||
862 | static int dm644x_ccdc_init(void) | ||
863 | { | ||
864 | printk(KERN_NOTICE "dm644x_ccdc_init\n"); | ||
865 | if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) | ||
866 | return -1; | ||
867 | printk(KERN_NOTICE "%s is registered with vpfe.\n", | ||
868 | ccdc_hw_dev.name); | ||
869 | return 0; | ||
870 | } | ||
871 | |||
872 | static void dm644x_ccdc_exit(void) | ||
873 | { | ||
874 | vpfe_unregister_ccdc_device(&ccdc_hw_dev); | ||
875 | } | ||
876 | |||
877 | module_init(dm644x_ccdc_init); | ||
878 | module_exit(dm644x_ccdc_exit); | ||
diff --git a/drivers/media/video/davinci/dm644x_ccdc_regs.h b/drivers/media/video/davinci/dm644x_ccdc_regs.h new file mode 100644 index 000000000000..6e5d05324466 --- /dev/null +++ b/drivers/media/video/davinci/dm644x_ccdc_regs.h | |||
@@ -0,0 +1,145 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006-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 _DM644X_CCDC_REGS_H | ||
19 | #define _DM644X_CCDC_REGS_H | ||
20 | |||
21 | /**************************************************************************\ | ||
22 | * Register OFFSET Definitions | ||
23 | \**************************************************************************/ | ||
24 | #define CCDC_PID 0x0 | ||
25 | #define CCDC_PCR 0x4 | ||
26 | #define CCDC_SYN_MODE 0x8 | ||
27 | #define CCDC_HD_VD_WID 0xc | ||
28 | #define CCDC_PIX_LINES 0x10 | ||
29 | #define CCDC_HORZ_INFO 0x14 | ||
30 | #define CCDC_VERT_START 0x18 | ||
31 | #define CCDC_VERT_LINES 0x1c | ||
32 | #define CCDC_CULLING 0x20 | ||
33 | #define CCDC_HSIZE_OFF 0x24 | ||
34 | #define CCDC_SDOFST 0x28 | ||
35 | #define CCDC_SDR_ADDR 0x2c | ||
36 | #define CCDC_CLAMP 0x30 | ||
37 | #define CCDC_DCSUB 0x34 | ||
38 | #define CCDC_COLPTN 0x38 | ||
39 | #define CCDC_BLKCMP 0x3c | ||
40 | #define CCDC_FPC 0x40 | ||
41 | #define CCDC_FPC_ADDR 0x44 | ||
42 | #define CCDC_VDINT 0x48 | ||
43 | #define CCDC_ALAW 0x4c | ||
44 | #define CCDC_REC656IF 0x50 | ||
45 | #define CCDC_CCDCFG 0x54 | ||
46 | #define CCDC_FMTCFG 0x58 | ||
47 | #define CCDC_FMT_HORZ 0x5c | ||
48 | #define CCDC_FMT_VERT 0x60 | ||
49 | #define CCDC_FMT_ADDR0 0x64 | ||
50 | #define CCDC_FMT_ADDR1 0x68 | ||
51 | #define CCDC_FMT_ADDR2 0x6c | ||
52 | #define CCDC_FMT_ADDR3 0x70 | ||
53 | #define CCDC_FMT_ADDR4 0x74 | ||
54 | #define CCDC_FMT_ADDR5 0x78 | ||
55 | #define CCDC_FMT_ADDR6 0x7c | ||
56 | #define CCDC_FMT_ADDR7 0x80 | ||
57 | #define CCDC_PRGEVEN_0 0x84 | ||
58 | #define CCDC_PRGEVEN_1 0x88 | ||
59 | #define CCDC_PRGODD_0 0x8c | ||
60 | #define CCDC_PRGODD_1 0x90 | ||
61 | #define CCDC_VP_OUT 0x94 | ||
62 | |||
63 | |||
64 | /*************************************************************** | ||
65 | * Define for various register bit mask and shifts for CCDC | ||
66 | ****************************************************************/ | ||
67 | #define CCDC_FID_POL_MASK 1 | ||
68 | #define CCDC_FID_POL_SHIFT 4 | ||
69 | #define CCDC_HD_POL_MASK 1 | ||
70 | #define CCDC_HD_POL_SHIFT 3 | ||
71 | #define CCDC_VD_POL_MASK 1 | ||
72 | #define CCDC_VD_POL_SHIFT 2 | ||
73 | #define CCDC_HSIZE_OFF_MASK 0xffffffe0 | ||
74 | #define CCDC_32BYTE_ALIGN_VAL 31 | ||
75 | #define CCDC_FRM_FMT_MASK 0x1 | ||
76 | #define CCDC_FRM_FMT_SHIFT 7 | ||
77 | #define CCDC_DATA_SZ_MASK 7 | ||
78 | #define CCDC_DATA_SZ_SHIFT 8 | ||
79 | #define CCDC_PIX_FMT_MASK 3 | ||
80 | #define CCDC_PIX_FMT_SHIFT 12 | ||
81 | #define CCDC_VP2SDR_DISABLE 0xFFFBFFFF | ||
82 | #define CCDC_WEN_ENABLE (1 << 17) | ||
83 | #define CCDC_SDR2RSZ_DISABLE 0xFFF7FFFF | ||
84 | #define CCDC_VDHDEN_ENABLE (1 << 16) | ||
85 | #define CCDC_LPF_ENABLE (1 << 14) | ||
86 | #define CCDC_ALAW_ENABLE (1 << 3) | ||
87 | #define CCDC_ALAW_GAMA_WD_MASK 7 | ||
88 | #define CCDC_BLK_CLAMP_ENABLE (1 << 31) | ||
89 | #define CCDC_BLK_SGAIN_MASK 0x1F | ||
90 | #define CCDC_BLK_ST_PXL_MASK 0x7FFF | ||
91 | #define CCDC_BLK_ST_PXL_SHIFT 10 | ||
92 | #define CCDC_BLK_SAMPLE_LN_MASK 7 | ||
93 | #define CCDC_BLK_SAMPLE_LN_SHIFT 28 | ||
94 | #define CCDC_BLK_SAMPLE_LINE_MASK 7 | ||
95 | #define CCDC_BLK_SAMPLE_LINE_SHIFT 25 | ||
96 | #define CCDC_BLK_DC_SUB_MASK 0x03FFF | ||
97 | #define CCDC_BLK_COMP_MASK 0xFF | ||
98 | #define CCDC_BLK_COMP_GB_COMP_SHIFT 8 | ||
99 | #define CCDC_BLK_COMP_GR_COMP_SHIFT 16 | ||
100 | #define CCDC_BLK_COMP_R_COMP_SHIFT 24 | ||
101 | #define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15) | ||
102 | #define CCDC_FPC_ENABLE (1 << 15) | ||
103 | #define CCDC_FPC_DISABLE 0 | ||
104 | #define CCDC_FPC_FPC_NUM_MASK 0x7FFF | ||
105 | #define CCDC_DATA_PACK_ENABLE (1 << 11) | ||
106 | #define CCDC_FMTCFG_VPIN_MASK 7 | ||
107 | #define CCDC_FMTCFG_VPIN_SHIFT 12 | ||
108 | #define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF | ||
109 | #define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF | ||
110 | #define CCDC_FMT_HORZ_FMTSPH_SHIFT 16 | ||
111 | #define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF | ||
112 | #define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF | ||
113 | #define CCDC_FMT_VERT_FMTSLV_SHIFT 16 | ||
114 | #define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF | ||
115 | #define CCDC_VP_OUT_VERT_NUM_SHIFT 17 | ||
116 | #define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF | ||
117 | #define CCDC_VP_OUT_HORZ_NUM_SHIFT 4 | ||
118 | #define CCDC_VP_OUT_HORZ_ST_MASK 0xF | ||
119 | #define CCDC_HORZ_INFO_SPH_SHIFT 16 | ||
120 | #define CCDC_VERT_START_SLV0_SHIFT 16 | ||
121 | #define CCDC_VDINT_VDINT0_SHIFT 16 | ||
122 | #define CCDC_VDINT_VDINT1_MASK 0xFFFF | ||
123 | #define CCDC_PPC_RAW 1 | ||
124 | #define CCDC_DCSUB_DEFAULT_VAL 0 | ||
125 | #define CCDC_CLAMP_DEFAULT_VAL 0 | ||
126 | #define CCDC_ENABLE_VIDEO_PORT 0x8000 | ||
127 | #define CCDC_DISABLE_VIDEO_PORT 0 | ||
128 | #define CCDC_COLPTN_VAL 0xBB11BB11 | ||
129 | #define CCDC_TWO_BYTES_PER_PIXEL 2 | ||
130 | #define CCDC_INTERLACED_IMAGE_INVERT 0x4B6D | ||
131 | #define CCDC_INTERLACED_NO_IMAGE_INVERT 0x0249 | ||
132 | #define CCDC_PROGRESSIVE_IMAGE_INVERT 0x4000 | ||
133 | #define CCDC_PROGRESSIVE_NO_IMAGE_INVERT 0 | ||
134 | #define CCDC_INTERLACED_HEIGHT_SHIFT 1 | ||
135 | #define CCDC_SYN_MODE_INPMOD_SHIFT 12 | ||
136 | #define CCDC_SYN_MODE_INPMOD_MASK 3 | ||
137 | #define CCDC_SYN_MODE_8BITS (7 << 8) | ||
138 | #define CCDC_SYN_FLDMODE_MASK 1 | ||
139 | #define CCDC_SYN_FLDMODE_SHIFT 7 | ||
140 | #define CCDC_REC656IF_BT656_EN 3 | ||
141 | #define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2) | ||
142 | #define CCDC_CCDCFG_Y8POS_SHIFT 11 | ||
143 | #define CCDC_SDOFST_FIELD_INTERLEAVED 0x249 | ||
144 | #define CCDC_NO_CULLING 0xffff00ff | ||
145 | #endif | ||
diff --git a/include/media/davinci/dm644x_ccdc.h b/include/media/davinci/dm644x_ccdc.h new file mode 100644 index 000000000000..3e178eb52fb3 --- /dev/null +++ b/include/media/davinci/dm644x_ccdc.h | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006-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 _DM644X_CCDC_H | ||
19 | #define _DM644X_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_gama_width { | ||
43 | CCDC_GAMMA_BITS_15_6, | ||
44 | CCDC_GAMMA_BITS_14_5, | ||
45 | CCDC_GAMMA_BITS_13_4, | ||
46 | CCDC_GAMMA_BITS_12_3, | ||
47 | CCDC_GAMMA_BITS_11_2, | ||
48 | CCDC_GAMMA_BITS_10_1, | ||
49 | CCDC_GAMMA_BITS_09_0 | ||
50 | }; | ||
51 | |||
52 | enum ccdc_data_size { | ||
53 | CCDC_DATA_16BITS, | ||
54 | CCDC_DATA_15BITS, | ||
55 | CCDC_DATA_14BITS, | ||
56 | CCDC_DATA_13BITS, | ||
57 | CCDC_DATA_12BITS, | ||
58 | CCDC_DATA_11BITS, | ||
59 | CCDC_DATA_10BITS, | ||
60 | CCDC_DATA_8BITS | ||
61 | }; | ||
62 | |||
63 | /* structure for ALaw */ | ||
64 | struct ccdc_a_law { | ||
65 | /* Enable/disable A-Law */ | ||
66 | unsigned char enable; | ||
67 | /* Gama Width Input */ | ||
68 | enum ccdc_gama_width gama_wd; | ||
69 | }; | ||
70 | |||
71 | /* structure for Black Clamping */ | ||
72 | struct ccdc_black_clamp { | ||
73 | unsigned char enable; | ||
74 | /* only if bClampEnable is TRUE */ | ||
75 | enum ccdc_sample_length sample_pixel; | ||
76 | /* only if bClampEnable is TRUE */ | ||
77 | enum ccdc_sample_line sample_ln; | ||
78 | /* only if bClampEnable is TRUE */ | ||
79 | unsigned short start_pixel; | ||
80 | /* only if bClampEnable is TRUE */ | ||
81 | unsigned short sgain; | ||
82 | /* only if bClampEnable is FALSE */ | ||
83 | unsigned short dc_sub; | ||
84 | }; | ||
85 | |||
86 | /* structure for Black Level Compensation */ | ||
87 | struct ccdc_black_compensation { | ||
88 | /* Constant value to subtract from Red component */ | ||
89 | char r; | ||
90 | /* Constant value to subtract from Gr component */ | ||
91 | char gr; | ||
92 | /* Constant value to subtract from Blue component */ | ||
93 | char b; | ||
94 | /* Constant value to subtract from Gb component */ | ||
95 | char gb; | ||
96 | }; | ||
97 | |||
98 | /* structure for fault pixel correction */ | ||
99 | struct ccdc_fault_pixel { | ||
100 | /* Enable or Disable fault pixel correction */ | ||
101 | unsigned char enable; | ||
102 | /* Number of fault pixel */ | ||
103 | unsigned short fp_num; | ||
104 | /* Address of fault pixel table */ | ||
105 | unsigned int fpc_table_addr; | ||
106 | }; | ||
107 | |||
108 | /* Structure for CCDC configuration parameters for raw capture mode passed | ||
109 | * by application | ||
110 | */ | ||
111 | struct ccdc_config_params_raw { | ||
112 | /* data size value from 8 to 16 bits */ | ||
113 | enum ccdc_data_size data_sz; | ||
114 | /* Structure for Optional A-Law */ | ||
115 | struct ccdc_a_law alaw; | ||
116 | /* Structure for Optical Black Clamp */ | ||
117 | struct ccdc_black_clamp blk_clamp; | ||
118 | /* Structure for Black Compensation */ | ||
119 | struct ccdc_black_compensation blk_comp; | ||
120 | /* Structure for Fault Pixel Module Configuration */ | ||
121 | struct ccdc_fault_pixel fault_pxl; | ||
122 | }; | ||
123 | |||
124 | |||
125 | #ifdef __KERNEL__ | ||
126 | #include <linux/io.h> | ||
127 | /* Define to enable/disable video port */ | ||
128 | #define FP_NUM_BYTES 4 | ||
129 | /* Define for extra pixel/line and extra lines/frame */ | ||
130 | #define NUM_EXTRAPIXELS 8 | ||
131 | #define NUM_EXTRALINES 8 | ||
132 | |||
133 | /* settings for commonly used video formats */ | ||
134 | #define CCDC_WIN_PAL {0, 0, 720, 576} | ||
135 | /* ntsc square pixel */ | ||
136 | #define CCDC_WIN_VGA {0, 0, (640 + NUM_EXTRAPIXELS), (480 + NUM_EXTRALINES)} | ||
137 | |||
138 | /* Structure for CCDC configuration parameters for raw capture mode */ | ||
139 | struct ccdc_params_raw { | ||
140 | /* pixel format */ | ||
141 | enum ccdc_pixfmt pix_fmt; | ||
142 | /* progressive or interlaced frame */ | ||
143 | enum ccdc_frmfmt frm_fmt; | ||
144 | /* video window */ | ||
145 | struct v4l2_rect win; | ||
146 | /* field id polarity */ | ||
147 | enum vpfe_pin_pol fid_pol; | ||
148 | /* vertical sync polarity */ | ||
149 | enum vpfe_pin_pol vd_pol; | ||
150 | /* horizontal sync polarity */ | ||
151 | enum vpfe_pin_pol hd_pol; | ||
152 | /* interleaved or separated fields */ | ||
153 | enum ccdc_buftype buf_type; | ||
154 | /* | ||
155 | * enable to store the image in inverse | ||
156 | * order in memory(bottom to top) | ||
157 | */ | ||
158 | unsigned char image_invert_enable; | ||
159 | /* configurable paramaters */ | ||
160 | struct ccdc_config_params_raw config_params; | ||
161 | }; | ||
162 | |||
163 | struct ccdc_params_ycbcr { | ||
164 | /* pixel format */ | ||
165 | enum ccdc_pixfmt pix_fmt; | ||
166 | /* progressive or interlaced frame */ | ||
167 | enum ccdc_frmfmt frm_fmt; | ||
168 | /* video window */ | ||
169 | struct v4l2_rect win; | ||
170 | /* field id polarity */ | ||
171 | enum vpfe_pin_pol fid_pol; | ||
172 | /* vertical sync polarity */ | ||
173 | enum vpfe_pin_pol vd_pol; | ||
174 | /* horizontal sync polarity */ | ||
175 | enum vpfe_pin_pol hd_pol; | ||
176 | /* enable BT.656 embedded sync mode */ | ||
177 | int bt656_enable; | ||
178 | /* cb:y:cr:y or y:cb:y:cr in memory */ | ||
179 | enum ccdc_pixorder pix_order; | ||
180 | /* interleaved or separated fields */ | ||
181 | enum ccdc_buftype buf_type; | ||
182 | }; | ||
183 | #endif | ||
184 | #endif /* _DM644X_CCDC_H */ | ||