brintos

brintos / linux-shallow public Read only

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