diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 15:09:54 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-10 15:09:54 -0700 |
commit | 7ae0dea900b027cd90e8a3e14deca9a19e17638b (patch) | |
tree | 428cbe411bba90f6580ae21338276c949e91f23a /include | |
parent | 6c74700fdb8e3bc34c31790384a8ec16c4fefd97 (diff) | |
parent | 560afa7d85bdfb294506afd3032c315e6827824f (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.h | 1 | ||||
-rw-r--r-- | include/media/cx2341x.h | 97 | ||||
-rw-r--r-- | include/media/cx25840.h | 87 | ||||
-rw-r--r-- | include/media/ir-core.h | 41 | ||||
-rw-r--r-- | include/media/lirc.h | 5 | ||||
-rw-r--r-- | include/media/rc-map.h | 1 | ||||
-rw-r--r-- | include/media/v4l2-ctrls.h | 460 | ||||
-rw-r--r-- | include/media/v4l2-dev.h | 4 | ||||
-rw-r--r-- | include/media/v4l2-device.h | 4 | ||||
-rw-r--r-- | include/media/v4l2-subdev.h | 54 |
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 */ |