aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMuralidharan Karicheri <m-karicheri2@ti.com>2009-09-16 13:31:10 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-18 23:19:39 -0400
commit6ffefff5a9e76c2e9cb5081e219a7a6a4a5eee9f (patch)
treef67bfe9ef23dc6192cd3cdefb1f25a7c1bf0a04c /drivers/media
parent89803d83b69c5ce05c590f01a0ba92b99d28b057 (diff)
V4L/DVB (12906c): V4L : vpif capture driver for DM6467
This is the vpif capture bridge driver for DM6467. This video supports two video channels each having a tvp5147 device at the input. This allows simultaneous capture of NTSC/PAL video in each of this channel. Both MMAP and USERPTR io mechanism are supported. Currently buffer allocation happens at REQBUF ioctl request. Since USERPTR IO is supported, this is not an issue since user applications can allocate buffers and pass the user space address to the driver. Following are TODOs :- 1) Adding support for allocation of buffers at init 2) VBI/HBI data service This has incorporated comments received against version v0 of the patch series. Resending to merge V4l linux-next create mode 100644 drivers/media/video/davinci/vpif_capture.c create mode 100644 drivers/media/video/davinci/vpif_capture.h Reviewed-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Muralidharan Karicheri <m-karicheri2@ti.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/davinci/vpif_capture.c2168
-rw-r--r--drivers/media/video/davinci/vpif_capture.h165
2 files changed, 2333 insertions, 0 deletions
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
new file mode 100644
index 000000000000..d947ee5e4eb4
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -0,0 +1,2168 @@
1/*
2 * Copyright (C) 2009 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; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * TODO : add support for VBI & HBI data service
19 * add static buffer allocation
20 */
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/mm.h>
27#include <linux/interrupt.h>
28#include <linux/workqueue.h>
29#include <linux/string.h>
30#include <linux/videodev2.h>
31#include <linux/wait.h>
32#include <linux/time.h>
33#include <linux/i2c.h>
34#include <linux/platform_device.h>
35#include <linux/io.h>
36#include <linux/version.h>
37#include <media/v4l2-device.h>
38#include <media/v4l2-ioctl.h>
39
40#include "vpif_capture.h"
41#include "vpif.h"
42
43MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
44MODULE_LICENSE("GPL");
45
46#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
47#define vpif_dbg(level, debug, fmt, arg...) \
48 v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
49
50static int debug = 1;
51static u32 ch0_numbuffers = 3;
52static u32 ch1_numbuffers = 3;
53static u32 ch0_bufsize = 1920 * 1080 * 2;
54static u32 ch1_bufsize = 720 * 576 * 2;
55
56module_param(debug, int, 0644);
57module_param(ch0_numbuffers, uint, S_IRUGO);
58module_param(ch1_numbuffers, uint, S_IRUGO);
59module_param(ch0_bufsize, uint, S_IRUGO);
60module_param(ch1_bufsize, uint, S_IRUGO);
61
62MODULE_PARM_DESC(debug, "Debug level 0-1");
63MODULE_PARM_DESC(ch2_numbuffers, "Channel0 buffer count (default:3)");
64MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
65MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 2)");
66MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
67
68static struct vpif_config_params config_params = {
69 .min_numbuffers = 3,
70 .numbuffers[0] = 3,
71 .numbuffers[1] = 3,
72 .min_bufsize[0] = 720 * 480 * 2,
73 .min_bufsize[1] = 720 * 480 * 2,
74 .channel_bufsize[0] = 1920 * 1080 * 2,
75 .channel_bufsize[1] = 720 * 576 * 2,
76};
77
78/* global variables */
79static struct vpif_device vpif_obj = { {NULL} };
80static struct device *vpif_dev;
81
82/**
83 * ch_params: video standard configuration parameters for vpif
84 */
85static const struct vpif_channel_config_params ch_params[] = {
86 {
87 "NTSC_M", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
88 286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
89 },
90 {
91 "PAL_BDGHIK", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
92 336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
93 },
94};
95
96/**
97 * vpif_uservirt_to_phys : translate user/virtual address to phy address
98 * @virtp: user/virtual address
99 *
100 * This inline function is used to convert user space virtual address to
101 * physical address.
102 */
103static inline u32 vpif_uservirt_to_phys(u32 virtp)
104{
105 unsigned long physp = 0;
106 struct mm_struct *mm = current->mm;
107 struct vm_area_struct *vma;
108
109 vma = find_vma(mm, virtp);
110
111 /* For kernel direct-mapped memory, take the easy way */
112 if (virtp >= PAGE_OFFSET)
113 physp = virt_to_phys((void *)virtp);
114 else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff))
115 /**
116 * this will catch, kernel-allocated, mmaped-to-usermode
117 * addresses
118 */
119 physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
120 else {
121 /* otherwise, use get_user_pages() for general userland pages */
122 int res, nr_pages = 1;
123 struct page *pages;
124
125 down_read(&current->mm->mmap_sem);
126
127 res = get_user_pages(current, current->mm,
128 virtp, nr_pages, 1, 0, &pages, NULL);
129 up_read(&current->mm->mmap_sem);
130
131 if (res == nr_pages)
132 physp = __pa(page_address(&pages[0]) +
133 (virtp & ~PAGE_MASK));
134 else {
135 vpif_err("get_user_pages failed\n");
136 return 0;
137 }
138 }
139 return physp;
140}
141
142/**
143 * buffer_prepare : callback function for buffer prepare
144 * @q : buffer queue ptr
145 * @vb: ptr to video buffer
146 * @field: field info
147 *
148 * This is the callback function for buffer prepare when videobuf_qbuf()
149 * function is called. The buffer is prepared and user space virtual address
150 * or user address is converted into physical address
151 */
152static int vpif_buffer_prepare(struct videobuf_queue *q,
153 struct videobuf_buffer *vb,
154 enum v4l2_field field)
155{
156 /* Get the file handle object and channel object */
157 struct vpif_fh *fh = q->priv_data;
158 struct channel_obj *ch = fh->channel;
159 struct common_obj *common;
160 unsigned long addr;
161
162
163 vpif_dbg(2, debug, "vpif_buffer_prepare\n");
164
165 common = &ch->common[VPIF_VIDEO_INDEX];
166
167 /* If buffer is not initialized, initialize it */
168 if (VIDEOBUF_NEEDS_INIT == vb->state) {
169 vb->width = common->width;
170 vb->height = common->height;
171 vb->size = vb->width * vb->height;
172 vb->field = field;
173 }
174 vb->state = VIDEOBUF_PREPARED;
175 /**
176 * if user pointer memory mechanism is used, get the physical
177 * address of the buffer
178 */
179 if (V4L2_MEMORY_USERPTR == common->memory) {
180 if (0 == vb->baddr) {
181 vpif_dbg(1, debug, "buffer address is 0\n");
182 return -EINVAL;
183
184 }
185 vb->boff = vpif_uservirt_to_phys(vb->baddr);
186 if (!IS_ALIGNED(vb->boff, 8))
187 goto exit;
188 }
189
190 addr = vb->boff;
191 if (q->streaming) {
192 if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
193 !IS_ALIGNED((addr + common->ybtm_off), 8) ||
194 !IS_ALIGNED((addr + common->ctop_off), 8) ||
195 !IS_ALIGNED((addr + common->cbtm_off), 8))
196 goto exit;
197 }
198 return 0;
199exit:
200 vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n");
201 return -EINVAL;
202}
203
204/**
205 * vpif_buffer_setup : Callback function for buffer setup.
206 * @q: buffer queue ptr
207 * @count: number of buffers
208 * @size: size of the buffer
209 *
210 * This callback function is called when reqbuf() is called to adjust
211 * the buffer count and buffer size
212 */
213static int vpif_buffer_setup(struct videobuf_queue *q, unsigned int *count,
214 unsigned int *size)
215{
216 /* Get the file handle object and channel object */
217 struct vpif_fh *fh = q->priv_data;
218 struct channel_obj *ch = fh->channel;
219 struct common_obj *common;
220
221 common = &ch->common[VPIF_VIDEO_INDEX];
222
223 vpif_dbg(2, debug, "vpif_buffer_setup\n");
224
225 /* If memory type is not mmap, return */
226 if (V4L2_MEMORY_MMAP != common->memory)
227 return 0;
228
229 /* Calculate the size of the buffer */
230 *size = config_params.channel_bufsize[ch->channel_id];
231
232 if (*count < config_params.min_numbuffers)
233 *count = config_params.min_numbuffers;
234 return 0;
235}
236
237/**
238 * vpif_buffer_queue : Callback function to add buffer to DMA queue
239 * @q: ptr to videobuf_queue
240 * @vb: ptr to videobuf_buffer
241 */
242static void vpif_buffer_queue(struct videobuf_queue *q,
243 struct videobuf_buffer *vb)
244{
245 /* Get the file handle object and channel object */
246 struct vpif_fh *fh = q->priv_data;
247 struct channel_obj *ch = fh->channel;
248 struct common_obj *common;
249
250 common = &ch->common[VPIF_VIDEO_INDEX];
251
252 vpif_dbg(2, debug, "vpif_buffer_queue\n");
253
254 /* add the buffer to the DMA queue */
255 list_add_tail(&vb->queue, &common->dma_queue);
256 /* Change state of the buffer */
257 vb->state = VIDEOBUF_QUEUED;
258}
259
260/**
261 * vpif_buffer_release : Callback function to free buffer
262 * @q: buffer queue ptr
263 * @vb: ptr to video buffer
264 *
265 * This function is called from the videobuf layer to free memory
266 * allocated to the buffers
267 */
268static void vpif_buffer_release(struct videobuf_queue *q,
269 struct videobuf_buffer *vb)
270{
271 /* Get the file handle object and channel object */
272 struct vpif_fh *fh = q->priv_data;
273 struct channel_obj *ch = fh->channel;
274 struct common_obj *common;
275
276 common = &ch->common[VPIF_VIDEO_INDEX];
277
278 videobuf_dma_contig_free(q, vb);
279 vb->state = VIDEOBUF_NEEDS_INIT;
280}
281
282static struct videobuf_queue_ops video_qops = {
283 .buf_setup = vpif_buffer_setup,
284 .buf_prepare = vpif_buffer_prepare,
285 .buf_queue = vpif_buffer_queue,
286 .buf_release = vpif_buffer_release,
287};
288
289static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
290 { {1, 1} };
291
292/**
293 * vpif_process_buffer_complete: process a completed buffer
294 * @common: ptr to common channel object
295 *
296 * This function time stamp the buffer and mark it as DONE. It also
297 * wake up any process waiting on the QUEUE and set the next buffer
298 * as current
299 */
300static void vpif_process_buffer_complete(struct common_obj *common)
301{
302 do_gettimeofday(&common->cur_frm->ts);
303 common->cur_frm->state = VIDEOBUF_DONE;
304 wake_up_interruptible(&common->cur_frm->done);
305 /* Make curFrm pointing to nextFrm */
306 common->cur_frm = common->next_frm;
307}
308
309/**
310 * vpif_schedule_next_buffer: set next buffer address for capture
311 * @common : ptr to common channel object
312 *
313 * This function will get next buffer from the dma queue and
314 * set the buffer address in the vpif register for capture.
315 * the buffer is marked active
316 */
317static void vpif_schedule_next_buffer(struct common_obj *common)
318{
319 unsigned long addr = 0;
320
321 common->next_frm = list_entry(common->dma_queue.next,
322 struct videobuf_buffer, queue);
323 /* Remove that buffer from the buffer queue */
324 list_del(&common->next_frm->queue);
325 common->next_frm->state = VIDEOBUF_ACTIVE;
326 if (V4L2_MEMORY_USERPTR == common->memory)
327 addr = common->next_frm->boff;
328 else
329 addr = videobuf_to_dma_contig(common->next_frm);
330
331 /* Set top and bottom field addresses in VPIF registers */
332 common->set_addr(addr + common->ytop_off,
333 addr + common->ybtm_off,
334 addr + common->ctop_off,
335 addr + common->cbtm_off);
336}
337
338/**
339 * vpif_channel_isr : ISR handler for vpif capture
340 * @irq: irq number
341 * @dev_id: dev_id ptr
342 *
343 * It changes status of the captured buffer, takes next buffer from the queue
344 * and sets its address in VPIF registers
345 */
346static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
347{
348 struct vpif_device *dev = &vpif_obj;
349 struct common_obj *common;
350 struct channel_obj *ch;
351 enum v4l2_field field;
352 int channel_id = 0;
353 int fid = -1, i;
354
355 channel_id = *(int *)(dev_id);
356 ch = dev->dev[channel_id];
357
358 field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
359
360 for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
361 common = &ch->common[i];
362 /* skip If streaming is not started in this channel */
363 if (0 == common->started)
364 continue;
365
366 /* Check the field format */
367 if (1 == ch->vpifparams.std_info.frm_fmt) {
368 /* Progressive mode */
369 if (list_empty(&common->dma_queue))
370 continue;
371
372 if (!channel_first_int[i][channel_id])
373 vpif_process_buffer_complete(common);
374
375 channel_first_int[i][channel_id] = 0;
376
377 vpif_schedule_next_buffer(common);
378
379
380 channel_first_int[i][channel_id] = 0;
381 } else {
382 /**
383 * Interlaced mode. If it is first interrupt, ignore
384 * it
385 */
386 if (channel_first_int[i][channel_id]) {
387 channel_first_int[i][channel_id] = 0;
388 continue;
389 }
390 if (0 == i) {
391 ch->field_id ^= 1;
392 /* Get field id from VPIF registers */
393 fid = vpif_channel_getfid(ch->channel_id);
394 if (fid != ch->field_id) {
395 /**
396 * If field id does not match stored
397 * field id, make them in sync
398 */
399 if (0 == fid)
400 ch->field_id = fid;
401 return IRQ_HANDLED;
402 }
403 }
404 /* device field id and local field id are in sync */
405 if (0 == fid) {
406 /* this is even field */
407 if (common->cur_frm == common->next_frm)
408 continue;
409
410 /* mark the current buffer as done */
411 vpif_process_buffer_complete(common);
412 } else if (1 == fid) {
413 /* odd field */
414 if (list_empty(&common->dma_queue) ||
415 (common->cur_frm != common->next_frm))
416 continue;
417
418 vpif_schedule_next_buffer(common);
419 }
420 }
421 }
422 return IRQ_HANDLED;
423}
424
425/**
426 * vpif_update_std_info() - update standard related info
427 * @ch: ptr to channel object
428 *
429 * For a given standard selected by application, update values
430 * in the device data structures
431 */
432static int vpif_update_std_info(struct channel_obj *ch)
433{
434 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
435 struct vpif_params *vpifparams = &ch->vpifparams;
436 const struct vpif_channel_config_params *config;
437 struct vpif_channel_config_params *std_info;
438 struct video_obj *vid_ch = &ch->video;
439 int index;
440
441 vpif_dbg(2, debug, "vpif_update_std_info\n");
442
443 std_info = &vpifparams->std_info;
444
445 for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
446 config = &ch_params[index];
447 if (config->stdid & vid_ch->stdid) {
448 memcpy(std_info, config, sizeof(*config));
449 break;
450 }
451 }
452
453 /* standard not found */
454 if (index == ARRAY_SIZE(ch_params))
455 return -EINVAL;
456
457 common->fmt.fmt.pix.width = std_info->width;
458 common->width = std_info->width;
459 common->fmt.fmt.pix.height = std_info->height;
460 common->height = std_info->height;
461 common->fmt.fmt.pix.bytesperline = std_info->width;
462 vpifparams->video_params.hpitch = std_info->width;
463 vpifparams->video_params.storage_mode = std_info->frm_fmt;
464 return 0;
465}
466
467/**
468 * vpif_calculate_offsets : This function calculates buffers offsets
469 * @ch : ptr to channel object
470 *
471 * This function calculates buffer offsets for Y and C in the top and
472 * bottom field
473 */
474static void vpif_calculate_offsets(struct channel_obj *ch)
475{
476 unsigned int hpitch, vpitch, sizeimage;
477 struct video_obj *vid_ch = &(ch->video);
478 struct vpif_params *vpifparams = &ch->vpifparams;
479 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
480 enum v4l2_field field = common->fmt.fmt.pix.field;
481
482 vpif_dbg(2, debug, "vpif_calculate_offsets\n");
483
484 if (V4L2_FIELD_ANY == field) {
485 if (vpifparams->std_info.frm_fmt)
486 vid_ch->buf_field = V4L2_FIELD_NONE;
487 else
488 vid_ch->buf_field = V4L2_FIELD_INTERLACED;
489 } else
490 vid_ch->buf_field = common->fmt.fmt.pix.field;
491
492 if (V4L2_MEMORY_USERPTR == common->memory)
493 sizeimage = common->fmt.fmt.pix.sizeimage;
494 else
495 sizeimage = config_params.channel_bufsize[ch->channel_id];
496
497 hpitch = common->fmt.fmt.pix.bytesperline;
498 vpitch = sizeimage / (hpitch * 2);
499
500 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
501 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
502 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
503 common->ytop_off = 0;
504 common->ybtm_off = hpitch;
505 common->ctop_off = sizeimage / 2;
506 common->cbtm_off = sizeimage / 2 + hpitch;
507 } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
508 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
509 common->ytop_off = 0;
510 common->ybtm_off = sizeimage / 4;
511 common->ctop_off = sizeimage / 2;
512 common->cbtm_off = common->ctop_off + sizeimage / 4;
513 } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
514 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
515 common->ybtm_off = 0;
516 common->ytop_off = sizeimage / 4;
517 common->cbtm_off = sizeimage / 2;
518 common->ctop_off = common->cbtm_off + sizeimage / 4;
519 }
520 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
521 (V4L2_FIELD_INTERLACED == vid_ch->buf_field))
522 vpifparams->video_params.storage_mode = 1;
523 else
524 vpifparams->video_params.storage_mode = 0;
525
526 if (1 == vpifparams->std_info.frm_fmt)
527 vpifparams->video_params.hpitch =
528 common->fmt.fmt.pix.bytesperline;
529 else {
530 if ((field == V4L2_FIELD_ANY)
531 || (field == V4L2_FIELD_INTERLACED))
532 vpifparams->video_params.hpitch =
533 common->fmt.fmt.pix.bytesperline * 2;
534 else
535 vpifparams->video_params.hpitch =
536 common->fmt.fmt.pix.bytesperline;
537 }
538
539 ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
540}
541
542/**
543 * vpif_config_format: configure default frame format in the device
544 * ch : ptr to channel object
545 */
546static void vpif_config_format(struct channel_obj *ch)
547{
548 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
549
550 vpif_dbg(2, debug, "vpif_config_format\n");
551
552 common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
553 if (config_params.numbuffers[ch->channel_id] == 0)
554 common->memory = V4L2_MEMORY_USERPTR;
555 else
556 common->memory = V4L2_MEMORY_MMAP;
557
558 common->fmt.fmt.pix.sizeimage
559 = config_params.channel_bufsize[ch->channel_id];
560
561 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
562 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
563 else
564 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
565 common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
566}
567
568/**
569 * vpif_get_default_field() - Get default field type based on interface
570 * @vpif_params - ptr to vpif params
571 */
572static inline enum v4l2_field vpif_get_default_field(
573 struct vpif_interface *iface)
574{
575 return (iface->if_type == VPIF_IF_RAW_BAYER) ? V4L2_FIELD_NONE :
576 V4L2_FIELD_INTERLACED;
577}
578
579/**
580 * vpif_check_format() - check given pixel format for compatibility
581 * @ch - channel ptr
582 * @pixfmt - Given pixel format
583 * @update - update the values as per hardware requirement
584 *
585 * Check the application pixel format for S_FMT and update the input
586 * values as per hardware limits for TRY_FMT. The default pixel and
587 * field format is selected based on interface type.
588 */
589static int vpif_check_format(struct channel_obj *ch,
590 struct v4l2_pix_format *pixfmt,
591 int update)
592{
593 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
594 struct vpif_params *vpif_params = &ch->vpifparams;
595 enum v4l2_field field = pixfmt->field;
596 u32 sizeimage, hpitch, vpitch;
597 int ret = -EINVAL;
598
599 vpif_dbg(2, debug, "vpif_check_format\n");
600 /**
601 * first check for the pixel format. If if_type is Raw bayer,
602 * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
603 * V4L2_PIX_FMT_YUV422P is supported
604 */
605 if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
606 if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
607 if (!update) {
608 vpif_dbg(2, debug, "invalid pix format\n");
609 goto exit;
610 }
611 pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
612 }
613 } else {
614 if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
615 if (!update) {
616 vpif_dbg(2, debug, "invalid pixel format\n");
617 goto exit;
618 }
619 pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
620 }
621 }
622
623 if (!(VPIF_VALID_FIELD(field))) {
624 if (!update) {
625 vpif_dbg(2, debug, "invalid field format\n");
626 goto exit;
627 }
628 /**
629 * By default use FIELD_NONE for RAW Bayer capture
630 * and FIELD_INTERLACED for other interfaces
631 */
632 field = vpif_get_default_field(&vpif_params->iface);
633 } else if (field == V4L2_FIELD_ANY)
634 /* unsupported field. Use default */
635 field = vpif_get_default_field(&vpif_params->iface);
636
637 /* validate the hpitch */
638 hpitch = pixfmt->bytesperline;
639 if (hpitch < vpif_params->std_info.width) {
640 if (!update) {
641 vpif_dbg(2, debug, "invalid hpitch\n");
642 goto exit;
643 }
644 hpitch = vpif_params->std_info.width;
645 }
646
647 if (V4L2_MEMORY_USERPTR == common->memory)
648 sizeimage = pixfmt->sizeimage;
649 else
650 sizeimage = config_params.channel_bufsize[ch->channel_id];
651
652 vpitch = sizeimage / (hpitch * 2);
653
654 /* validate the vpitch */
655 if (vpitch < vpif_params->std_info.height) {
656 if (!update) {
657 vpif_dbg(2, debug, "Invalid vpitch\n");
658 goto exit;
659 }
660 vpitch = vpif_params->std_info.height;
661 }
662
663 /* Check for 8 byte alignment */
664 if (!ALIGN(hpitch, 8)) {
665 if (!update) {
666 vpif_dbg(2, debug, "invalid pitch alignment\n");
667 goto exit;
668 }
669 /* adjust to next 8 byte boundary */
670 hpitch = (((hpitch + 7) / 8) * 8);
671 }
672 /* if update is set, modify the bytesperline and sizeimage */
673 if (update) {
674 pixfmt->bytesperline = hpitch;
675 pixfmt->sizeimage = hpitch * vpitch * 2;
676 }
677 /**
678 * Image width and height is always based on current standard width and
679 * height
680 */
681 pixfmt->width = common->fmt.fmt.pix.width;
682 pixfmt->height = common->fmt.fmt.pix.height;
683 return 0;
684exit:
685 return ret;
686}
687
688/**
689 * vpif_config_addr() - function to configure buffer address in vpif
690 * @ch - channel ptr
691 * @muxmode - channel mux mode
692 */
693static void vpif_config_addr(struct channel_obj *ch, int muxmode)
694{
695 struct common_obj *common;
696
697 vpif_dbg(2, debug, "vpif_config_addr\n");
698
699 common = &(ch->common[VPIF_VIDEO_INDEX]);
700
701 if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
702 common->set_addr = ch1_set_videobuf_addr;
703 else if (2 == muxmode)
704 common->set_addr = ch0_set_videobuf_addr_yc_nmux;
705 else
706 common->set_addr = ch0_set_videobuf_addr;
707}
708
709/**
710 * vpfe_mmap : It is used to map kernel space buffers into user spaces
711 * @filep: file pointer
712 * @vma: ptr to vm_area_struct
713 */
714static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
715{
716 /* Get the channel object and file handle object */
717 struct vpif_fh *fh = filep->private_data;
718 struct channel_obj *ch = fh->channel;
719 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
720
721 vpif_dbg(2, debug, "vpif_mmap\n");
722
723 return videobuf_mmap_mapper(&common->buffer_queue, vma);
724}
725
726/**
727 * vpif_poll: It is used for select/poll system call
728 * @filep: file pointer
729 * @wait: poll table to wait
730 */
731static unsigned int vpif_poll(struct file *filep, poll_table * wait)
732{
733 int err = 0;
734 struct vpif_fh *fh = filep->private_data;
735 struct channel_obj *channel = fh->channel;
736 struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
737
738 vpif_dbg(2, debug, "vpif_poll\n");
739
740 if (common->started)
741 err = videobuf_poll_stream(filep, &common->buffer_queue, wait);
742
743 return 0;
744}
745
746/**
747 * vpif_open : vpif open handler
748 * @filep: file ptr
749 *
750 * It creates object of file handle structure and stores it in private_data
751 * member of filepointer
752 */
753static int vpif_open(struct file *filep)
754{
755 struct vpif_capture_config *config = vpif_dev->platform_data;
756 struct video_device *vdev = video_devdata(filep);
757 struct common_obj *common;
758 struct video_obj *vid_ch;
759 struct channel_obj *ch;
760 struct vpif_fh *fh;
761 int i, ret = 0;
762
763 vpif_dbg(2, debug, "vpif_open\n");
764
765 ch = video_get_drvdata(vdev);
766
767 vid_ch = &ch->video;
768 common = &ch->common[VPIF_VIDEO_INDEX];
769
770 if (mutex_lock_interruptible(&common->lock))
771 return -ERESTARTSYS;
772
773 if (NULL == ch->curr_subdev_info) {
774 /**
775 * search through the sub device to see a registered
776 * sub device and make it as current sub device
777 */
778 for (i = 0; i < config->subdev_count; i++) {
779 if (vpif_obj.sd[i]) {
780 /* the sub device is registered */
781 ch->curr_subdev_info = &config->subdev_info[i];
782 /* make first input as the current input */
783 vid_ch->input_idx = 0;
784 break;
785 }
786 }
787 if (i == config->subdev_count) {
788 vpif_err("No sub device registered\n");
789 ret = -ENOENT;
790 goto exit;
791 }
792 }
793
794 /* Allocate memory for the file handle object */
795 fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL);
796 if (NULL == fh) {
797 vpif_err("unable to allocate memory for file handle object\n");
798 ret = -ENOMEM;
799 goto exit;
800 }
801
802 /* store pointer to fh in private_data member of filep */
803 filep->private_data = fh;
804 fh->channel = ch;
805 fh->initialized = 0;
806 /* If decoder is not initialized. initialize it */
807 if (!ch->initialized) {
808 fh->initialized = 1;
809 ch->initialized = 1;
810 memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
811 }
812 /* Increment channel usrs counter */
813 ch->usrs++;
814 /* Set io_allowed member to false */
815 fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
816 /* Initialize priority of this instance to default priority */
817 fh->prio = V4L2_PRIORITY_UNSET;
818 v4l2_prio_open(&ch->prio, &fh->prio);
819exit:
820 mutex_unlock(&common->lock);
821 return ret;
822}
823
824/**
825 * vpif_release : function to clean up file close
826 * @filep: file pointer
827 *
828 * This function deletes buffer queue, frees the buffers and the vpfe file
829 * handle
830 */
831static int vpif_release(struct file *filep)
832{
833 struct vpif_fh *fh = filep->private_data;
834 struct channel_obj *ch = fh->channel;
835 struct common_obj *common;
836
837 vpif_dbg(2, debug, "vpif_release\n");
838
839 common = &ch->common[VPIF_VIDEO_INDEX];
840
841 if (mutex_lock_interruptible(&common->lock))
842 return -ERESTARTSYS;
843
844 /* if this instance is doing IO */
845 if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
846 /* Reset io_usrs member of channel object */
847 common->io_usrs = 0;
848 /* Disable channel as per its device type and channel id */
849 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
850 enable_channel0(0);
851 channel0_intr_enable(0);
852 }
853 if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
854 (2 == common->started)) {
855 enable_channel1(0);
856 channel1_intr_enable(0);
857 }
858 common->started = 0;
859 /* Free buffers allocated */
860 videobuf_queue_cancel(&common->buffer_queue);
861 videobuf_mmap_free(&common->buffer_queue);
862 }
863
864 /* Decrement channel usrs counter */
865 ch->usrs--;
866
867 /* unlock mutex on channel object */
868 mutex_unlock(&common->lock);
869
870 /* Close the priority */
871 v4l2_prio_close(&ch->prio, &fh->prio);
872
873 if (fh->initialized)
874 ch->initialized = 0;
875
876 filep->private_data = NULL;
877 kfree(fh);
878 return 0;
879}
880
881/**
882 * vpif_reqbufs() - request buffer handler
883 * @file: file ptr
884 * @priv: file handle
885 * @reqbuf: request buffer structure ptr
886 */
887static int vpif_reqbufs(struct file *file, void *priv,
888 struct v4l2_requestbuffers *reqbuf)
889{
890 struct vpif_fh *fh = priv;
891 struct channel_obj *ch = fh->channel;
892 struct common_obj *common;
893 u8 index = 0;
894 int ret = 0;
895
896 vpif_dbg(2, debug, "vpif_reqbufs\n");
897
898 /**
899 * This file handle has not initialized the channel,
900 * It is not allowed to do settings
901 */
902 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
903 || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
904 if (!fh->initialized) {
905 vpif_dbg(1, debug, "Channel Busy\n");
906 return -EBUSY;
907 }
908 }
909
910 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type)
911 return -EINVAL;
912
913 index = VPIF_VIDEO_INDEX;
914
915 common = &ch->common[index];
916
917 if (mutex_lock_interruptible(&common->lock))
918 return -ERESTARTSYS;
919
920 if (0 != common->io_usrs) {
921 ret = -EBUSY;
922 goto reqbuf_exit;
923 }
924
925 /* Initialize videobuf queue as per the buffer type */
926 videobuf_queue_dma_contig_init(&common->buffer_queue,
927 &video_qops, NULL,
928 &common->irqlock,
929 reqbuf->type,
930 common->fmt.fmt.pix.field,
931 sizeof(struct videobuf_buffer), fh);
932
933 /* Set io allowed member of file handle to TRUE */
934 fh->io_allowed[index] = 1;
935 /* Increment io usrs member of channel object to 1 */
936 common->io_usrs = 1;
937 /* Store type of memory requested in channel object */
938 common->memory = reqbuf->memory;
939 INIT_LIST_HEAD(&common->dma_queue);
940
941 /* Allocate buffers */
942 ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
943
944reqbuf_exit:
945 mutex_unlock(&common->lock);
946 return ret;
947}
948
949/**
950 * vpif_querybuf() - query buffer handler
951 * @file: file ptr
952 * @priv: file handle
953 * @buf: v4l2 buffer structure ptr
954 */
955static int vpif_querybuf(struct file *file, void *priv,
956 struct v4l2_buffer *buf)
957{
958 struct vpif_fh *fh = priv;
959 struct channel_obj *ch = fh->channel;
960 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
961
962 vpif_dbg(2, debug, "vpif_querybuf\n");
963
964 if (common->fmt.type != buf->type)
965 return -EINVAL;
966
967 if (common->memory != V4L2_MEMORY_MMAP) {
968 vpif_dbg(1, debug, "Invalid memory\n");
969 return -EINVAL;
970 }
971
972 return videobuf_querybuf(&common->buffer_queue, buf);
973}
974
975/**
976 * vpif_qbuf() - query buffer handler
977 * @file: file ptr
978 * @priv: file handle
979 * @buf: v4l2 buffer structure ptr
980 */
981static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
982{
983
984 struct vpif_fh *fh = priv;
985 struct channel_obj *ch = fh->channel;
986 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
987 struct v4l2_buffer tbuf = *buf;
988 struct videobuf_buffer *buf1;
989 unsigned long addr = 0;
990 unsigned long flags;
991 int ret = 0;
992
993 vpif_dbg(2, debug, "vpif_qbuf\n");
994
995 if (common->fmt.type != tbuf.type) {
996 vpif_err("invalid buffer type\n");
997 return -EINVAL;
998 }
999
1000 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1001 vpif_err("fh io not allowed \n");
1002 return -EACCES;
1003 }
1004
1005 if (!(list_empty(&common->dma_queue)) ||
1006 (common->cur_frm != common->next_frm) ||
1007 !common->started ||
1008 (common->started && (0 == ch->field_id)))
1009 return videobuf_qbuf(&common->buffer_queue, buf);
1010
1011 /* bufferqueue is empty store buffer address in VPIF registers */
1012 mutex_lock(&common->buffer_queue.vb_lock);
1013 buf1 = common->buffer_queue.bufs[tbuf.index];
1014
1015 if ((buf1->state == VIDEOBUF_QUEUED) ||
1016 (buf1->state == VIDEOBUF_ACTIVE)) {
1017 vpif_err("invalid state\n");
1018 goto qbuf_exit;
1019 }
1020
1021 switch (buf1->memory) {
1022 case V4L2_MEMORY_MMAP:
1023 if (buf1->baddr == 0)
1024 goto qbuf_exit;
1025 break;
1026
1027 case V4L2_MEMORY_USERPTR:
1028 if (tbuf.length < buf1->bsize)
1029 goto qbuf_exit;
1030
1031 if ((VIDEOBUF_NEEDS_INIT != buf1->state)
1032 && (buf1->baddr != tbuf.m.userptr))
1033 vpif_buffer_release(&common->buffer_queue, buf1);
1034 buf1->baddr = tbuf.m.userptr;
1035 break;
1036
1037 default:
1038 goto qbuf_exit;
1039 }
1040
1041 local_irq_save(flags);
1042 ret = vpif_buffer_prepare(&common->buffer_queue, buf1,
1043 common->buffer_queue.field);
1044 if (ret < 0) {
1045 local_irq_restore(flags);
1046 goto qbuf_exit;
1047 }
1048
1049 buf1->state = VIDEOBUF_ACTIVE;
1050
1051 if (V4L2_MEMORY_USERPTR == common->memory)
1052 addr = buf1->boff;
1053 else
1054 addr = videobuf_to_dma_contig(buf1);
1055
1056 common->next_frm = buf1;
1057 common->set_addr(addr + common->ytop_off,
1058 addr + common->ybtm_off,
1059 addr + common->ctop_off,
1060 addr + common->cbtm_off);
1061
1062 local_irq_restore(flags);
1063 list_add_tail(&buf1->stream, &common->buffer_queue.stream);
1064 mutex_unlock(&common->buffer_queue.vb_lock);
1065 return 0;
1066
1067qbuf_exit:
1068 mutex_unlock(&common->buffer_queue.vb_lock);
1069 return -EINVAL;
1070}
1071
1072/**
1073 * vpif_dqbuf() - query buffer handler
1074 * @file: file ptr
1075 * @priv: file handle
1076 * @buf: v4l2 buffer structure ptr
1077 */
1078static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1079{
1080 struct vpif_fh *fh = priv;
1081 struct channel_obj *ch = fh->channel;
1082 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1083
1084 vpif_dbg(2, debug, "vpif_dqbuf\n");
1085
1086 return videobuf_dqbuf(&common->buffer_queue, buf,
1087 file->f_flags & O_NONBLOCK);
1088}
1089
1090/**
1091 * vpif_streamon() - streamon handler
1092 * @file: file ptr
1093 * @priv: file handle
1094 * @buftype: v4l2 buffer type
1095 */
1096static int vpif_streamon(struct file *file, void *priv,
1097 enum v4l2_buf_type buftype)
1098{
1099
1100 struct vpif_capture_config *config = vpif_dev->platform_data;
1101 struct vpif_fh *fh = priv;
1102 struct channel_obj *ch = fh->channel;
1103 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1104 struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
1105 struct vpif_params *vpif;
1106 unsigned long addr = 0;
1107 int ret = 0;
1108
1109 vpif_dbg(2, debug, "vpif_streamon\n");
1110
1111 vpif = &ch->vpifparams;
1112
1113 if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1114 vpif_dbg(1, debug, "buffer type not supported\n");
1115 return -EINVAL;
1116 }
1117
1118 /* If file handle is not allowed IO, return error */
1119 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1120 vpif_dbg(1, debug, "io not allowed\n");
1121 return -EACCES;
1122 }
1123
1124 /* If Streaming is already started, return error */
1125 if (common->started) {
1126 vpif_dbg(1, debug, "channel->started\n");
1127 return -EBUSY;
1128 }
1129
1130 if ((ch->channel_id == VPIF_CHANNEL0_VIDEO &&
1131 oth_ch->common[VPIF_VIDEO_INDEX].started &&
1132 vpif->std_info.ycmux_mode == 0) ||
1133 ((ch->channel_id == VPIF_CHANNEL1_VIDEO) &&
1134 (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
1135 vpif_dbg(1, debug, "other channel is being used\n");
1136 return -EBUSY;
1137 }
1138
1139 ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
1140 if (ret)
1141 return ret;
1142
1143 /* Enable streamon on the sub device */
1144 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1145 s_stream, 1);
1146
1147 if (ret && (ret != -ENOIOCTLCMD)) {
1148 vpif_dbg(1, debug, "stream on failed in subdev\n");
1149 return ret;
1150 }
1151
1152 /* Call videobuf_streamon to start streaming in videobuf */
1153 ret = videobuf_streamon(&common->buffer_queue);
1154 if (ret) {
1155 vpif_dbg(1, debug, "videobuf_streamon\n");
1156 return ret;
1157 }
1158
1159 if (mutex_lock_interruptible(&common->lock)) {
1160 ret = -ERESTARTSYS;
1161 goto streamoff_exit;
1162 }
1163
1164 /* If buffer queue is empty, return error */
1165 if (list_empty(&common->dma_queue)) {
1166 vpif_dbg(1, debug, "buffer queue is empty\n");
1167 ret = -EIO;
1168 goto exit;
1169 }
1170
1171 /* Get the next frame from the buffer queue */
1172 common->cur_frm = list_entry(common->dma_queue.next,
1173 struct videobuf_buffer, queue);
1174 common->next_frm = common->cur_frm;
1175
1176 /* Remove buffer from the buffer queue */
1177 list_del(&common->cur_frm->queue);
1178 /* Mark state of the current frame to active */
1179 common->cur_frm->state = VIDEOBUF_ACTIVE;
1180 /* Initialize field_id and started member */
1181 ch->field_id = 0;
1182 common->started = 1;
1183
1184 if (V4L2_MEMORY_USERPTR == common->memory)
1185 addr = common->cur_frm->boff;
1186 else
1187 addr = videobuf_to_dma_contig(common->cur_frm);
1188
1189 /* Calculate the offset for Y and C data in the buffer */
1190 vpif_calculate_offsets(ch);
1191
1192 if ((vpif->std_info.frm_fmt &&
1193 ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
1194 (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
1195 (!vpif->std_info.frm_fmt &&
1196 (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
1197 vpif_dbg(1, debug, "conflict in field format and std format\n");
1198 ret = -EINVAL;
1199 goto exit;
1200 }
1201
1202 /* configure 1 or 2 channel mode */
1203 ret = config->setup_input_channel_mode(vpif->std_info.ycmux_mode);
1204
1205 if (ret < 0) {
1206 vpif_dbg(1, debug, "can't set vpif channel mode\n");
1207 goto exit;
1208 }
1209
1210 /* Call vpif_set_params function to set the parameters and addresses */
1211 ret = vpif_set_video_params(vpif, ch->channel_id);
1212
1213 if (ret < 0) {
1214 vpif_dbg(1, debug, "can't set video params\n");
1215 goto exit;
1216 }
1217
1218 common->started = ret;
1219 vpif_config_addr(ch, ret);
1220
1221 common->set_addr(addr + common->ytop_off,
1222 addr + common->ybtm_off,
1223 addr + common->ctop_off,
1224 addr + common->cbtm_off);
1225
1226 /**
1227 * Set interrupt for both the fields in VPIF Register enable channel in
1228 * VPIF register
1229 */
1230 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
1231 channel0_intr_assert();
1232 channel0_intr_enable(1);
1233 enable_channel0(1);
1234 }
1235 if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
1236 (common->started == 2)) {
1237 channel1_intr_assert();
1238 channel1_intr_enable(1);
1239 enable_channel1(1);
1240 }
1241 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
1242 mutex_unlock(&common->lock);
1243 return ret;
1244
1245exit:
1246 mutex_unlock(&common->lock);
1247streamoff_exit:
1248 ret = videobuf_streamoff(&common->buffer_queue);
1249 return ret;
1250}
1251
1252/**
1253 * vpif_streamoff() - streamoff handler
1254 * @file: file ptr
1255 * @priv: file handle
1256 * @buftype: v4l2 buffer type
1257 */
1258static int vpif_streamoff(struct file *file, void *priv,
1259 enum v4l2_buf_type buftype)
1260{
1261
1262 struct vpif_fh *fh = priv;
1263 struct channel_obj *ch = fh->channel;
1264 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1265 int ret;
1266
1267 vpif_dbg(2, debug, "vpif_streamoff\n");
1268
1269 if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1270 vpif_dbg(1, debug, "buffer type not supported\n");
1271 return -EINVAL;
1272 }
1273
1274 /* If io is allowed for this file handle, return error */
1275 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1276 vpif_dbg(1, debug, "io not allowed\n");
1277 return -EACCES;
1278 }
1279
1280 /* If streaming is not started, return error */
1281 if (!common->started) {
1282 vpif_dbg(1, debug, "channel->started\n");
1283 return -EINVAL;
1284 }
1285
1286 if (mutex_lock_interruptible(&common->lock))
1287 return -ERESTARTSYS;
1288
1289 /* disable channel */
1290 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
1291 enable_channel0(0);
1292 channel0_intr_enable(0);
1293 } else {
1294 enable_channel1(0);
1295 channel1_intr_enable(0);
1296 }
1297
1298 common->started = 0;
1299
1300 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1301 s_stream, 0);
1302
1303 if (ret && (ret != -ENOIOCTLCMD))
1304 vpif_dbg(1, debug, "stream off failed in subdev\n");
1305
1306 mutex_unlock(&common->lock);
1307
1308 return videobuf_streamoff(&common->buffer_queue);
1309}
1310
1311/**
1312 * vpif_map_sub_device_to_input() - Maps sub device to input
1313 * @ch - ptr to channel
1314 * @config - ptr to capture configuration
1315 * @input_index - Given input index from application
1316 * @sub_device_index - index into sd table
1317 *
1318 * lookup the sub device information for a given input index.
1319 * we report all the inputs to application. inputs table also
1320 * has sub device name for the each input
1321 */
1322static struct vpif_subdev_info *vpif_map_sub_device_to_input(
1323 struct channel_obj *ch,
1324 struct vpif_capture_config *vpif_cfg,
1325 int input_index,
1326 int *sub_device_index)
1327{
1328 struct vpif_capture_chan_config *chan_cfg;
1329 struct vpif_subdev_info *subdev_info = NULL;
1330 const char *subdev_name = NULL;
1331 int i;
1332
1333 vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n");
1334
1335 chan_cfg = &vpif_cfg->chan_config[ch->channel_id];
1336
1337 /**
1338 * search through the inputs to find the sub device supporting
1339 * the input
1340 */
1341 for (i = 0; i < chan_cfg->input_count; i++) {
1342 /* For each sub device, loop through input */
1343 if (i == input_index) {
1344 subdev_name = chan_cfg->inputs[i].subdev_name;
1345 break;
1346 }
1347 }
1348
1349 /* if reached maximum. return null */
1350 if (i == chan_cfg->input_count || (NULL == subdev_name))
1351 return subdev_info;
1352
1353 /* loop through the sub device list to get the sub device info */
1354 for (i = 0; i < vpif_cfg->subdev_count; i++) {
1355 subdev_info = &vpif_cfg->subdev_info[i];
1356 if (!strcmp(subdev_info->name, subdev_name))
1357 break;
1358 }
1359
1360 if (i == vpif_cfg->subdev_count)
1361 return subdev_info;
1362
1363 /* check if the sub device is registered */
1364 if (NULL == vpif_obj.sd[i])
1365 return NULL;
1366
1367 *sub_device_index = i;
1368 return subdev_info;
1369}
1370
1371/**
1372 * vpif_querystd() - querystd handler
1373 * @file: file ptr
1374 * @priv: file handle
1375 * @std_id: ptr to std id
1376 *
1377 * This function is called to detect standard at the selected input
1378 */
1379static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
1380{
1381 struct vpif_fh *fh = priv;
1382 struct channel_obj *ch = fh->channel;
1383 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1384 int ret = 0;
1385
1386 vpif_dbg(2, debug, "vpif_querystd\n");
1387
1388 if (mutex_lock_interruptible(&common->lock))
1389 return -ERESTARTSYS;
1390
1391 /* Call querystd function of decoder device */
1392 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1393 querystd, std_id);
1394 if (ret < 0)
1395 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1396
1397 mutex_unlock(&common->lock);
1398 return ret;
1399}
1400
1401/**
1402 * vpif_g_std() - get STD handler
1403 * @file: file ptr
1404 * @priv: file handle
1405 * @std_id: ptr to std id
1406 */
1407static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
1408{
1409 struct vpif_fh *fh = priv;
1410 struct channel_obj *ch = fh->channel;
1411
1412 vpif_dbg(2, debug, "vpif_g_std\n");
1413
1414 *std = ch->video.stdid;
1415 return 0;
1416}
1417
1418/**
1419 * vpif_s_std() - set STD handler
1420 * @file: file ptr
1421 * @priv: file handle
1422 * @std_id: ptr to std id
1423 */
1424static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1425{
1426 struct vpif_fh *fh = priv;
1427 struct channel_obj *ch = fh->channel;
1428 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1429 int ret = 0;
1430
1431 vpif_dbg(2, debug, "vpif_s_std\n");
1432
1433 if (common->started) {
1434 vpif_err("streaming in progress\n");
1435 return -EBUSY;
1436 }
1437
1438 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1439 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1440 if (!fh->initialized) {
1441 vpif_dbg(1, debug, "Channel Busy\n");
1442 return -EBUSY;
1443 }
1444 }
1445
1446 ret = v4l2_prio_check(&ch->prio, &fh->prio);
1447 if (0 != ret)
1448 return ret;
1449
1450 fh->initialized = 1;
1451
1452 /* Call encoder subdevice function to set the standard */
1453 if (mutex_lock_interruptible(&common->lock))
1454 return -ERESTARTSYS;
1455
1456 ch->video.stdid = *std_id;
1457
1458 /* Get the information about the standard */
1459 if (vpif_update_std_info(ch)) {
1460 ret = -EINVAL;
1461 vpif_err("Error getting the standard info\n");
1462 goto s_std_exit;
1463 }
1464
1465 /* Configure the default format information */
1466 vpif_config_format(ch);
1467
1468 /* set standard in the sub device */
1469 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
1470 s_std, *std_id);
1471 if (ret < 0)
1472 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1473
1474s_std_exit:
1475 mutex_unlock(&common->lock);
1476 return ret;
1477}
1478
1479/**
1480 * vpif_enum_input() - ENUMINPUT handler
1481 * @file: file ptr
1482 * @priv: file handle
1483 * @input: ptr to input structure
1484 */
1485static int vpif_enum_input(struct file *file, void *priv,
1486 struct v4l2_input *input)
1487{
1488
1489 struct vpif_capture_config *config = vpif_dev->platform_data;
1490 struct vpif_capture_chan_config *chan_cfg;
1491 struct vpif_fh *fh = priv;
1492 struct channel_obj *ch = fh->channel;
1493
1494 chan_cfg = &config->chan_config[ch->channel_id];
1495
1496 if (input->index >= chan_cfg->input_count) {
1497 vpif_dbg(1, debug, "Invalid input index\n");
1498 return -EINVAL;
1499 }
1500
1501 memcpy(input, &chan_cfg->inputs[input->index].input,
1502 sizeof(*input));
1503 return 0;
1504}
1505
1506/**
1507 * vpif_g_input() - Get INPUT handler
1508 * @file: file ptr
1509 * @priv: file handle
1510 * @index: ptr to input index
1511 */
1512static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
1513{
1514 struct vpif_fh *fh = priv;
1515 struct channel_obj *ch = fh->channel;
1516 struct video_obj *vid_ch = &ch->video;
1517
1518 *index = vid_ch->input_idx;
1519
1520 return 0;
1521}
1522
1523/**
1524 * vpif_s_input() - Set INPUT handler
1525 * @file: file ptr
1526 * @priv: file handle
1527 * @index: input index
1528 */
1529static int vpif_s_input(struct file *file, void *priv, unsigned int index)
1530{
1531 struct vpif_capture_config *config = vpif_dev->platform_data;
1532 struct vpif_capture_chan_config *chan_cfg;
1533 struct vpif_fh *fh = priv;
1534 struct channel_obj *ch = fh->channel;
1535 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1536 struct video_obj *vid_ch = &ch->video;
1537 struct vpif_subdev_info *subdev_info;
1538 int ret = 0, sd_index = 0;
1539 u32 input = 0, output = 0;
1540
1541 chan_cfg = &config->chan_config[ch->channel_id];
1542
1543 if (common->started) {
1544 vpif_err("Streaming in progress\n");
1545 return -EBUSY;
1546 }
1547
1548 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1549 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1550 if (!fh->initialized) {
1551 vpif_dbg(1, debug, "Channel Busy\n");
1552 return -EBUSY;
1553 }
1554 }
1555
1556 ret = v4l2_prio_check(&ch->prio, &fh->prio);
1557 if (0 != ret)
1558 return ret;
1559
1560 fh->initialized = 1;
1561 subdev_info = vpif_map_sub_device_to_input(ch, config, index,
1562 &sd_index);
1563 if (NULL == subdev_info) {
1564 vpif_dbg(1, debug,
1565 "couldn't lookup sub device for the input index\n");
1566 return -EINVAL;
1567 }
1568
1569 if (mutex_lock_interruptible(&common->lock))
1570 return -ERESTARTSYS;
1571
1572 /* first setup input path from sub device to vpif */
1573 if (config->setup_input_path) {
1574 ret = config->setup_input_path(ch->channel_id,
1575 subdev_info->name);
1576 if (ret < 0) {
1577 vpif_dbg(1, debug, "couldn't setup input path for the"
1578 " sub device %s, for input index %d\n",
1579 subdev_info->name, index);
1580 goto exit;
1581 }
1582 }
1583
1584 if (subdev_info->can_route) {
1585 input = subdev_info->input;
1586 output = subdev_info->output;
1587 ret = v4l2_subdev_call(vpif_obj.sd[sd_index], video, s_routing,
1588 input, output, 0);
1589 if (ret < 0) {
1590 vpif_dbg(1, debug, "Failed to set input\n");
1591 goto exit;
1592 }
1593 }
1594 vid_ch->input_idx = index;
1595 ch->curr_subdev_info = subdev_info;
1596 ch->curr_sd_index = sd_index;
1597 /* copy interface parameters to vpif */
1598 ch->vpifparams.iface = subdev_info->vpif_if;
1599
1600 /* update tvnorms from the sub device input info */
1601 ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
1602
1603exit:
1604 mutex_unlock(&common->lock);
1605 return ret;
1606}
1607
1608/**
1609 * vpif_enum_fmt_vid_cap() - ENUM_FMT handler
1610 * @file: file ptr
1611 * @priv: file handle
1612 * @index: input index
1613 */
1614static int vpif_enum_fmt_vid_cap(struct file *file, void *priv,
1615 struct v4l2_fmtdesc *fmt)
1616{
1617 struct vpif_fh *fh = priv;
1618 struct channel_obj *ch = fh->channel;
1619
1620 if (fmt->index != 0) {
1621 vpif_dbg(1, debug, "Invalid format index\n");
1622 return -EINVAL;
1623 }
1624
1625 /* Fill in the information about format */
1626 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) {
1627 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1628 strcpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb");
1629 fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
1630 } else {
1631 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1632 strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
1633 fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
1634 }
1635 return 0;
1636}
1637
1638/**
1639 * vpif_try_fmt_vid_cap() - TRY_FMT handler
1640 * @file: file ptr
1641 * @priv: file handle
1642 * @fmt: ptr to v4l2 format structure
1643 */
1644static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
1645 struct v4l2_format *fmt)
1646{
1647 struct vpif_fh *fh = priv;
1648 struct channel_obj *ch = fh->channel;
1649 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
1650
1651 return vpif_check_format(ch, pixfmt, 1);
1652}
1653
1654
1655/**
1656 * vpif_g_fmt_vid_cap() - Set INPUT handler
1657 * @file: file ptr
1658 * @priv: file handle
1659 * @fmt: ptr to v4l2 format structure
1660 */
1661static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
1662 struct v4l2_format *fmt)
1663{
1664 struct vpif_fh *fh = priv;
1665 struct channel_obj *ch = fh->channel;
1666 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1667
1668 /* Check the validity of the buffer type */
1669 if (common->fmt.type != fmt->type)
1670 return -EINVAL;
1671
1672 /* Fill in the information about format */
1673 if (mutex_lock_interruptible(&common->lock))
1674 return -ERESTARTSYS;
1675
1676 *fmt = common->fmt;
1677 mutex_unlock(&common->lock);
1678 return 0;
1679}
1680
1681/**
1682 * vpif_s_fmt_vid_cap() - Set FMT handler
1683 * @file: file ptr
1684 * @priv: file handle
1685 * @fmt: ptr to v4l2 format structure
1686 */
1687static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
1688 struct v4l2_format *fmt)
1689{
1690 struct vpif_fh *fh = priv;
1691 struct channel_obj *ch = fh->channel;
1692 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1693 struct v4l2_pix_format *pixfmt;
1694 int ret = 0;
1695
1696 vpif_dbg(2, debug, "VIDIOC_S_FMT\n");
1697
1698 /* If streaming is started, return error */
1699 if (common->started) {
1700 vpif_dbg(1, debug, "Streaming is started\n");
1701 return -EBUSY;
1702 }
1703
1704 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1705 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1706 if (!fh->initialized) {
1707 vpif_dbg(1, debug, "Channel Busy\n");
1708 return -EBUSY;
1709 }
1710 }
1711
1712 ret = v4l2_prio_check(&ch->prio, &fh->prio);
1713 if (0 != ret)
1714 return ret;
1715
1716 fh->initialized = 1;
1717
1718 pixfmt = &fmt->fmt.pix;
1719 /* Check for valid field format */
1720 ret = vpif_check_format(ch, pixfmt, 0);
1721
1722 if (ret)
1723 return ret;
1724 /* store the format in the channel object */
1725 if (mutex_lock_interruptible(&common->lock))
1726 return -ERESTARTSYS;
1727
1728 common->fmt = *fmt;
1729 mutex_unlock(&common->lock);
1730
1731 return 0;
1732}
1733
1734/**
1735 * vpif_querycap() - QUERYCAP handler
1736 * @file: file ptr
1737 * @priv: file handle
1738 * @cap: ptr to v4l2_capability structure
1739 */
1740static int vpif_querycap(struct file *file, void *priv,
1741 struct v4l2_capability *cap)
1742{
1743 struct vpif_capture_config *config = vpif_dev->platform_data;
1744
1745 cap->version = VPIF_CAPTURE_VERSION_CODE;
1746 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1747 strlcpy(cap->driver, "vpif capture", sizeof(cap->driver));
1748 strlcpy(cap->bus_info, "DM646x Platform", sizeof(cap->bus_info));
1749 strlcpy(cap->card, config->card_name, sizeof(cap->card));
1750
1751 return 0;
1752}
1753
1754/**
1755 * vpif_g_priority() - get priority handler
1756 * @file: file ptr
1757 * @priv: file handle
1758 * @prio: ptr to v4l2_priority structure
1759 */
1760static int vpif_g_priority(struct file *file, void *priv,
1761 enum v4l2_priority *prio)
1762{
1763 struct vpif_fh *fh = priv;
1764 struct channel_obj *ch = fh->channel;
1765
1766 *prio = v4l2_prio_max(&ch->prio);
1767
1768 return 0;
1769}
1770
1771/**
1772 * vpif_s_priority() - set priority handler
1773 * @file: file ptr
1774 * @priv: file handle
1775 * @prio: ptr to v4l2_priority structure
1776 */
1777static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
1778{
1779 struct vpif_fh *fh = priv;
1780 struct channel_obj *ch = fh->channel;
1781
1782 return v4l2_prio_change(&ch->prio, &fh->prio, p);
1783}
1784
1785/**
1786 * vpif_cropcap() - cropcap handler
1787 * @file: file ptr
1788 * @priv: file handle
1789 * @crop: ptr to v4l2_cropcap structure
1790 */
1791static int vpif_cropcap(struct file *file, void *priv,
1792 struct v4l2_cropcap *crop)
1793{
1794 struct vpif_fh *fh = priv;
1795 struct channel_obj *ch = fh->channel;
1796 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1797
1798 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type)
1799 return -EINVAL;
1800
1801 crop->bounds.left = 0;
1802 crop->bounds.top = 0;
1803 crop->bounds.height = common->height;
1804 crop->bounds.width = common->width;
1805 crop->defrect = crop->bounds;
1806 return 0;
1807}
1808
1809/* vpif capture ioctl operations */
1810static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
1811 .vidioc_querycap = vpif_querycap,
1812 .vidioc_g_priority = vpif_g_priority,
1813 .vidioc_s_priority = vpif_s_priority,
1814 .vidioc_enum_fmt_vid_cap = vpif_enum_fmt_vid_cap,
1815 .vidioc_g_fmt_vid_cap = vpif_g_fmt_vid_cap,
1816 .vidioc_s_fmt_vid_cap = vpif_s_fmt_vid_cap,
1817 .vidioc_try_fmt_vid_cap = vpif_try_fmt_vid_cap,
1818 .vidioc_enum_input = vpif_enum_input,
1819 .vidioc_s_input = vpif_s_input,
1820 .vidioc_g_input = vpif_g_input,
1821 .vidioc_reqbufs = vpif_reqbufs,
1822 .vidioc_querybuf = vpif_querybuf,
1823 .vidioc_querystd = vpif_querystd,
1824 .vidioc_s_std = vpif_s_std,
1825 .vidioc_g_std = vpif_g_std,
1826 .vidioc_qbuf = vpif_qbuf,
1827 .vidioc_dqbuf = vpif_dqbuf,
1828 .vidioc_streamon = vpif_streamon,
1829 .vidioc_streamoff = vpif_streamoff,
1830 .vidioc_cropcap = vpif_cropcap,
1831};
1832
1833/* vpif file operations */
1834static struct v4l2_file_operations vpif_fops = {
1835 .owner = THIS_MODULE,
1836 .open = vpif_open,
1837 .release = vpif_release,
1838 .ioctl = video_ioctl2,
1839 .mmap = vpif_mmap,
1840 .poll = vpif_poll
1841};
1842
1843/* vpif video template */
1844static struct video_device vpif_video_template = {
1845 .name = "vpif",
1846 .fops = &vpif_fops,
1847 .minor = -1,
1848 .ioctl_ops = &vpif_ioctl_ops,
1849};
1850
1851/**
1852 * initialize_vpif() - Initialize vpif data structures
1853 *
1854 * Allocate memory for data structures and initialize them
1855 */
1856static int initialize_vpif(void)
1857{
1858 int err = 0, i, j;
1859 int free_channel_objects_index;
1860
1861 /* Default number of buffers should be 3 */
1862 if ((ch0_numbuffers > 0) &&
1863 (ch0_numbuffers < config_params.min_numbuffers))
1864 ch0_numbuffers = config_params.min_numbuffers;
1865 if ((ch1_numbuffers > 0) &&
1866 (ch1_numbuffers < config_params.min_numbuffers))
1867 ch1_numbuffers = config_params.min_numbuffers;
1868
1869 /* Set buffer size to min buffers size if it is invalid */
1870 if (ch0_bufsize < config_params.min_bufsize[VPIF_CHANNEL0_VIDEO])
1871 ch0_bufsize =
1872 config_params.min_bufsize[VPIF_CHANNEL0_VIDEO];
1873 if (ch1_bufsize < config_params.min_bufsize[VPIF_CHANNEL1_VIDEO])
1874 ch1_bufsize =
1875 config_params.min_bufsize[VPIF_CHANNEL1_VIDEO];
1876
1877 config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = ch0_numbuffers;
1878 config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = ch1_numbuffers;
1879 if (ch0_numbuffers) {
1880 config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO]
1881 = ch0_bufsize;
1882 }
1883 if (ch1_numbuffers) {
1884 config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO]
1885 = ch1_bufsize;
1886 }
1887
1888 /* Allocate memory for six channel objects */
1889 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1890 vpif_obj.dev[i] =
1891 kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);
1892 /* If memory allocation fails, return error */
1893 if (!vpif_obj.dev[i]) {
1894 free_channel_objects_index = i;
1895 err = -ENOMEM;
1896 goto vpif_init_free_channel_objects;
1897 }
1898 }
1899 return 0;
1900
1901vpif_init_free_channel_objects:
1902 for (j = 0; j < free_channel_objects_index; j++)
1903 kfree(vpif_obj.dev[j]);
1904 return err;
1905}
1906
1907/**
1908 * vpif_probe : This function probes the vpif capture driver
1909 * @pdev: platform device pointer
1910 *
1911 * This creates device entries by register itself to the V4L2 driver and
1912 * initializes fields of each channel objects
1913 */
1914static __init int vpif_probe(struct platform_device *pdev)
1915{
1916 struct vpif_subdev_info *subdevdata;
1917 struct vpif_capture_config *config;
1918 int i, j, k, m, q, err;
1919 struct i2c_adapter *i2c_adap;
1920 struct channel_obj *ch;
1921 struct common_obj *common;
1922 struct video_device *vfd;
1923 struct resource *res;
1924 int subdev_count;
1925
1926 vpif_dev = &pdev->dev;
1927
1928 err = initialize_vpif();
1929 if (err) {
1930 v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
1931 return err;
1932 }
1933
1934 k = 0;
1935 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
1936 for (i = res->start; i <= res->end; i++) {
1937 if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
1938 "DM646x_Capture",
1939 (void *)(&vpif_obj.dev[k]->channel_id))) {
1940 err = -EBUSY;
1941 i--;
1942 goto vpif_int_err;
1943 }
1944 }
1945 k++;
1946 }
1947
1948 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1949 /* Get the pointer to the channel object */
1950 ch = vpif_obj.dev[i];
1951 /* Allocate memory for video device */
1952 vfd = video_device_alloc();
1953 if (NULL == vfd) {
1954 for (j = 0; j < i; j++) {
1955 ch = vpif_obj.dev[j];
1956 video_device_release(ch->video_dev);
1957 }
1958 err = -ENOMEM;
1959 goto vpif_dev_alloc_err;
1960 }
1961
1962 /* Initialize field of video device */
1963 *vfd = vpif_video_template;
1964 vfd->v4l2_dev = &vpif_obj.v4l2_dev;
1965 vfd->release = video_device_release;
1966 snprintf(vfd->name, sizeof(vfd->name),
1967 "DM646x_VPIFCapture_DRIVER_V%d.%d.%d",
1968 (VPIF_CAPTURE_VERSION_CODE >> 16) & 0xff,
1969 (VPIF_CAPTURE_VERSION_CODE >> 8) & 0xff,
1970 (VPIF_CAPTURE_VERSION_CODE) & 0xff);
1971 /* Set video_dev to the video device */
1972 ch->video_dev = vfd;
1973 }
1974
1975 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
1976 ch = vpif_obj.dev[j];
1977 ch->channel_id = j;
1978 common = &(ch->common[VPIF_VIDEO_INDEX]);
1979 spin_lock_init(&common->irqlock);
1980 mutex_init(&common->lock);
1981 /* Initialize prio member of channel object */
1982 v4l2_prio_init(&ch->prio);
1983 err = video_register_device(ch->video_dev,
1984 VFL_TYPE_GRABBER, (j ? 1 : 0));
1985 if (err)
1986 goto probe_out;
1987
1988 video_set_drvdata(ch->video_dev, ch);
1989
1990 }
1991
1992 i2c_adap = i2c_get_adapter(1);
1993 config = pdev->dev.platform_data;
1994
1995 subdev_count = config->subdev_count;
1996 vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count,
1997 GFP_KERNEL);
1998 if (vpif_obj.sd == NULL) {
1999 vpif_err("unable to allocate memory for subdevice pointers\n");
2000 err = -ENOMEM;
2001 goto probe_out;
2002 }
2003
2004 err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
2005 if (err) {
2006 v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
2007 goto probe_subdev_out;
2008 }
2009
2010 for (i = 0; i < subdev_count; i++) {
2011 subdevdata = &config->subdev_info[i];
2012 vpif_obj.sd[i] =
2013 v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
2014 i2c_adap,
2015 subdevdata->name,
2016 &subdevdata->board_info,
2017 NULL);
2018
2019 if (!vpif_obj.sd[i]) {
2020 vpif_err("Error registering v4l2 subdevice\n");
2021 goto probe_subdev_out;
2022 }
2023 v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
2024 subdevdata->name);
2025
2026 if (vpif_obj.sd[i])
2027 vpif_obj.sd[i]->grp_id = 1 << i;
2028 }
2029 v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF Capture driver"
2030 " initialized\n");
2031
2032 return 0;
2033
2034probe_subdev_out:
2035 /* free sub devices memory */
2036 kfree(vpif_obj.sd);
2037
2038 j = VPIF_CAPTURE_MAX_DEVICES;
2039probe_out:
2040 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2041 for (k = 0; k < j; k++) {
2042 /* Get the pointer to the channel object */
2043 ch = vpif_obj.dev[k];
2044 /* Unregister video device */
2045 video_unregister_device(ch->video_dev);
2046 }
2047
2048vpif_dev_alloc_err:
2049 k = VPIF_CAPTURE_MAX_DEVICES-1;
2050 res = platform_get_resource(pdev, IORESOURCE_IRQ, k);
2051 i = res->end;
2052
2053vpif_int_err:
2054 for (q = k; q >= 0; q--) {
2055 for (m = i; m >= (int)res->start; m--)
2056 free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));
2057
2058 res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
2059 if (res)
2060 i = res->end;
2061 }
2062 return err;
2063}
2064
2065/**
2066 * vpif_remove() - driver remove handler
2067 * @device: ptr to platform device structure
2068 *
2069 * The vidoe device is unregistered
2070 */
2071static int vpif_remove(struct platform_device *device)
2072{
2073 int i;
2074 struct channel_obj *ch;
2075
2076 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2077
2078 /* un-register device */
2079 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2080 /* Get the pointer to the channel object */
2081 ch = vpif_obj.dev[i];
2082 /* Unregister video device */
2083 video_unregister_device(ch->video_dev);
2084 }
2085 return 0;
2086}
2087
2088/**
2089 * vpif_suspend: vpif device suspend
2090 *
2091 * TODO: Add suspend code here
2092 */
2093static int
2094vpif_suspend(struct device *dev)
2095{
2096 return -1;
2097}
2098
2099/**
2100 * vpif_resume: vpif device suspend
2101 *
2102 * TODO: Add resume code here
2103 */
2104static int
2105vpif_resume(struct device *dev)
2106{
2107 return -1;
2108}
2109
2110static struct dev_pm_ops vpif_dev_pm_ops = {
2111 .suspend = vpif_suspend,
2112 .resume = vpif_resume,
2113};
2114
2115static struct platform_driver vpif_driver = {
2116 .driver = {
2117 .name = "vpif_capture",
2118 .owner = THIS_MODULE,
2119 .pm = &vpif_dev_pm_ops,
2120 },
2121 .probe = vpif_probe,
2122 .remove = vpif_remove,
2123};
2124
2125/**
2126 * vpif_init: initialize the vpif driver
2127 *
2128 * This function registers device and driver to the kernel, requests irq
2129 * handler and allocates memory
2130 * for channel objects
2131 */
2132static __init int vpif_init(void)
2133{
2134 return platform_driver_register(&vpif_driver);
2135}
2136
2137/**
2138 * vpif_cleanup : This function clean up the vpif capture resources
2139 *
2140 * This will un-registers device and driver to the kernel, frees
2141 * requested irq handler and de-allocates memory allocated for channel
2142 * objects.
2143 */
2144static void vpif_cleanup(void)
2145{
2146 struct platform_device *pdev;
2147 struct resource *res;
2148 int irq_num;
2149 int i = 0;
2150
2151 pdev = container_of(vpif_dev, struct platform_device, dev);
2152 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
2153 for (irq_num = res->start; irq_num <= res->end; irq_num++)
2154 free_irq(irq_num,
2155 (void *)(&vpif_obj.dev[i]->channel_id));
2156 i++;
2157 }
2158
2159 platform_driver_unregister(&vpif_driver);
2160
2161 kfree(vpif_obj.sd);
2162 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
2163 kfree(vpif_obj.dev[i]);
2164}
2165
2166/* Function for module initialization and cleanup */
2167module_init(vpif_init);
2168module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/video/davinci/vpif_capture.h
new file mode 100644
index 000000000000..4e12ec8cac6f
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_capture.h
@@ -0,0 +1,165 @@
1/*
2 * Copyright (C) 2009 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; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#ifndef VPIF_CAPTURE_H
20#define VPIF_CAPTURE_H
21
22#ifdef __KERNEL__
23
24/* Header files */
25#include <linux/videodev2.h>
26#include <linux/version.h>
27#include <media/v4l2-common.h>
28#include <media/v4l2-device.h>
29#include <media/videobuf-core.h>
30#include <media/videobuf-dma-contig.h>
31#include <mach/dm646x.h>
32
33#include "vpif.h"
34
35/* Macros */
36#define VPIF_MAJOR_RELEASE 0
37#define VPIF_MINOR_RELEASE 0
38#define VPIF_BUILD 1
39#define VPIF_CAPTURE_VERSION_CODE ((VPIF_MAJOR_RELEASE << 16) | \
40 (VPIF_MINOR_RELEASE << 8) | VPIF_BUILD)
41
42#define VPIF_VALID_FIELD(field) (((V4L2_FIELD_ANY == field) || \
43 (V4L2_FIELD_NONE == field)) || \
44 (((V4L2_FIELD_INTERLACED == field) || \
45 (V4L2_FIELD_SEQ_TB == field)) || \
46 (V4L2_FIELD_SEQ_BT == field)))
47
48#define VPIF_CAPTURE_MAX_DEVICES 2
49#define VPIF_VIDEO_INDEX 0
50#define VPIF_NUMBER_OF_OBJECTS 1
51
52/* Enumerated data type to give id to each device per channel */
53enum vpif_channel_id {
54 VPIF_CHANNEL0_VIDEO = 0,
55 VPIF_CHANNEL1_VIDEO,
56};
57
58struct video_obj {
59 enum v4l2_field buf_field;
60 /* Currently selected or default standard */
61 v4l2_std_id stdid;
62 /* This is to track the last input that is passed to application */
63 u32 input_idx;
64};
65
66struct common_obj {
67 /* Pointer pointing to current v4l2_buffer */
68 struct videobuf_buffer *cur_frm;
69 /* Pointer pointing to current v4l2_buffer */
70 struct videobuf_buffer *next_frm;
71 /*
72 * This field keeps track of type of buffer exchange mechanism
73 * user has selected
74 */
75 enum v4l2_memory memory;
76 /* Used to store pixel format */
77 struct v4l2_format fmt;
78 /* Buffer queue used in video-buf */
79 struct videobuf_queue buffer_queue;
80 /* Queue of filled frames */
81 struct list_head dma_queue;
82 /* Used in video-buf */
83 spinlock_t irqlock;
84 /* lock used to access this structure */
85 struct mutex lock;
86 /* number of users performing IO */
87 u32 io_usrs;
88 /* Indicates whether streaming started */
89 u8 started;
90 /* Function pointer to set the addresses */
91 void (*set_addr) (unsigned long, unsigned long, unsigned long,
92 unsigned long);
93 /* offset where Y top starts from the starting of the buffer */
94 u32 ytop_off;
95 /* offset where Y bottom starts from the starting of the buffer */
96 u32 ybtm_off;
97 /* offset where C top starts from the starting of the buffer */
98 u32 ctop_off;
99 /* offset where C bottom starts from the starting of the buffer */
100 u32 cbtm_off;
101 /* Indicates width of the image data */
102 u32 width;
103 /* Indicates height of the image data */
104 u32 height;
105};
106
107struct channel_obj {
108 /* Identifies video device for this channel */
109 struct video_device *video_dev;
110 /* Used to keep track of state of the priority */
111 struct v4l2_prio_state prio;
112 /* number of open instances of the channel */
113 int usrs;
114 /* Indicates id of the field which is being displayed */
115 u32 field_id;
116 /* flag to indicate whether decoder is initialized */
117 u8 initialized;
118 /* Identifies channel */
119 enum vpif_channel_id channel_id;
120 /* index into sd table */
121 int curr_sd_index;
122 /* ptr to current sub device information */
123 struct vpif_subdev_info *curr_subdev_info;
124 /* vpif configuration params */
125 struct vpif_params vpifparams;
126 /* common object array */
127 struct common_obj common[VPIF_NUMBER_OF_OBJECTS];
128 /* video object */
129 struct video_obj video;
130};
131
132/* File handle structure */
133struct vpif_fh {
134 /* pointer to channel object for opened device */
135 struct channel_obj *channel;
136 /* Indicates whether this file handle is doing IO */
137 u8 io_allowed[VPIF_NUMBER_OF_OBJECTS];
138 /* Used to keep track priority of this instance */
139 enum v4l2_priority prio;
140 /* Used to indicate channel is initialize or not */
141 u8 initialized;
142};
143
144struct vpif_device {
145 struct v4l2_device v4l2_dev;
146 struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
147 struct v4l2_subdev **sd;
148};
149
150struct vpif_config_params {
151 u8 min_numbuffers;
152 u8 numbuffers[VPIF_CAPTURE_NUM_CHANNELS];
153 s8 device_type;
154 u32 min_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
155 u32 channel_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
156 u8 default_device[VPIF_CAPTURE_NUM_CHANNELS];
157 u8 max_device_type;
158};
159/* Struct which keeps track of the line numbers for the sliced vbi service */
160struct vpif_service_line {
161 u16 service_id;
162 u16 service_line[2];
163};
164#endif /* End of __KERNEL__ */
165#endif /* VPIF_CAPTURE_H */