diff options
Diffstat (limited to 'include/media')
27 files changed, 1503 insertions, 187 deletions
diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h index 9ebe855..8d08ebf 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 0b0cb17..46d1a14 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 ad1303f..6dc37fa 100644 --- a/include/media/ir-core.h +++ b/include/media/ir-core.h @@ -41,21 +41,51 @@ 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 * is opened. * @close: callback to allow drivers to disable polling/irq when IR input device * 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 + * @s_carrier_report: enable carrier reports */ struct ir_dev_props { enum rc_driver_type driver_type; unsigned long allowed_protos; u32 scanmask; - void *priv; + + 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, bool enable); + int (*s_learning_mode)(void *priv, int enable); + int (*s_carrier_report) (void *priv, int enable); }; struct ir_input_dev { @@ -63,9 +93,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 */ @@ -89,12 +120,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; @@ -104,8 +135,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) @@ -124,23 +159,54 @@ void ir_input_unregister(struct input_dev *input_dev); void ir_repeat(struct input_dev *dev); void ir_keydown(struct input_dev *dev, int scancode, u8 toggle); +void ir_keyup(struct ir_input_dev *ir); u32 ir_g_keycode_from_table(struct input_dev *input_dev, u32 scancode); /* From ir-raw-event.c */ struct ir_raw_event { - unsigned pulse:1; - unsigned duration:31; + union { + u32 duration; + + struct { + u32 carrier; + u8 duty_cycle; + }; + }; + + unsigned pulse:1; + unsigned reset:1; + unsigned timeout:1; + unsigned carrier_report:1; }; -#define IR_MAX_DURATION 0x7FFFFFFF /* a bit more than 2 seconds */ +#define DEFINE_IR_RAW_EVENT(event) \ + struct ir_raw_event event = { \ + { .duration = 0 } , \ + .pulse = 0, \ + .reset = 0, \ + .timeout = 0, \ + .carrier_report = 0 } + +static inline void init_ir_raw_event(struct ir_raw_event *ev) +{ + memset(ev, 0, sizeof(*ev)); +} + +#define IR_MAX_DURATION 0xFFFFFFFF /* a bit more than 4 seconds */ 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, bool idle); + static inline void ir_raw_event_reset(struct input_dev *input_dev) { - struct ir_raw_event ev = { .pulse = false, .duration = 0 }; + DEFINE_IR_RAW_EVENT(ev); + ev.reset = true; + ir_raw_event_store(input_dev, &ev); ir_raw_event_handle(input_dev); } diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h index 0506e45..557c676 100644 --- a/include/media/ir-kbd-i2c.h +++ b/include/media/ir-kbd-i2c.h @@ -3,6 +3,8 @@ #include <media/ir-common.h> +#define DEFAULT_POLLING_INTERVAL 100 /* ms */ + struct IR_i2c; struct IR_i2c { @@ -11,10 +13,12 @@ struct IR_i2c { struct i2c_client *c; struct input_dev *input; struct ir_input_state ir; - + u64 ir_type; /* Used to avoid fast repeating */ unsigned char old; + u32 polling_interval; /* in ms */ + struct delayed_work work; char name[32]; char phys[32]; @@ -24,7 +28,6 @@ struct IR_i2c { enum ir_kbd_get_key_fn { IR_KBD_GET_KEY_CUSTOM = 0, IR_KBD_GET_KEY_PIXELVIEW, - IR_KBD_GET_KEY_PV951, IR_KBD_GET_KEY_HAUP, IR_KBD_GET_KEY_KNC1, IR_KBD_GET_KEY_FUSIONHDTV, @@ -35,8 +38,9 @@ enum ir_kbd_get_key_fn { /* Can be passed when instantiating an ir_video i2c device */ struct IR_i2c_init_data { char *ir_codes; - const char *name; - u64 type; /* IR_TYPE_RC5, etc */ + const char *name; + u64 type; /* IR_TYPE_RC5, etc */ + u32 polling_interval; /* 0 means DEFAULT_POLLING_INTERVAL */ /* * Specify either a function pointer or a value indicating one of * ir_kbd_i2c's internal get_key functions diff --git a/include/media/lirc.h b/include/media/lirc.h new file mode 100644 index 0000000..6678a169 --- /dev/null +++ b/include/media/lirc.h @@ -0,0 +1,168 @@ +/* + * lirc.h - linux infrared remote control header file + * last modified 2010/07/13 by Jarod Wilson + */ + +#ifndef _LINUX_LIRC_H +#define _LINUX_LIRC_H + +#include <linux/types.h> +#include <linux/ioctl.h> + +#define PULSE_BIT 0x01000000 +#define PULSE_MASK 0x00FFFFFF + +#define LIRC_MODE2_SPACE 0x00000000 +#define LIRC_MODE2_PULSE 0x01000000 +#define LIRC_MODE2_FREQUENCY 0x02000000 +#define LIRC_MODE2_TIMEOUT 0x03000000 + +#define LIRC_VALUE_MASK 0x00FFFFFF +#define LIRC_MODE2_MASK 0xFF000000 + +#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE) +#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE) +#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY) +#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT) + +#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK) +#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK) + +#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE) +#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE) +#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY) +#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT) + +/* used heavily by lirc userspace */ +#define lirc_t int + +/*** lirc compatible hardware features ***/ + +#define LIRC_MODE2SEND(x) (x) +#define LIRC_SEND2MODE(x) (x) +#define LIRC_MODE2REC(x) ((x) << 16) +#define LIRC_REC2MODE(x) ((x) >> 16) + +#define LIRC_MODE_RAW 0x00000001 +#define LIRC_MODE_PULSE 0x00000002 +#define LIRC_MODE_MODE2 0x00000004 +#define LIRC_MODE_LIRCCODE 0x00000010 + + +#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) +#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) +#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) +#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) + +#define LIRC_CAN_SEND_MASK 0x0000003f + +#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 +#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 +#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 + +#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) +#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) +#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) +#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) + +#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) + +#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) +#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) + +#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 +#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 +#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 +#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000 +#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) + +#define LIRC_CAN_NOTIFY_DECODE 0x01000000 + +/*** IOCTL commands for lirc driver ***/ + +#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32) + +#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32) +#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32) +#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32) +#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32) +#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32) +#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32) +#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32) + +#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, __u32) +#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, __u32) + +#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, __u32) +#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, __u32) +#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, __u32) +#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, __u32) + +/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ +#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32) + +#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32) +#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32) +/* Note: these can reset the according pulse_width */ +#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32) +#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32) +#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32) +#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32) +#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32) + +/* + * when a timeout != 0 is set the driver will send a + * LIRC_MODE2_TIMEOUT data packet, otherwise LIRC_MODE2_TIMEOUT is + * never sent, timeout is disabled by default + */ +#define LIRC_SET_REC_TIMEOUT _IOW('i', 0x00000018, __u32) + +/* 1 enables, 0 disables timeout reports in MODE2 */ +#define LIRC_SET_REC_TIMEOUT_REPORTS _IOW('i', 0x00000019, __u32) + +/* + * pulses shorter than this are filtered out by hardware (software + * emulation in lirc_dev?) + */ +#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x0000001a, __u32) +/* + * spaces shorter than this are filtered out by hardware (software + * emulation in lirc_dev?) + */ +#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001b, __u32) +/* + * if filter cannot be set independantly for pulse/space, this should + * be used + */ +#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001c, __u32) + +/* + * 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) + +/* + * to set a range use + * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the + * lower bound first and later + * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound + */ + +#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32) +#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32) + +#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) + +#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/lirc_dev.h b/include/media/lirc_dev.h new file mode 100644 index 0000000..54780a5 --- /dev/null +++ b/include/media/lirc_dev.h @@ -0,0 +1,225 @@ +/* + * LIRC base driver + * + * by Artur Lipowski <alipowski@interia.pl> + * This code is licensed under GNU GPL + * + */ + +#ifndef _LINUX_LIRC_DEV_H +#define _LINUX_LIRC_DEV_H + +#define MAX_IRCTL_DEVICES 4 +#define BUFLEN 16 + +#define mod(n, div) ((n) % (div)) + +#include <linux/slab.h> +#include <linux/fs.h> +#include <linux/ioctl.h> +#include <linux/poll.h> +#include <linux/kfifo.h> +#include <media/lirc.h> + +struct lirc_buffer { + wait_queue_head_t wait_poll; + spinlock_t fifo_lock; + unsigned int chunk_size; + unsigned int size; /* in chunks */ + /* Using chunks instead of bytes pretends to simplify boundary checking + * And should allow for some performance fine tunning later */ + struct kfifo fifo; + u8 fifo_initialized; +}; + +static inline void lirc_buffer_clear(struct lirc_buffer *buf) +{ + unsigned long flags; + + if (buf->fifo_initialized) { + spin_lock_irqsave(&buf->fifo_lock, flags); + kfifo_reset(&buf->fifo); + spin_unlock_irqrestore(&buf->fifo_lock, flags); + } else + WARN(1, "calling %s on an uninitialized lirc_buffer\n", + __func__); +} + +static inline int lirc_buffer_init(struct lirc_buffer *buf, + unsigned int chunk_size, + unsigned int size) +{ + int ret; + + init_waitqueue_head(&buf->wait_poll); + spin_lock_init(&buf->fifo_lock); + buf->chunk_size = chunk_size; + buf->size = size; + ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL); + if (ret == 0) + buf->fifo_initialized = 1; + + return ret; +} + +static inline void lirc_buffer_free(struct lirc_buffer *buf) +{ + if (buf->fifo_initialized) { + kfifo_free(&buf->fifo); + buf->fifo_initialized = 0; + } else + WARN(1, "calling %s on an uninitialized lirc_buffer\n", + __func__); +} + +static inline int lirc_buffer_len(struct lirc_buffer *buf) +{ + int len; + unsigned long flags; + + spin_lock_irqsave(&buf->fifo_lock, flags); + len = kfifo_len(&buf->fifo); + spin_unlock_irqrestore(&buf->fifo_lock, flags); + + return len; +} + +static inline int lirc_buffer_full(struct lirc_buffer *buf) +{ + return lirc_buffer_len(buf) == buf->size * buf->chunk_size; +} + +static inline int lirc_buffer_empty(struct lirc_buffer *buf) +{ + return !lirc_buffer_len(buf); +} + +static inline int lirc_buffer_available(struct lirc_buffer *buf) +{ + return buf->size - (lirc_buffer_len(buf) / buf->chunk_size); +} + +static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf, + unsigned char *dest) +{ + unsigned int ret = 0; + + if (lirc_buffer_len(buf) >= buf->chunk_size) + ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size, + &buf->fifo_lock); + return ret; + +} + +static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf, + unsigned char *orig) +{ + unsigned int ret; + + ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size, + &buf->fifo_lock); + + return ret; +} + +struct lirc_driver { + char name[40]; + int minor; + __u32 code_length; + unsigned int buffer_size; /* in chunks holding one code each */ + int sample_rate; + __u32 features; + + unsigned int chunk_size; + + void *data; + int min_timeout; + int max_timeout; + int (*add_to_buf) (void *data, struct lirc_buffer *buf); + struct lirc_buffer *rbuf; + int (*set_use_inc) (void *data); + void (*set_use_dec) (void *data); + const struct file_operations *fops; + struct device *dev; + struct module *owner; +}; + +/* name: + * this string will be used for logs + * + * minor: + * indicates minor device (/dev/lirc) number for registered driver + * if caller fills it with negative value, then the first free minor + * number will be used (if available) + * + * code_length: + * length of the remote control key code expressed in bits + * + * sample_rate: + * + * data: + * it may point to any driver data and this pointer will be passed to + * all callback functions + * + * add_to_buf: + * add_to_buf will be called after specified period of the time or + * triggered by the external event, this behavior depends on value of + * the sample_rate this function will be called in user context. This + * routine should return 0 if data was added to the buffer and + * -ENODATA if none was available. This should add some number of bits + * evenly divisible by code_length to the buffer + * + * rbuf: + * if not NULL, it will be used as a read buffer, you will have to + * write to the buffer by other means, like irq's (see also + * lirc_serial.c). + * + * set_use_inc: + * set_use_inc will be called after device is opened + * + * set_use_dec: + * set_use_dec will be called after device is closed + * + * fops: + * file_operations for drivers which don't fit the current driver model. + * + * Some ioctl's can be directly handled by lirc_dev if the driver's + * ioctl function is NULL or if it returns -ENOIOCTLCMD (see also + * lirc_serial.c). + * + * owner: + * the module owning this struct + * + */ + + +/* following functions can be called ONLY from user context + * + * returns negative value on error or minor number + * of the registered device if success + * contents of the structure pointed by p is copied + */ +extern int lirc_register_driver(struct lirc_driver *d); + +/* returns negative value on error or 0 if success +*/ +extern int lirc_unregister_driver(int minor); + +/* Returns the private data stored in the lirc_driver + * associated with the given device file pointer. + */ +void *lirc_get_pdata(struct file *file); + +/* default file operations + * used by drivers if they override only some operations + */ +int lirc_dev_fop_open(struct inode *inode, struct file *file); +int lirc_dev_fop_close(struct inode *inode, struct file *file); +unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait); +long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +ssize_t lirc_dev_fop_read(struct file *file, char *buffer, size_t length, + loff_t *ppos); +ssize_t lirc_dev_fop_write(struct file *file, const char *buffer, size_t length, + loff_t *ppos); + +#endif diff --git a/include/media/omap1_camera.h b/include/media/omap1_camera.h new file mode 100644 index 0000000..819767c --- /dev/null +++ b/include/media/omap1_camera.h @@ -0,0 +1,35 @@ +/* + * Header for V4L2 SoC Camera driver for OMAP1 Camera Interface + * + * Copyright (C) 2010, Janusz Krzysztofik <jkrzyszt@tis.icnet.pl> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __MEDIA_OMAP1_CAMERA_H_ +#define __MEDIA_OMAP1_CAMERA_H_ + +#include <linux/bitops.h> + +#define OMAP1_CAMERA_IOSIZE 0x1c + +enum omap1_cam_vb_mode { + OMAP1_CAM_DMA_CONTIG = 0, + OMAP1_CAM_DMA_SG, +}; + +#define OMAP1_CAMERA_MIN_BUF_COUNT(x) ((x) == OMAP1_CAM_DMA_CONTIG ? 3 : 2) + +struct omap1_cam_platform_data { + unsigned long camexclk_khz; + unsigned long lclk_khz_max; + unsigned long flags; +}; + +#define OMAP1_CAMERA_LCLK_RISING BIT(0) +#define OMAP1_CAMERA_RST_LOW BIT(1) +#define OMAP1_CAMERA_RST_HIGH BIT(2) + +#endif /* __MEDIA_OMAP1_CAMERA_H_ */ diff --git a/include/media/rc-map.h b/include/media/rc-map.h index c78e99a..e0f17ed 100644 --- a/include/media/rc-map.h +++ b/include/media/rc-map.h @@ -17,8 +17,14 @@ #define IR_TYPE_RC6 (1 << 2) /* Philips RC6 protocol */ #define IR_TYPE_JVC (1 << 3) /* JVC protocol */ #define IR_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */ +#define IR_TYPE_RC5_SZ (1 << 5) /* RC5 variant used by Streamzap */ +#define IR_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */ #define IR_TYPE_OTHER (1u << 31) +#define IR_TYPE_ALL (IR_TYPE_RC5 | IR_TYPE_NEC | IR_TYPE_RC6 | \ + IR_TYPE_JVC | IR_TYPE_SONY | IR_TYPE_LIRC | \ + IR_TYPE_RC5_SZ | IR_TYPE_OTHER) + struct ir_scancode { u32 scancode; u32 keycode; @@ -30,7 +36,7 @@ struct ir_scancode_table { unsigned int len; /* Used number of entries */ unsigned int alloc; /* Size of *scan in bytes */ u64 ir_type; - char *name; + const char *name; spinlock_t lock; }; @@ -49,6 +55,8 @@ void rc_map_init(void); /* Names of the several keytables defined in-kernel */ #define RC_MAP_ADSTECH_DVB_T_PCI "rc-adstech-dvb-t-pci" +#define RC_MAP_ALINK_DTU_M "rc-alink-dtu-m" +#define RC_MAP_ANYSEE "rc-anysee" #define RC_MAP_APAC_VIEWCOMP "rc-apac-viewcomp" #define RC_MAP_ASUS_PC39 "rc-asus-pc39" #define RC_MAP_ATI_TV_WONDER_HD_600 "rc-ati-tv-wonder-hd-600" @@ -57,13 +65,19 @@ void rc_map_init(void); #define RC_MAP_AVERMEDIA_DVBT "rc-avermedia-dvbt" #define RC_MAP_AVERMEDIA_M135A "rc-avermedia-m135a" #define RC_MAP_AVERMEDIA_M733A_RM_K6 "rc-avermedia-m733a-rm-k6" +#define RC_MAP_AVERMEDIA_RM_KS "rc-avermedia-rm-ks" #define RC_MAP_AVERMEDIA "rc-avermedia" #define RC_MAP_AVERTV_303 "rc-avertv-303" +#define RC_MAP_AZUREWAVE_AD_TU700 "rc-azurewave-ad-tu700" #define RC_MAP_BEHOLD_COLUMBUS "rc-behold-columbus" #define RC_MAP_BEHOLD "rc-behold" #define RC_MAP_BUDGET_CI_OLD "rc-budget-ci-old" #define RC_MAP_CINERGY_1400 "rc-cinergy-1400" #define RC_MAP_CINERGY "rc-cinergy" +#define RC_MAP_DIB0700_NEC_TABLE "rc-dib0700-nec" +#define RC_MAP_DIB0700_RC5_TABLE "rc-dib0700-rc5" +#define RC_MAP_DIGITALNOW_TINYTWIN "rc-digitalnow-tinytwin" +#define RC_MAP_DIGITTRADE "rc-digittrade" #define RC_MAP_DM1105_NEC "rc-dm1105-nec" #define RC_MAP_DNTV_LIVE_DVBT_PRO "rc-dntv-live-dvbt-pro" #define RC_MAP_DNTV_LIVE_DVB_T "rc-dntv-live-dvb-t" @@ -87,7 +101,12 @@ void rc_map_init(void); #define RC_MAP_KAIOMY "rc-kaiomy" #define RC_MAP_KWORLD_315U "rc-kworld-315u" #define RC_MAP_KWORLD_PLUS_TV_ANALOG "rc-kworld-plus-tv-analog" +#define RC_MAP_LEADTEK_Y04G0051 "rc-leadtek-y04g0051" +#define RC_MAP_LIRC "rc-lirc" +#define RC_MAP_LME2510 "rc-lme2510" #define RC_MAP_MANLI "rc-manli" +#define RC_MAP_MSI_DIGIVOX_II "rc-msi-digivox-ii" +#define RC_MAP_MSI_DIGIVOX_III "rc-msi-digivox-iii" #define RC_MAP_MSI_TVANYWHERE_PLUS "rc-msi-tvanywhere-plus" #define RC_MAP_MSI_TVANYWHERE "rc-msi-tvanywhere" #define RC_MAP_NEBULA "rc-nebula" @@ -107,15 +126,22 @@ void rc_map_init(void); #define RC_MAP_PV951 "rc-pv951" #define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new" #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" +#define RC_MAP_STREAMZAP "rc-streamzap" #define RC_MAP_TBS_NEC "rc-tbs-nec" #define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs" +#define RC_MAP_TERRATEC_SLIM "rc-terratec-slim" #define RC_MAP_TEVII_NEC "rc-tevii-nec" +#define RC_MAP_TOTAL_MEDIA_IN_HAND "rc-total-media-in-hand" +#define RC_MAP_TREKSTOR "rc-trekstor" #define RC_MAP_TT_1500 "rc-tt-1500" +#define RC_MAP_TWINHAN_VP1027_DVBS "rc-twinhan1027" #define RC_MAP_VIDEOMATE_S350 "rc-videomate-s350" #define RC_MAP_VIDEOMATE_TV_PVR "rc-videomate-tv-pvr" #define RC_MAP_WINFAST "rc-winfast" #define RC_MAP_WINFAST_USBII_DELUXE "rc-winfast-usbii-deluxe" + /* * Please, do not just append newer Remote Controller names at the end. * The names should be ordered in alphabetical order diff --git a/include/media/s3c_fimc.h b/include/media/s3c_fimc.h new file mode 100644 index 0000000..ca1b673 --- /dev/null +++ b/include/media/s3c_fimc.h @@ -0,0 +1,60 @@ +/* + * Samsung S5P SoC camera interface driver header + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd + * Author: Sylwester Nawrocki, <s.nawrocki@samsung.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef S3C_FIMC_H_ +#define S3C_FIMC_H_ + +enum cam_bus_type { + FIMC_ITU_601 = 1, + FIMC_ITU_656, + FIMC_MIPI_CSI2, + FIMC_LCD_WB, /* FIFO link from LCD mixer */ +}; + +#define FIMC_CLK_INV_PCLK (1 << 0) +#define FIMC_CLK_INV_VSYNC (1 << 1) +#define FIMC_CLK_INV_HREF (1 << 2) +#define FIMC_CLK_INV_HSYNC (1 << 3) + +struct i2c_board_info; + +/** + * struct s3c_fimc_isp_info - image sensor information required for host + * interace configuration. + * + * @board_info: pointer to I2C subdevice's board info + * @bus_type: determines bus type, MIPI, ITU-R BT.601 etc. + * @i2c_bus_num: i2c control bus id the sensor is attached to + * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU) + * @bus_width: camera data bus width in bits + * @flags: flags defining bus signals polarity inversion (High by default) + */ +struct s3c_fimc_isp_info { + struct i2c_board_info *board_info; + enum cam_bus_type bus_type; + u16 i2c_bus_num; + u16 mux_id; + u16 bus_width; + u16 flags; +}; + + +#define FIMC_MAX_CAMIF_CLIENTS 2 + +/** + * struct s3c_platform_fimc - camera host interface platform data + * + * @isp_info: properties of camera sensor required for host interface setup + */ +struct s3c_platform_fimc { + struct s3c_fimc_isp_info *isp_info[FIMC_MAX_CAMIF_CLIENTS]; +}; +#endif /* S3C_FIMC_H_ */ diff --git a/include/media/sh_mobile_ceu.h b/include/media/sh_mobile_ceu.h index b677478..80346a6 100644 --- a/include/media/sh_mobile_ceu.h +++ b/include/media/sh_mobile_ceu.h @@ -6,8 +6,11 @@ #define SH_CEU_FLAG_HSYNC_LOW (1 << 2) /* default High if possible */ #define SH_CEU_FLAG_VSYNC_LOW (1 << 3) /* default High if possible */ +struct device; + struct sh_mobile_ceu_info { unsigned long flags; + struct device *csi2_dev; }; #endif /* __ASM_SH_MOBILE_CEU_H__ */ diff --git a/include/media/sh_mobile_csi2.h b/include/media/sh_mobile_csi2.h new file mode 100644 index 0000000..4d26151 --- /dev/null +++ b/include/media/sh_mobile_csi2.h @@ -0,0 +1,46 @@ +/* + * Driver header for the SH-Mobile MIPI CSI-2 unit + * + * Copyright (C) 2010, Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef SH_MIPI_CSI +#define SH_MIPI_CSI + +enum sh_csi2_phy { + SH_CSI2_PHY_MAIN, + SH_CSI2_PHY_SUB, +}; + +enum sh_csi2_type { + SH_CSI2C, + SH_CSI2I, +}; + +#define SH_CSI2_CRC (1 << 0) +#define SH_CSI2_ECC (1 << 1) + +struct platform_device; + +struct sh_csi2_client_config { + enum sh_csi2_phy phy; + unsigned char lanes; /* bitmask[3:0] */ + unsigned char channel; /* 0..3 */ + struct platform_device *pdev; /* client platform device */ +}; + +struct sh_csi2_pdata { + enum sh_csi2_type type; + unsigned int flags; + struct sh_csi2_client_config *clients; + int num_clients; +}; + +struct device; +struct v4l2_device; + +#endif diff --git a/include/media/sh_vou.h b/include/media/sh_vou.h index a3ef302..ec3ba9a 100644 --- a/include/media/sh_vou.h +++ b/include/media/sh_vou.h @@ -28,7 +28,6 @@ struct sh_vou_pdata { int i2c_adap; struct i2c_board_info *board_info; unsigned long flags; - char *module_name; }; #endif diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index b8289c2..86e3631 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -12,12 +12,17 @@ #ifndef SOC_CAMERA_H #define SOC_CAMERA_H +#include <linux/device.h> #include <linux/mutex.h> #include <linux/pm.h> #include <linux/videodev2.h> #include <media/videobuf-core.h> #include <media/v4l2-device.h> +extern struct bus_type soc_camera_bus_type; + +struct file; + struct soc_camera_device { struct list_head list; struct device dev; @@ -38,10 +43,7 @@ struct soc_camera_device { /* soc_camera.c private count. Only accessed with .video_lock held */ int use_count; struct mutex video_lock; /* Protects device data */ -}; - -struct soc_camera_file { - struct soc_camera_device *icd; + struct file *streamer; /* stream owner */ struct videobuf_queue vb_vidq; }; @@ -76,7 +78,7 @@ struct soc_camera_host_ops { int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); void (*init_videobuf)(struct videobuf_queue *, struct soc_camera_device *); - int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); + int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *); int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); int (*set_bus_param)(struct soc_camera_device *, __u32); int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *); diff --git a/include/media/sr030pc30.h b/include/media/sr030pc30.h new file mode 100644 index 0000000..6f901a6 --- /dev/null +++ b/include/media/sr030pc30.h @@ -0,0 +1,21 @@ +/* + * Driver header for SR030PC30 camera sensor + * + * Copyright (c) 2010 Samsung Electronics, Co. Ltd + * Contact: Sylwester Nawrocki <s.nawrocki@samsung.com> + * + * 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. + */ + +#ifndef SR030PC30_H +#define SR030PC30_H + +struct sr030pc30_platform_data { + unsigned long clk_rate; /* master clock frequency in Hz */ + int (*set_power)(struct device *dev, int on); +}; + +#endif /* SR030PC30_H */ diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h index 21b4428..51e89f2 100644 --- a/include/media/v4l2-chip-ident.h +++ b/include/media/v4l2-chip-ident.h @@ -38,6 +38,9 @@ enum { /* module tvaudio: reserved range 50-99 */ V4L2_IDENT_TVAUDIO = 50, /* A tvaudio chip, unknown which it is exactly */ + /* Sony IMX074 */ + V4L2_IDENT_IMX074 = 74, + /* module saa7110: just ident 100 */ V4L2_IDENT_SAA7110 = 100, @@ -70,6 +73,7 @@ enum { V4L2_IDENT_OV9655 = 255, V4L2_IDENT_SOI968 = 256, V4L2_IDENT_OV9640 = 257, + V4L2_IDENT_OV6650 = 258, /* module saa7146: reserved range 300-309 */ V4L2_IDENT_SAA7146 = 300, @@ -111,6 +115,10 @@ enum { V4L2_IDENT_VPX3216B = 3216, V4L2_IDENT_VPX3220A = 3220, + /* VX855 just ident 3409 */ + /* Other via devs could use 3314, 3324, 3327, 3336, 3364, 3353 */ + V4L2_IDENT_VIA_VX855 = 3409, + /* module tvp5150 */ V4L2_IDENT_TVP5150 = 5150, diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h index 98b3264..41dd480 100644 --- a/include/media/v4l2-common.h +++ b/include/media/v4l2-common.h @@ -232,4 +232,14 @@ void v4l_bound_align_image(unsigned int *w, unsigned int wmin, unsigned int hmax, unsigned int halign, unsigned int salign); int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info); + +struct v4l2_discrete_probe { + const struct v4l2_frmsize_discrete *sizes; + int num_sizes; +}; + +const struct v4l2_frmsize_discrete *v4l2_find_nearest_format( + const struct v4l2_discrete_probe *probe, + s32 width, s32 height); + #endif /* V4L2_COMMON_H_ */ diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h new file mode 100644 index 0000000..9b7bea9 --- /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 bebe44b..15802a0 100644 --- a/include/media/v4l2-dev.h +++ b/include/media/v4l2-dev.h @@ -21,12 +21,12 @@ #define VFL_TYPE_GRABBER 0 #define VFL_TYPE_VBI 1 #define VFL_TYPE_RADIO 2 -#define VFL_TYPE_VTX 3 -#define VFL_TYPE_MAX 4 +#define VFL_TYPE_MAX 3 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 @@ -41,8 +41,6 @@ struct v4l2_file_operations { unsigned int (*poll) (struct file *, struct poll_table_struct *); long (*ioctl) (struct file *, unsigned int, unsigned long); long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); - unsigned long (*get_unmapped_area) (struct file *, unsigned long, - unsigned long, unsigned long, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct file *); int (*release) (struct file *); @@ -67,6 +65,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; @@ -93,6 +94,9 @@ struct video_device /* ioctl callbacks */ const struct v4l2_ioctl_ops *ioctl_ops; + + /* serialization lock */ + struct mutex *lock; }; /* dev to video-device */ diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index 5d5d550..6648036 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. @@ -97,46 +101,67 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); /* Call the specified callback for all subdevs matching the condition. Ignore any errors. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \ +#define __v4l2_device_call_subdevs_p(v4l2_dev, sd, cond, o, f, args...) \ do { \ - struct v4l2_subdev *sd; \ + list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) \ + if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ + (sd)->ops->o->f((sd) , ##args); \ + } while (0) + +#define __v4l2_device_call_subdevs(v4l2_dev, cond, o, f, args...) \ + do { \ + struct v4l2_subdev *__sd; \ \ - list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) \ - if ((cond) && sd->ops->o && sd->ops->o->f) \ - sd->ops->o->f(sd , ##args); \ + __v4l2_device_call_subdevs_p(v4l2_dev, __sd, cond, o, \ + f , ##args); \ } while (0) /* Call the specified callback for all subdevs matching the condition. If the callback returns an error other than 0 or -ENOIOCTLCMD, then return with that error code. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \ +#define __v4l2_device_call_subdevs_until_err_p(v4l2_dev, sd, cond, o, f, args...) \ ({ \ - struct v4l2_subdev *sd; \ - long err = 0; \ + long __err = 0; \ \ - list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) { \ - if ((cond) && sd->ops->o && sd->ops->o->f) \ - err = sd->ops->o->f(sd , ##args); \ - if (err && err != -ENOIOCTLCMD) \ + list_for_each_entry((sd), &(v4l2_dev)->subdevs, list) { \ + if ((cond) && (sd)->ops->o && (sd)->ops->o->f) \ + __err = (sd)->ops->o->f((sd) , ##args); \ + if (__err && __err != -ENOIOCTLCMD) \ break; \ } \ - (err == -ENOIOCTLCMD) ? 0 : err; \ + (__err == -ENOIOCTLCMD) ? 0 : __err; \ +}) + +#define __v4l2_device_call_subdevs_until_err(v4l2_dev, cond, o, f, args...) \ +({ \ + struct v4l2_subdev *__sd; \ + __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o, \ + f, args...); \ }) /* Call the specified callback for all subdevs matching grp_id (if 0, then match them all). Ignore any errors. Note that you cannot add or delete a subdev while walking the subdevs list. */ -#define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \ - __v4l2_device_call_subdevs(v4l2_dev, \ - !(grpid) || sd->grp_id == (grpid), o, f , ##args) +#define v4l2_device_call_all(v4l2_dev, grpid, o, f, args...) \ + do { \ + struct v4l2_subdev *__sd; \ + \ + __v4l2_device_call_subdevs_p(v4l2_dev, __sd, \ + !(grpid) || __sd->grp_id == (grpid), o, f , \ + ##args); \ + } while (0) /* Call the specified callback for all subdevs matching grp_id (if 0, then match them all). If the callback returns an error other than 0 or -ENOIOCTLCMD, then return with that error code. Note that you cannot add or delete a subdev while walking the subdevs list. */ #define v4l2_device_call_until_err(v4l2_dev, grpid, o, f, args...) \ - __v4l2_device_call_subdevs_until_err(v4l2_dev, \ - !(grpid) || sd->grp_id == (grpid), o, f , ##args) +({ \ + struct v4l2_subdev *__sd; \ + __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, \ + !(grpid) || __sd->grp_id == (grpid), o, f , \ + ##args); \ +}) #endif diff --git a/include/media/v4l2-i2c-drv.h b/include/media/v4l2-i2c-drv.h deleted file mode 100644 index 74bf741..0000000 --- a/include/media/v4l2-i2c-drv.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * v4l2-i2c-drv.h - contains I2C handling code that's identical for - * all V4L2 I2C drivers. Use this header if the - * I2C driver is only used by drivers converted - * to the bus-based I2C API. - * - * Copyright (C) 2007 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* NOTE: the full version of this header is in the v4l-dvb repository - * and allows v4l i2c drivers to be compiled on pre-2.6.26 kernels. - * The version of this header as it appears in the kernel is a stripped - * version (without all the backwards compatibility stuff) and so it - * looks a bit odd. - * - * If you look at the full version then you will understand the reason - * for introducing this header since you really don't want to have all - * the tricky backwards compatibility code in each and every i2c driver. - * - * If the i2c driver will never be compiled for pre-2.6.26 kernels, then - * DO NOT USE this header! Just write it as a regular i2c driver. - */ - -#ifndef __V4L2_I2C_DRV_H__ -#define __V4L2_I2C_DRV_H__ - -#include <media/v4l2-common.h> - -struct v4l2_i2c_driver_data { - const char * const name; - int (*command)(struct i2c_client *client, unsigned int cmd, void *arg); - int (*probe)(struct i2c_client *client, const struct i2c_device_id *id); - int (*remove)(struct i2c_client *client); - int (*suspend)(struct i2c_client *client, pm_message_t state); - int (*resume)(struct i2c_client *client); - const struct i2c_device_id *id_table; -}; - -static struct v4l2_i2c_driver_data v4l2_i2c_data; -static struct i2c_driver v4l2_i2c_driver; - - -/* Bus-based I2C implementation for kernels >= 2.6.26 */ - -static int __init v4l2_i2c_drv_init(void) -{ - v4l2_i2c_driver.driver.name = v4l2_i2c_data.name; - v4l2_i2c_driver.command = v4l2_i2c_data.command; - v4l2_i2c_driver.probe = v4l2_i2c_data.probe; - v4l2_i2c_driver.remove = v4l2_i2c_data.remove; - v4l2_i2c_driver.suspend = v4l2_i2c_data.suspend; - v4l2_i2c_driver.resume = v4l2_i2c_data.resume; - v4l2_i2c_driver.id_table = v4l2_i2c_data.id_table; - return i2c_add_driver(&v4l2_i2c_driver); -} - - -static void __exit v4l2_i2c_drv_cleanup(void) -{ - i2c_del_driver(&v4l2_i2c_driver); -} - -module_init(v4l2_i2c_drv_init); -module_exit(v4l2_i2c_drv_cleanup); - -#endif /* __V4L2_I2C_DRV_H__ */ diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h index 865cda7..8e65598 100644 --- a/include/media/v4l2-mediabus.h +++ b/include/media/v4l2-mediabus.h @@ -24,14 +24,22 @@ */ enum v4l2_mbus_pixelcode { V4L2_MBUS_FMT_FIXED = 1, - V4L2_MBUS_FMT_YUYV8_2X8_LE, - V4L2_MBUS_FMT_YVYU8_2X8_LE, - V4L2_MBUS_FMT_YUYV8_2X8_BE, - V4L2_MBUS_FMT_YVYU8_2X8_BE, + V4L2_MBUS_FMT_YUYV8_2X8, + V4L2_MBUS_FMT_YVYU8_2X8, + V4L2_MBUS_FMT_UYVY8_2X8, + V4L2_MBUS_FMT_VYUY8_2X8, + V4L2_MBUS_FMT_YVYU10_2X10, + V4L2_MBUS_FMT_YUYV10_2X10, + V4L2_MBUS_FMT_YVYU10_1X20, + V4L2_MBUS_FMT_YUYV10_1X20, + V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE, + V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE, V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE, V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE, V4L2_MBUS_FMT_RGB565_2X8_LE, V4L2_MBUS_FMT_RGB565_2X8_BE, + V4L2_MBUS_FMT_BGR565_2X8_LE, + V4L2_MBUS_FMT_BGR565_2X8_BE, V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_GREY8_1X8, @@ -41,6 +49,11 @@ enum v4l2_mbus_pixelcode { V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE, V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE, V4L2_MBUS_FMT_SGRBG8_1X8, + V4L2_MBUS_FMT_SBGGR12_1X12, + V4L2_MBUS_FMT_YUYV8_1_5X8, + V4L2_MBUS_FMT_YVYU8_1_5X8, + V4L2_MBUS_FMT_UYVY8_1_5X8, + V4L2_MBUS_FMT_VYUY8_1_5X8, }; /** diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 02c6f4d..b0316a7 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. @@ -225,10 +256,6 @@ struct v4l2_subdev_video_ops { int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std); int (*g_input_status)(struct v4l2_subdev *sd, u32 *status); int (*s_stream)(struct v4l2_subdev *sd, int enable); - int (*enum_fmt)(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmtdesc); - int (*g_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); - int (*try_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); - int (*s_fmt)(struct v4l2_subdev *sd, struct v4l2_format *fmt); int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc); int (*g_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); @@ -307,11 +334,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 +357,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 +373,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 +386,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,22 +431,35 @@ 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 */ u32 grp_id; /* pointer to private data */ - void *priv; + void *dev_priv; + void *host_priv; }; static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p) { - sd->priv = p; + sd->dev_priv = p; } static inline void *v4l2_get_subdevdata(const struct v4l2_subdev *sd) { - return sd->priv; + return sd->dev_priv; +} + +static inline void v4l2_set_subdev_hostdata(struct v4l2_subdev *sd, void *p) +{ + sd->host_priv = p; +} + +static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd) +{ + return sd->host_priv; } static inline void v4l2_subdev_init(struct v4l2_subdev *sd, @@ -444,7 +473,8 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd, sd->flags = 0; sd->name[0] = '\0'; sd->grp_id = 0; - sd->priv = NULL; + sd->dev_priv = NULL; + sd->host_priv = NULL; } /* Call an ops of a v4l2_subdev, doing the right checks against diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h index f91a736..1d3835f 100644 --- a/include/media/videobuf-core.h +++ b/include/media/videobuf-core.h @@ -54,8 +54,6 @@ struct videobuf_queue; struct videobuf_mapping { unsigned int count; - unsigned long start; - unsigned long end; struct videobuf_queue *q; }; @@ -127,7 +125,7 @@ struct videobuf_queue_ops { struct videobuf_qtype_ops { u32 magic; - struct videobuf_buffer *(*alloc)(size_t size); + struct videobuf_buffer *(*alloc_vb)(size_t size); void *(*vaddr) (struct videobuf_buffer *buf); int (*iolock) (struct videobuf_queue *q, struct videobuf_buffer *vb, @@ -141,6 +139,7 @@ struct videobuf_qtype_ops { struct videobuf_queue { struct mutex vb_lock; + struct mutex *ext_lock; spinlock_t *irqlock; struct device *dev; @@ -169,11 +168,24 @@ struct videobuf_queue { void *priv_data; }; -int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr); +static inline void videobuf_queue_lock(struct videobuf_queue *q) +{ + if (!q->ext_lock) + mutex_lock(&q->vb_lock); +} + +static inline void videobuf_queue_unlock(struct videobuf_queue *q) +{ + if (!q->ext_lock) + mutex_unlock(&q->vb_lock); +} + +int videobuf_waiton(struct videobuf_queue *q, struct videobuf_buffer *vb, + int non_blocking, int intr); int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb, struct v4l2_framebuffer *fbuf); -struct videobuf_buffer *videobuf_alloc(struct videobuf_queue *q); +struct videobuf_buffer *videobuf_alloc_vb(struct videobuf_queue *q); /* Used on videobuf-dvb */ void *videobuf_queue_to_vaddr(struct videobuf_queue *q, @@ -187,7 +199,8 @@ void videobuf_queue_core_init(struct videobuf_queue *q, enum v4l2_field field, unsigned int msize, void *priv, - struct videobuf_qtype_ops *int_ops); + struct videobuf_qtype_ops *int_ops, + struct mutex *ext_lock); int videobuf_queue_is_busy(struct videobuf_queue *q); void videobuf_queue_cancel(struct videobuf_queue *q); diff --git a/include/media/videobuf-dma-contig.h b/include/media/videobuf-dma-contig.h index ebaa9bc..f0ed825 100644 --- a/include/media/videobuf-dma-contig.h +++ b/include/media/videobuf-dma-contig.h @@ -23,7 +23,8 @@ void videobuf_queue_dma_contig_init(struct videobuf_queue *q, enum v4l2_buf_type type, enum v4l2_field field, unsigned int msize, - void *priv); + void *priv, + struct mutex *ext_lock); dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); void videobuf_dma_contig_free(struct videobuf_queue *q, diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h index a195f3b..1c647e8 100644 --- a/include/media/videobuf-dma-sg.h +++ b/include/media/videobuf-dma-sg.h @@ -25,23 +25,6 @@ /* --------------------------------------------------------------------- */ /* - * Return a scatterlist for some page-aligned vmalloc()'ed memory - * block (NULL on errors). Memory for the scatterlist is allocated - * using kmalloc. The caller must free the memory. - */ -struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages); - -/* - * Return a scatterlist for a an array of userpages (NULL on errors). - * Memory for the scatterlist is allocated using kmalloc. The caller - * must free the memory. - */ -struct scatterlist *videobuf_pages_to_sg(struct page **pages, int nr_pages, - int offset); - -/* --------------------------------------------------------------------- */ - -/* * A small set of helper functions to manage buffers (both userland * and kernel) for DMA. * @@ -65,10 +48,11 @@ struct videobuf_dmabuf { /* for userland buffer */ int offset; + size_t size; struct page **pages; /* for kernel buffers */ - void *vmalloc; + void *vaddr; /* for overlay buffers (pci-pci dma) */ dma_addr_t bus_addr; @@ -87,6 +71,16 @@ struct videobuf_dma_sg_memory { struct videobuf_dmabuf dma; }; +/* + * Scatter-gather DMA buffer API. + * + * These functions provide a simple way to create a page list and a + * scatter-gather list from a kernel, userspace of physical address and map the + * memory for DMA operation. + * + * Despite the name, this is totally unrelated to videobuf, except that + * videobuf-dma-sg uses the same API internally. + */ void videobuf_dma_init(struct videobuf_dmabuf *dma); int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction, unsigned long data, unsigned long size); @@ -96,8 +90,8 @@ int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction, dma_addr_t addr, int nr_pages); int videobuf_dma_free(struct videobuf_dmabuf *dma); -int videobuf_dma_map(struct videobuf_queue *q, struct videobuf_dmabuf *dma); -int videobuf_dma_unmap(struct videobuf_queue *q, struct videobuf_dmabuf *dma); +int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma); +int videobuf_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma); struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf); void *videobuf_sg_alloc(size_t size); @@ -109,13 +103,8 @@ void videobuf_queue_sg_init(struct videobuf_queue *q, enum v4l2_buf_type type, enum v4l2_field field, unsigned int msize, - void *priv); - -/*FIXME: these variants are used only on *-alsa code, where videobuf is - * used without queue - */ -int videobuf_sg_dma_map(struct device *dev, struct videobuf_dmabuf *dma); -int videobuf_sg_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma); + void *priv, + struct mutex *ext_lock); #endif /* _VIDEOBUF_DMA_SG_H */ diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h index 851eb1a..486a97e 100644 --- a/include/media/videobuf-vmalloc.h +++ b/include/media/videobuf-vmalloc.h @@ -22,7 +22,7 @@ struct videobuf_vmalloc_memory { u32 magic; - void *vmalloc; + void *vaddr; /* remap_vmalloc_range seems to need to run * after mmap() on some cases */ @@ -36,7 +36,8 @@ void videobuf_queue_vmalloc_init(struct videobuf_queue *q, enum v4l2_buf_type type, enum v4l2_field field, unsigned int msize, - void *priv); + void *priv, + struct mutex *ext_lock); void *videobuf_to_vmalloc(struct videobuf_buffer *buf); diff --git a/include/media/wm8775.h b/include/media/wm8775.h index 60739c5..a1c4d41 100644 --- a/include/media/wm8775.h +++ b/include/media/wm8775.h @@ -32,4 +32,7 @@ #define WM8775_AIN3 4 #define WM8775_AIN4 8 +/* subdev group ID */ +#define WM8775_GID (1 << 0) + #endif |