diff options
Diffstat (limited to 'drivers/media')
45 files changed, 870 insertions, 1071 deletions
diff --git a/drivers/media/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb-core/dvb_ca_en50221.c index 72937756f60c..fb66184dc9b6 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb-core/dvb_ca_en50221.c @@ -169,10 +169,10 @@ static int dvb_ca_en50221_write_data(struct dvb_ca_private *ca, int slot, u8 * e /** * Safely find needle in haystack. * - * @param haystack Buffer to look in. - * @param hlen Number of bytes in haystack. - * @param needle Buffer to find. - * @param nlen Number of bytes in needle. + * @haystack: Buffer to look in. + * @hlen: Number of bytes in haystack. + * @needle: Buffer to find. + * @nlen: Number of bytes in needle. * @return Pointer into haystack needle was found at, or NULL if not found. */ static char *findstr(char * haystack, int hlen, char * needle, int nlen) @@ -197,7 +197,7 @@ static char *findstr(char * haystack, int hlen, char * needle, int nlen) /** - * Check CAM status. + * dvb_ca_en50221_check_camstatus - Check CAM status. */ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) { @@ -240,13 +240,13 @@ static int dvb_ca_en50221_check_camstatus(struct dvb_ca_private *ca, int slot) /** - * Wait for flags to become set on the STATUS register on a CAM interface, - * checking for errors and timeout. + * dvb_ca_en50221_wait_if_status - Wait for flags to become set on the STATUS + * register on a CAM interface, checking for errors and timeout. * - * @param ca CA instance. - * @param slot Slot on interface. - * @param waitfor Flags to wait for. - * @param timeout_ms Timeout in milliseconds. + * @ca: CA instance. + * @slot: Slot on interface. + * @waitfor: Flags to wait for. + * @timeout_ms: Timeout in milliseconds. * * @return 0 on success, nonzero on error. */ @@ -290,10 +290,10 @@ static int dvb_ca_en50221_wait_if_status(struct dvb_ca_private *ca, int slot, /** - * Initialise the link layer connection to a CAM. + * dvb_ca_en50221_link_init - Initialise the link layer connection to a CAM. * - * @param ca CA instance. - * @param slot Slot id. + * @ca: CA instance. + * @slot: Slot id. * * @return 0 on success, nonzero on failure. */ @@ -346,14 +346,14 @@ static int dvb_ca_en50221_link_init(struct dvb_ca_private *ca, int slot) } /** - * Read a tuple from attribute memory. + * dvb_ca_en50221_read_tuple - Read a tuple from attribute memory. * - * @param ca CA instance. - * @param slot Slot id. - * @param address Address to read from. Updated. - * @param tupleType Tuple id byte. Updated. - * @param tupleLength Tuple length. Updated. - * @param tuple Dest buffer for tuple (must be 256 bytes). Updated. + * @ca: CA instance. + * @slot: Slot id. + * @address: Address to read from. Updated. + * @tupleType: Tuple id byte. Updated. + * @tupleLength: Tuple length. Updated. + * @tuple: Dest buffer for tuple (must be 256 bytes). Updated. * * @return 0 on success, nonzero on error. */ @@ -399,11 +399,11 @@ static int dvb_ca_en50221_read_tuple(struct dvb_ca_private *ca, int slot, /** - * Parse attribute memory of a CAM module, extracting Config register, and checking - * it is a DVB CAM module. + * dvb_ca_en50221_parse_attributes - Parse attribute memory of a CAM module, + * extracting Config register, and checking it is a DVB CAM module. * - * @param ca CA instance. - * @param slot Slot id. + * @ca: CA instance. + * @slot: Slot id. * * @return 0 on success, <0 on failure. */ @@ -546,10 +546,10 @@ static int dvb_ca_en50221_parse_attributes(struct dvb_ca_private *ca, int slot) /** - * Set CAM's configoption correctly. + * dvb_ca_en50221_set_configoption - Set CAM's configoption correctly. * - * @param ca CA instance. - * @param slot Slot containing the CAM. + * @ca: CA instance. + * @slot: Slot containing the CAM. */ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot) { @@ -574,15 +574,16 @@ static int dvb_ca_en50221_set_configoption(struct dvb_ca_private *ca, int slot) /** - * This function talks to an EN50221 CAM control interface. It reads a buffer of - * data from the CAM. The data can either be stored in a supplied buffer, or - * automatically be added to the slot's rx_buffer. + * dvb_ca_en50221_read_data - This function talks to an EN50221 CAM control + * interface. It reads a buffer of data from the CAM. The data can either + * be stored in a supplied buffer, or automatically be added to the slot's + * rx_buffer. * - * @param ca CA instance. - * @param slot Slot to read from. - * @param ebuf If non-NULL, the data will be written to this buffer. If NULL, + * @ca: CA instance. + * @slot: Slot to read from. + * @ebuf: If non-NULL, the data will be written to this buffer. If NULL, * the data will be added into the buffering system as a normal fragment. - * @param ecount Size of ebuf. Ignored if ebuf is NULL. + * @ecount: Size of ebuf. Ignored if ebuf is NULL. * * @return Number of bytes read, or < 0 on error */ @@ -698,14 +699,14 @@ exit: /** - * This function talks to an EN50221 CAM control interface. It writes a buffer of data - * to a CAM. + * dvb_ca_en50221_write_data - This function talks to an EN50221 CAM control + * interface. It writes a buffer of data to a CAM. * - * @param ca CA instance. - * @param slot Slot to write to. - * @param ebuf The data in this buffer is treated as a complete link-level packet to + * @ca: CA instance. + * @slot: Slot to write to. + * @ebuf: The data in this buffer is treated as a complete link-level packet to * be written. - * @param count Size of ebuf. + * @count: Size of ebuf. * * @return Number of bytes written, or < 0 on error. */ @@ -790,10 +791,10 @@ EXPORT_SYMBOL(dvb_ca_en50221_camchange_irq); /** - * A CAM has been removed => shut it down. + * dvb_ca_en50221_camready_irq - A CAM has been removed => shut it down. * - * @param ca CA instance. - * @param slot Slot to shut down. + * @ca: CA instance. + * @slot: Slot to shut down. */ static int dvb_ca_en50221_slot_shutdown(struct dvb_ca_private *ca, int slot) { @@ -815,11 +816,11 @@ EXPORT_SYMBOL(dvb_ca_en50221_camready_irq); /** - * A CAMCHANGE IRQ has occurred. + * dvb_ca_en50221_camready_irq - A CAMCHANGE IRQ has occurred. * - * @param ca CA instance. - * @param slot Slot concerned. - * @param change_type One of the DVB_CA_CAMCHANGE_* values. + * @ca: CA instance. + * @slot: Slot concerned. + * @change_type: One of the DVB_CA_CAMCHANGE_* values. */ void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type) { @@ -844,10 +845,10 @@ EXPORT_SYMBOL(dvb_ca_en50221_frda_irq); /** - * A CAMREADY IRQ has occurred. + * dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred. * - * @param ca CA instance. - * @param slot Slot concerned. + * @ca: CA instance. + * @slot: Slot concerned. */ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot) { @@ -865,8 +866,8 @@ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot) /** * An FR or DA IRQ has occurred. * - * @param ca CA instance. - * @param slot Slot concerned. + * @ca: CA instance. + * @slot: Slot concerned. */ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) { @@ -899,7 +900,7 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) /** * Wake up the DVB CA thread * - * @param ca CA instance. + * @ca: CA instance. */ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca) { @@ -914,7 +915,7 @@ static void dvb_ca_en50221_thread_wakeup(struct dvb_ca_private *ca) /** * Update the delay used by the thread. * - * @param ca CA instance. + * @ca: CA instance. */ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) { @@ -1177,10 +1178,10 @@ static int dvb_ca_en50221_thread(void *data) * Real ioctl implementation. * NOTE: CA_SEND_MSG/CA_GET_MSG ioctls have userspace buffers passed to them. * - * @param inode Inode concerned. - * @param file File concerned. - * @param cmd IOCTL command. - * @param arg Associated argument. + * @inode: Inode concerned. + * @file: File concerned. + * @cmd: IOCTL command. + * @arg: Associated argument. * * @return 0 on success, <0 on error. */ @@ -1258,10 +1259,10 @@ out_unlock: /** * Wrapper for ioctl implementation. * - * @param inode Inode concerned. - * @param file File concerned. - * @param cmd IOCTL command. - * @param arg Associated argument. + * @inode: Inode concerned. + * @file: File concerned. + * @cmd: IOCTL command. + * @arg: Associated argument. * * @return 0 on success, <0 on error. */ @@ -1275,10 +1276,10 @@ static long dvb_ca_en50221_io_ioctl(struct file *file, /** * Implementation of write() syscall. * - * @param file File structure. - * @param buf Source buffer. - * @param count Size of source buffer. - * @param ppos Position in file (ignored). + * @file: File structure. + * @buf: Source buffer. + * @count: Size of source buffer. + * @ppos: Position in file (ignored). * * @return Number of bytes read, or <0 on error. */ @@ -1416,10 +1417,10 @@ nextslot: /** * Implementation of read() syscall. * - * @param file File structure. - * @param buf Destination buffer. - * @param count Size of destination buffer. - * @param ppos Position in file (ignored). + * @file: File structure. + * @buf: Destination buffer. + * @count: Size of destination buffer. + * @ppos: Position in file (ignored). * * @return Number of bytes read, or <0 on error. */ @@ -1519,8 +1520,8 @@ exit: /** * Implementation of file open syscall. * - * @param inode Inode concerned. - * @param file File concerned. + * @inode: Inode concerned. + * @file: File concerned. * * @return 0 on success, <0 on failure. */ @@ -1564,8 +1565,8 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) /** * Implementation of file close syscall. * - * @param inode Inode concerned. - * @param file File concerned. + * @inode: Inode concerned. + * @file: File concerned. * * @return 0 on success, <0 on failure. */ @@ -1592,8 +1593,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) /** * Implementation of poll() syscall. * - * @param file File concerned. - * @param wait poll wait table. + * @file: File concerned. + * @wait: poll wait table. * * @return Standard poll mask. */ @@ -1656,10 +1657,10 @@ static const struct dvb_device dvbdev_ca = { /** * Initialise a new DVB CA EN50221 interface device. * - * @param dvb_adapter DVB adapter to attach the new CA device to. - * @param ca The dvb_ca instance. - * @param flags Flags describing the CA device (DVB_CA_FLAG_*). - * @param slot_count Number of slots supported. + * @dvb_adapter: DVB adapter to attach the new CA device to. + * @ca: The dvb_ca instance. + * @flags: Flags describing the CA device (DVB_CA_FLAG_*). + * @slot_count: Number of slots supported. * * @return 0 on success, nonzero on failure */ @@ -1743,8 +1744,8 @@ EXPORT_SYMBOL(dvb_ca_en50221_release); /** * Release a DVB CA EN50221 interface device. * - * @param ca_dev The dvb_device_t instance for the CA device. - * @param ca The associated dvb_ca instance. + * @ca_dev: The dvb_device_t instance for the CA device. + * @ca: The associated dvb_ca instance. */ void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) { diff --git a/drivers/media/dvb-core/dvb_ca_en50221.h b/drivers/media/dvb-core/dvb_ca_en50221.h index 7df2e141187a..aba3b4fbd704 100644 --- a/drivers/media/dvb-core/dvb_ca_en50221.h +++ b/drivers/media/dvb-core/dvb_ca_en50221.h @@ -83,27 +83,27 @@ struct dvb_ca_en50221 { /* Functions for reporting IRQ events */ /** - * A CAMCHANGE IRQ has occurred. + * dvb_ca_en50221_camchange_irq - A CAMCHANGE IRQ has occurred. * - * @param ca CA instance. - * @param slot Slot concerned. - * @param change_type One of the DVB_CA_CAMCHANGE_* values + * @pubca: CA instance. + * @slot: Slot concerned. + * @change_type: One of the DVB_CA_CAMCHANGE_* values */ void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221* pubca, int slot, int change_type); /** - * A CAMREADY IRQ has occurred. + * dvb_ca_en50221_camready_irq - A CAMREADY IRQ has occurred. * - * @param ca CA instance. - * @param slot Slot concerned. + * @pubca: CA instance. + * @slot: Slot concerned. */ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221* pubca, int slot); /** - * An FR or a DA IRQ has occurred. + * dvb_ca_en50221_frda_irq - An FR or a DA IRQ has occurred. * - * @param ca CA instance. - * @param slot Slot concerned. + * @ca: CA instance. + * @slot: Slot concerned. */ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot); @@ -113,21 +113,21 @@ void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221* ca, int slot); /* Initialisation/shutdown functions */ /** - * Initialise a new DVB CA device. + * dvb_ca_en50221_init - Initialise a new DVB CA device. * - * @param dvb_adapter DVB adapter to attach the new CA device to. - * @param ca The dvb_ca instance. - * @param flags Flags describing the CA device (DVB_CA_EN50221_FLAG_*). - * @param slot_count Number of slots supported. + * @dvb_adapter: DVB adapter to attach the new CA device to. + * @ca: The dvb_ca instance. + * @flags: Flags describing the CA device (DVB_CA_EN50221_FLAG_*). + * @slot_count: Number of slots supported. * * @return 0 on success, nonzero on failure */ extern int dvb_ca_en50221_init(struct dvb_adapter *dvb_adapter, struct dvb_ca_en50221* ca, int flags, int slot_count); /** - * Release a DVB CA device. + * dvb_ca_en50221_release - Release a DVB CA device. * - * @param ca The associated dvb_ca instance. + * @ca: The associated dvb_ca instance. */ extern void dvb_ca_en50221_release(struct dvb_ca_en50221* ca); diff --git a/drivers/media/dvb-core/dvb_frontend.c b/drivers/media/dvb-core/dvb_frontend.c index 842b9c8f80c6..c38ef1a72b4a 100644 --- a/drivers/media/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb-core/dvb_frontend.c @@ -81,7 +81,6 @@ MODULE_PARM_DESC(dvb_mfe_wait_time, "Wait up to <mfe_wait_time> seconds on open( #define FESTATE_SEARCHING_SLOW (FESTATE_TUNING_SLOW | FESTATE_ZIGZAG_SLOW) #define FESTATE_LOSTLOCK (FESTATE_ZIGZAG_FAST | FESTATE_ZIGZAG_SLOW) -#define FE_ALGO_HW 1 /* * FESTATE_IDLE. No tuning parameters have been supplied and the loop is idling. * FESTATE_RETUNE. Parameters have been supplied, but we have not yet performed the first tune. diff --git a/drivers/media/dvb-core/dvb_frontend.h b/drivers/media/dvb-core/dvb_frontend.h index 4816947294fe..97661b2f247a 100644 --- a/drivers/media/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb-core/dvb_frontend.h @@ -48,6 +48,15 @@ */ #define MAX_DELSYS 8 +/** + * struct dvb_frontend_tune_settings - parameters to adjust frontend tuning + * + * @min_delay_ms: minimum delay for tuning, in ms + * @step_size: step size between two consecutive frequencies + * @max_drift: maximum drift + * + * NOTE: step_size is in Hz, for terrestrial/cable or kHz for satellite + */ struct dvb_frontend_tune_settings { int min_delay_ms; int step_size; @@ -56,6 +65,20 @@ struct dvb_frontend_tune_settings { struct dvb_frontend; +/** + * struct dvb_tuner_info - Frontend name and min/max ranges/bandwidths + * + * @name: name of the Frontend + * @frequency_min: minimal frequency supported + * @frequency_max: maximum frequency supported + * @frequency_step: frequency step + * @bandwidth_min: minimal frontend bandwidth supported + * @bandwidth_max: maximum frontend bandwidth supported + * @bandwidth_step: frontend bandwidth step + * + * NOTE: frequency parameters are in Hz, for terrestrial/cable or kHz for + * satellite. + */ struct dvb_tuner_info { char name[128]; @@ -68,6 +91,20 @@ struct dvb_tuner_info { u32 bandwidth_step; }; +/** + * struct analog_parameters - Parameters to tune into an analog/radio channel + * + * @frequency: Frequency used by analog TV tuner (either in 62.5 kHz step, + * for TV, or 62.5 Hz for radio) + * @mode: Tuner mode, as defined on enum v4l2_tuner_type + * @audmode: Audio mode as defined for the rxsubchans field at videodev2.h, + * e. g. V4L2_TUNER_MODE_* + * @std: TV standard bitmap as defined at videodev2.h, e. g. V4L2_STD_* + * + * Hybrid tuners should be supported by both V4L2 and DVB APIs. This + * struct contains the data that are used by the V4L2 side. To avoid + * dependencies from V4L2 headers, all enums here are declared as integers. + */ struct analog_parameters { unsigned int frequency; unsigned int mode; @@ -75,42 +112,6 @@ struct analog_parameters { u64 std; }; -enum dvbfe_modcod { - DVBFE_MODCOD_DUMMY_PLFRAME = 0, - DVBFE_MODCOD_QPSK_1_4, - DVBFE_MODCOD_QPSK_1_3, - DVBFE_MODCOD_QPSK_2_5, - DVBFE_MODCOD_QPSK_1_2, - DVBFE_MODCOD_QPSK_3_5, - DVBFE_MODCOD_QPSK_2_3, - DVBFE_MODCOD_QPSK_3_4, - DVBFE_MODCOD_QPSK_4_5, - DVBFE_MODCOD_QPSK_5_6, - DVBFE_MODCOD_QPSK_8_9, - DVBFE_MODCOD_QPSK_9_10, - DVBFE_MODCOD_8PSK_3_5, - DVBFE_MODCOD_8PSK_2_3, - DVBFE_MODCOD_8PSK_3_4, - DVBFE_MODCOD_8PSK_5_6, - DVBFE_MODCOD_8PSK_8_9, - DVBFE_MODCOD_8PSK_9_10, - DVBFE_MODCOD_16APSK_2_3, - DVBFE_MODCOD_16APSK_3_4, - DVBFE_MODCOD_16APSK_4_5, - DVBFE_MODCOD_16APSK_5_6, - DVBFE_MODCOD_16APSK_8_9, - DVBFE_MODCOD_16APSK_9_10, - DVBFE_MODCOD_32APSK_3_4, - DVBFE_MODCOD_32APSK_4_5, - DVBFE_MODCOD_32APSK_5_6, - DVBFE_MODCOD_32APSK_8_9, - DVBFE_MODCOD_32APSK_9_10, - DVBFE_MODCOD_RESERVED_1, - DVBFE_MODCOD_BPSK_1_3, - DVBFE_MODCOD_BPSK_1_4, - DVBFE_MODCOD_RESERVED_2 -}; - enum tuner_param { DVBFE_TUNER_FREQUENCY = (1 << 0), DVBFE_TUNER_TUNERSTEP = (1 << 1), @@ -121,30 +122,28 @@ enum tuner_param { DVBFE_TUNER_DUMMY = (1 << 31) }; -/* - * ALGO_HW: (Hardware Algorithm) - * ---------------------------------------------------------------- - * Devices that support this algorithm do everything in hardware - * and no software support is needed to handle them. - * Requesting these devices to LOCK is the only thing required, - * device is supposed to do everything in the hardware. - * - * ALGO_SW: (Software Algorithm) - * ---------------------------------------------------------------- +/** + * enum dvbfe_algo - defines the algorithm used to tune into a channel + * + * @DVBFE_ALGO_HW: Hardware Algorithm - + * Devices that support this algorithm do everything in hardware + * and no software support is needed to handle them. + * Requesting these devices to LOCK is the only thing required, + * device is supposed to do everything in the hardware. + * + * @DVBFE_ALGO_SW: Software Algorithm - * These are dumb devices, that require software to do everything * - * ALGO_CUSTOM: (Customizable Agorithm) - * ---------------------------------------------------------------- - * Devices having this algorithm can be customized to have specific - * algorithms in the frontend driver, rather than simply doing a - * software zig-zag. In this case the zigzag maybe hardware assisted - * or it maybe completely done in hardware. In all cases, usage of - * this algorithm, in conjunction with the search and track - * callbacks, utilizes the driver specific algorithm. - * - * ALGO_RECOVERY: (Recovery Algorithm) - * ---------------------------------------------------------------- - * These devices have AUTO recovery capabilities from LOCK failure + * @DVBFE_ALGO_CUSTOM: Customizable Agorithm - + * Devices having this algorithm can be customized to have specific + * algorithms in the frontend driver, rather than simply doing a + * software zig-zag. In this case the zigzag maybe hardware assisted + * or it maybe completely done in hardware. In all cases, usage of + * this algorithm, in conjunction with the search and track + * callbacks, utilizes the driver specific algorithm. + * + * @DVBFE_ALGO_RECOVERY: Recovery Algorithm - + * These devices have AUTO recovery capabilities from LOCK failure */ enum dvbfe_algo { DVBFE_ALGO_HW = (1 << 0), @@ -162,27 +161,27 @@ struct tuner_state { u32 refclock; }; -/* - * search callback possible return status +/** + * enum dvbfe_search - search callback possible return status * - * DVBFE_ALGO_SEARCH_SUCCESS - * The frontend search algorithm completed and returned successfully + * @DVBFE_ALGO_SEARCH_SUCCESS: + * The frontend search algorithm completed and returned successfully * - * DVBFE_ALGO_SEARCH_ASLEEP - * The frontend search algorithm is sleeping + * @DVBFE_ALGO_SEARCH_ASLEEP: + * The frontend search algorithm is sleeping * - * DVBFE_ALGO_SEARCH_FAILED - * The frontend search for a signal failed + * @DVBFE_ALGO_SEARCH_FAILED: + * The frontend search for a signal failed * - * DVBFE_ALGO_SEARCH_INVALID - * The frontend search algorith was probably supplied with invalid - * parameters and the search is an invalid one + * @DVBFE_ALGO_SEARCH_INVALID: + * The frontend search algorith was probably supplied with invalid + * parameters and the search is an invalid one * - * DVBFE_ALGO_SEARCH_ERROR - * The frontend search algorithm failed due to some error + * @DVBFE_ALGO_SEARCH_ERROR: + * The frontend search algorithm failed due to some error * - * DVBFE_ALGO_SEARCH_AGAIN - * The frontend search algorithm was requested to search again + * @DVBFE_ALGO_SEARCH_AGAIN: + * The frontend search algorithm was requested to search again */ enum dvbfe_search { DVBFE_ALGO_SEARCH_SUCCESS = (1 << 0), @@ -193,7 +192,56 @@ enum dvbfe_search { DVBFE_ALGO_SEARCH_ERROR = (1 << 31), }; - +/** + * struct dvb_tuner_ops - Tuner information and callbacks + * + * @info: embedded struct dvb_tuner_info with tuner properties + * @release: callback function called when frontend is dettached. + * drivers should free any allocated memory. + * @init: callback function used to initialize the tuner device. + * @sleep: callback function used to put the tuner to sleep. + * @suspend: callback function used to inform that the Kernel will + * suspend. + * @resume: callback function used to inform that the Kernel is + * resuming from suspend. + * @set_params: callback function used to inform the tuner to tune + * into a digital TV channel. The properties to be used + * are stored at @dvb_frontend.dtv_property_cache;. The + * tuner demod can change the parameters to reflect the + * changes needed for the channel to be tuned, and + * update statistics. + * @set_analog_params: callback function used to tune into an analog TV + * channel on hybrid tuners. It passes @analog_parameters; + * to the driver. + * @calc_regs: callback function used to pass register data settings + * for simple tuners. + * @set_config: callback function used to send some tuner-specific + * parameters. + * @get_frequency: get the actual tuned frequency + * @get_bandwidth: get the bandwitdh used by the low pass filters + * @get_if_frequency: get the Intermediate Frequency, in Hz. For baseband, + * should return 0. + * @get_status: returns the frontend lock status + * @get_rf_strength: returns the RF signal strengh. Used mostly to support + * analog TV and radio. Digital TV should report, instead, + * via DVBv5 API (@dvb_frontend.dtv_property_cache;). + * @get_afc: Used only by analog TV core. Reports the frequency + * drift due to AFC. + * @set_frequency: Set a new frequency. Please notice that using + * set_params is preferred. + * @set_bandwidth: Set a new frequency. Please notice that using + * set_params is preferred. + * @set_state: callback function used on some legacy drivers that + * don't implement set_params in order to set properties. + * Shouldn't be used on new drivers. + * @get_state: callback function used to get properties by some + * legacy drivers that don't implement set_params. + * Shouldn't be used on new drivers. + * + * NOTE: frequencies used on get_frequency and set_frequency are in Hz for + * terrestrial/cable or kHz for satellite. + * + */ struct dvb_tuner_ops { struct dvb_tuner_info info; @@ -237,10 +285,37 @@ struct dvb_tuner_ops { int (*get_state)(struct dvb_frontend *fe, enum tuner_param param, struct tuner_state *state); }; +/** + * struct analog_demod_info - Information struct for analog TV part of the demod + * + * @name: Name of the analog TV demodulator + */ struct analog_demod_info { char *name; }; +/** + * struct analog_demod_ops - Demodulation information and callbacks for + * analog TV and radio + * + * @info: pointer to struct analog_demod_info + * @set_params: callback function used to inform the demod to set the + * demodulator parameters needed to decode an analog or + * radio channel. The properties are passed via + * struct @analog_params;. + * @has_signal: returns 0xffff if has signal, or 0 if it doesn't. + * @get_afc: Used only by analog TV core. Reports the frequency + * drift due to AFC. + * @tuner_status: callback function that returns tuner status bits, e. g. + * TUNER_STATUS_LOCKED and TUNER_STATUS_STEREO. + * @standby: set the tuner to standby mode. + * @release: callback function called when frontend is dettached. + * drivers should free any allocated memory. + * @i2c_gate_ctrl: controls the I2C gate. Newer drivers should use I2C + * mux support instead. + * @set_config: callback function used to send some tuner-specific + * parameters. + */ struct analog_demod_ops { struct analog_demod_info info; @@ -260,6 +335,87 @@ struct analog_demod_ops { struct dtv_frontend_properties; + +/** + * struct dvb_frontend_ops - Demodulation information and callbacks for + * ditialt TV + * + * @info: embedded struct dvb_tuner_info with tuner properties + * @delsys: Delivery systems supported by the frontend + * @release: callback function called when frontend is dettached. + * drivers should free any allocated memory. + * @release_sec: callback function requesting that the Satelite Equipment + * Control (SEC) driver to release and free any memory + * allocated by the driver. + * @init: callback function used to initialize the tuner device. + * @sleep: callback function used to put the tuner to sleep. + * @write: callback function used by some demod legacy drivers to + * allow other drivers to write data into their registers. + * Should not be used on new drivers. + * @tune: callback function used by demod drivers that use + * @DVBFE_ALGO_HW; to tune into a frequency. + * @get_frontend_algo: returns the desired hardware algorithm. + * @set_frontend: callback function used to inform the demod to set the + * parameters for demodulating a digital TV channel. + * The properties to be used are stored at + * @dvb_frontend.dtv_property_cache;. The demod can change + * the parameters to reflect the changes needed for the + * channel to be decoded, and update statistics. + * @get_tune_settings: callback function + * @get_frontend: callback function used to inform the parameters + * actuall in use. The properties to be used are stored at + * @dvb_frontend.dtv_property_cache; and update + * statistics. Please notice that it should not return + * an error code if the statistics are not available + * because the demog is not locked. + * @read_status: returns the locking status of the frontend. + * @read_ber: legacy callback function to return the bit error rate. + * Newer drivers should provide such info via DVBv5 API, + * e. g. @set_frontend;/@get_frontend;, implementing this + * callback only if DVBv3 API compatibility is wanted. + * @read_signal_strength: legacy callback function to return the signal + * strength. Newer drivers should provide such info via + * DVBv5 API, e. g. @set_frontend;/@get_frontend;, + * implementing this callback only if DVBv3 API + * compatibility is wanted. + * @read_snr: legacy callback function to return the Signal/Noise + * rate. Newer drivers should provide such info via + * DVBv5 API, e. g. @set_frontend;/@get_frontend;, + * implementing this callback only if DVBv3 API + * compatibility is wanted. + * @read_ucblocks: legacy callback function to return the Uncorrected Error + * Blocks. Newer drivers should provide such info via + * DVBv5 API, e. g. @set_frontend;/@get_frontend;, + * implementing this callback only if DVBv3 API + * compatibility is wanted. + * @diseqc_reset_overload: callback function to implement the + * FE_DISEQC_RESET_OVERLOAD ioctl (only Satellite) + * @diseqc_send_master_cmd: callback function to implement the + * FE_DISEQC_SEND_MASTER_CMD ioctl (only Satellite). + * @diseqc_recv_slave_reply: callback function to implement the + * FE_DISEQC_RECV_SLAVE_REPLY ioctl (only Satellite) + * @diseqc_send_burst: callback function to implement the + * FE_DISEQC_SEND_BURST ioctl (only Satellite). + * @set_tone: callback function to implement the + * FE_SET_TONE ioctl (only Satellite). + * @set_voltage: callback function to implement the + * FE_SET_VOLTAGE ioctl (only Satellite). + * @enable_high_lnb_voltage: callback function to implement the + * FE_ENABLE_HIGH_LNB_VOLTAGE ioctl (only Satellite). + * @dishnetwork_send_legacy_command: callback function to implement the + * FE_DISHNETWORK_SEND_LEGACY_CMD ioctl (only Satellite). + * @i2c_gate_ctrl: controls the I2C gate. Newer drivers should use I2C + * mux support instead. + * @ts_bus_ctrl: callback function used to take control of the TS bus. + * @set_lna: callback function to power on/off/auto the LNA. + * @search: callback function used on some custom algo search algos. + * @tuner_ops: pointer to struct dvb_tuner_ops + * @analog_ops: pointer to struct analog_demod_ops + * @set_property: callback function to allow the frontend to validade + * incoming properties. Should not be used on new drivers. + * @get_property: callback function to allow the frontend to override + * outcoming properties. Should not be used on new drivers. + */ struct dvb_frontend_ops { struct dvb_frontend_info info; @@ -280,6 +436,7 @@ struct dvb_frontend_ops { unsigned int mode_flags, unsigned int *delay, enum fe_status *status); + /* get frontend tuning algorithm from the module */ enum dvbfe_algo (*get_frontend_algo)(struct dvb_frontend *fe); @@ -324,6 +481,7 @@ struct dvb_frontend_ops { #ifdef __DVB_CORE__ #define MAX_EVENT 8 +/* Used only internally at dvb_frontend.c */ struct dvb_fe_events { struct dvb_frontend_event events[MAX_EVENT]; int eventw; @@ -334,13 +492,83 @@ struct dvb_fe_events { }; #endif +/** + * struct dtv_frontend_properties - contains a list of properties that are + * specific to a digital TV standard. + * + * @frequency: frequency in Hz for terrestrial/cable or in kHz for + * Satellite + * @modulation: Frontend modulation type + * @voltage: SEC voltage (only Satellite) + * @sectone: SEC tone mode (only Satellite) + * @inversion: Spectral inversion + * @fec_inner: Forward error correction inner Code Rate + * @transmission_mode: Transmission Mode + * @bandwidth_hz: Bandwidth, in Hz. A zero value means that userspace + * wants to autodetect. + * @guard_interval: Guard Interval + * @hierarchy: Hierarchy + * @symbol_rate: Symbol Rate + * @code_rate_HP: high priority stream code rate + * @code_rate_LP: low priority stream code rate + * @pilot: Enable/disable/autodetect pilot tones + * @rolloff: Rolloff factor (alpha) + * @delivery_system: FE delivery system (e. g. digital TV standard) + * @interleaving: interleaving + * @isdbt_partial_reception: ISDB-T partial reception (only ISDB standard) + * @isdbt_sb_mode: ISDB-T Sound Broadcast (SB) mode (only ISDB standard) + * @isdbt_sb_subchannel: ISDB-T SB subchannel (only ISDB standard) + * @isdbt_sb_segment_idx: ISDB-T SB segment index (only ISDB standard) + * @isdbt_sb_segment_count: ISDB-T SB segment count (only ISDB standard) + * @isdbt_layer_enabled: ISDB Layer enabled (only ISDB standard) + * @layer: ISDB per-layer data (only ISDB standard) + * @layer.segment_count: Segment Count; + * @layer.fec: per layer code rate; + * @layer.modulation: per layer modulation; + * @layer.interleaving: per layer interleaving. + * @stream_id: If different than zero, enable substream filtering, if + * hardware supports (DVB-S2 and DVB-T2). + * @atscmh_fic_ver: Version number of the FIC (Fast Information Channel) + * signaling data (only ATSC-M/H) + * @atscmh_parade_id: Parade identification number (only ATSC-M/H) + * @atscmh_nog: Number of MH groups per MH subframe for a designated + * parade (only ATSC-M/H) + * @atscmh_tnog: Total number of MH groups including all MH groups + * belonging to all MH parades in one MH subframe + * (only ATSC-M/H) + * @atscmh_sgn: Start group number (only ATSC-M/H) + * @atscmh_prc: Parade repetition cycle (only ATSC-M/H) + * @atscmh_rs_frame_mode: Reed Solomon (RS) frame mode (only ATSC-M/H) + * @atscmh_rs_frame_ensemble: RS frame ensemble (only ATSC-M/H) + * @atscmh_rs_code_mode_pri: RS code mode pri (only ATSC-M/H) + * @atscmh_rs_code_mode_sec: RS code mode sec (only ATSC-M/H) + * @atscmh_sccc_block_mode: Series Concatenated Convolutional Code (SCCC) + * Block Mode (only ATSC-M/H) + * @atscmh_sccc_code_mode_a: SCCC code mode A (only ATSC-M/H) + * @atscmh_sccc_code_mode_b: SCCC code mode B (only ATSC-M/H) + * @atscmh_sccc_code_mode_c: SCCC code mode C (only ATSC-M/H) + * @atscmh_sccc_code_mode_d: SCCC code mode D (only ATSC-M/H) + * @lna: Power ON/OFF/AUTO the Linear Now-noise Amplifier (LNA) + * @strength: DVBv5 API statistics: Signal Strength + * @cnr: DVBv5 API statistics: Signal to Noise ratio of the + * (main) carrier + * @pre_bit_error: DVBv5 API statistics: pre-Viterbi bit error count + * @pre_bit_count: DVBv5 API statistics: pre-Viterbi bit count + * @post_bit_error: DVBv5 API statistics: post-Viterbi bit error count + * @post_bit_count: DVBv5 API statistics: post-Viterbi bit count + * @block_error: DVBv5 API statistics: block error count + * @block_count: DVBv5 API statistics: block count + * + * NOTE: derivated statistics like Uncorrected Error blocks (UCE) are + * calculated on userspace. + * + * Only a subset of the properties are needed for a given delivery system. + * For more info, consult the media_api.html with the documentation of the + * Userspace API. + */ struct dtv_frontend_properties { - - /* Cache State */ - u32 state; - u32 frequency; - enum fe_modulation modulation; + enum fe_modulation modulation; enum fe_sec_voltage voltage; enum fe_sec_tone_mode sectone; @@ -407,6 +635,11 @@ struct dtv_frontend_properties { struct dtv_fe_stats post_bit_count; struct dtv_fe_stats block_error; struct dtv_fe_stats block_count; + + /* private: */ + /* Cache State */ + u32 state; + }; #define DVB_FE_NO_EXIT 0 @@ -414,6 +647,25 @@ struct dtv_frontend_properties { #define DVB_FE_DEVICE_REMOVED 2 #define DVB_FE_DEVICE_RESUME 3 +/** + * struct dvb_frontend - Frontend structure to be used on drivers. + * + * @ops: embedded struct dvb_frontend_ops + * @dvb: pointer to struct dvb_adapter + * @demodulator_priv: demod private data + * @tuner_priv: tuner private data + * @frontend_priv: frontend private data + * @sec_priv: SEC private data + * @analog_demod_priv: Analog demod private data + * @dtv_property_cache: embedded struct dtv_frontend_properties + * @callback: callback function used on some drivers to call + * either the tuner or the demodulator. + * @id: Frontend ID + * @exit: Used to inform the DVB core that the frontend + * thread should exit (usually, means that the hardware + * got disconnected. + */ + struct dvb_frontend { struct dvb_frontend_ops ops; struct dvb_adapter *dvb; diff --git a/drivers/media/dvb-core/dvb_math.h b/drivers/media/dvb-core/dvb_math.h index aecc867e9404..34dc1df03cab 100644 --- a/drivers/media/dvb-core/dvb_math.h +++ b/drivers/media/dvb-core/dvb_math.h @@ -25,33 +25,38 @@ #include <linux/types.h> /** - * computes log2 of a value; the result is shifted left by 24 bits + * cintlog2 - computes log2 of a value; the result is shifted left by 24 bits + * + * @value: The value (must be != 0) * * to use rational values you can use the following method: * intlog2(value) = intlog2(value * 2^x) - x * 2^24 * - * example: intlog2(8) will give 3 << 24 = 3 * 2^24 - * example: intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24 - * example: intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24 + * Some usecase examples: + * intlog2(8) will give 3 << 24 = 3 * 2^24 + * intlog2(9) will give 3 << 24 + ... = 3.16... * 2^24 + * intlog2(1.5) = intlog2(3) - 2^24 = 0.584... * 2^24 + * * - * @param value The value (must be != 0) - * @return log2(value) * 2^24 + * return: log2(value) * 2^24 */ extern unsigned int intlog2(u32 value); /** - * computes log10 of a value; the result is shifted left by 24 bits + * intlog10 - computes log10 of a value; the result is shifted left by 24 bits + * + * @value: The value (must be != 0) * * to use rational values you can use the following method: * intlog10(value) = intlog10(value * 10^x) - x * 2^24 * - * example: intlog10(1000) will give 3 << 24 = 3 * 2^24 + * An usecase example: + * intlog10(1000) will give 3 << 24 = 3 * 2^24 * due to the implementation intlog10(1000) might be not exactly 3 * 2^24 * * look at intlog2 for similar examples * - * @param value The value (must be != 0) - * @return log10(value) * 2^24 + * return: log10(value) * 2^24 */ extern unsigned int intlog10(u32 value); diff --git a/drivers/media/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb-core/dvb_ringbuffer.h index 9e1e11b7c39c..3ebc2d34b4a2 100644 --- a/drivers/media/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb-core/dvb_ringbuffer.h @@ -45,33 +45,33 @@ struct dvb_ringbuffer { /* -** Notes: -** ------ -** (1) For performance reasons read and write routines don't check buffer sizes -** and/or number of bytes free/available. This has to be done before these -** routines are called. For example: -** -** *** write <buflen> bytes *** -** free = dvb_ringbuffer_free(rbuf); -** if (free >= buflen) -** count = dvb_ringbuffer_write(rbuf, buffer, buflen); -** else -** ... -** -** *** read min. 1000, max. <bufsize> bytes *** -** avail = dvb_ringbuffer_avail(rbuf); -** if (avail >= 1000) -** count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize)); -** else -** ... -** -** (2) If there is exactly one reader and one writer, there is no need -** to lock read or write operations. -** Two or more readers must be locked against each other. -** Flushing the buffer counts as a read operation. -** Resetting the buffer counts as a read and write operation. -** Two or more writers must be locked against each other. -*/ + * Notes: + * ------ + * (1) For performance reasons read and write routines don't check buffer sizes + * and/or number of bytes free/available. This has to be done before these + * routines are called. For example: + * + * *** write @buflen: bytes *** + * free = dvb_ringbuffer_free(rbuf); + * if (free >= buflen) + * count = dvb_ringbuffer_write(rbuf, buffer, buflen); + * else + * ... + * + * *** read min. 1000, max. @bufsize: bytes *** + * avail = dvb_ringbuffer_avail(rbuf); + * if (avail >= 1000) + * count = dvb_ringbuffer_read(rbuf, buffer, min(avail, bufsize)); + * else + * ... + * + * (2) If there is exactly one reader and one writer, there is no need + * to lock read or write operations. + * Two or more readers must be locked against each other. + * Flushing the buffer counts as a read operation. + * Resetting the buffer counts as a read and write operation. + * Two or more writers must be locked against each other. + */ /* initialize ring buffer, lock and queue */ extern void dvb_ringbuffer_init(struct dvb_ringbuffer *rbuf, void *data, size_t len); @@ -87,9 +87,9 @@ extern ssize_t dvb_ringbuffer_avail(struct dvb_ringbuffer *rbuf); /* -** Reset the read and write pointers to zero and flush the buffer -** This counts as a read and write operation -*/ + * Reset the read and write pointers to zero and flush the buffer + * This counts as a read and write operation + */ extern void dvb_ringbuffer_reset(struct dvb_ringbuffer *rbuf); @@ -101,19 +101,19 @@ extern void dvb_ringbuffer_flush(struct dvb_ringbuffer *rbuf); /* flush buffer protected by spinlock and wake-up waiting task(s) */ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); -/* peek at byte <offs> in the buffer */ +/* peek at byte @offs: in the buffer */ #define DVB_RINGBUFFER_PEEK(rbuf,offs) \ (rbuf)->data[((rbuf)->pread+(offs))%(rbuf)->size] -/* advance read ptr by <num> bytes */ +/* advance read ptr by @num: bytes */ #define DVB_RINGBUFFER_SKIP(rbuf,num) \ (rbuf)->pread=((rbuf)->pread+(num))%(rbuf)->size /* -** read <len> bytes from ring buffer into <buf> -** <usermem> specifies whether <buf> resides in user space -** returns number of bytes transferred or -EFAULT -*/ + * read @len: bytes from ring buffer into @buf: + * @usermem: specifies whether @buf: resides in user space + * returns number of bytes transferred or -EFAULT + */ extern ssize_t dvb_ringbuffer_read_user(struct dvb_ringbuffer *rbuf, u8 __user *buf, size_t len); extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, @@ -127,9 +127,9 @@ extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, { (rbuf)->data[(rbuf)->pwrite]=(byte); \ (rbuf)->pwrite=((rbuf)->pwrite+1)%(rbuf)->size; } /* -** write <len> bytes to ring buffer -** <usermem> specifies whether <buf> resides in user space -** returns number of bytes transferred or -EFAULT + * write @len: bytes to ring buffer + * @usermem: specifies whether @buf: resides in user space + * returns number of bytes transferred or -EFAULT */ extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len); @@ -138,48 +138,63 @@ extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf, /** - * Write a packet into the ringbuffer. + * dvb_ringbuffer_pkt_write - Write a packet into the ringbuffer. * - * <rbuf> Ringbuffer to write to. - * <buf> Buffer to write. - * <len> Length of buffer (currently limited to 65535 bytes max). + * @rbuf: Ringbuffer to write to. + * @buf: Buffer to write. + * @len: Length of buffer (currently limited to 65535 bytes max). * returns Number of bytes written, or -EFAULT, -ENOMEM, -EVINAL. */ extern ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len); /** - * Read from a packet in the ringbuffer. Note: unlike dvb_ringbuffer_read(), this - * does NOT update the read pointer in the ringbuffer. You must use - * dvb_ringbuffer_pkt_dispose() to mark a packet as no longer required. - * - * <rbuf> Ringbuffer concerned. - * <idx> Packet index as returned by dvb_ringbuffer_pkt_next(). - * <offset> Offset into packet to read from. - * <buf> Destination buffer for data. - * <len> Size of destination buffer. - * <usermem> Set to 1 if <buf> is in userspace. + * dvb_ringbuffer_pkt_read_user - Read from a packet in the ringbuffer. + * Note: unlike dvb_ringbuffer_read(), this does NOT update the read pointer + * in the ringbuffer. You must use dvb_ringbuffer_pkt_dispose() to mark a + * packet as no longer required. + * + * @rbuf: Ringbuffer concerned. + * @idx: Packet index as returned by dvb_ringbuffer_pkt_next(). + * @offset: Offset into packet to read from. + * @buf: Destination buffer for data. + * @len: Size of destination buffer. + * * returns Number of bytes read, or -EFAULT. */ extern ssize_t dvb_ringbuffer_pkt_read_user(struct dvb_ringbuffer *rbuf, size_t idx, int offset, u8 __user *buf, size_t len); + +/** + * dvb_ringbuffer_pkt_read - Read from a packet in the ringbuffer. + * Note: unlike dvb_ringbuffer_read_user(), this DOES update the read pointer + * in the ringbuffer. + * + * @rbuf: Ringbuffer concerned. + * @idx: Packet index as returned by dvb_ringbuffer_pkt_next(). + * @offset: Offset into packet to read from. + * @buf: Destination buffer for data. + * @len: Size of destination buffer. + * + * returns Number of bytes read, or -EFAULT. + */ extern ssize_t dvb_ringbuffer_pkt_read(struct dvb_ringbuffer *rbuf, size_t idx, int offset, u8 *buf, size_t len); /** - * Dispose of a packet in the ring buffer. + * dvb_ringbuffer_pkt_dispose - Dispose of a packet in the ring buffer. * - * <rbuf> Ring buffer concerned. - * <idx> Packet index as returned by dvb_ringbuffer_pkt_next(). + * @rbuf: Ring buffer concerned. + * @idx: Packet index as returned by dvb_ringbuffer_pkt_next(). */ extern void dvb_ringbuffer_pkt_dispose(struct dvb_ringbuffer *rbuf, size_t idx); /** - * Get the index of the next packet in a ringbuffer. + * dvb_ringbuffer_pkt_next - Get the index of the next packet in a ringbuffer. * - * <rbuf> Ringbuffer concerned. - * <idx> Previous packet index, or -1 to return the first packet index. - * <pktlen> On success, will be updated to contain the length of the packet in bytes. + * @rbuf: Ringbuffer concerned. + * @idx: Previous packet index, or -1 to return the first packet index. + * @pktlen: On success, will be updated to contain the length of the packet in bytes. * returns Packet index (if >=0), or -1 if no packets available. */ extern ssize_t dvb_ringbuffer_pkt_next(struct dvb_ringbuffer *rbuf, size_t idx, size_t* pktlen); diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h index 12629b8ecb0c..c61a4f03a66f 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -57,6 +57,25 @@ struct dvb_frontend; +/** + * struct dvb_adapter - represents a Digital TV adapter using Linux DVB API + * + * @num: Number of the adapter + * @list_head: List with the DVB adapters + * @device_list: List with the DVB devices + * @name: Name of the adapter + * @proposed_mac: proposed MAC address for the adapter + * @priv: private data + * @device: pointer to struct device + * @module: pointer to struct module + * @mfe_shared: mfe shared: indicates mutually exclusive frontends + * Thie usage of this flag is currently deprecated + * @mfe_dvbdev: Frontend device in use, in the case of MFE + * @mfe_lock: Lock to prevent using the other frontends when MFE is + * used. + * @mdev: pointer to struct media_device, used when the media + * controller is used. + */ struct dvb_adapter { int num; struct list_head list_head; @@ -78,7 +97,34 @@ struct dvb_adapter { #endif }; - +/** + * struct dvb_device - represents a DVB device node + * + * @list_head: List head with all DVB devices + * @fops: pointer to struct file_operations + * @adapter: pointer to the adapter that holds this device node + * @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND, + * DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET + * @minor: devnode minor number. Major number is always DVB_MAJOR. + * @id: device ID number, inside the adapter + * @readers: Initialized by the caller. Each call to open() in Read Only mode + * decreases this counter by one. + * @writers: Initialized by the caller. Each call to open() in Read/Write + * mode decreases this counter by one. + * @users: Initialized by the caller. Each call to open() in any mode + * decreases this counter by one. + * @wait_queue: wait queue, used to wait for certain events inside one of + * the DVB API callers + * @kernel_ioctl: callback function used to handle ioctl calls from userspace. + * @name: Name to be used for the device at the Media Controller + * @entity: pointer to struct media_entity associated with the device node + * @pads: pointer to struct media_pad associated with @entity; + * @priv: private data + * + * This structure is used by the DVB core (frontend, CA, net, demux) in + * order to create the device nodes. Usually, driver should not initialize + * this struct diretly. + */ struct dvb_device { struct list_head list_head; const struct file_operations *fops; @@ -109,19 +155,55 @@ struct dvb_device { void *priv; }; +/** + * dvb_register_adapter - Registers a new DVB adapter + * + * @adap: pointer to struct dvb_adapter + * @name: Adapter's name + * @module: initialized with THIS_MODULE at the caller + * @device: pointer to struct device that corresponds to the device driver + * @adapter_nums: Array with a list of the numbers for @dvb_register_adapter; + * to select among them. Typically, initialized with: + * DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums) + */ +int dvb_register_adapter(struct dvb_adapter *adap, const char *name, + struct module *module, struct device *device, + short *adapter_nums); -extern int dvb_register_adapter(struct dvb_adapter *adap, const char *name, - struct module *module, struct device *device, - short *adapter_nums); -extern int dvb_unregister_adapter (struct dvb_adapter *adap); - -extern int dvb_register_device (struct dvb_adapter *adap, - struct dvb_device **pdvbdev, - const struct dvb_device *template, - void *priv, - int type); +/** + * dvb_unregister_adapter - Unregisters a DVB adapter + * + * @adap: pointer to struct dvb_adapter + */ +int dvb_unregister_adapter(struct dvb_adapter *adap); -extern void dvb_unregister_device (struct dvb_device *dvbdev); +/** + * dvb_register_device - Registers a new DVB device + * + * @adap: pointer to struct dvb_adapter + * @pdvbdev: pointer to the place where the new struct dvb_device will be + * stored + * @template: Template used to create &pdvbdev; + * @device: pointer to struct device that corresponds to the device driver + * @adapter_nums: Array with a list of the numbers for @dvb_register_adapter; + * to select among them. Typically, initialized with: + * DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nums) + * @priv: private data + * @type: type of the device: DVB_DEVICE_SEC, DVB_DEVICE_FRONTEND, + * DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_CA, DVB_DEVICE_NET + */ +int dvb_register_device(struct dvb_adapter *adap, + struct dvb_device **pdvbdev, + const struct dvb_device *template, + void *priv, + int type); + +/** + * dvb_unregister_device - Unregisters a DVB device + * + * @dvbdev: pointer to struct dvb_device + */ +void dvb_unregister_device(struct dvb_device *dvbdev); #ifdef CONFIG_MEDIA_CONTROLLER_DVB void dvb_create_media_graph(struct dvb_adapter *adap); @@ -136,17 +218,17 @@ static inline void dvb_create_media_graph(struct dvb_adapter *adap) {} #define dvb_register_media_controller(a, b) {} #endif -extern int dvb_generic_open (struct inode *inode, struct file *file); -extern int dvb_generic_release (struct inode *inode, struct file *file); -extern long dvb_generic_ioctl (struct file *file, +int dvb_generic_open (struct inode *inode, struct file *file); +int dvb_generic_release (struct inode *inode, struct file *file); +long dvb_generic_ioctl (struct file *file, unsigned int cmd, unsigned long arg); /* we don't mess with video_usercopy() any more, we simply define out own dvb_usercopy(), which will hopefully become generic_usercopy() someday... */ -extern int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, - int (*func)(struct file *file, unsigned int cmd, void *arg)); +int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, + int (*func)(struct file *file, unsigned int cmd, void *arg)); /** generic DVB attach function. */ #ifdef CONFIG_MEDIA_ATTACH diff --git a/drivers/media/dvb-frontends/au8522_dig.c b/drivers/media/dvb-frontends/au8522_dig.c index b744a3f8d467..f956f13fb3dc 100644 --- a/drivers/media/dvb-frontends/au8522_dig.c +++ b/drivers/media/dvb-frontends/au8522_dig.c @@ -922,7 +922,7 @@ module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Enable verbose debug messages"); module_param(zv_mode, int, 0644); -MODULE_PARM_DESC(zv_mode, "Turn on/off ZeeVee modulator compatability mode (default:on).\n" +MODULE_PARM_DESC(zv_mode, "Turn on/off ZeeVee modulator compatibility mode (default:on).\n" "\t\ton - modified AU8522 QAM256 initialization.\n" "\t\tProvides faster lock when using ZeeVee modulator based sources"); diff --git a/drivers/media/dvb-frontends/cx24123.c b/drivers/media/dvb-frontends/cx24123.c index e18cf9e1185e..0fe7fb11124b 100644 --- a/drivers/media/dvb-frontends/cx24123.c +++ b/drivers/media/dvb-frontends/cx24123.c @@ -1011,7 +1011,7 @@ static int cx24123_tune(struct dvb_frontend *fe, static int cx24123_get_algo(struct dvb_frontend *fe) { - return 1; /* FE_ALGO_HW */ + return DVBFE_ALGO_HW; } static void cx24123_release(struct dvb_frontend *fe) diff --git a/drivers/media/dvb-frontends/horus3a.c b/drivers/media/dvb-frontends/horus3a.c index 5074305b289e..000606af70f7 100644 --- a/drivers/media/dvb-frontends/horus3a.c +++ b/drivers/media/dvb-frontends/horus3a.c @@ -285,6 +285,7 @@ static int horus3a_set_params(struct dvb_frontend *fe) rolloff = 20; break; case ROLLOFF_AUTO: + default: dev_err(&priv->i2c->dev, "horus3a: auto roll-off is not supported\n"); return -EINVAL; diff --git a/drivers/media/dvb-frontends/s921.c b/drivers/media/dvb-frontends/s921.c index b2d9fe13e1a0..d6a8fa63040b 100644 --- a/drivers/media/dvb-frontends/s921.c +++ b/drivers/media/dvb-frontends/s921.c @@ -466,7 +466,7 @@ static int s921_tune(struct dvb_frontend *fe, static int s921_get_algo(struct dvb_frontend *fe) { - return 1; /* FE_ALGO_HW */ + return DVBFE_ALGO_HW; } static void s921_release(struct dvb_frontend *fe) diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index d669547604cd..521bbf1b29bc 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -289,7 +289,8 @@ config VIDEO_SAA711X config VIDEO_TC358743 tristate "Toshiba TC358743 decoder" - depends on VIDEO_V4L2 && I2C + depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API + select HDMI ---help--- Support for the Toshiba TC358743 HDMI to MIPI CSI-2 bridge. diff --git a/drivers/media/i2c/adp1653.c b/drivers/media/i2c/adp1653.c index c70ababce954..5dd39775d6ca 100644 --- a/drivers/media/i2c/adp1653.c +++ b/drivers/media/i2c/adp1653.c @@ -465,7 +465,7 @@ static int adp1653_of_init(struct i2c_client *client, of_node_put(child); - pd->enable_gpio = devm_gpiod_get(&client->dev, "enable"); + pd->enable_gpio = devm_gpiod_get(&client->dev, "enable", GPIOD_OUT_LOW); if (!pd->enable_gpio) { dev_err(&client->dev, "Error getting GPIO\n"); return -EINVAL; diff --git a/drivers/media/i2c/adv7511.c b/drivers/media/i2c/adv7511.c index ef198cee8969..e4900df1140b 100644 --- a/drivers/media/i2c/adv7511.c +++ b/drivers/media/i2c/adv7511.c @@ -40,7 +40,7 @@ MODULE_PARM_DESC(debug, "debug level (0-2)"); MODULE_DESCRIPTION("Analog Devices ADV7511 HDMI Transmitter Device Driver"); MODULE_AUTHOR("Hans Verkuil"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL v2"); #define MASK_ADV7511_EDID_RDY_INT 0x04 #define MASK_ADV7511_MSEN_INT 0x40 diff --git a/drivers/media/i2c/tc358743.c b/drivers/media/i2c/tc358743.c index fe42c9a1cb78..9ef5baaf8646 100644 --- a/drivers/media/i2c/tc358743.c +++ b/drivers/media/i2c/tc358743.c @@ -870,7 +870,8 @@ static void tc358743_format_change(struct v4l2_subdev *sd) &timings, false); } - v4l2_subdev_notify_event(sd, &tc358743_ev_fmt); + if (sd->devnode) + v4l2_subdev_notify_event(sd, &tc358743_ev_fmt); } static void tc358743_init_interrupts(struct v4l2_subdev *sd) @@ -1681,7 +1682,6 @@ static const struct v4l2_ctrl_config tc358743_ctrl_audio_present = { #ifdef CONFIG_OF static void tc358743_gpio_reset(struct tc358743_state *state) { - gpiod_set_value(state->reset_gpio, 0); usleep_range(5000, 10000); gpiod_set_value(state->reset_gpio, 1); usleep_range(1000, 2000); @@ -1783,14 +1783,16 @@ static int tc358743_probe_of(struct tc358743_state *state) state->pdata.ths_trailcnt = 0x2; state->pdata.hstxvregcnt = 0; - state->reset_gpio = devm_gpiod_get(dev, "reset"); + state->reset_gpio = devm_gpiod_get_optional(dev, "reset", + GPIOD_OUT_LOW); if (IS_ERR(state->reset_gpio)) { dev_err(dev, "failed to get reset gpio\n"); ret = PTR_ERR(state->reset_gpio); goto disable_clk; } - tc358743_gpio_reset(state); + if (state->reset_gpio) + tc358743_gpio_reset(state); ret = 0; goto free_endpoint; @@ -1967,7 +1969,6 @@ MODULE_DEVICE_TABLE(i2c, tc358743_id); static struct i2c_driver tc358743_driver = { .driver = { - .owner = THIS_MODULE, .name = "tc358743", }, .probe = tc358743_probe, diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 4d8e01c7b1b2..153a46469814 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c @@ -282,9 +282,9 @@ __must_check int media_entity_pipeline_start(struct media_entity *entity, if (ret < 0 && ret != -ENOIOCTLCMD) { dev_dbg(entity->parent->dev, "link validation failed for \"%s\":%u -> \"%s\":%u, error %d\n", - entity->name, link->source->index, - link->sink->entity->name, - link->sink->index, ret); + link->source->entity->name, + link->source->index, + entity->name, link->sink->index, ret); goto error; } } diff --git a/drivers/media/pci/bt8xx/bttv-input.c b/drivers/media/pci/bt8xx/bttv-input.c index 67c8d6b2c335..a75c53da224a 100644 --- a/drivers/media/pci/bt8xx/bttv-input.c +++ b/drivers/media/pci/bt8xx/bttv-input.c @@ -194,21 +194,18 @@ static u32 bttv_rc5_decode(unsigned int code) static void bttv_rc5_timer_end(unsigned long data) { struct bttv_ir *ir = (struct bttv_ir *)data; - struct timeval tv; + ktime_t tv; u32 gap, rc5, scancode; u8 toggle, command, system; /* get time */ - do_gettimeofday(&tv); + tv = ktime_get(); + gap = ktime_to_us(ktime_sub(tv, ir->base_time)); /* avoid overflow with gap >1s */ - if (tv.tv_sec - ir->base_time.tv_sec > 1) { + if (gap > USEC_PER_SEC) { gap = 200000; - } else { - gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + - tv.tv_usec - ir->base_time.tv_usec; } - /* signal we're ready to start a new code */ ir->active = false; @@ -249,7 +246,7 @@ static void bttv_rc5_timer_end(unsigned long data) static int bttv_rc5_irq(struct bttv *btv) { struct bttv_ir *ir = btv->remote; - struct timeval tv; + ktime_t tv; u32 gpio; u32 gap; unsigned long current_jiffies; @@ -259,14 +256,12 @@ static int bttv_rc5_irq(struct bttv *btv) /* get time of bit */ current_jiffies = jiffies; - do_gettimeofday(&tv); + tv = ktime_get(); + gap = ktime_to_us(ktime_sub(tv, ir->base_time)); /* avoid overflow with gap >1s */ - if (tv.tv_sec - ir->base_time.tv_sec > 1) { + if (gap > USEC_PER_SEC) { gap = 200000; - } else { - gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) + - tv.tv_usec - ir->base_time.tv_usec; } dprintk("RC5 IRQ: gap %d us for %s\n", diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index a444cfb35c0b..31bf79d3b0d2 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -140,7 +140,7 @@ struct bttv_ir { bool rc5_gpio; /* Is RC5 legacy GPIO enabled? */ u32 last_bit; /* last raw bit seen */ u32 code; /* raw code under construction */ - struct timeval base_time; /* time of last seen code */ + ktime_t base_time; /* time of last seen code */ bool active; /* building raw code */ }; diff --git a/drivers/media/pci/cobalt/cobalt-irq.c b/drivers/media/pci/cobalt/cobalt-irq.c index dd4bff9cf339..d1f5898d11ba 100644 --- a/drivers/media/pci/cobalt/cobalt-irq.c +++ b/drivers/media/pci/cobalt/cobalt-irq.c @@ -139,7 +139,7 @@ done: also know about dropped frames. */ cb->vb.v4l2_buf.sequence = s->sequence++; vb2_buffer_done(&cb->vb, (skip || s->unstable_frame) ? - VB2_BUF_STATE_QUEUED : VB2_BUF_STATE_DONE); + VB2_BUF_STATE_REQUEUEING : VB2_BUF_STATE_DONE); } irqreturn_t cobalt_irq_handler(int irq, void *dev_id) diff --git a/drivers/media/pci/tw68/tw68-core.c b/drivers/media/pci/tw68/tw68-core.c index c135165a8b26..04706cc9b818 100644 --- a/drivers/media/pci/tw68/tw68-core.c +++ b/drivers/media/pci/tw68/tw68-core.c @@ -37,6 +37,7 @@ #include <linux/delay.h> #include <linux/mutex.h> #include <linux/dma-mapping.h> +#include <linux/pci_ids.h> #include <linux/pm.h> #include <media/v4l2-dev.h> @@ -70,13 +71,13 @@ static atomic_t tw68_instance = ATOMIC_INIT(0); * added under vendor 0x1797 (Techwell Inc.) as subsystem IDs. */ static const struct pci_device_id tw68_pci_tbl[] = { - {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6800)}, - {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6801)}, - {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6804)}, - {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6816_1)}, - {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6816_2)}, - {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6816_3)}, - {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6816_4)}, + {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6800)}, + {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6801)}, + {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6804)}, + {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_1)}, + {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_2)}, + {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_3)}, + {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_TECHWELL_6816_4)}, {0,} }; @@ -263,15 +264,15 @@ static int tw68_initdev(struct pci_dev *pci_dev, } switch (pci_id->device) { - case PCI_DEVICE_ID_6800: /* TW6800 */ + case PCI_DEVICE_ID_TECHWELL_6800: /* TW6800 */ dev->vdecoder = TW6800; dev->board_virqmask = TW68_VID_INTS; break; - case PCI_DEVICE_ID_6801: /* Video decoder for TW6802 */ + case PCI_DEVICE_ID_TECHWELL_6801: /* Video decoder for TW6802 */ dev->vdecoder = TW6801; dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX; break; - case PCI_DEVICE_ID_6804: /* Video decoder for TW6804 */ + case PCI_DEVICE_ID_TECHWELL_6804: /* Video decoder for TW6804 */ dev->vdecoder = TW6804; dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX; break; diff --git a/drivers/media/pci/tw68/tw68.h b/drivers/media/pci/tw68/tw68.h index 93f2335e004b..ef51e4d48866 100644 --- a/drivers/media/pci/tw68/tw68.h +++ b/drivers/media/pci/tw68/tw68.h @@ -42,22 +42,6 @@ #define UNSET (-1U) -/* system vendor and device ID's */ -#define PCI_VENDOR_ID_TECHWELL 0x1797 -#define PCI_DEVICE_ID_6800 0x6800 -#define PCI_DEVICE_ID_6801 0x6801 -#define PCI_DEVICE_ID_AUDIO2 0x6802 -#define PCI_DEVICE_ID_TS3 0x6803 -#define PCI_DEVICE_ID_6804 0x6804 -#define PCI_DEVICE_ID_AUDIO5 0x6805 -#define PCI_DEVICE_ID_TS6 0x6806 - -/* tw6816 based cards */ -#define PCI_DEVICE_ID_6816_1 0x6810 -#define PCI_DEVICE_ID_6816_2 0x6811 -#define PCI_DEVICE_ID_6816_3 0x6812 -#define PCI_DEVICE_ID_6816_4 0x6813 - #define TW68_NORMS ( \ V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM | \ V4L2_STD_PAL_M | V4L2_STD_PAL_Nc | V4L2_STD_PAL_60) diff --git a/drivers/media/pci/zoran/zoran_device.c b/drivers/media/pci/zoran/zoran_device.c index 40119b3c52c1..4d47ddac97dc 100644 --- a/drivers/media/pci/zoran/zoran_device.c +++ b/drivers/media/pci/zoran/zoran_device.c @@ -31,6 +31,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/vmalloc.h> +#include <linux/ktime.h> #include <linux/interrupt.h> #include <linux/proc_fs.h> @@ -181,20 +182,11 @@ dump_guests (struct zoran *zr) } } -static inline unsigned long -get_time (void) -{ - struct timeval tv; - - do_gettimeofday(&tv); - return (1000000 * tv.tv_sec + tv.tv_usec); -} - void detect_guest_activity (struct zoran *zr) { int timeout, i, j, res, guest[8], guest0[8], change[8][3]; - unsigned long t0, t1; + ktime_t t0, t1; dump_guests(zr); printk(KERN_INFO "%s: Detecting guests activity, please wait...\n", @@ -205,15 +197,15 @@ detect_guest_activity (struct zoran *zr) timeout = 0; j = 0; - t0 = get_time(); + t0 = ktime_get(); while (timeout < 10000) { udelay(10); timeout++; for (i = 1; (i < 8) && (j < 8); i++) { res = post_office_read(zr, i, 0); if (res != guest[i]) { - t1 = get_time(); - change[j][0] = (t1 - t0); + t1 = ktime_get(); + change[j][0] = ktime_to_us(ktime_sub(t1, t0)); t0 = t1; change[j][1] = i; change[j][2] = res; diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 3adf686e005d..dc75694ac12d 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -86,7 +86,7 @@ config VIDEO_M32R_AR_M64278 config VIDEO_OMAP3 tristate "OMAP 3 Camera support" depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 - depends on HAS_DMA + depends on HAS_DMA && OF depends on OMAP_IOMMU select ARM_DMA_USE_IOMMU select VIDEOBUF2_DMA_CONTIG diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c index 04310cd35bc1..a4654e0c104d 100644 --- a/drivers/media/platform/coda/coda-common.c +++ b/drivers/media/platform/coda/coda-common.c @@ -2181,7 +2181,7 @@ static int coda_probe(struct platform_device *pdev) /* Get IRAM pool from device tree or platform data */ pool = of_gen_pool_get(np, "iram", 0); if (!pool && pdata) - pool = gen_pool_get(pdata->iram_dev); + pool = gen_pool_get(pdata->iram_dev, NULL); if (!pool) { dev_err(&pdev->dev, "iram pool not available\n"); return -ENOMEM; diff --git a/drivers/media/platform/exynos4-is/fimc-m2m.c b/drivers/media/platform/exynos4-is/fimc-m2m.c index 0ad1b6f84a27..d2bfe7c2a6b4 100644 --- a/drivers/media/platform/exynos4-is/fimc-m2m.c +++ b/drivers/media/platform/exynos4-is/fimc-m2m.c @@ -188,7 +188,7 @@ static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, if (IS_ERR(f)) return PTR_ERR(f); /* - * Return number of non-contigous planes (plane buffers) + * Return number of non-contiguous planes (plane buffers) * depending on the configured color format. */ if (!f->fmt) diff --git a/drivers/media/platform/omap/omap_vout.c b/drivers/media/platform/omap/omap_vout.c index 7feb6394f111..70c28d19ea04 100644 --- a/drivers/media/platform/omap/omap_vout.c +++ b/drivers/media/platform/omap/omap_vout.c @@ -865,7 +865,7 @@ static void omap_vout_vm_close(struct vm_area_struct *vma) vout->mmap_count--; } -static struct vm_operations_struct omap_vout_vm_ops = { +static const struct vm_operations_struct omap_vout_vm_ops = { .open = omap_vout_vm_open, .close = omap_vout_vm_close, }; diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index 12be830d704f..56e683b19a73 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -101,7 +101,6 @@ static const struct isp_res_mapping isp_res_maps[] = { 0x0000, /* csi2a, len 0x0170 */ 0x0170, /* csiphy2, len 0x000c */ }, - .syscon_offset = 0xdc, .phy_type = ISP_PHY_TYPE_3430, }, { @@ -124,7 +123,6 @@ static const struct isp_res_mapping isp_res_maps[] = { 0x0570, /* csiphy1, len 0x000c */ 0x05c0, /* csi2c, len 0x0040 (2nd area) */ }, - .syscon_offset = 0x2f0, .phy_type = ISP_PHY_TYPE_3630, }, }; @@ -1796,47 +1794,6 @@ static void isp_unregister_entities(struct isp_device *isp) media_device_unregister(&isp->media_dev); } -/* - * isp_register_subdev - Register a sub-device - * @isp: OMAP3 ISP device - * @isp_subdev: platform data related to a sub-device - * - * Register an I2C sub-device which has not been registered by other - * means (such as the Device Tree). - * - * Return a pointer to the sub-device if it has been successfully - * registered, or NULL otherwise. - */ -static struct v4l2_subdev * -isp_register_subdev(struct isp_device *isp, - struct isp_platform_subdev *isp_subdev) -{ - struct i2c_adapter *adapter; - struct v4l2_subdev *sd; - - if (isp_subdev->board_info == NULL) - return NULL; - - adapter = i2c_get_adapter(isp_subdev->i2c_adapter_id); - if (adapter == NULL) { - dev_err(isp->dev, - "%s: Unable to get I2C adapter %d for device %s\n", - __func__, isp_subdev->i2c_adapter_id, - isp_subdev->board_info->type); - return NULL; - } - - sd = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter, - isp_subdev->board_info, NULL); - if (sd == NULL) { - dev_err(isp->dev, "%s: Unable to register subdev %s\n", - __func__, isp_subdev->board_info->type); - return NULL; - } - - return sd; -} - static int isp_link_entity( struct isp_device *isp, struct media_entity *entity, enum isp_interface_type interface) @@ -1910,8 +1867,6 @@ static int isp_link_entity( static int isp_register_entities(struct isp_device *isp) { - struct isp_platform_data *pdata = isp->pdata; - struct isp_platform_subdev *isp_subdev; int ret; isp->media_dev.dev = isp->dev; @@ -1968,37 +1923,6 @@ static int isp_register_entities(struct isp_device *isp) if (ret < 0) goto done; - /* - * Device Tree --- the external sub-devices will be registered - * later. The same goes for the sub-device node registration. - */ - if (isp->dev->of_node) - return 0; - - /* Register external entities */ - for (isp_subdev = pdata ? pdata->subdevs : NULL; - isp_subdev && isp_subdev->board_info; isp_subdev++) { - struct v4l2_subdev *sd; - - sd = isp_register_subdev(isp, isp_subdev); - - /* - * No bus information --- this is either a flash or a - * lens subdev. - */ - if (!sd || !isp_subdev->bus) - continue; - - sd->host_priv = isp_subdev->bus; - - ret = isp_link_entity(isp, &sd->entity, - isp_subdev->bus->interface); - if (ret < 0) - goto done; - } - - ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); - done: if (ret < 0) isp_unregister_entities(isp); @@ -2402,33 +2326,24 @@ static int isp_probe(struct platform_device *pdev) return -ENOMEM; } - if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { - ret = of_property_read_u32(pdev->dev.of_node, "ti,phy-type", - &isp->phy_type); - if (ret) - return ret; + ret = of_property_read_u32(pdev->dev.of_node, "ti,phy-type", + &isp->phy_type); + if (ret) + return ret; - isp->syscon = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, - "syscon"); - if (IS_ERR(isp->syscon)) - return PTR_ERR(isp->syscon); + isp->syscon = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "syscon"); + if (IS_ERR(isp->syscon)) + return PTR_ERR(isp->syscon); - ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1, - &isp->syscon_offset); - if (ret) - return ret; + ret = of_property_read_u32_index(pdev->dev.of_node, "syscon", 1, + &isp->syscon_offset); + if (ret) + return ret; - ret = isp_of_parse_nodes(&pdev->dev, &isp->notifier); - if (ret < 0) - return ret; - } else { - isp->pdata = pdev->dev.platform_data; - isp->syscon = syscon_regmap_lookup_by_pdevname("syscon.0"); - if (IS_ERR(isp->syscon)) - return PTR_ERR(isp->syscon); - dev_warn(&pdev->dev, - "Platform data support is deprecated! Please move to DT now!\n"); - } + ret = isp_of_parse_nodes(&pdev->dev, &isp->notifier); + if (ret < 0) + return ret; isp->autoidle = autoidle; @@ -2507,11 +2422,6 @@ static int isp_probe(struct platform_device *pdev) goto error_isp; } - if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node) { - isp->syscon_offset = isp_res_maps[m].syscon_offset; - isp->phy_type = isp_res_maps[m].phy_type; - } - for (i = 1; i < OMAP3_ISP_IOMEM_CSI2A_REGS1; i++) isp->mmio_base[i] = isp->mmio_base[0] + isp_res_maps[m].offset[i]; @@ -2555,15 +2465,12 @@ static int isp_probe(struct platform_device *pdev) if (ret < 0) goto error_modules; - if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { - isp->notifier.bound = isp_subdev_notifier_bound; - isp->notifier.complete = isp_subdev_notifier_complete; + isp->notifier.bound = isp_subdev_notifier_bound; + isp->notifier.complete = isp_subdev_notifier_complete; - ret = v4l2_async_notifier_register(&isp->v4l2_dev, - &isp->notifier); - if (ret) - goto error_register_entities; - } + ret = v4l2_async_notifier_register(&isp->v4l2_dev, &isp->notifier); + if (ret) + goto error_register_entities; isp_core_init(isp, 1); omap3isp_put(isp); diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index e579943175c4..5acc2e6511a5 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h @@ -17,7 +17,6 @@ #ifndef OMAP3_ISP_CORE_H #define OMAP3_ISP_CORE_H -#include <media/omap3isp.h> #include <media/v4l2-async.h> #include <media/v4l2-device.h> #include <linux/clk-provider.h> @@ -27,6 +26,7 @@ #include <linux/platform_device.h> #include <linux/wait.h> +#include "omap3isp.h" #include "ispstat.h" #include "ispccdc.h" #include "ispreg.h" @@ -101,15 +101,11 @@ struct regmap; * struct isp_res_mapping - Map ISP io resources to ISP revision. * @isp_rev: ISP_REVISION_x_x * @offset: register offsets of various ISP sub-blocks - * @syscon_offset: offset of the syscon register for 343x / 3630 - * (CONTROL_CSIRXFE / CONTROL_CAMERA_PHY_CTRL, respectively) - * from the syscon base address * @phy_type: ISP_PHY_TYPE_{3430,3630} */ struct isp_res_mapping { u32 isp_rev; u32 offset[OMAP3_ISP_IOMEM_LAST]; - u32 syscon_offset; u32 phy_type; }; @@ -184,7 +180,6 @@ struct isp_device { u32 revision; /* platform HW resources */ - struct isp_platform_data *pdata; unsigned int irq_num; void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST]; diff --git a/drivers/media/platform/omap3isp/ispcsiphy.h b/drivers/media/platform/omap3isp/ispcsiphy.h index e17c88beab92..28b63b28f9f7 100644 --- a/drivers/media/platform/omap3isp/ispcsiphy.h +++ b/drivers/media/platform/omap3isp/ispcsiphy.h @@ -17,7 +17,7 @@ #ifndef OMAP3_ISP_CSI_PHY_H #define OMAP3_ISP_CSI_PHY_H -#include <media/omap3isp.h> +#include "omap3isp.h" struct isp_csi2_device; struct regulator; diff --git a/drivers/media/platform/omap3isp/ispvideo.c b/drivers/media/platform/omap3isp/ispvideo.c index d285af18df7f..41bb8df91f72 100644 --- a/drivers/media/platform/omap3isp/ispvideo.c +++ b/drivers/media/platform/omap3isp/ispvideo.c @@ -1018,8 +1018,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) pipe->entities = 0; - if (video->isp->pdata && video->isp->pdata->set_constraints) - video->isp->pdata->set_constraints(video->isp, true); + /* TODO: Implement PM QoS */ pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]); pipe->max_rate = pipe->l3_ick; @@ -1100,8 +1099,7 @@ err_set_stream: err_check_format: media_entity_pipeline_stop(&video->video.entity); err_pipeline_start: - if (video->isp->pdata && video->isp->pdata->set_constraints) - video->isp->pdata->set_constraints(video->isp, false); + /* TODO: Implement PM QoS */ /* The DMA queue must be emptied here, otherwise CCDC interrupts that * will get triggered the next time the CCDC is powered up will try to * access buffers that might have been freed but still present in the @@ -1161,8 +1159,7 @@ isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) video->queue = NULL; video->error = false; - if (video->isp->pdata && video->isp->pdata->set_constraints) - video->isp->pdata->set_constraints(video->isp, false); + /* TODO: Implement PM QoS */ media_entity_pipeline_stop(&video->video.entity); done: diff --git a/drivers/media/platform/omap3isp/omap3isp.h b/drivers/media/platform/omap3isp/omap3isp.h new file mode 100644 index 000000000000..190e259a6a2d --- /dev/null +++ b/drivers/media/platform/omap3isp/omap3isp.h @@ -0,0 +1,132 @@ +/* + * omap3isp.h + * + * TI OMAP3 ISP - Bus Configuration + * + * Copyright (C) 2011 Nokia Corporation + * + * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com> + * Sakari Ailus <sakari.ailus@iki.fi> + * + * 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. + * + * 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. + */ + +#ifndef __OMAP3ISP_H__ +#define __OMAP3ISP_H__ + +enum isp_interface_type { + ISP_INTERFACE_PARALLEL, + ISP_INTERFACE_CSI2A_PHY2, + ISP_INTERFACE_CCP2B_PHY1, + ISP_INTERFACE_CCP2B_PHY2, + ISP_INTERFACE_CSI2C_PHY1, +}; + +/** + * struct isp_parallel_cfg - Parallel interface configuration + * @data_lane_shift: Data lane shifter + * 0 - CAMEXT[13:0] -> CAM[13:0] + * 1 - CAMEXT[13:2] -> CAM[11:0] + * 2 - CAMEXT[13:4] -> CAM[9:0] + * 3 - CAMEXT[13:6] -> CAM[7:0] + * @clk_pol: Pixel clock polarity + * 0 - Sample on rising edge, 1 - Sample on falling edge + * @hs_pol: Horizontal synchronization polarity + * 0 - Active high, 1 - Active low + * @vs_pol: Vertical synchronization polarity + * 0 - Active high, 1 - Active low + * @fld_pol: Field signal polarity + * 0 - Positive, 1 - Negative + * @data_pol: Data polarity + * 0 - Normal, 1 - One's complement + */ +struct isp_parallel_cfg { + unsigned int data_lane_shift:2; + unsigned int clk_pol:1; + unsigned int hs_pol:1; + unsigned int vs_pol:1; + unsigned int fld_pol:1; + unsigned int data_pol:1; +}; + +enum { + ISP_CCP2_PHY_DATA_CLOCK = 0, + ISP_CCP2_PHY_DATA_STROBE = 1, +}; + +enum { + ISP_CCP2_MODE_MIPI = 0, + ISP_CCP2_MODE_CCP2 = 1, +}; + +/** + * struct isp_csiphy_lane: CCP2/CSI2 lane position and polarity + * @pos: position of the lane + * @pol: polarity of the lane + */ +struct isp_csiphy_lane { + u8 pos; + u8 pol; +}; + +#define ISP_CSIPHY1_NUM_DATA_LANES 1 +#define ISP_CSIPHY2_NUM_DATA_LANES 2 + +/** + * struct isp_csiphy_lanes_cfg - CCP2/CSI2 lane configuration + * @data: Configuration of one or two data lanes + * @clk: Clock lane configuration + */ +struct isp_csiphy_lanes_cfg { + struct isp_csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES]; + struct isp_csiphy_lane clk; +}; + +/** + * struct isp_ccp2_cfg - CCP2 interface configuration + * @strobe_clk_pol: Strobe/clock polarity + * 0 - Non Inverted, 1 - Inverted + * @crc: Enable the cyclic redundancy check + * @ccp2_mode: Enable CCP2 compatibility mode + * ISP_CCP2_MODE_MIPI - MIPI-CSI1 mode + * ISP_CCP2_MODE_CCP2 - CCP2 mode + * @phy_layer: Physical layer selection + * ISP_CCP2_PHY_DATA_CLOCK - Data/clock physical layer + * ISP_CCP2_PHY_DATA_STROBE - Data/strobe physical layer + * @vpclk_div: Video port output clock control + */ +struct isp_ccp2_cfg { + unsigned int strobe_clk_pol:1; + unsigned int crc:1; + unsigned int ccp2_mode:1; + unsigned int phy_layer:1; + unsigned int vpclk_div:2; + struct isp_csiphy_lanes_cfg lanecfg; +}; + +/** + * struct isp_csi2_cfg - CSI2 interface configuration + * @crc: Enable the cyclic redundancy check + */ +struct isp_csi2_cfg { + unsigned crc:1; + struct isp_csiphy_lanes_cfg lanecfg; +}; + +struct isp_bus_cfg { + enum isp_interface_type interface; + union { + struct isp_parallel_cfg parallel; + struct isp_ccp2_cfg ccp2; + struct isp_csi2_cfg csi2; + } bus; /* gcc < 4.6.0 chokes on anonymous union initializers */ +}; + +#endif /* __OMAP3ISP_H__ */ diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c index 2abf0473f095..e5cb30e1f718 100644 --- a/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c +++ b/drivers/media/platform/s5p-mfc/s5p_mfc_opr_v6.c @@ -1736,7 +1736,7 @@ static void s5p_mfc_try_run_v6(struct s5p_mfc_dev *dev) mfc_debug(1, "New context: %d\n", new_ctx); ctx = dev->ctx[new_ctx]; - mfc_debug(1, "Seting new context to %p\n", ctx); + mfc_debug(1, "Setting new context to %p\n", ctx); /* Got context to run in ctx */ mfc_debug(1, "ctx->dst_queue_cnt=%d ctx->dpb_count=%d ctx->src_queue_cnt=%d\n", ctx->dst_queue_cnt, ctx->pb_count, ctx->src_queue_cnt); diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index db7700b0af7c..71dd71c0bd1f 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -98,6 +98,7 @@ #define VNMC_INF_YUV10_BT656 (2 << 16) #define VNMC_INF_YUV10_BT601 (3 << 16) #define VNMC_INF_YUV16 (5 << 16) +#define VNMC_INF_RGB888 (6 << 16) #define VNMC_VUP (1 << 10) #define VNMC_IM_ODD (0 << 3) #define VNMC_IM_ODD_EVEN (1 << 3) @@ -540,6 +541,9 @@ static int rcar_vin_videobuf_setup(struct vb2_queue *vq, unsigned int bytes_per_line; int ret; + if (fmt->fmt.pix.sizeimage < icd->sizeimage) + return -EINVAL; + xlate = soc_camera_xlate_by_fourcc(icd, fmt->fmt.pix.pixelformat); if (!xlate) @@ -589,7 +593,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) struct soc_camera_device *icd = priv->ici.icd; struct rcar_vin_cam *cam = icd->host_priv; u32 vnmc, dmr, interrupts; - bool progressive = false, output_is_yuv = false; + bool progressive = false, output_is_yuv = false, input_is_yuv = false; switch (priv->field) { case V4L2_FIELD_TOP: @@ -623,16 +627,22 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) case MEDIA_BUS_FMT_YUYV8_1X16: /* BT.601/BT.1358 16bit YCbCr422 */ vnmc |= VNMC_INF_YUV16; + input_is_yuv = true; break; case MEDIA_BUS_FMT_YUYV8_2X8: /* BT.656 8bit YCbCr422 or BT.601 8bit YCbCr422 */ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ? VNMC_INF_YUV8_BT656 : VNMC_INF_YUV8_BT601; + input_is_yuv = true; + break; + case MEDIA_BUS_FMT_RGB888_1X24: + vnmc |= VNMC_INF_RGB888; break; case MEDIA_BUS_FMT_YUYV10_2X10: /* BT.656 10bit YCbCr422 or BT.601 10bit YCbCr422 */ vnmc |= priv->pdata_flags & RCAR_VIN_BT656 ? VNMC_INF_YUV10_BT656 : VNMC_INF_YUV10_BT601; + input_is_yuv = true; break; default: break; @@ -676,7 +686,7 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) vnmc |= VNMC_VUP; /* If input and output use the same colorspace, use bypass mode */ - if (output_is_yuv) + if (input_is_yuv == output_is_yuv) vnmc |= VNMC_BPS; /* progressive or interlaced mode */ @@ -1423,6 +1433,7 @@ static int rcar_vin_get_formats(struct soc_camera_device *icd, unsigned int idx, case MEDIA_BUS_FMT_YUYV8_1X16: case MEDIA_BUS_FMT_YUYV8_2X8: case MEDIA_BUS_FMT_YUYV10_2X10: + case MEDIA_BUS_FMT_RGB888_1X24: if (cam->extra_fmt) break; @@ -1783,6 +1794,7 @@ static int rcar_vin_querycap(struct soc_camera_host *ici, strlcpy(cap->card, "R_Car_VIN", sizeof(cap->card)); cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s%d", DRV_NAME, ici->nr); return 0; } diff --git a/drivers/media/platform/sti/c8sectpfe/Kconfig b/drivers/media/platform/sti/c8sectpfe/Kconfig index 1b1110d7374f..641ad8f34956 100644 --- a/drivers/media/platform/sti/c8sectpfe/Kconfig +++ b/drivers/media/platform/sti/c8sectpfe/Kconfig @@ -2,7 +2,6 @@ config DVB_C8SECTPFE tristate "STMicroelectronics C8SECTPFE DVB support" depends on PINCTRL && DVB_CORE && I2C depends on ARCH_STI || ARCH_MULTIPLATFORM || COMPILE_TEST - select LIBELF_32 select FW_LOADER select FW_LOADER_USER_HELPER_FALLBACK select DEBUG_FS diff --git a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c index 1586a1e6836d..486aef50d99b 100644 --- a/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c +++ b/drivers/media/platform/sti/c8sectpfe/c8sectpfe-core.c @@ -585,9 +585,9 @@ static int configure_memdma_and_inputblock(struct c8sectpfei *fei, writel(tsin->pid_buffer_busaddr, fei->io + PIDF_BASE(tsin->tsin_id)); - dev_info(fei->dev, "chan=%d PIDF_BASE=0x%x pid_bus_addr=0x%x\n", + dev_info(fei->dev, "chan=%d PIDF_BASE=0x%x pid_bus_addr=%pad\n", tsin->tsin_id, readl(fei->io + PIDF_BASE(tsin->tsin_id)), - tsin->pid_buffer_busaddr); + &tsin->pid_buffer_busaddr); /* Configure and enable HW PID filtering */ diff --git a/drivers/media/rc/ir-rc5-decoder.c b/drivers/media/rc/ir-rc5-decoder.c index 8939ebd74391..84fa6e9b59a1 100644 --- a/drivers/media/rc/ir-rc5-decoder.c +++ b/drivers/media/rc/ir-rc5-decoder.c @@ -184,125 +184,9 @@ out: return -EINVAL; } -static struct ir_raw_timings_manchester ir_rc5_timings = { - .leader = RC5_UNIT, - .pulse_space_start = 0, - .clock = RC5_UNIT, - .trailer_space = RC5_UNIT * 10, -}; - -static struct ir_raw_timings_manchester ir_rc5x_timings[2] = { - { - .leader = RC5_UNIT, - .pulse_space_start = 0, - .clock = RC5_UNIT, - .trailer_space = RC5X_SPACE, - }, - { - .clock = RC5_UNIT, - .trailer_space = RC5_UNIT * 10, - }, -}; - -static struct ir_raw_timings_manchester ir_rc5_sz_timings = { - .leader = RC5_UNIT, - .pulse_space_start = 0, - .clock = RC5_UNIT, - .trailer_space = RC5_UNIT * 10, -}; - -static int ir_rc5_validate_filter(const struct rc_scancode_filter *scancode, - unsigned int important_bits) -{ - /* all important bits of scancode should be set in mask */ - if (~scancode->mask & important_bits) - return -EINVAL; - /* extra bits in mask should be zero in data */ - if (scancode->mask & scancode->data & ~important_bits) - return -EINVAL; - return 0; -} - -/** - * ir_rc5_encode() - Encode a scancode as a stream of raw events - * - * @protocols: allowed protocols - * @scancode: scancode filter describing scancode (helps distinguish between - * protocol subtypes when scancode is ambiguous) - * @events: array of raw ir events to write into - * @max: maximum size of @events - * - * Returns: The number of events written. - * -ENOBUFS if there isn't enough space in the array to fit the - * encoding. In this case all @max events will have been written. - * -EINVAL if the scancode is ambiguous or invalid. - */ -static int ir_rc5_encode(u64 protocols, - const struct rc_scancode_filter *scancode, - struct ir_raw_event *events, unsigned int max) -{ - int ret; - struct ir_raw_event *e = events; - unsigned int data, xdata, command, commandx, system; - - /* Detect protocol and convert scancode to raw data */ - if (protocols & RC_BIT_RC5 && - !ir_rc5_validate_filter(scancode, 0x1f7f)) { - /* decode scancode */ - command = (scancode->data & 0x003f) >> 0; - commandx = (scancode->data & 0x0040) >> 6; - system = (scancode->data & 0x1f00) >> 8; - /* encode data */ - data = !commandx << 12 | system << 6 | command; - - /* Modulate the data */ - ret = ir_raw_gen_manchester(&e, max, &ir_rc5_timings, RC5_NBITS, - data); - if (ret < 0) - return ret; - } else if (protocols & RC_BIT_RC5X && - !ir_rc5_validate_filter(scancode, 0x1f7f3f)) { - /* decode scancode */ - xdata = (scancode->data & 0x00003f) >> 0; - command = (scancode->data & 0x003f00) >> 8; - commandx = (scancode->data & 0x004000) >> 14; - system = (scancode->data & 0x1f0000) >> 16; - /* commandx and system overlap, bits must match when encoded */ - if (commandx == (system & 0x1)) - return -EINVAL; - /* encode data */ - data = 1 << 18 | system << 12 | command << 6 | xdata; - - /* Modulate the data */ - ret = ir_raw_gen_manchester(&e, max, &ir_rc5x_timings[0], - CHECK_RC5X_NBITS, - data >> (RC5X_NBITS-CHECK_RC5X_NBITS)); - if (ret < 0) - return ret; - ret = ir_raw_gen_manchester(&e, max - (e - events), - &ir_rc5x_timings[1], - RC5X_NBITS - CHECK_RC5X_NBITS, - data); - if (ret < 0) - return ret; - } else if (protocols & RC_BIT_RC5_SZ && - !ir_rc5_validate_filter(scancode, 0x2fff)) { - /* RC5-SZ scancode is raw enough for Manchester as it is */ - ret = ir_raw_gen_manchester(&e, max, &ir_rc5_sz_timings, - RC5_SZ_NBITS, scancode->data & 0x2fff); - if (ret < 0) - return ret; - } else { - return -EINVAL; - } - - return e - events; -} - static struct ir_raw_handler rc5_handler = { .protocols = RC_BIT_RC5 | RC_BIT_RC5X | RC_BIT_RC5_SZ, .decode = ir_rc5_decode, - .encode = ir_rc5_encode, }; static int __init ir_rc5_decode_init(void) diff --git a/drivers/media/rc/ir-rc6-decoder.c b/drivers/media/rc/ir-rc6-decoder.c index f9c70baf6e0c..d16bc67af732 100644 --- a/drivers/media/rc/ir-rc6-decoder.c +++ b/drivers/media/rc/ir-rc6-decoder.c @@ -291,133 +291,11 @@ out: return -EINVAL; } -static struct ir_raw_timings_manchester ir_rc6_timings[4] = { - { - .leader = RC6_PREFIX_PULSE, - .pulse_space_start = 0, - .clock = RC6_UNIT, - .invert = 1, - .trailer_space = RC6_PREFIX_SPACE, - }, - { - .clock = RC6_UNIT, - .invert = 1, - }, - { - .clock = RC6_UNIT * 2, - .invert = 1, - }, - { - .clock = RC6_UNIT, - .invert = 1, - .trailer_space = RC6_SUFFIX_SPACE, - }, -}; - -static int ir_rc6_validate_filter(const struct rc_scancode_filter *scancode, - unsigned int important_bits) -{ - /* all important bits of scancode should be set in mask */ - if (~scancode->mask & important_bits) - return -EINVAL; - /* extra bits in mask should be zero in data */ - if (scancode->mask & scancode->data & ~important_bits) - return -EINVAL; - return 0; -} - -/** - * ir_rc6_encode() - Encode a scancode as a stream of raw events - * - * @protocols: allowed protocols - * @scancode: scancode filter describing scancode (helps distinguish between - * protocol subtypes when scancode is ambiguous) - * @events: array of raw ir events to write into - * @max: maximum size of @events - * - * Returns: The number of events written. - * -ENOBUFS if there isn't enough space in the array to fit the - * encoding. In this case all @max events will have been written. - * -EINVAL if the scancode is ambiguous or invalid. - */ -static int ir_rc6_encode(u64 protocols, - const struct rc_scancode_filter *scancode, - struct ir_raw_event *events, unsigned int max) -{ - int ret; - struct ir_raw_event *e = events; - - if (protocols & RC_BIT_RC6_0 && - !ir_rc6_validate_filter(scancode, 0xffff)) { - - /* Modulate the preamble */ - ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0); - if (ret < 0) - return ret; - - /* Modulate the header (Start Bit & Mode-0) */ - ret = ir_raw_gen_manchester(&e, max - (e - events), - &ir_rc6_timings[1], - RC6_HEADER_NBITS, (1 << 3)); - if (ret < 0) - return ret; - - /* Modulate Trailer Bit */ - ret = ir_raw_gen_manchester(&e, max - (e - events), - &ir_rc6_timings[2], 1, 0); - if (ret < 0) - return ret; - - /* Modulate rest of the data */ - ret = ir_raw_gen_manchester(&e, max - (e - events), - &ir_rc6_timings[3], RC6_0_NBITS, - scancode->data); - if (ret < 0) - return ret; - - } else if (protocols & (RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | - RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE) && - !ir_rc6_validate_filter(scancode, 0x8fffffff)) { - - /* Modulate the preamble */ - ret = ir_raw_gen_manchester(&e, max, &ir_rc6_timings[0], 0, 0); - if (ret < 0) - return ret; - - /* Modulate the header (Start Bit & Header-version 6 */ - ret = ir_raw_gen_manchester(&e, max - (e - events), - &ir_rc6_timings[1], - RC6_HEADER_NBITS, (1 << 3 | 6)); - if (ret < 0) - return ret; - - /* Modulate Trailer Bit */ - ret = ir_raw_gen_manchester(&e, max - (e - events), - &ir_rc6_timings[2], 1, 0); - if (ret < 0) - return ret; - - /* Modulate rest of the data */ - ret = ir_raw_gen_manchester(&e, max - (e - events), - &ir_rc6_timings[3], - fls(scancode->mask), - scancode->data); - if (ret < 0) - return ret; - - } else { - return -EINVAL; - } - - return e - events; -} - static struct ir_raw_handler rc6_handler = { .protocols = RC_BIT_RC6_0 | RC_BIT_RC6_6A_20 | RC_BIT_RC6_6A_24 | RC_BIT_RC6_6A_32 | RC_BIT_RC6_MCE, .decode = ir_rc6_decode, - .encode = ir_rc6_encode, }; static int __init ir_rc6_decode_init(void) diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index baeb5971fd52..85af7a869167 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c @@ -526,130 +526,6 @@ static int nvt_set_tx_carrier(struct rc_dev *dev, u32 carrier) return 0; } -static int nvt_write_wakeup_codes(struct rc_dev *dev, - const u8 *wakeup_sample_buf, int count) -{ - int i = 0; - u8 reg, reg_learn_mode; - unsigned long flags; - struct nvt_dev *nvt = dev->priv; - - nvt_dbg_wake("writing wakeup samples"); - - reg = nvt_cir_wake_reg_read(nvt, CIR_WAKE_IRCON); - reg_learn_mode = reg & ~CIR_WAKE_IRCON_MODE0; - reg_learn_mode |= CIR_WAKE_IRCON_MODE1; - - /* Lock the learn area to prevent racing with wake-isr */ - spin_lock_irqsave(&nvt->nvt_lock, flags); - - /* Enable fifo writes */ - nvt_cir_wake_reg_write(nvt, reg_learn_mode, CIR_WAKE_IRCON); - - /* Clear cir wake rx fifo */ - nvt_clear_cir_wake_fifo(nvt); - - if (count > WAKE_FIFO_LEN) { - nvt_dbg_wake("HW FIFO too small for all wake samples"); - count = WAKE_FIFO_LEN; - } - - if (count) - pr_info("Wake samples (%d) =", count); - else - pr_info("Wake sample fifo cleared"); - - /* Write wake samples to fifo */ - for (i = 0; i < count; i++) { - pr_cont(" %02x", wakeup_sample_buf[i]); - nvt_cir_wake_reg_write(nvt, wakeup_sample_buf[i], - CIR_WAKE_WR_FIFO_DATA); - } - pr_cont("\n"); - - /* Switch cir to wakeup mode and disable fifo writing */ - nvt_cir_wake_reg_write(nvt, reg, CIR_WAKE_IRCON); - - /* Set number of bytes needed for wake */ - nvt_cir_wake_reg_write(nvt, count ? count : - CIR_WAKE_FIFO_CMP_BYTES, - CIR_WAKE_FIFO_CMP_DEEP); - - spin_unlock_irqrestore(&nvt->nvt_lock, flags); - - return 0; -} - -static int nvt_ir_raw_set_wakeup_filter(struct rc_dev *dev, - struct rc_scancode_filter *sc_filter) -{ - u8 *reg_buf; - u8 buf_val; - int i, ret, count; - unsigned int val; - struct ir_raw_event *raw; - bool complete; - - /* Require both mask and data to be set before actually committing */ - if (!sc_filter->mask || !sc_filter->data) - return 0; - - raw = kmalloc_array(WAKE_FIFO_LEN, sizeof(*raw), GFP_KERNEL); - if (!raw) - return -ENOMEM; - - ret = ir_raw_encode_scancode(dev->enabled_wakeup_protocols, sc_filter, - raw, WAKE_FIFO_LEN); - complete = (ret != -ENOBUFS); - if (!complete) - ret = WAKE_FIFO_LEN; - else if (ret < 0) - goto out_raw; - - reg_buf = kmalloc_array(WAKE_FIFO_LEN, sizeof(*reg_buf), GFP_KERNEL); - if (!reg_buf) { - ret = -ENOMEM; - goto out_raw; - } - - /* Inspect the ir samples */ - for (i = 0, count = 0; i < ret && count < WAKE_FIFO_LEN; ++i) { - val = NS_TO_US((raw[i]).duration) / SAMPLE_PERIOD; - - /* Split too large values into several smaller ones */ - while (val > 0 && count < WAKE_FIFO_LEN) { - - /* Skip last value for better comparison tolerance */ - if (complete && i == ret - 1 && val < BUF_LEN_MASK) - break; - - /* Clamp values to BUF_LEN_MASK at most */ - buf_val = (val > BUF_LEN_MASK) ? BUF_LEN_MASK : val; - - reg_buf[count] = buf_val; - val -= buf_val; - if ((raw[i]).pulse) - reg_buf[count] |= BUF_PULSE_BIT; - count++; - } - } - - ret = nvt_write_wakeup_codes(dev, reg_buf, count); - - kfree(reg_buf); -out_raw: - kfree(raw); - - return ret; -} - -/* Dummy implementation. nuvoton is agnostic to the protocol used */ -static int nvt_ir_raw_change_wakeup_protocol(struct rc_dev *dev, - u64 *rc_type) -{ - return 0; -} - /* * nvt_tx_ir * @@ -1167,14 +1043,11 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) /* Set up the rc device */ rdev->priv = nvt; rdev->driver_type = RC_DRIVER_IR_RAW; - rdev->encode_wakeup = true; rdev->allowed_protocols = RC_BIT_ALL; rdev->open = nvt_open; rdev->close = nvt_close; rdev->tx_ir = nvt_tx_ir; rdev->s_tx_carrier = nvt_set_tx_carrier; - rdev->s_wakeup_filter = nvt_ir_raw_set_wakeup_filter; - rdev->change_wakeup_protocol = nvt_ir_raw_change_wakeup_protocol; rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver"; rdev->input_phys = "nuvoton/cir0"; rdev->input_id.bustype = BUS_HOST; diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 9d0e161c2a88..e1cf23c3875b 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h @@ -63,7 +63,6 @@ static int debug; */ #define TX_BUF_LEN 256 #define RX_BUF_LEN 32 -#define WAKE_FIFO_LEN 67 struct nvt_dev { struct pnp_dev *pdev; diff --git a/drivers/media/rc/rc-core-priv.h b/drivers/media/rc/rc-core-priv.h index 4b994aa2f2a7..b68d4f762734 100644 --- a/drivers/media/rc/rc-core-priv.h +++ b/drivers/media/rc/rc-core-priv.h @@ -25,8 +25,6 @@ struct ir_raw_handler { u64 protocols; /* which are handled by this handler */ int (*decode)(struct rc_dev *dev, struct ir_raw_event event); - int (*encode)(u64 protocols, const struct rc_scancode_filter *scancode, - struct ir_raw_event *events, unsigned int max); /* These two should only be used by the lirc decoder */ int (*raw_register)(struct rc_dev *dev); @@ -152,44 +150,10 @@ static inline bool is_timing_event(struct ir_raw_event ev) #define TO_US(duration) DIV_ROUND_CLOSEST((duration), 1000) #define TO_STR(is_pulse) ((is_pulse) ? "pulse" : "space") -/* functions for IR encoders */ - -static inline void init_ir_raw_event_duration(struct ir_raw_event *ev, - unsigned int pulse, - u32 duration) -{ - init_ir_raw_event(ev); - ev->duration = duration; - ev->pulse = pulse; -} - -/** - * struct ir_raw_timings_manchester - Manchester coding timings - * @leader: duration of leader pulse (if any) 0 if continuing - * existing signal (see @pulse_space_start) - * @pulse_space_start: 1 for starting with pulse (0 for starting with space) - * @clock: duration of each pulse/space in ns - * @invert: if set clock logic is inverted - * (0 = space + pulse, 1 = pulse + space) - * @trailer_space: duration of trailer space in ns - */ -struct ir_raw_timings_manchester { - unsigned int leader; - unsigned int pulse_space_start:1; - unsigned int clock; - unsigned int invert:1; - unsigned int trailer_space; -}; - -int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max, - const struct ir_raw_timings_manchester *timings, - unsigned int n, unsigned int data); - /* * Routines from rc-raw.c to be used internally and by decoders */ u64 ir_raw_get_allowed_protocols(void); -u64 ir_raw_get_encode_protocols(void); int ir_raw_event_register(struct rc_dev *dev); void ir_raw_event_unregister(struct rc_dev *dev); int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler); diff --git a/drivers/media/rc/rc-ir-raw.c b/drivers/media/rc/rc-ir-raw.c index 1068f2ba56c6..ad260520a9d4 100644 --- a/drivers/media/rc/rc-ir-raw.c +++ b/drivers/media/rc/rc-ir-raw.c @@ -30,7 +30,6 @@ static LIST_HEAD(ir_raw_client_list); static DEFINE_MUTEX(ir_raw_handler_lock); static LIST_HEAD(ir_raw_handler_list); static u64 available_protocols; -static u64 encode_protocols; static int ir_raw_event_thread(void *data) { @@ -241,146 +240,12 @@ ir_raw_get_allowed_protocols(void) return protocols; } -/* used internally by the sysfs interface */ -u64 -ir_raw_get_encode_protocols(void) -{ - u64 protocols; - - mutex_lock(&ir_raw_handler_lock); - protocols = encode_protocols; - mutex_unlock(&ir_raw_handler_lock); - return protocols; -} - static int change_protocol(struct rc_dev *dev, u64 *rc_type) { /* the caller will update dev->enabled_protocols */ return 0; } -/** - * ir_raw_gen_manchester() - Encode data with Manchester (bi-phase) modulation. - * @ev: Pointer to pointer to next free event. *@ev is incremented for - * each raw event filled. - * @max: Maximum number of raw events to fill. - * @timings: Manchester modulation timings. - * @n: Number of bits of data. - * @data: Data bits to encode. - * - * Encodes the @n least significant bits of @data using Manchester (bi-phase) - * modulation with the timing characteristics described by @timings, writing up - * to @max raw IR events using the *@ev pointer. - * - * Returns: 0 on success. - * -ENOBUFS if there isn't enough space in the array to fit the - * full encoded data. In this case all @max events will have been - * written. - */ -int ir_raw_gen_manchester(struct ir_raw_event **ev, unsigned int max, - const struct ir_raw_timings_manchester *timings, - unsigned int n, unsigned int data) -{ - bool need_pulse; - unsigned int i; - int ret = -ENOBUFS; - - i = 1 << (n - 1); - - if (timings->leader) { - if (!max--) - return ret; - if (timings->pulse_space_start) { - init_ir_raw_event_duration((*ev)++, 1, timings->leader); - - if (!max--) - return ret; - init_ir_raw_event_duration((*ev), 0, timings->leader); - } else { - init_ir_raw_event_duration((*ev), 1, timings->leader); - } - i >>= 1; - } else { - /* continue existing signal */ - --(*ev); - } - /* from here on *ev will point to the last event rather than the next */ - - while (n && i > 0) { - need_pulse = !(data & i); - if (timings->invert) - need_pulse = !need_pulse; - if (need_pulse == !!(*ev)->pulse) { - (*ev)->duration += timings->clock; - } else { - if (!max--) - goto nobufs; - init_ir_raw_event_duration(++(*ev), need_pulse, - timings->clock); - } - - if (!max--) - goto nobufs; - init_ir_raw_event_duration(++(*ev), !need_pulse, - timings->clock); - i >>= 1; - } - - if (timings->trailer_space) { - if (!(*ev)->pulse) - (*ev)->duration += timings->trailer_space; - else if (!max--) - goto nobufs; - else - init_ir_raw_event_duration(++(*ev), 0, - timings->trailer_space); - } - - ret = 0; -nobufs: - /* point to the next event rather than last event before returning */ - ++(*ev); - return ret; -} -EXPORT_SYMBOL(ir_raw_gen_manchester); - -/** - * ir_raw_encode_scancode() - Encode a scancode as raw events - * - * @protocols: permitted protocols - * @scancode: scancode filter describing a single scancode - * @events: array of raw events to write into - * @max: max number of raw events - * - * Attempts to encode the scancode as raw events. - * - * Returns: The number of events written. - * -ENOBUFS if there isn't enough space in the array to fit the - * encoding. In this case all @max events will have been written. - * -EINVAL if the scancode is ambiguous or invalid, or if no - * compatible encoder was found. - */ -int ir_raw_encode_scancode(u64 protocols, - const struct rc_scancode_filter *scancode, - struct ir_raw_event *events, unsigned int max) -{ - struct ir_raw_handler *handler; - int ret = -EINVAL; - - mutex_lock(&ir_raw_handler_lock); - list_for_each_entry(handler, &ir_raw_handler_list, list) { - if (handler->protocols & protocols && handler->encode) { - ret = handler->encode(protocols, scancode, events, max); - if (ret >= 0 || ret == -ENOBUFS) - break; - } - } - mutex_unlock(&ir_raw_handler_lock); - - return ret; -} -EXPORT_SYMBOL(ir_raw_encode_scancode); - /* * Used to (un)register raw event clients */ @@ -463,8 +328,6 @@ int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler) list_for_each_entry(raw, &ir_raw_client_list, list) ir_raw_handler->raw_register(raw->dev); available_protocols |= ir_raw_handler->protocols; - if (ir_raw_handler->encode) - encode_protocols |= ir_raw_handler->protocols; mutex_unlock(&ir_raw_handler_lock); return 0; @@ -481,8 +344,6 @@ void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler) list_for_each_entry(raw, &ir_raw_client_list, list) ir_raw_handler->raw_unregister(raw->dev); available_protocols &= ~ir_raw_handler->protocols; - if (ir_raw_handler->encode) - encode_protocols &= ~ir_raw_handler->protocols; mutex_unlock(&ir_raw_handler_lock); } EXPORT_SYMBOL(ir_raw_handler_unregister); diff --git a/drivers/media/rc/rc-loopback.c b/drivers/media/rc/rc-loopback.c index d8bdf63ce985..63dace8198b0 100644 --- a/drivers/media/rc/rc-loopback.c +++ b/drivers/media/rc/rc-loopback.c @@ -26,7 +26,6 @@ #include <linux/device.h> #include <linux/module.h> #include <linux/sched.h> -#include <linux/slab.h> #include <media/rc-core.h> #define DRIVER_NAME "rc-loopback" @@ -177,39 +176,6 @@ static int loop_set_carrier_report(struct rc_dev *dev, int enable) return 0; } -static int loop_set_wakeup_filter(struct rc_dev *dev, - struct rc_scancode_filter *sc_filter) -{ - static const unsigned int max = 512; - struct ir_raw_event *raw; - int ret; - int i; - - /* fine to disable filter */ - if (!sc_filter->mask) - return 0; - - /* encode the specified filter and loop it back */ - raw = kmalloc_array(max, sizeof(*raw), GFP_KERNEL); - ret = ir_raw_encode_scancode(dev->enabled_wakeup_protocols, sc_filter, - raw, max); - /* still loop back the partial raw IR even if it's incomplete */ - if (ret == -ENOBUFS) - ret = max; - if (ret >= 0) { - /* do the loopback */ - for (i = 0; i < ret; ++i) - ir_raw_event_store(dev, &raw[i]); - ir_raw_event_handle(dev); - - ret = 0; - } - - kfree(raw); - - return ret; -} - static int __init loop_init(void) { struct rc_dev *rc; @@ -229,7 +195,6 @@ static int __init loop_init(void) rc->map_name = RC_MAP_EMPTY; rc->priv = &loopdev; rc->driver_type = RC_DRIVER_IR_RAW; - rc->encode_wakeup = true; rc->allowed_protocols = RC_BIT_ALL; rc->timeout = 100 * 1000 * 1000; /* 100 ms */ rc->min_timeout = 1; @@ -244,7 +209,6 @@ static int __init loop_init(void) rc->s_idle = loop_set_idle; rc->s_learning_mode = loop_set_learning_mode; rc->s_carrier_report = loop_set_carrier_report; - rc->s_wakeup_filter = loop_set_wakeup_filter; loopdev.txmask = RXMASK_REGULAR; loopdev.txcarrier = 36000; diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index d08cedb03c74..3f0f71adabb4 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c @@ -882,8 +882,6 @@ static ssize_t show_protocols(struct device *device, } else { enabled = dev->enabled_wakeup_protocols; allowed = dev->allowed_wakeup_protocols; - if (dev->encode_wakeup && !allowed) - allowed = ir_raw_get_encode_protocols(); } mutex_unlock(&dev->lock); @@ -1428,16 +1426,13 @@ int rc_register_device(struct rc_dev *dev) path ? path : "N/A"); kfree(path); - if (dev->driver_type == RC_DRIVER_IR_RAW || dev->encode_wakeup) { + if (dev->driver_type == RC_DRIVER_IR_RAW) { /* Load raw decoders, if they aren't already */ if (!raw_init) { IR_dprintk(1, "Loading raw decoders\n"); ir_raw_init(); raw_init = true; } - } - - if (dev->driver_type == RC_DRIVER_IR_RAW) { /* calls ir_register_device so unlock mutex here*/ mutex_unlock(&dev->lock); rc = ir_raw_event_register(dev); diff --git a/drivers/media/usb/cx231xx/cx231xx-video.c b/drivers/media/usb/cx231xx/cx231xx-video.c index c6ff8968286a..9798160698a3 100644 --- a/drivers/media/usb/cx231xx/cx231xx-video.c +++ b/drivers/media/usb/cx231xx/cx231xx-video.c @@ -1875,7 +1875,7 @@ static int cx231xx_close(struct file *filp) v4l2_fh_exit(&fh->fh); kfree(fh); dev->users--; - wake_up_interruptible_nr(&dev->open, 1); + wake_up_interruptible(&dev->open); return 0; } @@ -1908,7 +1908,7 @@ static int cx231xx_close(struct file *filp) } v4l2_fh_exit(&fh->fh); kfree(fh); - wake_up_interruptible_nr(&dev->open, 1); + wake_up_interruptible(&dev->open); return 0; } diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 243b28d07373..4f59b7ec05d0 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -717,6 +717,7 @@ static void __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) break; case VB2_BUF_STATE_PREPARING: case VB2_BUF_STATE_DEQUEUED: + case VB2_BUF_STATE_REQUEUEING: /* nothing */ break; } @@ -1184,7 +1185,8 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) if (WARN_ON(state != VB2_BUF_STATE_DONE && state != VB2_BUF_STATE_ERROR && - state != VB2_BUF_STATE_QUEUED)) + state != VB2_BUF_STATE_QUEUED && + state != VB2_BUF_STATE_REQUEUEING)) state = VB2_BUF_STATE_ERROR; #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -1201,24 +1203,32 @@ void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state) for (plane = 0; plane < vb->num_planes; ++plane) call_void_memop(vb, finish, vb->planes[plane].mem_priv); - /* Add the buffer to the done buffers list */ spin_lock_irqsave(&q->done_lock, flags); - vb->state = state; - if (state != VB2_BUF_STATE_QUEUED) + if (state == VB2_BUF_STATE_QUEUED || + state == VB2_BUF_STATE_REQUEUEING) { + vb->state = VB2_BUF_STATE_QUEUED; + } else { + /* Add the buffer to the done buffers list */ list_add_tail(&vb->done_entry, &q->done_list); + vb->state = state; + } atomic_dec(&q->owned_by_drv_count); spin_unlock_irqrestore(&q->done_lock, flags); trace_vb2_buf_done(q, vb); - if (state == VB2_BUF_STATE_QUEUED) { + switch (state) { + case VB2_BUF_STATE_QUEUED: + return; + case VB2_BUF_STATE_REQUEUEING: if (q->start_streaming_called) __enqueue_in_driver(vb); return; + default: + /* Inform any processes that may be waiting for buffers */ + wake_up(&q->done_wq); + break; } - - /* Inform any processes that may be waiting for buffers */ - wake_up(&q->done_wq); } EXPORT_SYMBOL_GPL(vb2_buffer_done); @@ -1248,19 +1258,19 @@ EXPORT_SYMBOL_GPL(vb2_discard_done); static void vb2_warn_zero_bytesused(struct vb2_buffer *vb) { - static bool __check_once __read_mostly; + static bool check_once; - if (__check_once) + if (check_once) return; - __check_once = true; - __WARN(); + check_once = true; + WARN_ON(1); - pr_warn_once("use of bytesused == 0 is deprecated and will be removed in the future,\n"); + pr_warn("use of bytesused == 0 is deprecated and will be removed in the future,\n"); if (vb->vb2_queue->allow_zero_bytesused) - pr_warn_once("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n"); + pr_warn("use VIDIOC_DECODER_CMD(V4L2_DEC_CMD_STOP) instead.\n"); else - pr_warn_once("use the actual size instead.\n"); + pr_warn("use the actual size instead.\n"); } /** |