cx25821-video.c 48.6 KB
Newer Older
1 2 3
/*
 *  Driver for the Conexant CX25821 PCIe bridge
 *
4
 *  Copyright (C) 2009 Conexant Systems Inc.
5 6
 *  Authors  <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
 *  Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 8 9
 *  Parts adapted/taken from Eduardo Moscoso Rubino
 *  Copyright (C) 2009 Eduardo Moscoso Rubino <moscoso@TopoLogica.com>
 *
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

27 28
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

29 30 31
#include "cx25821-video.h"

MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
32
MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
33 34
MODULE_LICENSE("GPL");

35 36
static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
37 38 39 40 41 42 43

module_param_array(video_nr, int, NULL, 0444);
module_param_array(radio_nr, int, NULL, 0444);

MODULE_PARM_DESC(video_nr, "video device numbers");
MODULE_PARM_DESC(radio_nr, "radio device numbers");

44
static unsigned int video_debug = VIDEO_DEBUG;
45 46 47 48 49 50 51 52 53 54 55
module_param(video_debug, int, 0644);
MODULE_PARM_DESC(video_debug, "enable debug messages [video]");

static unsigned int irq_debug;
module_param(irq_debug, int, 0644);
MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");

unsigned int vid_limit = 16;
module_param(vid_limit, int, 0644);
MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");

56 57 58 59
static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num);

static const struct v4l2_file_operations video_fops;
static const struct v4l2_ioctl_ops video_ioctl_ops;
60 61 62 63

#define FORMAT_FLAGS_PACKED       0x01

struct cx25821_fmt formats[] = {
64
	{
65 66 67 68
		.name = "8 bpp, gray",
		.fourcc = V4L2_PIX_FMT_GREY,
		.depth = 8,
		.flags = FORMAT_FLAGS_PACKED,
69
	 }, {
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
		.name = "4:1:1, packed, Y41P",
		.fourcc = V4L2_PIX_FMT_Y41P,
		.depth = 12,
		.flags = FORMAT_FLAGS_PACKED,
	}, {
		.name = "4:2:2, packed, YUYV",
		.fourcc = V4L2_PIX_FMT_YUYV,
		.depth = 16,
		.flags = FORMAT_FLAGS_PACKED,
	}, {
		.name = "4:2:2, packed, UYVY",
		.fourcc = V4L2_PIX_FMT_UYVY,
		.depth = 16,
		.flags = FORMAT_FLAGS_PACKED,
	}, {
		.name = "4:2:0, YUV",
		.fourcc = V4L2_PIX_FMT_YUV420,
		.depth = 12,
		.flags = FORMAT_FLAGS_PACKED,
	},
90 91
};

92
int cx25821_get_format_size(void)
93
{
94
	return ARRAY_SIZE(formats);
95 96
}

97
struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
98
{
99
	unsigned int i;
100

101
	if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P)
102
		return formats + 1;
103

104 105 106
	for (i = 0; i < ARRAY_SIZE(formats); i++)
		if (formats[i].fourcc == fourcc)
			return formats + i;
107

108
	pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc);
109
	return NULL;
110 111
}

112 113
void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
			  u32 count)
114
{
115 116
	struct cx25821_buffer *buf;
	int bc;
117

118 119 120 121 122
	for (bc = 0;; bc++) {
		if (list_empty(&q->active)) {
			dprintk(1, "bc=%d (=0: active empty)\n", bc);
			break;
		}
123

124 125
		buf = list_entry(q->active.next, struct cx25821_buffer,
				vb.queue);
126

127 128 129
		/* count comes from the hw and it is 16bit wide --
		 * this trick handles wrap-arounds correctly for
		 * up to 32767 buffers in flight... */
130
		if ((s16) (count - buf->count) < 0)
131
			break;
132

133
		v4l2_get_timestamp(&buf->vb.ts);
134 135 136 137
		buf->vb.state = VIDEOBUF_DONE;
		list_del(&buf->vb.queue);
		wake_up(&buf->vb.done);
	}
138

139 140 141 142 143
	if (list_empty(&q->active))
		del_timer(&q->timeout);
	else
		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
	if (bc != 1)
144
		pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc);
145 146 147 148 149
}

#ifdef TUNER_FLAG
int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
{
150 151
	dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
		__func__, (unsigned int)norm, v4l2_norm_to_name(norm));
152

153
	dev->tvnorm = norm;
154

155 156
	/* Tell the internal A/V decoder */
	cx25821_call_all(dev, core, s_std, norm);
157

158
	return 0;
159 160 161 162
}
#endif

struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
163 164 165
				       struct pci_dev *pci,
				       struct video_device *template,
				       char *type)
166
{
167 168 169 170 171 172 173 174 175 176 177
	struct video_device *vfd;
	dprintk(1, "%s()\n", __func__);

	vfd = video_device_alloc();
	if (NULL == vfd)
		return NULL;
	*vfd = *template;
	vfd->v4l2_dev = &dev->v4l2_dev;
	vfd->release = video_device_release;
	snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type,
		 cx25821_boards[dev->board].name);
178
	video_set_drvdata(vfd, dev);
179
	return vfd;
180 181 182 183 184
}

/*
static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
{
185 186 187 188 189 190 191 192 193 194 195 196
	int i;

	if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
		return -EINVAL;
	for (i = 0; i < CX25821_CTLS; i++)
		if (cx25821_ctls[i].v.id == qctrl->id)
			break;
	if (i == CX25821_CTLS) {
		*qctrl = no_ctl;
		return 0;
	}
	*qctrl = cx25821_ctls[i].v;
197
	return 0;
198 199 200
}
*/

201
/* resource management */
202 203
int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
		    unsigned int bit)
204
{
205 206 207 208 209 210 211
	dprintk(1, "%s()\n", __func__);
	if (fh->resources & bit)
		/* have it already allocated */
		return 1;

	/* is it free? */
	mutex_lock(&dev->lock);
212
	if (dev->channels[fh->channel_id].resources & bit) {
213 214 215 216 217 218
		/* no, someone else uses it */
		mutex_unlock(&dev->lock);
		return 0;
	}
	/* it's free, grab it */
	fh->resources |= bit;
219
	dev->channels[fh->channel_id].resources |= bit;
220
	dprintk(1, "res: get %d\n", bit);
221
	mutex_unlock(&dev->lock);
222
	return 1;
223 224
}

225
int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
226
{
227
	return fh->resources & bit;
228 229
}

230
int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit)
231
{
232
	return fh->dev->channels[fh->channel_id].resources & bit;
233 234
}

235 236
void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
		      unsigned int bits)
237
{
238 239 240 241 242
	BUG_ON((fh->resources & bits) != bits);
	dprintk(1, "%s()\n", __func__);

	mutex_lock(&dev->lock);
	fh->resources &= ~bits;
243
	dev->channels[fh->channel_id].resources &= ~bits;
244 245
	dprintk(1, "res: put %d\n", bits);
	mutex_unlock(&dev->lock);
246 247 248 249
}

int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
{
250 251
	struct v4l2_routing route;
	memset(&route, 0, sizeof(route));
252

253
	dprintk(1, "%s(): video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
254 255 256
		__func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
		INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
	dev->input = input;
257

258
	route.input = INPUT(input)->vmux;
259

260 261
	/* Tell the internal A/V decoder */
	cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
262

263
	return 0;
264 265 266
}

int cx25821_start_video_dma(struct cx25821_dev *dev,
267 268 269
			    struct cx25821_dmaqueue *q,
			    struct cx25821_buffer *buf,
			    struct sram_channel *channel)
270
{
271
	int tmp = 0;
272

273 274
	/* setup fifo + format */
	cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
275

276 277 278
	/* reset counter */
	cx_write(channel->gpcnt_ctl, 3);
	q->count = 1;
279

280 281 282
	/* enable irq */
	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
	cx_set(channel->int_msk, 0x11);
283

284 285
	/* start dma */
	cx_write(channel->dma_ctl, 0x11);	/* FIFO and RISC enable */
286

287 288 289
	/* make sure upstream setting if any is reversed */
	tmp = cx_read(VID_CH_MODE_SEL);
	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
290

291
	return 0;
292 293
}

294 295 296
static int cx25821_restart_video_queue(struct cx25821_dev *dev,
				       struct cx25821_dmaqueue *q,
				       struct sram_channel *channel)
297
{
298 299
	struct cx25821_buffer *buf, *prev;
	struct list_head *item;
300

301
	if (!list_empty(&q->active)) {
302 303
		buf = list_entry(q->active.next, struct cx25821_buffer,
				vb.queue);
304

305
		cx25821_start_video_dma(dev, q, buf, channel);
306

307 308 309 310
		list_for_each(item, &q->active) {
			buf = list_entry(item, struct cx25821_buffer, vb.queue);
			buf->count = q->count++;
		}
311

312 313 314
		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
		return 0;
	}
315

316 317 318 319 320
	prev = NULL;
	for (;;) {
		if (list_empty(&q->queued))
			return 0;

321 322
		buf = list_entry(q->queued.next, struct cx25821_buffer,
				vb.queue);
323 324 325 326 327 328 329 330 331 332 333 334 335 336

		if (NULL == prev) {
			list_move_tail(&buf->vb.queue, &q->active);
			cx25821_start_video_dma(dev, q, buf, channel);
			buf->vb.state = VIDEOBUF_ACTIVE;
			buf->count = q->count++;
			mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
		} else if (prev->vb.width == buf->vb.width &&
			   prev->vb.height == buf->vb.height &&
			   prev->fmt == buf->fmt) {
			list_move_tail(&buf->vb.queue, &q->active);
			buf->vb.state = VIDEOBUF_ACTIVE;
			buf->count = q->count++;
			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
337
			prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
338 339 340 341
		} else {
			return 0;
		}
		prev = buf;
342
	}
343 344
}

345
static void cx25821_vid_timeout(unsigned long data)
346
{
347 348 349
	struct cx25821_data *timeout_data = (struct cx25821_data *)data;
	struct cx25821_dev *dev = timeout_data->dev;
	struct sram_channel *channel = timeout_data->channel;
350
	struct cx25821_dmaqueue *q = &dev->channels[channel->i].vidq;
351 352 353
	struct cx25821_buffer *buf;
	unsigned long flags;

354
	/* cx25821_sram_channel_dump(dev, channel); */
355 356 357 358
	cx_clear(channel->dma_ctl, 0x11);

	spin_lock_irqsave(&dev->slock, flags);
	while (!list_empty(&q->active)) {
359 360
		buf = list_entry(q->active.next, struct cx25821_buffer,
				vb.queue);
361
		list_del(&buf->vb.queue);
362

363 364 365 366 367 368
		buf->vb.state = VIDEOBUF_ERROR;
		wake_up(&buf->vb.done);
	}

	cx25821_restart_video_queue(dev, q, channel);
	spin_unlock_irqrestore(&dev->slock, flags);
369 370 371 372
}

int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
{
373 374 375
	u32 count = 0;
	int handled = 0;
	u32 mask;
376
	struct sram_channel *channel = dev->channels[chan_num].sram_channels;
377 378 379 380 381 382 383 384 385

	mask = cx_read(channel->int_msk);
	if (0 == (status & mask))
		return handled;

	cx_write(channel->int_stat, status);

	/* risc op code error */
	if (status & (1 << 16)) {
386 387
		pr_warn("%s, %s: video risc op code error\n",
			dev->name, channel->name);
388 389 390
		cx_clear(channel->dma_ctl, 0x11);
		cx25821_sram_channel_dump(dev, channel);
	}
391

392 393 394 395
	/* risc1 y */
	if (status & FLD_VID_DST_RISC1) {
		spin_lock(&dev->slock);
		count = cx_read(channel->gpcnt);
396 397
		cx25821_video_wakeup(dev, &dev->channels[channel->i].vidq,
				count);
398 399 400
		spin_unlock(&dev->slock);
		handled++;
	}
401

402 403 404 405
	/* risc2 y */
	if (status & 0x10) {
		dprintk(2, "stopper video\n");
		spin_lock(&dev->slock);
406 407
		cx25821_restart_video_queue(dev,
				&dev->channels[channel->i].vidq, channel);
408 409 410 411
		spin_unlock(&dev->slock);
		handled++;
	}
	return handled;
412 413 414 415
}

void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
{
416
	if (dev->ioctl_dev) {
417
		if (video_is_registered(dev->ioctl_dev))
418 419 420
			video_unregister_device(dev->ioctl_dev);
		else
			video_device_release(dev->ioctl_dev);
421

422 423
		dev->ioctl_dev = NULL;
	}
424
}
425

426 427
void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
{
428
	cx_clear(PCI_INT_MSK, 1);
429

430 431 432 433
	if (dev->channels[chan_num].video_dev) {
		if (video_is_registered(dev->channels[chan_num].video_dev))
			video_unregister_device(
					dev->channels[chan_num].video_dev);
434
		else
435 436
			video_device_release(
					dev->channels[chan_num].video_dev);
437

438
		dev->channels[chan_num].video_dev = NULL;
439

440 441
		btcx_riscmem_free(dev->pci,
				&dev->channels[chan_num].vidq.stopper);
442

443
		pr_warn("device %d released!\n", chan_num);
444
	}
445 446 447

}

448
int cx25821_video_register(struct cx25821_dev *dev)
449
{
450
	int err;
451
	int i;
452

453 454 455 456 457 458 459 460
	struct video_device cx25821_video_device = {
		.name = "cx25821-video",
		.fops = &video_fops,
		.minor = -1,
		.ioctl_ops = &video_ioctl_ops,
		.tvnorms = CX25821_NORMS,
		.current_norm = V4L2_STD_NTSC_M,
	};
461

462
	spin_lock_init(&dev->slock);
463

464 465
	for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) {
		cx25821_init_controls(dev, i);
466

467
		cx25821_risc_stopper(dev->pci, &dev->channels[i].vidq.stopper,
468
			dev->channels[i].sram_channels->dma_ctl, 0x11, 0);
469

470 471 472
		dev->channels[i].sram_channels = &cx25821_sram_channels[i];
		dev->channels[i].video_dev = NULL;
		dev->channels[i].resources = 0;
473

474 475 476 477 478 479 480 481
		cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff);

		INIT_LIST_HEAD(&dev->channels[i].vidq.active);
		INIT_LIST_HEAD(&dev->channels[i].vidq.queued);

		dev->channels[i].timeout_data.dev = dev;
		dev->channels[i].timeout_data.channel =
			&cx25821_sram_channels[i];
482
		dev->channels[i].vidq.timeout.function = cx25821_vid_timeout;
483 484 485
		dev->channels[i].vidq.timeout.data =
			(unsigned long)&dev->channels[i].timeout_data;
		init_timer(&dev->channels[i].vidq.timeout);
486

487
		/* register v4l devices */
488 489
		dev->channels[i].video_dev = cx25821_vdev_init(dev, dev->pci,
				&cx25821_video_device, "video");
490

491 492
		err = video_register_device(dev->channels[i].video_dev,
				VFL_TYPE_GRABBER, video_nr[dev->nr]);
493

494 495
		if (err < 0)
			goto fail_unreg;
496

497
	}
498

499
	/* set PCI interrupt */
500
	cx_set(PCI_INT_MSK, 0xff);
501

502 503
	/* initial device configuration */
	mutex_lock(&dev->lock);
504
#ifdef TUNER_FLAG
505
	dev->tvnorm = cx25821_video_device.current_norm;
506
	cx25821_set_tvnorm(dev, dev->tvnorm);
507
#endif
508
	mutex_unlock(&dev->lock);
509

510
	return 0;
511

512
fail_unreg:
513
	cx25821_video_unregister(dev, i);
514
	return err;
515 516
}

517
int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,
518
		 unsigned int *size)
519
{
520
	struct cx25821_fh *fh = q->priv_data;
521

522
	*size = fh->fmt->depth * fh->width * fh->height >> 3;
523

524 525
	if (0 == *count)
		*count = 32;
526

527 528
	if (*size * *count > vid_limit * 1024 * 1024)
		*count = (vid_limit * 1024 * 1024) / *size;
529

530
	return 0;
531 532
}

533
int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
534
		   enum v4l2_field field)
535
{
536 537 538
	struct cx25821_fh *fh = q->priv_data;
	struct cx25821_dev *dev = fh->dev;
	struct cx25821_buffer *buf =
539
		container_of(vb, struct cx25821_buffer, vb);
540
	int rc, init_buffer = 0;
541
	u32 line0_offset;
542 543
	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
	int bpl_local = LINE_SIZE_D1;
544
	int channel_opened = fh->channel_id;
545 546 547 548 549

	BUG_ON(NULL == fh->fmt);
	if (fh->width < 48 || fh->width > 720 ||
	    fh->height < 32 || fh->height > 576)
		return -EINVAL;
550

551
	buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
552

553 554
	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
		return -EINVAL;
555

556 557 558 559 560 561 562 563
	if (buf->fmt != fh->fmt ||
	    buf->vb.width != fh->width ||
	    buf->vb.height != fh->height || buf->vb.field != field) {
		buf->fmt = fh->fmt;
		buf->vb.width = fh->width;
		buf->vb.height = fh->height;
		buf->vb.field = field;
		init_buffer = 1;
564
	}
565 566 567 568 569

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		init_buffer = 1;
		rc = videobuf_iolock(q, &buf->vb, NULL);
		if (0 != rc) {
570
			printk(KERN_DEBUG pr_fmt("videobuf_iolock failed!\n"));
571
			goto fail;
572 573 574
		}
	}

575 576 577 578 579
	dprintk(1, "init_buffer=%d\n", init_buffer);

	if (init_buffer) {

		channel_opened = dev->channel_opened;
580 581
		if (channel_opened < 0 || channel_opened > 7)
			channel_opened = 7;
582

583 584
		if (dev->channels[channel_opened].pixel_formats ==
				PIXEL_FRMT_411)
585 586 587 588
			buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
		else
			buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);

589 590
		if (dev->channels[channel_opened].pixel_formats ==
				PIXEL_FRMT_411) {
591 592
			bpl_local = buf->bpl;
		} else {
593
			bpl_local = buf->bpl;   /* Default */
594 595

			if (channel_opened >= 0 && channel_opened <= 7) {
596 597
				if (dev->channels[channel_opened]
						.use_cif_resolution) {
598 599
					if (dev->tvnorm & V4L2_STD_PAL_BG ||
					    dev->tvnorm & V4L2_STD_PAL_DK)
600 601
						bpl_local = 352 << 1;
					else
602 603 604
						bpl_local = dev->channels[
							channel_opened].
							cif_width << 1;
605 606 607
				}
			}
		}
608

609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644
		switch (buf->vb.field) {
		case V4L2_FIELD_TOP:
			cx25821_risc_buffer(dev->pci, &buf->risc,
					    dma->sglist, 0, UNSET,
					    buf->bpl, 0, buf->vb.height);
			break;
		case V4L2_FIELD_BOTTOM:
			cx25821_risc_buffer(dev->pci, &buf->risc,
					    dma->sglist, UNSET, 0,
					    buf->bpl, 0, buf->vb.height);
			break;
		case V4L2_FIELD_INTERLACED:
			/* All other formats are top field first */
			line0_offset = 0;
			dprintk(1, "top field first\n");

			cx25821_risc_buffer(dev->pci, &buf->risc,
					    dma->sglist, line0_offset,
					    bpl_local, bpl_local, bpl_local,
					    buf->vb.height >> 1);
			break;
		case V4L2_FIELD_SEQ_TB:
			cx25821_risc_buffer(dev->pci, &buf->risc,
					    dma->sglist,
					    0, buf->bpl * (buf->vb.height >> 1),
					    buf->bpl, 0, buf->vb.height >> 1);
			break;
		case V4L2_FIELD_SEQ_BT:
			cx25821_risc_buffer(dev->pci, &buf->risc,
					    dma->sglist,
					    buf->bpl * (buf->vb.height >> 1), 0,
					    buf->bpl, 0, buf->vb.height >> 1);
			break;
		default:
			BUG();
		}
645
	}
646

647 648 649
	dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
		buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth,
		fh->fmt->name, (unsigned long)buf->risc.dma);
650

651
	buf->vb.state = VIDEOBUF_PREPARED;
652

653
	return 0;
654

655
fail:
656 657
	cx25821_free_buffer(q, buf);
	return rc;
658 659
}

660 661
void cx25821_buffer_release(struct videobuf_queue *q,
			    struct videobuf_buffer *vb)
662
{
663
	struct cx25821_buffer *buf =
664
		container_of(vb, struct cx25821_buffer, vb);
665

666
	cx25821_free_buffer(q, buf);
667 668 669 670
}

struct videobuf_queue *get_queue(struct cx25821_fh *fh)
{
671 672 673 674 675 676 677
	switch (fh->type) {
	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
		return &fh->vidq;
	default:
		BUG();
		return NULL;
	}
678 679
}

680
int cx25821_get_resource(struct cx25821_fh *fh, int resource)
681
{
682 683 684 685 686 687 688
	switch (fh->type) {
	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
		return resource;
	default:
		BUG();
		return 0;
	}
689 690
}

691
int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
692
{
693
	struct cx25821_fh *fh = file->private_data;
694

695
	return videobuf_mmap_mapper(get_queue(fh), vma);
696 697
}

698 699 700

static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
{
701
	struct cx25821_buffer *buf =
702
		container_of(vb, struct cx25821_buffer, vb);
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733
	struct cx25821_buffer *prev;
	struct cx25821_fh *fh = vq->priv_data;
	struct cx25821_dev *dev = fh->dev;
	struct cx25821_dmaqueue *q = &dev->channels[fh->channel_id].vidq;

	/* add jump to stopper */
	buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
	buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
	buf->risc.jmp[2] = cpu_to_le32(0);      /* bits 63-32 */

	dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);

	if (!list_empty(&q->queued)) {
		list_add_tail(&buf->vb.queue, &q->queued);
		buf->vb.state = VIDEOBUF_QUEUED;
		dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
				buf->vb.i);

	} else if (list_empty(&q->active)) {
		list_add_tail(&buf->vb.queue, &q->active);
		cx25821_start_video_dma(dev, q, buf,
				dev->channels[fh->channel_id].sram_channels);
		buf->vb.state = VIDEOBUF_ACTIVE;
		buf->count = q->count++;
		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
		dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
				buf, buf->vb.i, buf->count, q->count);
	} else {
		prev = list_entry(q->active.prev, struct cx25821_buffer,
				vb.queue);
		if (prev->vb.width == buf->vb.width
734 735
		   && prev->vb.height == buf->vb.height
		   && prev->fmt == buf->fmt) {
736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
			list_add_tail(&buf->vb.queue, &q->active);
			buf->vb.state = VIDEOBUF_ACTIVE;
			buf->count = q->count++;
			prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);

			/* 64 bit bits 63-32 */
			prev->risc.jmp[2] = cpu_to_le32(0);
			dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
					buf, buf->vb.i, buf->count);

		} else {
			list_add_tail(&buf->vb.queue, &q->queued);
			buf->vb.state = VIDEOBUF_QUEUED;
			dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
					buf->vb.i);
		}
	}

	if (list_empty(&q->active))
		dprintk(2, "active queue empty!\n");
756 757 758
}

static struct videobuf_queue_ops cx25821_video_qops = {
759 760 761 762
	.buf_setup = cx25821_buffer_setup,
	.buf_prepare = cx25821_buffer_prepare,
	.buf_queue = buffer_queue,
	.buf_release = cx25821_buffer_release,
763 764 765 766
};

static int video_open(struct file *file)
{
767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
	struct video_device *vdev = video_devdata(file);
	struct cx25821_dev *h, *dev = video_drvdata(file);
	struct cx25821_fh *fh;
	struct list_head *list;
	int minor = video_devdata(file)->minor;
	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	u32 pix_format;
	int ch_id = 0;
	int i;

	dprintk(1, "open dev=%s type=%s\n", video_device_node_name(vdev),
			v4l2_type_names[type]);

	/* allocate + initialize per filehandle data */
	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
	if (NULL == fh)
		return -ENOMEM;
784

785
	mutex_lock(&cx25821_devlist_mutex);
786

787 788 789
	list_for_each(list, &cx25821_devlist)
	{
		h = list_entry(list, struct cx25821_dev, devlist);
790

791 792
		for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) {
			if (h->channels[i].video_dev &&
793
			    h->channels[i].video_dev->minor == minor) {
794 795 796 797 798 799 800 801
				dev = h;
				ch_id = i;
				type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			}
		}
	}

	if (NULL == dev) {
802
		mutex_unlock(&cx25821_devlist_mutex);
803
		kfree(fh);
804
		return -ENODEV;
805
	}
806

807 808 809 810 811 812 813 814 815 816 817 818
	file->private_data = fh;
	fh->dev = dev;
	fh->type = type;
	fh->width = 720;
	fh->channel_id = ch_id;

	if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
		fh->height = 576;
	else
		fh->height = 480;

	dev->channel_opened = fh->channel_id;
819 820 821 822
	if (dev->channels[ch_id].pixel_formats == PIXEL_FRMT_411)
		pix_format = V4L2_PIX_FMT_Y41P;
	else
		pix_format = V4L2_PIX_FMT_YUYV;
823 824 825 826
	fh->fmt = cx25821_format_by_fourcc(pix_format);

	v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio);

827 828 829 830
	videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops, &dev->pci->dev,
			&dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE,
			V4L2_FIELD_INTERLACED, sizeof(struct cx25821_buffer),
			fh, NULL);
831

832
	dprintk(1, "post videobuf_queue_init()\n");
833
	mutex_unlock(&cx25821_devlist_mutex);
834

835
	return 0;
836 837 838
}

static ssize_t video_read(struct file *file, char __user * data, size_t count,
839
			 loff_t *ppos)
840
{
841
	struct cx25821_fh *fh = file->private_data;
842

843 844 845 846
	switch (fh->type) {
	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
		if (cx25821_res_locked(fh, RESOURCE_VIDEO0))
			return -EBUSY;
847

848
		return videobuf_read_one(&fh->vidq, data, count, ppos,
849
					file->f_flags & O_NONBLOCK);
850

851 852 853 854
	default:
		BUG();
		return 0;
	}
855 856 857
}

static unsigned int video_poll(struct file *file,
858
			      struct poll_table_struct *wait)
859
{
860 861 862 863 864 865 866 867
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_buffer *buf;

	if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
		/* streaming capture */
		if (list_empty(&fh->vidq.stream))
			return POLLERR;
		buf = list_entry(fh->vidq.stream.next,
868
				struct cx25821_buffer, vb.stream);
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
	} else {
		/* read() capture */
		buf = (struct cx25821_buffer *)fh->vidq.read_buf;
		if (NULL == buf)
			return POLLERR;
	}

	poll_wait(file, &buf->vb.done, wait);
	if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
		if (buf->vb.state == VIDEOBUF_DONE) {
			struct cx25821_dev *dev = fh->dev;

			if (dev && dev->channels[fh->channel_id]
					.use_cif_resolution) {
				u8 cam_id = *((char *)buf->vb.baddr + 3);
				memcpy((char *)buf->vb.baddr,
885 886
				      (char *)buf->vb.baddr + (fh->width * 2),
				      (fh->width * 2));
887 888 889
				*((char *)buf->vb.baddr + 3) = cam_id;
			}
		}
890

891 892
		return POLLIN | POLLRDNORM;
	}
893

894
	return 0;
895 896 897 898
}

static int video_release(struct file *file)
{
899 900
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_dev *dev = fh->dev;
901

902 903
	/* stop the risc engine and fifo */
	cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
904

905 906 907 908 909
	/* stop video capture */
	if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
		videobuf_queue_cancel(&fh->vidq);
		cx25821_res_free(dev, fh, RESOURCE_VIDEO0);
	}
910

911 912 913 914
	if (fh->vidq.read_buf) {
		cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
		kfree(fh->vidq.read_buf);
	}
915

916
	videobuf_mmap_free(&fh->vidq);
917

918 919 920
	v4l2_prio_close(&dev->channels[fh->channel_id].prio, fh->prio);
	file->private_data = NULL;
	kfree(fh);
921

922
	return 0;
923 924 925 926
}

static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
927 928
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = fh->dev;
929

930 931
	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
		return -EINVAL;
932

933 934
	if (unlikely(i != fh->type))
		return -EINVAL;
935

936 937 938
	if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh,
						RESOURCE_VIDEO0))))
		return -EBUSY;
939

940
	return videobuf_streamon(get_queue(fh));
941 942 943 944
}

static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
{
945 946 947 948 949 950 951 952 953 954 955 956 957 958 959
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = fh->dev;
	int err, res;

	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;
	if (i != fh->type)
		return -EINVAL;

	res = cx25821_get_resource(fh, RESOURCE_VIDEO0);
	err = videobuf_streamoff(get_queue(fh));
	if (err < 0)
		return err;
	cx25821_res_free(dev, fh, res);
	return 0;
960 961 962
}

static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
963
				struct v4l2_format *f)
964
{
965 966
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
967
	struct v4l2_mbus_framefmt mbus_fmt;
968 969 970 971 972 973 974 975 976
	int err;
	int pix_format = PIXEL_FRMT_422;

	if (fh) {
		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
				      fh->prio);
		if (0 != err)
			return err;
	}
977

978 979
	dprintk(2, "%s()\n", __func__);
	err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
980

981 982
	if (0 != err)
		return err;
983

984 985
	fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
	fh->vidq.field = f->fmt.pix.field;
986

987 988 989
	/* check if width and height is valid based on set standard */
	if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm))
		fh->width = f->fmt.pix.width;
990

991 992
	if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm))
		fh->height = f->fmt.pix.height;
993

994 995 996 997 998 999
	if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
		pix_format = PIXEL_FRMT_411;
	else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
		pix_format = PIXEL_FRMT_422;
	else
		return -EINVAL;
1000

1001
	cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
1002

1003 1004 1005 1006 1007
	/* check if cif resolution */
	if (fh->width == 320 || fh->width == 352)
		dev->channels[fh->channel_id].use_cif_resolution = 1;
	else
		dev->channels[fh->channel_id].use_cif_resolution = 0;
1008

1009 1010
	dev->channels[fh->channel_id].cif_width = fh->width;
	medusa_set_resolution(dev, fh->width, SRAM_CH00);
1011

1012 1013
	dprintk(2, "%s(): width=%d height=%d field=%d\n", __func__, fh->width,
		fh->height, fh->vidq.field);
1014 1015
	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
	cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt);
1016

1017
	return 0;
1018 1019 1020 1021
}

static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
{
1022 1023 1024
	int ret_val = 0;
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1025

1026
	ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
1027

1028
	p->sequence = dev->channels[fh->channel_id].vidq.count;
1029

1030
	return ret_val;
1031 1032 1033 1034
}

static int vidioc_log_status(struct file *file, void *priv)
{
1035 1036 1037
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	struct cx25821_fh *fh = priv;
	char name[32 + 2];
1038

1039 1040 1041
	struct sram_channel *sram_ch = dev->channels[fh->channel_id]
								.sram_channels;
	u32 tmp = 0;
1042

1043
	snprintf(name, sizeof(name), "%s/2", dev->name);
1044 1045
	pr_info("%s/2: ============  START LOG STATUS  ============\n",
		dev->name);
1046 1047
	cx25821_call_all(dev, core, log_status);
	tmp = cx_read(sram_ch->dma_ctl);
1048 1049 1050 1051
	pr_info("Video input 0 is %s\n",
		(tmp & 0x11) ? "streaming" : "stopped");
	pr_info("%s/2: =============  END LOG STATUS  =============\n",
		dev->name);
1052
	return 0;
1053 1054 1055
}

static int vidioc_s_ctrl(struct file *file, void *priv,
1056
			struct v4l2_control *ctl)
1057
{
1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	int err;

	if (fh) {
		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
				      fh->prio);
		if (0 != err)
			return err;
	}

	return cx25821_set_control(dev, ctl, fh->channel_id);
1070 1071
}

1072 1073 1074
/* VIDEO IOCTLS */
int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
				 struct v4l2_format *f)
1075
{
1076
	struct cx25821_fh *fh = priv;
1077

1078 1079 1080 1081 1082 1083
	f->fmt.pix.width = fh->width;
	f->fmt.pix.height = fh->height;
	f->fmt.pix.field = fh->vidq.field;
	f->fmt.pix.pixelformat = fh->fmt->fourcc;
	f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3;
	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
1084

1085
	return 0;
1086 1087
}

1088 1089
int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
				   struct v4l2_format *f)
1090
{
1091 1092 1093
	struct cx25821_fmt *fmt;
	enum v4l2_field field;
	unsigned int maxw, maxh;
1094

1095
	fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
1096 1097
	if (NULL == fmt)
		return -EINVAL;
1098

1099 1100 1101
	field = f->fmt.pix.field;
	maxw = 720;
	maxh = 576;
1102

1103
	if (V4L2_FIELD_ANY == field) {
1104 1105 1106 1107
		if (f->fmt.pix.height > maxh / 2)
			field = V4L2_FIELD_INTERLACED;
		else
			field = V4L2_FIELD_TOP;
1108
	}
1109

1110 1111 1112 1113 1114 1115 1116 1117 1118 1119
	switch (field) {
	case V4L2_FIELD_TOP:
	case V4L2_FIELD_BOTTOM:
		maxh = maxh / 2;
		break;
	case V4L2_FIELD_INTERLACED:
		break;
	default:
		return -EINVAL;
	}
1120

1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132
	f->fmt.pix.field = field;
	if (f->fmt.pix.height < 32)
		f->fmt.pix.height = 32;
	if (f->fmt.pix.height > maxh)
		f->fmt.pix.height = maxh;
	if (f->fmt.pix.width < 48)
		f->fmt.pix.width = 48;
	if (f->fmt.pix.width > maxw)
		f->fmt.pix.width = maxw;
	f->fmt.pix.width &= ~0x03;
	f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
	f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
1133

1134
	return 0;
1135 1136
}

1137 1138
int cx25821_vidioc_querycap(struct file *file, void *priv,
			    struct v4l2_capability *cap)
1139
{
1140 1141 1142 1143 1144 1145
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;

	strcpy(cap->driver, "cx25821");
	strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
	sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
	cap->version = CX25821_VERSION_CODE;
1146 1147
	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
		V4L2_CAP_STREAMING;
1148 1149 1150
	if (UNSET != dev->tuner_type)
		cap->capabilities |= V4L2_CAP_TUNER;
	return 0;
1151 1152
}

1153
int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1154
			    struct v4l2_fmtdesc *f)
1155
{
1156 1157
	if (unlikely(f->index >= ARRAY_SIZE(formats)))
		return -EINVAL;
1158

1159 1160
	strlcpy(f->description, formats[f->index].name, sizeof(f->description));
	f->pixelformat = formats[f->index].fourcc;
1161

1162
	return 0;
1163 1164
}

1165 1166
int cx25821_vidioc_reqbufs(struct file *file, void *priv,
			   struct v4l2_requestbuffers *p)
1167
{
1168 1169
	struct cx25821_fh *fh = priv;
	return videobuf_reqbufs(get_queue(fh), p);
1170 1171
}

1172 1173
int cx25821_vidioc_querybuf(struct file *file, void *priv,
			    struct v4l2_buffer *p)
1174
{
1175 1176
	struct cx25821_fh *fh = priv;
	return videobuf_querybuf(get_queue(fh), p);
1177 1178
}

1179
int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1180
{
1181 1182
	struct cx25821_fh *fh = priv;
	return videobuf_qbuf(get_queue(fh), p);
1183 1184
}

1185
int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
1186 1187
{
	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
1188
	struct cx25821_fh *fh = f;
1189

1190
	*p = v4l2_prio_max(&dev->channels[fh->channel_id].prio);
1191 1192 1193 1194

	return 0;
}

1195 1196
int cx25821_vidioc_s_priority(struct file *file, void *f,
			      enum v4l2_priority prio)
1197 1198 1199 1200
{
	struct cx25821_fh *fh = f;
	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;

1201 1202
	return v4l2_prio_change(&dev->channels[fh->channel_id].prio, &fh->prio,
			prio);
1203 1204 1205
}

#ifdef TUNER_FLAG
1206
int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
1207
{
1208 1209 1210
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	int err;
1211

1212
	dprintk(1, "%s()\n", __func__);
1213

1214
	if (fh) {
1215 1216
		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
				      fh->prio);
1217 1218 1219
		if (0 != err)
			return err;
	}
1220

1221
	if (dev->tvnorm == *tvnorms)
1222
		return 0;
1223

1224 1225 1226
	mutex_lock(&dev->lock);
	cx25821_set_tvnorm(dev, *tvnorms);
	mutex_unlock(&dev->lock);
1227

1228
	medusa_set_videostandard(dev);
1229

1230
	return 0;
1231 1232 1233 1234 1235
}
#endif

int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
{
1236
	static const char * const iname[] = {
1237 1238 1239 1240 1241 1242
		[CX25821_VMUX_COMPOSITE] = "Composite",
		[CX25821_VMUX_SVIDEO] = "S-Video",
		[CX25821_VMUX_DEBUG] = "for debug only",
	};
	unsigned int n;
	dprintk(1, "%s()\n", __func__);
1243

1244
	n = i->index;
1245
	if (n >= 2)
1246 1247 1248 1249
		return -EINVAL;

	if (0 == INPUT(n)->type)
		return -EINVAL;
1250

1251 1252
	i->type = V4L2_INPUT_TYPE_CAMERA;
	strcpy(i->name, iname[INPUT(n)->type]);
1253

1254 1255
	i->std = CX25821_NORMS;
	return 0;
1256 1257
}

1258 1259
int cx25821_vidioc_enum_input(struct file *file, void *priv,
			      struct v4l2_input *i)
1260
{
1261 1262 1263
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	dprintk(1, "%s()\n", __func__);
	return cx25821_enum_input(dev, i);
1264 1265
}

1266
int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1267
{
1268
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1269

1270
	*i = dev->input;
1271
	dprintk(1, "%s(): returns %d\n", __func__, *i);
1272
	return 0;
1273 1274
}

1275
int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
1276
{
1277 1278 1279
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	int err;
1280

1281
	dprintk(1, "%s(%d)\n", __func__, i);
1282

1283
	if (fh) {
1284 1285
		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
				      fh->prio);
1286 1287 1288
		if (0 != err)
			return err;
	}
1289

1290
	if (i >= CX25821_NR_INPUT) {
1291
		dprintk(1, "%s(): -EINVAL\n", __func__);
1292 1293
		return -EINVAL;
	}
1294

1295 1296 1297 1298
	mutex_lock(&dev->lock);
	cx25821_video_mux(dev, i);
	mutex_unlock(&dev->lock);
	return 0;
1299 1300 1301
}

#ifdef TUNER_FLAG
1302 1303
int cx25821_vidioc_g_frequency(struct file *file, void *priv,
			       struct v4l2_frequency *f)
1304
{
1305 1306
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = fh->dev;
1307

1308
	f->frequency = dev->freq;
1309

1310
	cx25821_call_all(dev, tuner, g_frequency, f);
1311

1312
	return 0;
1313 1314
}

1315
int cx25821_set_freq(struct cx25821_dev *dev, const struct v4l2_frequency *f)
1316
{
1317 1318
	mutex_lock(&dev->lock);
	dev->freq = f->frequency;
1319

1320
	cx25821_call_all(dev, tuner, s_frequency, f);
1321

1322 1323
	/* When changing channels it is required to reset TVAUDIO */
	msleep(10);
1324

1325
	mutex_unlock(&dev->lock);
1326

1327
	return 0;
1328 1329
}

1330
int cx25821_vidioc_s_frequency(struct file *file, void *priv,
1331
			       const struct v4l2_frequency *f)
1332
{
1333
	struct cx25821_fh *fh = priv;
1334
	struct cx25821_dev *dev;
1335
	int err;
1336

1337
	if (fh) {
1338 1339 1340
		dev = fh->dev;
		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
				      fh->prio);
1341 1342
		if (0 != err)
			return err;
1343 1344 1345
	} else {
		pr_err("Invalid fh pointer!\n");
		return -EINVAL;
1346 1347 1348
	}

	return cx25821_set_freq(dev, f);
1349 1350 1351 1352
}
#endif

#ifdef CONFIG_VIDEO_ADV_DEBUG
1353
int cx25821_vidioc_g_register(struct file *file, void *fh,
1354
		      struct v4l2_dbg_register *reg)
1355
{
1356
	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
1357

1358 1359
	if (!v4l2_chip_match_host(&reg->match))
		return -EINVAL;
1360

1361
	cx25821_call_all(dev, core, g_register, reg);
1362

1363
	return 0;
1364 1365
}

1366
int cx25821_vidioc_s_register(struct file *file, void *fh,
1367
		      struct v4l2_dbg_register *reg)
1368
{
1369
	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
1370

1371 1372
	if (!v4l2_chip_match_host(&reg->match))
		return -EINVAL;
1373

1374
	cx25821_call_all(dev, core, s_register, reg);
1375

1376
	return 0;
1377 1378 1379 1380 1381
}

#endif

#ifdef TUNER_FLAG
1382
int cx25821_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1383
{
1384
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1385

1386 1387 1388 1389
	if (unlikely(UNSET == dev->tuner_type))
		return -EINVAL;
	if (0 != t->index)
		return -EINVAL;
1390

1391 1392 1393 1394
	strcpy(t->name, "Television");
	t->type = V4L2_TUNER_ANALOG_TV;
	t->capability = V4L2_TUNER_CAP_NORM;
	t->rangehigh = 0xffffffffUL;
1395

1396 1397
	t->signal = 0xffff;	/* LOCKED */
	return 0;
1398 1399
}

1400
int cx25821_vidioc_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t)
1401
{
1402 1403 1404
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	struct cx25821_fh *fh = priv;
	int err;
1405

1406
	if (fh) {
1407 1408
		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
				      fh->prio);
1409 1410 1411
		if (0 != err)
			return err;
	}
1412

1413 1414 1415 1416 1417 1418 1419
	dprintk(1, "%s()\n", __func__);
	if (UNSET == dev->tuner_type)
		return -EINVAL;
	if (0 != t->index)
		return -EINVAL;

	return 0;
1420 1421 1422
}

#endif
1423
/*****************************************************************************/
1424
static const struct v4l2_queryctrl no_ctl = {
1425
	.name = "42",
1426 1427 1428 1429 1430 1431
	.flags = V4L2_CTRL_FLAG_DISABLED,
};

static struct v4l2_queryctrl cx25821_ctls[] = {
	/* --- video --- */
	{
1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463
		.id = V4L2_CID_BRIGHTNESS,
		.name = "Brightness",
		.minimum = 0,
		.maximum = 10000,
		.step = 1,
		.default_value = 6200,
		.type = V4L2_CTRL_TYPE_INTEGER,
	}, {
		.id = V4L2_CID_CONTRAST,
		.name = "Contrast",
		.minimum = 0,
		.maximum = 10000,
		.step = 1,
		.default_value = 5000,
		.type = V4L2_CTRL_TYPE_INTEGER,
	}, {
		.id = V4L2_CID_SATURATION,
		.name = "Saturation",
		.minimum = 0,
		.maximum = 10000,
		.step = 1,
		.default_value = 5000,
		.type = V4L2_CTRL_TYPE_INTEGER,
	}, {
		.id = V4L2_CID_HUE,
		.name = "Hue",
		.minimum = 0,
		.maximum = 10000,
		.step = 1,
		.default_value = 5000,
		.type = V4L2_CTRL_TYPE_INTEGER,
	}
1464 1465 1466 1467 1468 1469 1470
};
static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);

static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
{
	int i;

1471
	if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483
		return -EINVAL;
	for (i = 0; i < CX25821_CTLS; i++)
		if (cx25821_ctls[i].id == qctrl->id)
			break;
	if (i == CX25821_CTLS) {
		*qctrl = no_ctl;
		return 0;
	}
	*qctrl = cx25821_ctls[i];
	return 0;
}

1484
int cx25821_vidioc_queryctrl(struct file *file, void *priv,
1485
		     struct v4l2_queryctrl *qctrl)
1486
{
1487 1488 1489 1490 1491 1492
	return cx25821_ctrl_query(qctrl);
}

/* ------------------------------------------------------------------ */
/* VIDEO CTRL IOCTLS                                                  */

1493
static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
1494 1495 1496 1497 1498
{
	unsigned int i;

	for (i = 0; i < CX25821_CTLS; i++)
		if (cx25821_ctls[i].id == id)
1499
			return cx25821_ctls + i;
1500 1501 1502
	return NULL;
}

1503 1504
int cx25821_vidioc_g_ctrl(struct file *file, void *priv,
			  struct v4l2_control *ctl)
1505
{
1506
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1507
	struct cx25821_fh *fh = priv;
1508

1509
	const struct v4l2_queryctrl *ctrl;
1510 1511 1512 1513 1514

	ctrl = ctrl_by_id(ctl->id);

	if (NULL == ctrl)
		return -EINVAL;
1515 1516
	switch (ctl->id) {
	case V4L2_CID_BRIGHTNESS:
1517
		ctl->value = dev->channels[fh->channel_id].ctl_bright;
1518
		break;
1519
	case V4L2_CID_HUE:
1520
		ctl->value = dev->channels[fh->channel_id].ctl_hue;
1521
		break;
1522
	case V4L2_CID_CONTRAST:
1523
		ctl->value = dev->channels[fh->channel_id].ctl_contrast;
1524
		break;
1525
	case V4L2_CID_SATURATION:
1526
		ctl->value = dev->channels[fh->channel_id].ctl_saturation;
1527
		break;
1528
	}
1529 1530 1531 1532
	return 0;
}

int cx25821_set_control(struct cx25821_dev *dev,
1533
			struct v4l2_control *ctl, int chan_num)
1534
{
1535
	int err;
1536
	const struct v4l2_queryctrl *ctrl;
1537

1538
	err = -EINVAL;
1539 1540 1541

	ctrl = ctrl_by_id(ctl->id);

1542
	if (NULL == ctrl)
1543 1544
		return err;

1545 1546 1547 1548
	switch (ctrl->type) {
	case V4L2_CTRL_TYPE_BOOLEAN:
	case V4L2_CTRL_TYPE_MENU:
	case V4L2_CTRL_TYPE_INTEGER:
1549 1550 1551 1552 1553
		if (ctl->value < ctrl->minimum)
			ctl->value = ctrl->minimum;
		if (ctl->value > ctrl->maximum)
			ctl->value = ctrl->maximum;
		break;
1554 1555
	default:
		/* nothing */ ;
1556
	}
1557

1558 1559
	switch (ctl->id) {
	case V4L2_CID_BRIGHTNESS:
1560
		dev->channels[chan_num].ctl_bright = ctl->value;
1561 1562
		medusa_set_brightness(dev, ctl->value, chan_num);
		break;
1563
	case V4L2_CID_HUE:
1564
		dev->channels[chan_num].ctl_hue = ctl->value;
1565 1566
		medusa_set_hue(dev, ctl->value, chan_num);
		break;
1567
	case V4L2_CID_CONTRAST:
1568
		dev->channels[chan_num].ctl_contrast = ctl->value;
1569 1570
		medusa_set_contrast(dev, ctl->value, chan_num);
		break;
1571
	case V4L2_CID_SATURATION:
1572
		dev->channels[chan_num].ctl_saturation = ctl->value;
1573 1574
		medusa_set_saturation(dev, ctl->value, chan_num);
		break;
1575
	}
1576

1577
	err = 0;
1578 1579 1580 1581

	return err;
}

1582
static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num)
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593
{
	struct v4l2_control ctrl;
	int i;
	for (i = 0; i < CX25821_CTLS; i++) {
		ctrl.id = cx25821_ctls[i].id;
		ctrl.value = cx25821_ctls[i].default_value;

		cx25821_set_control(dev, &ctrl, chan_num);
	}
}

1594 1595
int cx25821_vidioc_cropcap(struct file *file, void *priv,
			   struct v4l2_cropcap *cropcap)
1596 1597
{
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1598

1599 1600
	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;
1601 1602
	cropcap->bounds.top = 0;
	cropcap->bounds.left = 0;
1603 1604
	cropcap->bounds.width = 720;
	cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
1605
	cropcap->pixelaspect.numerator =
1606
		dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10;
1607
	cropcap->pixelaspect.denominator =
1608
		dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11;
1609 1610 1611 1612
	cropcap->defrect = cropcap->bounds;
	return 0;
}

1613
int cx25821_vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop)
1614
{
1615 1616 1617 1618 1619
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	struct cx25821_fh *fh = priv;
	int err;

	if (fh) {
1620 1621
		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
				      fh->prio);
1622 1623 1624
		if (0 != err)
			return err;
	}
1625
	/* cx25821_vidioc_s_crop not supported */
1626
	return -EINVAL;
1627 1628
}

1629
int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1630
{
1631
	/* cx25821_vidioc_g_crop not supported */
1632
	return -EINVAL;
1633 1634
}

1635
int cx25821_vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
1636
{
1637
	/* medusa does not support video standard sensing of current input */
1638
	*norm = CX25821_NORMS;
1639

1640
	return 0;
1641 1642
}

1643
int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm)
1644
{
1645 1646 1647 1648 1649 1650
	if (tvnorm == V4L2_STD_PAL_BG) {
		if (width == 352 || width == 720)
			return 1;
		else
			return 0;
	}
1651

1652 1653 1654 1655 1656 1657 1658
	if (tvnorm == V4L2_STD_NTSC_M) {
		if (width == 320 || width == 352 || width == 720)
			return 1;
		else
			return 0;
	}
	return 0;
1659 1660
}

1661
int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm)
1662
{
1663 1664 1665 1666 1667 1668
	if (tvnorm == V4L2_STD_PAL_BG) {
		if (height == 576 || height == 288)
			return 1;
		else
			return 0;
	}
1669

1670 1671 1672 1673 1674 1675
	if (tvnorm == V4L2_STD_NTSC_M) {
		if (height == 480 || height == 240)
			return 1;
		else
			return 0;
	}
1676

1677
	return 0;
1678
}
1679 1680

static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
1681
				 unsigned long arg)
1682
{
1683 1684 1685 1686
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_dev *dev = fh->dev;
	int command = 0;
	struct upstream_user_struct *data_from_user;
1687

1688
	data_from_user = (struct upstream_user_struct *)arg;
1689

1690 1691 1692 1693
	if (!data_from_user) {
		pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
		return 0;
	}
1694

1695
	command = data_from_user->command;
1696

1697 1698
	if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO)
		return 0;
1699

1700 1701 1702 1703 1704 1705
	dev->input_filename = data_from_user->input_filename;
	dev->input_audiofilename = data_from_user->input_filename;
	dev->vid_stdname = data_from_user->vid_stdname;
	dev->pixel_format = data_from_user->pixel_format;
	dev->channel_select = data_from_user->channel_select;
	dev->command = data_from_user->command;
1706

1707 1708 1709 1710
	switch (command) {
	case UPSTREAM_START_VIDEO:
		cx25821_start_upstream_video_ch1(dev, data_from_user);
		break;
1711

1712 1713 1714 1715
	case UPSTREAM_STOP_VIDEO:
		cx25821_stop_upstream_video_ch1(dev);
		break;
	}
1716

1717
	return 0;
1718 1719 1720
}

static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
1721
				  unsigned long arg)
1722
{
1723 1724 1725 1726
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_dev *dev = fh->dev;
	int command = 0;
	struct upstream_user_struct *data_from_user;
1727

1728
	data_from_user = (struct upstream_user_struct *)arg;
1729

1730 1731 1732 1733
	if (!data_from_user) {
		pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
		return 0;
	}
1734

1735
	command = data_from_user->command;
1736

1737 1738
	if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO)
		return 0;
1739

1740 1741 1742 1743 1744 1745
	dev->input_filename_ch2 = data_from_user->input_filename;
	dev->input_audiofilename = data_from_user->input_filename;
	dev->vid_stdname_ch2 = data_from_user->vid_stdname;
	dev->pixel_format_ch2 = data_from_user->pixel_format;
	dev->channel_select_ch2 = data_from_user->channel_select;
	dev->command_ch2 = data_from_user->command;
1746

1747 1748 1749 1750
	switch (command) {
	case UPSTREAM_START_VIDEO:
		cx25821_start_upstream_video_ch2(dev, data_from_user);
		break;
1751

1752 1753 1754 1755
	case UPSTREAM_STOP_VIDEO:
		cx25821_stop_upstream_video_ch2(dev);
		break;
	}
1756

1757
	return 0;
1758 1759 1760
}

static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
1761
				  unsigned long arg)
1762
{
1763 1764 1765 1766
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_dev *dev = fh->dev;
	int command = 0;
	struct upstream_user_struct *data_from_user;
1767

1768
	data_from_user = (struct upstream_user_struct *)arg;
1769

1770 1771 1772 1773
	if (!data_from_user) {
		pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
		return 0;
	}
1774

1775
	command = data_from_user->command;
1776

1777 1778
	if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO)
		return 0;
1779

1780 1781 1782 1783 1784 1785
	dev->input_filename = data_from_user->input_filename;
	dev->input_audiofilename = data_from_user->input_filename;
	dev->vid_stdname = data_from_user->vid_stdname;
	dev->pixel_format = data_from_user->pixel_format;
	dev->channel_select = data_from_user->channel_select;
	dev->command = data_from_user->command;
1786

1787 1788 1789 1790
	switch (command) {
	case UPSTREAM_START_AUDIO:
		cx25821_start_upstream_audio(dev, data_from_user);
		break;
1791

1792 1793 1794 1795
	case UPSTREAM_STOP_AUDIO:
		cx25821_stop_upstream_audio(dev);
		break;
	}
1796

1797
	return 0;
1798 1799 1800
}

static long video_ioctl_set(struct file *file, unsigned int cmd,
1801
			   unsigned long arg)
1802
{
1803 1804 1805 1806 1807
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_dev *dev = fh->dev;
	struct downstream_user_struct *data_from_user;
	int command;
	int width = 720;
1808 1809 1810 1811 1812
	int selected_channel = 0;
	int pix_format = 0;
	int i = 0;
	int cif_enable = 0;
	int cif_width = 0;
1813

1814
	data_from_user = (struct downstream_user_struct *)arg;
1815

1816 1817 1818 1819
	if (!data_from_user) {
		pr_err("%s(): User data is INVALID. Returning\n", __func__);
		return 0;
	}
1820

1821
	command = data_from_user->command;
1822

1823
	if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
1824 1825 1826
	   && command != ENABLE_CIF_RESOLUTION && command != REG_READ
	   && command != REG_WRITE && command != MEDUSA_READ
	   && command != MEDUSA_WRITE) {
1827 1828
		return 0;
	}
1829

1830 1831
	switch (command) {
	case SET_VIDEO_STD:
1832 1833 1834 1835
		if (!strcmp(data_from_user->vid_stdname, "PAL"))
			dev->tvnorm = V4L2_STD_PAL_BG;
		else
			dev->tvnorm = V4L2_STD_NTSC_M;
1836 1837
		medusa_set_videostandard(dev);
		break;
1838

1839 1840 1841 1842 1843 1844 1845 1846
	case SET_PIXEL_FORMAT:
		selected_channel = data_from_user->decoder_select;
		pix_format = data_from_user->pixel_format;

		if (!(selected_channel <= 7 && selected_channel >= 0)) {
			selected_channel -= 4;
			selected_channel = selected_channel % 8;
		}
1847

1848 1849
		if (selected_channel >= 0)
			cx25821_set_pixel_format(dev, selected_channel,
1850
						pix_format);
1851

1852 1853 1854 1855 1856 1857 1858 1859 1860
		break;

	case ENABLE_CIF_RESOLUTION:
		selected_channel = data_from_user->decoder_select;
		cif_enable = data_from_user->cif_resolution_enable;
		cif_width = data_from_user->cif_width;

		if (cif_enable) {
			if (dev->tvnorm & V4L2_STD_PAL_BG
1861
			    || dev->tvnorm & V4L2_STD_PAL_DK) {
1862
				width = 352;
1863 1864 1865 1866 1867
			} else {
				width = cif_width;
				if (cif_width != 320 && cif_width != 352)
					width = 320;
			}
1868 1869 1870 1871 1872 1873 1874 1875
		}

		if (!(selected_channel <= 7 && selected_channel >= 0)) {
			selected_channel -= 4;
			selected_channel = selected_channel % 8;
		}

		if (selected_channel <= 7 && selected_channel >= 0) {
1876 1877
			dev->channels[selected_channel].use_cif_resolution =
				cif_enable;
1878 1879 1880 1881 1882 1883 1884 1885
			dev->channels[selected_channel].cif_width = width;
		} else {
			for (i = 0; i < VID_CHANNEL_NUM; i++) {
				dev->channels[i].use_cif_resolution =
					cif_enable;
				dev->channels[i].cif_width = width;
			}
		}
1886

1887 1888 1889 1890 1891 1892 1893 1894 1895
		medusa_set_resolution(dev, width, selected_channel);
		break;
	case REG_READ:
		data_from_user->reg_data = cx_read(data_from_user->reg_address);
		break;
	case REG_WRITE:
		cx_write(data_from_user->reg_address, data_from_user->reg_data);
		break;
	case MEDUSA_READ:
1896
		cx25821_i2c_read(&dev->i2c_bus[0],
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907
					 (u16) data_from_user->reg_address,
					 &data_from_user->reg_data);
		break;
	case MEDUSA_WRITE:
		cx25821_i2c_write(&dev->i2c_bus[0],
				  (u16) data_from_user->reg_address,
				  data_from_user->reg_data);
		break;
	}

	return 0;
1908 1909 1910
}

static long cx25821_video_ioctl(struct file *file,
1911
				unsigned int cmd, unsigned long arg)
1912
{
1913
	int ret = 0;
1914

1915
	struct cx25821_fh *fh = file->private_data;
1916

1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930
	/* check to see if it's the video upstream */
	if (fh->channel_id == SRAM_CH09) {
		ret = video_ioctl_upstream9(file, cmd, arg);
		return ret;
	} else if (fh->channel_id == SRAM_CH10) {
		ret = video_ioctl_upstream10(file, cmd, arg);
		return ret;
	} else if (fh->channel_id == SRAM_CH11) {
		ret = video_ioctl_upstream11(file, cmd, arg);
		ret = video_ioctl_set(file, cmd, arg);
		return ret;
	}

	return video_ioctl2(file, cmd, arg);
1931 1932 1933 1934
}

/* exported stuff */
static const struct v4l2_file_operations video_fops = {
1935 1936 1937 1938 1939 1940 1941
	.owner = THIS_MODULE,
	.open = video_open,
	.release = video_release,
	.read = video_read,
	.poll = video_poll,
	.mmap = cx25821_video_mmap,
	.ioctl = cx25821_video_ioctl,
1942 1943 1944
};

static const struct v4l2_ioctl_ops video_ioctl_ops = {
1945 1946 1947 1948 1949 1950 1951 1952 1953
	.vidioc_querycap = cx25821_vidioc_querycap,
	.vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
	.vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
	.vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
	.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
	.vidioc_reqbufs = cx25821_vidioc_reqbufs,
	.vidioc_querybuf = cx25821_vidioc_querybuf,
	.vidioc_qbuf = cx25821_vidioc_qbuf,
	.vidioc_dqbuf = vidioc_dqbuf,
1954
#ifdef TUNER_FLAG
1955 1956
	.vidioc_s_std = cx25821_vidioc_s_std,
	.vidioc_querystd = cx25821_vidioc_querystd,
1957
#endif
1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971
	.vidioc_cropcap = cx25821_vidioc_cropcap,
	.vidioc_s_crop = cx25821_vidioc_s_crop,
	.vidioc_g_crop = cx25821_vidioc_g_crop,
	.vidioc_enum_input = cx25821_vidioc_enum_input,
	.vidioc_g_input = cx25821_vidioc_g_input,
	.vidioc_s_input = cx25821_vidioc_s_input,
	.vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
	.vidioc_s_ctrl = vidioc_s_ctrl,
	.vidioc_queryctrl = cx25821_vidioc_queryctrl,
	.vidioc_streamon = vidioc_streamon,
	.vidioc_streamoff = vidioc_streamoff,
	.vidioc_log_status = vidioc_log_status,
	.vidioc_g_priority = cx25821_vidioc_g_priority,
	.vidioc_s_priority = cx25821_vidioc_s_priority,
1972
#ifdef TUNER_FLAG
1973 1974 1975 1976
	.vidioc_g_tuner = cx25821_vidioc_g_tuner,
	.vidioc_s_tuner = cx25821_vidioc_s_tuner,
	.vidioc_g_frequency = cx25821_vidioc_g_frequency,
	.vidioc_s_frequency = cx25821_vidioc_s_frequency,
1977 1978
#endif
#ifdef CONFIG_VIDEO_ADV_DEBUG
1979 1980
	.vidioc_g_register = cx25821_vidioc_g_register,
	.vidioc_s_register = cx25821_vidioc_s_register,
1981 1982 1983 1984
#endif
};

struct video_device cx25821_videoioctl_template = {
1985 1986 1987 1988 1989
	.name = "cx25821-videoioctl",
	.fops = &video_fops,
	.ioctl_ops = &video_ioctl_ops,
	.tvnorms = CX25821_NORMS,
	.current_norm = V4L2_STD_NTSC_M,
1990
};