Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b1e2e4d authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

[media] v4l2-ioctl.c: use the new table for std/tuner/modulator ioctls

parent e325b244
Loading
Loading
Loading
Loading
+220 −210
Original line number Original line Diff line number Diff line
@@ -364,6 +364,68 @@ static void v4l_print_buftype(const void *arg, bool write_only)
	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
	pr_cont("type=%s\n", prt_names(*(u32 *)arg, v4l2_type_names));
}
}


static void v4l_print_modulator(const void *arg, bool write_only)
{
	const struct v4l2_modulator *p = arg;

	if (write_only)
		pr_cont("index=%u, txsubchans=0x%x", p->index, p->txsubchans);
	else
		pr_cont("index=%u, name=%s, capability=0x%x, "
			"rangelow=%u, rangehigh=%u, txsubchans=0x%x\n",
			p->index, p->name, p->capability,
			p->rangelow, p->rangehigh, p->txsubchans);
}

static void v4l_print_tuner(const void *arg, bool write_only)
{
	const struct v4l2_tuner *p = arg;

	if (write_only)
		pr_cont("index=%u, audmode=%u\n", p->index, p->audmode);
	else
		pr_cont("index=%u, name=%s, type=%u, capability=0x%x, "
			"rangelow=%u, rangehigh=%u, signal=%u, afc=%d, "
			"rxsubchans=0x%x, audmode=%u\n",
			p->index, p->name, p->type,
			p->capability, p->rangelow,
			p->rangehigh, p->signal, p->afc,
			p->rxsubchans, p->audmode);
}

static void v4l_print_frequency(const void *arg, bool write_only)
{
	const struct v4l2_frequency *p = arg;

	pr_cont("tuner=%u, type=%u, frequency=%u\n",
				p->tuner, p->type, p->frequency);
}

static void v4l_print_standard(const void *arg, bool write_only)
{
	const struct v4l2_standard *p = arg;

	pr_cont("index=%u, id=0x%Lx, name=%s, fps=%u/%u, "
		"framelines=%u\n", p->index,
		(unsigned long long)p->id, p->name,
		p->frameperiod.numerator,
		p->frameperiod.denominator,
		p->framelines);
}

static void v4l_print_std(const void *arg, bool write_only)
{
	pr_cont("std=0x%08Lx\n", *(const long long unsigned *)arg);
}

static void v4l_print_hw_freq_seek(const void *arg, bool write_only)
{
	const struct v4l2_hw_freq_seek *p = arg;

	pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n",
		p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing);
}

static void v4l_print_u32(const void *arg, bool write_only)
static void v4l_print_u32(const void *arg, bool write_only)
{
{
	pr_cont("value=%u\n", *(const u32 *)arg);
	pr_cont("value=%u\n", *(const u32 *)arg);
@@ -861,6 +923,153 @@ static int v4l_streamoff(const struct v4l2_ioctl_ops *ops,
	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
	return ops->vidioc_streamoff(file, fh, *(unsigned int *)arg);
}
}


static int v4l_g_tuner(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct video_device *vfd = video_devdata(file);
	struct v4l2_tuner *p = arg;

	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
	return ops->vidioc_g_tuner(file, fh, p);
}

static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct video_device *vfd = video_devdata(file);
	struct v4l2_tuner *p = arg;

	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
	return ops->vidioc_s_tuner(file, fh, p);
}

static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct video_device *vfd = video_devdata(file);
	struct v4l2_frequency *p = arg;

	p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
	return ops->vidioc_g_frequency(file, fh, p);
}

static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct video_device *vfd = video_devdata(file);
	struct v4l2_frequency *p = arg;
	enum v4l2_tuner_type type;

	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
	if (p->type != type)
		return -EINVAL;
	return ops->vidioc_s_frequency(file, fh, p);
}

static int v4l_enumstd(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct video_device *vfd = video_devdata(file);
	struct v4l2_standard *p = arg;
	v4l2_std_id id = vfd->tvnorms, curr_id = 0;
	unsigned int index = p->index, i, j = 0;
	const char *descr = "";

	/* Return norm array in a canonical way */
	for (i = 0; i <= index && id; i++) {
		/* last std value in the standards array is 0, so this
		   while always ends there since (id & 0) == 0. */
		while ((id & standards[j].std) != standards[j].std)
			j++;
		curr_id = standards[j].std;
		descr = standards[j].descr;
		j++;
		if (curr_id == 0)
			break;
		if (curr_id != V4L2_STD_PAL &&
				curr_id != V4L2_STD_SECAM &&
				curr_id != V4L2_STD_NTSC)
			id &= ~curr_id;
	}
	if (i <= index)
		return -EINVAL;

	v4l2_video_std_construct(p, curr_id, descr);
	return 0;
}

static int v4l_g_std(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct video_device *vfd = video_devdata(file);
	v4l2_std_id *id = arg;

	/* Calls the specific handler */
	if (ops->vidioc_g_std)
		return ops->vidioc_g_std(file, fh, arg);
	if (vfd->current_norm) {
		*id = vfd->current_norm;
		return 0;
	}
	return -ENOTTY;
}

static int v4l_s_std(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct video_device *vfd = video_devdata(file);
	v4l2_std_id *id = arg, norm;
	int ret;

	norm = (*id) & vfd->tvnorms;
	if (vfd->tvnorms && !norm)	/* Check if std is supported */
		return -EINVAL;

	/* Calls the specific handler */
	ret = ops->vidioc_s_std(file, fh, &norm);

	/* Updates standard information */
	if (ret >= 0)
		vfd->current_norm = norm;
	return ret;
}

static int v4l_querystd(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct video_device *vfd = video_devdata(file);
	v4l2_std_id *p = arg;

	/*
	 * If nothing detected, it should return all supported
	 * standard.
	 * Drivers just need to mask the std argument, in order
	 * to remove the standards that don't apply from the mask.
	 * This means that tuners, audio and video decoders can join
	 * their efforts to improve the standards detection.
	 */
	*p = vfd->tvnorms;
	return ops->vidioc_querystd(file, fh, arg);
}

static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
				struct file *file, void *fh, void *arg)
{
	struct video_device *vfd = video_devdata(file);
	struct v4l2_hw_freq_seek *p = arg;
	enum v4l2_tuner_type type;

	type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
	if (p->type != type)
		return -EINVAL;
	return ops->vidioc_s_hw_freq_seek(file, fh, p);
}

struct v4l2_ioctl_info {
struct v4l2_ioctl_info {
	unsigned int ioctl;
	unsigned int ioctl;
	u32 flags;
	u32 flags;
@@ -927,14 +1136,14 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
	IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO),
	IOCTL_INFO_FNC(VIDIOC_STREAMOFF, v4l_streamoff, v4l_print_buftype, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_G_PARM, INFO_FL_CLEAR(v4l2_streamparm, type)),
	IOCTL_INFO(VIDIOC_G_PARM, INFO_FL_CLEAR(v4l2_streamparm, type)),
	IOCTL_INFO(VIDIOC_S_PARM, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_S_PARM, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_G_STD, 0),
	IOCTL_INFO_FNC(VIDIOC_G_STD, v4l_g_std, v4l_print_std, 0),
	IOCTL_INFO(VIDIOC_S_STD, INFO_FL_PRIO),
	IOCTL_INFO_FNC(VIDIOC_S_STD, v4l_s_std, v4l_print_std, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_ENUMSTD, INFO_FL_CLEAR(v4l2_standard, index)),
	IOCTL_INFO_FNC(VIDIOC_ENUMSTD, v4l_enumstd, v4l_print_standard, INFO_FL_CLEAR(v4l2_standard, index)),
	IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
	IOCTL_INFO_FNC(VIDIOC_ENUMINPUT, v4l_enuminput, v4l_print_enuminput, INFO_FL_CLEAR(v4l2_input, index)),
	IOCTL_INFO(VIDIOC_G_CTRL, INFO_FL_CTRL),
	IOCTL_INFO(VIDIOC_G_CTRL, INFO_FL_CTRL),
	IOCTL_INFO(VIDIOC_S_CTRL, INFO_FL_PRIO | INFO_FL_CTRL),
	IOCTL_INFO(VIDIOC_S_CTRL, INFO_FL_PRIO | INFO_FL_CTRL),
	IOCTL_INFO(VIDIOC_G_TUNER, INFO_FL_CLEAR(v4l2_tuner, index)),
	IOCTL_INFO_FNC(VIDIOC_G_TUNER, v4l_g_tuner, v4l_print_tuner, INFO_FL_CLEAR(v4l2_tuner, index)),
	IOCTL_INFO(VIDIOC_S_TUNER, INFO_FL_PRIO),
	IOCTL_INFO_FNC(VIDIOC_S_TUNER, v4l_s_tuner, v4l_print_tuner, INFO_FL_PRIO),
	IOCTL_INFO_STD(VIDIOC_G_AUDIO, vidioc_g_audio, v4l_print_audio, 0),
	IOCTL_INFO_STD(VIDIOC_G_AUDIO, vidioc_g_audio, v4l_print_audio, 0),
	IOCTL_INFO_STD(VIDIOC_S_AUDIO, vidioc_s_audio, v4l_print_audio, INFO_FL_PRIO),
	IOCTL_INFO_STD(VIDIOC_S_AUDIO, vidioc_s_audio, v4l_print_audio, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_QUERYCTRL, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
	IOCTL_INFO(VIDIOC_QUERYCTRL, INFO_FL_CTRL | INFO_FL_CLEAR(v4l2_queryctrl, id)),
@@ -946,10 +1155,10 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
	IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
	IOCTL_INFO_FNC(VIDIOC_ENUMOUTPUT, v4l_enumoutput, v4l_print_enumoutput, INFO_FL_CLEAR(v4l2_output, index)),
	IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
	IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
	IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
	IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_G_MODULATOR, INFO_FL_CLEAR(v4l2_modulator, index)),
	IOCTL_INFO_STD(VIDIOC_G_MODULATOR, vidioc_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
	IOCTL_INFO(VIDIOC_S_MODULATOR, INFO_FL_PRIO),
	IOCTL_INFO_STD(VIDIOC_S_MODULATOR, vidioc_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_G_FREQUENCY, INFO_FL_CLEAR(v4l2_frequency, tuner)),
	IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
	IOCTL_INFO(VIDIOC_S_FREQUENCY, INFO_FL_PRIO),
	IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_CROPCAP, INFO_FL_CLEAR(v4l2_cropcap, type)),
	IOCTL_INFO(VIDIOC_CROPCAP, INFO_FL_CLEAR(v4l2_cropcap, type)),
	IOCTL_INFO(VIDIOC_G_CROP, INFO_FL_CLEAR(v4l2_crop, type)),
	IOCTL_INFO(VIDIOC_G_CROP, INFO_FL_CLEAR(v4l2_crop, type)),
	IOCTL_INFO(VIDIOC_S_CROP, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_S_CROP, INFO_FL_PRIO),
@@ -957,7 +1166,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
	IOCTL_INFO(VIDIOC_S_SELECTION, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_S_SELECTION, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_G_JPEGCOMP, 0),
	IOCTL_INFO(VIDIOC_G_JPEGCOMP, 0),
	IOCTL_INFO(VIDIOC_S_JPEGCOMP, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_S_JPEGCOMP, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_QUERYSTD, 0),
	IOCTL_INFO_FNC(VIDIOC_QUERYSTD, v4l_querystd, v4l_print_std, 0),
	IOCTL_INFO_FNC(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
	IOCTL_INFO_FNC(VIDIOC_TRY_FMT, v4l_try_fmt, v4l_print_format, 0),
	IOCTL_INFO_STD(VIDIOC_ENUMAUDIO, vidioc_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
	IOCTL_INFO_STD(VIDIOC_ENUMAUDIO, vidioc_enumaudio, v4l_print_audio, INFO_FL_CLEAR(v4l2_audio, index)),
	IOCTL_INFO_STD(VIDIOC_ENUMAUDOUT, vidioc_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
	IOCTL_INFO_STD(VIDIOC_ENUMAUDOUT, vidioc_enumaudout, v4l_print_audioout, INFO_FL_CLEAR(v4l2_audioout, index)),
@@ -978,7 +1187,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
	IOCTL_INFO(VIDIOC_DBG_S_REGISTER, 0),
	IOCTL_INFO(VIDIOC_DBG_S_REGISTER, 0),
	IOCTL_INFO(VIDIOC_DBG_G_REGISTER, 0),
	IOCTL_INFO(VIDIOC_DBG_G_REGISTER, 0),
	IOCTL_INFO(VIDIOC_DBG_G_CHIP_IDENT, 0),
	IOCTL_INFO(VIDIOC_DBG_G_CHIP_IDENT, 0),
	IOCTL_INFO(VIDIOC_S_HW_FREQ_SEEK, INFO_FL_PRIO),
	IOCTL_INFO_FNC(VIDIOC_S_HW_FREQ_SEEK, v4l_s_hw_freq_seek, v4l_print_hw_freq_seek, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_ENUM_DV_PRESETS, 0),
	IOCTL_INFO(VIDIOC_ENUM_DV_PRESETS, 0),
	IOCTL_INFO(VIDIOC_S_DV_PRESET, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_S_DV_PRESET, INFO_FL_PRIO),
	IOCTL_INFO(VIDIOC_G_DV_PRESET, 0),
	IOCTL_INFO(VIDIOC_G_DV_PRESET, 0),
@@ -1160,102 +1369,6 @@ static long __video_do_ioctl(struct file *file,
			dbgbuf(cmd, vfd, p);
			dbgbuf(cmd, vfd, p);
		break;
		break;
	}
	}
	/* ---------- tv norms ---------- */
	case VIDIOC_ENUMSTD:
	{
		struct v4l2_standard *p = arg;
		v4l2_std_id id = vfd->tvnorms, curr_id = 0;
		unsigned int index = p->index, i, j = 0;
		const char *descr = "";

		if (id == 0)
			break;
		ret = -EINVAL;

		/* Return norm array in a canonical way */
		for (i = 0; i <= index && id; i++) {
			/* last std value in the standards array is 0, so this
			   while always ends there since (id & 0) == 0. */
			while ((id & standards[j].std) != standards[j].std)
				j++;
			curr_id = standards[j].std;
			descr = standards[j].descr;
			j++;
			if (curr_id == 0)
				break;
			if (curr_id != V4L2_STD_PAL &&
			    curr_id != V4L2_STD_SECAM &&
			    curr_id != V4L2_STD_NTSC)
				id &= ~curr_id;
		}
		if (i <= index)
			break;

		v4l2_video_std_construct(p, curr_id, descr);

		dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
				"framelines=%d\n", p->index,
				(unsigned long long)p->id, p->name,
				p->frameperiod.numerator,
				p->frameperiod.denominator,
				p->framelines);

		ret = 0;
		break;
	}
	case VIDIOC_G_STD:
	{
		v4l2_std_id *id = arg;

		/* Calls the specific handler */
		if (ops->vidioc_g_std)
			ret = ops->vidioc_g_std(file, fh, id);
		else if (vfd->current_norm) {
			ret = 0;
			*id = vfd->current_norm;
		}

		if (likely(!ret))
			dbgarg(cmd, "std=0x%08Lx\n", (long long unsigned)*id);
		break;
	}
	case VIDIOC_S_STD:
	{
		v4l2_std_id *id = arg, norm;

		dbgarg(cmd, "std=%08Lx\n", (long long unsigned)*id);

		ret = -EINVAL;
		norm = (*id) & vfd->tvnorms;
		if (vfd->tvnorms && !norm)	/* Check if std is supported */
			break;

		/* Calls the specific handler */
		ret = ops->vidioc_s_std(file, fh, &norm);

		/* Updates standard information */
		if (ret >= 0)
			vfd->current_norm = norm;
		break;
	}
	case VIDIOC_QUERYSTD:
	{
		v4l2_std_id *p = arg;

		/*
		 * If nothing detected, it should return all supported
		 * Drivers just need to mask the std argument, in order
		 * to remove the standards that don't apply from the mask.
		 * This means that tuners, audio and video decoders can join
		 * their efforts to improve the standards detection
		 */
		*p = vfd->tvnorms;
		ret = ops->vidioc_querystd(file, fh, arg);
		if (!ret)
			dbgarg(cmd, "detected std=%08Lx\n",
						(unsigned long long)*p);
		break;
	}


	/* --- controls ---------------------------------------------- */
	/* --- controls ---------------------------------------------- */
	case VIDIOC_QUERYCTRL:
	case VIDIOC_QUERYCTRL:
@@ -1426,31 +1539,6 @@ static long __video_do_ioctl(struct file *file,
				p->id, p->index);
				p->id, p->index);
		break;
		break;
	}
	}
	case VIDIOC_G_MODULATOR:
	{
		struct v4l2_modulator *p = arg;

		ret = ops->vidioc_g_modulator(file, fh, p);
		if (!ret)
			dbgarg(cmd, "index=%d, name=%s, "
					"capability=%d, rangelow=%d,"
					" rangehigh=%d, txsubchans=%d\n",
					p->index, p->name, p->capability,
					p->rangelow, p->rangehigh,
					p->txsubchans);
		break;
	}
	case VIDIOC_S_MODULATOR:
	{
		struct v4l2_modulator *p = arg;

		dbgarg(cmd, "index=%d, name=%s, capability=%d, "
				"rangelow=%d, rangehigh=%d, txsubchans=%d\n",
				p->index, p->name, p->capability, p->rangelow,
				p->rangehigh, p->txsubchans);
			ret = ops->vidioc_s_modulator(file, fh, p);
		break;
	}
	case VIDIOC_G_CROP:
	case VIDIOC_G_CROP:
	{
	{
		struct v4l2_crop *p = arg;
		struct v4l2_crop *p = arg;
@@ -1684,68 +1772,6 @@ static long __video_do_ioctl(struct file *file,
		ret = ops->vidioc_s_parm(file, fh, p);
		ret = ops->vidioc_s_parm(file, fh, p);
		break;
		break;
	}
	}
	case VIDIOC_G_TUNER:
	{
		struct v4l2_tuner *p = arg;

		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
		ret = ops->vidioc_g_tuner(file, fh, p);
		if (!ret)
			dbgarg(cmd, "index=%d, name=%s, type=%d, "
					"capability=0x%x, rangelow=%d, "
					"rangehigh=%d, signal=%d, afc=%d, "
					"rxsubchans=0x%x, audmode=%d\n",
					p->index, p->name, p->type,
					p->capability, p->rangelow,
					p->rangehigh, p->signal, p->afc,
					p->rxsubchans, p->audmode);
		break;
	}
	case VIDIOC_S_TUNER:
	{
		struct v4l2_tuner *p = arg;

		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
		dbgarg(cmd, "index=%d, name=%s, type=%d, "
				"capability=0x%x, rangelow=%d, "
				"rangehigh=%d, signal=%d, afc=%d, "
				"rxsubchans=0x%x, audmode=%d\n",
				p->index, p->name, p->type,
				p->capability, p->rangelow,
				p->rangehigh, p->signal, p->afc,
				p->rxsubchans, p->audmode);
		ret = ops->vidioc_s_tuner(file, fh, p);
		break;
	}
	case VIDIOC_G_FREQUENCY:
	{
		struct v4l2_frequency *p = arg;

		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
		ret = ops->vidioc_g_frequency(file, fh, p);
		if (!ret)
			dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
					p->tuner, p->type, p->frequency);
		break;
	}
	case VIDIOC_S_FREQUENCY:
	{
		struct v4l2_frequency *p = arg;
		enum v4l2_tuner_type type;

		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
		dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
				p->tuner, p->type, p->frequency);
		if (p->type != type)
			ret = -EINVAL;
		else
			ret = ops->vidioc_s_frequency(file, fh, p);
		break;
	}
	case VIDIOC_G_SLICED_VBI_CAP:
	case VIDIOC_G_SLICED_VBI_CAP:
	{
	{
		struct v4l2_sliced_vbi_cap *p = arg;
		struct v4l2_sliced_vbi_cap *p = arg;
@@ -1805,22 +1831,6 @@ static long __video_do_ioctl(struct file *file,
			dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
			dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
		break;
		break;
	}
	}
	case VIDIOC_S_HW_FREQ_SEEK:
	{
		struct v4l2_hw_freq_seek *p = arg;
		enum v4l2_tuner_type type;

		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
		dbgarg(cmd,
			"tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n",
			p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing);
		if (p->type != type)
			ret = -EINVAL;
		else
			ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
		break;
	}
	case VIDIOC_ENUM_FRAMESIZES:
	case VIDIOC_ENUM_FRAMESIZES:
	{
	{
		struct v4l2_frmsizeenum *p = arg;
		struct v4l2_frmsizeenum *p = arg;