/*
* Video for Linux Two
*
* A generic video device interface for the LINUX operating system
* using a set of device structures/vectors for low level operations.
*
* This file replaces the videodev.c file that comes with the
* regular kernel distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Author: Bill Dirks <bill@thedirks.org>
* based on code by Alan Cox, <alan@cymru.net>
*
*/
/*
* Video capture interface for Linux
*
* A generic video device interface for the LINUX operating system
* using a set of device structures/vectors for low level operations.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Author: Alan Cox, <alan@lxorguk.ukuu.org.uk>
*
* Fixes:
*/
/*
* Video4linux 1/2 integration by Justin Schoeman
* <justin@suntiger.ee.up.ac.za>
* 2.4 PROCFS support ported from 2.4 kernels by
* Iñaki García Etxebarria <garetxe@euskalnet.net>
* Makefile fix by "W. Michael Petullo" <mike@flyn.org>
* 2.4 devfs support ported from 2.4 kernels by
* Dan Merillat <dan@merillat.org>
* Added Gerd Knorrs v4l1 enhancements (Justin Schoeman)
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/i2c.h>
#if defined(CONFIG_SPI)
#include <linux/spi/spi.h>
#endif
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/io.h>
#include <asm/div64.h>
#define __OLD_VIDIOC_ /* To allow fixing old calls*/
#include <media/v4l2-common.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
#include <linux/videodev2.h>
MODULE_AUTHOR("Bill Dirks, Justin Schoeman, Gerd Knorr");
MODULE_DESCRIPTION("misc helper functions for v4l2 device drivers");
MODULE_LICENSE("GPL");
/*
*
* V 4 L 2 D R I V E R H E L P E R A P I
*
*/
/*
* Video Standard Operations (contributed by Michael Schimek)
*/
/* ----------------------------------------------------------------- */
/* priority handling */
#define V4L2_PRIO_VALID(val) (val == V4L2_PRIORITY_BACKGROUND || \
val == V4L2_PRIORITY_INTERACTIVE || \
val == V4L2_PRIORITY_RECORD)
void v4l2_prio_init(struct v4l2_prio_state *global)
{
memset(global, 0, sizeof(*global));
}
EXPORT_SYMBOL(v4l2_prio_init);
int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
enum v4l2_priority new)
{
if (!V4L2_PRIO_VALID(new))
return -EINVAL;
if (*local == new)
return 0;
atomic_inc(&global->prios[new]);
if (V4L2_PRIO_VALID(*local))
atomic_dec(&global->prios[*local]);
*local = new;
return 0;
}
EXPORT_SYMBOL(v4l2_prio_change);
void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
{
v4l2_prio_change(global, local, V4L2_PRIORITY_DEFAULT);
}
EXPORT_SYMBOL(v4l2_prio_open);
void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)
{
if (V4L2_PRIO_VALID(local))
atomic_dec(&global->prios[local]);
}
EXPORT_SYMBOL(v4l2_prio_close);
enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
{
if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
return V4L2_PRIORITY_RECORD;
if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
return V4L2_PRIORITY_INTERACTIVE;
if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
return V4L2_PRIORITY_BACKGROUND;
return V4L2_PRIORITY_UNSET;
}
EXPORT_SYMBOL(v4l2_prio_max);
int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)
{
return (local < v4l2_prio_max(global)) ? -EBUSY : 0;
}
EXPORT_SYMBOL(v4l2_prio_check);
/* ----------------------------------------------------------------- */
/* Helper functions for control handling */
/* Check for correctness of the ctrl's value based on the data from
struct v4l2_queryctrl and the available menu items. Note that
menu_items may be NULL, in that case it is ignored. */
int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
const char **menu_items)
{
if (qctrl->flags & V4L2_CTRL_FLAG_DISABLED)
return -EINVAL;
if (qctrl->flags & V4L2_CTRL_FLAG_GRABBED)
return -EBUSY;
if