• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/cx25821/
1/*
2 *  Driver for the Conexant CX25821 PCIe bridge
3 *
4 *  Copyright (C) 2009 Conexant Systems Inc.
5 *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *  Parts adapted/taken from Eduardo Moscoso Rubino
8 *  Copyright (C) 2009 Eduardo Moscoso Rubino <moscoso@TopoLogica.com>
9 *
10 *
11 *  This program is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License as published by
13 *  the Free Software Foundation; either version 2 of the License, or
14 *  (at your option) any later version.
15 *
16 *  This program is distributed in the hope that it will be useful,
17 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 *
20 *  GNU General Public License for more details.
21 *
22 *  You should have received a copy of the GNU General Public License
23 *  along with this program; if not, write to the Free Software
24 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include "cx25821-video.h"
28
29MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
30MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
31MODULE_LICENSE("GPL");
32
33static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
34static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
35
36module_param_array(video_nr, int, NULL, 0444);
37module_param_array(radio_nr, int, NULL, 0444);
38
39MODULE_PARM_DESC(video_nr, "video device numbers");
40MODULE_PARM_DESC(radio_nr, "radio device numbers");
41
42static unsigned int video_debug = VIDEO_DEBUG;
43module_param(video_debug, int, 0644);
44MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
45
46static unsigned int irq_debug;
47module_param(irq_debug, int, 0644);
48MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
49
50unsigned int vid_limit = 16;
51module_param(vid_limit, int, 0644);
52MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
53
54static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num);
55
56static const struct v4l2_file_operations video_fops;
57static const struct v4l2_ioctl_ops video_ioctl_ops;
58
59#define FORMAT_FLAGS_PACKED       0x01
60
61struct cx25821_fmt formats[] = {
62	{
63		.name = "8 bpp, gray",
64		.fourcc = V4L2_PIX_FMT_GREY,
65		.depth = 8,
66		.flags = FORMAT_FLAGS_PACKED,
67	 }, {
68		.name = "4:1:1, packed, Y41P",
69		.fourcc = V4L2_PIX_FMT_Y41P,
70		.depth = 12,
71		.flags = FORMAT_FLAGS_PACKED,
72	}, {
73		.name = "4:2:2, packed, YUYV",
74		.fourcc = V4L2_PIX_FMT_YUYV,
75		.depth = 16,
76		.flags = FORMAT_FLAGS_PACKED,
77	}, {
78		.name = "4:2:2, packed, UYVY",
79		.fourcc = V4L2_PIX_FMT_UYVY,
80		.depth = 16,
81		.flags = FORMAT_FLAGS_PACKED,
82	}, {
83		.name = "4:2:0, YUV",
84		.fourcc = V4L2_PIX_FMT_YUV420,
85		.depth = 12,
86		.flags = FORMAT_FLAGS_PACKED,
87	},
88};
89
90int cx25821_get_format_size(void)
91{
92	return ARRAY_SIZE(formats);
93}
94
95struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
96{
97	unsigned int i;
98
99	if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P) {
100		return formats + 1;
101	}
102
103	for (i = 0; i < ARRAY_SIZE(formats); i++)
104		if (formats[i].fourcc == fourcc)
105			return formats + i;
106
107	printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
108	return NULL;
109}
110
111void cx25821_dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q)
112{
113	struct cx25821_buffer *buf;
114	struct list_head *item;
115	dprintk(1, "%s()\n", __func__);
116
117	if (!list_empty(&q->active)) {
118		list_for_each(item, &q->active)
119		    buf = list_entry(item, struct cx25821_buffer, vb.queue);
120	}
121
122	if (!list_empty(&q->queued)) {
123		list_for_each(item, &q->queued)
124		    buf = list_entry(item, struct cx25821_buffer, vb.queue);
125	}
126
127}
128
129void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
130			  u32 count)
131{
132	struct cx25821_buffer *buf;
133	int bc;
134
135	for (bc = 0;; bc++) {
136		if (list_empty(&q->active)) {
137			dprintk(1, "bc=%d (=0: active empty)\n", bc);
138			break;
139		}
140
141		buf =
142		    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
143
144		/* count comes from the hw and it is 16bit wide --
145		 * this trick handles wrap-arounds correctly for
146		 * up to 32767 buffers in flight... */
147		if ((s16) (count - buf->count) < 0) {
148			break;
149		}
150
151		do_gettimeofday(&buf->vb.ts);
152		buf->vb.state = VIDEOBUF_DONE;
153		list_del(&buf->vb.queue);
154		wake_up(&buf->vb.done);
155	}
156
157	if (list_empty(&q->active))
158		del_timer(&q->timeout);
159	else
160		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
161	if (bc != 1)
162		printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
163		       __func__, bc);
164}
165
166#ifdef TUNER_FLAG
167int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
168{
169	dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__,
170		(unsigned int)norm, v4l2_norm_to_name(norm));
171
172	dev->tvnorm = norm;
173
174	/* Tell the internal A/V decoder */
175	cx25821_call_all(dev, core, s_std, norm);
176
177	return 0;
178}
179#endif
180
181struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
182				       struct pci_dev *pci,
183				       struct video_device *template,
184				       char *type)
185{
186	struct video_device *vfd;
187	dprintk(1, "%s()\n", __func__);
188
189	vfd = video_device_alloc();
190	if (NULL == vfd)
191		return NULL;
192	*vfd = *template;
193	vfd->v4l2_dev = &dev->v4l2_dev;
194	vfd->release = video_device_release;
195	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type,
196		 cx25821_boards[dev->board].name);
197	video_set_drvdata(vfd, dev);
198	return vfd;
199}
200
201/*
202static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
203{
204    int i;
205
206    if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
207	return -EINVAL;
208    for (i = 0; i < CX25821_CTLS; i++)
209	if (cx25821_ctls[i].v.id == qctrl->id)
210	    break;
211    if (i == CX25821_CTLS) {
212	*qctrl = no_ctl;
213	return 0;
214    }
215    *qctrl = cx25821_ctls[i].v;
216    return 0;
217}
218*/
219
220/* resource management */
221int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
222{
223	dprintk(1, "%s()\n", __func__);
224	if (fh->resources & bit)
225		/* have it already allocated */
226		return 1;
227
228	/* is it free? */
229	mutex_lock(&dev->lock);
230       if (dev->channels[fh->channel_id].resources & bit) {
231		/* no, someone else uses it */
232		mutex_unlock(&dev->lock);
233		return 0;
234	}
235	/* it's free, grab it */
236	fh->resources |= bit;
237       dev->channels[fh->channel_id].resources |= bit;
238	dprintk(1, "res: get %d\n", bit);
239	mutex_unlock(&dev->lock);
240	return 1;
241}
242
243int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
244{
245	return fh->resources & bit;
246}
247
248int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit)
249{
250       return fh->dev->channels[fh->channel_id].resources & bit;
251}
252
253void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits)
254{
255	BUG_ON((fh->resources & bits) != bits);
256	dprintk(1, "%s()\n", __func__);
257
258	mutex_lock(&dev->lock);
259	fh->resources &= ~bits;
260       dev->channels[fh->channel_id].resources &= ~bits;
261	dprintk(1, "res: put %d\n", bits);
262	mutex_unlock(&dev->lock);
263}
264
265int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
266{
267	struct v4l2_routing route;
268	memset(&route, 0, sizeof(route));
269
270	dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
271		__func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
272		INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
273	dev->input = input;
274
275	route.input = INPUT(input)->vmux;
276
277	/* Tell the internal A/V decoder */
278	cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
279
280	return 0;
281}
282
283int cx25821_start_video_dma(struct cx25821_dev *dev,
284			    struct cx25821_dmaqueue *q,
285			    struct cx25821_buffer *buf,
286			    struct sram_channel *channel)
287{
288	int tmp = 0;
289
290	/* setup fifo + format */
291	cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
292
293	/* reset counter */
294	cx_write(channel->gpcnt_ctl, 3);
295	q->count = 1;
296
297	/* enable irq */
298	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
299	cx_set(channel->int_msk, 0x11);
300
301	/* start dma */
302	cx_write(channel->dma_ctl, 0x11);	/* FIFO and RISC enable */
303
304	/* make sure upstream setting if any is reversed */
305	tmp = cx_read(VID_CH_MODE_SEL);
306	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
307
308	return 0;
309}
310
311int cx25821_restart_video_queue(struct cx25821_dev *dev,
312				struct cx25821_dmaqueue *q,
313				struct sram_channel *channel)
314{
315	struct cx25821_buffer *buf, *prev;
316	struct list_head *item;
317
318	if (!list_empty(&q->active)) {
319		buf =
320		    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
321
322		cx25821_start_video_dma(dev, q, buf, channel);
323
324		list_for_each(item, &q->active) {
325			buf = list_entry(item, struct cx25821_buffer, vb.queue);
326			buf->count = q->count++;
327		}
328
329		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
330		return 0;
331	}
332
333	prev = NULL;
334	for (;;) {
335		if (list_empty(&q->queued))
336			return 0;
337
338		buf =
339		    list_entry(q->queued.next, struct cx25821_buffer, vb.queue);
340
341		if (NULL == prev) {
342			list_move_tail(&buf->vb.queue, &q->active);
343			cx25821_start_video_dma(dev, q, buf, channel);
344			buf->vb.state = VIDEOBUF_ACTIVE;
345			buf->count = q->count++;
346			mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
347		} else if (prev->vb.width == buf->vb.width &&
348			   prev->vb.height == buf->vb.height &&
349			   prev->fmt == buf->fmt) {
350			list_move_tail(&buf->vb.queue, &q->active);
351			buf->vb.state = VIDEOBUF_ACTIVE;
352			buf->count = q->count++;
353			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
354			prev->risc.jmp[2] = cpu_to_le32(0);	/* Bits 63 - 32 */
355		} else {
356			return 0;
357		}
358		prev = buf;
359	}
360}
361
362void cx25821_vid_timeout(unsigned long data)
363{
364	struct cx25821_data *timeout_data = (struct cx25821_data *)data;
365	struct cx25821_dev *dev = timeout_data->dev;
366	struct sram_channel *channel = timeout_data->channel;
367       struct cx25821_dmaqueue *q = &dev->channels[channel->i].vidq;
368	struct cx25821_buffer *buf;
369	unsigned long flags;
370
371       /* cx25821_sram_channel_dump(dev, channel); */
372	cx_clear(channel->dma_ctl, 0x11);
373
374	spin_lock_irqsave(&dev->slock, flags);
375	while (!list_empty(&q->active)) {
376		buf =
377		    list_entry(q->active.next, struct cx25821_buffer, vb.queue);
378		list_del(&buf->vb.queue);
379
380		buf->vb.state = VIDEOBUF_ERROR;
381		wake_up(&buf->vb.done);
382	}
383
384	cx25821_restart_video_queue(dev, q, channel);
385	spin_unlock_irqrestore(&dev->slock, flags);
386}
387
388int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
389{
390	u32 count = 0;
391	int handled = 0;
392	u32 mask;
393       struct sram_channel *channel = dev->channels[chan_num].sram_channels;
394
395	mask = cx_read(channel->int_msk);
396	if (0 == (status & mask))
397		return handled;
398
399	cx_write(channel->int_stat, status);
400
401	/* risc op code error */
402	if (status & (1 << 16)) {
403		printk(KERN_WARNING "%s, %s: video risc op code error\n",
404		       dev->name, channel->name);
405		cx_clear(channel->dma_ctl, 0x11);
406		cx25821_sram_channel_dump(dev, channel);
407	}
408
409	/* risc1 y */
410	if (status & FLD_VID_DST_RISC1) {
411		spin_lock(&dev->slock);
412		count = cx_read(channel->gpcnt);
413	       cx25821_video_wakeup(dev,
414		       &dev->channels[channel->i].vidq, count);
415		spin_unlock(&dev->slock);
416		handled++;
417	}
418
419	/* risc2 y */
420	if (status & 0x10) {
421		dprintk(2, "stopper video\n");
422		spin_lock(&dev->slock);
423	       cx25821_restart_video_queue(dev,
424			       &dev->channels[channel->i].vidq,
425				       channel);
426		spin_unlock(&dev->slock);
427		handled++;
428	}
429	return handled;
430}
431
432void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
433{
434	if (dev->ioctl_dev) {
435		if (video_is_registered(dev->ioctl_dev))
436			video_unregister_device(dev->ioctl_dev);
437		else
438			video_device_release(dev->ioctl_dev);
439
440		dev->ioctl_dev = NULL;
441	}
442}
443
444void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
445{
446	cx_clear(PCI_INT_MSK, 1);
447
448       if (dev->channels[chan_num].video_dev) {
449	       if (video_is_registered(dev->channels[chan_num].video_dev))
450		       video_unregister_device(
451			       dev->channels[chan_num].video_dev);
452		else
453		       video_device_release(
454			       dev->channels[chan_num].video_dev);
455
456	       dev->channels[chan_num].video_dev = NULL;
457
458	       btcx_riscmem_free(dev->pci,
459		       &dev->channels[chan_num].vidq.stopper);
460
461		printk(KERN_WARNING "device %d released!\n", chan_num);
462	}
463
464}
465
466int cx25821_video_register(struct cx25821_dev *dev)
467{
468	int err;
469       int i;
470
471       struct video_device cx25821_video_device = {
472	       .name = "cx25821-video",
473	       .fops = &video_fops,
474	       .minor = -1,
475	       .ioctl_ops = &video_ioctl_ops,
476	       .tvnorms = CX25821_NORMS,
477	       .current_norm = V4L2_STD_NTSC_M,
478       };
479
480	spin_lock_init(&dev->slock);
481
482    for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) {
483	       cx25821_init_controls(dev, i);
484
485	       cx25821_risc_stopper(dev->pci,
486			       &dev->channels[i].vidq.stopper,
487			       dev->channels[i].sram_channels->dma_ctl,
488			       0x11, 0);
489
490	       dev->channels[i].sram_channels = &cx25821_sram_channels[i];
491	       dev->channels[i].video_dev = NULL;
492	       dev->channels[i].resources = 0;
493
494	       cx_write(dev->channels[i].sram_channels->int_stat,
495			       0xffffffff);
496
497	       INIT_LIST_HEAD(&dev->channels[i].vidq.active);
498	       INIT_LIST_HEAD(&dev->channels[i].vidq.queued);
499
500	       dev->channels[i].timeout_data.dev = dev;
501	       dev->channels[i].timeout_data.channel =
502				       &cx25821_sram_channels[i];
503	       dev->channels[i].vidq.timeout.function =
504				       cx25821_vid_timeout;
505	       dev->channels[i].vidq.timeout.data =
506		       (unsigned long)&dev->channels[i].timeout_data;
507	       init_timer(&dev->channels[i].vidq.timeout);
508
509	       /* register v4l devices */
510	       dev->channels[i].video_dev = cx25821_vdev_init(dev,
511		       dev->pci, &cx25821_video_device, "video");
512
513	       err = video_register_device(dev->channels[i].video_dev,
514			       VFL_TYPE_GRABBER, video_nr[dev->nr]);
515
516	       if (err < 0)
517		       goto fail_unreg;
518
519	}
520
521    /* set PCI interrupt */
522	cx_set(PCI_INT_MSK, 0xff);
523
524	/* initial device configuration */
525	mutex_lock(&dev->lock);
526#ifdef TUNER_FLAG
527       dev->tvnorm = cx25821_video_device.current_norm;
528	cx25821_set_tvnorm(dev, dev->tvnorm);
529#endif
530	mutex_unlock(&dev->lock);
531
532
533    return 0;
534
535fail_unreg:
536       cx25821_video_unregister(dev, i);
537	return err;
538}
539
540int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,
541		 unsigned int *size)
542{
543	struct cx25821_fh *fh = q->priv_data;
544
545	*size = fh->fmt->depth * fh->width * fh->height >> 3;
546
547	if (0 == *count)
548		*count = 32;
549
550	if (*size * *count > vid_limit * 1024 * 1024)
551		*count = (vid_limit * 1024 * 1024) / *size;
552
553	return 0;
554}
555
556int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
557		   enum v4l2_field field)
558{
559	struct cx25821_fh *fh = q->priv_data;
560	struct cx25821_dev *dev = fh->dev;
561	struct cx25821_buffer *buf =
562	    container_of(vb, struct cx25821_buffer, vb);
563	int rc, init_buffer = 0;
564	u32 line0_offset, line1_offset;
565	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
566	int bpl_local = LINE_SIZE_D1;
567       int channel_opened = fh->channel_id;
568
569	BUG_ON(NULL == fh->fmt);
570	if (fh->width < 48 || fh->width > 720 ||
571	    fh->height < 32 || fh->height > 576)
572		return -EINVAL;
573
574	buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
575
576	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
577		return -EINVAL;
578
579	if (buf->fmt != fh->fmt ||
580	    buf->vb.width != fh->width ||
581	    buf->vb.height != fh->height || buf->vb.field != field) {
582		buf->fmt = fh->fmt;
583		buf->vb.width = fh->width;
584		buf->vb.height = fh->height;
585		buf->vb.field = field;
586		init_buffer = 1;
587	}
588
589	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
590		init_buffer = 1;
591		rc = videobuf_iolock(q, &buf->vb, NULL);
592		if (0 != rc) {
593			printk(KERN_DEBUG "videobuf_iolock failed!\n");
594			goto fail;
595		}
596	}
597
598	dprintk(1, "init_buffer=%d\n", init_buffer);
599
600	if (init_buffer) {
601
602		channel_opened = dev->channel_opened;
603		channel_opened = (channel_opened < 0
604				  || channel_opened > 7) ? 7 : channel_opened;
605
606	       if (dev->channels[channel_opened]
607		       .pixel_formats == PIXEL_FRMT_411)
608			buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
609		else
610			buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
611
612	       if (dev->channels[channel_opened]
613		       .pixel_formats == PIXEL_FRMT_411) {
614			bpl_local = buf->bpl;
615		} else {
616		       bpl_local = buf->bpl;   /* Default */
617
618			if (channel_opened >= 0 && channel_opened <= 7) {
619			       if (dev->channels[channel_opened]
620					       .use_cif_resolution) {
621					if (dev->tvnorm & V4L2_STD_PAL_BG
622					    || dev->tvnorm & V4L2_STD_PAL_DK)
623						bpl_local = 352 << 1;
624					else
625						bpl_local =
626						 dev->channels[channel_opened].
627						 cif_width <<
628						 1;
629				}
630			}
631		}
632
633		switch (buf->vb.field) {
634		case V4L2_FIELD_TOP:
635			cx25821_risc_buffer(dev->pci, &buf->risc,
636					    dma->sglist, 0, UNSET,
637					    buf->bpl, 0, buf->vb.height);
638			break;
639		case V4L2_FIELD_BOTTOM:
640			cx25821_risc_buffer(dev->pci, &buf->risc,
641					    dma->sglist, UNSET, 0,
642					    buf->bpl, 0, buf->vb.height);
643			break;
644		case V4L2_FIELD_INTERLACED:
645			/* All other formats are top field first */
646			line0_offset = 0;
647			line1_offset = buf->bpl;
648			dprintk(1, "top field first\n");
649
650			cx25821_risc_buffer(dev->pci, &buf->risc,
651					    dma->sglist, line0_offset,
652					    bpl_local, bpl_local, bpl_local,
653					    buf->vb.height >> 1);
654			break;
655		case V4L2_FIELD_SEQ_TB:
656			cx25821_risc_buffer(dev->pci, &buf->risc,
657					    dma->sglist,
658					    0, buf->bpl * (buf->vb.height >> 1),
659					    buf->bpl, 0, buf->vb.height >> 1);
660			break;
661		case V4L2_FIELD_SEQ_BT:
662			cx25821_risc_buffer(dev->pci, &buf->risc,
663					    dma->sglist,
664					    buf->bpl * (buf->vb.height >> 1), 0,
665					    buf->bpl, 0, buf->vb.height >> 1);
666			break;
667		default:
668			BUG();
669		}
670	}
671
672	dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
673		buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth,
674		fh->fmt->name, (unsigned long)buf->risc.dma);
675
676	buf->vb.state = VIDEOBUF_PREPARED;
677
678	return 0;
679
680      fail:
681	cx25821_free_buffer(q, buf);
682	return rc;
683}
684
685void cx25821_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
686{
687	struct cx25821_buffer *buf =
688	    container_of(vb, struct cx25821_buffer, vb);
689
690	cx25821_free_buffer(q, buf);
691}
692
693struct videobuf_queue *get_queue(struct cx25821_fh *fh)
694{
695	switch (fh->type) {
696	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
697		return &fh->vidq;
698	default:
699		BUG();
700		return NULL;
701	}
702}
703
704int cx25821_get_resource(struct cx25821_fh *fh, int resource)
705{
706	switch (fh->type) {
707	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
708		return resource;
709	default:
710		BUG();
711		return 0;
712	}
713}
714
715int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
716{
717	struct cx25821_fh *fh = file->private_data;
718
719	return videobuf_mmap_mapper(get_queue(fh), vma);
720}
721
722
723static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
724{
725       struct cx25821_buffer *buf =
726	   container_of(vb, struct cx25821_buffer, vb);
727       struct cx25821_buffer *prev;
728       struct cx25821_fh *fh = vq->priv_data;
729       struct cx25821_dev *dev = fh->dev;
730       struct cx25821_dmaqueue *q = &dev->channels[fh->channel_id].vidq;
731
732       /* add jump to stopper */
733       buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
734       buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
735       buf->risc.jmp[2] = cpu_to_le32(0);      /* bits 63-32 */
736
737       dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
738
739       if (!list_empty(&q->queued)) {
740	       list_add_tail(&buf->vb.queue, &q->queued);
741	       buf->vb.state = VIDEOBUF_QUEUED;
742	       dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
743		       buf->vb.i);
744
745       } else if (list_empty(&q->active)) {
746	       list_add_tail(&buf->vb.queue, &q->active);
747	       cx25821_start_video_dma(dev, q, buf,
748				       dev->channels[fh->channel_id].
749				       sram_channels);
750	       buf->vb.state = VIDEOBUF_ACTIVE;
751	       buf->count = q->count++;
752	       mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
753	       dprintk(2,
754		       "[%p/%d] buffer_queue - first active, buf cnt = %d, \
755		       q->count = %d\n",
756		       buf, buf->vb.i, buf->count, q->count);
757       } else {
758	       prev =
759		   list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
760	       if (prev->vb.width == buf->vb.width
761		   && prev->vb.height == buf->vb.height
762		   && prev->fmt == buf->fmt) {
763		       list_add_tail(&buf->vb.queue, &q->active);
764		       buf->vb.state = VIDEOBUF_ACTIVE;
765		       buf->count = q->count++;
766		       prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
767
768		       /* 64 bit bits 63-32 */
769		       prev->risc.jmp[2] = cpu_to_le32(0);
770		       dprintk(2,
771			       "[%p/%d] buffer_queue - append to active, \
772			       buf->count=%d\n",
773			       buf, buf->vb.i, buf->count);
774
775	       } else {
776		       list_add_tail(&buf->vb.queue, &q->queued);
777		       buf->vb.state = VIDEOBUF_QUEUED;
778		       dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
779			       buf->vb.i);
780	       }
781       }
782
783       if (list_empty(&q->active))
784	       dprintk(2, "active queue empty!\n");
785}
786
787static struct videobuf_queue_ops cx25821_video_qops = {
788       .buf_setup = cx25821_buffer_setup,
789       .buf_prepare = cx25821_buffer_prepare,
790       .buf_queue = buffer_queue,
791       .buf_release = cx25821_buffer_release,
792};
793
794static int video_open(struct file *file)
795{
796       struct video_device *vdev = video_devdata(file);
797       struct cx25821_dev *h, *dev = video_drvdata(file);
798       struct cx25821_fh *fh;
799       struct list_head *list;
800       int minor = video_devdata(file)->minor;
801       enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
802       u32 pix_format;
803       int ch_id = 0;
804       int i;
805
806       dprintk(1, "open dev=%s type=%s\n",
807		       video_device_node_name(vdev),
808		       v4l2_type_names[type]);
809
810       /* allocate + initialize per filehandle data */
811       fh = kzalloc(sizeof(*fh), GFP_KERNEL);
812       if (NULL == fh)
813	       return -ENOMEM;
814
815       lock_kernel();
816
817       list_for_each(list, &cx25821_devlist)
818       {
819	       h = list_entry(list, struct cx25821_dev, devlist);
820
821	       for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) {
822		       if (h->channels[i].video_dev &&
823			   h->channels[i].video_dev->minor == minor) {
824			       dev = h;
825			       ch_id = i;
826			       type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
827		       }
828	       }
829       }
830
831       if (NULL == dev) {
832	       unlock_kernel();
833	       return -ENODEV;
834       }
835
836       file->private_data = fh;
837       fh->dev = dev;
838       fh->type = type;
839       fh->width = 720;
840    fh->channel_id = ch_id;
841
842       if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
843	       fh->height = 576;
844       else
845	       fh->height = 480;
846
847       dev->channel_opened = fh->channel_id;
848       pix_format =
849	   (dev->channels[ch_id].pixel_formats ==
850	    PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
851       fh->fmt = cx25821_format_by_fourcc(pix_format);
852
853       v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio);
854
855       videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
856			      &dev->pci->dev, &dev->slock,
857			      V4L2_BUF_TYPE_VIDEO_CAPTURE,
858			      V4L2_FIELD_INTERLACED,
859			      sizeof(struct cx25821_buffer), fh);
860
861       dprintk(1, "post videobuf_queue_init()\n");
862       unlock_kernel();
863
864       return 0;
865}
866
867static ssize_t video_read(struct file *file, char __user * data, size_t count,
868			 loff_t *ppos)
869{
870       struct cx25821_fh *fh = file->private_data;
871
872       switch (fh->type) {
873       case V4L2_BUF_TYPE_VIDEO_CAPTURE:
874	       if (cx25821_res_locked(fh, RESOURCE_VIDEO0))
875		       return -EBUSY;
876
877	       return videobuf_read_one(&fh->vidq, data, count, ppos,
878					file->f_flags & O_NONBLOCK);
879
880       default:
881	       BUG();
882	       return 0;
883       }
884}
885
886static unsigned int video_poll(struct file *file,
887			      struct poll_table_struct *wait)
888{
889       struct cx25821_fh *fh = file->private_data;
890       struct cx25821_buffer *buf;
891
892       if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
893	       /* streaming capture */
894	       if (list_empty(&fh->vidq.stream))
895		       return POLLERR;
896	       buf = list_entry(fh->vidq.stream.next,
897				struct cx25821_buffer, vb.stream);
898       } else {
899	       /* read() capture */
900	       buf = (struct cx25821_buffer *)fh->vidq.read_buf;
901	       if (NULL == buf)
902		       return POLLERR;
903       }
904
905       poll_wait(file, &buf->vb.done, wait);
906       if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
907	       if (buf->vb.state == VIDEOBUF_DONE) {
908		       struct cx25821_dev *dev = fh->dev;
909
910		       if (dev && dev->channels[fh->channel_id]
911					       .use_cif_resolution) {
912			       u8 cam_id = *((char *)buf->vb.baddr + 3);
913			       memcpy((char *)buf->vb.baddr,
914				      (char *)buf->vb.baddr + (fh->width * 2),
915				      (fh->width * 2));
916			       *((char *)buf->vb.baddr + 3) = cam_id;
917		       }
918	       }
919
920	       return POLLIN | POLLRDNORM;
921       }
922
923       return 0;
924}
925
926static int video_release(struct file *file)
927{
928       struct cx25821_fh *fh = file->private_data;
929       struct cx25821_dev *dev = fh->dev;
930
931       /* stop the risc engine and fifo */
932       cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
933
934       /* stop video capture */
935       if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
936	       videobuf_queue_cancel(&fh->vidq);
937	       cx25821_res_free(dev, fh, RESOURCE_VIDEO0);
938       }
939
940       if (fh->vidq.read_buf) {
941	       cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
942	       kfree(fh->vidq.read_buf);
943       }
944
945       videobuf_mmap_free(&fh->vidq);
946
947       v4l2_prio_close(&dev->channels[fh->channel_id].prio, fh->prio);
948       file->private_data = NULL;
949       kfree(fh);
950
951       return 0;
952}
953
954static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
955{
956       struct cx25821_fh *fh = priv;
957       struct cx25821_dev *dev = fh->dev;
958
959       if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
960	       return -EINVAL;
961
962       if (unlikely(i != fh->type))
963	       return -EINVAL;
964
965       if (unlikely(!cx25821_res_get(dev, fh,
966		       cx25821_get_resource(fh, RESOURCE_VIDEO0))))
967	       return -EBUSY;
968
969       return videobuf_streamon(get_queue(fh));
970}
971
972static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
973{
974       struct cx25821_fh *fh = priv;
975       struct cx25821_dev *dev = fh->dev;
976       int err, res;
977
978       if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
979	       return -EINVAL;
980       if (i != fh->type)
981	       return -EINVAL;
982
983       res = cx25821_get_resource(fh, RESOURCE_VIDEO0);
984       err = videobuf_streamoff(get_queue(fh));
985       if (err < 0)
986	       return err;
987       cx25821_res_free(dev, fh, res);
988       return 0;
989}
990
991static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
992			       struct v4l2_format *f)
993{
994       struct cx25821_fh *fh = priv;
995       struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
996       int err;
997       int pix_format = PIXEL_FRMT_422;
998
999       if (fh) {
1000	       err = v4l2_prio_check(&dev->channels[fh->channel_id]
1001					       .prio, fh->prio);
1002	       if (0 != err)
1003		       return err;
1004       }
1005
1006       dprintk(2, "%s()\n", __func__);
1007       err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
1008
1009       if (0 != err)
1010	       return err;
1011
1012       fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
1013       fh->vidq.field = f->fmt.pix.field;
1014
1015       /* check if width and height is valid based on set standard */
1016       if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm))
1017	       fh->width = f->fmt.pix.width;
1018
1019       if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm))
1020	       fh->height = f->fmt.pix.height;
1021
1022       if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
1023	       pix_format = PIXEL_FRMT_411;
1024       else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
1025	       pix_format = PIXEL_FRMT_422;
1026       else
1027	       return -EINVAL;
1028
1029       cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
1030
1031       /* check if cif resolution */
1032       if (fh->width == 320 || fh->width == 352)
1033	       dev->channels[fh->channel_id].use_cif_resolution = 1;
1034       else
1035	       dev->channels[fh->channel_id].use_cif_resolution = 0;
1036
1037       dev->channels[fh->channel_id].cif_width = fh->width;
1038       medusa_set_resolution(dev, fh->width, SRAM_CH00);
1039
1040       dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
1041	       fh->height, fh->vidq.field);
1042       cx25821_call_all(dev, video, s_fmt, f);
1043
1044       return 0;
1045}
1046
1047static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1048{
1049       int ret_val = 0;
1050       struct cx25821_fh *fh = priv;
1051       struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1052
1053       ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
1054
1055    p->sequence = dev->channels[fh->channel_id].vidq.count;
1056
1057       return ret_val;
1058}
1059
1060static int vidioc_log_status(struct file *file, void *priv)
1061{
1062       struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1063       struct cx25821_fh *fh = priv;
1064       char name[32 + 2];
1065
1066       struct sram_channel *sram_ch = dev->channels[fh->channel_id]
1067						       .sram_channels;
1068       u32 tmp = 0;
1069
1070       snprintf(name, sizeof(name), "%s/2", dev->name);
1071       printk(KERN_INFO "%s/2: ============  START LOG STATUS  ============\n",
1072	      dev->name);
1073       cx25821_call_all(dev, core, log_status);
1074       tmp = cx_read(sram_ch->dma_ctl);
1075       printk(KERN_INFO "Video input 0 is %s\n",
1076	      (tmp & 0x11) ? "streaming" : "stopped");
1077       printk(KERN_INFO "%s/2: =============  END LOG STATUS  =============\n",
1078	      dev->name);
1079       return 0;
1080}
1081
1082static int vidioc_s_ctrl(struct file *file, void *priv,
1083			struct v4l2_control *ctl)
1084{
1085       struct cx25821_fh *fh = priv;
1086       struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1087       int err;
1088
1089       if (fh) {
1090	       err = v4l2_prio_check(&dev->channels[fh->channel_id]
1091					       .prio, fh->prio);
1092	       if (0 != err)
1093		       return err;
1094       }
1095
1096       return cx25821_set_control(dev, ctl, fh->channel_id);
1097}
1098
1099/* VIDEO IOCTLS                                                       */
1100int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
1101{
1102	struct cx25821_fh *fh = priv;
1103
1104	f->fmt.pix.width = fh->width;
1105	f->fmt.pix.height = fh->height;
1106	f->fmt.pix.field = fh->vidq.field;
1107	f->fmt.pix.pixelformat = fh->fmt->fourcc;
1108	f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3;
1109	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
1110
1111	return 0;
1112}
1113
1114int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
1115{
1116	struct cx25821_fmt *fmt;
1117	enum v4l2_field field;
1118	unsigned int maxw, maxh;
1119
1120	fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
1121	if (NULL == fmt)
1122		return -EINVAL;
1123
1124	field = f->fmt.pix.field;
1125	maxw = 720;
1126	maxh = 576;
1127
1128	if (V4L2_FIELD_ANY == field) {
1129		field = (f->fmt.pix.height > maxh / 2)
1130		    ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
1131	}
1132
1133	switch (field) {
1134	case V4L2_FIELD_TOP:
1135	case V4L2_FIELD_BOTTOM:
1136		maxh = maxh / 2;
1137		break;
1138	case V4L2_FIELD_INTERLACED:
1139		break;
1140	default:
1141		return -EINVAL;
1142	}
1143
1144	f->fmt.pix.field = field;
1145	if (f->fmt.pix.height < 32)
1146		f->fmt.pix.height = 32;
1147	if (f->fmt.pix.height > maxh)
1148		f->fmt.pix.height = maxh;
1149	if (f->fmt.pix.width < 48)
1150		f->fmt.pix.width = 48;
1151	if (f->fmt.pix.width > maxw)
1152		f->fmt.pix.width = maxw;
1153	f->fmt.pix.width &= ~0x03;
1154	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
1155	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
1156
1157	return 0;
1158}
1159
1160int cx25821_vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
1161{
1162	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1163
1164	strcpy(cap->driver, "cx25821");
1165	strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
1166	sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
1167	cap->version = CX25821_VERSION_CODE;
1168	cap->capabilities =
1169	    V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1170	if (UNSET != dev->tuner_type)
1171		cap->capabilities |= V4L2_CAP_TUNER;
1172	return 0;
1173}
1174
1175int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1176			    struct v4l2_fmtdesc *f)
1177{
1178	if (unlikely(f->index >= ARRAY_SIZE(formats)))
1179		return -EINVAL;
1180
1181	strlcpy(f->description, formats[f->index].name, sizeof(f->description));
1182	f->pixelformat = formats[f->index].fourcc;
1183
1184	return 0;
1185}
1186
1187#ifdef CONFIG_VIDEO_V4L1_COMPAT
1188int cx25821_vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1189{
1190	struct cx25821_fh *fh = priv;
1191	struct videobuf_queue *q;
1192	struct v4l2_requestbuffers req;
1193	unsigned int i;
1194	int err;
1195
1196	q = get_queue(fh);
1197	memset(&req, 0, sizeof(req));
1198	req.type = q->type;
1199	req.count = 8;
1200	req.memory = V4L2_MEMORY_MMAP;
1201	err = videobuf_reqbufs(q, &req);
1202	if (err < 0)
1203		return err;
1204
1205	mbuf->frames = req.count;
1206	mbuf->size = 0;
1207	for (i = 0; i < mbuf->frames; i++) {
1208		mbuf->offsets[i] = q->bufs[i]->boff;
1209		mbuf->size += q->bufs[i]->bsize;
1210	}
1211	return 0;
1212}
1213#endif
1214
1215int cx25821_vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)
1216{
1217	struct cx25821_fh *fh = priv;
1218	return videobuf_reqbufs(get_queue(fh), p);
1219}
1220
1221int cx25821_vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
1222{
1223	struct cx25821_fh *fh = priv;
1224	return videobuf_querybuf(get_queue(fh), p);
1225}
1226
1227int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1228{
1229	struct cx25821_fh *fh = priv;
1230	return videobuf_qbuf(get_queue(fh), p);
1231}
1232
1233int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
1234{
1235	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
1236       struct cx25821_fh *fh = f;
1237
1238       *p = v4l2_prio_max(&dev->channels[fh->channel_id].prio);
1239
1240	return 0;
1241}
1242
1243int cx25821_vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio)
1244{
1245	struct cx25821_fh *fh = f;
1246	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
1247
1248       return v4l2_prio_change(&dev->channels[fh->channel_id]
1249				       .prio, &fh->prio, prio);
1250}
1251
1252#ifdef TUNER_FLAG
1253int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
1254{
1255	struct cx25821_fh *fh = priv;
1256	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1257	int err;
1258
1259	dprintk(1, "%s()\n", __func__);
1260
1261	if (fh) {
1262	       err = v4l2_prio_check(&dev->channels[fh->channel_id]
1263					       .prio, fh->prio);
1264		if (0 != err)
1265			return err;
1266	}
1267
1268	if (dev->tvnorm == *tvnorms) {
1269		return 0;
1270	}
1271
1272	mutex_lock(&dev->lock);
1273	cx25821_set_tvnorm(dev, *tvnorms);
1274	mutex_unlock(&dev->lock);
1275
1276	medusa_set_videostandard(dev);
1277
1278	return 0;
1279}
1280#endif
1281
1282int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
1283{
1284	static const char *iname[] = {
1285		[CX25821_VMUX_COMPOSITE] = "Composite",
1286		[CX25821_VMUX_SVIDEO] = "S-Video",
1287		[CX25821_VMUX_DEBUG] = "for debug only",
1288	};
1289	unsigned int n;
1290	dprintk(1, "%s()\n", __func__);
1291
1292	n = i->index;
1293	if (n >= 2)
1294		return -EINVAL;
1295
1296	if (0 == INPUT(n)->type)
1297		return -EINVAL;
1298
1299	memset(i, 0, sizeof(*i));
1300	i->index = n;
1301	i->type = V4L2_INPUT_TYPE_CAMERA;
1302	strcpy(i->name, iname[INPUT(n)->type]);
1303
1304	i->std = CX25821_NORMS;
1305	return 0;
1306}
1307
1308int cx25821_vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i)
1309{
1310	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1311	dprintk(1, "%s()\n", __func__);
1312	return cx25821_enum_input(dev, i);
1313}
1314
1315int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1316{
1317	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1318
1319	*i = dev->input;
1320	dprintk(1, "%s() returns %d\n", __func__, *i);
1321	return 0;
1322}
1323
1324int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
1325{
1326	struct cx25821_fh *fh = priv;
1327	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1328	int err;
1329
1330	dprintk(1, "%s(%d)\n", __func__, i);
1331
1332	if (fh) {
1333	       err = v4l2_prio_check(&dev->channels[fh->channel_id]
1334					       .prio, fh->prio);
1335		if (0 != err)
1336			return err;
1337	}
1338
1339	if (i > 2) {
1340		dprintk(1, "%s() -EINVAL\n", __func__);
1341		return -EINVAL;
1342	}
1343
1344	mutex_lock(&dev->lock);
1345	cx25821_video_mux(dev, i);
1346	mutex_unlock(&dev->lock);
1347	return 0;
1348}
1349
1350#ifdef TUNER_FLAG
1351int cx25821_vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
1352{
1353	struct cx25821_fh *fh = priv;
1354	struct cx25821_dev *dev = fh->dev;
1355
1356	f->frequency = dev->freq;
1357
1358	cx25821_call_all(dev, tuner, g_frequency, f);
1359
1360	return 0;
1361}
1362
1363int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
1364{
1365	mutex_lock(&dev->lock);
1366	dev->freq = f->frequency;
1367
1368	cx25821_call_all(dev, tuner, s_frequency, f);
1369
1370	/* When changing channels it is required to reset TVAUDIO */
1371	msleep(10);
1372
1373	mutex_unlock(&dev->lock);
1374
1375	return 0;
1376}
1377
1378int cx25821_vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
1379{
1380	struct cx25821_fh *fh = priv;
1381	struct cx25821_dev *dev;
1382	int err;
1383
1384	if (fh) {
1385	       dev = fh->dev;
1386	       err = v4l2_prio_check(&dev->channels[fh->channel_id]
1387					       .prio, fh->prio);
1388		if (0 != err)
1389			return err;
1390       } else {
1391	       printk(KERN_ERR "Invalid fh pointer!\n");
1392	       return -EINVAL;
1393	}
1394
1395	return cx25821_set_freq(dev, f);
1396}
1397#endif
1398
1399#ifdef CONFIG_VIDEO_ADV_DEBUG
1400int cx25821_vidioc_g_register(struct file *file, void *fh,
1401		      struct v4l2_dbg_register *reg)
1402{
1403	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
1404
1405	if (!v4l2_chip_match_host(&reg->match))
1406		return -EINVAL;
1407
1408	cx25821_call_all(dev, core, g_register, reg);
1409
1410	return 0;
1411}
1412
1413int cx25821_vidioc_s_register(struct file *file, void *fh,
1414		      struct v4l2_dbg_register *reg)
1415{
1416	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
1417
1418	if (!v4l2_chip_match_host(&reg->match))
1419		return -EINVAL;
1420
1421	cx25821_call_all(dev, core, s_register, reg);
1422
1423	return 0;
1424}
1425
1426#endif
1427
1428#ifdef TUNER_FLAG
1429int cx25821_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1430{
1431	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1432
1433	if (unlikely(UNSET == dev->tuner_type))
1434		return -EINVAL;
1435	if (0 != t->index)
1436		return -EINVAL;
1437
1438	strcpy(t->name, "Television");
1439	t->type = V4L2_TUNER_ANALOG_TV;
1440	t->capability = V4L2_TUNER_CAP_NORM;
1441	t->rangehigh = 0xffffffffUL;
1442
1443	t->signal = 0xffff;	/* LOCKED */
1444	return 0;
1445}
1446
1447int cx25821_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1448{
1449	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1450	struct cx25821_fh *fh = priv;
1451	int err;
1452
1453	if (fh) {
1454	       err = v4l2_prio_check(&dev->channels[fh->channel_id]
1455					       .prio, fh->prio);
1456		if (0 != err)
1457			return err;
1458	}
1459
1460	dprintk(1, "%s()\n", __func__);
1461	if (UNSET == dev->tuner_type)
1462		return -EINVAL;
1463	if (0 != t->index)
1464		return -EINVAL;
1465
1466	return 0;
1467}
1468
1469#endif
1470/*****************************************************************************/
1471static const struct v4l2_queryctrl no_ctl = {
1472	.name = "42",
1473	.flags = V4L2_CTRL_FLAG_DISABLED,
1474};
1475
1476static struct v4l2_queryctrl cx25821_ctls[] = {
1477	/* --- video --- */
1478	{
1479	 .id = V4L2_CID_BRIGHTNESS,
1480	 .name = "Brightness",
1481	 .minimum = 0,
1482	 .maximum = 10000,
1483	 .step = 1,
1484	 .default_value = 6200,
1485	 .type = V4L2_CTRL_TYPE_INTEGER,
1486	 }, {
1487	     .id = V4L2_CID_CONTRAST,
1488	     .name = "Contrast",
1489	     .minimum = 0,
1490	     .maximum = 10000,
1491	     .step = 1,
1492	     .default_value = 5000,
1493	     .type = V4L2_CTRL_TYPE_INTEGER,
1494	     }, {
1495		 .id = V4L2_CID_SATURATION,
1496		 .name = "Saturation",
1497		 .minimum = 0,
1498		 .maximum = 10000,
1499		 .step = 1,
1500		 .default_value = 5000,
1501		 .type = V4L2_CTRL_TYPE_INTEGER,
1502		 }, {
1503		     .id = V4L2_CID_HUE,
1504		     .name = "Hue",
1505		     .minimum = 0,
1506		     .maximum = 10000,
1507		     .step = 1,
1508		     .default_value = 5000,
1509		     .type = V4L2_CTRL_TYPE_INTEGER,
1510		     }
1511};
1512static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);
1513
1514static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
1515{
1516	int i;
1517
1518	if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
1519		return -EINVAL;
1520	for (i = 0; i < CX25821_CTLS; i++)
1521		if (cx25821_ctls[i].id == qctrl->id)
1522			break;
1523	if (i == CX25821_CTLS) {
1524		*qctrl = no_ctl;
1525		return 0;
1526	}
1527	*qctrl = cx25821_ctls[i];
1528	return 0;
1529}
1530
1531int cx25821_vidioc_queryctrl(struct file *file, void *priv,
1532		     struct v4l2_queryctrl *qctrl)
1533{
1534	return cx25821_ctrl_query(qctrl);
1535}
1536
1537/* ------------------------------------------------------------------ */
1538/* VIDEO CTRL IOCTLS                                                  */
1539
1540static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
1541{
1542	unsigned int i;
1543
1544	for (i = 0; i < CX25821_CTLS; i++)
1545		if (cx25821_ctls[i].id == id)
1546			return cx25821_ctls + i;
1547	return NULL;
1548}
1549
1550int cx25821_vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl)
1551{
1552	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1553       struct cx25821_fh *fh = priv;
1554
1555	const struct v4l2_queryctrl *ctrl;
1556
1557	ctrl = ctrl_by_id(ctl->id);
1558
1559	if (NULL == ctrl)
1560		return -EINVAL;
1561	switch (ctl->id) {
1562	case V4L2_CID_BRIGHTNESS:
1563	       ctl->value = dev->channels[fh->channel_id].ctl_bright;
1564		break;
1565	case V4L2_CID_HUE:
1566	       ctl->value = dev->channels[fh->channel_id].ctl_hue;
1567		break;
1568	case V4L2_CID_CONTRAST:
1569	       ctl->value = dev->channels[fh->channel_id].ctl_contrast;
1570		break;
1571	case V4L2_CID_SATURATION:
1572	       ctl->value = dev->channels[fh->channel_id].ctl_saturation;
1573		break;
1574	}
1575	return 0;
1576}
1577
1578int cx25821_set_control(struct cx25821_dev *dev,
1579			struct v4l2_control *ctl, int chan_num)
1580{
1581	int err;
1582	const struct v4l2_queryctrl *ctrl;
1583
1584	err = -EINVAL;
1585
1586	ctrl = ctrl_by_id(ctl->id);
1587
1588	if (NULL == ctrl)
1589		return err;
1590
1591	switch (ctrl->type) {
1592	case V4L2_CTRL_TYPE_BOOLEAN:
1593	case V4L2_CTRL_TYPE_MENU:
1594	case V4L2_CTRL_TYPE_INTEGER:
1595		if (ctl->value < ctrl->minimum)
1596			ctl->value = ctrl->minimum;
1597		if (ctl->value > ctrl->maximum)
1598			ctl->value = ctrl->maximum;
1599		break;
1600	default:
1601		/* nothing */ ;
1602	};
1603
1604	switch (ctl->id) {
1605	case V4L2_CID_BRIGHTNESS:
1606	       dev->channels[chan_num].ctl_bright = ctl->value;
1607		medusa_set_brightness(dev, ctl->value, chan_num);
1608		break;
1609	case V4L2_CID_HUE:
1610	       dev->channels[chan_num].ctl_hue = ctl->value;
1611		medusa_set_hue(dev, ctl->value, chan_num);
1612		break;
1613	case V4L2_CID_CONTRAST:
1614	       dev->channels[chan_num].ctl_contrast = ctl->value;
1615		medusa_set_contrast(dev, ctl->value, chan_num);
1616		break;
1617	case V4L2_CID_SATURATION:
1618	       dev->channels[chan_num].ctl_saturation = ctl->value;
1619		medusa_set_saturation(dev, ctl->value, chan_num);
1620		break;
1621	}
1622
1623	err = 0;
1624
1625	return err;
1626}
1627
1628static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num)
1629{
1630	struct v4l2_control ctrl;
1631	int i;
1632	for (i = 0; i < CX25821_CTLS; i++) {
1633		ctrl.id = cx25821_ctls[i].id;
1634		ctrl.value = cx25821_ctls[i].default_value;
1635
1636		cx25821_set_control(dev, &ctrl, chan_num);
1637	}
1638}
1639
1640int cx25821_vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap)
1641{
1642	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1643
1644	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1645		return -EINVAL;
1646	cropcap->bounds.top = cropcap->bounds.left = 0;
1647	cropcap->bounds.width = 720;
1648	cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
1649	cropcap->pixelaspect.numerator =
1650	    dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10;
1651	cropcap->pixelaspect.denominator =
1652	    dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11;
1653	cropcap->defrect = cropcap->bounds;
1654	return 0;
1655}
1656
1657int cx25821_vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1658{
1659	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1660	struct cx25821_fh *fh = priv;
1661	int err;
1662
1663	if (fh) {
1664	       err = v4l2_prio_check(&dev->channels[fh->channel_id].
1665					       prio, fh->prio);
1666		if (0 != err)
1667			return err;
1668	}
1669       /* cx25821_vidioc_s_crop not supported */
1670	return -EINVAL;
1671}
1672
1673int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1674{
1675       /* cx25821_vidioc_g_crop not supported */
1676	return -EINVAL;
1677}
1678
1679int cx25821_vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
1680{
1681       /* medusa does not support video standard sensing of current input */
1682	*norm = CX25821_NORMS;
1683
1684	return 0;
1685}
1686
1687int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm)
1688{
1689	if (tvnorm == V4L2_STD_PAL_BG) {
1690		if (width == 352 || width == 720)
1691			return 1;
1692		else
1693			return 0;
1694	}
1695
1696	if (tvnorm == V4L2_STD_NTSC_M) {
1697		if (width == 320 || width == 352 || width == 720)
1698			return 1;
1699		else
1700			return 0;
1701	}
1702	return 0;
1703}
1704
1705int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm)
1706{
1707	if (tvnorm == V4L2_STD_PAL_BG) {
1708		if (height == 576 || height == 288)
1709			return 1;
1710		else
1711			return 0;
1712	}
1713
1714	if (tvnorm == V4L2_STD_NTSC_M) {
1715		if (height == 480 || height == 240)
1716			return 1;
1717		else
1718			return 0;
1719	}
1720
1721	return 0;
1722}
1723
1724static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
1725				 unsigned long arg)
1726{
1727       struct cx25821_fh *fh = file->private_data;
1728       struct cx25821_dev *dev = fh->dev;
1729       int command = 0;
1730       struct upstream_user_struct *data_from_user;
1731
1732       data_from_user = (struct upstream_user_struct *)arg;
1733
1734       if (!data_from_user) {
1735	       printk
1736		   ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
1737		    __func__);
1738	       return 0;
1739       }
1740
1741       command = data_from_user->command;
1742
1743       if (command != UPSTREAM_START_VIDEO &&
1744	       command != UPSTREAM_STOP_VIDEO)
1745	       return 0;
1746
1747       dev->input_filename = data_from_user->input_filename;
1748       dev->input_audiofilename = data_from_user->input_filename;
1749       dev->vid_stdname = data_from_user->vid_stdname;
1750       dev->pixel_format = data_from_user->pixel_format;
1751       dev->channel_select = data_from_user->channel_select;
1752       dev->command = data_from_user->command;
1753
1754       switch (command) {
1755       case UPSTREAM_START_VIDEO:
1756	       cx25821_start_upstream_video_ch1(dev, data_from_user);
1757	       break;
1758
1759       case UPSTREAM_STOP_VIDEO:
1760	       cx25821_stop_upstream_video_ch1(dev);
1761	       break;
1762       }
1763
1764       return 0;
1765}
1766
1767static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
1768				  unsigned long arg)
1769{
1770       struct cx25821_fh *fh = file->private_data;
1771       struct cx25821_dev *dev = fh->dev;
1772       int command = 0;
1773       struct upstream_user_struct *data_from_user;
1774
1775       data_from_user = (struct upstream_user_struct *)arg;
1776
1777       if (!data_from_user) {
1778	       printk
1779		   ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
1780		    __func__);
1781	       return 0;
1782       }
1783
1784       command = data_from_user->command;
1785
1786       if (command != UPSTREAM_START_VIDEO &&
1787	       command != UPSTREAM_STOP_VIDEO)
1788	       return 0;
1789
1790       dev->input_filename_ch2 = data_from_user->input_filename;
1791       dev->input_audiofilename = data_from_user->input_filename;
1792       dev->vid_stdname_ch2 = data_from_user->vid_stdname;
1793       dev->pixel_format_ch2 = data_from_user->pixel_format;
1794       dev->channel_select_ch2 = data_from_user->channel_select;
1795       dev->command_ch2 = data_from_user->command;
1796
1797       switch (command) {
1798       case UPSTREAM_START_VIDEO:
1799	       cx25821_start_upstream_video_ch2(dev, data_from_user);
1800	       break;
1801
1802       case UPSTREAM_STOP_VIDEO:
1803	       cx25821_stop_upstream_video_ch2(dev);
1804	       break;
1805       }
1806
1807       return 0;
1808}
1809
1810static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
1811				  unsigned long arg)
1812{
1813       struct cx25821_fh *fh = file->private_data;
1814       struct cx25821_dev *dev = fh->dev;
1815       int command = 0;
1816       struct upstream_user_struct *data_from_user;
1817
1818       data_from_user = (struct upstream_user_struct *)arg;
1819
1820       if (!data_from_user) {
1821	       printk
1822		   ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
1823		    __func__);
1824	       return 0;
1825       }
1826
1827       command = data_from_user->command;
1828
1829       if (command != UPSTREAM_START_AUDIO &&
1830	       command != UPSTREAM_STOP_AUDIO)
1831	       return 0;
1832
1833       dev->input_filename = data_from_user->input_filename;
1834       dev->input_audiofilename = data_from_user->input_filename;
1835       dev->vid_stdname = data_from_user->vid_stdname;
1836       dev->pixel_format = data_from_user->pixel_format;
1837       dev->channel_select = data_from_user->channel_select;
1838       dev->command = data_from_user->command;
1839
1840       switch (command) {
1841       case UPSTREAM_START_AUDIO:
1842	       cx25821_start_upstream_audio(dev, data_from_user);
1843	       break;
1844
1845       case UPSTREAM_STOP_AUDIO:
1846	       cx25821_stop_upstream_audio(dev);
1847	       break;
1848       }
1849
1850       return 0;
1851}
1852
1853static long video_ioctl_set(struct file *file, unsigned int cmd,
1854			   unsigned long arg)
1855{
1856       struct cx25821_fh *fh = file->private_data;
1857       struct cx25821_dev *dev = fh->dev;
1858       struct downstream_user_struct *data_from_user;
1859       int command;
1860       int width = 720;
1861       int selected_channel = 0, pix_format = 0, i = 0;
1862       int cif_enable = 0, cif_width = 0;
1863       u32 value = 0;
1864
1865       data_from_user = (struct downstream_user_struct *)arg;
1866
1867       if (!data_from_user) {
1868	       printk(
1869	       "cx25821 in %s(): User data is INVALID. Returning.\n",
1870	       __func__);
1871	       return 0;
1872       }
1873
1874       command = data_from_user->command;
1875
1876       if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
1877	   && command != ENABLE_CIF_RESOLUTION && command != REG_READ
1878	   && command != REG_WRITE && command != MEDUSA_READ
1879	   && command != MEDUSA_WRITE) {
1880	       return 0;
1881       }
1882
1883       switch (command) {
1884       case SET_VIDEO_STD:
1885	       dev->tvnorm =
1886		   !strcmp(data_from_user->vid_stdname,
1887			   "PAL") ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
1888	       medusa_set_videostandard(dev);
1889	       break;
1890
1891       case SET_PIXEL_FORMAT:
1892	       selected_channel = data_from_user->decoder_select;
1893	       pix_format = data_from_user->pixel_format;
1894
1895	       if (!(selected_channel <= 7 && selected_channel >= 0)) {
1896		       selected_channel -= 4;
1897		       selected_channel = selected_channel % 8;
1898	       }
1899
1900	       if (selected_channel >= 0)
1901		       cx25821_set_pixel_format(dev, selected_channel,
1902						pix_format);
1903
1904	       break;
1905
1906       case ENABLE_CIF_RESOLUTION:
1907	       selected_channel = data_from_user->decoder_select;
1908	       cif_enable = data_from_user->cif_resolution_enable;
1909	       cif_width = data_from_user->cif_width;
1910
1911	       if (cif_enable) {
1912		       if (dev->tvnorm & V4L2_STD_PAL_BG
1913			   || dev->tvnorm & V4L2_STD_PAL_DK)
1914			       width = 352;
1915		       else
1916			       width = (cif_width == 320
1917					|| cif_width == 352) ? cif_width : 320;
1918	       }
1919
1920	       if (!(selected_channel <= 7 && selected_channel >= 0)) {
1921		       selected_channel -= 4;
1922		       selected_channel = selected_channel % 8;
1923	       }
1924
1925	       if (selected_channel <= 7 && selected_channel >= 0) {
1926		       dev->channels[selected_channel].
1927			       use_cif_resolution = cif_enable;
1928		       dev->channels[selected_channel].cif_width = width;
1929	       } else {
1930		       for (i = 0; i < VID_CHANNEL_NUM; i++) {
1931			       dev->channels[i].use_cif_resolution =
1932				       cif_enable;
1933			       dev->channels[i].cif_width = width;
1934		       }
1935	       }
1936
1937	       medusa_set_resolution(dev, width, selected_channel);
1938	       break;
1939       case REG_READ:
1940	       data_from_user->reg_data = cx_read(data_from_user->reg_address);
1941	       break;
1942       case REG_WRITE:
1943	       cx_write(data_from_user->reg_address, data_from_user->reg_data);
1944	       break;
1945       case MEDUSA_READ:
1946	       value =
1947		   cx25821_i2c_read(&dev->i2c_bus[0],
1948				    (u16) data_from_user->reg_address,
1949				    &data_from_user->reg_data);
1950	       break;
1951       case MEDUSA_WRITE:
1952	       cx25821_i2c_write(&dev->i2c_bus[0],
1953				 (u16) data_from_user->reg_address,
1954				 data_from_user->reg_data);
1955	       break;
1956       }
1957
1958       return 0;
1959}
1960
1961static long cx25821_video_ioctl(struct file *file,
1962			       unsigned int cmd, unsigned long arg)
1963{
1964       int  ret = 0;
1965
1966       struct cx25821_fh  *fh  = file->private_data;
1967
1968       /* check to see if it's the video upstream */
1969       if (fh->channel_id == SRAM_CH09) {
1970	       ret = video_ioctl_upstream9(file, cmd, arg);
1971	       return ret;
1972       } else if (fh->channel_id == SRAM_CH10) {
1973	       ret = video_ioctl_upstream10(file, cmd, arg);
1974	       return ret;
1975       } else if (fh->channel_id == SRAM_CH11) {
1976	       ret = video_ioctl_upstream11(file, cmd, arg);
1977	       ret = video_ioctl_set(file, cmd, arg);
1978	       return ret;
1979       }
1980
1981    return video_ioctl2(file, cmd, arg);
1982}
1983
1984/* exported stuff */
1985static const struct v4l2_file_operations video_fops = {
1986       .owner = THIS_MODULE,
1987       .open = video_open,
1988       .release = video_release,
1989       .read = video_read,
1990       .poll = video_poll,
1991       .mmap = cx25821_video_mmap,
1992       .ioctl = cx25821_video_ioctl,
1993};
1994
1995static const struct v4l2_ioctl_ops video_ioctl_ops = {
1996       .vidioc_querycap = cx25821_vidioc_querycap,
1997       .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
1998       .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
1999       .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
2000       .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
2001       .vidioc_reqbufs = cx25821_vidioc_reqbufs,
2002       .vidioc_querybuf = cx25821_vidioc_querybuf,
2003       .vidioc_qbuf = cx25821_vidioc_qbuf,
2004       .vidioc_dqbuf = vidioc_dqbuf,
2005#ifdef TUNER_FLAG
2006       .vidioc_s_std = cx25821_vidioc_s_std,
2007       .vidioc_querystd = cx25821_vidioc_querystd,
2008#endif
2009       .vidioc_cropcap = cx25821_vidioc_cropcap,
2010       .vidioc_s_crop = cx25821_vidioc_s_crop,
2011       .vidioc_g_crop = cx25821_vidioc_g_crop,
2012       .vidioc_enum_input = cx25821_vidioc_enum_input,
2013       .vidioc_g_input = cx25821_vidioc_g_input,
2014       .vidioc_s_input = cx25821_vidioc_s_input,
2015       .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
2016       .vidioc_s_ctrl = vidioc_s_ctrl,
2017       .vidioc_queryctrl = cx25821_vidioc_queryctrl,
2018       .vidioc_streamon = vidioc_streamon,
2019       .vidioc_streamoff = vidioc_streamoff,
2020       .vidioc_log_status = vidioc_log_status,
2021       .vidioc_g_priority = cx25821_vidioc_g_priority,
2022       .vidioc_s_priority = cx25821_vidioc_s_priority,
2023#ifdef CONFIG_VIDEO_V4L1_COMPAT
2024       .vidiocgmbuf = cx25821_vidiocgmbuf,
2025#endif
2026#ifdef TUNER_FLAG
2027       .vidioc_g_tuner = cx25821_vidioc_g_tuner,
2028       .vidioc_s_tuner = cx25821_vidioc_s_tuner,
2029       .vidioc_g_frequency = cx25821_vidioc_g_frequency,
2030       .vidioc_s_frequency = cx25821_vidioc_s_frequency,
2031#endif
2032#ifdef CONFIG_VIDEO_ADV_DEBUG
2033       .vidioc_g_register = cx25821_vidioc_g_register,
2034       .vidioc_s_register = cx25821_vidioc_s_register,
2035#endif
2036};
2037
2038struct video_device cx25821_videoioctl_template = {
2039	       .name = "cx25821-videoioctl",
2040	       .fops = &video_fops,
2041	       .ioctl_ops = &video_ioctl_ops,
2042	       .tvnorms = CX25821_NORMS,
2043	       .current_norm = V4L2_STD_NTSC_M,
2044};
2045