File Index
Files and directories
Sign in
FILE

pvrusb2-v4l2.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/usb/pvrusb2/pvrusb2-v4l2.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *
   4 *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
   5 *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
   6 */
   7
   8#include <linux/kernel.h>
   9#include <linux/slab.h>
  10#include "pvrusb2-context.h"
  11#include "pvrusb2-hdw.h"
  12#include "pvrusb2.h"
  13#include "pvrusb2-debug.h"
  14#include "pvrusb2-v4l2.h"
  15#include "pvrusb2-ioread.h"
  16#include <linux/videodev2.h>
  17#include <linux/module.h>
  18#include <media/v4l2-dev.h>
  19#include <media/v4l2-device.h>
  20#include <media/v4l2-fh.h>
  21#include <media/v4l2-common.h>
  22#include <media/v4l2-ioctl.h>
  23
  24struct pvr2_v4l2;
  25
  26struct pvr2_v4l2_dev {
  27	struct video_device devbase; /* MUST be first! */
  28	struct pvr2_v4l2 *v4lp;
  29	struct pvr2_context_stream *stream;
  30	/* Information about this device: */
  31	enum pvr2_config config; /* Expected stream format */
  32	int v4l_type; /* V4L defined type for this device node */
  33	enum pvr2_v4l_type minor_type; /* pvr2-understood minor device type */
  34};
  35
  36struct pvr2_v4l2_fh {
  37	struct v4l2_fh fh;
  38	struct pvr2_channel channel;
  39	struct pvr2_v4l2_dev *pdi;
  40	struct pvr2_ioread *rhp;
  41	struct file *file;
  42	wait_queue_head_t wait_data;
  43	int fw_mode_flag;
  44	/* Map contiguous ordinal value to input id */
  45	unsigned char *input_map;
  46	unsigned int input_cnt;
  47};
  48
  49static inline struct pvr2_v4l2_fh *to_pvr2_v4l2_fh(struct file *filp)
  50{
  51	return container_of(file_to_v4l2_fh(filp), struct pvr2_v4l2_fh, fh);
  52}
  53
  54struct pvr2_v4l2 {
  55	struct pvr2_channel channel;
  56
  57	/* streams - Note that these must be separately, individually,
  58	 * allocated pointers.  This is because the v4l core is going to
  59	 * manage their deletion - separately, individually...  */
  60	struct pvr2_v4l2_dev *dev_video;
  61	struct pvr2_v4l2_dev *dev_radio;
  62};
  63
  64static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
  65module_param_array(video_nr, int, NULL, 0444);
  66MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor");
  67static int radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
  68module_param_array(radio_nr, int, NULL, 0444);
  69MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor");
  70static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
  71module_param_array(vbi_nr, int, NULL, 0444);
  72MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
  73
  74#define PVR_FORMAT_PIX  0
  75#define PVR_FORMAT_VBI  1
  76
  77static struct v4l2_format pvr_format [] = {
  78	[PVR_FORMAT_PIX] = {
  79		.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
  80		.fmt    = {
  81			.pix        = {
  82				.width          = 720,
  83				.height         = 576,
  84				.pixelformat    = V4L2_PIX_FMT_MPEG,
  85				.field          = V4L2_FIELD_INTERLACED,
  86				/* FIXME : Don't know what to put here... */
  87				.sizeimage      = 32 * 1024,
  88			}
  89		}
  90	},
  91	[PVR_FORMAT_VBI] = {
  92		.type   = V4L2_BUF_TYPE_VBI_CAPTURE,
  93		.fmt    = {
  94			.vbi        = {
  95				.sampling_rate = 27000000,
  96				.offset = 248,
  97				.samples_per_line = 1443,
  98				.sample_format = V4L2_PIX_FMT_GREY,
  99				.start = { 0, 0 },
 100				.count = { 0, 0 },
 101				.flags = 0,
 102			}
 103		}
 104	}
 105};
 106
 107
 108
 109/*
 110 * This is part of Video 4 Linux API. These procedures handle ioctl() calls.
 111 */
 112static int pvr2_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
 113{
 114	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 115	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 116
 117	strscpy(cap->driver, "pvrusb2", sizeof(cap->driver));
 118	strscpy(cap->bus_info, pvr2_hdw_get_bus_info(hdw),
 119		sizeof(cap->bus_info));
 120	strscpy(cap->card, pvr2_hdw_get_desc(hdw), sizeof(cap->card));
 121	cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER |
 122			    V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
 123			    V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS;
 124	return 0;
 125}
 126
 127static int pvr2_g_std(struct file *file, void *priv, v4l2_std_id *std)
 128{
 129	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 130	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 131	int val = 0;
 132	int ret;
 133
 134	ret = pvr2_ctrl_get_value(
 135			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), &val);
 136	*std = val;
 137	return ret;
 138}
 139
 140static int pvr2_s_std(struct file *file, void *priv, v4l2_std_id std)
 141{
 142	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 143	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 144	int ret;
 145
 146	ret = pvr2_ctrl_set_value(
 147		pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDCUR), std);
 148	pvr2_hdw_commit_ctl(hdw);
 149	return ret;
 150}
 151
 152static int pvr2_querystd(struct file *file, void *priv, v4l2_std_id *std)
 153{
 154	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 155	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 156	int val = 0;
 157	int ret;
 158
 159	ret = pvr2_ctrl_get_value(
 160		pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_STDDETECT), &val);
 161	*std = val;
 162	return ret;
 163}
 164
 165static int pvr2_enum_input(struct file *file, void *priv, struct v4l2_input *vi)
 166{
 167	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 168	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 169	struct pvr2_ctrl *cptr;
 170	struct v4l2_input tmp;
 171	unsigned int cnt;
 172	int val;
 173
 174	cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
 175
 176	memset(&tmp, 0, sizeof(tmp));
 177	tmp.index = vi->index;
 178	if (vi->index >= fh->input_cnt)
 179		return -EINVAL;
 180	val = fh->input_map[vi->index];
 181	switch (val) {
 182	case PVR2_CVAL_INPUT_TV:
 183	case PVR2_CVAL_INPUT_DTV:
 184	case PVR2_CVAL_INPUT_RADIO:
 185		tmp.type = V4L2_INPUT_TYPE_TUNER;
 186		break;
 187	case PVR2_CVAL_INPUT_SVIDEO:
 188	case PVR2_CVAL_INPUT_COMPOSITE:
 189		tmp.type = V4L2_INPUT_TYPE_CAMERA;
 190		break;
 191	default:
 192		return -EINVAL;
 193	}
 194
 195	cnt = 0;
 196	pvr2_ctrl_get_valname(cptr, val,
 197			tmp.name, sizeof(tmp.name) - 1, &cnt);
 198	tmp.name[cnt] = 0;
 199
 200	/* Don't bother with audioset, since this driver currently
 201	   always switches the audio whenever the video is
 202	   switched. */
 203
 204	/* Handling std is a tougher problem.  It doesn't make
 205	   sense in cases where a device might be multi-standard.
 206	   We could just copy out the current value for the
 207	   standard, but it can change over time.  For now just
 208	   leave it zero. */
 209	*vi = tmp;
 210	return 0;
 211}
 212
 213static int pvr2_g_input(struct file *file, void *priv, unsigned int *i)
 214{
 215	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 216	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 217	unsigned int idx;
 218	struct pvr2_ctrl *cptr;
 219	int val;
 220	int ret;
 221
 222	cptr = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
 223	val = 0;
 224	ret = pvr2_ctrl_get_value(cptr, &val);
 225	*i = 0;
 226	for (idx = 0; idx < fh->input_cnt; idx++) {
 227		if (fh->input_map[idx] == val) {
 228			*i = idx;
 229			break;
 230		}
 231	}
 232	return ret;
 233}
 234
 235static int pvr2_s_input(struct file *file, void *priv, unsigned int inp)
 236{
 237	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 238	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 239	int ret;
 240
 241	if (inp >= fh->input_cnt)
 242		return -EINVAL;
 243	ret = pvr2_ctrl_set_value(
 244			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
 245			fh->input_map[inp]);
 246	pvr2_hdw_commit_ctl(hdw);
 247	return ret;
 248}
 249
 250static int pvr2_enumaudio(struct file *file, void *priv, struct v4l2_audio *vin)
 251{
 252	/* pkt: FIXME: We are returning one "fake" input here
 253	   which could very well be called "whatever_we_like".
 254	   This is for apps that want to see an audio input
 255	   just to feel comfortable, as well as to test if
 256	   it can do stereo or sth. There is actually no guarantee
 257	   that the actual audio input cannot change behind the app's
 258	   back, but most applications should not mind that either.
 259
 260	   Hopefully, mplayer people will work with us on this (this
 261	   whole mess is to support mplayer pvr://), or Hans will come
 262	   up with a more standard way to say "we have inputs but we
 263	   don 't want you to change them independent of video" which
 264	   will sort this mess.
 265	 */
 266
 267	if (vin->index > 0)
 268		return -EINVAL;
 269	strscpy(vin->name, "PVRUSB2 Audio", sizeof(vin->name));
 270	vin->capability = V4L2_AUDCAP_STEREO;
 271	return 0;
 272}
 273
 274static int pvr2_g_audio(struct file *file, void *priv, struct v4l2_audio *vin)
 275{
 276	/* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */
 277	vin->index = 0;
 278	strscpy(vin->name, "PVRUSB2 Audio", sizeof(vin->name));
 279	vin->capability = V4L2_AUDCAP_STEREO;
 280	return 0;
 281}
 282
 283static int pvr2_s_audio(struct file *file, void *priv, const struct v4l2_audio *vout)
 284{
 285	if (vout->index)
 286		return -EINVAL;
 287	return 0;
 288}
 289
 290static int pvr2_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
 291{
 292	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 293	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 294
 295	if (vt->index != 0)
 296		return -EINVAL; /* Only answer for the 1st tuner */
 297
 298	pvr2_hdw_execute_tuner_poll(hdw);
 299	return pvr2_hdw_get_tuner_status(hdw, vt);
 300}
 301
 302static int pvr2_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *vt)
 303{
 304	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 305	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 306	int ret;
 307
 308	if (vt->index != 0)
 309		return -EINVAL;
 310
 311	ret = pvr2_ctrl_set_value(
 312			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_AUDIOMODE),
 313			vt->audmode);
 314	pvr2_hdw_commit_ctl(hdw);
 315	return ret;
 316}
 317
 318static int pvr2_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *vf)
 319{
 320	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 321	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 322	unsigned long fv;
 323	struct v4l2_tuner vt;
 324	int cur_input;
 325	struct pvr2_ctrl *ctrlp;
 326	int ret;
 327
 328	ret = pvr2_hdw_get_tuner_status(hdw, &vt);
 329	if (ret != 0)
 330		return ret;
 331	ctrlp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT);
 332	ret = pvr2_ctrl_get_value(ctrlp, &cur_input);
 333	if (ret != 0)
 334		return ret;
 335	if (vf->type == V4L2_TUNER_RADIO) {
 336		if (cur_input != PVR2_CVAL_INPUT_RADIO)
 337			pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_RADIO);
 338	} else {
 339		if (cur_input == PVR2_CVAL_INPUT_RADIO)
 340			pvr2_ctrl_set_value(ctrlp, PVR2_CVAL_INPUT_TV);
 341	}
 342	fv = vf->frequency;
 343	if (vt.capability & V4L2_TUNER_CAP_LOW)
 344		fv = (fv * 125) / 2;
 345	else
 346		fv = fv * 62500;
 347	ret = pvr2_ctrl_set_value(
 348			pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
 349	pvr2_hdw_commit_ctl(hdw);
 350	return ret;
 351}
 352
 353static int pvr2_g_frequency(struct file *file, void *priv, struct v4l2_frequency *vf)
 354{
 355	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 356	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 357	int val = 0;
 358	int cur_input;
 359	struct v4l2_tuner vt;
 360	int ret;
 361
 362	ret = pvr2_hdw_get_tuner_status(hdw, &vt);
 363	if (ret != 0)
 364		return ret;
 365	ret = pvr2_ctrl_get_value(
 366			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_FREQUENCY),
 367			&val);
 368	if (ret != 0)
 369		return ret;
 370	pvr2_ctrl_get_value(
 371			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_INPUT),
 372			&cur_input);
 373	if (cur_input == PVR2_CVAL_INPUT_RADIO)
 374		vf->type = V4L2_TUNER_RADIO;
 375	else
 376		vf->type = V4L2_TUNER_ANALOG_TV;
 377	if (vt.capability & V4L2_TUNER_CAP_LOW)
 378		val = (val * 2) / 125;
 379	else
 380		val /= 62500;
 381	vf->frequency = val;
 382	return 0;
 383}
 384
 385static int pvr2_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *fd)
 386{
 387	/* Only one format is supported: MPEG. */
 388	if (fd->index)
 389		return -EINVAL;
 390
 391	fd->pixelformat = V4L2_PIX_FMT_MPEG;
 392	return 0;
 393}
 394
 395static int pvr2_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
 396{
 397	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 398	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 399	int val;
 400
 401	memcpy(vf, &pvr_format[PVR_FORMAT_PIX], sizeof(struct v4l2_format));
 402	val = 0;
 403	pvr2_ctrl_get_value(
 404			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES),
 405			&val);
 406	vf->fmt.pix.width = val;
 407	val = 0;
 408	pvr2_ctrl_get_value(
 409			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES),
 410			&val);
 411	vf->fmt.pix.height = val;
 412	return 0;
 413}
 414
 415static int pvr2_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
 416{
 417	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 418	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 419	int lmin, lmax, ldef;
 420	struct pvr2_ctrl *hcp, *vcp;
 421	int h = vf->fmt.pix.height;
 422	int w = vf->fmt.pix.width;
 423
 424	hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
 425	vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
 426
 427	lmin = pvr2_ctrl_get_min(hcp);
 428	lmax = pvr2_ctrl_get_max(hcp);
 429	pvr2_ctrl_get_def(hcp, &ldef);
 430	if (w == -1)
 431		w = ldef;
 432	else if (w < lmin)
 433		w = lmin;
 434	else if (w > lmax)
 435		w = lmax;
 436	lmin = pvr2_ctrl_get_min(vcp);
 437	lmax = pvr2_ctrl_get_max(vcp);
 438	pvr2_ctrl_get_def(vcp, &ldef);
 439	if (h == -1)
 440		h = ldef;
 441	else if (h < lmin)
 442		h = lmin;
 443	else if (h > lmax)
 444		h = lmax;
 445
 446	memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
 447			sizeof(struct v4l2_format));
 448	vf->fmt.pix.width = w;
 449	vf->fmt.pix.height = h;
 450	return 0;
 451}
 452
 453static int pvr2_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *vf)
 454{
 455	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 456	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 457	struct pvr2_ctrl *hcp, *vcp;
 458	int ret = pvr2_try_fmt_vid_cap(file, fh, vf);
 459
 460	if (ret)
 461		return ret;
 462	hcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_HRES);
 463	vcp = pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES);
 464	pvr2_ctrl_set_value(hcp, vf->fmt.pix.width);
 465	pvr2_ctrl_set_value(vcp, vf->fmt.pix.height);
 466	pvr2_hdw_commit_ctl(hdw);
 467	return 0;
 468}
 469
 470static int pvr2_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 471{
 472	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 473	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 474	struct pvr2_v4l2_dev *pdi = fh->pdi;
 475	int ret;
 476
 477	if (!fh->pdi->stream) {
 478		/* No stream defined for this node.  This means
 479		   that we're not currently allowed to stream from
 480		   this node. */
 481		return -EPERM;
 482	}
 483	ret = pvr2_hdw_set_stream_type(hdw, pdi->config);
 484	if (ret < 0)
 485		return ret;
 486	return pvr2_hdw_set_streaming(hdw, !0);
 487}
 488
 489static int pvr2_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
 490{
 491	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 492	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 493
 494	if (!fh->pdi->stream) {
 495		/* No stream defined for this node.  This means
 496		   that we're not currently allowed to stream from
 497		   this node. */
 498		return -EPERM;
 499	}
 500	return pvr2_hdw_set_streaming(hdw, 0);
 501}
 502
 503static int pvr2_query_ext_ctrl(struct file *file, void *priv,
 504			       struct v4l2_query_ext_ctrl *vc)
 505{
 506	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 507	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 508	struct pvr2_ctrl *cptr;
 509	int val;
 510
 511	if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
 512		cptr = pvr2_hdw_get_ctrl_nextv4l(
 513				hdw, (vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
 514		if (cptr)
 515			vc->id = pvr2_ctrl_get_v4lid(cptr);
 516	} else {
 517		cptr = pvr2_hdw_get_ctrl_v4l(hdw, vc->id);
 518	}
 519	if (!cptr) {
 520		pvr2_trace(PVR2_TRACE_V4LIOCTL,
 521				"QUERYCTRL id=0x%x not implemented here",
 522				vc->id);
 523		return -EINVAL;
 524	}
 525
 526	pvr2_trace(PVR2_TRACE_V4LIOCTL,
 527			"QUERYEXTCTRL id=0x%x mapping name=%s (%s)",
 528			vc->id, pvr2_ctrl_get_name(cptr),
 529			pvr2_ctrl_get_desc(cptr));
 530	strscpy(vc->name, pvr2_ctrl_get_desc(cptr), sizeof(vc->name));
 531	vc->flags = pvr2_ctrl_get_v4lflags(cptr);
 532	pvr2_ctrl_get_def(cptr, &val);
 533	vc->default_value = val;
 534	vc->nr_of_dims = 0;
 535	vc->elems = 1;
 536	vc->elem_size = 4;
 537	switch (pvr2_ctrl_get_type(cptr)) {
 538	case pvr2_ctl_enum:
 539		vc->type = V4L2_CTRL_TYPE_MENU;
 540		vc->minimum = 0;
 541		vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
 542		vc->step = 1;
 543		break;
 544	case pvr2_ctl_bool:
 545		vc->type = V4L2_CTRL_TYPE_BOOLEAN;
 546		vc->minimum = 0;
 547		vc->maximum = 1;
 548		vc->step = 1;
 549		break;
 550	case pvr2_ctl_int:
 551		vc->type = V4L2_CTRL_TYPE_INTEGER;
 552		vc->minimum = pvr2_ctrl_get_min(cptr);
 553		vc->maximum = pvr2_ctrl_get_max(cptr);
 554		vc->step = 1;
 555		break;
 556	default:
 557		pvr2_trace(PVR2_TRACE_V4LIOCTL,
 558				"QUERYEXTCTRL id=0x%x name=%s not mappable",
 559				vc->id, pvr2_ctrl_get_name(cptr));
 560		return -EINVAL;
 561	}
 562	return 0;
 563}
 564
 565static int pvr2_querymenu(struct file *file, void *priv, struct v4l2_querymenu *vm)
 566{
 567	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 568	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 569	unsigned int cnt = 0;
 570	int ret;
 571
 572	ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw, vm->id),
 573			vm->index,
 574			vm->name, sizeof(vm->name) - 1,
 575			&cnt);
 576	vm->name[cnt] = 0;
 577	return ret;
 578}
 579
 580static int pvr2_g_ext_ctrls(struct file *file, void *priv,
 581					struct v4l2_ext_controls *ctls)
 582{
 583	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 584	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 585	struct v4l2_ext_control *ctrl;
 586	struct pvr2_ctrl *cptr;
 587	unsigned int idx;
 588	int val;
 589	int ret;
 590
 591	ret = 0;
 592	for (idx = 0; idx < ctls->count; idx++) {
 593		ctrl = ctls->controls + idx;
 594		cptr = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id);
 595		if (cptr) {
 596			if (ctls->which == V4L2_CTRL_WHICH_DEF_VAL)
 597				pvr2_ctrl_get_def(cptr, &val);
 598			else
 599				ret = pvr2_ctrl_get_value(cptr, &val);
 600		} else
 601			ret = -EINVAL;
 602
 603		if (ret) {
 604			ctls->error_idx = idx;
 605			return ret;
 606		}
 607		/* Ensure that if read as a 64 bit value, the user
 608		   will still get a hopefully sane value */
 609		ctrl->value64 = 0;
 610		ctrl->value = val;
 611	}
 612	return 0;
 613}
 614
 615static int pvr2_s_ext_ctrls(struct file *file, void *priv,
 616		struct v4l2_ext_controls *ctls)
 617{
 618	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 619	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 620	struct v4l2_ext_control *ctrl;
 621	unsigned int idx;
 622	int ret;
 623
 624	ret = 0;
 625	for (idx = 0; idx < ctls->count; idx++) {
 626		ctrl = ctls->controls + idx;
 627		ret = pvr2_ctrl_set_value(
 628				pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id),
 629				ctrl->value);
 630		if (ret) {
 631			ctls->error_idx = idx;
 632			goto commit;
 633		}
 634	}
 635commit:
 636	pvr2_hdw_commit_ctl(hdw);
 637	return ret;
 638}
 639
 640static int pvr2_try_ext_ctrls(struct file *file, void *priv,
 641		struct v4l2_ext_controls *ctls)
 642{
 643	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 644	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 645	struct v4l2_ext_control *ctrl;
 646	struct pvr2_ctrl *pctl;
 647	unsigned int idx;
 648
 649	/* For the moment just validate that the requested control
 650	   actually exists. */
 651	for (idx = 0; idx < ctls->count; idx++) {
 652		ctrl = ctls->controls + idx;
 653		pctl = pvr2_hdw_get_ctrl_v4l(hdw, ctrl->id);
 654		if (!pctl) {
 655			ctls->error_idx = idx;
 656			return -EINVAL;
 657		}
 658	}
 659	return 0;
 660}
 661
 662static int pvr2_g_pixelaspect(struct file *file, void *priv,
 663			      int type, struct v4l2_fract *f)
 664{
 665	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 666	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 667	struct v4l2_cropcap cap = { .type = type };
 668	int ret;
 669
 670	if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 671		return -EINVAL;
 672	ret = pvr2_hdw_get_cropcap(hdw, &cap);
 673	if (!ret)
 674		*f = cap.pixelaspect;
 675	return ret;
 676}
 677
 678static int pvr2_g_selection(struct file *file, void *priv,
 679			    struct v4l2_selection *sel)
 680{
 681	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 682	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 683	struct v4l2_cropcap cap;
 684	int val = 0;
 685	int ret;
 686
 687	if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 688		return -EINVAL;
 689
 690	cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 691
 692	switch (sel->target) {
 693	case V4L2_SEL_TGT_CROP:
 694		ret = pvr2_ctrl_get_value(
 695			  pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val);
 696		if (ret != 0)
 697			return -EINVAL;
 698		sel->r.left = val;
 699		ret = pvr2_ctrl_get_value(
 700			  pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val);
 701		if (ret != 0)
 702			return -EINVAL;
 703		sel->r.top = val;
 704		ret = pvr2_ctrl_get_value(
 705			  pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val);
 706		if (ret != 0)
 707			return -EINVAL;
 708		sel->r.width = val;
 709		ret = pvr2_ctrl_get_value(
 710			  pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val);
 711		if (ret != 0)
 712			return -EINVAL;
 713		sel->r.height = val;
 714		break;
 715	case V4L2_SEL_TGT_CROP_DEFAULT:
 716		ret = pvr2_hdw_get_cropcap(hdw, &cap);
 717		sel->r = cap.defrect;
 718		break;
 719	case V4L2_SEL_TGT_CROP_BOUNDS:
 720		ret = pvr2_hdw_get_cropcap(hdw, &cap);
 721		sel->r = cap.bounds;
 722		break;
 723	default:
 724		return -EINVAL;
 725	}
 726	return ret;
 727}
 728
 729static int pvr2_s_selection(struct file *file, void *priv,
 730			    struct v4l2_selection *sel)
 731{
 732	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 733	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 734	int ret;
 735
 736	if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
 737	    sel->target != V4L2_SEL_TGT_CROP)
 738		return -EINVAL;
 739	ret = pvr2_ctrl_set_value(
 740			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
 741			sel->r.left);
 742	if (ret != 0)
 743		goto commit;
 744	ret = pvr2_ctrl_set_value(
 745			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT),
 746			sel->r.top);
 747	if (ret != 0)
 748		goto commit;
 749	ret = pvr2_ctrl_set_value(
 750			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW),
 751			sel->r.width);
 752	if (ret != 0)
 753		goto commit;
 754	ret = pvr2_ctrl_set_value(
 755			pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH),
 756			sel->r.height);
 757commit:
 758	pvr2_hdw_commit_ctl(hdw);
 759	return ret;
 760}
 761
 762static int pvr2_log_status(struct file *file, void *priv)
 763{
 764	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
 765	struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 766
 767	pvr2_hdw_trigger_module_log(hdw);
 768	return 0;
 769}
 770
 771static const struct v4l2_ioctl_ops pvr2_ioctl_ops = {
 772	.vidioc_querycap		    = pvr2_querycap,
 773	.vidioc_s_audio			    = pvr2_s_audio,
 774	.vidioc_g_audio			    = pvr2_g_audio,
 775	.vidioc_enumaudio		    = pvr2_enumaudio,
 776	.vidioc_enum_input		    = pvr2_enum_input,
 777	.vidioc_g_pixelaspect		    = pvr2_g_pixelaspect,
 778	.vidioc_s_selection		    = pvr2_s_selection,
 779	.vidioc_g_selection		    = pvr2_g_selection,
 780	.vidioc_g_input			    = pvr2_g_input,
 781	.vidioc_s_input			    = pvr2_s_input,
 782	.vidioc_g_frequency		    = pvr2_g_frequency,
 783	.vidioc_s_frequency		    = pvr2_s_frequency,
 784	.vidioc_s_tuner			    = pvr2_s_tuner,
 785	.vidioc_g_tuner			    = pvr2_g_tuner,
 786	.vidioc_g_std			    = pvr2_g_std,
 787	.vidioc_s_std			    = pvr2_s_std,
 788	.vidioc_querystd		    = pvr2_querystd,
 789	.vidioc_log_status		    = pvr2_log_status,
 790	.vidioc_enum_fmt_vid_cap	    = pvr2_enum_fmt_vid_cap,
 791	.vidioc_g_fmt_vid_cap		    = pvr2_g_fmt_vid_cap,
 792	.vidioc_s_fmt_vid_cap		    = pvr2_s_fmt_vid_cap,
 793	.vidioc_try_fmt_vid_cap		    = pvr2_try_fmt_vid_cap,
 794	.vidioc_streamon		    = pvr2_streamon,
 795	.vidioc_streamoff		    = pvr2_streamoff,
 796	.vidioc_query_ext_ctrl		    = pvr2_query_ext_ctrl,
 797	.vidioc_querymenu		    = pvr2_querymenu,
 798	.vidioc_g_ext_ctrls		    = pvr2_g_ext_ctrls,
 799	.vidioc_s_ext_ctrls		    = pvr2_s_ext_ctrls,
 800	.vidioc_try_ext_ctrls		    = pvr2_try_ext_ctrls,
 801};
 802
 803static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
 804{
 805	struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
 806	enum pvr2_config cfg = dip->config;
 807	char msg[80];
 808	unsigned int mcnt;
 809
 810	/* Construct the unregistration message *before* we actually
 811	   perform the unregistration step.  By doing it this way we don't
 812	   have to worry about potentially touching deleted resources. */
 813	mcnt = scnprintf(msg, sizeof(msg) - 1,
 814			 "pvrusb2: unregistered device %s [%s]",
 815			 video_device_node_name(&dip->devbase),
 816			 pvr2_config_get_name(cfg));
 817	msg[mcnt] = 0;
 818
 819	pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
 820
 821	/* Paranoia */
 822	dip->v4lp = NULL;
 823	dip->stream = NULL;
 824
 825	/* Actual deallocation happens later when all internal references
 826	   are gone. */
 827	video_unregister_device(&dip->devbase);
 828
 829	pr_info("%s\n", msg);
 830
 831}
 832
 833
 834static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
 835{
 836	if (!dip) return;
 837	if (!dip->devbase.v4l2_dev->dev) return;
 838	dip->devbase.v4l2_dev->dev = NULL;
 839	device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
 840}
 841
 842
 843static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
 844{
 845	if (vp->dev_video) {
 846		pvr2_v4l2_dev_destroy(vp->dev_video);
 847		vp->dev_video = NULL;
 848	}
 849	if (vp->dev_radio) {
 850		pvr2_v4l2_dev_destroy(vp->dev_radio);
 851		vp->dev_radio = NULL;
 852	}
 853
 854	pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
 855	pvr2_channel_done(&vp->channel);
 856	kfree(vp);
 857}
 858
 859
 860static void pvr2_video_device_release(struct video_device *vdev)
 861{
 862	struct pvr2_v4l2_dev *dev;
 863	dev = container_of(vdev,struct pvr2_v4l2_dev,devbase);
 864	kfree(dev);
 865}
 866
 867
 868static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
 869{
 870	struct pvr2_v4l2 *vp;
 871	vp = container_of(chp,struct pvr2_v4l2,channel);
 872	if (!vp->channel.mc_head->disconnect_flag) return;
 873	pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
 874	pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
 875	if (!list_empty(&vp->dev_video->devbase.fh_list) ||
 876	    (vp->dev_radio &&
 877	     !list_empty(&vp->dev_radio->devbase.fh_list))) {
 878		pvr2_trace(PVR2_TRACE_STRUCT,
 879			   "pvr2_v4l2 internal_check exit-empty id=%p", vp);
 880		return;
 881	}
 882	pvr2_v4l2_destroy_no_lock(vp);
 883}
 884
 885
 886static int pvr2_v4l2_release(struct file *file)
 887{
 888	struct pvr2_v4l2_fh *fhp = to_pvr2_v4l2_fh(file);
 889	struct pvr2_v4l2 *vp = fhp->pdi->v4lp;
 890	struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw;
 891
 892	pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
 893
 894	if (fhp->rhp) {
 895		struct pvr2_stream *sp;
 896		pvr2_hdw_set_streaming(hdw,0);
 897		sp = pvr2_ioread_get_stream(fhp->rhp);
 898		if (sp) pvr2_stream_set_callback(sp,NULL,NULL);
 899		pvr2_ioread_destroy(fhp->rhp);
 900		fhp->rhp = NULL;
 901	}
 902
 903	v4l2_fh_del(&fhp->fh, file);
 904	v4l2_fh_exit(&fhp->fh);
 905
 906	pvr2_channel_done(&fhp->channel);
 907	pvr2_trace(PVR2_TRACE_STRUCT,
 908		   "Destroying pvr_v4l2_fh id=%p",fhp);
 909	if (fhp->input_map) {
 910		kfree(fhp->input_map);
 911		fhp->input_map = NULL;
 912	}
 913	kfree(fhp);
 914	if (vp->channel.mc_head->disconnect_flag &&
 915	    list_empty(&vp->dev_video->devbase.fh_list) &&
 916	    (!vp->dev_radio ||
 917	     list_empty(&vp->dev_radio->devbase.fh_list))) {
 918		pvr2_v4l2_destroy_no_lock(vp);
 919	}
 920	return 0;
 921}
 922
 923
 924static int pvr2_v4l2_open(struct file *file)
 925{
 926	struct pvr2_v4l2_dev *dip; /* Our own context pointer */
 927	struct pvr2_v4l2_fh *fhp;
 928	struct pvr2_v4l2 *vp;
 929	struct pvr2_hdw *hdw;
 930	unsigned int input_mask = 0;
 931	unsigned int input_cnt,idx;
 932	int ret = 0;
 933
 934	dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
 935
 936	vp = dip->v4lp;
 937	hdw = vp->channel.hdw;
 938
 939	pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
 940
 941	if (!pvr2_hdw_dev_ok(hdw)) {
 942		pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
 943			   "pvr2_v4l2_open: hardware not ready");
 944		return -EIO;
 945	}
 946
 947	fhp = kzalloc(sizeof(*fhp),GFP_KERNEL);
 948	if (!fhp) {
 949		return -ENOMEM;
 950	}
 951
 952	v4l2_fh_init(&fhp->fh, &dip->devbase);
 953	init_waitqueue_head(&fhp->wait_data);
 954	fhp->pdi = dip;
 955
 956	pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
 957	pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
 958
 959	if (dip->v4l_type == VFL_TYPE_RADIO) {
 960		/* Opening device as a radio, legal input selection subset
 961		   is just the radio. */
 962		input_mask = (1 << PVR2_CVAL_INPUT_RADIO);
 963	} else {
 964		/* Opening the main V4L device, legal input selection
 965		   subset includes all analog inputs. */
 966		input_mask = ((1 << PVR2_CVAL_INPUT_RADIO) |
 967			      (1 << PVR2_CVAL_INPUT_TV) |
 968			      (1 << PVR2_CVAL_INPUT_COMPOSITE) |
 969			      (1 << PVR2_CVAL_INPUT_SVIDEO));
 970	}
 971	ret = pvr2_channel_limit_inputs(&fhp->channel,input_mask);
 972	if (ret) {
 973		pvr2_channel_done(&fhp->channel);
 974		pvr2_trace(PVR2_TRACE_STRUCT,
 975			   "Destroying pvr_v4l2_fh id=%p (input mask error)",
 976			   fhp);
 977		v4l2_fh_exit(&fhp->fh);
 978		kfree(fhp);
 979		return ret;
 980	}
 981
 982	input_mask &= pvr2_hdw_get_input_available(hdw);
 983	input_cnt = 0;
 984	for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
 985		if (input_mask & (1UL << idx)) input_cnt++;
 986	}
 987	fhp->input_cnt = input_cnt;
 988	fhp->input_map = kzalloc(input_cnt,GFP_KERNEL);
 989	if (!fhp->input_map) {
 990		pvr2_channel_done(&fhp->channel);
 991		pvr2_trace(PVR2_TRACE_STRUCT,
 992			   "Destroying pvr_v4l2_fh id=%p (input map failure)",
 993			   fhp);
 994		v4l2_fh_exit(&fhp->fh);
 995		kfree(fhp);
 996		return -ENOMEM;
 997	}
 998	input_cnt = 0;
 999	for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1000		if (!(input_mask & (1UL << idx))) continue;
1001		fhp->input_map[input_cnt++] = idx;
1002	}
1003
1004	fhp->file = file;
1005
1006	fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
1007	v4l2_fh_add(&fhp->fh, file);
1008
1009	return 0;
1010}
1011
1012
1013static void pvr2_v4l2_notify(void *ptr)
1014{
1015	struct pvr2_v4l2_fh *fhp = ptr;
1016
1017	wake_up(&fhp->wait_data);
1018}
1019
1020static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
1021{
1022	int ret;
1023	struct pvr2_stream *sp;
1024	struct pvr2_hdw *hdw;
1025	if (fh->rhp) return 0;
1026
1027	if (!fh->pdi->stream) {
1028		/* No stream defined for this node.  This means that we're
1029		   not currently allowed to stream from this node. */
1030		return -EPERM;
1031	}
1032
1033	/* First read() attempt.  Try to claim the stream and start
1034	   it... */
1035	if ((ret = pvr2_channel_claim_stream(&fh->channel,
1036					     fh->pdi->stream)) != 0) {
1037		/* Someone else must already have it */
1038		return ret;
1039	}
1040
1041	fh->rhp = pvr2_channel_create_mpeg_stream(fh->pdi->stream);
1042	if (!fh->rhp) {
1043		pvr2_channel_claim_stream(&fh->channel,NULL);
1044		return -ENOMEM;
1045	}
1046
1047	hdw = fh->channel.mc_head->hdw;
1048	sp = fh->pdi->stream->stream;
1049	pvr2_stream_set_callback(sp, pvr2_v4l2_notify, fh);
1050	pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
1051	if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
1052	return pvr2_ioread_set_enabled(fh->rhp,!0);
1053}
1054
1055
1056static ssize_t pvr2_v4l2_read(struct file *file,
1057			      char __user *buff, size_t count, loff_t *ppos)
1058{
1059	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
1060	int ret;
1061
1062	if (fh->fw_mode_flag) {
1063		struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
1064		char *tbuf;
1065		int c1,c2;
1066		int tcnt = 0;
1067		unsigned int offs = *ppos;
1068
1069		tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
1070		if (!tbuf) return -ENOMEM;
1071
1072		while (count) {
1073			c1 = count;
1074			if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
1075			c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
1076			if (c2 < 0) {
1077				tcnt = c2;
1078				break;
1079			}
1080			if (!c2) break;
1081			if (copy_to_user(buff,tbuf,c2)) {
1082				tcnt = -EFAULT;
1083				break;
1084			}
1085			offs += c2;
1086			tcnt += c2;
1087			buff += c2;
1088			count -= c2;
1089			*ppos += c2;
1090		}
1091		kfree(tbuf);
1092		return tcnt;
1093	}
1094
1095	if (!fh->rhp) {
1096		ret = pvr2_v4l2_iosetup(fh);
1097		if (ret) {
1098			return ret;
1099		}
1100	}
1101
1102	for (;;) {
1103		ret = pvr2_ioread_read(fh->rhp,buff,count);
1104		if (ret >= 0) break;
1105		if (ret != -EAGAIN) break;
1106		if (file->f_flags & O_NONBLOCK) break;
1107		/* Doing blocking I/O.  Wait here. */
1108		ret = wait_event_interruptible(
1109			fh->wait_data,
1110			pvr2_ioread_avail(fh->rhp) >= 0);
1111		if (ret < 0) break;
1112	}
1113
1114	return ret;
1115}
1116
1117
1118static __poll_t pvr2_v4l2_poll(struct file *file, poll_table *wait)
1119{
1120	__poll_t mask = 0;
1121	struct pvr2_v4l2_fh *fh = to_pvr2_v4l2_fh(file);
1122	int ret;
1123
1124	if (fh->fw_mode_flag) {
1125		mask |= EPOLLIN | EPOLLRDNORM;
1126		return mask;
1127	}
1128
1129	if (!fh->rhp) {
1130		ret = pvr2_v4l2_iosetup(fh);
1131		if (ret) return EPOLLERR;
1132	}
1133
1134	poll_wait(file,&fh->wait_data,wait);
1135
1136	if (pvr2_ioread_avail(fh->rhp) >= 0) {
1137		mask |= EPOLLIN | EPOLLRDNORM;
1138	}
1139
1140	return mask;
1141}
1142
1143
1144static const struct v4l2_file_operations vdev_fops = {
1145	.owner      = THIS_MODULE,
1146	.open       = pvr2_v4l2_open,
1147	.release    = pvr2_v4l2_release,
1148	.read       = pvr2_v4l2_read,
1149	.unlocked_ioctl = video_ioctl2,
1150	.poll       = pvr2_v4l2_poll,
1151};
1152
1153
1154static const struct video_device vdev_template = {
1155	.fops       = &vdev_fops,
1156};
1157
1158
1159static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1160			       struct pvr2_v4l2 *vp,
1161			       int v4l_type)
1162{
1163	int mindevnum;
1164	int unit_number;
1165	struct pvr2_hdw *hdw;
1166	int *nr_ptr = NULL;
1167	u32 caps = V4L2_CAP_TUNER | V4L2_CAP_READWRITE;
1168
1169	dip->v4lp = vp;
1170
1171	hdw = vp->channel.mc_head->hdw;
1172	dip->v4l_type = v4l_type;
1173	switch (v4l_type) {
1174	case VFL_TYPE_VIDEO:
1175		dip->stream = &vp->channel.mc_head->video_stream;
1176		dip->config = pvr2_config_mpeg;
1177		dip->minor_type = pvr2_v4l_type_video;
1178		nr_ptr = video_nr;
1179		caps |= V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_AUDIO;
1180		break;
1181	case VFL_TYPE_VBI:
1182		dip->config = pvr2_config_vbi;
1183		dip->minor_type = pvr2_v4l_type_vbi;
1184		nr_ptr = vbi_nr;
1185		caps |= V4L2_CAP_VBI_CAPTURE;
1186		break;
1187	case VFL_TYPE_RADIO:
1188		dip->stream = &vp->channel.mc_head->video_stream;
1189		dip->config = pvr2_config_mpeg;
1190		dip->minor_type = pvr2_v4l_type_radio;
1191		nr_ptr = radio_nr;
1192		caps |= V4L2_CAP_RADIO;
1193		break;
1194	default:
1195		/* Bail out (this should be impossible) */
1196		pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev due to unrecognized config\n");
1197		return;
1198	}
1199
1200	dip->devbase = vdev_template;
1201	dip->devbase.release = pvr2_video_device_release;
1202	dip->devbase.ioctl_ops = &pvr2_ioctl_ops;
1203	dip->devbase.device_caps = caps;
1204	{
1205		int val;
1206		pvr2_ctrl_get_value(
1207			pvr2_hdw_get_ctrl_by_id(hdw,
1208						PVR2_CID_STDAVAIL), &val);
1209		dip->devbase.tvnorms = (v4l2_std_id)val;
1210	}
1211
1212	mindevnum = -1;
1213	unit_number = pvr2_hdw_get_unit_number(hdw);
1214	if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
1215		mindevnum = nr_ptr[unit_number];
1216	}
1217	pvr2_hdw_set_v4l2_dev(hdw, &dip->devbase);
1218	if ((video_register_device(&dip->devbase,
1219				   dip->v4l_type, mindevnum) < 0) &&
1220	    (video_register_device(&dip->devbase,
1221				   dip->v4l_type, -1) < 0)) {
1222		pr_err(KBUILD_MODNAME
1223			": Failed to register pvrusb2 v4l device\n");
1224	}
1225
1226	pr_info("pvrusb2: registered device %s [%s]\n",
1227	       video_device_node_name(&dip->devbase),
1228	       pvr2_config_get_name(dip->config));
1229
1230	pvr2_hdw_v4l_store_minor_number(hdw,
1231					dip->minor_type,dip->devbase.minor);
1232}
1233
1234
1235struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1236{
1237	struct pvr2_v4l2 *vp;
1238
1239	vp = kzalloc(sizeof(*vp),GFP_KERNEL);
1240	if (!vp) return vp;
1241	pvr2_channel_init(&vp->channel,mnp);
1242	pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1243
1244	vp->channel.check_func = pvr2_v4l2_internal_check;
1245
1246	/* register streams */
1247	vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);
1248	if (!vp->dev_video) goto fail;
1249	pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_VIDEO);
1250	if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) &
1251	    (1 << PVR2_CVAL_INPUT_RADIO)) {
1252		vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);
1253		if (!vp->dev_radio) goto fail;
1254		pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO);
1255	}
1256
1257	return vp;
1258 fail:
1259	pvr2_trace(PVR2_TRACE_STRUCT,"Failure creating pvr2_v4l2 id=%p",vp);
1260	pvr2_v4l2_destroy_no_lock(vp);
1261	return NULL;
1262}
~/ Read-only file preview.