summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-10 15:09:54 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-10 15:09:54 -0700
commit7ae0dea900b027cd90e8a3e14deca9a19e17638b (patch)
tree428cbe411bba90f6580ae21338276c949e91f23a /include
parent6c74700fdb8e3bc34c31790384a8ec16c4fefd97 (diff)
parent560afa7d85bdfb294506afd3032c315e6827824f (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (94 commits) V4L/DVB: tvp7002: fix write to H-PLL Feedback Divider LSB register V4L/DVB: dvb: siano: free spinlock before schedule() V4L/DVB: media: video: pvrusb2: remove custom hex_to_bin() V4L/DVB: drivers: usbvideo: remove custom implementation of hex_to_bin() V4L/DVB: Report supported QAM modes on bt8xx V4L/DVB: media: ir-keytable: null dereference in debug code V4L/DVB: ivtv: convert to the new control framework V4L/DVB: ivtv: convert gpio subdev to new control framework V4L/DVB: wm8739: convert to the new control framework V4L/DVB: cs53l32a: convert to new control framework V4L/DVB: wm8775: convert to the new control framework V4L/DVB: cx2341x: convert to the control framework V4L/DVB: cx25840: convert to the new control framework V4L/DVB: cx25840/ivtv: replace ugly priv control with s_config V4L/DVB: saa717x: convert to the new control framework V4L/DVB: msp3400: convert to the new control framework V4L/DVB: saa7115: convert to the new control framework V4L/DVB: v4l2: hook up the new control framework into the core framework V4L/DVB: Documentation: add v4l2-controls.txt documenting the new controls API V4L/DVB: v4l2-ctrls: Whitespace cleanups ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/videodev2.h1
-rw-r--r--include/media/cx2341x.h97
-rw-r--r--include/media/cx25840.h87
-rw-r--r--include/media/ir-core.h41
-rw-r--r--include/media/lirc.h5
-rw-r--r--include/media/rc-map.h1
-rw-r--r--include/media/v4l2-ctrls.h460
-rw-r--r--include/media/v4l2-dev.h4
-rw-r--r--include/media/v4l2-device.h4
-rw-r--r--include/media/v4l2-subdev.h54
10 files changed, 732 insertions, 22 deletions
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 047f7e6edb86..61490c6dcdbd 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -277,6 +277,7 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_RGB565 v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */
#define V4L2_PIX_FMT_RGB555X v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */
#define V4L2_PIX_FMT_RGB565X v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */
+#define V4L2_PIX_FMT_BGR666 v4l2_fourcc('B', 'G', 'R', 'H') /* 18 BGR-6-6-6 */
#define V4L2_PIX_FMT_BGR24 v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */
#define V4L2_PIX_FMT_RGB24 v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */
#define V4L2_PIX_FMT_BGR32 v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */
diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h
index 9ebe8558b9b6..8d08ebfe20b7 100644
--- a/include/media/cx2341x.h
+++ b/include/media/cx2341x.h
@@ -19,6 +19,8 @@
#ifndef CX2341X_H
#define CX2341X_H
+#include <media/v4l2-ctrls.h>
+
enum cx2341x_port {
CX2341X_PORT_MEMORY = 0,
CX2341X_PORT_STREAMING = 1,
@@ -99,6 +101,101 @@ int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p);
void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix);
+struct cx2341x_handler;
+
+struct cx2341x_handler_ops {
+ /* needed for the video clock freq */
+ int (*s_audio_sampling_freq)(struct cx2341x_handler *hdl, u32 val);
+ /* needed for dualwatch */
+ int (*s_audio_mode)(struct cx2341x_handler *hdl, u32 val);
+ /* needed for setting up the video resolution */
+ int (*s_video_encoding)(struct cx2341x_handler *hdl, u32 val);
+ /* needed for setting up the sliced vbi insertion data structures */
+ int (*s_stream_vbi_fmt)(struct cx2341x_handler *hdl, u32 val);
+};
+
+struct cx2341x_handler {
+ u32 capabilities;
+ enum cx2341x_port port;
+ u16 width;
+ u16 height;
+ u16 is_50hz;
+ u32 audio_properties;
+
+ struct v4l2_ctrl_handler hdl;
+ void *priv;
+ cx2341x_mbox_func func;
+ const struct cx2341x_handler_ops *ops;
+
+ struct v4l2_ctrl *stream_vbi_fmt;
+
+ struct {
+ /* audio cluster */
+ struct v4l2_ctrl *audio_sampling_freq;
+ struct v4l2_ctrl *audio_encoding;
+ struct v4l2_ctrl *audio_l2_bitrate;
+ struct v4l2_ctrl *audio_mode;
+ struct v4l2_ctrl *audio_mode_extension;
+ struct v4l2_ctrl *audio_emphasis;
+ struct v4l2_ctrl *audio_crc;
+ struct v4l2_ctrl *audio_ac3_bitrate;
+ };
+
+ struct {
+ /* video gop cluster */
+ struct v4l2_ctrl *video_b_frames;
+ struct v4l2_ctrl *video_gop_size;
+ };
+
+ struct {
+ /* stream type cluster */
+ struct v4l2_ctrl *stream_type;
+ struct v4l2_ctrl *video_encoding;
+ struct v4l2_ctrl *video_bitrate_mode;
+ struct v4l2_ctrl *video_bitrate;
+ struct v4l2_ctrl *video_bitrate_peak;
+ };
+
+ struct {
+ /* video mute cluster */
+ struct v4l2_ctrl *video_mute;
+ struct v4l2_ctrl *video_mute_yuv;
+ };
+
+ struct {
+ /* video filter mode cluster */
+ struct v4l2_ctrl *video_spatial_filter_mode;
+ struct v4l2_ctrl *video_temporal_filter_mode;
+ struct v4l2_ctrl *video_median_filter_type;
+ };
+
+ struct {
+ /* video filter type cluster */
+ struct v4l2_ctrl *video_luma_spatial_filter_type;
+ struct v4l2_ctrl *video_chroma_spatial_filter_type;
+ };
+
+ struct {
+ /* video filter cluster */
+ struct v4l2_ctrl *video_spatial_filter;
+ struct v4l2_ctrl *video_temporal_filter;
+ };
+
+ struct {
+ /* video median cluster */
+ struct v4l2_ctrl *video_luma_median_filter_top;
+ struct v4l2_ctrl *video_luma_median_filter_bottom;
+ struct v4l2_ctrl *video_chroma_median_filter_top;
+ struct v4l2_ctrl *video_chroma_median_filter_bottom;
+ };
+};
+
+int cx2341x_handler_init(struct cx2341x_handler *cxhdl,
+ unsigned nr_of_controls_hint);
+void cx2341x_handler_set_50hz(struct cx2341x_handler *cxhdl, int is_50hz);
+int cx2341x_handler_setup(struct cx2341x_handler *cxhdl);
+void cx2341x_handler_set_busy(struct cx2341x_handler *cxhdl, int busy);
+
/* Firmware names */
#define CX2341X_FIRM_ENC_FILENAME "v4l-cx2341x-enc.fw"
/* Decoder firmware for the cx23415 only */
diff --git a/include/media/cx25840.h b/include/media/cx25840.h
index 0b0cb1776796..46d1a141208e 100644
--- a/include/media/cx25840.h
+++ b/include/media/cx25840.h
@@ -97,4 +97,91 @@ enum cx25840_audio_input {
CX25840_AUDIO8,
};
+enum cx25840_io_pin {
+ CX25840_PIN_DVALID_PRGM0 = 0,
+ CX25840_PIN_FIELD_PRGM1,
+ CX25840_PIN_HRESET_PRGM2,
+ CX25840_PIN_VRESET_HCTL_PRGM3,
+ CX25840_PIN_IRQ_N_PRGM4,
+ CX25840_PIN_IR_TX_PRGM6,
+ CX25840_PIN_IR_RX_PRGM5,
+ CX25840_PIN_GPIO0_PRGM8,
+ CX25840_PIN_GPIO1_PRGM9,
+ CX25840_PIN_SA_SDIN, /* Alternate GP Input only */
+ CX25840_PIN_SA_SDOUT, /* Alternate GP Input only */
+ CX25840_PIN_PLL_CLK_PRGM7,
+ CX25840_PIN_CHIP_SEL_VIPCLK, /* Output only */
+};
+
+enum cx25840_io_pad {
+ /* Output pads */
+ CX25840_PAD_DEFAULT = 0,
+ CX25840_PAD_ACTIVE,
+ CX25840_PAD_VACTIVE,
+ CX25840_PAD_CBFLAG,
+ CX25840_PAD_VID_DATA_EXT0,
+ CX25840_PAD_VID_DATA_EXT1,
+ CX25840_PAD_GPO0,
+ CX25840_PAD_GPO1,
+ CX25840_PAD_GPO2,
+ CX25840_PAD_GPO3,
+ CX25840_PAD_IRQ_N,
+ CX25840_PAD_AC_SYNC,
+ CX25840_PAD_AC_SDOUT,
+ CX25840_PAD_PLL_CLK,
+ CX25840_PAD_VRESET,
+ CX25840_PAD_RESERVED,
+ /* Pads for PLL_CLK output only */
+ CX25840_PAD_XTI_X5_DLL,
+ CX25840_PAD_AUX_PLL,
+ CX25840_PAD_VID_PLL,
+ CX25840_PAD_XTI,
+ /* Input Pads */
+ CX25840_PAD_GPI0,
+ CX25840_PAD_GPI1,
+ CX25840_PAD_GPI2,
+ CX25840_PAD_GPI3,
+};
+
+enum cx25840_io_pin_strength {
+ CX25840_PIN_DRIVE_MEDIUM = 0,
+ CX25840_PIN_DRIVE_SLOW,
+ CX25840_PIN_DRIVE_FAST,
+};
+
+enum cx23885_io_pin {
+ CX23885_PIN_IR_RX_GPIO19,
+ CX23885_PIN_IR_TX_GPIO20,
+ CX23885_PIN_I2S_SDAT_GPIO21,
+ CX23885_PIN_I2S_WCLK_GPIO22,
+ CX23885_PIN_I2S_BCLK_GPIO23,
+ CX23885_PIN_IRQ_N_GPIO16,
+};
+
+enum cx23885_io_pad {
+ CX23885_PAD_IR_RX,
+ CX23885_PAD_GPIO19,
+ CX23885_PAD_IR_TX,
+ CX23885_PAD_GPIO20,
+ CX23885_PAD_I2S_SDAT,
+ CX23885_PAD_GPIO21,
+ CX23885_PAD_I2S_WCLK,
+ CX23885_PAD_GPIO22,
+ CX23885_PAD_I2S_BCLK,
+ CX23885_PAD_GPIO23,
+ CX23885_PAD_IRQ_N,
+ CX23885_PAD_GPIO16,
+};
+
+/* pvr150_workaround activates a workaround for a hardware bug that is
+ present in Hauppauge PVR-150 (and possibly PVR-500) cards that have
+ certain NTSC tuners (tveeprom tuner model numbers 85, 99 and 112). The
+ audio autodetect fails on some channels for these models and the workaround
+ is to select the audio standard explicitly. Many thanks to Hauppauge for
+ providing this information.
+ This platform data only needs to be supplied by the ivtv driver. */
+struct cx25840_platform_data {
+ int pvr150_workaround;
+};
+
#endif
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index 513e60dd1010..eb7fddf8f607 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -41,6 +41,11 @@ enum rc_driver_type {
* anything with it. Yet, as the same keycode table can be used with other
* devices, a mask is provided to allow its usage. Drivers should generally
* leave this field in blank
+ * @timeout: optional time after which device stops sending data
+ * @min_timeout: minimum timeout supported by device
+ * @max_timeout: maximum timeout supported by device
+ * @rx_resolution : resolution (in ns) of input sampler
+ * @tx_resolution: resolution (in ns) of output sampler
* @priv: driver-specific data, to be used on the callbacks
* @change_protocol: allow changing the protocol used on hardware decoders
* @open: callback to allow drivers to enable polling/irq when IR input device
@@ -49,19 +54,36 @@ enum rc_driver_type {
* is opened.
* @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
* @s_tx_carrier: set transmit carrier frequency
+ * @s_tx_duty_cycle: set transmit duty cycle (0% - 100%)
+ * @s_rx_carrier: inform driver about carrier it is expected to handle
* @tx_ir: transmit IR
+ * @s_idle: optional: enable/disable hardware idle mode, upon which,
+ device doesn't interrupt host until it sees IR pulses
+ * @s_learning_mode: enable wide band receiver used for learning
*/
struct ir_dev_props {
enum rc_driver_type driver_type;
unsigned long allowed_protos;
u32 scanmask;
+
+ u32 timeout;
+ u32 min_timeout;
+ u32 max_timeout;
+
+ u32 rx_resolution;
+ u32 tx_resolution;
+
void *priv;
int (*change_protocol)(void *priv, u64 ir_type);
int (*open)(void *priv);
void (*close)(void *priv);
int (*s_tx_mask)(void *priv, u32 mask);
int (*s_tx_carrier)(void *priv, u32 carrier);
+ int (*s_tx_duty_cycle)(void *priv, u32 duty_cycle);
+ int (*s_rx_carrier_range)(void *priv, u32 min, u32 max);
int (*tx_ir)(void *priv, int *txbuf, u32 n);
+ void (*s_idle)(void *priv, int enable);
+ int (*s_learning_mode)(void *priv, int enable);
};
struct ir_input_dev {
@@ -69,9 +91,10 @@ struct ir_input_dev {
char *driver_name; /* Name of the driver module */
struct ir_scancode_table rc_tab; /* scan/key table */
unsigned long devno; /* device number */
- const struct ir_dev_props *props; /* Device properties */
+ struct ir_dev_props *props; /* Device properties */
struct ir_raw_event_ctrl *raw; /* for raw pulse/space events */
struct input_dev *input_dev; /* the input device associated with this device */
+ bool idle;
/* key info - needed by IR keycode handlers */
spinlock_t keylock; /* protects the below members */
@@ -95,12 +118,12 @@ enum raw_event_type {
/* From ir-keytable.c */
int __ir_input_register(struct input_dev *dev,
const struct ir_scancode_table *ir_codes,
- const struct ir_dev_props *props,
+ struct ir_dev_props *props,
const char *driver_name);
static inline int ir_input_register(struct input_dev *dev,
const char *map_name,
- const struct ir_dev_props *props,
+ struct ir_dev_props *props,
const char *driver_name) {
struct ir_scancode_table *ir_codes;
struct ir_input_dev *ir_dev;
@@ -110,8 +133,12 @@ static inline int ir_input_register(struct input_dev *dev,
return -EINVAL;
ir_codes = get_rc_map(map_name);
- if (!ir_codes)
- return -EINVAL;
+ if (!ir_codes) {
+ ir_codes = get_rc_map(RC_MAP_EMPTY);
+
+ if (!ir_codes)
+ return -EINVAL;
+ }
rc = __ir_input_register(dev, ir_codes, props, driver_name);
if (rc < 0)
@@ -144,6 +171,10 @@ struct ir_raw_event {
void ir_raw_event_handle(struct input_dev *input_dev);
int ir_raw_event_store(struct input_dev *input_dev, struct ir_raw_event *ev);
int ir_raw_event_store_edge(struct input_dev *input_dev, enum raw_event_type type);
+int ir_raw_event_store_with_filter(struct input_dev *input_dev,
+ struct ir_raw_event *ev);
+void ir_raw_event_set_idle(struct input_dev *input_dev, int idle);
+
static inline void ir_raw_event_reset(struct input_dev *input_dev)
{
struct ir_raw_event ev = { .pulse = false, .duration = 0 };
diff --git a/include/media/lirc.h b/include/media/lirc.h
index 42c467c50519..6678a169fd9e 100644
--- a/include/media/lirc.h
+++ b/include/media/lirc.h
@@ -77,6 +77,7 @@
#define LIRC_CAN_SET_REC_FILTER 0x08000000
#define LIRC_CAN_MEASURE_CARRIER 0x02000000
+#define LIRC_CAN_USE_WIDEBAND_RECEIVER 0x04000000
#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK)
#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
@@ -145,7 +146,7 @@
* if enabled from the next key press on the driver will send
* LIRC_MODE2_FREQUENCY packets
*/
-#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32)
+#define LIRC_SET_MEASURE_CARRIER_MODE _IOW('i', 0x0000001d, __u32)
/*
* to set a range use
@@ -162,4 +163,6 @@
#define LIRC_SETUP_START _IO('i', 0x00000021)
#define LIRC_SETUP_END _IO('i', 0x00000022)
+#define LIRC_SET_WIDEBAND_RECEIVER _IOW('i', 0x00000023, __u32)
+
#endif
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index 9569d0863f8b..a9c041d49662 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -114,6 +114,7 @@ void rc_map_init(void);
#define RC_MAP_PURPLETV "rc-purpletv"
#define RC_MAP_PV951 "rc-pv951"
#define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new"
+#define RC_MAP_RC5_STREAMZAP "rc-rc5-streamzap"
#define RC_MAP_RC5_TV "rc-rc5-tv"
#define RC_MAP_RC6_MCE "rc-rc6-mce"
#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
new file mode 100644
index 000000000000..9b7bea928a88
--- /dev/null
+++ b/include/media/v4l2-ctrls.h
@@ -0,0 +1,460 @@
+/*
+ V4L2 controls support header.
+
+ Copyright (C) 2010 Hans Verkuil <hverkuil@xs4all.nl>
+
+ 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.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _V4L2_CTRLS_H
+#define _V4L2_CTRLS_H
+
+#include <linux/list.h>
+#include <linux/device.h>
+
+/* forward references */
+struct v4l2_ctrl_handler;
+struct v4l2_ctrl;
+struct video_device;
+struct v4l2_subdev;
+
+/** struct v4l2_ctrl_ops - The control operations that the driver has to provide.
+ * @g_volatile_ctrl: Get a new value for this control. Generally only relevant
+ * for volatile (and usually read-only) controls such as a control
+ * that returns the current signal strength which changes
+ * continuously.
+ * If not set, then the currently cached value will be returned.
+ * @try_ctrl: Test whether the control's value is valid. Only relevant when
+ * the usual min/max/step checks are not sufficient.
+ * @s_ctrl: Actually set the new control value. s_ctrl is compulsory. The
+ * ctrl->handler->lock is held when these ops are called, so no
+ * one else can access controls owned by that handler.
+ */
+struct v4l2_ctrl_ops {
+ int (*g_volatile_ctrl)(struct v4l2_ctrl *ctrl);
+ int (*try_ctrl)(struct v4l2_ctrl *ctrl);
+ int (*s_ctrl)(struct v4l2_ctrl *ctrl);
+};
+
+/** struct v4l2_ctrl - The control structure.
+ * @node: The list node.
+ * @handler: The handler that owns the control.
+ * @cluster: Point to start of cluster array.
+ * @ncontrols: Number of controls in cluster array.
+ * @has_new: Internal flag: set when there is a valid new value.
+ * @done: Internal flag: set for each processed control.
+ * @is_private: If set, then this control is private to its handler and it
+ * will not be added to any other handlers. Drivers can set
+ * this flag.
+ * @is_volatile: If set, then this control is volatile. This means that the
+ * control's current value cannot be cached and needs to be
+ * retrieved through the g_volatile_ctrl op. Drivers can set
+ * this flag.
+ * @ops: The control ops.
+ * @id: The control ID.
+ * @name: The control name.
+ * @type: The control type.
+ * @minimum: The control's minimum value.
+ * @maximum: The control's maximum value.
+ * @default_value: The control's default value.
+ * @step: The control's step value for non-menu controls.
+ * @menu_skip_mask: The control's skip mask for menu controls. This makes it
+ * easy to skip menu items that are not valid. If bit X is set,
+ * then menu item X is skipped. Of course, this only works for
+ * menus with <= 32 menu items. There are no menus that come
+ * close to that number, so this is OK. Should we ever need more,
+ * then this will have to be extended to a u64 or a bit array.
+ * @qmenu: A const char * array for all menu items. Array entries that are
+ * empty strings ("") correspond to non-existing menu items (this
+ * is in addition to the menu_skip_mask above). The last entry
+ * must be NULL.
+ * @flags: The control's flags.
+ * @cur: The control's current value.
+ * @val: The control's new s32 value.
+ * @val64: The control's new s64 value.
+ * @string: The control's new string value.
+ * @priv: The control's private pointer. For use by the driver. It is
+ * untouched by the control framework. Note that this pointer is
+ * not freed when the control is deleted. Should this be needed
+ * then a new internal bitfield can be added to tell the framework
+ * to free this pointer.
+ */
+struct v4l2_ctrl {
+ /* Administrative fields */
+ struct list_head node;
+ struct v4l2_ctrl_handler *handler;
+ struct v4l2_ctrl **cluster;
+ unsigned ncontrols;
+ unsigned int has_new:1;
+ unsigned int done:1;
+
+ unsigned int is_private:1;
+ unsigned int is_volatile:1;
+
+ const struct v4l2_ctrl_ops *ops;
+ u32 id;
+ const char *name;
+ enum v4l2_ctrl_type type;
+ s32 minimum, maximum, default_value;
+ union {
+ u32 step;
+ u32 menu_skip_mask;
+ };
+ const char **qmenu;
+ unsigned long flags;
+ union {
+ s32 val;
+ s64 val64;
+ char *string;
+ } cur;
+ union {
+ s32 val;
+ s64 val64;
+ char *string;
+ };
+ void *priv;
+};
+
+/** struct v4l2_ctrl_ref - The control reference.
+ * @node: List node for the sorted list.
+ * @next: Single-link list node for the hash.
+ * @ctrl: The actual control information.
+ *
+ * Each control handler has a list of these refs. The list_head is used to
+ * keep a sorted-by-control-ID list of all controls, while the next pointer
+ * is used to link the control in the hash's bucket.
+ */
+struct v4l2_ctrl_ref {
+ struct list_head node;
+ struct v4l2_ctrl_ref *next;
+ struct v4l2_ctrl *ctrl;
+};
+
+/** struct v4l2_ctrl_handler - The control handler keeps track of all the
+ * controls: both the controls owned by the handler and those inherited
+ * from other handlers.
+ * @lock: Lock to control access to this handler and its controls.
+ * @ctrls: The list of controls owned by this handler.
+ * @ctrl_refs: The list of control references.
+ * @cached: The last found control reference. It is common that the same
+ * control is needed multiple times, so this is a simple
+ * optimization.
+ * @buckets: Buckets for the hashing. Allows for quick control lookup.
+ * @nr_of_buckets: Total number of buckets in the array.
+ * @error: The error code of the first failed control addition.
+ */
+struct v4l2_ctrl_handler {
+ struct mutex lock;
+ struct list_head ctrls;
+ struct list_head ctrl_refs;
+ struct v4l2_ctrl_ref *cached;
+ struct v4l2_ctrl_ref **buckets;
+ u16 nr_of_buckets;
+ int error;
+};
+
+/** struct v4l2_ctrl_config - Control configuration structure.
+ * @ops: The control ops.
+ * @id: The control ID.
+ * @name: The control name.
+ * @type: The control type.
+ * @min: The control's minimum value.
+ * @max: The control's maximum value.
+ * @step: The control's step value for non-menu controls.
+ * @def: The control's default value.
+ * @flags: The control's flags.
+ * @menu_skip_mask: The control's skip mask for menu controls. This makes it
+ * easy to skip menu items that are not valid. If bit X is set,
+ * then menu item X is skipped. Of course, this only works for
+ * menus with <= 32 menu items. There are no menus that come
+ * close to that number, so this is OK. Should we ever need more,
+ * then this will have to be extended to a u64 or a bit array.
+ * @qmenu: A const char * array for all menu items. Array entries that are
+ * empty strings ("") correspond to non-existing menu items (this
+ * is in addition to the menu_skip_mask above). The last entry
+ * must be NULL.
+ * @is_private: If set, then this control is private to its handler and it
+ * will not be added to any other handlers.
+ * @is_volatile: If set, then this control is volatile. This means that the
+ * control's current value cannot be cached and needs to be
+ * retrieved through the g_volatile_ctrl op.
+ */
+struct v4l2_ctrl_config {
+ const struct v4l2_ctrl_ops *ops;
+ u32 id;
+ const char *name;
+ enum v4l2_ctrl_type type;
+ s32 min;
+ s32 max;
+ u32 step;
+ s32 def;
+ u32 flags;
+ u32 menu_skip_mask;
+ const char **qmenu;
+ unsigned int is_private:1;
+ unsigned int is_volatile:1;
+};
+
+/** v4l2_ctrl_fill() - Fill in the control fields based on the control ID.
+ *
+ * This works for all standard V4L2 controls.
+ * For non-standard controls it will only fill in the given arguments
+ * and @name will be NULL.
+ *
+ * This function will overwrite the contents of @name, @type and @flags.
+ * The contents of @min, @max, @step and @def may be modified depending on
+ * the type.
+ *
+ * Do not use in drivers! It is used internally for backwards compatibility
+ * control handling only. Once all drivers are converted to use the new
+ * control framework this function will no longer be exported.
+ */
+void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
+ s32 *min, s32 *max, s32 *step, s32 *def, u32 *flags);
+
+
+/** v4l2_ctrl_handler_init() - Initialize the control handler.
+ * @hdl: The control handler.
+ * @nr_of_controls_hint: A hint of how many controls this handler is
+ * expected to refer to. This is the total number, so including
+ * any inherited controls. It doesn't have to be precise, but if
+ * it is way off, then you either waste memory (too many buckets
+ * are allocated) or the control lookup becomes slower (not enough
+ * buckets are allocated, so there are more slow list lookups).
+ * It will always work, though.
+ *
+ * Returns an error if the buckets could not be allocated. This error will
+ * also be stored in @hdl->error.
+ */
+int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
+ unsigned nr_of_controls_hint);
+
+/** v4l2_ctrl_handler_free() - Free all controls owned by the handler and free
+ * the control list.
+ * @hdl: The control handler.
+ *
+ * Does nothing if @hdl == NULL.
+ */
+void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl);
+
+/** v4l2_ctrl_handler_setup() - Call the s_ctrl op for all controls belonging
+ * to the handler to initialize the hardware to the current control values.
+ * @hdl: The control handler.
+ *
+ * Button controls will be skipped, as are read-only controls.
+ *
+ * If @hdl == NULL, then this just returns 0.
+ */
+int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl);
+
+/** v4l2_ctrl_handler_log_status() - Log all controls owned by the handler.
+ * @hdl: The control handler.
+ * @prefix: The prefix to use when logging the control values. If the
+ * prefix does not end with a space, then ": " will be added
+ * after the prefix. If @prefix == NULL, then no prefix will be
+ * used.
+ *
+ * For use with VIDIOC_LOG_STATUS.
+ *
+ * Does nothing if @hdl == NULL.
+ */
+void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
+ const char *prefix);
+
+/** v4l2_ctrl_new_custom() - Allocate and initialize a new custom V4L2
+ * control.
+ * @hdl: The control handler.
+ * @cfg: The control's configuration data.
+ * @priv: The control's driver-specific private data.
+ *
+ * If the &v4l2_ctrl struct could not be allocated then NULL is returned
+ * and @hdl->error is set to the error code (if it wasn't set already).
+ */
+struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_config *cfg, void *priv);
+
+/** v4l2_ctrl_new_std() - Allocate and initialize a new standard V4L2 non-menu control.
+ * @hdl: The control handler.
+ * @ops: The control ops.
+ * @id: The control ID.
+ * @min: The control's minimum value.
+ * @max: The control's maximum value.
+ * @step: The control's step value
+ * @def: The control's default value.
+ *
+ * If the &v4l2_ctrl struct could not be allocated, or the control
+ * ID is not known, then NULL is returned and @hdl->error is set to the
+ * appropriate error code (if it wasn't set already).
+ *
+ * If @id refers to a menu control, then this function will return NULL.
+ *
+ * Use v4l2_ctrl_new_std_menu() when adding menu controls.
+ */
+struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops,
+ u32 id, s32 min, s32 max, u32 step, s32 def);
+
+/** v4l2_ctrl_new_std_menu() - Allocate and initialize a new standard V4L2 menu control.
+ * @hdl: The control handler.
+ * @ops: The control ops.
+ * @id: The control ID.
+ * @max: The control's maximum value.
+ * @mask: The control's skip mask for menu controls. This makes it
+ * easy to skip menu items that are not valid. If bit X is set,
+ * then menu item X is skipped. Of course, this only works for
+ * menus with <= 32 menu items. There are no menus that come
+ * close to that number, so this is OK. Should we ever need more,
+ * then this will have to be extended to a u64 or a bit array.
+ * @def: The control's default value.
+ *
+ * Same as v4l2_ctrl_new_std(), but @min is set to 0 and the @mask value
+ * determines which menu items are to be skipped.
+ *
+ * If @id refers to a non-menu control, then this function will return NULL.
+ */
+struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
+ const struct v4l2_ctrl_ops *ops,
+ u32 id, s32 max, s32 mask, s32 def);
+
+/** v4l2_ctrl_add_ctrl() - Add a control from another handler to this handler.
+ * @hdl: The control handler.
+ * @ctrl: The control to add.
+ *
+ * It will return NULL if it was unable to add the control reference.
+ * If the control already belonged to the handler, then it will do
+ * nothing and just return @ctrl.
+ */
+struct v4l2_ctrl *v4l2_ctrl_add_ctrl(struct v4l2_ctrl_handler *hdl,
+ struct v4l2_ctrl *ctrl);
+
+/** v4l2_ctrl_add_handler() - Add all controls from handler @add to
+ * handler @hdl.
+ * @hdl: The control handler.
+ * @add: The control handler whose controls you want to add to
+ * the @hdl control handler.
+ *
+ * Does nothing if either of the two is a NULL pointer.
+ * In case of an error @hdl->error will be set to the error code (if it
+ * wasn't set already).
+ */
+int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
+ struct v4l2_ctrl_handler *add);
+
+
+/** v4l2_ctrl_cluster() - Mark all controls in the cluster as belonging to that cluster.
+ * @ncontrols: The number of controls in this cluster.
+ * @controls: The cluster control array of size @ncontrols.
+ */
+void v4l2_ctrl_cluster(unsigned ncontrols, struct v4l2_ctrl **controls);
+
+
+/** v4l2_ctrl_find() - Find a control with the given ID.
+ * @hdl: The control handler.
+ * @id: The control ID to find.
+ *
+ * If @hdl == NULL this will return NULL as well. Will lock the handler so
+ * do not use from inside &v4l2_ctrl_ops.
+ */
+struct v4l2_ctrl *v4l2_ctrl_find(struct v4l2_ctrl_handler *hdl, u32 id);
+
+/** v4l2_ctrl_activate() - Make the control active or inactive.
+ * @ctrl: The control to (de)activate.
+ * @active: True if the control should become active.
+ *
+ * This sets or clears the V4L2_CTRL_FLAG_INACTIVE flag atomically.
+ * Does nothing if @ctrl == NULL.
+ * This will usually be called from within the s_ctrl op.
+ *
+ * This function can be called regardless of whether the control handler
+ * is locked or not.
+ */
+void v4l2_ctrl_activate(struct v4l2_ctrl *ctrl, bool active);
+
+/** v4l2_ctrl_grab() - Mark the control as grabbed or not grabbed.
+ * @ctrl: The control to (de)activate.
+ * @grabbed: True if the control should become grabbed.
+ *
+ * This sets or clears the V4L2_CTRL_FLAG_GRABBED flag atomically.
+ * Does nothing if @ctrl == NULL.
+ * This will usually be called when starting or stopping streaming in the
+ * driver.
+ *
+ * This function can be called regardless of whether the control handler
+ * is locked or not.
+ */
+void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
+
+/** v4l2_ctrl_lock() - Helper function to lock the handler
+ * associated with the control.
+ * @ctrl: The control to lock.
+ */
+static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
+{
+ mutex_lock(&ctrl->handler->lock);
+}
+
+/** v4l2_ctrl_lock() - Helper function to unlock the handler
+ * associated with the control.
+ * @ctrl: The control to unlock.
+ */
+static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl)
+{
+ mutex_unlock(&ctrl->handler->lock);
+}
+
+/** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver.
+ * @ctrl: The control.
+ *
+ * This returns the control's value safely by going through the control
+ * framework. This function will lock the control's handler, so it cannot be
+ * used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for integer type controls only.
+ */
+s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl);
+
+/** v4l2_ctrl_s_ctrl() - Helper function to set the control's value from within a driver.
+ * @ctrl: The control.
+ * @val: The new value.
+ *
+ * This set the control's new value safely by going through the control
+ * framework. This function will lock the control's handler, so it cannot be
+ * used from within the &v4l2_ctrl_ops functions.
+ *
+ * This function is for integer type controls only.
+ */
+int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val);
+
+
+/* Helpers for ioctl_ops. If hdl == NULL then they will all return -EINVAL. */
+int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc);
+int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm);
+int v4l2_g_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *ctrl);
+int v4l2_s_ctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_control *ctrl);
+int v4l2_g_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c);
+int v4l2_try_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c);
+int v4l2_s_ext_ctrls(struct v4l2_ctrl_handler *hdl, struct v4l2_ext_controls *c);
+
+/* Helpers for subdevices. If the associated ctrl_handler == NULL then they
+ will all return -EINVAL. */
+int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
+int v4l2_subdev_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm);
+int v4l2_subdev_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs);
+int v4l2_subdev_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs);
+int v4l2_subdev_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *cs);
+int v4l2_subdev_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+int v4l2_subdev_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+
+#endif
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index bebe44b03e0f..1efcacbed01a 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -27,6 +27,7 @@
struct v4l2_ioctl_callbacks;
struct video_device;
struct v4l2_device;
+struct v4l2_ctrl_handler;
/* Flag to mark the video_device struct as registered.
Drivers can clear this flag if they want to block all future
@@ -67,6 +68,9 @@ struct video_device
struct device *parent; /* device parent */
struct v4l2_device *v4l2_dev; /* v4l2_device parent */
+ /* Control handler associated with this device node. May be NULL. */
+ struct v4l2_ctrl_handler *ctrl_handler;
+
/* device info */
char name[32];
int vfl_type;
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index 5d5d550e63ad..8bcbd7a0271c 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -32,6 +32,8 @@
#define V4L2_DEVICE_NAME_SIZE (20 + 16)
+struct v4l2_ctrl_handler;
+
struct v4l2_device {
/* dev->driver_data points to this struct.
Note: dev might be NULL if there is no parent device
@@ -47,6 +49,8 @@ struct v4l2_device {
/* notify callback called by some sub-devices. */
void (*notify)(struct v4l2_subdev *sd,
unsigned int notification, void *arg);
+ /* The control handler. May be NULL. */
+ struct v4l2_ctrl_handler *ctrl_handler;
};
/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev.
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 02c6f4d11ed3..4a97d7341a94 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -35,6 +35,7 @@
#define V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ 0x00000001
struct v4l2_device;
+struct v4l2_ctrl_handler;
struct v4l2_subdev;
struct tuner_setup;
@@ -90,10 +91,31 @@ struct v4l2_decode_vbi_line {
not yet implemented) since ops provide proper type-checking.
*/
+/* Subdevice external IO pin configuration */
+#define V4L2_SUBDEV_IO_PIN_DISABLE (1 << 0) /* ENABLE assumed */
+#define V4L2_SUBDEV_IO_PIN_OUTPUT (1 << 1)
+#define V4L2_SUBDEV_IO_PIN_INPUT (1 << 2)
+#define V4L2_SUBDEV_IO_PIN_SET_VALUE (1 << 3) /* Set output value */
+#define V4L2_SUBDEV_IO_PIN_ACTIVE_LOW (1 << 4) /* ACTIVE HIGH assumed */
+
+struct v4l2_subdev_io_pin_config {
+ u32 flags; /* V4L2_SUBDEV_IO_PIN_* flags for this pin's config */
+ u8 pin; /* Chip external IO pin to configure */
+ u8 function; /* Internal signal pad/function to route to IO pin */
+ u8 value; /* Initial value for pin - e.g. GPIO output value */
+ u8 strength; /* Pin drive strength */
+};
+
/* s_config: if set, then it is always called by the v4l2_i2c_new_subdev*
functions after the v4l2_subdev was registered. It is used to pass
platform data to the subdev which can be used during initialization.
+ s_io_pin_config: configure one or more chip I/O pins for chips that
+ multiplex different internal signal pads out to IO pins. This function
+ takes a pointer to an array of 'n' pin configuration entries, one for
+ each pin being configured. This function could be called at times
+ other than just subdevice initialization.
+
init: initialize the sensor registors to some sort of reasonable default
values. Do not use for new drivers and should be removed in existing
drivers.
@@ -110,11 +132,18 @@ struct v4l2_decode_vbi_line {
s_power: puts subdevice in power saving mode (on == 0) or normal operation
mode (on == 1).
+
+ interrupt_service_routine: Called by the bridge chip's interrupt service
+ handler, when an interrupt status has be raised due to this subdev,
+ so that this subdev can handle the details. It may schedule work to be
+ performed later. It must not sleep. *Called from an IRQ context*.
*/
struct v4l2_subdev_core_ops {
int (*g_chip_ident)(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip);
int (*log_status)(struct v4l2_subdev *sd);
int (*s_config)(struct v4l2_subdev *sd, int irq, void *platform_data);
+ int (*s_io_pin_config)(struct v4l2_subdev *sd, size_t n,
+ struct v4l2_subdev_io_pin_config *pincfg);
int (*init)(struct v4l2_subdev *sd, u32 val);
int (*load_fw)(struct v4l2_subdev *sd);
int (*reset)(struct v4l2_subdev *sd, u32 val);
@@ -133,6 +162,8 @@ struct v4l2_subdev_core_ops {
int (*s_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg);
#endif
int (*s_power)(struct v4l2_subdev *sd, int on);
+ int (*interrupt_service_routine)(struct v4l2_subdev *sd,
+ u32 status, bool *handled);
};
/* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio.
@@ -307,11 +338,6 @@ struct v4l2_subdev_sensor_ops {
};
/*
- interrupt_service_routine: Called by the bridge chip's interrupt service
- handler, when an IR interrupt status has be raised due to this subdev,
- so that this subdev can handle the details. It may schedule work to be
- performed later. It must not sleep. *Called from an IRQ context*.
-
[rt]x_g_parameters: Get the current operating parameters and state of the
the IR receiver or transmitter.
@@ -335,14 +361,9 @@ struct v4l2_subdev_sensor_ops {
*/
enum v4l2_subdev_ir_mode {
- V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, /* space & mark widths in nanosecs */
+ V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, /* uses struct ir_raw_event records */
};
-/* Data format of data read or written for V4L2_SUBDEV_IR_MODE_PULSE_WIDTH */
-#define V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS 0x7fffffff
-#define V4L2_SUBDEV_IR_PULSE_LEVEL_MASK 0x80000000
-#define V4L2_SUBDEV_IR_PULSE_RX_SEQ_END 0xffffffff
-
struct v4l2_subdev_ir_parameters {
/* Either Rx or Tx */
unsigned int bytes_per_data_element; /* of data in read or write call */
@@ -356,7 +377,10 @@ struct v4l2_subdev_ir_parameters {
u32 max_pulse_width; /* ns, valid only for baseband signal */
unsigned int carrier_freq; /* Hz, valid only for modulated signal*/
unsigned int duty_cycle; /* percent, valid only for modulated signal*/
- bool invert; /* logically invert sense of mark/space */
+ bool invert_level; /* invert signal level */
+
+ /* Tx only */
+ bool invert_carrier_sense; /* Send 0/space as a carrier burst */
/* Rx only */
u32 noise_filter_min_width; /* ns, min time of a valid pulse */
@@ -366,10 +390,6 @@ struct v4l2_subdev_ir_parameters {
};
struct v4l2_subdev_ir_ops {
- /* Common to receiver and transmitter */
- int (*interrupt_service_routine)(struct v4l2_subdev *sd,
- u32 status, bool *handled);
-
/* Receiver */
int (*rx_read)(struct v4l2_subdev *sd, u8 *buf, size_t count,
ssize_t *num);
@@ -415,6 +435,8 @@ struct v4l2_subdev {
u32 flags;
struct v4l2_device *v4l2_dev;
const struct v4l2_subdev_ops *ops;
+ /* The control handler of this subdev. May be NULL. */
+ struct v4l2_ctrl_handler *ctrl_handler;
/* name must be unique */
char name[V4L2_SUBDEV_NAME_SIZE];
/* can be used to group similar subdevs, value is driver-specific */