Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-btrfs-devel.git] / drivers / media / video / davinci / vpbe_venc.c
blob03a3e5c65ee78c53c017096ca55cf35d81ec0402
1 /*
2 * Copyright (C) 2010 Texas Instruments Inc
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.
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.
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
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>
28 #include <mach/hardware.h>
29 #include <mach/mux.h>
30 #include <mach/io.h>
31 #include <mach/i2c.h>
33 #include <linux/io.h>
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>
40 #include "vpbe_venc_regs.h"
42 #define MODULE_NAME VPBE_VENC_SUBDEV_NAME
44 static int debug = 2;
45 module_param(debug, int, 0644);
46 MODULE_PARM_DESC(debug, "Debug level 0-2");
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;
60 static inline struct venc_state *to_state(struct v4l2_subdev *sd)
62 return container_of(sd, struct venc_state, sd);
65 static inline u32 venc_read(struct v4l2_subdev *sd, u32 offset)
67 struct venc_state *venc = to_state(sd);
69 return readl(venc->venc_base + offset);
72 static inline u32 venc_write(struct v4l2_subdev *sd, u32 offset, u32 val)
74 struct venc_state *venc = to_state(sd);
76 writel(val, (venc->venc_base + offset));
78 return val;
81 static inline u32 venc_modify(struct v4l2_subdev *sd, u32 offset,
82 u32 val, u32 mask)
84 u32 new_val = (venc_read(sd, offset) & ~mask) | (val & mask);
86 venc_write(sd, offset, new_val);
88 return new_val;
91 static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val)
93 struct venc_state *venc = to_state(sd);
95 writel(val, venc->vdaccfg_reg);
97 val = readl(venc->vdaccfg_reg);
99 return val;
102 /* This function sets the dac of the VPBE for various outputs
104 static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index)
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;
122 return 0;
125 static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable)
127 v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n");
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);
144 } else {
145 venc_write(sd, VENC_VMOD, 0);
146 /* disable VCLK output pin enable */
147 venc_write(sd, VENC_VIDCTL, 0x141);
149 /* Disable output sync pins */
150 venc_write(sd, VENC_SYNCCTL, 0);
152 /* Disable DCLOCK */
153 venc_write(sd, VENC_DCLKCTL, 0);
154 venc_write(sd, VENC_DRGBX1, 0x0000057C);
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);
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);
169 venc_write(sd, VENC_HSDLY, 0);
170 venc_write(sd, VENC_VSDLY, 0);
172 venc_write(sd, VENC_YCCCTL, 0);
173 venc_write(sd, VENC_VSTARTA, 0);
175 /* Set OSD clock and OSD Sync Adavance registers */
176 venc_write(sd, VENC_OSDCLK0, 1);
177 venc_write(sd, VENC_OSDCLK1, 2);
182 * setting NTSC mode
184 static int venc_set_ntsc(struct v4l2_subdev *sd)
186 struct venc_state *venc = to_state(sd);
187 struct venc_platform_data *pdata = venc->pdata;
189 v4l2_dbg(debug, 2, sd, "venc_set_ntsc\n");
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;
196 venc_enabledigitaloutput(sd, 0);
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);
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);
214 return 0;
218 * setting PAL mode
220 static int venc_set_pal(struct v4l2_subdev *sd)
222 struct venc_state *venc = to_state(sd);
224 v4l2_dbg(debug, 2, sd, "venc_set_pal\n");
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;
231 venc_enabledigitaloutput(sd, 0);
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);
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);
252 return 0;
256 * venc_set_480p59_94
258 * This function configures the video encoder to EDTV(525p) component setting.
260 static int venc_set_480p59_94(struct v4l2_subdev *sd)
262 struct venc_state *venc = to_state(sd);
263 struct venc_platform_data *pdata = venc->pdata;
265 v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n");
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;
271 venc_enabledigitaloutput(sd, 0);
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);
288 venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC);
290 return 0;
294 * venc_set_625p
296 * This function configures the video encoder to HDTV(625p) component setting
298 static int venc_set_576p50(struct v4l2_subdev *sd)
300 struct venc_state *venc = to_state(sd);
301 struct venc_platform_data *pdata = venc->pdata;
303 v4l2_dbg(debug, 2, sd, "venc_set_576p50\n");
305 /* Setup clock at VPSS & VENC for SD */
306 if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0)
307 return -EINVAL;
309 venc_enabledigitaloutput(sd, 0);
311 venc_write(sd, VENC_OSDCLK0, 0);
312 venc_write(sd, VENC_OSDCLK1, 1);
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);
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);
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);
330 return 0;
333 static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
335 v4l2_dbg(debug, 1, sd, "venc_s_std_output\n");
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);
342 return -EINVAL;
345 static int venc_s_dv_preset(struct v4l2_subdev *sd,
346 struct v4l2_dv_preset *dv_preset)
348 v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n");
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);
355 return -EINVAL;
358 static int venc_s_routing(struct v4l2_subdev *sd, u32 input, u32 output,
359 u32 config)
361 struct venc_state *venc = to_state(sd);
362 int ret;
364 v4l2_dbg(debug, 1, sd, "venc_s_routing\n");
366 ret = venc_set_dac(sd, output);
367 if (!ret)
368 venc->output = output;
370 return ret;
373 static long venc_ioctl(struct v4l2_subdev *sd,
374 unsigned int cmd,
375 void *arg)
377 u32 val;
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;
390 return 0;
393 static const struct v4l2_subdev_core_ops venc_core_ops = {
394 .ioctl = venc_ioctl,
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,
403 static const struct v4l2_subdev_ops venc_ops = {
404 .core = &venc_core_ops,
405 .video = &venc_video_ops,
408 static int venc_initialize(struct v4l2_subdev *sd)
410 struct venc_state *venc = to_state(sd);
411 int ret;
413 /* Set default to output to composite and std to NTSC */
414 venc->output = 0;
415 venc->std = V4L2_STD_525_60;
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;
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;
429 return ret;
432 static int venc_device_get(struct device *dev, void *data)
434 struct platform_device *pdev = to_platform_device(dev);
435 struct venc_state **venc = data;
437 if (strcmp(MODULE_NAME, pdev->name) == 0)
438 *venc = platform_get_drvdata(pdev);
440 return 0;
443 struct v4l2_subdev *venc_sub_dev_init(struct v4l2_device *v4l2_dev,
444 const char *venc_name)
446 struct venc_state *venc;
447 int err;
449 err = bus_for_each_dev(&platform_bus_type, NULL, &venc,
450 venc_device_get);
451 if (venc == NULL)
452 return NULL;
454 v4l2_subdev_init(&venc->sd, &venc_ops);
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;
462 if (venc_initialize(&venc->sd)) {
463 v4l2_err(v4l2_dev,
464 "vpbe venc initialization failed\n");
465 return NULL;
468 return &venc->sd;
470 EXPORT_SYMBOL(venc_sub_dev_init);
472 static int venc_probe(struct platform_device *pdev)
474 struct venc_state *venc;
475 struct resource *res;
476 int ret;
478 venc = kzalloc(sizeof(struct venc_state), GFP_KERNEL);
479 if (venc == NULL)
480 return -ENOMEM;
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;
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;
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;
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;
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;
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;
524 static int venc_remove(struct platform_device *pdev)
526 struct venc_state *venc = platform_get_drvdata(pdev);
527 struct resource *res;
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);
534 return 0;
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,
546 static int venc_init(void)
548 if (platform_driver_register(&venc_driver)) {
549 printk(KERN_ERR "Unable to register venc driver\n");
550 return -ENODEV;
552 return 0;
555 static void venc_exit(void)
557 platform_driver_unregister(&venc_driver);
558 return;
561 module_init(venc_init);
562 module_exit(venc_exit);
564 MODULE_LICENSE("GPL");
565 MODULE_DESCRIPTION("VPBE VENC Driver");
566 MODULE_AUTHOR("Texas Instruments");