Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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