aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManjunath Hadli <manjunath.hadli@ti.com>2011-06-17 03:01:31 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-07-27 16:53:09 -0400
commita2c25b444e99f2369b29e507568c8703186174d0 (patch)
treec67e95cb9f0a3b83274b1f0c79c6c25fba3dc687
parent9a78efc8fbd6776cd0f704be9cac7b013f3d3d16 (diff)
[media] davinci vpbe: V4L2 display driver for DM644X SoC
This is the display driver for Texas Instruments's DM644X family SoC. This patch contains the main implementation of the driver with the V4L2 interface. The driver implements the streaming model with support for both kernel allocated buffers and user pointers. It also implements all of the necessary IOCTLs necessary and supported by the video display device. Signed-off-by: Manjunath Hadli <manjunath.hadli@ti.com> Acked-by: Muralidharan Karicheri <m-karicheri2@ti.com> Acked-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/davinci/vpbe_display.c1860
-rw-r--r--include/media/davinci/vpbe_display.h147
-rw-r--r--include/media/davinci/vpbe_types.h91
3 files changed, 2098 insertions, 0 deletions
diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c
new file mode 100644
index 000000000000..7f1d83a6d575
--- /dev/null
+++ b/drivers/media/video/davinci/vpbe_display.c
@@ -0,0 +1,1860 @@
1/*
2 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/errno.h>
17#include <linux/interrupt.h>
18#include <linux/string.h>
19#include <linux/wait.h>
20#include <linux/time.h>
21#include <linux/platform_device.h>
22#include <linux/irq.h>
23#include <linux/mm.h>
24#include <linux/mutex.h>
25#include <linux/videodev2.h>
26#include <linux/slab.h>
27
28#include <asm/pgtable.h>
29#include <mach/cputype.h>
30
31#include <media/v4l2-dev.h>
32#include <media/v4l2-common.h>
33#include <media/v4l2-ioctl.h>
34#include <media/v4l2-device.h>
35#include <media/davinci/vpbe_display.h>
36#include <media/davinci/vpbe_types.h>
37#include <media/davinci/vpbe.h>
38#include <media/davinci/vpbe_venc.h>
39#include <media/davinci/vpbe_osd.h>
40#include "vpbe_venc_regs.h"
41
42#define VPBE_DISPLAY_DRIVER "vpbe-v4l2"
43
44static int debug;
45
46#define VPBE_DISPLAY_SD_BUF_SIZE (720*576*2)
47#define VPBE_DEFAULT_NUM_BUFS 3
48
49module_param(debug, int, 0644);
50
51static int venc_is_second_field(struct vpbe_display *disp_dev)
52{
53 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
54 int ret;
55 int val;
56
57 ret = v4l2_subdev_call(vpbe_dev->venc,
58 core,
59 ioctl,
60 VENC_GET_FLD,
61 &val);
62 if (ret < 0) {
63 v4l2_err(&vpbe_dev->v4l2_dev,
64 "Error in getting Field ID 0\n");
65 }
66 return val;
67}
68
69static void vpbe_isr_even_field(struct vpbe_display *disp_obj,
70 struct vpbe_layer *layer)
71{
72 struct timespec timevalue;
73
74 if (layer->cur_frm == layer->next_frm)
75 return;
76 ktime_get_ts(&timevalue);
77 layer->cur_frm->ts.tv_sec = timevalue.tv_sec;
78 layer->cur_frm->ts.tv_usec = timevalue.tv_nsec / NSEC_PER_USEC;
79 layer->cur_frm->state = VIDEOBUF_DONE;
80 wake_up_interruptible(&layer->cur_frm->done);
81 /* Make cur_frm pointing to next_frm */
82 layer->cur_frm = layer->next_frm;
83}
84
85static void vpbe_isr_odd_field(struct vpbe_display *disp_obj,
86 struct vpbe_layer *layer)
87{
88 struct osd_state *osd_device = disp_obj->osd_device;
89 unsigned long addr;
90
91 spin_lock(&disp_obj->dma_queue_lock);
92 if (list_empty(&layer->dma_queue) ||
93 (layer->cur_frm != layer->next_frm)) {
94 spin_unlock(&disp_obj->dma_queue_lock);
95 return;
96 }
97 /*
98 * one field is displayed configure
99 * the next frame if it is available
100 * otherwise hold on current frame
101 * Get next from the buffer queue
102 */
103 layer->next_frm = list_entry(
104 layer->dma_queue.next,
105 struct videobuf_buffer,
106 queue);
107 /* Remove that from the buffer queue */
108 list_del(&layer->next_frm->queue);
109 spin_unlock(&disp_obj->dma_queue_lock);
110 /* Mark state of the frame to active */
111 layer->next_frm->state = VIDEOBUF_ACTIVE;
112 addr = videobuf_to_dma_contig(layer->next_frm);
113 osd_device->ops.start_layer(osd_device,
114 layer->layer_info.id,
115 addr,
116 disp_obj->cbcr_ofst);
117}
118
119/* interrupt service routine */
120static irqreturn_t venc_isr(int irq, void *arg)
121{
122 struct vpbe_display *disp_dev = (struct vpbe_display *)arg;
123 struct vpbe_layer *layer;
124 static unsigned last_event;
125 unsigned event = 0;
126 int fid;
127 int i;
128
129 if ((NULL == arg) || (NULL == disp_dev->dev[0]))
130 return IRQ_HANDLED;
131
132 if (venc_is_second_field(disp_dev))
133 event |= VENC_SECOND_FIELD;
134 else
135 event |= VENC_FIRST_FIELD;
136
137 if (event == (last_event & ~VENC_END_OF_FRAME)) {
138 /*
139 * If the display is non-interlaced, then we need to flag the
140 * end-of-frame event at every interrupt regardless of the
141 * value of the FIDST bit. We can conclude that the display is
142 * non-interlaced if the value of the FIDST bit is unchanged
143 * from the previous interrupt.
144 */
145 event |= VENC_END_OF_FRAME;
146 } else if (event == VENC_SECOND_FIELD) {
147 /* end-of-frame for interlaced display */
148 event |= VENC_END_OF_FRAME;
149 }
150 last_event = event;
151
152 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
153 layer = disp_dev->dev[i];
154 /* If streaming is started in this layer */
155 if (!layer->started)
156 continue;
157
158 if (layer->layer_first_int) {
159 layer->layer_first_int = 0;
160 continue;
161 }
162 /* Check the field format */
163 if ((V4L2_FIELD_NONE == layer->pix_fmt.field) &&
164 (event & VENC_END_OF_FRAME)) {
165 /* Progressive mode */
166
167 vpbe_isr_even_field(disp_dev, layer);
168 vpbe_isr_odd_field(disp_dev, layer);
169 } else {
170 /* Interlaced mode */
171
172 layer->field_id ^= 1;
173 if (event & VENC_FIRST_FIELD)
174 fid = 0;
175 else
176 fid = 1;
177
178 /*
179 * If field id does not match with store
180 * field id
181 */
182 if (fid != layer->field_id) {
183 /* Make them in sync */
184 layer->field_id = fid;
185 continue;
186 }
187 /*
188 * device field id and local field id are
189 * in sync. If this is even field
190 */
191 if (0 == fid)
192 vpbe_isr_even_field(disp_dev, layer);
193 else /* odd field */
194 vpbe_isr_odd_field(disp_dev, layer);
195 }
196 }
197
198 return IRQ_HANDLED;
199}
200
201/*
202 * vpbe_buffer_prepare()
203 * This is the callback function called from videobuf_qbuf() function
204 * the buffer is prepared and user space virtual address is converted into
205 * physical address
206 */
207static int vpbe_buffer_prepare(struct videobuf_queue *q,
208 struct videobuf_buffer *vb,
209 enum v4l2_field field)
210{
211 struct vpbe_fh *fh = q->priv_data;
212 struct vpbe_layer *layer = fh->layer;
213 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
214 unsigned long addr;
215 int ret;
216
217 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
218 "vpbe_buffer_prepare\n");
219
220 /* If buffer is not initialized, initialize it */
221 if (VIDEOBUF_NEEDS_INIT == vb->state) {
222 vb->width = layer->pix_fmt.width;
223 vb->height = layer->pix_fmt.height;
224 vb->size = layer->pix_fmt.sizeimage;
225 vb->field = field;
226
227 ret = videobuf_iolock(q, vb, NULL);
228 if (ret < 0) {
229 v4l2_err(&vpbe_dev->v4l2_dev, "Failed to map \
230 user address\n");
231 return -EINVAL;
232 }
233
234 addr = videobuf_to_dma_contig(vb);
235
236 if (q->streaming) {
237 if (!IS_ALIGNED(addr, 8)) {
238 v4l2_err(&vpbe_dev->v4l2_dev,
239 "buffer_prepare:offset is \
240 not aligned to 32 bytes\n");
241 return -EINVAL;
242 }
243 }
244 vb->state = VIDEOBUF_PREPARED;
245 }
246 return 0;
247}
248
249/*
250 * vpbe_buffer_setup()
251 * This function allocates memory for the buffers
252 */
253static int vpbe_buffer_setup(struct videobuf_queue *q,
254 unsigned int *count,
255 unsigned int *size)
256{
257 /* Get the file handle object and layer object */
258 struct vpbe_fh *fh = q->priv_data;
259 struct vpbe_layer *layer = fh->layer;
260 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
261
262 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_buffer_setup\n");
263
264 *size = layer->pix_fmt.sizeimage;
265
266 /* Store number of buffers allocated in numbuffer member */
267 if (*count < VPBE_DEFAULT_NUM_BUFS)
268 *count = layer->numbuffers = VPBE_DEFAULT_NUM_BUFS;
269
270 return 0;
271}
272
273/*
274 * vpbe_buffer_queue()
275 * This function adds the buffer to DMA queue
276 */
277static void vpbe_buffer_queue(struct videobuf_queue *q,
278 struct videobuf_buffer *vb)
279{
280 /* Get the file handle object and layer object */
281 struct vpbe_fh *fh = q->priv_data;
282 struct vpbe_layer *layer = fh->layer;
283 struct vpbe_display *disp = fh->disp_dev;
284 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
285 unsigned long flags;
286
287 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
288 "vpbe_buffer_queue\n");
289
290 /* add the buffer to the DMA queue */
291 spin_lock_irqsave(&disp->dma_queue_lock, flags);
292 list_add_tail(&vb->queue, &layer->dma_queue);
293 spin_unlock_irqrestore(&disp->dma_queue_lock, flags);
294 /* Change state of the buffer */
295 vb->state = VIDEOBUF_QUEUED;
296}
297
298/*
299 * vpbe_buffer_release()
300 * This function is called from the videobuf layer to free memory allocated to
301 * the buffers
302 */
303static void vpbe_buffer_release(struct videobuf_queue *q,
304 struct videobuf_buffer *vb)
305{
306 /* Get the file handle object and layer object */
307 struct vpbe_fh *fh = q->priv_data;
308 struct vpbe_layer *layer = fh->layer;
309 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
310
311 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
312 "vpbe_buffer_release\n");
313
314 if (V4L2_MEMORY_USERPTR != layer->memory)
315 videobuf_dma_contig_free(q, vb);
316
317 vb->state = VIDEOBUF_NEEDS_INIT;
318}
319
320static struct videobuf_queue_ops video_qops = {
321 .buf_setup = vpbe_buffer_setup,
322 .buf_prepare = vpbe_buffer_prepare,
323 .buf_queue = vpbe_buffer_queue,
324 .buf_release = vpbe_buffer_release,
325};
326
327static
328struct vpbe_layer*
329_vpbe_display_get_other_win_layer(struct vpbe_display *disp_dev,
330 struct vpbe_layer *layer)
331{
332 enum vpbe_display_device_id thiswin, otherwin;
333 thiswin = layer->device_id;
334
335 otherwin = (thiswin == VPBE_DISPLAY_DEVICE_0) ?
336 VPBE_DISPLAY_DEVICE_1 : VPBE_DISPLAY_DEVICE_0;
337 return disp_dev->dev[otherwin];
338}
339
340static int vpbe_set_osd_display_params(struct vpbe_display *disp_dev,
341 struct vpbe_layer *layer)
342{
343 struct osd_layer_config *cfg = &layer->layer_info.config;
344 struct osd_state *osd_device = disp_dev->osd_device;
345 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
346 unsigned long addr;
347 int ret;
348
349 addr = videobuf_to_dma_contig(layer->cur_frm);
350 /* Set address in the display registers */
351 osd_device->ops.start_layer(osd_device,
352 layer->layer_info.id,
353 addr,
354 disp_dev->cbcr_ofst);
355
356 ret = osd_device->ops.enable_layer(osd_device,
357 layer->layer_info.id, 0);
358 if (ret < 0) {
359 v4l2_err(&vpbe_dev->v4l2_dev,
360 "Error in enabling osd window layer 0\n");
361 return -1;
362 }
363
364 /* Enable the window */
365 layer->layer_info.enable = 1;
366 if (cfg->pixfmt == PIXFMT_NV12) {
367 struct vpbe_layer *otherlayer =
368 _vpbe_display_get_other_win_layer(disp_dev, layer);
369
370 ret = osd_device->ops.enable_layer(osd_device,
371 otherlayer->layer_info.id, 1);
372 if (ret < 0) {
373 v4l2_err(&vpbe_dev->v4l2_dev,
374 "Error in enabling osd window layer 1\n");
375 return -1;
376 }
377 otherlayer->layer_info.enable = 1;
378 }
379 return 0;
380}
381
382static void
383vpbe_disp_calculate_scale_factor(struct vpbe_display *disp_dev,
384 struct vpbe_layer *layer,
385 int expected_xsize, int expected_ysize)
386{
387 struct display_layer_info *layer_info = &layer->layer_info;
388 struct v4l2_pix_format *pixfmt = &layer->pix_fmt;
389 struct osd_layer_config *cfg = &layer->layer_info.config;
390 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
391 int calculated_xsize;
392 int h_exp = 0;
393 int v_exp = 0;
394 int h_scale;
395 int v_scale;
396
397 v4l2_std_id standard_id = vpbe_dev->current_timings.timings.std_id;
398
399 /*
400 * Application initially set the image format. Current display
401 * size is obtained from the vpbe display controller. expected_xsize
402 * and expected_ysize are set through S_CROP ioctl. Based on this,
403 * driver will calculate the scale factors for vertical and
404 * horizontal direction so that the image is displayed scaled
405 * and expanded. Application uses expansion to display the image
406 * in a square pixel. Otherwise it is displayed using displays
407 * pixel aspect ratio.It is expected that application chooses
408 * the crop coordinates for cropped or scaled display. if crop
409 * size is less than the image size, it is displayed cropped or
410 * it is displayed scaled and/or expanded.
411 *
412 * to begin with, set the crop window same as expected. Later we
413 * will override with scaled window size
414 */
415
416 cfg->xsize = pixfmt->width;
417 cfg->ysize = pixfmt->height;
418 layer_info->h_zoom = ZOOM_X1; /* no horizontal zoom */
419 layer_info->v_zoom = ZOOM_X1; /* no horizontal zoom */
420 layer_info->h_exp = H_EXP_OFF; /* no horizontal zoom */
421 layer_info->v_exp = V_EXP_OFF; /* no horizontal zoom */
422
423 if (pixfmt->width < expected_xsize) {
424 h_scale = vpbe_dev->current_timings.xres / pixfmt->width;
425 if (h_scale < 2)
426 h_scale = 1;
427 else if (h_scale >= 4)
428 h_scale = 4;
429 else
430 h_scale = 2;
431 cfg->xsize *= h_scale;
432 if (cfg->xsize < expected_xsize) {
433 if ((standard_id & V4L2_STD_525_60) ||
434 (standard_id & V4L2_STD_625_50)) {
435 calculated_xsize = (cfg->xsize *
436 VPBE_DISPLAY_H_EXP_RATIO_N) /
437 VPBE_DISPLAY_H_EXP_RATIO_D;
438 if (calculated_xsize <= expected_xsize) {
439 h_exp = 1;
440 cfg->xsize = calculated_xsize;
441 }
442 }
443 }
444 if (h_scale == 2)
445 layer_info->h_zoom = ZOOM_X2;
446 else if (h_scale == 4)
447 layer_info->h_zoom = ZOOM_X4;
448 if (h_exp)
449 layer_info->h_exp = H_EXP_9_OVER_8;
450 } else {
451 /* no scaling, only cropping. Set display area to crop area */
452 cfg->xsize = expected_xsize;
453 }
454
455 if (pixfmt->height < expected_ysize) {
456 v_scale = expected_ysize / pixfmt->height;
457 if (v_scale < 2)
458 v_scale = 1;
459 else if (v_scale >= 4)
460 v_scale = 4;
461 else
462 v_scale = 2;
463 cfg->ysize *= v_scale;
464 if (cfg->ysize < expected_ysize) {
465 if ((standard_id & V4L2_STD_625_50)) {
466 calculated_xsize = (cfg->ysize *
467 VPBE_DISPLAY_V_EXP_RATIO_N) /
468 VPBE_DISPLAY_V_EXP_RATIO_D;
469 if (calculated_xsize <= expected_ysize) {
470 v_exp = 1;
471 cfg->ysize = calculated_xsize;
472 }
473 }
474 }
475 if (v_scale == 2)
476 layer_info->v_zoom = ZOOM_X2;
477 else if (v_scale == 4)
478 layer_info->v_zoom = ZOOM_X4;
479 if (v_exp)
480 layer_info->h_exp = V_EXP_6_OVER_5;
481 } else {
482 /* no scaling, only cropping. Set display area to crop area */
483 cfg->ysize = expected_ysize;
484 }
485 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
486 "crop display xsize = %d, ysize = %d\n",
487 cfg->xsize, cfg->ysize);
488}
489
490static void vpbe_disp_adj_position(struct vpbe_display *disp_dev,
491 struct vpbe_layer *layer,
492 int top, int left)
493{
494 struct osd_layer_config *cfg = &layer->layer_info.config;
495 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
496
497 cfg->xpos = min((unsigned int)left,
498 vpbe_dev->current_timings.xres - cfg->xsize);
499 cfg->ypos = min((unsigned int)top,
500 vpbe_dev->current_timings.yres - cfg->ysize);
501
502 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
503 "new xpos = %d, ypos = %d\n",
504 cfg->xpos, cfg->ypos);
505}
506
507static void vpbe_disp_check_window_params(struct vpbe_display *disp_dev,
508 struct v4l2_rect *c)
509{
510 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
511
512 if ((c->width == 0) ||
513 ((c->width + c->left) > vpbe_dev->current_timings.xres))
514 c->width = vpbe_dev->current_timings.xres - c->left;
515
516 if ((c->height == 0) || ((c->height + c->top) >
517 vpbe_dev->current_timings.yres))
518 c->height = vpbe_dev->current_timings.yres - c->top;
519
520 /* window height must be even for interlaced display */
521 if (vpbe_dev->current_timings.interlaced)
522 c->height &= (~0x01);
523
524}
525
526/**
527 * vpbe_try_format()
528 * If user application provides width and height, and have bytesperline set
529 * to zero, driver calculates bytesperline and sizeimage based on hardware
530 * limits.
531 */
532static int vpbe_try_format(struct vpbe_display *disp_dev,
533 struct v4l2_pix_format *pixfmt, int check)
534{
535 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
536 int min_height = 1;
537 int min_width = 32;
538 int max_height;
539 int max_width;
540 int bpp;
541
542 if ((pixfmt->pixelformat != V4L2_PIX_FMT_UYVY) &&
543 (pixfmt->pixelformat != V4L2_PIX_FMT_NV12))
544 /* choose default as V4L2_PIX_FMT_UYVY */
545 pixfmt->pixelformat = V4L2_PIX_FMT_UYVY;
546
547 /* Check the field format */
548 if ((pixfmt->field != V4L2_FIELD_INTERLACED) &&
549 (pixfmt->field != V4L2_FIELD_NONE)) {
550 if (vpbe_dev->current_timings.interlaced)
551 pixfmt->field = V4L2_FIELD_INTERLACED;
552 else
553 pixfmt->field = V4L2_FIELD_NONE;
554 }
555
556 if (pixfmt->field == V4L2_FIELD_INTERLACED)
557 min_height = 2;
558
559 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
560 bpp = 1;
561 else
562 bpp = 2;
563
564 max_width = vpbe_dev->current_timings.xres;
565 max_height = vpbe_dev->current_timings.yres;
566
567 min_width /= bpp;
568
569 if (!pixfmt->width || (pixfmt->width < min_width) ||
570 (pixfmt->width > max_width)) {
571 pixfmt->width = vpbe_dev->current_timings.xres;
572 }
573
574 if (!pixfmt->height || (pixfmt->height < min_height) ||
575 (pixfmt->height > max_height)) {
576 pixfmt->height = vpbe_dev->current_timings.yres;
577 }
578
579 if (pixfmt->bytesperline < (pixfmt->width * bpp))
580 pixfmt->bytesperline = pixfmt->width * bpp;
581
582 /* Make the bytesperline 32 byte aligned */
583 pixfmt->bytesperline = ((pixfmt->width * bpp + 31) & ~31);
584
585 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
586 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height +
587 (pixfmt->bytesperline * pixfmt->height >> 1);
588 else
589 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
590
591 return 0;
592}
593
594static int vpbe_display_g_priority(struct file *file, void *priv,
595 enum v4l2_priority *p)
596{
597 struct vpbe_fh *fh = file->private_data;
598 struct vpbe_layer *layer = fh->layer;
599
600 *p = v4l2_prio_max(&layer->prio);
601
602 return 0;
603}
604
605static int vpbe_display_s_priority(struct file *file, void *priv,
606 enum v4l2_priority p)
607{
608 struct vpbe_fh *fh = file->private_data;
609 struct vpbe_layer *layer = fh->layer;
610 int ret;
611
612 ret = v4l2_prio_change(&layer->prio, &fh->prio, p);
613
614 return ret;
615}
616
617static int vpbe_display_querycap(struct file *file, void *priv,
618 struct v4l2_capability *cap)
619{
620 struct vpbe_fh *fh = file->private_data;
621 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
622
623 cap->version = VPBE_DISPLAY_VERSION_CODE;
624 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
625 strlcpy(cap->driver, VPBE_DISPLAY_DRIVER, sizeof(cap->driver));
626 strlcpy(cap->bus_info, "platform", sizeof(cap->bus_info));
627 strlcpy(cap->card, vpbe_dev->cfg->module_name, sizeof(cap->card));
628
629 return 0;
630}
631
632static int vpbe_display_s_crop(struct file *file, void *priv,
633 struct v4l2_crop *crop)
634{
635 struct vpbe_fh *fh = file->private_data;
636 struct vpbe_layer *layer = fh->layer;
637 struct vpbe_display *disp_dev = fh->disp_dev;
638 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
639 struct osd_layer_config *cfg = &layer->layer_info.config;
640 struct osd_state *osd_device = disp_dev->osd_device;
641 struct v4l2_rect *rect = &crop->c;
642 int ret;
643
644 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
645 "VIDIOC_S_CROP, layer id = %d\n", layer->device_id);
646
647 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
648 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buf type\n");
649 return -EINVAL;
650 }
651
652 if (rect->top < 0)
653 rect->top = 0;
654 if (rect->left < 0)
655 rect->left = 0;
656
657 vpbe_disp_check_window_params(disp_dev, rect);
658
659 osd_device->ops.get_layer_config(osd_device,
660 layer->layer_info.id, cfg);
661
662 vpbe_disp_calculate_scale_factor(disp_dev, layer,
663 rect->width,
664 rect->height);
665 vpbe_disp_adj_position(disp_dev, layer, rect->top,
666 rect->left);
667 ret = osd_device->ops.set_layer_config(osd_device,
668 layer->layer_info.id, cfg);
669 if (ret < 0) {
670 v4l2_err(&vpbe_dev->v4l2_dev,
671 "Error in set layer config:\n");
672 return -EINVAL;
673 }
674
675 /* apply zooming and h or v expansion */
676 osd_device->ops.set_zoom(osd_device,
677 layer->layer_info.id,
678 layer->layer_info.h_zoom,
679 layer->layer_info.v_zoom);
680 ret = osd_device->ops.set_vid_expansion(osd_device,
681 layer->layer_info.h_exp,
682 layer->layer_info.v_exp);
683 if (ret < 0) {
684 v4l2_err(&vpbe_dev->v4l2_dev,
685 "Error in set vid expansion:\n");
686 return -EINVAL;
687 }
688
689 if ((layer->layer_info.h_zoom != ZOOM_X1) ||
690 (layer->layer_info.v_zoom != ZOOM_X1) ||
691 (layer->layer_info.h_exp != H_EXP_OFF) ||
692 (layer->layer_info.v_exp != V_EXP_OFF))
693 /* Enable expansion filter */
694 osd_device->ops.set_interpolation_filter(osd_device, 1);
695 else
696 osd_device->ops.set_interpolation_filter(osd_device, 0);
697
698 return 0;
699}
700
701static int vpbe_display_g_crop(struct file *file, void *priv,
702 struct v4l2_crop *crop)
703{
704 struct vpbe_fh *fh = file->private_data;
705 struct vpbe_layer *layer = fh->layer;
706 struct osd_layer_config *cfg = &layer->layer_info.config;
707 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
708 struct osd_state *osd_device = fh->disp_dev->osd_device;
709 struct v4l2_rect *rect = &crop->c;
710 int ret;
711
712 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
713 "VIDIOC_G_CROP, layer id = %d\n",
714 layer->device_id);
715
716 if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
717 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buf type\n");
718 ret = -EINVAL;
719 }
720 osd_device->ops.get_layer_config(osd_device,
721 layer->layer_info.id, cfg);
722 rect->top = cfg->ypos;
723 rect->left = cfg->xpos;
724 rect->width = cfg->xsize;
725 rect->height = cfg->ysize;
726
727 return 0;
728}
729
730static int vpbe_display_cropcap(struct file *file, void *priv,
731 struct v4l2_cropcap *cropcap)
732{
733 struct vpbe_fh *fh = file->private_data;
734 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
735
736 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_CROPCAP ioctl\n");
737
738 cropcap->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
739 cropcap->bounds.left = 0;
740 cropcap->bounds.top = 0;
741 cropcap->bounds.width = vpbe_dev->current_timings.xres;
742 cropcap->bounds.height = vpbe_dev->current_timings.yres;
743 cropcap->pixelaspect = vpbe_dev->current_timings.aspect;
744 cropcap->defrect = cropcap->bounds;
745 return 0;
746}
747
748static int vpbe_display_g_fmt(struct file *file, void *priv,
749 struct v4l2_format *fmt)
750{
751 struct vpbe_fh *fh = file->private_data;
752 struct vpbe_layer *layer = fh->layer;
753 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
754
755 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
756 "VIDIOC_G_FMT, layer id = %d\n",
757 layer->device_id);
758
759 /* If buffer type is video output */
760 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
761 v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
762 return -EINVAL;
763 }
764 /* Fill in the information about format */
765 fmt->fmt.pix = layer->pix_fmt;
766
767 return 0;
768}
769
770static int vpbe_display_enum_fmt(struct file *file, void *priv,
771 struct v4l2_fmtdesc *fmt)
772{
773 struct vpbe_fh *fh = file->private_data;
774 struct vpbe_layer *layer = fh->layer;
775 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
776 unsigned int index = 0;
777
778 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
779 "VIDIOC_ENUM_FMT, layer id = %d\n",
780 layer->device_id);
781 if (fmt->index > 1) {
782 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid format index\n");
783 return -EINVAL;
784 }
785
786 /* Fill in the information about format */
787 index = fmt->index;
788 memset(fmt, 0, sizeof(*fmt));
789 fmt->index = index;
790 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
791 if (index == 0) {
792 strcpy(fmt->description, "YUV 4:2:2 - UYVY");
793 fmt->pixelformat = V4L2_PIX_FMT_UYVY;
794 } else {
795 strcpy(fmt->description, "Y/CbCr 4:2:0");
796 fmt->pixelformat = V4L2_PIX_FMT_NV12;
797 }
798
799 return 0;
800}
801
802static int vpbe_display_s_fmt(struct file *file, void *priv,
803 struct v4l2_format *fmt)
804{
805 struct vpbe_fh *fh = file->private_data;
806 struct vpbe_layer *layer = fh->layer;
807 struct vpbe_display *disp_dev = fh->disp_dev;
808 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
809 struct osd_layer_config *cfg = &layer->layer_info.config;
810 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
811 struct osd_state *osd_device = disp_dev->osd_device;
812 int ret;
813
814 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
815 "VIDIOC_S_FMT, layer id = %d\n",
816 layer->device_id);
817
818 /* If streaming is started, return error */
819 if (layer->started) {
820 v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
821 return -EBUSY;
822 }
823 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
824 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "invalid type\n");
825 return -EINVAL;
826 }
827 /* Check for valid pixel format */
828 ret = vpbe_try_format(disp_dev, pixfmt, 1);
829 if (ret)
830 return ret;
831
832 /* YUV420 is requested, check availability of the
833 other video window */
834
835 layer->pix_fmt = *pixfmt;
836
837 /* Get osd layer config */
838 osd_device->ops.get_layer_config(osd_device,
839 layer->layer_info.id, cfg);
840 /* Store the pixel format in the layer object */
841 cfg->xsize = pixfmt->width;
842 cfg->ysize = pixfmt->height;
843 cfg->line_length = pixfmt->bytesperline;
844 cfg->ypos = 0;
845 cfg->xpos = 0;
846 cfg->interlaced = vpbe_dev->current_timings.interlaced;
847
848 if (V4L2_PIX_FMT_UYVY == pixfmt->pixelformat)
849 cfg->pixfmt = PIXFMT_YCbCrI;
850
851 /* Change of the default pixel format for both video windows */
852 if (V4L2_PIX_FMT_NV12 == pixfmt->pixelformat) {
853 struct vpbe_layer *otherlayer;
854 cfg->pixfmt = PIXFMT_NV12;
855 otherlayer = _vpbe_display_get_other_win_layer(disp_dev,
856 layer);
857 otherlayer->layer_info.config.pixfmt = PIXFMT_NV12;
858 }
859
860 /* Set the layer config in the osd window */
861 ret = osd_device->ops.set_layer_config(osd_device,
862 layer->layer_info.id, cfg);
863 if (ret < 0) {
864 v4l2_err(&vpbe_dev->v4l2_dev,
865 "Error in S_FMT params:\n");
866 return -EINVAL;
867 }
868
869 /* Readback and fill the local copy of current pix format */
870 osd_device->ops.get_layer_config(osd_device,
871 layer->layer_info.id, cfg);
872
873 return 0;
874}
875
876static int vpbe_display_try_fmt(struct file *file, void *priv,
877 struct v4l2_format *fmt)
878{
879 struct vpbe_fh *fh = file->private_data;
880 struct vpbe_display *disp_dev = fh->disp_dev;
881 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
882 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
883
884 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_TRY_FMT\n");
885
886 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != fmt->type) {
887 v4l2_err(&vpbe_dev->v4l2_dev, "invalid type\n");
888 return -EINVAL;
889 }
890
891 /* Check for valid field format */
892 return vpbe_try_format(disp_dev, pixfmt, 0);
893
894}
895
896/**
897 * vpbe_display_s_std - Set the given standard in the encoder
898 *
899 * Sets the standard if supported by the current encoder. Return the status.
900 * 0 - success & -EINVAL on error
901 */
902static int vpbe_display_s_std(struct file *file, void *priv,
903 v4l2_std_id *std_id)
904{
905 struct vpbe_fh *fh = priv;
906 struct vpbe_layer *layer = fh->layer;
907 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
908 int ret;
909
910 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_STD\n");
911
912 /* If streaming is started, return error */
913 if (layer->started) {
914 v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
915 return -EBUSY;
916 }
917 if (NULL != vpbe_dev->ops.s_std) {
918 ret = vpbe_dev->ops.s_std(vpbe_dev, std_id);
919 if (ret) {
920 v4l2_err(&vpbe_dev->v4l2_dev,
921 "Failed to set standard for sub devices\n");
922 return -EINVAL;
923 }
924 } else {
925 return -EINVAL;
926 }
927
928 return 0;
929}
930
931/**
932 * vpbe_display_g_std - Get the standard in the current encoder
933 *
934 * Get the standard in the current encoder. Return the status. 0 - success
935 * -EINVAL on error
936 */
937static int vpbe_display_g_std(struct file *file, void *priv,
938 v4l2_std_id *std_id)
939{
940 struct vpbe_fh *fh = priv;
941 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
942
943 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_STD\n");
944
945 /* Get the standard from the current encoder */
946 if (vpbe_dev->current_timings.timings_type & VPBE_ENC_STD) {
947 *std_id = vpbe_dev->current_timings.timings.std_id;
948 return 0;
949 }
950
951 return -EINVAL;
952}
953
954/**
955 * vpbe_display_enum_output - enumerate outputs
956 *
957 * Enumerates the outputs available at the vpbe display
958 * returns the status, -EINVAL if end of output list
959 */
960static int vpbe_display_enum_output(struct file *file, void *priv,
961 struct v4l2_output *output)
962{
963 struct vpbe_fh *fh = priv;
964 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
965 int ret;
966
967 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_OUTPUT\n");
968
969 /* Enumerate outputs */
970
971 if (NULL == vpbe_dev->ops.enum_outputs)
972 return -EINVAL;
973
974 ret = vpbe_dev->ops.enum_outputs(vpbe_dev, output);
975 if (ret) {
976 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
977 "Failed to enumerate outputs\n");
978 return -EINVAL;
979 }
980
981 return 0;
982}
983
984/**
985 * vpbe_display_s_output - Set output to
986 * the output specified by the index
987 */
988static int vpbe_display_s_output(struct file *file, void *priv,
989 unsigned int i)
990{
991 struct vpbe_fh *fh = priv;
992 struct vpbe_layer *layer = fh->layer;
993 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
994 int ret;
995
996 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_OUTPUT\n");
997 /* If streaming is started, return error */
998 if (layer->started) {
999 v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
1000 return -EBUSY;
1001 }
1002 if (NULL == vpbe_dev->ops.set_output)
1003 return -EINVAL;
1004
1005 ret = vpbe_dev->ops.set_output(vpbe_dev, i);
1006 if (ret) {
1007 v4l2_err(&vpbe_dev->v4l2_dev,
1008 "Failed to set output for sub devices\n");
1009 return -EINVAL;
1010 }
1011
1012 return 0;
1013}
1014
1015/**
1016 * vpbe_display_g_output - Get output from subdevice
1017 * for a given by the index
1018 */
1019static int vpbe_display_g_output(struct file *file, void *priv,
1020 unsigned int *i)
1021{
1022 struct vpbe_fh *fh = priv;
1023 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1024
1025 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_OUTPUT\n");
1026 /* Get the standard from the current encoder */
1027 *i = vpbe_dev->current_out_index;
1028
1029 return 0;
1030}
1031
1032/**
1033 * vpbe_display_enum_dv_presets - Enumerate the dv presets
1034 *
1035 * enum the preset in the current encoder. Return the status. 0 - success
1036 * -EINVAL on error
1037 */
1038static int
1039vpbe_display_enum_dv_presets(struct file *file, void *priv,
1040 struct v4l2_dv_enum_preset *preset)
1041{
1042 struct vpbe_fh *fh = priv;
1043 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1044 int ret;
1045
1046 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_ENUM_DV_PRESETS\n");
1047
1048 /* Enumerate outputs */
1049 if (NULL == vpbe_dev->ops.enum_dv_presets)
1050 return -EINVAL;
1051
1052 ret = vpbe_dev->ops.enum_dv_presets(vpbe_dev, preset);
1053 if (ret) {
1054 v4l2_err(&vpbe_dev->v4l2_dev,
1055 "Failed to enumerate dv presets info\n");
1056 return -EINVAL;
1057 }
1058
1059 return 0;
1060}
1061
1062/**
1063 * vpbe_display_s_dv_preset - Set the dv presets
1064 *
1065 * Set the preset in the current encoder. Return the status. 0 - success
1066 * -EINVAL on error
1067 */
1068static int
1069vpbe_display_s_dv_preset(struct file *file, void *priv,
1070 struct v4l2_dv_preset *preset)
1071{
1072 struct vpbe_fh *fh = priv;
1073 struct vpbe_layer *layer = fh->layer;
1074 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1075 int ret;
1076
1077 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_S_DV_PRESETS\n");
1078
1079
1080 /* If streaming is started, return error */
1081 if (layer->started) {
1082 v4l2_err(&vpbe_dev->v4l2_dev, "Streaming is started\n");
1083 return -EBUSY;
1084 }
1085
1086 /* Set the given standard in the encoder */
1087 if (NULL != vpbe_dev->ops.s_dv_preset)
1088 return -EINVAL;
1089
1090 ret = vpbe_dev->ops.s_dv_preset(vpbe_dev, preset);
1091 if (ret) {
1092 v4l2_err(&vpbe_dev->v4l2_dev,
1093 "Failed to set the dv presets info\n");
1094 return -EINVAL;
1095 }
1096 /* set the current norm to zero to be consistent. If STD is used
1097 * v4l2 layer will set the norm properly on successful s_std call
1098 */
1099 layer->video_dev.current_norm = 0;
1100
1101 return 0;
1102}
1103
1104/**
1105 * vpbe_display_g_dv_preset - Set the dv presets
1106 *
1107 * Get the preset in the current encoder. Return the status. 0 - success
1108 * -EINVAL on error
1109 */
1110static int
1111vpbe_display_g_dv_preset(struct file *file, void *priv,
1112 struct v4l2_dv_preset *dv_preset)
1113{
1114 struct vpbe_fh *fh = priv;
1115 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1116
1117 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_G_DV_PRESETS\n");
1118
1119 /* Get the given standard in the encoder */
1120
1121 if (vpbe_dev->current_timings.timings_type &
1122 VPBE_ENC_DV_PRESET) {
1123 dv_preset->preset =
1124 vpbe_dev->current_timings.timings.dv_preset;
1125 } else {
1126 return -EINVAL;
1127 }
1128
1129 return 0;
1130}
1131
1132static int vpbe_display_streamoff(struct file *file, void *priv,
1133 enum v4l2_buf_type buf_type)
1134{
1135 struct vpbe_fh *fh = file->private_data;
1136 struct vpbe_layer *layer = fh->layer;
1137 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1138 struct osd_state *osd_device = fh->disp_dev->osd_device;
1139 int ret;
1140
1141 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1142 "VIDIOC_STREAMOFF,layer id = %d\n",
1143 layer->device_id);
1144
1145 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) {
1146 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1147 return -EINVAL;
1148 }
1149
1150 /* If io is allowed for this file handle, return error */
1151 if (!fh->io_allowed) {
1152 v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
1153 return -EACCES;
1154 }
1155
1156 /* If streaming is not started, return error */
1157 if (!layer->started) {
1158 v4l2_err(&vpbe_dev->v4l2_dev, "streaming not started in layer"
1159 " id = %d\n", layer->device_id);
1160 return -EINVAL;
1161 }
1162
1163 osd_device->ops.disable_layer(osd_device,
1164 layer->layer_info.id);
1165 layer->started = 0;
1166 ret = videobuf_streamoff(&layer->buffer_queue);
1167
1168 return ret;
1169}
1170
1171static int vpbe_display_streamon(struct file *file, void *priv,
1172 enum v4l2_buf_type buf_type)
1173{
1174 struct vpbe_fh *fh = file->private_data;
1175 struct vpbe_layer *layer = fh->layer;
1176 struct vpbe_display *disp_dev = fh->disp_dev;
1177 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1178 struct osd_state *osd_device = disp_dev->osd_device;
1179 int ret;
1180
1181 osd_device->ops.disable_layer(osd_device,
1182 layer->layer_info.id);
1183
1184 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "VIDIOC_STREAMON, layerid=%d\n",
1185 layer->device_id);
1186
1187 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf_type) {
1188 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1189 return -EINVAL;
1190 }
1191
1192 /* If file handle is not allowed IO, return error */
1193 if (!fh->io_allowed) {
1194 v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
1195 return -EACCES;
1196 }
1197 /* If Streaming is already started, return error */
1198 if (layer->started) {
1199 v4l2_err(&vpbe_dev->v4l2_dev, "layer is already streaming\n");
1200 return -EBUSY;
1201 }
1202
1203 /*
1204 * Call videobuf_streamon to start streaming
1205 * in videobuf
1206 */
1207 ret = videobuf_streamon(&layer->buffer_queue);
1208 if (ret) {
1209 v4l2_err(&vpbe_dev->v4l2_dev,
1210 "error in videobuf_streamon\n");
1211 return ret;
1212 }
1213 /* If buffer queue is empty, return error */
1214 if (list_empty(&layer->dma_queue)) {
1215 v4l2_err(&vpbe_dev->v4l2_dev, "buffer queue is empty\n");
1216 goto streamoff;
1217 }
1218 /* Get the next frame from the buffer queue */
1219 layer->next_frm = layer->cur_frm = list_entry(layer->dma_queue.next,
1220 struct videobuf_buffer, queue);
1221 /* Remove buffer from the buffer queue */
1222 list_del(&layer->cur_frm->queue);
1223 /* Mark state of the current frame to active */
1224 layer->cur_frm->state = VIDEOBUF_ACTIVE;
1225 /* Initialize field_id and started member */
1226 layer->field_id = 0;
1227
1228 /* Set parameters in OSD and VENC */
1229 ret = vpbe_set_osd_display_params(disp_dev, layer);
1230 if (ret < 0)
1231 goto streamoff;
1232
1233 /*
1234 * if request format is yuv420 semiplanar, need to
1235 * enable both video windows
1236 */
1237 layer->started = 1;
1238
1239 layer->layer_first_int = 1;
1240
1241 return ret;
1242streamoff:
1243 ret = videobuf_streamoff(&layer->buffer_queue);
1244 return ret;
1245}
1246
1247static int vpbe_display_dqbuf(struct file *file, void *priv,
1248 struct v4l2_buffer *buf)
1249{
1250 struct vpbe_fh *fh = file->private_data;
1251 struct vpbe_layer *layer = fh->layer;
1252 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1253 int ret;
1254
1255 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1256 "VIDIOC_DQBUF, layer id = %d\n",
1257 layer->device_id);
1258
1259 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) {
1260 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1261 return -EINVAL;
1262 }
1263 /* If this file handle is not allowed to do IO, return error */
1264 if (!fh->io_allowed) {
1265 v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
1266 return -EACCES;
1267 }
1268 if (file->f_flags & O_NONBLOCK)
1269 /* Call videobuf_dqbuf for non blocking mode */
1270 ret = videobuf_dqbuf(&layer->buffer_queue, buf, 1);
1271 else
1272 /* Call videobuf_dqbuf for blocking mode */
1273 ret = videobuf_dqbuf(&layer->buffer_queue, buf, 0);
1274
1275 return ret;
1276}
1277
1278static int vpbe_display_qbuf(struct file *file, void *priv,
1279 struct v4l2_buffer *p)
1280{
1281 struct vpbe_fh *fh = file->private_data;
1282 struct vpbe_layer *layer = fh->layer;
1283 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1284
1285 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1286 "VIDIOC_QBUF, layer id = %d\n",
1287 layer->device_id);
1288
1289 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != p->type) {
1290 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1291 return -EINVAL;
1292 }
1293
1294 /* If this file handle is not allowed to do IO, return error */
1295 if (!fh->io_allowed) {
1296 v4l2_err(&vpbe_dev->v4l2_dev, "No io_allowed\n");
1297 return -EACCES;
1298 }
1299
1300 return videobuf_qbuf(&layer->buffer_queue, p);
1301}
1302
1303static int vpbe_display_querybuf(struct file *file, void *priv,
1304 struct v4l2_buffer *buf)
1305{
1306 struct vpbe_fh *fh = file->private_data;
1307 struct vpbe_layer *layer = fh->layer;
1308 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1309 int ret;
1310
1311 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1312 "VIDIOC_QUERYBUF, layer id = %d\n",
1313 layer->device_id);
1314
1315 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != buf->type) {
1316 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1317 return -EINVAL;
1318 }
1319
1320 /* Call videobuf_querybuf to get information */
1321 ret = videobuf_querybuf(&layer->buffer_queue, buf);
1322
1323 return ret;
1324}
1325
1326static int vpbe_display_reqbufs(struct file *file, void *priv,
1327 struct v4l2_requestbuffers *req_buf)
1328{
1329 struct vpbe_fh *fh = file->private_data;
1330 struct vpbe_layer *layer = fh->layer;
1331 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1332 int ret;
1333
1334 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_reqbufs\n");
1335
1336 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != req_buf->type) {
1337 v4l2_err(&vpbe_dev->v4l2_dev, "Invalid buffer type\n");
1338 return -EINVAL;
1339 }
1340
1341 /* If io users of the layer is not zero, return error */
1342 if (0 != layer->io_usrs) {
1343 v4l2_err(&vpbe_dev->v4l2_dev, "not IO user\n");
1344 return -EBUSY;
1345 }
1346 /* Initialize videobuf queue as per the buffer type */
1347 videobuf_queue_dma_contig_init(&layer->buffer_queue,
1348 &video_qops,
1349 vpbe_dev->pdev,
1350 &layer->irqlock,
1351 V4L2_BUF_TYPE_VIDEO_OUTPUT,
1352 layer->pix_fmt.field,
1353 sizeof(struct videobuf_buffer),
1354 fh, NULL);
1355
1356 /* Set io allowed member of file handle to TRUE */
1357 fh->io_allowed = 1;
1358 /* Increment io usrs member of layer object to 1 */
1359 layer->io_usrs = 1;
1360 /* Store type of memory requested in layer object */
1361 layer->memory = req_buf->memory;
1362 /* Initialize buffer queue */
1363 INIT_LIST_HEAD(&layer->dma_queue);
1364 /* Allocate buffers */
1365 ret = videobuf_reqbufs(&layer->buffer_queue, req_buf);
1366
1367 return ret;
1368}
1369
1370/*
1371 * vpbe_display_mmap()
1372 * It is used to map kernel space buffers into user spaces
1373 */
1374static int vpbe_display_mmap(struct file *filep, struct vm_area_struct *vma)
1375{
1376 /* Get the layer object and file handle object */
1377 struct vpbe_fh *fh = filep->private_data;
1378 struct vpbe_layer *layer = fh->layer;
1379 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1380
1381 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_mmap\n");
1382
1383 return videobuf_mmap_mapper(&layer->buffer_queue, vma);
1384}
1385
1386/* vpbe_display_poll(): It is used for select/poll system call
1387 */
1388static unsigned int vpbe_display_poll(struct file *filep, poll_table *wait)
1389{
1390 struct vpbe_fh *fh = filep->private_data;
1391 struct vpbe_layer *layer = fh->layer;
1392 struct vpbe_device *vpbe_dev = fh->disp_dev->vpbe_dev;
1393 unsigned int err = 0;
1394
1395 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_poll\n");
1396 if (layer->started)
1397 err = videobuf_poll_stream(filep, &layer->buffer_queue, wait);
1398 return err;
1399}
1400
1401/*
1402 * vpbe_display_open()
1403 * It creates object of file handle structure and stores it in private_data
1404 * member of filepointer
1405 */
1406static int vpbe_display_open(struct file *file)
1407{
1408 struct vpbe_fh *fh = NULL;
1409 struct vpbe_layer *layer = video_drvdata(file);
1410 struct vpbe_display *disp_dev = layer->disp_dev;
1411 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1412 struct osd_state *osd_device = disp_dev->osd_device;
1413 int err;
1414
1415 /* Allocate memory for the file handle object */
1416 fh = kmalloc(sizeof(struct vpbe_fh), GFP_KERNEL);
1417 if (fh == NULL) {
1418 v4l2_err(&vpbe_dev->v4l2_dev,
1419 "unable to allocate memory for file handle object\n");
1420 return -ENOMEM;
1421 }
1422 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1423 "vpbe display open plane = %d\n",
1424 layer->device_id);
1425
1426 /* store pointer to fh in private_data member of filep */
1427 file->private_data = fh;
1428 fh->layer = layer;
1429 fh->disp_dev = disp_dev;
1430
1431 if (!layer->usrs) {
1432
1433 /* First claim the layer for this device */
1434 err = osd_device->ops.request_layer(osd_device,
1435 layer->layer_info.id);
1436 if (err < 0) {
1437 /* Couldn't get layer */
1438 v4l2_err(&vpbe_dev->v4l2_dev,
1439 "Display Manager failed to allocate layer\n");
1440 kfree(fh);
1441 return -EINVAL;
1442 }
1443 }
1444 /* Increment layer usrs counter */
1445 layer->usrs++;
1446 /* Set io_allowed member to false */
1447 fh->io_allowed = 0;
1448 /* Initialize priority of this instance to default priority */
1449 fh->prio = V4L2_PRIORITY_UNSET;
1450 v4l2_prio_open(&layer->prio, &fh->prio);
1451 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev,
1452 "vpbe display device opened successfully\n");
1453 return 0;
1454}
1455
1456/*
1457 * vpbe_display_release()
1458 * This function deletes buffer queue, frees the buffers and the davinci
1459 * display file * handle
1460 */
1461static int vpbe_display_release(struct file *file)
1462{
1463 /* Get the layer object and file handle object */
1464 struct vpbe_fh *fh = file->private_data;
1465 struct vpbe_layer *layer = fh->layer;
1466 struct osd_layer_config *cfg = &layer->layer_info.config;
1467 struct vpbe_display *disp_dev = fh->disp_dev;
1468 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1469 struct osd_state *osd_device = disp_dev->osd_device;
1470
1471 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_release\n");
1472
1473 /* if this instance is doing IO */
1474 if (fh->io_allowed) {
1475 /* Reset io_usrs member of layer object */
1476 layer->io_usrs = 0;
1477
1478 osd_device->ops.disable_layer(osd_device,
1479 layer->layer_info.id);
1480 layer->started = 0;
1481 /* Free buffers allocated */
1482 videobuf_queue_cancel(&layer->buffer_queue);
1483 videobuf_mmap_free(&layer->buffer_queue);
1484 }
1485
1486 /* Decrement layer usrs counter */
1487 layer->usrs--;
1488 /* If this file handle has initialize encoder device, reset it */
1489 if (!layer->usrs) {
1490 if (cfg->pixfmt == PIXFMT_NV12) {
1491 struct vpbe_layer *otherlayer;
1492 otherlayer =
1493 _vpbe_display_get_other_win_layer(disp_dev, layer);
1494 osd_device->ops.disable_layer(osd_device,
1495 otherlayer->layer_info.id);
1496 osd_device->ops.release_layer(osd_device,
1497 otherlayer->layer_info.id);
1498 }
1499 osd_device->ops.disable_layer(osd_device,
1500 layer->layer_info.id);
1501 osd_device->ops.release_layer(osd_device,
1502 layer->layer_info.id);
1503 }
1504 /* Close the priority */
1505 v4l2_prio_close(&layer->prio, fh->prio);
1506 file->private_data = NULL;
1507
1508 /* Free memory allocated to file handle object */
1509 kfree(fh);
1510
1511 disp_dev->cbcr_ofst = 0;
1512
1513 return 0;
1514}
1515
1516#ifdef CONFIG_VIDEO_ADV_DEBUG
1517static int vpbe_display_g_register(struct file *file, void *priv,
1518 struct v4l2_dbg_register *reg)
1519{
1520 struct v4l2_dbg_match *match = &reg->match;
1521
1522 if (match->type >= 2) {
1523 v4l2_subdev_call(vpbe_dev->venc,
1524 core,
1525 g_register,
1526 reg);
1527 }
1528
1529 return 0;
1530}
1531
1532static int vpbe_display_s_register(struct file *file, void *priv,
1533 struct v4l2_dbg_register *reg)
1534{
1535 return 0;
1536}
1537#endif
1538
1539/* vpbe capture ioctl operations */
1540static const struct v4l2_ioctl_ops vpbe_ioctl_ops = {
1541 .vidioc_querycap = vpbe_display_querycap,
1542 .vidioc_g_fmt_vid_out = vpbe_display_g_fmt,
1543 .vidioc_enum_fmt_vid_out = vpbe_display_enum_fmt,
1544 .vidioc_s_fmt_vid_out = vpbe_display_s_fmt,
1545 .vidioc_try_fmt_vid_out = vpbe_display_try_fmt,
1546 .vidioc_reqbufs = vpbe_display_reqbufs,
1547 .vidioc_querybuf = vpbe_display_querybuf,
1548 .vidioc_qbuf = vpbe_display_qbuf,
1549 .vidioc_dqbuf = vpbe_display_dqbuf,
1550 .vidioc_streamon = vpbe_display_streamon,
1551 .vidioc_streamoff = vpbe_display_streamoff,
1552 .vidioc_cropcap = vpbe_display_cropcap,
1553 .vidioc_g_crop = vpbe_display_g_crop,
1554 .vidioc_s_crop = vpbe_display_s_crop,
1555 .vidioc_g_priority = vpbe_display_g_priority,
1556 .vidioc_s_priority = vpbe_display_s_priority,
1557 .vidioc_s_std = vpbe_display_s_std,
1558 .vidioc_g_std = vpbe_display_g_std,
1559 .vidioc_enum_output = vpbe_display_enum_output,
1560 .vidioc_s_output = vpbe_display_s_output,
1561 .vidioc_g_output = vpbe_display_g_output,
1562 .vidioc_s_dv_preset = vpbe_display_s_dv_preset,
1563 .vidioc_g_dv_preset = vpbe_display_g_dv_preset,
1564 .vidioc_enum_dv_presets = vpbe_display_enum_dv_presets,
1565#ifdef CONFIG_VIDEO_ADV_DEBUG
1566 .vidioc_g_register = vpbe_display_g_register,
1567 .vidioc_s_register = vpbe_display_s_register,
1568#endif
1569};
1570
1571static struct v4l2_file_operations vpbe_fops = {
1572 .owner = THIS_MODULE,
1573 .open = vpbe_display_open,
1574 .release = vpbe_display_release,
1575 .unlocked_ioctl = video_ioctl2,
1576 .mmap = vpbe_display_mmap,
1577 .poll = vpbe_display_poll
1578};
1579
1580static int vpbe_device_get(struct device *dev, void *data)
1581{
1582 struct platform_device *pdev = to_platform_device(dev);
1583 struct vpbe_display *vpbe_disp = data;
1584
1585 if (strcmp("vpbe_controller", pdev->name) == 0)
1586 vpbe_disp->vpbe_dev = platform_get_drvdata(pdev);
1587
1588 if (strcmp("vpbe-osd", pdev->name) == 0)
1589 vpbe_disp->osd_device = platform_get_drvdata(pdev);
1590
1591 return 0;
1592}
1593
1594static __devinit int init_vpbe_layer(int i, struct vpbe_display *disp_dev,
1595 struct platform_device *pdev)
1596{
1597 struct vpbe_layer *vpbe_display_layer = NULL;
1598 struct video_device *vbd = NULL;
1599
1600 /* Allocate memory for four plane display objects */
1601
1602 disp_dev->dev[i] =
1603 kzalloc(sizeof(struct vpbe_layer), GFP_KERNEL);
1604
1605 /* If memory allocation fails, return error */
1606 if (!disp_dev->dev[i]) {
1607 printk(KERN_ERR "ran out of memory\n");
1608 return -ENOMEM;
1609 }
1610 spin_lock_init(&disp_dev->dev[i]->irqlock);
1611 mutex_init(&disp_dev->dev[i]->opslock);
1612
1613 /* Get the pointer to the layer object */
1614 vpbe_display_layer = disp_dev->dev[i];
1615 vbd = &vpbe_display_layer->video_dev;
1616 /* Initialize field of video device */
1617 vbd->release = video_device_release_empty;
1618 vbd->fops = &vpbe_fops;
1619 vbd->ioctl_ops = &vpbe_ioctl_ops;
1620 vbd->minor = -1;
1621 vbd->v4l2_dev = &disp_dev->vpbe_dev->v4l2_dev;
1622 vbd->lock = &vpbe_display_layer->opslock;
1623
1624 if (disp_dev->vpbe_dev->current_timings.timings_type &
1625 VPBE_ENC_STD) {
1626 vbd->tvnorms = (V4L2_STD_525_60 | V4L2_STD_625_50);
1627 vbd->current_norm =
1628 disp_dev->vpbe_dev->
1629 current_timings.timings.std_id;
1630 } else
1631 vbd->current_norm = 0;
1632
1633 snprintf(vbd->name, sizeof(vbd->name),
1634 "DaVinci_VPBE Display_DRIVER_V%d.%d.%d",
1635 (VPBE_DISPLAY_VERSION_CODE >> 16) & 0xff,
1636 (VPBE_DISPLAY_VERSION_CODE >> 8) & 0xff,
1637 (VPBE_DISPLAY_VERSION_CODE) & 0xff);
1638
1639 vpbe_display_layer->device_id = i;
1640
1641 vpbe_display_layer->layer_info.id =
1642 ((i == VPBE_DISPLAY_DEVICE_0) ? WIN_VID0 : WIN_VID1);
1643
1644 /* Initialize prio member of layer object */
1645 v4l2_prio_init(&vpbe_display_layer->prio);
1646
1647 return 0;
1648}
1649
1650static __devinit int register_device(struct vpbe_layer *vpbe_display_layer,
1651 struct vpbe_display *disp_dev,
1652 struct platform_device *pdev) {
1653 int err;
1654
1655 v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
1656 "Trying to register VPBE display device.\n");
1657 v4l2_info(&disp_dev->vpbe_dev->v4l2_dev,
1658 "layer=%x,layer->video_dev=%x\n",
1659 (int)vpbe_display_layer,
1660 (int)&vpbe_display_layer->video_dev);
1661
1662 err = video_register_device(&vpbe_display_layer->video_dev,
1663 VFL_TYPE_GRABBER,
1664 -1);
1665 if (err)
1666 return -ENODEV;
1667
1668 vpbe_display_layer->disp_dev = disp_dev;
1669 /* set the driver data in platform device */
1670 platform_set_drvdata(pdev, disp_dev);
1671 video_set_drvdata(&vpbe_display_layer->video_dev,
1672 vpbe_display_layer);
1673
1674 return 0;
1675}
1676
1677
1678
1679/*
1680 * vpbe_display_probe()
1681 * This function creates device entries by register itself to the V4L2 driver
1682 * and initializes fields of each layer objects
1683 */
1684static __devinit int vpbe_display_probe(struct platform_device *pdev)
1685{
1686 struct vpbe_layer *vpbe_display_layer;
1687 struct vpbe_display *disp_dev;
1688 struct resource *res = NULL;
1689 int k;
1690 int i;
1691 int err;
1692 int irq;
1693
1694 printk(KERN_DEBUG "vpbe_display_probe\n");
1695 /* Allocate memory for vpbe_display */
1696 disp_dev = kzalloc(sizeof(struct vpbe_display), GFP_KERNEL);
1697 if (!disp_dev) {
1698 printk(KERN_ERR "ran out of memory\n");
1699 return -ENOMEM;
1700 }
1701
1702 spin_lock_init(&disp_dev->dma_queue_lock);
1703 /*
1704 * Scan all the platform devices to find the vpbe
1705 * controller device and get the vpbe_dev object
1706 */
1707 err = bus_for_each_dev(&platform_bus_type, NULL, disp_dev,
1708 vpbe_device_get);
1709 if (err < 0)
1710 return err;
1711 /* Initialize the vpbe display controller */
1712 if (NULL != disp_dev->vpbe_dev->ops.initialize) {
1713 err = disp_dev->vpbe_dev->ops.initialize(&pdev->dev,
1714 disp_dev->vpbe_dev);
1715 if (err) {
1716 v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
1717 "Error initing vpbe\n");
1718 err = -ENOMEM;
1719 goto probe_out;
1720 }
1721 }
1722
1723 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1724 if (init_vpbe_layer(i, disp_dev, pdev)) {
1725 err = -ENODEV;
1726 goto probe_out;
1727 }
1728 }
1729
1730 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1731 if (!res) {
1732 v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
1733 "Unable to get VENC interrupt resource\n");
1734 err = -ENODEV;
1735 goto probe_out;
1736 }
1737
1738 irq = res->start;
1739 if (request_irq(irq, venc_isr, IRQF_DISABLED, VPBE_DISPLAY_DRIVER,
1740 disp_dev)) {
1741 v4l2_err(&disp_dev->vpbe_dev->v4l2_dev,
1742 "Unable to request interrupt\n");
1743 err = -ENODEV;
1744 goto probe_out;
1745 }
1746
1747 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1748 if (register_device(disp_dev->dev[i], disp_dev, pdev)) {
1749 err = -ENODEV;
1750 goto probe_out;
1751 }
1752 }
1753
1754 printk(KERN_DEBUG "Successfully completed the probing of vpbe v4l2 device\n");
1755 return 0;
1756
1757probe_out:
1758 free_irq(res->start, disp_dev);
1759 for (k = 0; k < VPBE_DISPLAY_MAX_DEVICES; k++) {
1760 /* Get the pointer to the layer object */
1761 vpbe_display_layer = disp_dev->dev[k];
1762 /* Unregister video device */
1763 if (vpbe_display_layer) {
1764 video_unregister_device(
1765 &vpbe_display_layer->video_dev);
1766 kfree(disp_dev->dev[k]);
1767 }
1768 }
1769 kfree(disp_dev);
1770 return err;
1771}
1772
1773/*
1774 * vpbe_display_remove()
1775 * It un-register hardware layer from V4L2 driver
1776 */
1777static int vpbe_display_remove(struct platform_device *pdev)
1778{
1779 struct vpbe_layer *vpbe_display_layer;
1780 struct vpbe_display *disp_dev = platform_get_drvdata(pdev);
1781 struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev;
1782 struct resource *res;
1783 int i;
1784
1785 v4l2_dbg(1, debug, &vpbe_dev->v4l2_dev, "vpbe_display_remove\n");
1786
1787 /* unregister irq */
1788 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1789 free_irq(res->start, disp_dev);
1790
1791 /* deinitialize the vpbe display controller */
1792 if (NULL != vpbe_dev->ops.deinitialize)
1793 vpbe_dev->ops.deinitialize(&pdev->dev, vpbe_dev);
1794 /* un-register device */
1795 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1796 /* Get the pointer to the layer object */
1797 vpbe_display_layer = disp_dev->dev[i];
1798 /* Unregister video device */
1799 video_unregister_device(&vpbe_display_layer->video_dev);
1800
1801 }
1802 for (i = 0; i < VPBE_DISPLAY_MAX_DEVICES; i++) {
1803 kfree(disp_dev->dev[i]);
1804 disp_dev->dev[i] = NULL;
1805 }
1806
1807 return 0;
1808}
1809
1810static struct platform_driver vpbe_display_driver = {
1811 .driver = {
1812 .name = VPBE_DISPLAY_DRIVER,
1813 .owner = THIS_MODULE,
1814 .bus = &platform_bus_type,
1815 },
1816 .probe = vpbe_display_probe,
1817 .remove = __devexit_p(vpbe_display_remove),
1818};
1819
1820/*
1821 * vpbe_display_init()
1822 * This function registers device and driver to the kernel, requests irq
1823 * handler and allocates memory for layer objects
1824 */
1825static __devinit int vpbe_display_init(void)
1826{
1827 int err;
1828
1829 printk(KERN_DEBUG "vpbe_display_init\n");
1830
1831 /* Register driver to the kernel */
1832 err = platform_driver_register(&vpbe_display_driver);
1833 if (0 != err)
1834 return err;
1835
1836 printk(KERN_DEBUG "vpbe_display_init:"
1837 "VPBE V4L2 Display Driver V1.0 loaded\n");
1838 return 0;
1839}
1840
1841/*
1842 * vpbe_display_cleanup()
1843 * This function un-registers device and driver to the kernel, frees requested
1844 * irq handler and de-allocates memory allocated for layer objects.
1845 */
1846static void vpbe_display_cleanup(void)
1847{
1848 printk(KERN_DEBUG "vpbe_display_cleanup\n");
1849
1850 /* platform driver unregister */
1851 platform_driver_unregister(&vpbe_display_driver);
1852}
1853
1854/* Function for module initialization and cleanup */
1855module_init(vpbe_display_init);
1856module_exit(vpbe_display_cleanup);
1857
1858MODULE_DESCRIPTION("TI DM644x/DM355/DM365 VPBE Display controller");
1859MODULE_LICENSE("GPL");
1860MODULE_AUTHOR("Texas Instruments");
diff --git a/include/media/davinci/vpbe_display.h b/include/media/davinci/vpbe_display.h
new file mode 100644
index 000000000000..dbf6b37682cd
--- /dev/null
+++ b/include/media/davinci/vpbe_display.h
@@ -0,0 +1,147 @@
1/*
2 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation version 2.
7 *
8 * This program is distributed WITHOUT ANY WARRANTY of any
9 * kind, whether express or implied; without even the implied warranty
10 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13#ifndef VPBE_DISPLAY_H
14#define VPBE_DISPLAY_H
15
16/* Header files */
17#include <linux/videodev2.h>
18#include <media/v4l2-common.h>
19#include <media/videobuf-dma-contig.h>
20#include <media/davinci/vpbe_types.h>
21#include <media/davinci/vpbe_osd.h>
22#include <media/davinci/vpbe.h>
23
24#define VPBE_DISPLAY_MAX_DEVICES 2
25
26enum vpbe_display_device_id {
27 VPBE_DISPLAY_DEVICE_0,
28 VPBE_DISPLAY_DEVICE_1
29};
30
31#define VPBE_DISPLAY_DRV_NAME "vpbe-display"
32
33#define VPBE_DISPLAY_MAJOR_RELEASE 1
34#define VPBE_DISPLAY_MINOR_RELEASE 0
35#define VPBE_DISPLAY_BUILD 1
36#define VPBE_DISPLAY_VERSION_CODE ((VPBE_DISPLAY_MAJOR_RELEASE << 16) | \
37 (VPBE_DISPLAY_MINOR_RELEASE << 8) | \
38 VPBE_DISPLAY_BUILD)
39
40#define VPBE_DISPLAY_VALID_FIELD(field) ((V4L2_FIELD_NONE == field) || \
41 (V4L2_FIELD_ANY == field) || (V4L2_FIELD_INTERLACED == field))
42
43/* Exp ratio numerator and denominator constants */
44#define VPBE_DISPLAY_H_EXP_RATIO_N 9
45#define VPBE_DISPLAY_H_EXP_RATIO_D 8
46#define VPBE_DISPLAY_V_EXP_RATIO_N 6
47#define VPBE_DISPLAY_V_EXP_RATIO_D 5
48
49/* Zoom multiplication factor */
50#define VPBE_DISPLAY_ZOOM_4X 4
51#define VPBE_DISPLAY_ZOOM_2X 2
52
53/* Structures */
54struct display_layer_info {
55 int enable;
56 /* Layer ID used by Display Manager */
57 enum osd_layer id;
58 struct osd_layer_config config;
59 enum osd_zoom_factor h_zoom;
60 enum osd_zoom_factor v_zoom;
61 enum osd_h_exp_ratio h_exp;
62 enum osd_v_exp_ratio v_exp;
63};
64
65/* vpbe display object structure */
66struct vpbe_layer {
67 /* number of buffers in fbuffers */
68 unsigned int numbuffers;
69 /* Pointer to the vpbe_display */
70 struct vpbe_display *disp_dev;
71 /* Pointer pointing to current v4l2_buffer */
72 struct videobuf_buffer *cur_frm;
73 /* Pointer pointing to next v4l2_buffer */
74 struct videobuf_buffer *next_frm;
75 /* videobuf specific parameters
76 * Buffer queue used in video-buf
77 */
78 struct videobuf_queue buffer_queue;
79 /* Queue of filled frames */
80 struct list_head dma_queue;
81 /* Used in video-buf */
82 spinlock_t irqlock;
83 /* V4l2 specific parameters */
84 /* Identifies video device for this layer */
85 struct video_device video_dev;
86 /* This field keeps track of type of buffer exchange mechanism user
87 * has selected
88 */
89 enum v4l2_memory memory;
90 /* Used to keep track of state of the priority */
91 struct v4l2_prio_state prio;
92 /* Used to store pixel format */
93 struct v4l2_pix_format pix_fmt;
94 enum v4l2_field buf_field;
95 /* Video layer configuration params */
96 struct display_layer_info layer_info;
97 /* vpbe specific parameters
98 * enable window for display
99 */
100 unsigned char window_enable;
101 /* number of open instances of the layer */
102 unsigned int usrs;
103 /* number of users performing IO */
104 unsigned int io_usrs;
105 /* Indicates id of the field which is being displayed */
106 unsigned int field_id;
107 /* Indicates whether streaming started */
108 unsigned char started;
109 /* Identifies device object */
110 enum vpbe_display_device_id device_id;
111 /* facilitation of ioctl ops lock by v4l2*/
112 struct mutex opslock;
113 u8 layer_first_int;
114};
115
116/* vpbe device structure */
117struct vpbe_display {
118 /* layer specific parameters */
119 /* lock for isr updates to buf layers*/
120 spinlock_t dma_queue_lock;
121 /* C-Plane offset from start of y-plane */
122 unsigned int cbcr_ofst;
123 struct vpbe_layer *dev[VPBE_DISPLAY_MAX_DEVICES];
124 struct vpbe_device *vpbe_dev;
125 struct osd_state *osd_device;
126};
127
128/* File handle structure */
129struct vpbe_fh {
130 /* vpbe device structure */
131 struct vpbe_display *disp_dev;
132 /* pointer to layer object for opened device */
133 struct vpbe_layer *layer;
134 /* Indicates whether this file handle is doing IO */
135 unsigned char io_allowed;
136 /* Used to keep track priority of this instance */
137 enum v4l2_priority prio;
138};
139
140struct buf_config_params {
141 unsigned char min_numbuffers;
142 unsigned char numbuffers[VPBE_DISPLAY_MAX_DEVICES];
143 unsigned int min_bufsize[VPBE_DISPLAY_MAX_DEVICES];
144 unsigned int layer_bufsize[VPBE_DISPLAY_MAX_DEVICES];
145};
146
147#endif /* VPBE_DISPLAY_H */
diff --git a/include/media/davinci/vpbe_types.h b/include/media/davinci/vpbe_types.h
new file mode 100644
index 000000000000..727f55170e41
--- /dev/null
+++ b/include/media/davinci/vpbe_types.h
@@ -0,0 +1,91 @@
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_TYPES_H
18#define _VPBE_TYPES_H
19
20enum vpbe_version {
21 VPBE_VERSION_1 = 1,
22 VPBE_VERSION_2,
23 VPBE_VERSION_3,
24};
25
26/* vpbe_timing_type - Timing types used in vpbe device */
27enum vpbe_enc_timings_type {
28 VPBE_ENC_STD = 0x1,
29 VPBE_ENC_DV_PRESET = 0x2,
30 VPBE_ENC_CUSTOM_TIMINGS = 0x4,
31 /* Used when set timings through FB device interface */
32 VPBE_ENC_TIMINGS_INVALID = 0x8,
33};
34
35union vpbe_timings {
36 v4l2_std_id std_id;
37 unsigned int dv_preset;
38};
39
40/*
41 * struct vpbe_enc_mode_info
42 * @name: ptr to name string of the standard, "NTSC", "PAL" etc
43 * @std: standard or non-standard mode. 1 - standard, 0 - nonstandard
44 * @interlaced: 1 - interlaced, 0 - non interlaced/progressive
45 * @xres: x or horizontal resolution of the display
46 * @yres: y or vertical resolution of the display
47 * @fps: frame per second
48 * @left_margin: left margin of the display
49 * @right_margin: right margin of the display
50 * @upper_margin: upper margin of the display
51 * @lower_margin: lower margin of the display
52 * @hsync_len: h-sync length
53 * @vsync_len: v-sync length
54 * @flags: bit field: bit usage is documented below
55 *
56 * Description:
57 * Structure holding timing and resolution information of a standard.
58 * Used by vpbe_device to set required non-standard timing in the
59 * venc when lcd controller output is connected to a external encoder.
60 * A table of timings is maintained in vpbe device to set this in
61 * venc when external encoder is connected to lcd controller output.
62 * Encoder may provide a g_dv_timings() API to override these values
63 * as needed.
64 *
65 * Notes
66 * ------
67 * if_type should be used only by encoder manager and encoder.
68 * flags usage
69 * b0 (LSB) - hsync polarity, 0 - negative, 1 - positive
70 * b1 - vsync polarity, 0 - negative, 1 - positive
71 * b2 - field id polarity, 0 - negative, 1 - positive
72 */
73struct vpbe_enc_mode_info {
74 unsigned char *name;
75 enum vpbe_enc_timings_type timings_type;
76 union vpbe_timings timings;
77 unsigned int interlaced;
78 unsigned int xres;
79 unsigned int yres;
80 struct v4l2_fract aspect;
81 struct v4l2_fract fps;
82 unsigned int left_margin;
83 unsigned int right_margin;
84 unsigned int upper_margin;
85 unsigned int lower_margin;
86 unsigned int hsync_len;
87 unsigned int vsync_len;
88 unsigned int flags;
89};
90
91#endif