cx18-ioctl.c 32.7 KB
Newer Older
1 2 3 4 5 6
/*
 *  cx18 ioctl system call
 *
 *  Derived from ivtv-ioctl.c
 *
 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
7
 *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA
 *  02111-1307  USA
 */

#include "cx18-driver.h"
26
#include "cx18-io.h"
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
#include "cx18-version.h"
#include "cx18-mailbox.h"
#include "cx18-i2c.h"
#include "cx18-queue.h"
#include "cx18-fileops.h"
#include "cx18-vbi.h"
#include "cx18-audio.h"
#include "cx18-video.h"
#include "cx18-streams.h"
#include "cx18-ioctl.h"
#include "cx18-gpio.h"
#include "cx18-controls.h"
#include "cx18-cards.h"
#include "cx18-av-core.h"
#include <media/tveeprom.h>
#include <media/v4l2-chip-ident.h>

44
u16 cx18_service2vbi(int type)
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
{
	switch (type) {
	case V4L2_SLICED_TELETEXT_B:
		return CX18_SLICED_TYPE_TELETEXT_B;
	case V4L2_SLICED_CAPTION_525:
		return CX18_SLICED_TYPE_CAPTION_525;
	case V4L2_SLICED_WSS_625:
		return CX18_SLICED_TYPE_WSS_625;
	case V4L2_SLICED_VPS:
		return CX18_SLICED_TYPE_VPS;
	default:
		return 0;
	}
}

60
/* Check if VBI services are allowed on the (field, line) for the video std */
61 62
static int valid_service_line(int field, int line, int is_pal)
{
63 64
	return (is_pal && line >= 6 &&
		((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
65 66 67
	       (!is_pal && line >= 10 && line < 22);
}

68 69 70 71 72 73 74
/*
 * For a (field, line, std) and inbound potential set of services for that line,
 * return the first valid service of those passed in the incoming set for that
 * line in priority order:
 * CC, VPS, or WSS over TELETEXT for well known lines
 * TELETEXT, before VPS, before CC, before WSS, for other lines
 */
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
{
	u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
	int i;

	set = set & valid_set;
	if (set == 0 || !valid_service_line(field, line, is_pal))
		return 0;
	if (!is_pal) {
		if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
			return V4L2_SLICED_CAPTION_525;
	} else {
		if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
			return V4L2_SLICED_VPS;
		if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
			return V4L2_SLICED_WSS_625;
		if (line == 23)
			return 0;
	}
	for (i = 0; i < 32; i++) {
		if ((1 << i) & set)
			return 1 << i;
	}
	return 0;
}

101 102 103 104
/*
 * Expand the service_set of *fmt into valid service_lines for the std,
 * and clear the passed in fmt->service_set
 */
105
void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
106 107 108 109 110 111 112 113 114 115 116
{
	u16 set = fmt->service_set;
	int f, l;

	fmt->service_set = 0;
	for (f = 0; f < 2; f++) {
		for (l = 0; l < 24; l++)
			fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
	}
}

117 118 119 120
/*
 * Sanitize the service_lines in *fmt per the video std, and return 1
 * if any service_line is left as valid after santization
 */
121 122 123 124 125 126 127 128 129 130 131 132 133
static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
{
	int f, l;
	u16 set = 0;

	for (f = 0; f < 2; f++) {
		for (l = 0; l < 24; l++) {
			fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
			set |= fmt->service_lines[f][l];
		}
	}
	return set != 0;
}
134

135
/* Compute the service_set from the assumed valid service_lines of *fmt */
136
u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
137 138 139 140 141 142 143 144 145 146 147
{
	int f, l;
	u16 set = 0;

	for (f = 0; f < 2; f++) {
		for (l = 0; l < 24; l++)
			set |= fmt->service_lines[f][l];
	}
	return set;
}

148 149 150
static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
				struct v4l2_format *fmt)
{
151
	struct cx18_open_id *id = fh2id(fh);
152
	struct cx18 *cx = id->cx;
153
	struct cx18_stream *s = &cx->streams[id->type];
154
	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
155

156 157
	pixfmt->width = cx->cxhdl.width;
	pixfmt->height = cx->cxhdl.height;
158 159 160
	pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
	pixfmt->field = V4L2_FIELD_INTERLACED;
	pixfmt->priv = 0;
161
	if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
162
		pixfmt->pixelformat = s->pixelformat;
163 164 165 166 167 168
		/* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
		   UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
		if (s->pixelformat == V4L2_PIX_FMT_HM12)
			pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
		else
			pixfmt->sizeimage = pixfmt->height * 720 * 2;
169
		pixfmt->bytesperline = 720;
170
	} else {
171 172 173
		pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
		pixfmt->sizeimage = 128 * 1024;
		pixfmt->bytesperline = 0;
174 175 176
	}
	return 0;
}
177

178 179 180
static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
				struct v4l2_format *fmt)
{
181
	struct cx18 *cx = fh2id(fh)->cx;
182
	struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
183

184
	vbifmt->sampling_rate = 27000000;
185
	vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
186
	vbifmt->samples_per_line = vbi_active_samples - 4;
187 188 189 190 191 192 193
	vbifmt->sample_format = V4L2_PIX_FMT_GREY;
	vbifmt->start[0] = cx->vbi.start[0];
	vbifmt->start[1] = cx->vbi.start[1];
	vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count;
	vbifmt->flags = 0;
	vbifmt->reserved[0] = 0;
	vbifmt->reserved[1] = 0;
194 195 196
	return 0;
}

197 198
static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
					struct v4l2_format *fmt)
199
{
200
	struct cx18 *cx = fh2id(fh)->cx;
201 202
	struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;

203
	/* sane, V4L2 spec compliant, defaults */
204 205 206 207
	vbifmt->reserved[0] = 0;
	vbifmt->reserved[1] = 0;
	vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
	memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
208 209 210 211 212 213 214
	vbifmt->service_set = 0;

	/*
	 * Fetch the configured service_lines and total service_set from the
	 * digitizer/slicer.  Note, cx18_av_vbi() wipes the passed in
	 * fmt->fmt.sliced under valid calling conditions
	 */
215
	if (v4l2_subdev_call(cx->sd_av, vbi, g_sliced_fmt, &fmt->fmt.sliced))
216
		return -EINVAL;
217

218 219 220 221
	/* Ensure V4L2 spec compliant output */
	vbifmt->reserved[0] = 0;
	vbifmt->reserved[1] = 0;
	vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
222 223
	vbifmt->service_set = cx18_get_service_set(vbifmt);
	return 0;
224
}
225

226 227 228
static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
				struct v4l2_format *fmt)
{
229
	struct cx18_open_id *id = fh2id(fh);
230 231 232
	struct cx18 *cx = id->cx;
	int w = fmt->fmt.pix.width;
	int h = fmt->fmt.pix.height;
233
	int min_h = 2;
234

235
	w = min(w, 720);
236 237 238 239 240 241
	w = max(w, 2);
	if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
		/* YUV height must be a multiple of 32 */
		h &= ~0x1f;
		min_h = 32;
	}
242
	h = min(h, cx->is_50hz ? 576 : 480);
243 244
	h = max(h, min_h);

245 246 247 248
	fmt->fmt.pix.width = w;
	fmt->fmt.pix.height = h;
	return 0;
}
249

250 251 252 253 254 255 256 257 258
static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
				struct v4l2_format *fmt)
{
	return cx18_g_fmt_vbi_cap(file, fh, fmt);
}

static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
					struct v4l2_format *fmt)
{
259
	struct cx18 *cx = fh2id(fh)->cx;
260 261 262 263 264 265
	struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;

	vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
	vbifmt->reserved[0] = 0;
	vbifmt->reserved[1] = 0;

266
	/* If given a service set, expand it validly & clear passed in set */
267 268
	if (vbifmt->service_set)
		cx18_expand_service_set(vbifmt, cx->is_50hz);
269 270 271
	/* Sanitize the service_lines, and compute the new set if any valid */
	if (check_service_set(vbifmt, cx->is_50hz))
		vbifmt->service_set = cx18_get_service_set(vbifmt);
272
	return 0;
273 274 275 276 277
}

static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
				struct v4l2_format *fmt)
{
278
	struct cx18_open_id *id = fh2id(fh);
279
	struct cx18 *cx = id->cx;
280
	struct v4l2_mbus_framefmt mbus_fmt;
281
	struct cx18_stream *s = &cx->streams[id->type];
282
	int ret;
283
	int w, h;
284 285 286 287

	ret = cx18_try_fmt_vid_cap(file, fh, fmt);
	if (ret)
		return ret;
288 289
	w = fmt->fmt.pix.width;
	h = fmt->fmt.pix.height;
290

291 292
	if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
	    s->pixelformat == fmt->fmt.pix.pixelformat)
293
		return 0;
294 295

	if (atomic_read(&cx->ana_capturing) > 0)
296
		return -EBUSY;
297

298 299
	s->pixelformat = fmt->fmt.pix.pixelformat;

300 301
	mbus_fmt.width = cx->cxhdl.width = w;
	mbus_fmt.height = cx->cxhdl.height = h;
302 303
	mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
	v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
304
	return cx18_g_fmt_vid_cap(file, fh, fmt);
305 306
}

307 308
static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
				struct v4l2_format *fmt)
309
{
310
	struct cx18_open_id *id = fh2id(fh);
311
	struct cx18 *cx = id->cx;
312
	int ret;
313

314 315 316 317 318
	/*
	 * Changing the Encoder's Raw VBI parameters won't have any effect
	 * if any analog capture is ongoing
	 */
	if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
319
		return -EBUSY;
320

321 322
	/*
	 * Set the digitizer registers for raw active VBI.
L
Lucas De Marchi 已提交
323
	 * Note cx18_av_vbi_wipes out a lot of the passed in fmt under valid
324 325
	 * calling conditions
	 */
326
	ret = v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &fmt->fmt.vbi);
327 328 329 330
	if (ret)
		return ret;

	/* Store our new v4l2 (non-)sliced VBI state */
331
	cx->vbi.sliced_in->service_set = 0;
332
	cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
333

334 335 336 337 338 339
	return cx18_g_fmt_vbi_cap(file, fh, fmt);
}

static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
					struct v4l2_format *fmt)
{
340
	struct cx18_open_id *id = fh2id(fh);
341 342 343 344
	struct cx18 *cx = id->cx;
	int ret;
	struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;

345
	cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
346

347 348 349 350 351
	/*
	 * Changing the Encoder's Raw VBI parameters won't have any effect
	 * if any analog capture is ongoing
	 */
	if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
352
		return -EBUSY;
353

354 355 356 357 358
	/*
	 * Set the service_lines requested in the digitizer/slicer registers.
	 * Note, cx18_av_vbi() wipes some "impossible" service lines in the
	 * passed in fmt->fmt.sliced under valid calling conditions
	 */
359
	ret = v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &fmt->fmt.sliced);
360 361 362
	if (ret)
		return ret;
	/* Store our current v4l2 sliced VBI settings */
363 364 365
	cx->vbi.in.type =  V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
	memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
	return 0;
366 367 368
}

static int cx18_g_chip_ident(struct file *file, void *fh,
369
				struct v4l2_dbg_chip_ident *chip)
370
{
371
	struct cx18 *cx = fh2id(fh)->cx;
372
	int err = 0;
373 374 375

	chip->ident = V4L2_IDENT_NONE;
	chip->revision = 0;
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
	switch (chip->match.type) {
	case V4L2_CHIP_MATCH_HOST:
		switch (chip->match.addr) {
		case 0:
			chip->ident = V4L2_IDENT_CX23418;
			chip->revision = cx18_read_reg(cx, 0xC72028);
			break;
		case 1:
			/*
			 * The A/V decoder is always present, but in the rare
			 * case that the card doesn't have analog, we don't
			 * use it.  We find it w/o using the cx->sd_av pointer
			 */
			cx18_call_hw(cx, CX18_HW_418_AV,
				     core, g_chip_ident, chip);
			break;
		default:
			/*
			 * Could return ident = V4L2_IDENT_UNKNOWN if we had
			 * other host chips at higher addresses, but we don't
			 */
			err = -EINVAL; /* per V4L2 spec */
			break;
		}
		break;
	case V4L2_CHIP_MATCH_I2C_DRIVER:
		/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
		cx18_call_all(cx, core, g_chip_ident, chip);
		break;
	case V4L2_CHIP_MATCH_I2C_ADDR:
		/*
		 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
		 * to look if a chip is at the address with no driver.  That's a
		 * dangerous thing to do with EEPROMs anyway.
		 */
		cx18_call_all(cx, core, g_chip_ident, chip);
		break;
	default:
		err = -EINVAL;
		break;
416
	}
417
	return err;
418 419
}

420 421 422
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
{
423
	struct v4l2_dbg_register *regs = arg;
424 425 426 427 428 429

	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
	if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
		return -EINVAL;

430
	regs->size = 4;
431
	if (cmd == VIDIOC_DBG_S_REGISTER)
432
		cx18_write_enc(cx, regs->val, regs->reg);
433 434
	else
		regs->val = cx18_read_enc(cx, regs->reg);
435 436 437
	return 0;
}

438
static int cx18_g_register(struct file *file, void *fh,
439
				struct v4l2_dbg_register *reg)
440
{
441
	struct cx18 *cx = fh2id(fh)->cx;
442

443
	if (v4l2_chip_match_host(&reg->match))
444
		return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
445 446
	/* FIXME - errors shouldn't be ignored */
	cx18_call_all(cx, core, g_register, reg);
447
	return 0;
448 449 450
}

static int cx18_s_register(struct file *file, void *fh,
451
				struct v4l2_dbg_register *reg)
452
{
453
	struct cx18 *cx = fh2id(fh)->cx;
454

455
	if (v4l2_chip_match_host(&reg->match))
456
		return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
457 458
	/* FIXME - errors shouldn't be ignored */
	cx18_call_all(cx, core, s_register, reg);
459
	return 0;
460
}
461
#endif
462 463 464 465

static int cx18_querycap(struct file *file, void *fh,
				struct v4l2_capability *vcap)
{
466
	struct cx18 *cx = fh2id(fh)->cx;
467

468 469
	strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
	strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
470 471
	snprintf(vcap->bus_info, sizeof(vcap->bus_info),
		 "PCI:%s", pci_name(cx->pci_dev));
472 473 474 475
	vcap->version = CX18_DRIVER_VERSION; 	    /* version */
	vcap->capabilities = cx->v4l2_cap; 	    /* capabilities */
	return 0;
}
476

477 478
static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
{
479
	struct cx18 *cx = fh2id(fh)->cx;
480

481 482
	return cx18_get_audio_input(cx, vin->index, vin);
}
483

484 485
static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
{
486
	struct cx18 *cx = fh2id(fh)->cx;
487

488 489 490
	vin->index = cx->audio_input;
	return cx18_get_audio_input(cx, vin->index, vin);
}
491

492 493
static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
{
494
	struct cx18 *cx = fh2id(fh)->cx;
495

496 497 498 499 500 501
	if (vout->index >= cx->nof_audio_inputs)
		return -EINVAL;
	cx->audio_input = vout->index;
	cx18_audio_set_io(cx);
	return 0;
}
502

503 504
static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
{
505
	struct cx18 *cx = fh2id(fh)->cx;
506

507 508 509
	/* set it to defaults from our table */
	return cx18_get_input(cx, vin->index, vin);
}
510

511 512 513
static int cx18_cropcap(struct file *file, void *fh,
			struct v4l2_cropcap *cropcap)
{
514
	struct cx18 *cx = fh2id(fh)->cx;
515

516 517 518 519 520 521 522 523 524 525
	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;
	cropcap->bounds.top = cropcap->bounds.left = 0;
	cropcap->bounds.width = 720;
	cropcap->bounds.height = cx->is_50hz ? 576 : 480;
	cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
	cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
	cropcap->defrect = cropcap->bounds;
	return 0;
}
526

527 528
static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
{
529
	struct cx18_open_id *id = fh2id(fh);
530
	struct cx18 *cx = id->cx;
531

532 533
	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;
534 535
	CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
	return -EINVAL;
536
}
537

538 539
static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
{
540
	struct cx18 *cx = fh2id(fh)->cx;
541

542 543
	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
		return -EINVAL;
544 545
	CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
	return -EINVAL;
546 547 548 549 550
}

static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
					struct v4l2_fmtdesc *fmt)
{
551 552 553 554 555 556 557 558 559 560 561 562
	static const struct v4l2_fmtdesc formats[] = {
		{ 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
		  "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
		},
		{ 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
		  "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
		},
		{ 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
		  "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
		},
	};

563
	if (fmt->index > ARRAY_SIZE(formats) - 1)
564 565 566 567 568 569 570
		return -EINVAL;
	*fmt = formats[fmt->index];
	return 0;
}

static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
{
571
	struct cx18 *cx = fh2id(fh)->cx;
572 573 574 575 576 577 578

	*i = cx->active_input;
	return 0;
}

int cx18_s_input(struct file *file, void *fh, unsigned int inp)
{
579
	struct cx18_open_id *id = fh2id(fh);
580 581
	struct cx18 *cx = id->cx;

582
	if (inp >= cx->nof_inputs)
583 584 585 586
		return -EINVAL;

	if (inp == cx->active_input) {
		CX18_DEBUG_INFO("Input unchanged\n");
587 588 589
		return 0;
	}

590 591
	CX18_DEBUG_INFO("Changing input from %d to %d\n",
			cx->active_input, inp);
592

593 594 595
	cx->active_input = inp;
	/* Set the audio input to whatever is appropriate for the input type. */
	cx->audio_input = cx->card->video_inputs[inp].audio_index;
596

597 598 599 600 601 602 603 604
	/* prevent others from messing with the streams until
	   we're finished changing inputs. */
	cx18_mute(cx);
	cx18_video_set_io(cx);
	cx18_audio_set_io(cx);
	cx18_unmute(cx);
	return 0;
}
605

606 607 608
static int cx18_g_frequency(struct file *file, void *fh,
				struct v4l2_frequency *vf)
{
609
	struct cx18 *cx = fh2id(fh)->cx;
610

611 612
	if (vf->tuner != 0)
		return -EINVAL;
613

614
	cx18_call_all(cx, tuner, g_frequency, vf);
615 616
	return 0;
}
617

618 619
int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
{
620
	struct cx18_open_id *id = fh2id(fh);
621
	struct cx18 *cx = id->cx;
622

623 624
	if (vf->tuner != 0)
		return -EINVAL;
625

626 627
	cx18_mute(cx);
	CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
628
	cx18_call_all(cx, tuner, s_frequency, vf);
629 630 631
	cx18_unmute(cx);
	return 0;
}
632

633 634
static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
{
635
	struct cx18 *cx = fh2id(fh)->cx;
636

637 638 639
	*std = cx->std;
	return 0;
}
640

641 642
int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
{
643
	struct cx18_open_id *id = fh2id(fh);
644
	struct cx18 *cx = id->cx;
645

646 647
	if ((*std & V4L2_STD_ALL) == 0)
		return -EINVAL;
648

649 650 651 652 653 654 655 656 657
	if (*std == cx->std)
		return 0;

	if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
	    atomic_read(&cx->ana_capturing) > 0) {
		/* Switching standard would turn off the radio or mess
		   with already running streams, prevent that by
		   returning EBUSY. */
		return -EBUSY;
658 659
	}

660 661
	cx->std = *std;
	cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
662 663 664 665
	cx->is_50hz = !cx->is_60hz;
	cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
	cx->cxhdl.width = 720;
	cx->cxhdl.height = cx->is_50hz ? 576 : 480;
666 667 668 669 670 671 672
	cx->vbi.count = cx->is_50hz ? 18 : 12;
	cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
	cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
	CX18_DEBUG_INFO("Switching standard to %llx.\n",
			(unsigned long long) cx->std);

	/* Tuner */
673
	cx18_call_all(cx, core, s_std, cx->std);
674 675
	return 0;
}
676

677 678
static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
{
679
	struct cx18_open_id *id = fh2id(fh);
680 681 682 683 684
	struct cx18 *cx = id->cx;

	if (vt->index != 0)
		return -EINVAL;

685
	cx18_call_all(cx, tuner, s_tuner, vt);
686 687 688 689 690
	return 0;
}

static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
{
691
	struct cx18 *cx = fh2id(fh)->cx;
692 693 694 695

	if (vt->index != 0)
		return -EINVAL;

696
	cx18_call_all(cx, tuner, g_tuner, vt);
697 698 699 700 701 702 703

	if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
		strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
		vt->type = V4L2_TUNER_RADIO;
	} else {
		strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
		vt->type = V4L2_TUNER_ANALOG_TV;
704 705
	}

706 707 708 709 710 711
	return 0;
}

static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
					struct v4l2_sliced_vbi_cap *cap)
{
712
	struct cx18 *cx = fh2id(fh)->cx;
713 714 715
	int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
	int f, l;

716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
	if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
		return -EINVAL;

	cap->service_set = 0;
	for (f = 0; f < 2; f++) {
		for (l = 0; l < 24; l++) {
			if (valid_service_line(f, l, cx->is_50hz)) {
				/*
				 * We can find all v4l2 supported vbi services
				 * for the standard, on a valid line for the std
				 */
				cap->service_lines[f][l] = set;
				cap->service_set |= set;
			} else
				cap->service_lines[f][l] = 0;
731 732
		}
	}
733 734 735
	for (f = 0; f < 3; f++)
		cap->reserved[f] = 0;
	return 0;
736
}
737

738 739 740 741 742 743 744 745 746 747 748 749 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 816 817 818 819 820 821 822 823 824 825 826 827 828 829
static int _cx18_process_idx_data(struct cx18_buffer *buf,
				  struct v4l2_enc_idx *idx)
{
	int consumed, remaining;
	struct v4l2_enc_idx_entry *e_idx;
	struct cx18_enc_idx_entry *e_buf;

	/* Frame type lookup: 1=I, 2=P, 4=B */
	const int mapping[8] = {
		-1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
		-1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
	};

	/*
	 * Assumption here is that a buf holds an integral number of
	 * struct cx18_enc_idx_entry objects and is properly aligned.
	 * This is enforced by the module options on IDX buffer sizes.
	 */
	remaining = buf->bytesused - buf->readpos;
	consumed = 0;
	e_idx = &idx->entry[idx->entries];
	e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];

	while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
	       idx->entries < V4L2_ENC_IDX_ENTRIES) {

		e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
				| le32_to_cpu(e_buf->offset_low);

		e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
			     | le32_to_cpu(e_buf->pts_low);

		e_idx->length = le32_to_cpu(e_buf->length);

		e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];

		e_idx->reserved[0] = 0;
		e_idx->reserved[1] = 0;

		idx->entries++;
		e_idx = &idx->entry[idx->entries];
		e_buf++;

		remaining -= sizeof(struct cx18_enc_idx_entry);
		consumed += sizeof(struct cx18_enc_idx_entry);
	}

	/* Swallow any partial entries at the end, if there are any */
	if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
		consumed += remaining;

	buf->readpos += consumed;
	return consumed;
}

static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
				 struct v4l2_enc_idx *idx)
{
	if (s->type != CX18_ENC_STREAM_TYPE_IDX)
		return -EINVAL;

	if (mdl->curr_buf == NULL)
		mdl->curr_buf = list_first_entry(&mdl->buf_list,
						 struct cx18_buffer, list);

	if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
		/*
		 * For some reason we've exhausted the buffers, but the MDL
		 * object still said some data was unread.
		 * Fix that and bail out.
		 */
		mdl->readpos = mdl->bytesused;
		return 0;
	}

	list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {

		/* Skip any empty buffers in the MDL */
		if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
			continue;

		mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);

		/* exit when MDL drained or request satisfied */
		if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
		    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
		    mdl->readpos >= mdl->bytesused)
			break;
	}
	return 0;
}

830 831 832
static int cx18_g_enc_index(struct file *file, void *fh,
				struct v4l2_enc_idx *idx)
{
833
	struct cx18 *cx = fh2id(fh)->cx;
834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874
	struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
	s32 tmp;
	struct cx18_mdl *mdl;

	if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
		return -EINVAL;

	/* Compute the best case number of entries we can buffer */
	tmp = s->buffers -
			  s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
	if (tmp <= 0)
		tmp = 1;
	tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);

	/* Fill out the header of the return structure */
	idx->entries = 0;
	idx->entries_cap = tmp;
	memset(idx->reserved, 0, sizeof(idx->reserved));

	/* Pull IDX MDLs and buffers from q_full and populate the entries */
	do {
		mdl = cx18_dequeue(s, &s->q_full);
		if (mdl == NULL) /* No more IDX data right now */
			break;

		/* Extract the Index entry data from the MDL and buffers */
		cx18_process_idx_data(s, mdl, idx);
		if (mdl->readpos < mdl->bytesused) {
			/* We finished with data remaining, push the MDL back */
			cx18_push(s, mdl, &s->q_full);
			break;
		}

		/* We drained this MDL, schedule it to go to the firmware */
		cx18_enqueue(s, mdl, &s->q_free);

	} while (idx->entries < V4L2_ENC_IDX_ENTRIES);

	/* Tell the work handler to send free IDX MDLs to the firmware */
	cx18_stream_load_fw_queue(s);
	return 0;
875
}
876

877 878 879
static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
{
	struct videobuf_queue *q = NULL;
880 881
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
882

883
	switch (s->vb_type) {
884
	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
885
		q = &s->vbuf_q;
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
		break;
	case V4L2_BUF_TYPE_VBI_CAPTURE:
		break;
	default:
		break;
	}
	return q;
}

static int cx18_streamon(struct file *file, void *priv,
	enum v4l2_buf_type type)
{
	struct cx18_open_id *id = file->private_data;
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	/* Start the hardware only if we're the video device */
903 904
	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
905 906 907 908 909 910
		return -EINVAL;

	if (id->type != CX18_ENC_STREAM_TYPE_YUV)
		return -EINVAL;

	/* Establish a buffer timeout */
911
	mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
912 913 914 915 916 917 918 919

	return videobuf_streamon(cx18_vb_queue(id));
}

static int cx18_streamoff(struct file *file, void *priv,
	enum v4l2_buf_type type)
{
	struct cx18_open_id *id = file->private_data;
920 921
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
922 923

	/* Start the hardware only if we're the video device */
924 925
	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
926 927 928 929 930 931 932 933 934 935 936 937
		return -EINVAL;

	if (id->type != CX18_ENC_STREAM_TYPE_YUV)
		return -EINVAL;

	return videobuf_streamoff(cx18_vb_queue(id));
}

static int cx18_reqbufs(struct file *file, void *priv,
	struct v4l2_requestbuffers *rb)
{
	struct cx18_open_id *id = file->private_data;
938 939
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
940

941 942
	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
943 944 945 946 947 948 949 950 951
		return -EINVAL;

	return videobuf_reqbufs(cx18_vb_queue(id), rb);
}

static int cx18_querybuf(struct file *file, void *priv,
	struct v4l2_buffer *b)
{
	struct cx18_open_id *id = file->private_data;
952 953
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
954

955 956
	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
957 958 959 960 961 962 963 964
		return -EINVAL;

	return videobuf_querybuf(cx18_vb_queue(id), b);
}

static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
	struct cx18_open_id *id = file->private_data;
965 966
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];
967

968 969
	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
970 971 972 973 974 975 976 977
		return -EINVAL;

	return videobuf_qbuf(cx18_vb_queue(id), b);
}

static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
{
	struct cx18_open_id *id = file->private_data;
978 979 980 981 982
	struct cx18 *cx = id->cx;
	struct cx18_stream *s = &cx->streams[id->type];

	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
983 984 985 986 987
		return -EINVAL;

	return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
}

988 989 990
static int cx18_encoder_cmd(struct file *file, void *fh,
				struct v4l2_encoder_cmd *enc)
{
991
	struct cx18_open_id *id = fh2id(fh);
992
	struct cx18 *cx = id->cx;
993
	u32 h;
994

995 996 997 998 999 1000 1001 1002 1003 1004 1005
	switch (enc->cmd) {
	case V4L2_ENC_CMD_START:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
		enc->flags = 0;
		return cx18_start_capture(id);

	case V4L2_ENC_CMD_STOP:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
		enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
		cx18_stop_capture(id,
				  enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1006 1007
		break;

1008 1009 1010 1011 1012 1013
	case V4L2_ENC_CMD_PAUSE:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
		enc->flags = 0;
		if (!atomic_read(&cx->ana_capturing))
			return -EPERM;
		if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
1014
			return 0;
1015 1016 1017 1018 1019 1020
		h = cx18_find_handle(cx);
		if (h == CX18_INVALID_TASK_HANDLE) {
			CX18_ERR("Can't find valid task handle for "
				 "V4L2_ENC_CMD_PAUSE\n");
			return -EBADFD;
		}
1021
		cx18_mute(cx);
1022
		cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
1023 1024 1025 1026 1027 1028 1029 1030 1031
		break;

	case V4L2_ENC_CMD_RESUME:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
		enc->flags = 0;
		if (!atomic_read(&cx->ana_capturing))
			return -EPERM;
		if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
			return 0;
1032 1033 1034 1035 1036 1037 1038
		h = cx18_find_handle(cx);
		if (h == CX18_INVALID_TASK_HANDLE) {
			CX18_ERR("Can't find valid task handle for "
				 "V4L2_ENC_CMD_RESUME\n");
			return -EBADFD;
		}
		cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
1039 1040 1041 1042 1043
		cx18_unmute(cx);
		break;

	default:
		CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1044 1045
		return -EINVAL;
	}
1046 1047
	return 0;
}
1048

1049 1050 1051
static int cx18_try_encoder_cmd(struct file *file, void *fh,
				struct v4l2_encoder_cmd *enc)
{
1052
	struct cx18 *cx = fh2id(fh)->cx;
1053

1054 1055 1056 1057
	switch (enc->cmd) {
	case V4L2_ENC_CMD_START:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
		enc->flags = 0;
1058 1059
		break;

1060 1061 1062 1063
	case V4L2_ENC_CMD_STOP:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
		enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
		break;
1064

1065 1066 1067 1068
	case V4L2_ENC_CMD_PAUSE:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
		enc->flags = 0;
		break;
1069

1070 1071 1072
	case V4L2_ENC_CMD_RESUME:
		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
		enc->flags = 0;
1073 1074 1075
		break;

	default:
1076
		CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1077 1078 1079 1080 1081
		return -EINVAL;
	}
	return 0;
}

1082
static int cx18_log_status(struct file *file, void *fh)
1083
{
1084
	struct cx18 *cx = fh2id(fh)->cx;
1085 1086 1087
	struct v4l2_input vidin;
	struct v4l2_audio audin;
	int i;
1088

1089
	CX18_INFO("=================  START STATUS CARD #%d  "
1090
		  "=================\n", cx->instance);
1091
	CX18_INFO("Version: %s  Card: %s\n", CX18_VERSION, cx->card_name);
1092 1093 1094 1095 1096
	if (cx->hw_flags & CX18_HW_TVEEPROM) {
		struct tveeprom tv;

		cx18_read_eeprom(cx, &tv);
	}
1097
	cx18_call_all(cx, core, log_status);
1098 1099 1100 1101
	cx18_get_input(cx, cx->active_input, &vidin);
	cx18_get_audio_input(cx, cx->audio_input, &audin);
	CX18_INFO("Video Input: %s\n", vidin.name);
	CX18_INFO("Audio Input: %s\n", audin.name);
1102
	mutex_lock(&cx->gpio_lock);
1103 1104
	CX18_INFO("GPIO:  direction 0x%08x, value 0x%08x\n",
		cx->gpio_dir, cx->gpio_val);
1105
	mutex_unlock(&cx->gpio_lock);
1106 1107
	CX18_INFO("Tuner: %s\n",
		test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ?  "Radio" : "TV");
1108
	v4l2_ctrl_handler_log_status(&cx->cxhdl.hdl, cx->v4l2_dev.name);
1109 1110 1111 1112
	CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
	for (i = 0; i < CX18_MAX_STREAMS; i++) {
		struct cx18_stream *s = &cx->streams[i];

1113
		if (s->video_dev == NULL || s->buffers == 0)
1114 1115 1116
			continue;
		CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
			  s->name, s->s_flags,
1117 1118
			  atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
			   / s->buffers,
1119 1120 1121 1122 1123
			  (s->buffers * s->buf_size) / 1024, s->buffers);
	}
	CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
			(long long)cx->mpg_data_received,
			(long long)cx->vbi_data_inserted);
1124 1125
	CX18_INFO("==================  END STATUS CARD #%d  "
		  "==================\n", cx->instance);
1126 1127 1128
	return 0;
}

1129 1130
static long cx18_default(struct file *file, void *fh, bool valid_prio,
							int cmd, void *arg)
1131
{
1132
	struct cx18 *cx = fh2id(fh)->cx;
1133 1134

	switch (cmd) {
1135 1136 1137 1138
	case VIDIOC_INT_RESET: {
		u32 val = *(u32 *)arg;

		if ((val == 0) || (val & 0x01))
1139 1140
			cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
				     (u32) CX18_GPIO_RESET_Z8F0811);
1141 1142 1143
		break;
	}

1144
	default:
1145 1146 1147 1148 1149
		return -EINVAL;
	}
	return 0;
}

1150
long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
1151 1152
		    unsigned long arg)
{
1153
	struct video_device *vfd = video_devdata(filp);
1154
	struct cx18_open_id *id = file2id(filp);
1155
	struct cx18 *cx = id->cx;
1156
	long res;
1157 1158

	mutex_lock(&cx->serialize_lock);
1159 1160 1161

	if (cx18_debug & CX18_DBGFLG_IOCTL)
		vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
1162
	res = video_ioctl2(filp, cmd, arg);
1163
	vfd->debug = 0;
1164 1165 1166
	mutex_unlock(&cx->serialize_lock);
	return res;
}
1167

1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200
static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
	.vidioc_querycap                = cx18_querycap,
	.vidioc_s_audio                 = cx18_s_audio,
	.vidioc_g_audio                 = cx18_g_audio,
	.vidioc_enumaudio               = cx18_enumaudio,
	.vidioc_enum_input              = cx18_enum_input,
	.vidioc_cropcap                 = cx18_cropcap,
	.vidioc_s_crop                  = cx18_s_crop,
	.vidioc_g_crop                  = cx18_g_crop,
	.vidioc_g_input                 = cx18_g_input,
	.vidioc_s_input                 = cx18_s_input,
	.vidioc_g_frequency             = cx18_g_frequency,
	.vidioc_s_frequency             = cx18_s_frequency,
	.vidioc_s_tuner                 = cx18_s_tuner,
	.vidioc_g_tuner                 = cx18_g_tuner,
	.vidioc_g_enc_index             = cx18_g_enc_index,
	.vidioc_g_std                   = cx18_g_std,
	.vidioc_s_std                   = cx18_s_std,
	.vidioc_log_status              = cx18_log_status,
	.vidioc_enum_fmt_vid_cap        = cx18_enum_fmt_vid_cap,
	.vidioc_encoder_cmd             = cx18_encoder_cmd,
	.vidioc_try_encoder_cmd         = cx18_try_encoder_cmd,
	.vidioc_g_fmt_vid_cap           = cx18_g_fmt_vid_cap,
	.vidioc_g_fmt_vbi_cap           = cx18_g_fmt_vbi_cap,
	.vidioc_g_fmt_sliced_vbi_cap    = cx18_g_fmt_sliced_vbi_cap,
	.vidioc_s_fmt_vid_cap           = cx18_s_fmt_vid_cap,
	.vidioc_s_fmt_vbi_cap           = cx18_s_fmt_vbi_cap,
	.vidioc_s_fmt_sliced_vbi_cap    = cx18_s_fmt_sliced_vbi_cap,
	.vidioc_try_fmt_vid_cap         = cx18_try_fmt_vid_cap,
	.vidioc_try_fmt_vbi_cap         = cx18_try_fmt_vbi_cap,
	.vidioc_try_fmt_sliced_vbi_cap  = cx18_try_fmt_sliced_vbi_cap,
	.vidioc_g_sliced_vbi_cap        = cx18_g_sliced_vbi_cap,
	.vidioc_g_chip_ident            = cx18_g_chip_ident,
1201
#ifdef CONFIG_VIDEO_ADV_DEBUG
1202 1203
	.vidioc_g_register              = cx18_g_register,
	.vidioc_s_register              = cx18_s_register,
1204
#endif
1205
	.vidioc_default                 = cx18_default,
1206 1207 1208 1209 1210 1211
	.vidioc_streamon                = cx18_streamon,
	.vidioc_streamoff               = cx18_streamoff,
	.vidioc_reqbufs                 = cx18_reqbufs,
	.vidioc_querybuf                = cx18_querybuf,
	.vidioc_qbuf                    = cx18_qbuf,
	.vidioc_dqbuf                   = cx18_dqbuf,
1212 1213 1214 1215 1216
};

void cx18_set_funcs(struct video_device *vdev)
{
	vdev->ioctl_ops = &cx18_ioctl_ops;
1217
}