diff options
Diffstat (limited to 'include/media/v4l2-subdev.h')
-rw-r--r-- | include/media/v4l2-subdev.h | 281 |
1 files changed, 242 insertions, 39 deletions
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index a503e1cee78b..b0316a7cf08d 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h @@ -22,8 +22,20 @@ #define _V4L2_SUBDEV_H #include <media/v4l2-common.h> +#include <media/v4l2-mediabus.h> + +/* generic v4l2_device notify callback notification values */ +#define V4L2_SUBDEV_IR_RX_NOTIFY _IOW('v', 0, u32) +#define V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ 0x00000001 +#define V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED 0x00000002 +#define V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN 0x00000004 +#define V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN 0x00000008 + +#define V4L2_SUBDEV_IR_TX_NOTIFY _IOW('v', 1, u32) +#define V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ 0x00000001 struct v4l2_device; +struct v4l2_ctrl_handler; struct v4l2_subdev; struct tuner_setup; @@ -79,7 +91,32 @@ struct v4l2_decode_vbi_line { not yet implemented) since ops provide proper type-checking. */ -/* init: initialize the sensor registors to some sort of reasonable default +/* 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. @@ -92,10 +129,21 @@ struct v4l2_decode_vbi_line { s_gpio: set GPIO pins. Very simple right now, might need to be extended with a direction argument if needed. + + 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); @@ -113,6 +161,9 @@ struct v4l2_subdev_core_ops { int (*g_register)(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg); 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. @@ -122,8 +173,6 @@ struct v4l2_subdev_core_ops { s_type_addr: sets tuner type and its I2C addr. s_config: sets tda9887 specific stuff, like port1, port2 and qss - - s_standby: puts tuner on powersaving state, disabling it, except for i2c. */ struct v4l2_subdev_tuner_ops { int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type); @@ -132,9 +181,10 @@ struct v4l2_subdev_tuner_ops { int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); int (*g_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt); int (*s_tuner)(struct v4l2_subdev *sd, struct v4l2_tuner *vt); + int (*g_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm); + int (*s_modulator)(struct v4l2_subdev *sd, struct v4l2_modulator *vm); int (*s_type_addr)(struct v4l2_subdev *sd, struct tuner_setup *type); int (*s_config)(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *config); - int (*s_standby)(struct v4l2_subdev *sd); }; /* s_clock_freq: set the frequency (in Hz) of the audio clock output. @@ -161,6 +211,76 @@ struct v4l2_subdev_audio_ops { int (*s_clock_freq)(struct v4l2_subdev *sd, u32 freq); int (*s_i2s_clock_freq)(struct v4l2_subdev *sd, u32 freq); int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); + int (*s_stream)(struct v4l2_subdev *sd, int enable); +}; + +/* + s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by + video input devices. + + s_crystal_freq: sets the frequency of the crystal used to generate the + clocks in Hz. An extra flags field allows device specific configuration + regarding clock frequency dividers, etc. If not used, then set flags + to 0. If the frequency is not supported, then -EINVAL is returned. + + g_input_status: get input status. Same as the status field in the v4l2_input + struct. + + s_routing: see s_routing in audio_ops, except this version is for video + devices. + + s_dv_preset: set dv (Digital Video) preset in the sub device. Similar to + s_std() + + query_dv_preset: query dv preset in the sub device. This is similar to + querystd() + + s_dv_timings(): Set custom dv timings in the sub device. This is used + when sub device is capable of setting detailed timing information + in the hardware to generate/detect the video signal. + + g_dv_timings(): Get custom dv timings in the sub device. + + enum_mbus_fmt: enumerate pixel formats, provided by a video data source + + g_mbus_fmt: get the current pixel format, provided by a video data source + + try_mbus_fmt: try to set a pixel format on a video data source + + s_mbus_fmt: set a pixel format on a video data source + */ +struct v4l2_subdev_video_ops { + int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); + int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags); + int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std); + 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 (*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); + int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); + int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); + int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); + int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); + int (*enum_dv_presets) (struct v4l2_subdev *sd, + struct v4l2_dv_enum_preset *preset); + int (*s_dv_preset)(struct v4l2_subdev *sd, + struct v4l2_dv_preset *preset); + int (*query_dv_preset)(struct v4l2_subdev *sd, + struct v4l2_dv_preset *preset); + int (*s_dv_timings)(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings); + int (*g_dv_timings)(struct v4l2_subdev *sd, + struct v4l2_dv_timings *timings); + int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, + enum v4l2_mbus_pixelcode *code); + int (*g_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*try_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); + int (*s_mbus_fmt)(struct v4l2_subdev *sd, + struct v4l2_mbus_framefmt *fmt); }; /* @@ -186,52 +306,121 @@ struct v4l2_subdev_audio_ops { member (to determine whether CC data from the first or second field should be obtained). - s_std_output: set v4l2_std_id for video OUTPUT devices. This is ignored by - video input devices. + s_raw_fmt: setup the video encoder/decoder for raw VBI. - s_crystal_freq: sets the frequency of the crystal used to generate the - clocks in Hz. An extra flags field allows device specific configuration - regarding clock frequency dividers, etc. If not used, then set flags - to 0. If the frequency is not supported, then -EINVAL is returned. + g_sliced_fmt: retrieve the current sliced VBI settings. - g_input_status: get input status. Same as the status field in the v4l2_input - struct. - - s_routing: see s_routing in audio_ops, except this version is for video - devices. + s_sliced_fmt: setup the sliced VBI settings. */ -struct v4l2_subdev_video_ops { - int (*s_routing)(struct v4l2_subdev *sd, u32 input, u32 output, u32 config); - int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags); +struct v4l2_subdev_vbi_ops { int (*decode_vbi_line)(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi_line); int (*s_vbi_data)(struct v4l2_subdev *sd, const struct v4l2_sliced_vbi_data *vbi_data); int (*g_vbi_data)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_data *vbi_data); int (*g_sliced_vbi_cap)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_cap *cap); - int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std); - 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 (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); - int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); - int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); - int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); + int (*s_raw_fmt)(struct v4l2_subdev *sd, struct v4l2_vbi_format *fmt); + int (*g_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt); + int (*s_sliced_fmt)(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_format *fmt); +}; + +/** + * struct v4l2_subdev_sensor_ops - v4l2-subdev sensor operations + * @g_skip_top_lines: number of lines at the top of the image to be skipped. + * This is needed for some sensors, which always corrupt + * several top lines of the output image, or which send their + * metadata in them. + */ +struct v4l2_subdev_sensor_ops { + int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines); +}; + +/* + [rt]x_g_parameters: Get the current operating parameters and state of the + the IR receiver or transmitter. + + [rt]x_s_parameters: Set the current operating parameters and state of the + the IR receiver or transmitter. It is recommended to call + [rt]x_g_parameters first to fill out the current state, and only change + the fields that need to be changed. Upon return, the actual device + operating parameters and state will be returned. Note that hardware + limitations may prevent the actual settings from matching the requested + settings - e.g. an actual carrier setting of 35,904 Hz when 36,000 Hz + was requested. An exception is when the shutdown parameter is true. + The last used operational parameters will be returned, but the actual + state of the hardware be different to minimize power consumption and + processing when shutdown is true. + + rx_read: Reads received codes or pulse width data. + The semantics are similar to a non-blocking read() call. + + tx_write: Writes codes or pulse width data for transmission. + The semantics are similar to a non-blocking write() call. + */ + +enum v4l2_subdev_ir_mode { + V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, /* uses struct ir_raw_event records */ +}; + +struct v4l2_subdev_ir_parameters { + /* Either Rx or Tx */ + unsigned int bytes_per_data_element; /* of data in read or write call */ + enum v4l2_subdev_ir_mode mode; + + bool enable; + bool interrupt_enable; + bool shutdown; /* true: set hardware to low/no power, false: normal */ + + bool modulation; /* true: uses carrier, false: baseband */ + 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_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 */ + unsigned int carrier_range_lower; /* Hz, valid only for modulated sig */ + unsigned int carrier_range_upper; /* Hz, valid only for modulated sig */ + u32 resolution; /* ns */ +}; + +struct v4l2_subdev_ir_ops { + /* Receiver */ + int (*rx_read)(struct v4l2_subdev *sd, u8 *buf, size_t count, + ssize_t *num); + + int (*rx_g_parameters)(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *params); + int (*rx_s_parameters)(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *params); + + /* Transmitter */ + int (*tx_write)(struct v4l2_subdev *sd, u8 *buf, size_t count, + ssize_t *num); + + int (*tx_g_parameters)(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *params); + int (*tx_s_parameters)(struct v4l2_subdev *sd, + struct v4l2_subdev_ir_parameters *params); }; struct v4l2_subdev_ops { - const struct v4l2_subdev_core_ops *core; - const struct v4l2_subdev_tuner_ops *tuner; - const struct v4l2_subdev_audio_ops *audio; - const struct v4l2_subdev_video_ops *video; + const struct v4l2_subdev_core_ops *core; + const struct v4l2_subdev_tuner_ops *tuner; + const struct v4l2_subdev_audio_ops *audio; + const struct v4l2_subdev_video_ops *video; + const struct v4l2_subdev_vbi_ops *vbi; + const struct v4l2_subdev_ir_ops *ir; + const struct v4l2_subdev_sensor_ops *sensor; }; #define V4L2_SUBDEV_NAME_SIZE 32 /* Set this flag if this subdev is a i2c device. */ #define V4L2_SUBDEV_FL_IS_I2C (1U << 0) +/* Set this flag if this subdev is a spi device. */ +#define V4L2_SUBDEV_FL_IS_SPI (1U << 1) /* Each instance of a subdev driver should create this struct, either stand-alone or embedded in a larger struct. @@ -242,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, @@ -271,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 @@ -280,7 +483,7 @@ static inline void v4l2_subdev_init(struct v4l2_subdev *sd, Example: err = v4l2_subdev_call(sd, core, g_chip_ident, &chip); */ #define v4l2_subdev_call(sd, o, f, args...) \ - (!(sd) ? -ENODEV : (((sd) && (sd)->ops->o && (sd)->ops->o->f) ? \ + (!(sd) ? -ENODEV : (((sd)->ops->o && (sd)->ops->o->f) ? \ (sd)->ops->o->f((sd) , ##args) : -ENOIOCTLCMD)) /* Send a notification to v4l2_device. */ |