aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/davinci
diff options
context:
space:
mode:
authorMuralidharan Karicheri <m-karicheri2@ti.com>2010-01-13 18:27:06 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-02-26 13:10:45 -0500
commitc70fc2d2ccff1ce4cf0441ed060045022e6cc5c8 (patch)
tree436259993e9a79231c4a5df386f2a939d687d26c /drivers/media/video/davinci
parent51444ea3d4f5baa0338297aba7065fd695528a36 (diff)
V4L/DVB: vpfe-capture - converting dm355 ccdc driver to a platform driver
1) clocks are configured using generic clock names; 2) converts the driver to a platform driver; 3) cleanup - consolidate all static variables inside a structure, ccdc_cfg; The ccdc now uses a generic name for clocks. "master" and "slave". On individual platforms these clocks will inherit from the platform specific clock. This will allow re-use of the driver for the same IP across different SoCs. Updated based on Kevin's comments on clock configuration and error code (v3, v4). Reviewed-by: Kevin Hilman <khilman@deeprootsystems.com> Reviewed-by: Vaibhav Hiremath <hvaibhav@ti.com> Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Muralidharan Karicheri <m-karicheri2@ti.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/davinci')
-rw-r--r--drivers/media/video/davinci/dm355_ccdc.c410
1 files changed, 257 insertions, 153 deletions
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
index 31439001637..c29ac88ffd7 100644
--- a/drivers/media/video/davinci/dm355_ccdc.c
+++ b/drivers/media/video/davinci/dm355_ccdc.c
@@ -37,8 +37,12 @@
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/uaccess.h> 38#include <linux/uaccess.h>
39#include <linux/videodev2.h> 39#include <linux/videodev2.h>
40#include <linux/clk.h>
41#include <linux/err.h>
42
40#include <media/davinci/dm355_ccdc.h> 43#include <media/davinci/dm355_ccdc.h>
41#include <media/davinci/vpss.h> 44#include <media/davinci/vpss.h>
45
42#include "dm355_ccdc_regs.h" 46#include "dm355_ccdc_regs.h"
43#include "ccdc_hw_device.h" 47#include "ccdc_hw_device.h"
44 48
@@ -46,67 +50,75 @@ MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("CCDC Driver for DM355"); 50MODULE_DESCRIPTION("CCDC Driver for DM355");
47MODULE_AUTHOR("Texas Instruments"); 51MODULE_AUTHOR("Texas Instruments");
48 52
49static struct device *dev; 53static struct ccdc_oper_config {
50 54 struct device *dev;
51/* Object for CCDC raw mode */ 55 /* CCDC interface type */
52static struct ccdc_params_raw ccdc_hw_params_raw = { 56 enum vpfe_hw_if_type if_type;
53 .pix_fmt = CCDC_PIXFMT_RAW, 57 /* Raw Bayer configuration */
54 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE, 58 struct ccdc_params_raw bayer;
55 .win = CCDC_WIN_VGA, 59 /* YCbCr configuration */
56 .fid_pol = VPFE_PINPOL_POSITIVE, 60 struct ccdc_params_ycbcr ycbcr;
57 .vd_pol = VPFE_PINPOL_POSITIVE, 61 /* Master clock */
58 .hd_pol = VPFE_PINPOL_POSITIVE, 62 struct clk *mclk;
59 .gain = { 63 /* slave clock */
60 .r_ye = 256, 64 struct clk *sclk;
61 .gb_g = 256, 65 /* ccdc base address */
62 .gr_cy = 256, 66 void __iomem *base_addr;
63 .b_mg = 256 67} ccdc_cfg = {
64 }, 68 /* Raw configurations */
65 .config_params = { 69 .bayer = {
66 .datasft = 2, 70 .pix_fmt = CCDC_PIXFMT_RAW,
67 .data_sz = CCDC_DATA_10BITS, 71 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
68 .mfilt1 = CCDC_NO_MEDIAN_FILTER1, 72 .win = CCDC_WIN_VGA,
69 .mfilt2 = CCDC_NO_MEDIAN_FILTER2, 73 .fid_pol = VPFE_PINPOL_POSITIVE,
70 .alaw = { 74 .vd_pol = VPFE_PINPOL_POSITIVE,
71 .gama_wd = 2, 75 .hd_pol = VPFE_PINPOL_POSITIVE,
76 .gain = {
77 .r_ye = 256,
78 .gb_g = 256,
79 .gr_cy = 256,
80 .b_mg = 256
72 }, 81 },
73 .blk_clamp = { 82 .config_params = {
74 .sample_pixel = 1, 83 .datasft = 2,
75 .dc_sub = 25 84 .mfilt1 = CCDC_NO_MEDIAN_FILTER1,
76 }, 85 .mfilt2 = CCDC_NO_MEDIAN_FILTER2,
77 .col_pat_field0 = { 86 .alaw = {
78 .olop = CCDC_GREEN_BLUE, 87 .gama_wd = 2,
79 .olep = CCDC_BLUE, 88 },
80 .elop = CCDC_RED, 89 .blk_clamp = {
81 .elep = CCDC_GREEN_RED 90 .sample_pixel = 1,
82 }, 91 .dc_sub = 25
83 .col_pat_field1 = { 92 },
84 .olop = CCDC_GREEN_BLUE, 93 .col_pat_field0 = {
85 .olep = CCDC_BLUE, 94 .olop = CCDC_GREEN_BLUE,
86 .elop = CCDC_RED, 95 .olep = CCDC_BLUE,
87 .elep = CCDC_GREEN_RED 96 .elop = CCDC_RED,
97 .elep = CCDC_GREEN_RED
98 },
99 .col_pat_field1 = {
100 .olop = CCDC_GREEN_BLUE,
101 .olep = CCDC_BLUE,
102 .elop = CCDC_RED,
103 .elep = CCDC_GREEN_RED
104 },
88 }, 105 },
89 }, 106 },
107 /* YCbCr configuration */
108 .ycbcr = {
109 .win = CCDC_WIN_PAL,
110 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
111 .frm_fmt = CCDC_FRMFMT_INTERLACED,
112 .fid_pol = VPFE_PINPOL_POSITIVE,
113 .vd_pol = VPFE_PINPOL_POSITIVE,
114 .hd_pol = VPFE_PINPOL_POSITIVE,
115 .bt656_enable = 1,
116 .pix_order = CCDC_PIXORDER_CBYCRY,
117 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
118 },
90}; 119};
91 120
92 121
93/* Object for CCDC ycbcr mode */
94static 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
106static enum vpfe_hw_if_type ccdc_if_type;
107static void *__iomem ccdc_base_addr;
108static int ccdc_addr_size;
109
110/* Raw Bayer formats */ 122/* Raw Bayer formats */
111static u32 ccdc_raw_bayer_pix_formats[] = 123static u32 ccdc_raw_bayer_pix_formats[] =
112 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16}; 124 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
@@ -118,18 +130,12 @@ static u32 ccdc_raw_yuv_pix_formats[] =
118/* register access routines */ 130/* register access routines */
119static inline u32 regr(u32 offset) 131static inline u32 regr(u32 offset)
120{ 132{
121 return __raw_readl(ccdc_base_addr + offset); 133 return __raw_readl(ccdc_cfg.base_addr + offset);
122} 134}
123 135
124static inline void regw(u32 val, u32 offset) 136static inline void regw(u32 val, u32 offset)
125{ 137{
126 __raw_writel(val, ccdc_base_addr + offset); 138 __raw_writel(val, ccdc_cfg.base_addr + offset);
127}
128
129static void ccdc_set_ccdc_base(void *addr, int size)
130{
131 ccdc_base_addr = addr;
132 ccdc_addr_size = size;
133} 139}
134 140
135static void ccdc_enable(int en) 141static void ccdc_enable(int en)
@@ -153,12 +159,12 @@ static void ccdc_enable_output_to_sdram(int en)
153static void ccdc_config_gain_offset(void) 159static void ccdc_config_gain_offset(void)
154{ 160{
155 /* configure gain */ 161 /* configure gain */
156 regw(ccdc_hw_params_raw.gain.r_ye, RYEGAIN); 162 regw(ccdc_cfg.bayer.gain.r_ye, RYEGAIN);
157 regw(ccdc_hw_params_raw.gain.gr_cy, GRCYGAIN); 163 regw(ccdc_cfg.bayer.gain.gr_cy, GRCYGAIN);
158 regw(ccdc_hw_params_raw.gain.gb_g, GBGGAIN); 164 regw(ccdc_cfg.bayer.gain.gb_g, GBGGAIN);
159 regw(ccdc_hw_params_raw.gain.b_mg, BMGGAIN); 165 regw(ccdc_cfg.bayer.gain.b_mg, BMGGAIN);
160 /* configure offset */ 166 /* configure offset */
161 regw(ccdc_hw_params_raw.ccdc_offset, OFFSET); 167 regw(ccdc_cfg.bayer.ccdc_offset, OFFSET);
162} 168}
163 169
164/* 170/*
@@ -169,7 +175,7 @@ static int ccdc_restore_defaults(void)
169{ 175{
170 int i; 176 int i;
171 177
172 dev_dbg(dev, "\nstarting ccdc_restore_defaults..."); 178 dev_dbg(ccdc_cfg.dev, "\nstarting ccdc_restore_defaults...");
173 /* set all registers to zero */ 179 /* set all registers to zero */
174 for (i = 0; i <= CCDC_REG_LAST; i += 4) 180 for (i = 0; i <= CCDC_REG_LAST; i += 4)
175 regw(0, i); 181 regw(0, i);
@@ -180,30 +186,29 @@ static int ccdc_restore_defaults(void)
180 regw(CULH_DEFAULT, CULH); 186 regw(CULH_DEFAULT, CULH);
181 regw(CULV_DEFAULT, CULV); 187 regw(CULV_DEFAULT, CULV);
182 /* Set default Gain and Offset */ 188 /* Set default Gain and Offset */
183 ccdc_hw_params_raw.gain.r_ye = GAIN_DEFAULT; 189 ccdc_cfg.bayer.gain.r_ye = GAIN_DEFAULT;
184 ccdc_hw_params_raw.gain.gb_g = GAIN_DEFAULT; 190 ccdc_cfg.bayer.gain.gb_g = GAIN_DEFAULT;
185 ccdc_hw_params_raw.gain.gr_cy = GAIN_DEFAULT; 191 ccdc_cfg.bayer.gain.gr_cy = GAIN_DEFAULT;
186 ccdc_hw_params_raw.gain.b_mg = GAIN_DEFAULT; 192 ccdc_cfg.bayer.gain.b_mg = GAIN_DEFAULT;
187 ccdc_config_gain_offset(); 193 ccdc_config_gain_offset();
188 regw(OUTCLIP_DEFAULT, OUTCLIP); 194 regw(OUTCLIP_DEFAULT, OUTCLIP);
189 regw(LSCCFG2_DEFAULT, LSCCFG2); 195 regw(LSCCFG2_DEFAULT, LSCCFG2);
190 /* select ccdc input */ 196 /* select ccdc input */
191 if (vpss_select_ccdc_source(VPSS_CCDCIN)) { 197 if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
192 dev_dbg(dev, "\ncouldn't select ccdc input source"); 198 dev_dbg(ccdc_cfg.dev, "\ncouldn't select ccdc input source");
193 return -EFAULT; 199 return -EFAULT;
194 } 200 }
195 /* select ccdc clock */ 201 /* select ccdc clock */
196 if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) { 202 if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
197 dev_dbg(dev, "\ncouldn't enable ccdc clock"); 203 dev_dbg(ccdc_cfg.dev, "\ncouldn't enable ccdc clock");
198 return -EFAULT; 204 return -EFAULT;
199 } 205 }
200 dev_dbg(dev, "\nEnd of ccdc_restore_defaults..."); 206 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_restore_defaults...");
201 return 0; 207 return 0;
202} 208}
203 209
204static int ccdc_open(struct device *device) 210static int ccdc_open(struct device *device)
205{ 211{
206 dev = device;
207 return ccdc_restore_defaults(); 212 return ccdc_restore_defaults();
208} 213}
209 214
@@ -226,7 +231,7 @@ static void ccdc_setwin(struct v4l2_rect *image_win,
226 int vert_start, vert_nr_lines; 231 int vert_start, vert_nr_lines;
227 int mid_img = 0; 232 int mid_img = 0;
228 233
229 dev_dbg(dev, "\nStarting ccdc_setwin..."); 234 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_setwin...");
230 235
231 /* 236 /*
232 * ppc - per pixel count. indicates how many pixels per cell 237 * ppc - per pixel count. indicates how many pixels per cell
@@ -260,45 +265,46 @@ static void ccdc_setwin(struct v4l2_rect *image_win,
260 regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0); 265 regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
261 regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1); 266 regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
262 regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV); 267 regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
263 dev_dbg(dev, "\nEnd of ccdc_setwin..."); 268 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_setwin...");
264} 269}
265 270
266static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) 271static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
267{ 272{
268 if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT || 273 if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
269 ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) { 274 ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
270 dev_dbg(dev, "Invalid value of data shift\n"); 275 dev_dbg(ccdc_cfg.dev, "Invalid value of data shift\n");
271 return -EINVAL; 276 return -EINVAL;
272 } 277 }
273 278
274 if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 || 279 if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
275 ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) { 280 ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
276 dev_dbg(dev, "Invalid value of median filter1\n"); 281 dev_dbg(ccdc_cfg.dev, "Invalid value of median filter1\n");
277 return -EINVAL; 282 return -EINVAL;
278 } 283 }
279 284
280 if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 || 285 if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
281 ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) { 286 ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
282 dev_dbg(dev, "Invalid value of median filter2\n"); 287 dev_dbg(ccdc_cfg.dev, "Invalid value of median filter2\n");
283 return -EINVAL; 288 return -EINVAL;
284 } 289 }
285 290
286 if ((ccdcparam->med_filt_thres < 0) || 291 if ((ccdcparam->med_filt_thres < 0) ||
287 (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) { 292 (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
288 dev_dbg(dev, "Invalid value of median filter threshold\n"); 293 dev_dbg(ccdc_cfg.dev,
294 "Invalid value of median filter thresold\n");
289 return -EINVAL; 295 return -EINVAL;
290 } 296 }
291 297
292 if (ccdcparam->data_sz < CCDC_DATA_16BITS || 298 if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
293 ccdcparam->data_sz > CCDC_DATA_8BITS) { 299 ccdcparam->data_sz > CCDC_DATA_8BITS) {
294 dev_dbg(dev, "Invalid value of data size\n"); 300 dev_dbg(ccdc_cfg.dev, "Invalid value of data size\n");
295 return -EINVAL; 301 return -EINVAL;
296 } 302 }
297 303
298 if (ccdcparam->alaw.enable) { 304 if (ccdcparam->alaw.enable) {
299 if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 || 305 if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
300 ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) { 306 ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
301 dev_dbg(dev, "Invalid value of ALAW\n"); 307 dev_dbg(ccdc_cfg.dev, "Invalid value of ALAW\n");
302 return -EINVAL; 308 return -EINVAL;
303 } 309 }
304 } 310 }
@@ -306,12 +312,14 @@ static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
306 if (ccdcparam->blk_clamp.b_clamp_enable) { 312 if (ccdcparam->blk_clamp.b_clamp_enable) {
307 if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS || 313 if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
308 ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) { 314 ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
309 dev_dbg(dev, "Invalid value of sample pixel\n"); 315 dev_dbg(ccdc_cfg.dev,
316 "Invalid value of sample pixel\n");
310 return -EINVAL; 317 return -EINVAL;
311 } 318 }
312 if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES || 319 if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
313 ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) { 320 ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
314 dev_dbg(dev, "Invalid value of sample lines\n"); 321 dev_dbg(ccdc_cfg.dev,
322 "Invalid value of sample lines\n");
315 return -EINVAL; 323 return -EINVAL;
316 } 324 }
317 } 325 }
@@ -325,18 +333,18 @@ static int ccdc_set_params(void __user *params)
325 int x; 333 int x;
326 334
327 /* only raw module parameters can be set through the IOCTL */ 335 /* only raw module parameters can be set through the IOCTL */
328 if (ccdc_if_type != VPFE_RAW_BAYER) 336 if (ccdc_cfg.if_type != VPFE_RAW_BAYER)
329 return -EINVAL; 337 return -EINVAL;
330 338
331 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params)); 339 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
332 if (x) { 340 if (x) {
333 dev_dbg(dev, "ccdc_set_params: error in copying ccdc" 341 dev_dbg(ccdc_cfg.dev, "ccdc_set_params: error in copying ccdc"
334 "params, %d\n", x); 342 "params, %d\n", x);
335 return -EFAULT; 343 return -EFAULT;
336 } 344 }
337 345
338 if (!validate_ccdc_param(&ccdc_raw_params)) { 346 if (!validate_ccdc_param(&ccdc_raw_params)) {
339 memcpy(&ccdc_hw_params_raw.config_params, 347 memcpy(&ccdc_cfg.bayer.config_params,
340 &ccdc_raw_params, 348 &ccdc_raw_params,
341 sizeof(ccdc_raw_params)); 349 sizeof(ccdc_raw_params));
342 return 0; 350 return 0;
@@ -347,11 +355,11 @@ static int ccdc_set_params(void __user *params)
347/* This function will configure CCDC for YCbCr video capture */ 355/* This function will configure CCDC for YCbCr video capture */
348static void ccdc_config_ycbcr(void) 356static void ccdc_config_ycbcr(void)
349{ 357{
350 struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr; 358 struct ccdc_params_ycbcr *params = &ccdc_cfg.ycbcr;
351 u32 temp; 359 u32 temp;
352 360
353 /* first set the CCDC power on defaults values in all registers */ 361 /* first set the CCDC power on defaults values in all registers */
354 dev_dbg(dev, "\nStarting ccdc_config_ycbcr..."); 362 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_ycbcr...");
355 ccdc_restore_defaults(); 363 ccdc_restore_defaults();
356 364
357 /* configure pixel format & video frame format */ 365 /* configure pixel format & video frame format */
@@ -403,7 +411,7 @@ static void ccdc_config_ycbcr(void)
403 regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST); 411 regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
404 } 412 }
405 413
406 dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n"); 414 dev_dbg(ccdc_cfg.dev, "\nEnd of ccdc_config_ycbcr...\n");
407} 415}
408 416
409/* 417/*
@@ -483,7 +491,7 @@ int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
483 */ 491 */
484 492
485 if (count) { 493 if (count) {
486 dev_err(dev, "defect table write timeout !!!\n"); 494 dev_err(ccdc_cfg.dev, "defect table write timeout !!!\n");
487 return -1; 495 return -1;
488 } 496 }
489 return 0; 497 return 0;
@@ -605,12 +613,12 @@ static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
605/* This function will configure CCDC for Raw mode image capture */ 613/* This function will configure CCDC for Raw mode image capture */
606static int ccdc_config_raw(void) 614static int ccdc_config_raw(void)
607{ 615{
608 struct ccdc_params_raw *params = &ccdc_hw_params_raw; 616 struct ccdc_params_raw *params = &ccdc_cfg.bayer;
609 struct ccdc_config_params_raw *config_params = 617 struct ccdc_config_params_raw *config_params =
610 &ccdc_hw_params_raw.config_params; 618 &ccdc_cfg.bayer.config_params;
611 unsigned int val; 619 unsigned int val;
612 620
613 dev_dbg(dev, "\nStarting ccdc_config_raw..."); 621 dev_dbg(ccdc_cfg.dev, "\nStarting ccdc_config_raw...");
614 622
615 /* restore power on defaults to register */ 623 /* restore power on defaults to register */
616 ccdc_restore_defaults(); 624 ccdc_restore_defaults();
@@ -659,7 +667,7 @@ static int ccdc_config_raw(void)
659 val |= (config_params->datasft & CCDC_DATASFT_MASK) << 667 val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
660 CCDC_DATASFT_SHIFT; 668 CCDC_DATASFT_SHIFT;
661 regw(val , MODESET); 669 regw(val , MODESET);
662 dev_dbg(dev, "\nWriting 0x%x to MODESET...\n", val); 670 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to MODESET...\n", val);
663 671
664 /* Configure the Median Filter threshold */ 672 /* Configure the Median Filter threshold */
665 regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT); 673 regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
@@ -681,7 +689,7 @@ static int ccdc_config_raw(void)
681 (config_params->mfilt2 << CCDC_MFILT2_SHIFT)); 689 (config_params->mfilt2 << CCDC_MFILT2_SHIFT));
682 690
683 regw(val, GAMMAWD); 691 regw(val, GAMMAWD);
684 dev_dbg(dev, "\nWriting 0x%x to GAMMAWD...\n", val); 692 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to GAMMAWD...\n", val);
685 693
686 /* configure video window */ 694 /* configure video window */
687 ccdc_setwin(&params->win, params->frm_fmt, 1); 695 ccdc_setwin(&params->win, params->frm_fmt, 1);
@@ -706,7 +714,7 @@ static int ccdc_config_raw(void)
706 /* Configure the Gain & offset control */ 714 /* Configure the Gain & offset control */
707 ccdc_config_gain_offset(); 715 ccdc_config_gain_offset();
708 716
709 dev_dbg(dev, "\nWriting %x to COLPTN...\n", val); 717 dev_dbg(ccdc_cfg.dev, "\nWriting %x to COLPTN...\n", val);
710 718
711 /* Configure DATAOFST register */ 719 /* Configure DATAOFST register */
712 val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) << 720 val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
@@ -726,7 +734,7 @@ static int ccdc_config_raw(void)
726 CCDC_HSIZE_VAL_MASK; 734 CCDC_HSIZE_VAL_MASK;
727 735
728 /* adjust to multiple of 32 */ 736 /* adjust to multiple of 32 */
729 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n", 737 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
730 (((params->win.width) + 31) >> 5) & 738 (((params->win.width) + 31) >> 5) &
731 CCDC_HSIZE_VAL_MASK); 739 CCDC_HSIZE_VAL_MASK);
732 } else { 740 } else {
@@ -734,7 +742,7 @@ static int ccdc_config_raw(void)
734 val |= (((params->win.width * 2) + 31) >> 5) & 742 val |= (((params->win.width * 2) + 31) >> 5) &
735 CCDC_HSIZE_VAL_MASK; 743 CCDC_HSIZE_VAL_MASK;
736 744
737 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n", 745 dev_dbg(ccdc_cfg.dev, "\nWriting 0x%x to HSIZE...\n",
738 (((params->win.width * 2) + 31) >> 5) & 746 (((params->win.width * 2) + 31) >> 5) &
739 CCDC_HSIZE_VAL_MASK); 747 CCDC_HSIZE_VAL_MASK);
740 } 748 }
@@ -745,34 +753,34 @@ static int ccdc_config_raw(void)
745 if (params->image_invert_enable) { 753 if (params->image_invert_enable) {
746 /* For interlace inverse mode */ 754 /* For interlace inverse mode */
747 regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST); 755 regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
748 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 756 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
749 CCDC_SDOFST_INTERLACE_INVERSE); 757 CCDC_SDOFST_INTERLACE_INVERSE);
750 } else { 758 } else {
751 /* For interlace non inverse mode */ 759 /* For interlace non inverse mode */
752 regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST); 760 regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
753 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 761 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
754 CCDC_SDOFST_INTERLACE_NORMAL); 762 CCDC_SDOFST_INTERLACE_NORMAL);
755 } 763 }
756 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) { 764 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
757 if (params->image_invert_enable) { 765 if (params->image_invert_enable) {
758 /* For progessive inverse mode */ 766 /* For progessive inverse mode */
759 regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST); 767 regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
760 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 768 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
761 CCDC_SDOFST_PROGRESSIVE_INVERSE); 769 CCDC_SDOFST_PROGRESSIVE_INVERSE);
762 } else { 770 } else {
763 /* For progessive non inverse mode */ 771 /* For progessive non inverse mode */
764 regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST); 772 regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
765 dev_dbg(dev, "\nWriting %x to SDOFST...\n", 773 dev_dbg(ccdc_cfg.dev, "\nWriting %x to SDOFST...\n",
766 CCDC_SDOFST_PROGRESSIVE_NORMAL); 774 CCDC_SDOFST_PROGRESSIVE_NORMAL);
767 } 775 }
768 } 776 }
769 dev_dbg(dev, "\nend of ccdc_config_raw..."); 777 dev_dbg(ccdc_cfg.dev, "\nend of ccdc_config_raw...");
770 return 0; 778 return 0;
771} 779}
772 780
773static int ccdc_configure(void) 781static int ccdc_configure(void)
774{ 782{
775 if (ccdc_if_type == VPFE_RAW_BAYER) 783 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
776 return ccdc_config_raw(); 784 return ccdc_config_raw();
777 else 785 else
778 ccdc_config_ycbcr(); 786 ccdc_config_ycbcr();
@@ -781,23 +789,23 @@ static int ccdc_configure(void)
781 789
782static int ccdc_set_buftype(enum ccdc_buftype buf_type) 790static int ccdc_set_buftype(enum ccdc_buftype buf_type)
783{ 791{
784 if (ccdc_if_type == VPFE_RAW_BAYER) 792 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
785 ccdc_hw_params_raw.buf_type = buf_type; 793 ccdc_cfg.bayer.buf_type = buf_type;
786 else 794 else
787 ccdc_hw_params_ycbcr.buf_type = buf_type; 795 ccdc_cfg.ycbcr.buf_type = buf_type;
788 return 0; 796 return 0;
789} 797}
790static enum ccdc_buftype ccdc_get_buftype(void) 798static enum ccdc_buftype ccdc_get_buftype(void)
791{ 799{
792 if (ccdc_if_type == VPFE_RAW_BAYER) 800 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
793 return ccdc_hw_params_raw.buf_type; 801 return ccdc_cfg.bayer.buf_type;
794 return ccdc_hw_params_ycbcr.buf_type; 802 return ccdc_cfg.ycbcr.buf_type;
795} 803}
796 804
797static int ccdc_enum_pix(u32 *pix, int i) 805static int ccdc_enum_pix(u32 *pix, int i)
798{ 806{
799 int ret = -EINVAL; 807 int ret = -EINVAL;
800 if (ccdc_if_type == VPFE_RAW_BAYER) { 808 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
801 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) { 809 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
802 *pix = ccdc_raw_bayer_pix_formats[i]; 810 *pix = ccdc_raw_bayer_pix_formats[i];
803 ret = 0; 811 ret = 0;
@@ -813,20 +821,19 @@ static int ccdc_enum_pix(u32 *pix, int i)
813 821
814static int ccdc_set_pixel_format(u32 pixfmt) 822static int ccdc_set_pixel_format(u32 pixfmt)
815{ 823{
816 struct ccdc_a_law *alaw = 824 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
817 &ccdc_hw_params_raw.config_params.alaw;
818 825
819 if (ccdc_if_type == VPFE_RAW_BAYER) { 826 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
820 ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW; 827 ccdc_cfg.bayer.pix_fmt = CCDC_PIXFMT_RAW;
821 if (pixfmt == V4L2_PIX_FMT_SBGGR8) 828 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
822 alaw->enable = 1; 829 alaw->enable = 1;
823 else if (pixfmt != V4L2_PIX_FMT_SBGGR16) 830 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
824 return -EINVAL; 831 return -EINVAL;
825 } else { 832 } else {
826 if (pixfmt == V4L2_PIX_FMT_YUYV) 833 if (pixfmt == V4L2_PIX_FMT_YUYV)
827 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR; 834 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
828 else if (pixfmt == V4L2_PIX_FMT_UYVY) 835 else if (pixfmt == V4L2_PIX_FMT_UYVY)
829 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY; 836 ccdc_cfg.ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
830 else 837 else
831 return -EINVAL; 838 return -EINVAL;
832 } 839 }
@@ -834,17 +841,16 @@ static int ccdc_set_pixel_format(u32 pixfmt)
834} 841}
835static u32 ccdc_get_pixel_format(void) 842static u32 ccdc_get_pixel_format(void)
836{ 843{
837 struct ccdc_a_law *alaw = 844 struct ccdc_a_law *alaw = &ccdc_cfg.bayer.config_params.alaw;
838 &ccdc_hw_params_raw.config_params.alaw;
839 u32 pixfmt; 845 u32 pixfmt;
840 846
841 if (ccdc_if_type == VPFE_RAW_BAYER) 847 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
842 if (alaw->enable) 848 if (alaw->enable)
843 pixfmt = V4L2_PIX_FMT_SBGGR8; 849 pixfmt = V4L2_PIX_FMT_SBGGR8;
844 else 850 else
845 pixfmt = V4L2_PIX_FMT_SBGGR16; 851 pixfmt = V4L2_PIX_FMT_SBGGR16;
846 else { 852 else {
847 if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR) 853 if (ccdc_cfg.ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
848 pixfmt = V4L2_PIX_FMT_YUYV; 854 pixfmt = V4L2_PIX_FMT_YUYV;
849 else 855 else
850 pixfmt = V4L2_PIX_FMT_UYVY; 856 pixfmt = V4L2_PIX_FMT_UYVY;
@@ -853,53 +859,53 @@ static u32 ccdc_get_pixel_format(void)
853} 859}
854static int ccdc_set_image_window(struct v4l2_rect *win) 860static int ccdc_set_image_window(struct v4l2_rect *win)
855{ 861{
856 if (ccdc_if_type == VPFE_RAW_BAYER) 862 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
857 ccdc_hw_params_raw.win = *win; 863 ccdc_cfg.bayer.win = *win;
858 else 864 else
859 ccdc_hw_params_ycbcr.win = *win; 865 ccdc_cfg.ycbcr.win = *win;
860 return 0; 866 return 0;
861} 867}
862 868
863static void ccdc_get_image_window(struct v4l2_rect *win) 869static void ccdc_get_image_window(struct v4l2_rect *win)
864{ 870{
865 if (ccdc_if_type == VPFE_RAW_BAYER) 871 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
866 *win = ccdc_hw_params_raw.win; 872 *win = ccdc_cfg.bayer.win;
867 else 873 else
868 *win = ccdc_hw_params_ycbcr.win; 874 *win = ccdc_cfg.ycbcr.win;
869} 875}
870 876
871static unsigned int ccdc_get_line_length(void) 877static unsigned int ccdc_get_line_length(void)
872{ 878{
873 struct ccdc_config_params_raw *config_params = 879 struct ccdc_config_params_raw *config_params =
874 &ccdc_hw_params_raw.config_params; 880 &ccdc_cfg.bayer.config_params;
875 unsigned int len; 881 unsigned int len;
876 882
877 if (ccdc_if_type == VPFE_RAW_BAYER) { 883 if (ccdc_cfg.if_type == VPFE_RAW_BAYER) {
878 if ((config_params->alaw.enable) || 884 if ((config_params->alaw.enable) ||
879 (config_params->data_sz == CCDC_DATA_8BITS)) 885 (config_params->data_sz == CCDC_DATA_8BITS))
880 len = ccdc_hw_params_raw.win.width; 886 len = ccdc_cfg.bayer.win.width;
881 else 887 else
882 len = ccdc_hw_params_raw.win.width * 2; 888 len = ccdc_cfg.bayer.win.width * 2;
883 } else 889 } else
884 len = ccdc_hw_params_ycbcr.win.width * 2; 890 len = ccdc_cfg.ycbcr.win.width * 2;
885 return ALIGN(len, 32); 891 return ALIGN(len, 32);
886} 892}
887 893
888static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt) 894static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
889{ 895{
890 if (ccdc_if_type == VPFE_RAW_BAYER) 896 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
891 ccdc_hw_params_raw.frm_fmt = frm_fmt; 897 ccdc_cfg.bayer.frm_fmt = frm_fmt;
892 else 898 else
893 ccdc_hw_params_ycbcr.frm_fmt = frm_fmt; 899 ccdc_cfg.ycbcr.frm_fmt = frm_fmt;
894 return 0; 900 return 0;
895} 901}
896 902
897static enum ccdc_frmfmt ccdc_get_frame_format(void) 903static enum ccdc_frmfmt ccdc_get_frame_format(void)
898{ 904{
899 if (ccdc_if_type == VPFE_RAW_BAYER) 905 if (ccdc_cfg.if_type == VPFE_RAW_BAYER)
900 return ccdc_hw_params_raw.frm_fmt; 906 return ccdc_cfg.bayer.frm_fmt;
901 else 907 else
902 return ccdc_hw_params_ycbcr.frm_fmt; 908 return ccdc_cfg.ycbcr.frm_fmt;
903} 909}
904 910
905static int ccdc_getfid(void) 911static int ccdc_getfid(void)
@@ -916,14 +922,14 @@ static inline void ccdc_setfbaddr(unsigned long addr)
916 922
917static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params) 923static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
918{ 924{
919 ccdc_if_type = params->if_type; 925 ccdc_cfg.if_type = params->if_type;
920 926
921 switch (params->if_type) { 927 switch (params->if_type) {
922 case VPFE_BT656: 928 case VPFE_BT656:
923 case VPFE_YCBCR_SYNC_16: 929 case VPFE_YCBCR_SYNC_16:
924 case VPFE_YCBCR_SYNC_8: 930 case VPFE_YCBCR_SYNC_8:
925 ccdc_hw_params_ycbcr.vd_pol = params->vdpol; 931 ccdc_cfg.ycbcr.vd_pol = params->vdpol;
926 ccdc_hw_params_ycbcr.hd_pol = params->hdpol; 932 ccdc_cfg.ycbcr.hd_pol = params->hdpol;
927 break; 933 break;
928 default: 934 default:
929 /* TODO add support for raw bayer here */ 935 /* TODO add support for raw bayer here */
@@ -938,7 +944,6 @@ static struct ccdc_hw_device ccdc_hw_dev = {
938 .hw_ops = { 944 .hw_ops = {
939 .open = ccdc_open, 945 .open = ccdc_open,
940 .close = ccdc_close, 946 .close = ccdc_close,
941 .set_ccdc_base = ccdc_set_ccdc_base,
942 .enable = ccdc_enable, 947 .enable = ccdc_enable,
943 .enable_out_to_sdram = ccdc_enable_output_to_sdram, 948 .enable_out_to_sdram = ccdc_enable_output_to_sdram,
944 .set_hw_if_params = ccdc_set_hw_if_params, 949 .set_hw_if_params = ccdc_set_hw_if_params,
@@ -959,19 +964,118 @@ static struct ccdc_hw_device ccdc_hw_dev = {
959 }, 964 },
960}; 965};
961 966
962static int __init dm355_ccdc_init(void) 967static int __init dm355_ccdc_probe(struct platform_device *pdev)
963{ 968{
964 printk(KERN_NOTICE "dm355_ccdc_init\n"); 969 void (*setup_pinmux)(void);
965 if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0) 970 struct resource *res;
966 return -1; 971 int status = 0;
967 printk(KERN_NOTICE "%s is registered with vpfe.\n", 972
968 ccdc_hw_dev.name); 973 /*
974 * first try to register with vpfe. If not correct platform, then we
975 * don't have to iomap
976 */
977 status = vpfe_register_ccdc_device(&ccdc_hw_dev);
978 if (status < 0)
979 return status;
980
981 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
982 if (!res) {
983 status = -ENODEV;
984 goto fail_nores;
985 }
986
987 res = request_mem_region(res->start, resource_size(res), res->name);
988 if (!res) {
989 status = -EBUSY;
990 goto fail_nores;
991 }
992
993 ccdc_cfg.base_addr = ioremap_nocache(res->start, resource_size(res));
994 if (!ccdc_cfg.base_addr) {
995 status = -ENOMEM;
996 goto fail_nomem;
997 }
998
999 /* Get and enable Master clock */
1000 ccdc_cfg.mclk = clk_get(&pdev->dev, "master");
1001 if (IS_ERR(ccdc_cfg.mclk)) {
1002 status = PTR_ERR(ccdc_cfg.mclk);
1003 goto fail_nomap;
1004 }
1005 if (clk_enable(ccdc_cfg.mclk)) {
1006 status = -ENODEV;
1007 goto fail_mclk;
1008 }
1009
1010 /* Get and enable Slave clock */
1011 ccdc_cfg.sclk = clk_get(&pdev->dev, "slave");
1012 if (IS_ERR(ccdc_cfg.sclk)) {
1013 status = PTR_ERR(ccdc_cfg.sclk);
1014 goto fail_mclk;
1015 }
1016 if (clk_enable(ccdc_cfg.sclk)) {
1017 status = -ENODEV;
1018 goto fail_sclk;
1019 }
1020
1021 /* Platform data holds setup_pinmux function ptr */
1022 if (NULL == pdev->dev.platform_data) {
1023 status = -ENODEV;
1024 goto fail_sclk;
1025 }
1026 setup_pinmux = pdev->dev.platform_data;
1027 /*
1028 * setup Mux configuration for ccdc which may be different for
1029 * different SoCs using this CCDC
1030 */
1031 setup_pinmux();
1032 ccdc_cfg.dev = &pdev->dev;
1033 printk(KERN_NOTICE "%s is registered with vpfe.\n", ccdc_hw_dev.name);
969 return 0; 1034 return 0;
1035fail_sclk:
1036 clk_put(ccdc_cfg.sclk);
1037fail_mclk:
1038 clk_put(ccdc_cfg.mclk);
1039fail_nomap:
1040 iounmap(ccdc_cfg.base_addr);
1041fail_nomem:
1042 release_mem_region(res->start, resource_size(res));
1043fail_nores:
1044 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1045 return status;
970} 1046}
971 1047
972static void __exit dm355_ccdc_exit(void) 1048static int dm355_ccdc_remove(struct platform_device *pdev)
973{ 1049{
1050 struct resource *res;
1051
1052 clk_put(ccdc_cfg.mclk);
1053 clk_put(ccdc_cfg.sclk);
1054 iounmap(ccdc_cfg.base_addr);
1055 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1056 if (res)
1057 release_mem_region(res->start, resource_size(res));
974 vpfe_unregister_ccdc_device(&ccdc_hw_dev); 1058 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
1059 return 0;
1060}
1061
1062static struct platform_driver dm355_ccdc_driver = {
1063 .driver = {
1064 .name = "dm355_ccdc",
1065 .owner = THIS_MODULE,
1066 },
1067 .remove = __devexit_p(dm355_ccdc_remove),
1068 .probe = dm355_ccdc_probe,
1069};
1070
1071static int __init dm355_ccdc_init(void)
1072{
1073 return platform_driver_register(&dm355_ccdc_driver);
1074}
1075
1076static void __exit dm355_ccdc_exit(void)
1077{
1078 platform_driver_unregister(&dm355_ccdc_driver);
975} 1079}
976 1080
977module_init(dm355_ccdc_init); 1081module_init(dm355_ccdc_init);