Linux Audio

Check our new training course

Linux BSP development engineering services

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