diff options
author | Tony Lindgren <tony@atomide.com> | 2010-03-01 17:19:05 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2010-03-01 17:19:05 -0500 |
commit | d702d12167a2c05a346f49aac7a311d597762495 (patch) | |
tree | baae42c299cce34d6df24b5d01f8b1d0b481bd9a /drivers/media/video/davinci/dm355_ccdc.c | |
parent | 9418c65f9bd861d0f7e39aab9cfb3aa6f2275d11 (diff) | |
parent | ac0f6f927db539e03e1f3f61bcd4ed57d5cde7a9 (diff) |
Merge with mainline to remove plat-omap/Kconfig conflict
Conflicts:
arch/arm/plat-omap/Kconfig
Diffstat (limited to 'drivers/media/video/davinci/dm355_ccdc.c')
-rw-r--r-- | drivers/media/video/davinci/dm355_ccdc.c | 410 |
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 314390016370..c29ac88ffd78 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"); | |||
46 | MODULE_DESCRIPTION("CCDC Driver for DM355"); | 50 | MODULE_DESCRIPTION("CCDC Driver for DM355"); |
47 | MODULE_AUTHOR("Texas Instruments"); | 51 | MODULE_AUTHOR("Texas Instruments"); |
48 | 52 | ||
49 | static struct device *dev; | 53 | static struct ccdc_oper_config { |
50 | 54 | struct device *dev; | |
51 | /* Object for CCDC raw mode */ | 55 | /* CCDC interface type */ |
52 | static 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 */ | ||
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 */ | 122 | /* Raw Bayer formats */ |
111 | static u32 ccdc_raw_bayer_pix_formats[] = | 123 | static 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 */ |
119 | static inline u32 regr(u32 offset) | 131 | static 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 | ||
124 | static inline void regw(u32 val, u32 offset) | 136 | static 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 | |||
129 | static void ccdc_set_ccdc_base(void *addr, int size) | ||
130 | { | ||
131 | ccdc_base_addr = addr; | ||
132 | ccdc_addr_size = size; | ||
133 | } | 139 | } |
134 | 140 | ||
135 | static void ccdc_enable(int en) | 141 | static void ccdc_enable(int en) |
@@ -153,12 +159,12 @@ static void ccdc_enable_output_to_sdram(int en) | |||
153 | static void ccdc_config_gain_offset(void) | 159 | static 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 | ||
204 | static int ccdc_open(struct device *device) | 210 | static 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 | ||
266 | static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam) | 271 | static 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 */ |
348 | static void ccdc_config_ycbcr(void) | 356 | static 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 */ |
606 | static int ccdc_config_raw(void) | 614 | static 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(¶ms->win, params->frm_fmt, 1); | 695 | ccdc_setwin(¶ms->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 | ||
773 | static int ccdc_configure(void) | 781 | static 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 | ||
782 | static int ccdc_set_buftype(enum ccdc_buftype buf_type) | 790 | static 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 | } |
790 | static enum ccdc_buftype ccdc_get_buftype(void) | 798 | static 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 | ||
797 | static int ccdc_enum_pix(u32 *pix, int i) | 805 | static 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 | ||
814 | static int ccdc_set_pixel_format(u32 pixfmt) | 822 | static 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 | } |
835 | static u32 ccdc_get_pixel_format(void) | 842 | static 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 | } |
854 | static int ccdc_set_image_window(struct v4l2_rect *win) | 860 | static 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 | ||
863 | static void ccdc_get_image_window(struct v4l2_rect *win) | 869 | static 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 | ||
871 | static unsigned int ccdc_get_line_length(void) | 877 | static 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 | ||
888 | static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt) | 894 | static 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 | ||
897 | static enum ccdc_frmfmt ccdc_get_frame_format(void) | 903 | static 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 | ||
905 | static int ccdc_getfid(void) | 911 | static int ccdc_getfid(void) |
@@ -916,14 +922,14 @@ static inline void ccdc_setfbaddr(unsigned long addr) | |||
916 | 922 | ||
917 | static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params) | 923 | static 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 | ||
962 | static int __init dm355_ccdc_init(void) | 967 | static 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; |
1035 | fail_sclk: | ||
1036 | clk_put(ccdc_cfg.sclk); | ||
1037 | fail_mclk: | ||
1038 | clk_put(ccdc_cfg.mclk); | ||
1039 | fail_nomap: | ||
1040 | iounmap(ccdc_cfg.base_addr); | ||
1041 | fail_nomem: | ||
1042 | release_mem_region(res->start, resource_size(res)); | ||
1043 | fail_nores: | ||
1044 | vpfe_unregister_ccdc_device(&ccdc_hw_dev); | ||
1045 | return status; | ||
970 | } | 1046 | } |
971 | 1047 | ||
972 | static void __exit dm355_ccdc_exit(void) | 1048 | static 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 | |||
1062 | static 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 | |||
1071 | static int __init dm355_ccdc_init(void) | ||
1072 | { | ||
1073 | return platform_driver_register(&dm355_ccdc_driver); | ||
1074 | } | ||
1075 | |||
1076 | static void __exit dm355_ccdc_exit(void) | ||
1077 | { | ||
1078 | platform_driver_unregister(&dm355_ccdc_driver); | ||
975 | } | 1079 | } |
976 | 1080 | ||
977 | module_init(dm355_ccdc_init); | 1081 | module_init(dm355_ccdc_init); |