diff options
-rw-r--r-- | drivers/media/video/davinci/vpbe_venc.c | 566 | ||||
-rw-r--r-- | drivers/media/video/davinci/vpbe_venc_regs.h | 177 | ||||
-rw-r--r-- | include/media/davinci/vpbe_venc.h | 45 |
3 files changed, 788 insertions, 0 deletions
diff --git a/drivers/media/video/davinci/vpbe_venc.c b/drivers/media/video/davinci/vpbe_venc.c new file mode 100644 index 000000000000..03a3e5c65ee7 --- /dev/null +++ b/drivers/media/video/davinci/vpbe_venc.c | |||
@@ -0,0 +1,566 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 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 version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
16 | */ | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/ctype.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/device.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <linux/videodev2.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #include <mach/hardware.h> | ||
29 | #include <mach/mux.h> | ||
30 | #include <mach/io.h> | ||
31 | #include <mach/i2c.h> | ||
32 | |||
33 | #include <linux/io.h> | ||
34 | |||
35 | #include <media/davinci/vpbe_types.h> | ||
36 | #include <media/davinci/vpbe_venc.h> | ||
37 | #include <media/davinci/vpss.h> | ||
38 | #include <media/v4l2-device.h> | ||
39 | |||
40 | #include "vpbe_venc_regs.h" | ||
41 | |||
42 | #define MODULE_NAME VPBE_VENC_SUBDEV_NAME | ||
43 | |||
44 | static int debug = 2; | ||
45 | module_param(debug, int, 0644); | ||
46 | MODULE_PARM_DESC(debug, "Debug level 0-2"); | ||
47 | |||
48 | struct venc_state { | ||
49 | struct v4l2_subdev sd; | ||
50 | struct venc_callback *callback; | ||
51 | struct venc_platform_data *pdata; | ||
52 | struct device *pdev; | ||
53 | u32 output; | ||
54 | v4l2_std_id std; | ||
55 | spinlock_t lock; | ||
56 | void __iomem *venc_base; | ||
57 | void __iomem *vdaccfg_reg; | ||
58 | }; | ||
59 | |||
60 | static inline struct venc_state *to_state(struct v4l2_subdev *sd) | ||
61 | { | ||
62 | return container_of(sd, struct venc_state, sd); | ||
63 | } | ||
64 | |||
65 | static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset) | ||
66 | { | ||
67 | struct venc_state *venc = to_state(sd); | ||
68 | |||
69 | return readl(venc->venc_base + offset); | ||
70 | } | ||
71 | |||
72 | static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val) | ||
73 | { | ||
74 | struct venc_state *venc = to_state(sd); | ||
75 | |||
76 | writel(val, (venc->venc_base + offset)); | ||
77 | |||
78 | return val; | ||
79 | } | ||
80 | |||
81 | static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset, | ||
82 | u32 val, u32 mask) | ||
83 | { | ||
84 | u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask); | ||
85 | |||
86 | venc_write(sd, offset, new_val); | ||
87 | |||
88 | return new_val; | ||
89 | } | ||
90 | |||
91 | static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val) | ||
92 | { | ||
93 | struct venc_state *venc = to_state(sd); | ||
94 | |||
95 | writel(val, venc->vdaccfg_reg); | ||
96 | |||
97 | val = readl(venc->vdaccfg_reg); | ||
98 | |||
99 | return val; | ||
100 | } | ||
101 | |||
102 | /* This function sets the dac of the VPBE for various outputs | ||
103 | */ | ||
104 | static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index) | ||
105 | { | ||
106 | switch (out_index) { | ||
107 | case 0: | ||
108 | v4l2_dbg(debug, 1, sd, "Setting output to Composite\n"); | ||
109 | venc_write(sd, VENC_DACSEL, 0); | ||
110 | break; | ||
111 | case 1: | ||
112 | v4l2_dbg(debug, 1, sd, "Setting output to S-Video\n"); | ||
113 | venc_write(sd, VENC_DACSEL, 0x210); | ||
114 | break; | ||
115 | case 2: | ||
116 | venc_write(sd, VENC_DACSEL, 0x543); | ||
117 | break; | ||
118 | default: | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable) | ||
126 | { | ||
127 | v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n"); | ||
128 | |||
129 | if (benable) { | ||
130 | venc_write(sd, VENC_VMOD, 0); | ||
131 | venc_write(sd, VENC_CVBS, 0); | ||
132 | venc_write(sd, VENC_LCDOUT, 0); | ||
133 | venc_write(sd, VENC_HSPLS, 0); | ||
134 | venc_write(sd, VENC_HSTART, 0); | ||
135 | venc_write(sd, VENC_HVALID, 0); | ||
136 | venc_write(sd, VENC_HINT, 0); | ||
137 | venc_write(sd, VENC_VSPLS, 0); | ||
138 | venc_write(sd, VENC_VSTART, 0); | ||
139 | venc_write(sd, VENC_VVALID, 0); | ||
140 | venc_write(sd, VENC_VINT, 0); | ||
141 | venc_write(sd, VENC_YCCCTL, 0); | ||
142 | venc_write(sd, VENC_DACSEL, 0); | ||
143 | |||
144 | } else { | ||
145 | venc_write(sd, VENC_VMOD, 0); | ||
146 | /* disable VCLK output pin enable */ | ||
147 | venc_write(sd, VENC_VIDCTL, 0x141); | ||
148 | |||
149 | /* Disable output sync pins */ | ||
150 | venc_write(sd, VENC_SYNCCTL, 0); | ||
151 | |||
152 | /* Disable DCLOCK */ | ||
153 | venc_write(sd, VENC_DCLKCTL, 0); | ||
154 | venc_write(sd, VENC_DRGBX1, 0x0000057C); | ||
155 | |||
156 | /* Disable LCD output control (accepting default polarity) */ | ||
157 | venc_write(sd, VENC_LCDOUT, 0); | ||
158 | venc_write(sd, VENC_CMPNT, 0x100); | ||
159 | venc_write(sd, VENC_HSPLS, 0); | ||
160 | venc_write(sd, VENC_HINT, 0); | ||
161 | venc_write(sd, VENC_HSTART, 0); | ||
162 | venc_write(sd, VENC_HVALID, 0); | ||
163 | |||
164 | venc_write(sd, VENC_VSPLS, 0); | ||
165 | venc_write(sd, VENC_VINT, 0); | ||
166 | venc_write(sd, VENC_VSTART, 0); | ||
167 | venc_write(sd, VENC_VVALID, 0); | ||
168 | |||
169 | venc_write(sd, VENC_HSDLY, 0); | ||
170 | venc_write(sd, VENC_VSDLY, 0); | ||
171 | |||
172 | venc_write(sd, VENC_YCCCTL, 0); | ||
173 | venc_write(sd, VENC_VSTARTA, 0); | ||
174 | |||
175 | /* Set OSD clock and OSD Sync Adavance registers */ | ||
176 | venc_write(sd, VENC_OSDCLK0, 1); | ||
177 | venc_write(sd, VENC_OSDCLK1, 2); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * setting NTSC mode | ||
183 | */ | ||
184 | static int venc_set_ntsc(struct v4l2_subdev *sd) | ||
185 | { | ||
186 | struct venc_state *venc = to_state(sd); | ||
187 | struct venc_platform_data *pdata = venc->pdata; | ||
188 | |||
189 | v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n"); | ||
190 | |||
191 | /* Setup clock at VPSS & VENC for SD */ | ||
192 | vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1); | ||
193 | if (pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_525_60) < 0) | ||
194 | return -EINVAL; | ||
195 | |||
196 | venc_enabledigitaloutput(sd, 0); | ||
197 | |||
198 | /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ | ||
199 | venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); | ||
200 | /* Set REC656 Mode */ | ||
201 | venc_write(sd, VENC_YCCCTL, 0x1); | ||
202 | venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ); | ||
203 | venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS); | ||
204 | |||
205 | venc_write(sd, VENC_VMOD, 0); | ||
206 | venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), | ||
207 | VENC_VMOD_VIE); | ||
208 | venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_VMD), VENC_VMOD_VMD); | ||
209 | venc_modify(sd, VENC_VMOD, (0 << VENC_VMOD_TVTYP_SHIFT), | ||
210 | VENC_VMOD_TVTYP); | ||
211 | venc_write(sd, VENC_DACTST, 0x0); | ||
212 | venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * setting PAL mode | ||
219 | */ | ||
220 | static int venc_set_pal(struct v4l2_subdev *sd) | ||
221 | { | ||
222 | struct venc_state *venc = to_state(sd); | ||
223 | |||
224 | v4l2_dbg(debug, 2, sd, "venc_set_pal\n"); | ||
225 | |||
226 | /* Setup clock at VPSS & VENC for SD */ | ||
227 | vpss_enable_clock(VPSS_VENC_CLOCK_SEL, 1); | ||
228 | if (venc->pdata->setup_clock(VPBE_ENC_STD, V4L2_STD_625_50) < 0) | ||
229 | return -EINVAL; | ||
230 | |||
231 | venc_enabledigitaloutput(sd, 0); | ||
232 | |||
233 | /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ | ||
234 | venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); | ||
235 | /* Set REC656 Mode */ | ||
236 | venc_write(sd, VENC_YCCCTL, 0x1); | ||
237 | |||
238 | venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT, | ||
239 | VENC_SYNCCTL_OVD); | ||
240 | venc_write(sd, VENC_VMOD, 0); | ||
241 | venc_modify(sd, VENC_VMOD, | ||
242 | (1 << VENC_VMOD_VIE_SHIFT), | ||
243 | VENC_VMOD_VIE); | ||
244 | venc_modify(sd, VENC_VMOD, | ||
245 | (0 << VENC_VMOD_VMD), VENC_VMOD_VMD); | ||
246 | venc_modify(sd, VENC_VMOD, | ||
247 | (1 << VENC_VMOD_TVTYP_SHIFT), | ||
248 | VENC_VMOD_TVTYP); | ||
249 | venc_write(sd, VENC_DACTST, 0x0); | ||
250 | venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * venc_set_480p59_94 | ||
257 | * | ||
258 | * This function configures the video encoder to EDTV(525p) component setting. | ||
259 | */ | ||
260 | static int venc_set_480p59_94(struct v4l2_subdev *sd) | ||
261 | { | ||
262 | struct venc_state *venc = to_state(sd); | ||
263 | struct venc_platform_data *pdata = venc->pdata; | ||
264 | |||
265 | v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n"); | ||
266 | |||
267 | /* Setup clock at VPSS & VENC for SD */ | ||
268 | if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0) | ||
269 | return -EINVAL; | ||
270 | |||
271 | venc_enabledigitaloutput(sd, 0); | ||
272 | |||
273 | venc_write(sd, VENC_OSDCLK0, 0); | ||
274 | venc_write(sd, VENC_OSDCLK1, 1); | ||
275 | venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, | ||
276 | VENC_VDPRO_DAFRQ); | ||
277 | venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, | ||
278 | VENC_VDPRO_DAUPS); | ||
279 | venc_write(sd, VENC_VMOD, 0); | ||
280 | venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), | ||
281 | VENC_VMOD_VIE); | ||
282 | venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD); | ||
283 | venc_modify(sd, VENC_VMOD, (HDTV_525P << VENC_VMOD_TVTYP_SHIFT), | ||
284 | VENC_VMOD_TVTYP); | ||
285 | venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 << | ||
286 | VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD); | ||
287 | |||
288 | venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * venc_set_625p | ||
295 | * | ||
296 | * This function configures the video encoder to HDTV(625p) component setting | ||
297 | */ | ||
298 | static int venc_set_576p50(struct v4l2_subdev *sd) | ||
299 | { | ||
300 | struct venc_state *venc = to_state(sd); | ||
301 | struct venc_platform_data *pdata = venc->pdata; | ||
302 | |||
303 | v4l2_dbg(debug, 2, sd, "venc_set_576p50\n"); | ||
304 | |||
305 | /* Setup clock at VPSS & VENC for SD */ | ||
306 | if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0) | ||
307 | return -EINVAL; | ||
308 | |||
309 | venc_enabledigitaloutput(sd, 0); | ||
310 | |||
311 | venc_write(sd, VENC_OSDCLK0, 0); | ||
312 | venc_write(sd, VENC_OSDCLK1, 1); | ||
313 | |||
314 | venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, | ||
315 | VENC_VDPRO_DAFRQ); | ||
316 | venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, | ||
317 | VENC_VDPRO_DAUPS); | ||
318 | |||
319 | venc_write(sd, VENC_VMOD, 0); | ||
320 | venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), | ||
321 | VENC_VMOD_VIE); | ||
322 | venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD); | ||
323 | venc_modify(sd, VENC_VMOD, (HDTV_625P << VENC_VMOD_TVTYP_SHIFT), | ||
324 | VENC_VMOD_TVTYP); | ||
325 | |||
326 | venc_modify(sd, VENC_VMOD, VENC_VMOD_VDMD_YCBCR8 << | ||
327 | VENC_VMOD_VDMD_SHIFT, VENC_VMOD_VDMD); | ||
328 | venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) | ||
334 | { | ||
335 | v4l2_dbg(debug, 1, sd, "venc_s_std_output\n"); | ||
336 | |||
337 | if (norm & V4L2_STD_525_60) | ||
338 | return venc_set_ntsc(sd); | ||
339 | else if (norm & V4L2_STD_625_50) | ||
340 | return venc_set_pal(sd); | ||
341 | |||
342 | return -EINVAL; | ||
343 | } | ||
344 | |||
345 | static int venc_s_dv_preset(struct v4l2_subdev *sd, | ||
346 | struct v4l2_dv_preset *dv_preset) | ||
347 | { | ||
348 | v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n"); | ||
349 | |||
350 | if (dv_preset->preset == V4L2_DV_576P50) | ||
351 | return venc_set_576p50(sd); | ||
352 | else if (dv_preset->preset == V4L2_DV_480P59_94) | ||
353 | return venc_set_480p59_94(sd); | ||
354 | |||
355 | return -EINVAL; | ||
356 | } | ||
357 | |||
358 | static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output, | ||
359 | u32 config) | ||
360 | { | ||
361 | struct venc_state *venc = to_state(sd); | ||
362 | int ret; | ||
363 | |||
364 | v4l2_dbg(debug, 1, sd, "venc_s_routing\n"); | ||
365 | |||
366 | ret = venc_set_dac(sd, output); | ||
367 | if (!ret) | ||
368 | venc->output = output; | ||
369 | |||
370 | return ret; | ||
371 | } | ||
372 | |||
373 | static long venc_ioctl(struct v4l2_subdev *sd, | ||
374 | unsigned int cmd, | ||
375 | void *arg) | ||
376 | { | ||
377 | u32 val; | ||
378 | |||
379 | switch (cmd) { | ||
380 | case VENC_GET_FLD: | ||
381 | val = venc_read(sd, VENC_VSTAT); | ||
382 | *((int *)arg) = ((val & VENC_VSTAT_FIDST) == | ||
383 | VENC_VSTAT_FIDST); | ||
384 | break; | ||
385 | default: | ||
386 | v4l2_err(sd, "Wrong IOCTL cmd\n"); | ||
387 | break; | ||
388 | } | ||
389 | |||
390 | return 0; | ||
391 | } | ||
392 | |||
393 | static const struct v4l2_subdev_core_ops venc_core_ops = { | ||
394 | .ioctl = venc_ioctl, | ||
395 | }; | ||
396 | |||
397 | static const struct v4l2_subdev_video_ops venc_video_ops = { | ||
398 | .s_routing = venc_s_routing, | ||
399 | .s_std_output = venc_s_std_output, | ||
400 | .s_dv_preset = venc_s_dv_preset, | ||
401 | }; | ||
402 | |||
403 | static const struct v4l2_subdev_ops venc_ops = { | ||
404 | .core = &venc_core_ops, | ||
405 | .video = &venc_video_ops, | ||
406 | }; | ||
407 | |||
408 | static int venc_initialize(struct v4l2_subdev *sd) | ||
409 | { | ||
410 | struct venc_state *venc = to_state(sd); | ||
411 | int ret; | ||
412 | |||
413 | /* Set default to output to composite and std to NTSC */ | ||
414 | venc->output = 0; | ||
415 | venc->std = V4L2_STD_525_60; | ||
416 | |||
417 | ret = venc_s_routing(sd, 0, venc->output, 0); | ||
418 | if (ret < 0) { | ||
419 | v4l2_err(sd, "Error setting output during init\n"); | ||
420 | return -EINVAL; | ||
421 | } | ||
422 | |||
423 | ret = venc_s_std_output(sd, venc->std); | ||
424 | if (ret < 0) { | ||
425 | v4l2_err(sd, "Error setting std during init\n"); | ||
426 | return -EINVAL; | ||
427 | } | ||
428 | |||
429 | return ret; | ||
430 | } | ||
431 | |||
432 | static int venc_device_get(struct device *dev, void *data) | ||
433 | { | ||
434 | struct platform_device *pdev = to_platform_device(dev); | ||
435 | struct venc_state **venc = data; | ||
436 | |||
437 | if (strcmp(MODULE_NAME, pdev->name) == 0) | ||
438 | *venc = platform_get_drvdata(pdev); | ||
439 | |||
440 | return 0; | ||
441 | } | ||
442 | |||
443 | struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev, | ||
444 | const char *venc_name) | ||
445 | { | ||
446 | struct venc_state *venc; | ||
447 | int err; | ||
448 | |||
449 | err = bus_for_each_dev(&platform_bus_type, NULL, &venc, | ||
450 | venc_device_get); | ||
451 | if (venc == NULL) | ||
452 | return NULL; | ||
453 | |||
454 | v4l2_subdev_init(&venc->sd, &venc_ops); | ||
455 | |||
456 | strcpy(venc->sd.name, venc_name); | ||
457 | if (v4l2_device_register_subdev(v4l2_dev, &venc->sd) < 0) { | ||
458 | v4l2_err(v4l2_dev, | ||
459 | "vpbe unable to register venc sub device\n"); | ||
460 | return NULL; | ||
461 | } | ||
462 | if (venc_initialize(&venc->sd)) { | ||
463 | v4l2_err(v4l2_dev, | ||
464 | "vpbe venc initialization failed\n"); | ||
465 | return NULL; | ||
466 | } | ||
467 | |||
468 | return &venc->sd; | ||
469 | } | ||
470 | EXPORT_SYMBOL(venc_sub_dev_init); | ||
471 | |||
472 | static int venc_probe(struct platform_device *pdev) | ||
473 | { | ||
474 | struct venc_state *venc; | ||
475 | struct resource *res; | ||
476 | int ret; | ||
477 | |||
478 | venc = kzalloc(sizeof(struct venc_state), GFP_KERNEL); | ||
479 | if (venc == NULL) | ||
480 | return -ENOMEM; | ||
481 | |||
482 | venc->pdev = &pdev->dev; | ||
483 | venc->pdata = pdev->dev.platform_data; | ||
484 | if (NULL == venc->pdata) { | ||
485 | dev_err(venc->pdev, "Unable to get platform data for" | ||
486 | " VENC sub device"); | ||
487 | ret = -ENOENT; | ||
488 | goto free_mem; | ||
489 | } | ||
490 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
491 | if (!res) { | ||
492 | dev_err(venc->pdev, | ||
493 | "Unable to get VENC register address map\n"); | ||
494 | ret = -ENODEV; | ||
495 | goto free_mem; | ||
496 | } | ||
497 | |||
498 | if (!request_mem_region(res->start, resource_size(res), "venc")) { | ||
499 | dev_err(venc->pdev, "Unable to reserve VENC MMIO region\n"); | ||
500 | ret = -ENODEV; | ||
501 | goto free_mem; | ||
502 | } | ||
503 | |||
504 | venc->venc_base = ioremap_nocache(res->start, resource_size(res)); | ||
505 | if (!venc->venc_base) { | ||
506 | dev_err(venc->pdev, "Unable to map VENC IO space\n"); | ||
507 | ret = -ENODEV; | ||
508 | goto release_venc_mem_region; | ||
509 | } | ||
510 | |||
511 | spin_lock_init(&venc->lock); | ||
512 | platform_set_drvdata(pdev, venc); | ||
513 | dev_notice(venc->pdev, "VENC sub device probe success\n"); | ||
514 | return 0; | ||
515 | |||
516 | release_venc_mem_region: | ||
517 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
518 | release_mem_region(res->start, resource_size(res)); | ||
519 | free_mem: | ||
520 | kfree(venc); | ||
521 | return ret; | ||
522 | } | ||
523 | |||
524 | static int venc_remove(struct platform_device *pdev) | ||
525 | { | ||
526 | struct venc_state *venc = platform_get_drvdata(pdev); | ||
527 | struct resource *res; | ||
528 | |||
529 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
530 | iounmap((void *)venc->venc_base); | ||
531 | release_mem_region(res->start, resource_size(res)); | ||
532 | kfree(venc); | ||
533 | |||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | static struct platform_driver venc_driver = { | ||
538 | .probe = venc_probe, | ||
539 | .remove = venc_remove, | ||
540 | .driver = { | ||
541 | .name = MODULE_NAME, | ||
542 | .owner = THIS_MODULE, | ||
543 | }, | ||
544 | }; | ||
545 | |||
546 | static int venc_init(void) | ||
547 | { | ||
548 | if (platform_driver_register(&venc_driver)) { | ||
549 | printk(KERN_ERR "Unable to register venc driver\n"); | ||
550 | return -ENODEV; | ||
551 | } | ||
552 | return 0; | ||
553 | } | ||
554 | |||
555 | static void venc_exit(void) | ||
556 | { | ||
557 | platform_driver_unregister(&venc_driver); | ||
558 | return; | ||
559 | } | ||
560 | |||
561 | module_init(venc_init); | ||
562 | module_exit(venc_exit); | ||
563 | |||
564 | MODULE_LICENSE("GPL"); | ||
565 | MODULE_DESCRIPTION("VPBE VENC Driver"); | ||
566 | MODULE_AUTHOR("Texas Instruments"); | ||
diff --git a/drivers/media/video/davinci/vpbe_venc_regs.h b/drivers/media/video/davinci/vpbe_venc_regs.h new file mode 100644 index 000000000000..947cb1510776 --- /dev/null +++ b/drivers/media/video/davinci/vpbe_venc_regs.h | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006-2010 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 version 2.. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
16 | */ | ||
17 | #ifndef _VPBE_VENC_REGS_H | ||
18 | #define _VPBE_VENC_REGS_H | ||
19 | |||
20 | /* VPBE Video Encoder / Digital LCD Subsystem Registers (VENC) */ | ||
21 | #define VENC_VMOD 0x00 | ||
22 | #define VENC_VIDCTL 0x04 | ||
23 | #define VENC_VDPRO 0x08 | ||
24 | #define VENC_SYNCCTL 0x0C | ||
25 | #define VENC_HSPLS 0x10 | ||
26 | #define VENC_VSPLS 0x14 | ||
27 | #define VENC_HINT 0x18 | ||
28 | #define VENC_HSTART 0x1C | ||
29 | #define VENC_HVALID 0x20 | ||
30 | #define VENC_VINT 0x24 | ||
31 | #define VENC_VSTART 0x28 | ||
32 | #define VENC_VVALID 0x2C | ||
33 | #define VENC_HSDLY 0x30 | ||
34 | #define VENC_VSDLY 0x34 | ||
35 | #define VENC_YCCCTL 0x38 | ||
36 | #define VENC_RGBCTL 0x3C | ||
37 | #define VENC_RGBCLP 0x40 | ||
38 | #define VENC_LINECTL 0x44 | ||
39 | #define VENC_CULLLINE 0x48 | ||
40 | #define VENC_LCDOUT 0x4C | ||
41 | #define VENC_BRTS 0x50 | ||
42 | #define VENC_BRTW 0x54 | ||
43 | #define VENC_ACCTL 0x58 | ||
44 | #define VENC_PWMP 0x5C | ||
45 | #define VENC_PWMW 0x60 | ||
46 | #define VENC_DCLKCTL 0x64 | ||
47 | #define VENC_DCLKPTN0 0x68 | ||
48 | #define VENC_DCLKPTN1 0x6C | ||
49 | #define VENC_DCLKPTN2 0x70 | ||
50 | #define VENC_DCLKPTN3 0x74 | ||
51 | #define VENC_DCLKPTN0A 0x78 | ||
52 | #define VENC_DCLKPTN1A 0x7C | ||
53 | #define VENC_DCLKPTN2A 0x80 | ||
54 | #define VENC_DCLKPTN3A 0x84 | ||
55 | #define VENC_DCLKHS 0x88 | ||
56 | #define VENC_DCLKHSA 0x8C | ||
57 | #define VENC_DCLKHR 0x90 | ||
58 | #define VENC_DCLKVS 0x94 | ||
59 | #define VENC_DCLKVR 0x98 | ||
60 | #define VENC_CAPCTL 0x9C | ||
61 | #define VENC_CAPDO 0xA0 | ||
62 | #define VENC_CAPDE 0xA4 | ||
63 | #define VENC_ATR0 0xA8 | ||
64 | #define VENC_ATR1 0xAC | ||
65 | #define VENC_ATR2 0xB0 | ||
66 | #define VENC_VSTAT 0xB8 | ||
67 | #define VENC_RAMADR 0xBC | ||
68 | #define VENC_RAMPORT 0xC0 | ||
69 | #define VENC_DACTST 0xC4 | ||
70 | #define VENC_YCOLVL 0xC8 | ||
71 | #define VENC_SCPROG 0xCC | ||
72 | #define VENC_CVBS 0xDC | ||
73 | #define VENC_CMPNT 0xE0 | ||
74 | #define VENC_ETMG0 0xE4 | ||
75 | #define VENC_ETMG1 0xE8 | ||
76 | #define VENC_ETMG2 0xEC | ||
77 | #define VENC_ETMG3 0xF0 | ||
78 | #define VENC_DACSEL 0xF4 | ||
79 | #define VENC_ARGBX0 0x100 | ||
80 | #define VENC_ARGBX1 0x104 | ||
81 | #define VENC_ARGBX2 0x108 | ||
82 | #define VENC_ARGBX3 0x10C | ||
83 | #define VENC_ARGBX4 0x110 | ||
84 | #define VENC_DRGBX0 0x114 | ||
85 | #define VENC_DRGBX1 0x118 | ||
86 | #define VENC_DRGBX2 0x11C | ||
87 | #define VENC_DRGBX3 0x120 | ||
88 | #define VENC_DRGBX4 0x124 | ||
89 | #define VENC_VSTARTA 0x128 | ||
90 | #define VENC_OSDCLK0 0x12C | ||
91 | #define VENC_OSDCLK1 0x130 | ||
92 | #define VENC_HVLDCL0 0x134 | ||
93 | #define VENC_HVLDCL1 0x138 | ||
94 | #define VENC_OSDHADV 0x13C | ||
95 | #define VENC_CLKCTL 0x140 | ||
96 | #define VENC_GAMCTL 0x144 | ||
97 | #define VENC_XHINTVL 0x174 | ||
98 | |||
99 | /* bit definitions */ | ||
100 | #define VPBE_PCR_VENC_DIV (1 << 1) | ||
101 | #define VPBE_PCR_CLK_OFF (1 << 0) | ||
102 | |||
103 | #define VENC_VMOD_VDMD_SHIFT 12 | ||
104 | #define VENC_VMOD_VDMD_YCBCR16 0 | ||
105 | #define VENC_VMOD_VDMD_YCBCR8 1 | ||
106 | #define VENC_VMOD_VDMD_RGB666 2 | ||
107 | #define VENC_VMOD_VDMD_RGB8 3 | ||
108 | #define VENC_VMOD_VDMD_EPSON 4 | ||
109 | #define VENC_VMOD_VDMD_CASIO 5 | ||
110 | #define VENC_VMOD_VDMD_UDISPQVGA 6 | ||
111 | #define VENC_VMOD_VDMD_STNLCD 7 | ||
112 | #define VENC_VMOD_VIE_SHIFT 1 | ||
113 | #define VENC_VMOD_VDMD (7 << 12) | ||
114 | #define VENC_VMOD_ITLCL (1 << 11) | ||
115 | #define VENC_VMOD_ITLC (1 << 10) | ||
116 | #define VENC_VMOD_NSIT (1 << 9) | ||
117 | #define VENC_VMOD_HDMD (1 << 8) | ||
118 | #define VENC_VMOD_TVTYP_SHIFT 6 | ||
119 | #define VENC_VMOD_TVTYP (3 << 6) | ||
120 | #define VENC_VMOD_SLAVE (1 << 5) | ||
121 | #define VENC_VMOD_VMD (1 << 4) | ||
122 | #define VENC_VMOD_BLNK (1 << 3) | ||
123 | #define VENC_VMOD_VIE (1 << 1) | ||
124 | #define VENC_VMOD_VENC (1 << 0) | ||
125 | |||
126 | /* VMOD TVTYP options for HDMD=0 */ | ||
127 | #define SDTV_NTSC 0 | ||
128 | #define SDTV_PAL 1 | ||
129 | /* VMOD TVTYP options for HDMD=1 */ | ||
130 | #define HDTV_525P 0 | ||
131 | #define HDTV_625P 1 | ||
132 | #define HDTV_1080I 2 | ||
133 | #define HDTV_720P 3 | ||
134 | |||
135 | #define VENC_VIDCTL_VCLKP (1 << 14) | ||
136 | #define VENC_VIDCTL_VCLKE_SHIFT 13 | ||
137 | #define VENC_VIDCTL_VCLKE (1 << 13) | ||
138 | #define VENC_VIDCTL_VCLKZ_SHIFT 12 | ||
139 | #define VENC_VIDCTL_VCLKZ (1 << 12) | ||
140 | #define VENC_VIDCTL_SYDIR_SHIFT 8 | ||
141 | #define VENC_VIDCTL_SYDIR (1 << 8) | ||
142 | #define VENC_VIDCTL_DOMD_SHIFT 4 | ||
143 | #define VENC_VIDCTL_DOMD (3 << 4) | ||
144 | #define VENC_VIDCTL_YCDIR_SHIFT 0 | ||
145 | #define VENC_VIDCTL_YCDIR (1 << 0) | ||
146 | |||
147 | #define VENC_VDPRO_ATYCC_SHIFT 5 | ||
148 | #define VENC_VDPRO_ATYCC (1 << 5) | ||
149 | #define VENC_VDPRO_ATCOM_SHIFT 4 | ||
150 | #define VENC_VDPRO_ATCOM (1 << 4) | ||
151 | #define VENC_VDPRO_DAFRQ (1 << 3) | ||
152 | #define VENC_VDPRO_DAUPS (1 << 2) | ||
153 | #define VENC_VDPRO_CUPS (1 << 1) | ||
154 | #define VENC_VDPRO_YUPS (1 << 0) | ||
155 | |||
156 | #define VENC_SYNCCTL_VPL_SHIFT 3 | ||
157 | #define VENC_SYNCCTL_VPL (1 << 3) | ||
158 | #define VENC_SYNCCTL_HPL_SHIFT 2 | ||
159 | #define VENC_SYNCCTL_HPL (1 << 2) | ||
160 | #define VENC_SYNCCTL_SYEV_SHIFT 1 | ||
161 | #define VENC_SYNCCTL_SYEV (1 << 1) | ||
162 | #define VENC_SYNCCTL_SYEH_SHIFT 0 | ||
163 | #define VENC_SYNCCTL_SYEH (1 << 0) | ||
164 | #define VENC_SYNCCTL_OVD_SHIFT 14 | ||
165 | #define VENC_SYNCCTL_OVD (1 << 14) | ||
166 | |||
167 | #define VENC_DCLKCTL_DCKEC_SHIFT 11 | ||
168 | #define VENC_DCLKCTL_DCKEC (1 << 11) | ||
169 | #define VENC_DCLKCTL_DCKPW_SHIFT 0 | ||
170 | #define VENC_DCLKCTL_DCKPW (0x3f << 0) | ||
171 | |||
172 | #define VENC_VSTAT_FIDST (1 << 4) | ||
173 | |||
174 | #define VENC_CMPNT_MRGB_SHIFT 14 | ||
175 | #define VENC_CMPNT_MRGB (1 << 14) | ||
176 | |||
177 | #endif /* _VPBE_VENC_REGS_H */ | ||
diff --git a/include/media/davinci/vpbe_venc.h b/include/media/davinci/vpbe_venc.h new file mode 100644 index 000000000000..426c205831a2 --- /dev/null +++ b/include/media/davinci/vpbe_venc.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 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 version 2. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
16 | */ | ||
17 | #ifndef _VPBE_VENC_H | ||
18 | #define _VPBE_VENC_H | ||
19 | |||
20 | #include <media/v4l2-subdev.h> | ||
21 | #include <media/davinci/vpbe_types.h> | ||
22 | |||
23 | #define VPBE_VENC_SUBDEV_NAME "vpbe-venc" | ||
24 | |||
25 | /* venc events */ | ||
26 | #define VENC_END_OF_FRAME BIT(0) | ||
27 | #define VENC_FIRST_FIELD BIT(1) | ||
28 | #define VENC_SECOND_FIELD BIT(2) | ||
29 | |||
30 | struct venc_platform_data { | ||
31 | enum vpbe_version venc_type; | ||
32 | int (*setup_clock)(enum vpbe_enc_timings_type type, | ||
33 | unsigned int mode); | ||
34 | /* Number of LCD outputs supported */ | ||
35 | int num_lcd_outputs; | ||
36 | }; | ||
37 | |||
38 | enum venc_ioctls { | ||
39 | VENC_GET_FLD = 1, | ||
40 | }; | ||
41 | |||
42 | /* exported functions */ | ||
43 | struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev, | ||
44 | const char *venc_name); | ||
45 | #endif | ||