Linux Audio

Check our new training course

Loading...
   1/*
   2 *  cx18 ioctl system call
   3 *
   4 *  Derived from ivtv-ioctl.c
   5 *
   6 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
   7 *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
   8 *
   9 *  This program is free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License as published by
  11 *  the Free Software Foundation; either version 2 of the License, or
  12 *  (at your option) any later version.
  13 *
  14 *  This program is distributed in the hope that it will be useful,
  15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *  GNU General Public License for more details.
  18 *
  19 *  You should have received a copy of the GNU General Public License
  20 *  along with this program; if not, write to the Free Software
  21 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  22 *  02111-1307  USA
  23 */
  24
  25#include "cx18-driver.h"
  26#include "cx18-io.h"
  27#include "cx18-version.h"
  28#include "cx18-mailbox.h"
  29#include "cx18-i2c.h"
  30#include "cx18-queue.h"
  31#include "cx18-fileops.h"
  32#include "cx18-vbi.h"
  33#include "cx18-audio.h"
  34#include "cx18-video.h"
  35#include "cx18-streams.h"
  36#include "cx18-ioctl.h"
  37#include "cx18-gpio.h"
  38#include "cx18-controls.h"
  39#include "cx18-cards.h"
  40#include "cx18-av-core.h"
  41#include <media/tveeprom.h>
  42#include <media/v4l2-chip-ident.h>
  43
  44u16 cx18_service2vbi(int type)
  45{
  46	switch (type) {
  47	case V4L2_SLICED_TELETEXT_B:
  48		return CX18_SLICED_TYPE_TELETEXT_B;
  49	case V4L2_SLICED_CAPTION_525:
  50		return CX18_SLICED_TYPE_CAPTION_525;
  51	case V4L2_SLICED_WSS_625:
  52		return CX18_SLICED_TYPE_WSS_625;
  53	case V4L2_SLICED_VPS:
  54		return CX18_SLICED_TYPE_VPS;
  55	default:
  56		return 0;
  57	}
  58}
  59
  60/* Check if VBI services are allowed on the (field, line) for the video std */
  61static int valid_service_line(int field, int line, int is_pal)
  62{
  63	return (is_pal && line >= 6 &&
  64		((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
  65	       (!is_pal && line >= 10 && line < 22);
  66}
  67
  68/*
  69 * For a (field, line, std) and inbound potential set of services for that line,
  70 * return the first valid service of those passed in the incoming set for that
  71 * line in priority order:
  72 * CC, VPS, or WSS over TELETEXT for well known lines
  73 * TELETEXT, before VPS, before CC, before WSS, for other lines
  74 */
  75static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
  76{
  77	u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
  78	int i;
  79
  80	set = set & valid_set;
  81	if (set == 0 || !valid_service_line(field, line, is_pal))
  82		return 0;
  83	if (!is_pal) {
  84		if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
  85			return V4L2_SLICED_CAPTION_525;
  86	} else {
  87		if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
  88			return V4L2_SLICED_VPS;
  89		if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
  90			return V4L2_SLICED_WSS_625;
  91		if (line == 23)
  92			return 0;
  93	}
  94	for (i = 0; i < 32; i++) {
  95		if ((1 << i) & set)
  96			return 1 << i;
  97	}
  98	return 0;
  99}
 100
 101/*
 102 * Expand the service_set of *fmt into valid service_lines for the std,
 103 * and clear the passed in fmt->service_set
 104 */
 105void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
 106{
 107	u16 set = fmt->service_set;
 108	int f, l;
 109
 110	fmt->service_set = 0;
 111	for (f = 0; f < 2; f++) {
 112		for (l = 0; l < 24; l++)
 113			fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
 114	}
 115}
 116
 117/*
 118 * Sanitize the service_lines in *fmt per the video std, and return 1
 119 * if any service_line is left as valid after santization
 120 */
 121static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
 122{
 123	int f, l;
 124	u16 set = 0;
 125
 126	for (f = 0; f < 2; f++) {
 127		for (l = 0; l < 24; l++) {
 128			fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
 129			set |= fmt->service_lines[f][l];
 130		}
 131	}
 132	return set != 0;
 133}
 134
 135/* Compute the service_set from the assumed valid service_lines of *fmt */
 136u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
 137{
 138	int f, l;
 139	u16 set = 0;
 140
 141	for (f = 0; f < 2; f++) {
 142		for (l = 0; l < 24; l++)
 143			set |= fmt->service_lines[f][l];
 144	}
 145	return set;
 146}
 147
 148static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
 149				struct v4l2_format *fmt)
 150{
 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	pixfmt->width = cx->cxhdl.width;
 157	pixfmt->height = cx->cxhdl.height;
 158	pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
 159	pixfmt->field = V4L2_FIELD_INTERLACED;
 160	pixfmt->priv = 0;
 161	if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
 162		pixfmt->pixelformat = s->pixelformat;
 163		pixfmt->sizeimage = s->vb_bytes_per_frame;
 164		pixfmt->bytesperline = 720;
 165	} else {
 166		pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
 167		pixfmt->sizeimage = 128 * 1024;
 168		pixfmt->bytesperline = 0;
 169	}
 170	return 0;
 171}
 172
 173static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
 174				struct v4l2_format *fmt)
 175{
 176	struct cx18 *cx = fh2id(fh)->cx;
 177	struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
 178
 179	vbifmt->sampling_rate = 27000000;
 180	vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
 181	vbifmt->samples_per_line = vbi_active_samples - 4;
 182	vbifmt->sample_format = V4L2_PIX_FMT_GREY;
 183	vbifmt->start[0] = cx->vbi.start[0];
 184	vbifmt->start[1] = cx->vbi.start[1];
 185	vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count;
 186	vbifmt->flags = 0;
 187	vbifmt->reserved[0] = 0;
 188	vbifmt->reserved[1] = 0;
 189	return 0;
 190}
 191
 192static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
 193					struct v4l2_format *fmt)
 194{
 195	struct cx18 *cx = fh2id(fh)->cx;
 196	struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
 197
 198	/* sane, V4L2 spec compliant, defaults */
 199	vbifmt->reserved[0] = 0;
 200	vbifmt->reserved[1] = 0;
 201	vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
 202	memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
 203	vbifmt->service_set = 0;
 204
 205	/*
 206	 * Fetch the configured service_lines and total service_set from the
 207	 * digitizer/slicer.  Note, cx18_av_vbi() wipes the passed in
 208	 * fmt->fmt.sliced under valid calling conditions
 209	 */
 210	if (v4l2_subdev_call(cx->sd_av, vbi, g_sliced_fmt, &fmt->fmt.sliced))
 211		return -EINVAL;
 212
 213	/* Ensure V4L2 spec compliant output */
 214	vbifmt->reserved[0] = 0;
 215	vbifmt->reserved[1] = 0;
 216	vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
 217	vbifmt->service_set = cx18_get_service_set(vbifmt);
 218	return 0;
 219}
 220
 221static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
 222				struct v4l2_format *fmt)
 223{
 224	struct cx18_open_id *id = fh2id(fh);
 225	struct cx18 *cx = id->cx;
 226	int w = fmt->fmt.pix.width;
 227	int h = fmt->fmt.pix.height;
 228	int min_h = 2;
 229
 230	w = min(w, 720);
 231	w = max(w, 2);
 232	if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
 233		/* YUV height must be a multiple of 32 */
 234		h &= ~0x1f;
 235		min_h = 32;
 236	}
 237	h = min(h, cx->is_50hz ? 576 : 480);
 238	h = max(h, min_h);
 239
 240	fmt->fmt.pix.width = w;
 241	fmt->fmt.pix.height = h;
 242	return 0;
 243}
 244
 245static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
 246				struct v4l2_format *fmt)
 247{
 248	return cx18_g_fmt_vbi_cap(file, fh, fmt);
 249}
 250
 251static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
 252					struct v4l2_format *fmt)
 253{
 254	struct cx18 *cx = fh2id(fh)->cx;
 255	struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
 256
 257	vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
 258	vbifmt->reserved[0] = 0;
 259	vbifmt->reserved[1] = 0;
 260
 261	/* If given a service set, expand it validly & clear passed in set */
 262	if (vbifmt->service_set)
 263		cx18_expand_service_set(vbifmt, cx->is_50hz);
 264	/* Sanitize the service_lines, and compute the new set if any valid */
 265	if (check_service_set(vbifmt, cx->is_50hz))
 266		vbifmt->service_set = cx18_get_service_set(vbifmt);
 267	return 0;
 268}
 269
 270static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
 271				struct v4l2_format *fmt)
 272{
 273	struct cx18_open_id *id = fh2id(fh);
 274	struct cx18 *cx = id->cx;
 275	struct v4l2_mbus_framefmt mbus_fmt;
 276	struct cx18_stream *s = &cx->streams[id->type];
 277	int ret;
 278	int w, h;
 279
 280	ret = cx18_try_fmt_vid_cap(file, fh, fmt);
 281	if (ret)
 282		return ret;
 283	w = fmt->fmt.pix.width;
 284	h = fmt->fmt.pix.height;
 285
 286	if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
 287	    s->pixelformat == fmt->fmt.pix.pixelformat)
 288		return 0;
 289
 290	if (atomic_read(&cx->ana_capturing) > 0)
 291		return -EBUSY;
 292
 293	s->pixelformat = fmt->fmt.pix.pixelformat;
 294	/* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
 295	   UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
 296	if (s->pixelformat == V4L2_PIX_FMT_HM12)
 297		s->vb_bytes_per_frame = h * 720 * 3 / 2;
 298	else
 299		s->vb_bytes_per_frame = h * 720 * 2;
 300
 301	mbus_fmt.width = cx->cxhdl.width = w;
 302	mbus_fmt.height = cx->cxhdl.height = h;
 303	mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
 304	v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
 305	return cx18_g_fmt_vid_cap(file, fh, fmt);
 306}
 307
 308static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
 309				struct v4l2_format *fmt)
 310{
 311	struct cx18_open_id *id = fh2id(fh);
 312	struct cx18 *cx = id->cx;
 313	int ret;
 314
 315	/*
 316	 * Changing the Encoder's Raw VBI parameters won't have any effect
 317	 * if any analog capture is ongoing
 318	 */
 319	if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
 320		return -EBUSY;
 321
 322	/*
 323	 * Set the digitizer registers for raw active VBI.
 324	 * Note cx18_av_vbi_wipes out a lot of the passed in fmt under valid
 325	 * calling conditions
 326	 */
 327	ret = v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &fmt->fmt.vbi);
 328	if (ret)
 329		return ret;
 330
 331	/* Store our new v4l2 (non-)sliced VBI state */
 332	cx->vbi.sliced_in->service_set = 0;
 333	cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
 334
 335	return cx18_g_fmt_vbi_cap(file, fh, fmt);
 336}
 337
 338static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
 339					struct v4l2_format *fmt)
 340{
 341	struct cx18_open_id *id = fh2id(fh);
 342	struct cx18 *cx = id->cx;
 343	int ret;
 344	struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
 345
 346	cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
 347
 348	/*
 349	 * Changing the Encoder's Raw VBI parameters won't have any effect
 350	 * if any analog capture is ongoing
 351	 */
 352	if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
 353		return -EBUSY;
 354
 355	/*
 356	 * Set the service_lines requested in the digitizer/slicer registers.
 357	 * Note, cx18_av_vbi() wipes some "impossible" service lines in the
 358	 * passed in fmt->fmt.sliced under valid calling conditions
 359	 */
 360	ret = v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &fmt->fmt.sliced);
 361	if (ret)
 362		return ret;
 363	/* Store our current v4l2 sliced VBI settings */
 364	cx->vbi.in.type =  V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
 365	memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
 366	return 0;
 367}
 368
 369static int cx18_g_chip_ident(struct file *file, void *fh,
 370				struct v4l2_dbg_chip_ident *chip)
 371{
 372	struct cx18 *cx = fh2id(fh)->cx;
 373	int err = 0;
 374
 375	chip->ident = V4L2_IDENT_NONE;
 376	chip->revision = 0;
 377	switch (chip->match.type) {
 378	case V4L2_CHIP_MATCH_HOST:
 379		switch (chip->match.addr) {
 380		case 0:
 381			chip->ident = V4L2_IDENT_CX23418;
 382			chip->revision = cx18_read_reg(cx, 0xC72028);
 383			break;
 384		case 1:
 385			/*
 386			 * The A/V decoder is always present, but in the rare
 387			 * case that the card doesn't have analog, we don't
 388			 * use it.  We find it w/o using the cx->sd_av pointer
 389			 */
 390			cx18_call_hw(cx, CX18_HW_418_AV,
 391				     core, g_chip_ident, chip);
 392			break;
 393		default:
 394			/*
 395			 * Could return ident = V4L2_IDENT_UNKNOWN if we had
 396			 * other host chips at higher addresses, but we don't
 397			 */
 398			err = -EINVAL; /* per V4L2 spec */
 399			break;
 400		}
 401		break;
 402	case V4L2_CHIP_MATCH_I2C_DRIVER:
 403		/* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
 404		cx18_call_all(cx, core, g_chip_ident, chip);
 405		break;
 406	case V4L2_CHIP_MATCH_I2C_ADDR:
 407		/*
 408		 * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
 409		 * to look if a chip is at the address with no driver.  That's a
 410		 * dangerous thing to do with EEPROMs anyway.
 411		 */
 412		cx18_call_all(cx, core, g_chip_ident, chip);
 413		break;
 414	default:
 415		err = -EINVAL;
 416		break;
 417	}
 418	return err;
 419}
 420
 421#ifdef CONFIG_VIDEO_ADV_DEBUG
 422static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
 423{
 424	struct v4l2_dbg_register *regs = arg;
 425
 426	if (!capable(CAP_SYS_ADMIN))
 427		return -EPERM;
 428	if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
 429		return -EINVAL;
 430
 431	regs->size = 4;
 432	if (cmd == VIDIOC_DBG_S_REGISTER)
 433		cx18_write_enc(cx, regs->val, regs->reg);
 434	else
 435		regs->val = cx18_read_enc(cx, regs->reg);
 436	return 0;
 437}
 438
 439static int cx18_g_register(struct file *file, void *fh,
 440				struct v4l2_dbg_register *reg)
 441{
 442	struct cx18 *cx = fh2id(fh)->cx;
 443
 444	if (v4l2_chip_match_host(&reg->match))
 445		return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
 446	/* FIXME - errors shouldn't be ignored */
 447	cx18_call_all(cx, core, g_register, reg);
 448	return 0;
 449}
 450
 451static int cx18_s_register(struct file *file, void *fh,
 452				struct v4l2_dbg_register *reg)
 453{
 454	struct cx18 *cx = fh2id(fh)->cx;
 455
 456	if (v4l2_chip_match_host(&reg->match))
 457		return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
 458	/* FIXME - errors shouldn't be ignored */
 459	cx18_call_all(cx, core, s_register, reg);
 460	return 0;
 461}
 462#endif
 463
 464static int cx18_querycap(struct file *file, void *fh,
 465				struct v4l2_capability *vcap)
 466{
 467	struct cx18_open_id *id = fh2id(fh);
 468	struct cx18 *cx = id->cx;
 469
 470	strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
 471	strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
 472	snprintf(vcap->bus_info, sizeof(vcap->bus_info),
 473		 "PCI:%s", pci_name(cx->pci_dev));
 474	vcap->capabilities = cx->v4l2_cap; 	    /* capabilities */
 475	if (id->type == CX18_ENC_STREAM_TYPE_YUV)
 476		vcap->capabilities |= V4L2_CAP_STREAMING;
 477	return 0;
 478}
 479
 480static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
 481{
 482	struct cx18 *cx = fh2id(fh)->cx;
 483
 484	return cx18_get_audio_input(cx, vin->index, vin);
 485}
 486
 487static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
 488{
 489	struct cx18 *cx = fh2id(fh)->cx;
 490
 491	vin->index = cx->audio_input;
 492	return cx18_get_audio_input(cx, vin->index, vin);
 493}
 494
 495static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
 496{
 497	struct cx18 *cx = fh2id(fh)->cx;
 498
 499	if (vout->index >= cx->nof_audio_inputs)
 500		return -EINVAL;
 501	cx->audio_input = vout->index;
 502	cx18_audio_set_io(cx);
 503	return 0;
 504}
 505
 506static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
 507{
 508	struct cx18 *cx = fh2id(fh)->cx;
 509
 510	/* set it to defaults from our table */
 511	return cx18_get_input(cx, vin->index, vin);
 512}
 513
 514static int cx18_cropcap(struct file *file, void *fh,
 515			struct v4l2_cropcap *cropcap)
 516{
 517	struct cx18 *cx = fh2id(fh)->cx;
 518
 519	if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 520		return -EINVAL;
 521	cropcap->bounds.top = cropcap->bounds.left = 0;
 522	cropcap->bounds.width = 720;
 523	cropcap->bounds.height = cx->is_50hz ? 576 : 480;
 524	cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10;
 525	cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11;
 526	cropcap->defrect = cropcap->bounds;
 527	return 0;
 528}
 529
 530static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 531{
 532	struct cx18_open_id *id = fh2id(fh);
 533	struct cx18 *cx = id->cx;
 534
 535	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 536		return -EINVAL;
 537	CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
 538	return -EINVAL;
 539}
 540
 541static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 542{
 543	struct cx18 *cx = fh2id(fh)->cx;
 544
 545	if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 546		return -EINVAL;
 547	CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
 548	return -EINVAL;
 549}
 550
 551static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
 552					struct v4l2_fmtdesc *fmt)
 553{
 554	static const struct v4l2_fmtdesc formats[] = {
 555		{ 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
 556		  "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
 557		},
 558		{ 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
 559		  "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
 560		},
 561		{ 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
 562		  "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
 563		},
 564	};
 565
 566	if (fmt->index > ARRAY_SIZE(formats) - 1)
 567		return -EINVAL;
 568	*fmt = formats[fmt->index];
 569	return 0;
 570}
 571
 572static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
 573{
 574	struct cx18 *cx = fh2id(fh)->cx;
 575
 576	*i = cx->active_input;
 577	return 0;
 578}
 579
 580int cx18_s_input(struct file *file, void *fh, unsigned int inp)
 581{
 582	struct cx18_open_id *id = fh2id(fh);
 583	struct cx18 *cx = id->cx;
 584
 585	if (inp >= cx->nof_inputs)
 586		return -EINVAL;
 587
 588	if (inp == cx->active_input) {
 589		CX18_DEBUG_INFO("Input unchanged\n");
 590		return 0;
 591	}
 592
 593	CX18_DEBUG_INFO("Changing input from %d to %d\n",
 594			cx->active_input, inp);
 595
 596	cx->active_input = inp;
 597	/* Set the audio input to whatever is appropriate for the input type. */
 598	cx->audio_input = cx->card->video_inputs[inp].audio_index;
 599
 600	/* prevent others from messing with the streams until
 601	   we're finished changing inputs. */
 602	cx18_mute(cx);
 603	cx18_video_set_io(cx);
 604	cx18_audio_set_io(cx);
 605	cx18_unmute(cx);
 606	return 0;
 607}
 608
 609static int cx18_g_frequency(struct file *file, void *fh,
 610				struct v4l2_frequency *vf)
 611{
 612	struct cx18 *cx = fh2id(fh)->cx;
 613
 614	if (vf->tuner != 0)
 615		return -EINVAL;
 616
 617	cx18_call_all(cx, tuner, g_frequency, vf);
 618	return 0;
 619}
 620
 621int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
 622{
 623	struct cx18_open_id *id = fh2id(fh);
 624	struct cx18 *cx = id->cx;
 625
 626	if (vf->tuner != 0)
 627		return -EINVAL;
 628
 629	cx18_mute(cx);
 630	CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
 631	cx18_call_all(cx, tuner, s_frequency, vf);
 632	cx18_unmute(cx);
 633	return 0;
 634}
 635
 636static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
 637{
 638	struct cx18 *cx = fh2id(fh)->cx;
 639
 640	*std = cx->std;
 641	return 0;
 642}
 643
 644int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
 645{
 646	struct cx18_open_id *id = fh2id(fh);
 647	struct cx18 *cx = id->cx;
 648
 649	if ((*std & V4L2_STD_ALL) == 0)
 650		return -EINVAL;
 651
 652	if (*std == cx->std)
 653		return 0;
 654
 655	if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
 656	    atomic_read(&cx->ana_capturing) > 0) {
 657		/* Switching standard would turn off the radio or mess
 658		   with already running streams, prevent that by
 659		   returning EBUSY. */
 660		return -EBUSY;
 661	}
 662
 663	cx->std = *std;
 664	cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
 665	cx->is_50hz = !cx->is_60hz;
 666	cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
 667	cx->cxhdl.width = 720;
 668	cx->cxhdl.height = cx->is_50hz ? 576 : 480;
 669	cx->vbi.count = cx->is_50hz ? 18 : 12;
 670	cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
 671	cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
 672	CX18_DEBUG_INFO("Switching standard to %llx.\n",
 673			(unsigned long long) cx->std);
 674
 675	/* Tuner */
 676	cx18_call_all(cx, core, s_std, cx->std);
 677	return 0;
 678}
 679
 680static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
 681{
 682	struct cx18_open_id *id = fh2id(fh);
 683	struct cx18 *cx = id->cx;
 684
 685	if (vt->index != 0)
 686		return -EINVAL;
 687
 688	cx18_call_all(cx, tuner, s_tuner, vt);
 689	return 0;
 690}
 691
 692static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
 693{
 694	struct cx18 *cx = fh2id(fh)->cx;
 695
 696	if (vt->index != 0)
 697		return -EINVAL;
 698
 699	cx18_call_all(cx, tuner, g_tuner, vt);
 700
 701	if (vt->type == V4L2_TUNER_RADIO)
 702		strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
 703	else
 704		strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
 705	return 0;
 706}
 707
 708static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
 709					struct v4l2_sliced_vbi_cap *cap)
 710{
 711	struct cx18 *cx = fh2id(fh)->cx;
 712	int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
 713	int f, l;
 714
 715	if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
 716		return -EINVAL;
 717
 718	cap->service_set = 0;
 719	for (f = 0; f < 2; f++) {
 720		for (l = 0; l < 24; l++) {
 721			if (valid_service_line(f, l, cx->is_50hz)) {
 722				/*
 723				 * We can find all v4l2 supported vbi services
 724				 * for the standard, on a valid line for the std
 725				 */
 726				cap->service_lines[f][l] = set;
 727				cap->service_set |= set;
 728			} else
 729				cap->service_lines[f][l] = 0;
 730		}
 731	}
 732	for (f = 0; f < 3; f++)
 733		cap->reserved[f] = 0;
 734	return 0;
 735}
 736
 737static int _cx18_process_idx_data(struct cx18_buffer *buf,
 738				  struct v4l2_enc_idx *idx)
 739{
 740	int consumed, remaining;
 741	struct v4l2_enc_idx_entry *e_idx;
 742	struct cx18_enc_idx_entry *e_buf;
 743
 744	/* Frame type lookup: 1=I, 2=P, 4=B */
 745	const int mapping[8] = {
 746		-1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
 747		-1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
 748	};
 749
 750	/*
 751	 * Assumption here is that a buf holds an integral number of
 752	 * struct cx18_enc_idx_entry objects and is properly aligned.
 753	 * This is enforced by the module options on IDX buffer sizes.
 754	 */
 755	remaining = buf->bytesused - buf->readpos;
 756	consumed = 0;
 757	e_idx = &idx->entry[idx->entries];
 758	e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];
 759
 760	while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
 761	       idx->entries < V4L2_ENC_IDX_ENTRIES) {
 762
 763		e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
 764				| le32_to_cpu(e_buf->offset_low);
 765
 766		e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
 767			     | le32_to_cpu(e_buf->pts_low);
 768
 769		e_idx->length = le32_to_cpu(e_buf->length);
 770
 771		e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];
 772
 773		e_idx->reserved[0] = 0;
 774		e_idx->reserved[1] = 0;
 775
 776		idx->entries++;
 777		e_idx = &idx->entry[idx->entries];
 778		e_buf++;
 779
 780		remaining -= sizeof(struct cx18_enc_idx_entry);
 781		consumed += sizeof(struct cx18_enc_idx_entry);
 782	}
 783
 784	/* Swallow any partial entries at the end, if there are any */
 785	if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
 786		consumed += remaining;
 787
 788	buf->readpos += consumed;
 789	return consumed;
 790}
 791
 792static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
 793				 struct v4l2_enc_idx *idx)
 794{
 795	if (s->type != CX18_ENC_STREAM_TYPE_IDX)
 796		return -EINVAL;
 797
 798	if (mdl->curr_buf == NULL)
 799		mdl->curr_buf = list_first_entry(&mdl->buf_list,
 800						 struct cx18_buffer, list);
 801
 802	if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
 803		/*
 804		 * For some reason we've exhausted the buffers, but the MDL
 805		 * object still said some data was unread.
 806		 * Fix that and bail out.
 807		 */
 808		mdl->readpos = mdl->bytesused;
 809		return 0;
 810	}
 811
 812	list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
 813
 814		/* Skip any empty buffers in the MDL */
 815		if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
 816			continue;
 817
 818		mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);
 819
 820		/* exit when MDL drained or request satisfied */
 821		if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
 822		    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
 823		    mdl->readpos >= mdl->bytesused)
 824			break;
 825	}
 826	return 0;
 827}
 828
 829static int cx18_g_enc_index(struct file *file, void *fh,
 830				struct v4l2_enc_idx *idx)
 831{
 832	struct cx18 *cx = fh2id(fh)->cx;
 833	struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 834	s32 tmp;
 835	struct cx18_mdl *mdl;
 836
 837	if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
 838		return -EINVAL;
 839
 840	/* Compute the best case number of entries we can buffer */
 841	tmp = s->buffers -
 842			  s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
 843	if (tmp <= 0)
 844		tmp = 1;
 845	tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);
 846
 847	/* Fill out the header of the return structure */
 848	idx->entries = 0;
 849	idx->entries_cap = tmp;
 850	memset(idx->reserved, 0, sizeof(idx->reserved));
 851
 852	/* Pull IDX MDLs and buffers from q_full and populate the entries */
 853	do {
 854		mdl = cx18_dequeue(s, &s->q_full);
 855		if (mdl == NULL) /* No more IDX data right now */
 856			break;
 857
 858		/* Extract the Index entry data from the MDL and buffers */
 859		cx18_process_idx_data(s, mdl, idx);
 860		if (mdl->readpos < mdl->bytesused) {
 861			/* We finished with data remaining, push the MDL back */
 862			cx18_push(s, mdl, &s->q_full);
 863			break;
 864		}
 865
 866		/* We drained this MDL, schedule it to go to the firmware */
 867		cx18_enqueue(s, mdl, &s->q_free);
 868
 869	} while (idx->entries < V4L2_ENC_IDX_ENTRIES);
 870
 871	/* Tell the work handler to send free IDX MDLs to the firmware */
 872	cx18_stream_load_fw_queue(s);
 873	return 0;
 874}
 875
 876static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
 877{
 878	struct videobuf_queue *q = NULL;
 879	struct cx18 *cx = id->cx;
 880	struct cx18_stream *s = &cx->streams[id->type];
 881
 882	switch (s->vb_type) {
 883	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 884		q = &s->vbuf_q;
 885		break;
 886	case V4L2_BUF_TYPE_VBI_CAPTURE:
 887		break;
 888	default:
 889		break;
 890	}
 891	return q;
 892}
 893
 894static int cx18_streamon(struct file *file, void *priv,
 895	enum v4l2_buf_type type)
 896{
 897	struct cx18_open_id *id = file->private_data;
 898	struct cx18 *cx = id->cx;
 899	struct cx18_stream *s = &cx->streams[id->type];
 900
 901	/* Start the hardware only if we're the video device */
 902	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 903		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 904		return -EINVAL;
 905
 906	if (id->type != CX18_ENC_STREAM_TYPE_YUV)
 907		return -EINVAL;
 908
 909	/* Establish a buffer timeout */
 910	mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
 911
 912	return videobuf_streamon(cx18_vb_queue(id));
 913}
 914
 915static int cx18_streamoff(struct file *file, void *priv,
 916	enum v4l2_buf_type type)
 917{
 918	struct cx18_open_id *id = file->private_data;
 919	struct cx18 *cx = id->cx;
 920	struct cx18_stream *s = &cx->streams[id->type];
 921
 922	/* Start the hardware only if we're the video device */
 923	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 924		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 925		return -EINVAL;
 926
 927	if (id->type != CX18_ENC_STREAM_TYPE_YUV)
 928		return -EINVAL;
 929
 930	return videobuf_streamoff(cx18_vb_queue(id));
 931}
 932
 933static int cx18_reqbufs(struct file *file, void *priv,
 934	struct v4l2_requestbuffers *rb)
 935{
 936	struct cx18_open_id *id = file->private_data;
 937	struct cx18 *cx = id->cx;
 938	struct cx18_stream *s = &cx->streams[id->type];
 939
 940	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 941		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 942		return -EINVAL;
 943
 944	return videobuf_reqbufs(cx18_vb_queue(id), rb);
 945}
 946
 947static int cx18_querybuf(struct file *file, void *priv,
 948	struct v4l2_buffer *b)
 949{
 950	struct cx18_open_id *id = file->private_data;
 951	struct cx18 *cx = id->cx;
 952	struct cx18_stream *s = &cx->streams[id->type];
 953
 954	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 955		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 956		return -EINVAL;
 957
 958	return videobuf_querybuf(cx18_vb_queue(id), b);
 959}
 960
 961static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 962{
 963	struct cx18_open_id *id = file->private_data;
 964	struct cx18 *cx = id->cx;
 965	struct cx18_stream *s = &cx->streams[id->type];
 966
 967	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 968		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 969		return -EINVAL;
 970
 971	return videobuf_qbuf(cx18_vb_queue(id), b);
 972}
 973
 974static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 975{
 976	struct cx18_open_id *id = file->private_data;
 977	struct cx18 *cx = id->cx;
 978	struct cx18_stream *s = &cx->streams[id->type];
 979
 980	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 981		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 982		return -EINVAL;
 983
 984	return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
 985}
 986
 987static int cx18_encoder_cmd(struct file *file, void *fh,
 988				struct v4l2_encoder_cmd *enc)
 989{
 990	struct cx18_open_id *id = fh2id(fh);
 991	struct cx18 *cx = id->cx;
 992	u32 h;
 993
 994	switch (enc->cmd) {
 995	case V4L2_ENC_CMD_START:
 996		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
 997		enc->flags = 0;
 998		return cx18_start_capture(id);
 999
1000	case V4L2_ENC_CMD_STOP:
1001		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1002		enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1003		cx18_stop_capture(id,
1004				  enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1005		break;
1006
1007	case V4L2_ENC_CMD_PAUSE:
1008		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1009		enc->flags = 0;
1010		if (!atomic_read(&cx->ana_capturing))
1011			return -EPERM;
1012		if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
1013			return 0;
1014		h = cx18_find_handle(cx);
1015		if (h == CX18_INVALID_TASK_HANDLE) {
1016			CX18_ERR("Can't find valid task handle for "
1017				 "V4L2_ENC_CMD_PAUSE\n");
1018			return -EBADFD;
1019		}
1020		cx18_mute(cx);
1021		cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
1022		break;
1023
1024	case V4L2_ENC_CMD_RESUME:
1025		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1026		enc->flags = 0;
1027		if (!atomic_read(&cx->ana_capturing))
1028			return -EPERM;
1029		if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
1030			return 0;
1031		h = cx18_find_handle(cx);
1032		if (h == CX18_INVALID_TASK_HANDLE) {
1033			CX18_ERR("Can't find valid task handle for "
1034				 "V4L2_ENC_CMD_RESUME\n");
1035			return -EBADFD;
1036		}
1037		cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
1038		cx18_unmute(cx);
1039		break;
1040
1041	default:
1042		CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1043		return -EINVAL;
1044	}
1045	return 0;
1046}
1047
1048static int cx18_try_encoder_cmd(struct file *file, void *fh,
1049				struct v4l2_encoder_cmd *enc)
1050{
1051	struct cx18 *cx = fh2id(fh)->cx;
1052
1053	switch (enc->cmd) {
1054	case V4L2_ENC_CMD_START:
1055		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1056		enc->flags = 0;
1057		break;
1058
1059	case V4L2_ENC_CMD_STOP:
1060		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1061		enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1062		break;
1063
1064	case V4L2_ENC_CMD_PAUSE:
1065		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1066		enc->flags = 0;
1067		break;
1068
1069	case V4L2_ENC_CMD_RESUME:
1070		CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1071		enc->flags = 0;
1072		break;
1073
1074	default:
1075		CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1076		return -EINVAL;
1077	}
1078	return 0;
1079}
1080
1081static int cx18_log_status(struct file *file, void *fh)
1082{
1083	struct cx18 *cx = fh2id(fh)->cx;
1084	struct v4l2_input vidin;
1085	struct v4l2_audio audin;
1086	int i;
1087
1088	CX18_INFO("Version: %s  Card: %s\n", CX18_VERSION, cx->card_name);
1089	if (cx->hw_flags & CX18_HW_TVEEPROM) {
1090		struct tveeprom tv;
1091
1092		cx18_read_eeprom(cx, &tv);
1093	}
1094	cx18_call_all(cx, core, log_status);
1095	cx18_get_input(cx, cx->active_input, &vidin);
1096	cx18_get_audio_input(cx, cx->audio_input, &audin);
1097	CX18_INFO("Video Input: %s\n", vidin.name);
1098	CX18_INFO("Audio Input: %s\n", audin.name);
1099	mutex_lock(&cx->gpio_lock);
1100	CX18_INFO("GPIO:  direction 0x%08x, value 0x%08x\n",
1101		cx->gpio_dir, cx->gpio_val);
1102	mutex_unlock(&cx->gpio_lock);
1103	CX18_INFO("Tuner: %s\n",
1104		test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ?  "Radio" : "TV");
1105	v4l2_ctrl_handler_log_status(&cx->cxhdl.hdl, cx->v4l2_dev.name);
1106	CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
1107	for (i = 0; i < CX18_MAX_STREAMS; i++) {
1108		struct cx18_stream *s = &cx->streams[i];
1109
1110		if (s->video_dev == NULL || s->buffers == 0)
1111			continue;
1112		CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
1113			  s->name, s->s_flags,
1114			  atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
1115			   / s->buffers,
1116			  (s->buffers * s->buf_size) / 1024, s->buffers);
1117	}
1118	CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
1119			(long long)cx->mpg_data_received,
1120			(long long)cx->vbi_data_inserted);
1121	return 0;
1122}
1123
1124static long cx18_default(struct file *file, void *fh, bool valid_prio,
1125							int cmd, void *arg)
1126{
1127	struct cx18 *cx = fh2id(fh)->cx;
1128
1129	switch (cmd) {
1130	case VIDIOC_INT_RESET: {
1131		u32 val = *(u32 *)arg;
1132
1133		if ((val == 0) || (val & 0x01))
1134			cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
1135				     (u32) CX18_GPIO_RESET_Z8F0811);
1136		break;
1137	}
1138
1139	default:
1140		return -ENOTTY;
1141	}
1142	return 0;
1143}
1144
1145long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
1146		    unsigned long arg)
1147{
1148	struct video_device *vfd = video_devdata(filp);
1149	struct cx18_open_id *id = file2id(filp);
1150	struct cx18 *cx = id->cx;
1151	long res;
1152
1153	mutex_lock(&cx->serialize_lock);
1154
1155	if (cx18_debug & CX18_DBGFLG_IOCTL)
1156		vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
1157	res = video_ioctl2(filp, cmd, arg);
1158	vfd->debug = 0;
1159	mutex_unlock(&cx->serialize_lock);
1160	return res;
1161}
1162
1163static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1164	.vidioc_querycap                = cx18_querycap,
1165	.vidioc_s_audio                 = cx18_s_audio,
1166	.vidioc_g_audio                 = cx18_g_audio,
1167	.vidioc_enumaudio               = cx18_enumaudio,
1168	.vidioc_enum_input              = cx18_enum_input,
1169	.vidioc_cropcap                 = cx18_cropcap,
1170	.vidioc_s_crop                  = cx18_s_crop,
1171	.vidioc_g_crop                  = cx18_g_crop,
1172	.vidioc_g_input                 = cx18_g_input,
1173	.vidioc_s_input                 = cx18_s_input,
1174	.vidioc_g_frequency             = cx18_g_frequency,
1175	.vidioc_s_frequency             = cx18_s_frequency,
1176	.vidioc_s_tuner                 = cx18_s_tuner,
1177	.vidioc_g_tuner                 = cx18_g_tuner,
1178	.vidioc_g_enc_index             = cx18_g_enc_index,
1179	.vidioc_g_std                   = cx18_g_std,
1180	.vidioc_s_std                   = cx18_s_std,
1181	.vidioc_log_status              = cx18_log_status,
1182	.vidioc_enum_fmt_vid_cap        = cx18_enum_fmt_vid_cap,
1183	.vidioc_encoder_cmd             = cx18_encoder_cmd,
1184	.vidioc_try_encoder_cmd         = cx18_try_encoder_cmd,
1185	.vidioc_g_fmt_vid_cap           = cx18_g_fmt_vid_cap,
1186	.vidioc_g_fmt_vbi_cap           = cx18_g_fmt_vbi_cap,
1187	.vidioc_g_fmt_sliced_vbi_cap    = cx18_g_fmt_sliced_vbi_cap,
1188	.vidioc_s_fmt_vid_cap           = cx18_s_fmt_vid_cap,
1189	.vidioc_s_fmt_vbi_cap           = cx18_s_fmt_vbi_cap,
1190	.vidioc_s_fmt_sliced_vbi_cap    = cx18_s_fmt_sliced_vbi_cap,
1191	.vidioc_try_fmt_vid_cap         = cx18_try_fmt_vid_cap,
1192	.vidioc_try_fmt_vbi_cap         = cx18_try_fmt_vbi_cap,
1193	.vidioc_try_fmt_sliced_vbi_cap  = cx18_try_fmt_sliced_vbi_cap,
1194	.vidioc_g_sliced_vbi_cap        = cx18_g_sliced_vbi_cap,
1195	.vidioc_g_chip_ident            = cx18_g_chip_ident,
1196#ifdef CONFIG_VIDEO_ADV_DEBUG
1197	.vidioc_g_register              = cx18_g_register,
1198	.vidioc_s_register              = cx18_s_register,
1199#endif
1200	.vidioc_default                 = cx18_default,
1201	.vidioc_streamon                = cx18_streamon,
1202	.vidioc_streamoff               = cx18_streamoff,
1203	.vidioc_reqbufs                 = cx18_reqbufs,
1204	.vidioc_querybuf                = cx18_querybuf,
1205	.vidioc_qbuf                    = cx18_qbuf,
1206	.vidioc_dqbuf                   = cx18_dqbuf,
1207};
1208
1209void cx18_set_funcs(struct video_device *vdev)
1210{
1211	vdev->ioctl_ops = &cx18_ioctl_ops;
1212}