cx25821-video.c 39.7 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
static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
36 37 38 39 40

module_param_array(video_nr, int, NULL, 0444);

MODULE_PARM_DESC(video_nr, "video device numbers");

41
static unsigned int video_debug = VIDEO_DEBUG;
42 43 44 45 46 47 48
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]");

49
static unsigned int vid_limit = 16;
50 51 52 53 54
module_param(vid_limit, int, 0644);
MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");

#define FORMAT_FLAGS_PACKED       0x01

55
static const struct cx25821_fmt formats[] = {
56
	{
57 58 59 60
		.name = "8 bpp, gray",
		.fourcc = V4L2_PIX_FMT_GREY,
		.depth = 8,
		.flags = FORMAT_FLAGS_PACKED,
61
	 }, {
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
		.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,
	},
82 83
};

84
static const struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc)
85
{
86
	unsigned int i;
87

88
	if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P)
89
		return formats + 1;
90

91 92 93
	for (i = 0; i < ARRAY_SIZE(formats); i++)
		if (formats[i].fourcc == fourcc)
			return formats + i;
94

95
	pr_err("%s(0x%08x) NOT FOUND\n", __func__, fourcc);
96
	return NULL;
97 98
}

99 100
void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
			  u32 count)
101
{
102 103
	struct cx25821_buffer *buf;
	int bc;
104

105 106 107 108 109
	for (bc = 0;; bc++) {
		if (list_empty(&q->active)) {
			dprintk(1, "bc=%d (=0: active empty)\n", bc);
			break;
		}
110

111 112
		buf = list_entry(q->active.next, struct cx25821_buffer,
				vb.queue);
113

114 115 116
		/* count comes from the hw and it is 16bit wide --
		 * this trick handles wrap-arounds correctly for
		 * up to 32767 buffers in flight... */
117
		if ((s16) (count - buf->count) < 0)
118
			break;
119

120
		v4l2_get_timestamp(&buf->vb.ts);
121 122 123 124
		buf->vb.state = VIDEOBUF_DONE;
		list_del(&buf->vb.queue);
		wake_up(&buf->vb.done);
	}
125

126 127 128 129 130
	if (list_empty(&q->active))
		del_timer(&q->timeout);
	else
		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
	if (bc != 1)
131
		pr_err("%s: %d buffers handled (should be 1)\n", __func__, bc);
132 133
}

134
static int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
135
{
136 137
	dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
		__func__, (unsigned int)norm, v4l2_norm_to_name(norm));
138

139
	dev->tvnorm = norm;
140

141 142
	/* Tell the internal A/V decoder */
	cx25821_call_all(dev, core, s_std, norm);
143

144
	return 0;
145 146
}

147
/* resource management */
H
Hans Verkuil 已提交
148
static int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
149
		    unsigned int bit)
150
{
151 152 153 154 155 156
	dprintk(1, "%s()\n", __func__);
	if (fh->resources & bit)
		/* have it already allocated */
		return 1;

	/* is it free? */
157
	if (dev->channels[fh->channel_id].resources & bit) {
158 159 160 161 162
		/* no, someone else uses it */
		return 0;
	}
	/* it's free, grab it */
	fh->resources |= bit;
163
	dev->channels[fh->channel_id].resources |= bit;
164 165
	dprintk(1, "res: get %d\n", bit);
	return 1;
166 167
}

H
Hans Verkuil 已提交
168
static int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
169
{
170
	return fh->resources & bit;
171 172
}

H
Hans Verkuil 已提交
173
static int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit)
174
{
175
	return fh->dev->channels[fh->channel_id].resources & bit;
176 177
}

H
Hans Verkuil 已提交
178
static void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
179
		      unsigned int bits)
180
{
181 182 183 184
	BUG_ON((fh->resources & bits) != bits);
	dprintk(1, "%s()\n", __func__);

	fh->resources &= ~bits;
185
	dev->channels[fh->channel_id].resources &= ~bits;
186
	dprintk(1, "res: put %d\n", bits);
187 188
}

189
static int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
190
{
191 192
	struct v4l2_routing route;
	memset(&route, 0, sizeof(route));
193

194
	dprintk(1, "%s(): video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
195 196 197
		__func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
		INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
	dev->input = input;
198

199
	route.input = INPUT(input)->vmux;
200

201 202
	/* Tell the internal A/V decoder */
	cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
203

204
	return 0;
205 206 207
}

int cx25821_start_video_dma(struct cx25821_dev *dev,
208 209
			    struct cx25821_dmaqueue *q,
			    struct cx25821_buffer *buf,
210
			    const struct sram_channel *channel)
211
{
212
	int tmp = 0;
213

214 215
	/* setup fifo + format */
	cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
216

217 218 219
	/* reset counter */
	cx_write(channel->gpcnt_ctl, 3);
	q->count = 1;
220

221 222 223
	/* enable irq */
	cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
	cx_set(channel->int_msk, 0x11);
224

225 226
	/* start dma */
	cx_write(channel->dma_ctl, 0x11);	/* FIFO and RISC enable */
227

228 229 230
	/* make sure upstream setting if any is reversed */
	tmp = cx_read(VID_CH_MODE_SEL);
	cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
231

232
	return 0;
233 234
}

235 236
static int cx25821_restart_video_queue(struct cx25821_dev *dev,
				       struct cx25821_dmaqueue *q,
237
				       const struct sram_channel *channel)
238
{
239 240
	struct cx25821_buffer *buf, *prev;
	struct list_head *item;
241

242
	if (!list_empty(&q->active)) {
243 244
		buf = list_entry(q->active.next, struct cx25821_buffer,
				vb.queue);
245

246
		cx25821_start_video_dma(dev, q, buf, channel);
247

248 249 250 251
		list_for_each(item, &q->active) {
			buf = list_entry(item, struct cx25821_buffer, vb.queue);
			buf->count = q->count++;
		}
252

253 254 255
		mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
		return 0;
	}
256

257 258 259 260 261
	prev = NULL;
	for (;;) {
		if (list_empty(&q->queued))
			return 0;

262 263
		buf = list_entry(q->queued.next, struct cx25821_buffer,
				vb.queue);
264 265 266 267 268 269 270 271 272 273 274 275 276 277

		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);
278
			prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
279 280 281 282
		} else {
			return 0;
		}
		prev = buf;
283
	}
284 285
}

286
static void cx25821_vid_timeout(unsigned long data)
287
{
288 289
	struct cx25821_data *timeout_data = (struct cx25821_data *)data;
	struct cx25821_dev *dev = timeout_data->dev;
290
	const struct sram_channel *channel = timeout_data->channel;
291
	struct cx25821_dmaqueue *q = &dev->channels[channel->i].vidq;
292 293 294
	struct cx25821_buffer *buf;
	unsigned long flags;

295
	/* cx25821_sram_channel_dump(dev, channel); */
296 297 298 299
	cx_clear(channel->dma_ctl, 0x11);

	spin_lock_irqsave(&dev->slock, flags);
	while (!list_empty(&q->active)) {
300 301
		buf = list_entry(q->active.next, struct cx25821_buffer,
				vb.queue);
302
		list_del(&buf->vb.queue);
303

304 305 306 307 308 309
		buf->vb.state = VIDEOBUF_ERROR;
		wake_up(&buf->vb.done);
	}

	cx25821_restart_video_queue(dev, q, channel);
	spin_unlock_irqrestore(&dev->slock, flags);
310 311 312 313
}

int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
{
314 315 316
	u32 count = 0;
	int handled = 0;
	u32 mask;
317
	const struct sram_channel *channel = dev->channels[chan_num].sram_channels;
318 319 320 321 322 323 324 325 326

	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)) {
327 328
		pr_warn("%s, %s: video risc op code error\n",
			dev->name, channel->name);
329 330 331
		cx_clear(channel->dma_ctl, 0x11);
		cx25821_sram_channel_dump(dev, channel);
	}
332

333 334 335 336
	/* risc1 y */
	if (status & FLD_VID_DST_RISC1) {
		spin_lock(&dev->slock);
		count = cx_read(channel->gpcnt);
337 338
		cx25821_video_wakeup(dev, &dev->channels[channel->i].vidq,
				count);
339 340 341
		spin_unlock(&dev->slock);
		handled++;
	}
342

343 344 345 346
	/* risc2 y */
	if (status & 0x10) {
		dprintk(2, "stopper video\n");
		spin_lock(&dev->slock);
347 348
		cx25821_restart_video_queue(dev,
				&dev->channels[channel->i].vidq, channel);
349 350 351 352
		spin_unlock(&dev->slock);
		handled++;
	}
	return handled;
353 354
}

355
static int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,
356
		 unsigned int *size)
357
{
358
	struct cx25821_fh *fh = q->priv_data;
359

360
	*size = fh->fmt->depth * fh->width * fh->height >> 3;
361

362 363
	if (0 == *count)
		*count = 32;
364

365 366
	if (*size * *count > vid_limit * 1024 * 1024)
		*count = (vid_limit * 1024 * 1024) / *size;
367

368
	return 0;
369 370
}

371
static int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
372
		   enum v4l2_field field)
373
{
374 375 376
	struct cx25821_fh *fh = q->priv_data;
	struct cx25821_dev *dev = fh->dev;
	struct cx25821_buffer *buf =
377
		container_of(vb, struct cx25821_buffer, vb);
378
	int rc, init_buffer = 0;
379
	u32 line0_offset;
380 381
	struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
	int bpl_local = LINE_SIZE_D1;
382
	int channel_opened = fh->channel_id;
383 384 385 386 387

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

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

391 392
	if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
		return -EINVAL;
393

394 395 396 397 398 399 400 401
	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;
402
	}
403 404 405 406 407

	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
		init_buffer = 1;
		rc = videobuf_iolock(q, &buf->vb, NULL);
		if (0 != rc) {
408
			printk(KERN_DEBUG pr_fmt("videobuf_iolock failed!\n"));
409
			goto fail;
410 411 412
		}
	}

413 414 415 416 417
	dprintk(1, "init_buffer=%d\n", init_buffer);

	if (init_buffer) {

		channel_opened = dev->channel_opened;
418 419
		if (channel_opened < 0 || channel_opened > 7)
			channel_opened = 7;
420

421 422
		if (dev->channels[channel_opened].pixel_formats ==
				PIXEL_FRMT_411)
423 424 425 426
			buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
		else
			buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);

427 428
		if (dev->channels[channel_opened].pixel_formats ==
				PIXEL_FRMT_411) {
429 430
			bpl_local = buf->bpl;
		} else {
431
			bpl_local = buf->bpl;   /* Default */
432 433

			if (channel_opened >= 0 && channel_opened <= 7) {
434 435
				if (dev->channels[channel_opened]
						.use_cif_resolution) {
436 437
					if (dev->tvnorm & V4L2_STD_PAL_BG ||
					    dev->tvnorm & V4L2_STD_PAL_DK)
438 439
						bpl_local = 352 << 1;
					else
440 441 442
						bpl_local = dev->channels[
							channel_opened].
							cif_width << 1;
443 444 445
				}
			}
		}
446

447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
		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();
		}
483
	}
484

485 486 487
	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);
488

489
	buf->vb.state = VIDEOBUF_PREPARED;
490

491
	return 0;
492

493
fail:
494 495
	cx25821_free_buffer(q, buf);
	return rc;
496 497
}

498
static void cx25821_buffer_release(struct videobuf_queue *q,
499
			    struct videobuf_buffer *vb)
500
{
501
	struct cx25821_buffer *buf =
502
		container_of(vb, struct cx25821_buffer, vb);
503

504
	cx25821_free_buffer(q, buf);
505 506
}

507
static struct videobuf_queue *get_queue(struct cx25821_fh *fh)
508
{
509 510 511 512 513 514 515
	switch (fh->type) {
	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
		return &fh->vidq;
	default:
		BUG();
		return NULL;
	}
516 517
}

518
static int cx25821_get_resource(struct cx25821_fh *fh, int resource)
519
{
520 521 522 523 524 525 526
	switch (fh->type) {
	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
		return resource;
	default:
		BUG();
		return 0;
	}
527 528
}

529
static int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
530
{
531
	struct cx25821_fh *fh = file->private_data;
532

533
	return videobuf_mmap_mapper(get_queue(fh), vma);
534 535
}

536 537 538

static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
{
539
	struct cx25821_buffer *buf =
540
		container_of(vb, struct cx25821_buffer, vb);
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
	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
572 573
		   && prev->vb.height == buf->vb.height
		   && prev->fmt == buf->fmt) {
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
			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");
594 595 596
}

static struct videobuf_queue_ops cx25821_video_qops = {
597 598 599 600
	.buf_setup = cx25821_buffer_setup,
	.buf_prepare = cx25821_buffer_prepare,
	.buf_queue = buffer_queue,
	.buf_release = cx25821_buffer_release,
601 602 603 604
};

static int video_open(struct file *file)
{
605
	struct video_device *vdev = video_devdata(file);
606
	struct cx25821_dev *dev = video_drvdata(file);
607 608 609
	struct cx25821_fh *fh;
	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	u32 pix_format;
610
	int ch_id;
611

612
	for (ch_id = 0; ch_id < MAX_VID_CHANNEL_NUM - 1; ch_id++)
613
		if (&dev->channels[ch_id].vdev == vdev)
614 615 616 617 618 619
			break;

	/* Can't happen */
	if (ch_id >= MAX_VID_CHANNEL_NUM - 1)
		return -ENODEV;

620 621 622 623
	/* allocate + initialize per filehandle data */
	fh = kzalloc(sizeof(*fh), GFP_KERNEL);
	if (NULL == fh)
		return -ENOMEM;
624

625 626 627 628 629 630 631 632 633 634 635 636
	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;
637 638 639 640
	if (dev->channels[ch_id].pixel_formats == PIXEL_FRMT_411)
		pix_format = V4L2_PIX_FMT_Y41P;
	else
		pix_format = V4L2_PIX_FMT_YUYV;
641 642 643 644
	fh->fmt = cx25821_format_by_fourcc(pix_format);

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

645 646 647
	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),
H
Hans Verkuil 已提交
648
			fh, &dev->lock);
649

650
	dprintk(1, "post videobuf_queue_init()\n");
651

652
	return 0;
653 654 655
}

static ssize_t video_read(struct file *file, char __user * data, size_t count,
656
			 loff_t *ppos)
657
{
658
	struct cx25821_fh *fh = file->private_data;
H
Hans Verkuil 已提交
659 660
	struct cx25821_dev *dev = fh->dev;
	int err;
661

662 663
	switch (fh->type) {
	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
H
Hans Verkuil 已提交
664 665
		if (mutex_lock_interruptible(&dev->lock))
			return -ERESTARTSYS;
666
		if (cx25821_res_locked(fh, RESOURCE_VIDEO0))
H
Hans Verkuil 已提交
667 668 669
			err = -EBUSY;
		else
			err = videobuf_read_one(&fh->vidq, data, count, ppos,
670
					file->f_flags & O_NONBLOCK);
H
Hans Verkuil 已提交
671 672
		mutex_unlock(&dev->lock);
		return err;
673

674
	default:
H
Hans Verkuil 已提交
675
		return -ENODEV;
676
	}
H
Hans Verkuil 已提交
677

678 679 680
}

static unsigned int video_poll(struct file *file,
681
			      struct poll_table_struct *wait)
682
{
683 684 685 686 687 688 689 690
	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,
691
				struct cx25821_buffer, vb.stream);
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
	} 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,
708 709
				      (char *)buf->vb.baddr + (fh->width * 2),
				      (fh->width * 2));
710 711 712
				*((char *)buf->vb.baddr + 3) = cam_id;
			}
		}
713

714 715
		return POLLIN | POLLRDNORM;
	}
716

717
	return 0;
718 719 720 721
}

static int video_release(struct file *file)
{
722 723
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_dev *dev = fh->dev;
724 725
	const struct sram_channel *sram_ch =
		dev->channels[0].sram_channels;
726

H
Hans Verkuil 已提交
727
	mutex_lock(&dev->lock);
728
	/* stop the risc engine and fifo */
729
	cx_write(sram_ch->dma_ctl, 0); /* FIFO and RISC disable */
730

731 732 733 734 735
	/* stop video capture */
	if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
		videobuf_queue_cancel(&fh->vidq);
		cx25821_res_free(dev, fh, RESOURCE_VIDEO0);
	}
H
Hans Verkuil 已提交
736
	mutex_unlock(&dev->lock);
737

738 739 740 741
	if (fh->vidq.read_buf) {
		cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
		kfree(fh->vidq.read_buf);
	}
742

743
	videobuf_mmap_free(&fh->vidq);
744

745 746 747
	v4l2_prio_close(&dev->channels[fh->channel_id].prio, fh->prio);
	file->private_data = NULL;
	kfree(fh);
748

749
	return 0;
750 751
}

752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
/* VIDEO IOCTLS */
static int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
				 struct v4l2_format *f)
{
	struct cx25821_fh *fh = priv;

	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;

	return 0;
}

static int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
				   struct v4l2_format *f)
{
	const struct cx25821_fmt *fmt;
	enum v4l2_field field;
	unsigned int maxw, maxh;

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

	field = f->fmt.pix.field;
	maxw = 720;
	maxh = 576;

	if (V4L2_FIELD_ANY == field) {
		if (f->fmt.pix.height > maxh / 2)
			field = V4L2_FIELD_INTERLACED;
		else
			field = V4L2_FIELD_TOP;
	}

	switch (field) {
	case V4L2_FIELD_TOP:
	case V4L2_FIELD_BOTTOM:
		maxh = maxh / 2;
		break;
	case V4L2_FIELD_INTERLACED:
		break;
	default:
		return -EINVAL;
	}

	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;

	return 0;
}
816 817
static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
818 819
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = fh->dev;
820

821 822
	if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
		return -EINVAL;
823

824 825
	if (unlikely(i != fh->type))
		return -EINVAL;
826

827 828 829
	if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh,
						RESOURCE_VIDEO0))))
		return -EBUSY;
830

831
	return videobuf_streamon(get_queue(fh));
832 833 834 835
}

static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
{
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
	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;
851 852
}

853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889
static int cx25821_is_valid_width(u32 width, v4l2_std_id tvnorm)
{
	if (tvnorm == V4L2_STD_PAL_BG) {
		if (width == 352 || width == 720)
			return 1;
		else
			return 0;
	}

	if (tvnorm == V4L2_STD_NTSC_M) {
		if (width == 320 || width == 352 || width == 720)
			return 1;
		else
			return 0;
	}
	return 0;
}

static int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm)
{
	if (tvnorm == V4L2_STD_PAL_BG) {
		if (height == 576 || height == 288)
			return 1;
		else
			return 0;
	}

	if (tvnorm == V4L2_STD_NTSC_M) {
		if (height == 480 || height == 240)
			return 1;
		else
			return 0;
	}

	return 0;
}

890
static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
891
				struct v4l2_format *f)
892
{
893 894
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
895
	struct v4l2_mbus_framefmt mbus_fmt;
896 897 898 899 900 901 902 903 904
	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;
	}
905

906
	err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
907

908 909
	if (0 != err)
		return err;
910

911 912
	fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat);
	fh->vidq.field = f->fmt.pix.field;
913

914 915 916
	/* 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;
917

918 919
	if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm))
		fh->height = f->fmt.pix.height;
920

921 922 923 924 925 926
	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;
927

928
	cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
929

930 931 932 933 934
	/* 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;
935

936 937
	dev->channels[fh->channel_id].cif_width = fh->width;
	medusa_set_resolution(dev, fh->width, SRAM_CH00);
938

939 940
	v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED);
	cx25821_call_all(dev, video, s_mbus_fmt, &mbus_fmt);
941

942
	return 0;
943 944 945 946
}

static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
{
947 948 949
	int ret_val = 0;
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
950

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

953
	p->sequence = dev->channels[fh->channel_id].vidq.count;
954

955
	return ret_val;
956 957 958 959
}

static int vidioc_log_status(struct file *file, void *priv)
{
960 961
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	struct cx25821_fh *fh = priv;
962
	const struct sram_channel *sram_ch =
963
		dev->channels[fh->channel_id].sram_channels;
964
	u32 tmp = 0;
965

966 967
	cx25821_call_all(dev, core, log_status);
	tmp = cx_read(sram_ch->dma_ctl);
968 969
	pr_info("Video input 0 is %s\n",
		(tmp & 0x11) ? "streaming" : "stopped");
970
	return 0;
971 972
}

973

974
static int cx25821_vidioc_querycap(struct file *file, void *priv,
975
			    struct v4l2_capability *cap)
976
{
977
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
978 979 980 981
	struct cx25821_fh *fh = priv;
	const u32 cap_input = V4L2_CAP_VIDEO_CAPTURE |
			V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
	const u32 cap_output = V4L2_CAP_VIDEO_OUTPUT;
982 983 984 985

	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));
986 987 988 989 990
	if (fh->channel_id >= VID_CHANNEL_NUM)
		cap->device_caps = cap_output;
	else
		cap->device_caps = cap_input;
	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
991
	return 0;
992 993
}

994
static int cx25821_vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
995
			    struct v4l2_fmtdesc *f)
996
{
997 998
	if (unlikely(f->index >= ARRAY_SIZE(formats)))
		return -EINVAL;
999

1000 1001
	strlcpy(f->description, formats[f->index].name, sizeof(f->description));
	f->pixelformat = formats[f->index].fourcc;
1002

1003
	return 0;
1004 1005
}

1006
static int cx25821_vidioc_reqbufs(struct file *file, void *priv,
1007
			   struct v4l2_requestbuffers *p)
1008
{
1009 1010
	struct cx25821_fh *fh = priv;
	return videobuf_reqbufs(get_queue(fh), p);
1011 1012
}

1013
static int cx25821_vidioc_querybuf(struct file *file, void *priv,
1014
			    struct v4l2_buffer *p)
1015
{
1016 1017
	struct cx25821_fh *fh = priv;
	return videobuf_querybuf(get_queue(fh), p);
1018 1019
}

1020
static int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1021
{
1022 1023
	struct cx25821_fh *fh = priv;
	return videobuf_qbuf(get_queue(fh), p);
1024 1025
}

1026
static int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
1027 1028
{
	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
1029
	struct cx25821_fh *fh = f;
1030

1031
	*p = v4l2_prio_max(&dev->channels[fh->channel_id].prio);
1032 1033 1034 1035

	return 0;
}

1036
static int cx25821_vidioc_s_priority(struct file *file, void *f,
1037
			      enum v4l2_priority prio)
1038 1039 1040 1041
{
	struct cx25821_fh *fh = f;
	struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;

1042 1043
	return v4l2_prio_change(&dev->channels[fh->channel_id].prio, &fh->prio,
			prio);
1044 1045
}

1046
static int cx25821_vidioc_g_std(struct file *file, void *priv, v4l2_std_id *tvnorms)
1047 1048 1049 1050 1051 1052 1053
{
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;

	*tvnorms = dev->tvnorm;
	return 0;
}

1054
int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id tvnorms)
1055
{
1056 1057 1058
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	int err;
1059

1060
	if (fh) {
1061 1062
		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
				      fh->prio);
1063 1064 1065
		if (0 != err)
			return err;
	}
1066

1067
	if (dev->tvnorm == tvnorms)
1068
		return 0;
1069

1070
	cx25821_set_tvnorm(dev, tvnorms);
1071

1072
	medusa_set_videostandard(dev);
1073

1074
	return 0;
1075 1076
}

1077 1078
static int cx25821_vidioc_enum_input(struct file *file, void *priv,
			      struct v4l2_input *i)
1079
{
1080
	static const char * const iname[] = {
1081 1082 1083 1084
		[CX25821_VMUX_COMPOSITE] = "Composite",
		[CX25821_VMUX_SVIDEO] = "S-Video",
		[CX25821_VMUX_DEBUG] = "for debug only",
	};
1085
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1086
	unsigned int n;
1087

1088
	n = i->index;
1089
	if (n >= CX25821_NR_INPUT)
1090 1091 1092 1093
		return -EINVAL;

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

1095 1096
	i->type = V4L2_INPUT_TYPE_CAMERA;
	strcpy(i->name, iname[INPUT(n)->type]);
1097

1098 1099
	i->std = CX25821_NORMS;
	return 0;
1100 1101
}

1102
static int cx25821_vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1103
{
1104
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1105

1106 1107
	*i = dev->input;
	return 0;
1108 1109
}

1110
static int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
1111
{
1112 1113 1114
	struct cx25821_fh *fh = priv;
	struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
	int err;
1115

1116
	if (fh) {
1117 1118
		err = v4l2_prio_check(&dev->channels[fh->channel_id].prio,
				      fh->prio);
1119 1120 1121
		if (0 != err)
			return err;
	}
1122

1123
	if (i >= CX25821_NR_INPUT || INPUT(i)->type == 0)
1124
		return -EINVAL;
1125

1126 1127
	cx25821_video_mux(dev, i);
	return 0;
1128 1129 1130
}

#ifdef CONFIG_VIDEO_ADV_DEBUG
1131
int cx25821_vidioc_g_register(struct file *file, void *fh,
1132
		      struct v4l2_dbg_register *reg)
1133
{
1134
	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
1135

1136 1137
	if (!v4l2_chip_match_host(&reg->match))
		return -EINVAL;
1138

1139
	cx25821_call_all(dev, core, g_register, reg);
1140

1141
	return 0;
1142 1143
}

1144
int cx25821_vidioc_s_register(struct file *file, void *fh,
1145
		      const struct v4l2_dbg_register *reg)
1146
{
1147
	struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
1148

1149 1150
	if (!v4l2_chip_match_host(&reg->match))
		return -EINVAL;
1151

1152
	cx25821_call_all(dev, core, s_register, reg);
1153

1154
	return 0;
1155 1156 1157 1158
}

#endif

1159
static int cx25821_s_ctrl(struct v4l2_ctrl *ctrl)
1160
{
1161 1162 1163
	struct cx25821_channel *chan =
		container_of(ctrl->handler, struct cx25821_channel, hdl);
	struct cx25821_dev *dev = chan->dev;
1164

1165
	switch (ctrl->id) {
1166
	case V4L2_CID_BRIGHTNESS:
1167
		medusa_set_brightness(dev, ctrl->val, chan->id);
1168
		break;
1169
	case V4L2_CID_HUE:
1170
		medusa_set_hue(dev, ctrl->val, chan->id);
1171
		break;
1172
	case V4L2_CID_CONTRAST:
1173
		medusa_set_contrast(dev, ctrl->val, chan->id);
1174
		break;
1175
	case V4L2_CID_SATURATION:
1176
		medusa_set_saturation(dev, ctrl->val, chan->id);
1177
		break;
1178
	default:
1179
		return -EINVAL;
1180
	}
1181
	return 0;
1182 1183
}

1184
static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
1185
				 unsigned long arg)
1186
{
1187 1188 1189 1190
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_dev *dev = fh->dev;
	int command = 0;
	struct upstream_user_struct *data_from_user;
1191

1192
	data_from_user = (struct upstream_user_struct *)arg;
1193

1194 1195 1196 1197
	if (!data_from_user) {
		pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
		return 0;
	}
1198

1199
	command = data_from_user->command;
1200

1201 1202
	if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO)
		return 0;
1203

1204 1205 1206 1207 1208 1209
	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;
1210

1211 1212 1213 1214
	switch (command) {
	case UPSTREAM_START_VIDEO:
		cx25821_start_upstream_video_ch1(dev, data_from_user);
		break;
1215

1216 1217 1218 1219
	case UPSTREAM_STOP_VIDEO:
		cx25821_stop_upstream_video_ch1(dev);
		break;
	}
1220

1221
	return 0;
1222 1223 1224
}

static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
1225
				  unsigned long arg)
1226
{
1227 1228 1229 1230
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_dev *dev = fh->dev;
	int command = 0;
	struct upstream_user_struct *data_from_user;
1231

1232
	data_from_user = (struct upstream_user_struct *)arg;
1233

1234 1235 1236 1237
	if (!data_from_user) {
		pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
		return 0;
	}
1238

1239
	command = data_from_user->command;
1240

1241 1242
	if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO)
		return 0;
1243

1244 1245 1246 1247 1248 1249
	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;
1250

1251 1252 1253 1254
	switch (command) {
	case UPSTREAM_START_VIDEO:
		cx25821_start_upstream_video_ch2(dev, data_from_user);
		break;
1255

1256 1257 1258 1259
	case UPSTREAM_STOP_VIDEO:
		cx25821_stop_upstream_video_ch2(dev);
		break;
	}
1260

1261
	return 0;
1262 1263 1264
}

static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
1265
				  unsigned long arg)
1266
{
1267 1268 1269 1270
	struct cx25821_fh *fh = file->private_data;
	struct cx25821_dev *dev = fh->dev;
	int command = 0;
	struct upstream_user_struct *data_from_user;
1271

1272
	data_from_user = (struct upstream_user_struct *)arg;
1273

1274 1275 1276 1277
	if (!data_from_user) {
		pr_err("%s(): Upstream data is INVALID. Returning\n", __func__);
		return 0;
	}
1278

1279
	command = data_from_user->command;
1280

1281 1282
	if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO)
		return 0;
1283

1284 1285 1286 1287 1288 1289
	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;
1290

1291 1292 1293 1294
	switch (command) {
	case UPSTREAM_START_AUDIO:
		cx25821_start_upstream_audio(dev, data_from_user);
		break;
1295

1296 1297 1298 1299
	case UPSTREAM_STOP_AUDIO:
		cx25821_stop_upstream_audio(dev);
		break;
	}
1300

1301
	return 0;
1302 1303 1304
}

static long video_ioctl_set(struct file *file, unsigned int cmd,
1305
			   unsigned long arg)
1306
{
1307 1308 1309 1310 1311
	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;
1312 1313 1314 1315 1316
	int selected_channel = 0;
	int pix_format = 0;
	int i = 0;
	int cif_enable = 0;
	int cif_width = 0;
1317

1318
	data_from_user = (struct downstream_user_struct *)arg;
1319

1320 1321 1322 1323
	if (!data_from_user) {
		pr_err("%s(): User data is INVALID. Returning\n", __func__);
		return 0;
	}
1324

1325
	command = data_from_user->command;
1326

1327
	if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
1328 1329 1330
	   && command != ENABLE_CIF_RESOLUTION && command != REG_READ
	   && command != REG_WRITE && command != MEDUSA_READ
	   && command != MEDUSA_WRITE) {
1331 1332
		return 0;
	}
1333

1334 1335
	switch (command) {
	case SET_VIDEO_STD:
1336 1337 1338 1339
		if (!strcmp(data_from_user->vid_stdname, "PAL"))
			dev->tvnorm = V4L2_STD_PAL_BG;
		else
			dev->tvnorm = V4L2_STD_NTSC_M;
1340 1341
		medusa_set_videostandard(dev);
		break;
1342

1343 1344 1345 1346 1347 1348 1349 1350
	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;
		}
1351

1352 1353
		if (selected_channel >= 0)
			cx25821_set_pixel_format(dev, selected_channel,
1354
						pix_format);
1355

1356 1357 1358 1359 1360 1361 1362 1363 1364
		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
1365
			    || dev->tvnorm & V4L2_STD_PAL_DK) {
1366
				width = 352;
1367 1368 1369 1370 1371
			} else {
				width = cif_width;
				if (cif_width != 320 && cif_width != 352)
					width = 320;
			}
1372 1373 1374 1375 1376 1377 1378 1379
		}

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

		if (selected_channel <= 7 && selected_channel >= 0) {
1380 1381
			dev->channels[selected_channel].use_cif_resolution =
				cif_enable;
1382 1383 1384 1385 1386 1387 1388 1389
			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;
			}
		}
1390

1391 1392 1393 1394 1395 1396 1397 1398 1399
		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:
1400
		cx25821_i2c_read(&dev->i2c_bus[0],
1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411
					 (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;
1412 1413 1414
}

static long cx25821_video_ioctl(struct file *file,
1415
				unsigned int cmd, unsigned long arg)
1416
{
1417
	int ret = 0;
1418

1419
	struct cx25821_fh *fh = file->private_data;
1420

1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434
	/* 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);
1435 1436
}

1437 1438 1439 1440
static const struct v4l2_ctrl_ops cx25821_ctrl_ops = {
	.s_ctrl = cx25821_s_ctrl,
};

1441
static const struct v4l2_file_operations video_fops = {
1442 1443 1444 1445 1446 1447
	.owner = THIS_MODULE,
	.open = video_open,
	.release = video_release,
	.read = video_read,
	.poll = video_poll,
	.mmap = cx25821_video_mmap,
H
Hans Verkuil 已提交
1448
	.unlocked_ioctl = cx25821_video_ioctl,
1449 1450 1451
};

static const struct v4l2_ioctl_ops video_ioctl_ops = {
1452 1453 1454 1455 1456 1457 1458 1459 1460
	.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,
1461
	.vidioc_g_std = cx25821_vidioc_g_std,
1462 1463 1464 1465 1466 1467 1468 1469 1470
	.vidioc_s_std = cx25821_vidioc_s_std,
	.vidioc_enum_input = cx25821_vidioc_enum_input,
	.vidioc_g_input = cx25821_vidioc_g_input,
	.vidioc_s_input = cx25821_vidioc_s_input,
	.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,
1471
#ifdef CONFIG_VIDEO_ADV_DEBUG
1472 1473
	.vidioc_g_register = cx25821_vidioc_g_register,
	.vidioc_s_register = cx25821_vidioc_s_register,
1474 1475 1476
#endif
};

1477 1478
static const struct video_device cx25821_video_device = {
	.name = "cx25821-video",
1479
	.fops = &video_fops,
1480
	.release = video_device_release_empty,
1481
	.minor = -1,
1482 1483
	.ioctl_ops = &video_ioctl_ops,
	.tvnorms = CX25821_NORMS,
1484
};
1485 1486 1487 1488 1489

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

1490 1491
	if (video_is_registered(&dev->channels[chan_num].vdev)) {
		video_unregister_device(&dev->channels[chan_num].vdev);
1492
		v4l2_ctrl_handler_free(&dev->channels[chan_num].hdl);
1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503

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

int cx25821_video_register(struct cx25821_dev *dev)
{
	int err;
	int i;

H
Hans Verkuil 已提交
1504 1505 1506 1507
	/* initial device configuration */
	dev->tvnorm = V4L2_STD_NTSC_M,
	cx25821_set_tvnorm(dev, dev->tvnorm);

1508 1509 1510
	spin_lock_init(&dev->slock);

	for (i = 0; i < VID_CHANNEL_NUM; ++i) {
1511
		struct video_device *vdev = &dev->channels[i].vdev;
1512
		struct v4l2_ctrl_handler *hdl = &dev->channels[i].hdl;
1513

1514 1515 1516
		if (i == SRAM_CH08) /* audio channel */
			continue;

1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
		v4l2_ctrl_handler_init(hdl, 4);
		v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
			V4L2_CID_BRIGHTNESS, 0, 10000, 1, 6200);
		v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
			V4L2_CID_CONTRAST, 0, 10000, 1, 5000);
		v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
			V4L2_CID_SATURATION, 0, 10000, 1, 5000);
		v4l2_ctrl_new_std(hdl, &cx25821_ctrl_ops,
			V4L2_CID_HUE, 0, 10000, 1, 5000);
		if (hdl->error) {
			err = hdl->error;
			goto fail_unreg;
		}
H
Hans Verkuil 已提交
1530 1531 1532
		err = v4l2_ctrl_handler_setup(hdl);
		if (err)
			goto fail_unreg;
1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553

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

		dev->channels[i].sram_channels = &cx25821_sram_channels[i];
		dev->channels[i].resources = 0;

		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];
		dev->channels[i].vidq.timeout.function = cx25821_vid_timeout;
		dev->channels[i].vidq.timeout.data =
			(unsigned long)&dev->channels[i].timeout_data;
		init_timer(&dev->channels[i].vidq.timeout);

		/* register v4l devices */
1554 1555
		*vdev = cx25821_video_device;
		vdev->v4l2_dev = &dev->v4l2_dev;
1556
		vdev->ctrl_handler = hdl;
H
Hans Verkuil 已提交
1557
		vdev->lock = &dev->lock;
1558 1559
		snprintf(vdev->name, sizeof(vdev->name), "%s #%d", dev->name, i);
		video_set_drvdata(vdev, dev);
1560

1561 1562
		err = video_register_device(vdev, VFL_TYPE_GRABBER,
					    video_nr[dev->nr]);
1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573

		if (err < 0)
			goto fail_unreg;
	}

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

	return 0;

fail_unreg:
1574 1575
	while (i >= 0)
		cx25821_video_unregister(dev, i--);
1576 1577
	return err;
}