diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/iio/imu/adis.h | 87 |
1 files changed, 85 insertions, 2 deletions
diff --git a/include/linux/iio/imu/adis.h b/include/linux/iio/imu/adis.h index dd8219138c2e..2df67448f0d1 100644 --- a/include/linux/iio/imu/adis.h +++ b/include/linux/iio/imu/adis.h @@ -83,10 +83,13 @@ struct adis_data { * @trig: IIO trigger object data * @data: ADIS chip variant specific data * @burst: ADIS burst transfer information + * @burst_extra_len: Burst extra length. Should only be used by devices that can + * dynamically change their burst mode length. * @state_lock: Lock used by the device to protect state * @msg: SPI message object * @xfer: SPI transfer objects to be used for a @msg * @current_page: Some ADIS devices have registers, this selects current page + * @irq_flag: IRQ handling flags as passed to request_irq() * @buffer: Data buffer for information read from the device * @tx: DMA safe TX buffer for SPI transfers * @rx: DMA safe RX buffer for SPI transfers @@ -97,7 +100,7 @@ struct adis { const struct adis_data *data; struct adis_burst *burst; - + unsigned int burst_extra_len; /** * The state_lock is meant to be used during operations that require * a sequence of SPI R/W in order to protect the SPI transfer @@ -113,6 +116,7 @@ struct adis { struct spi_message msg; struct spi_transfer *xfer; unsigned int current_page; + unsigned long irq_flag; void *buffer; uint8_t tx[10] ____cacheline_aligned; @@ -331,6 +335,65 @@ static inline int adis_read_reg_32(struct adis *adis, unsigned int reg, return ret; } +int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask, + const u32 val, u8 size); +/** + * adis_update_bits_base() - ADIS Update bits function - Locked version + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @mask: Bitmask to change + * @val: Value to be written + * @size: Size of the register to update + * + * Updates the desired bits of @reg in accordance with @mask and @val. + */ +static inline int adis_update_bits_base(struct adis *adis, unsigned int reg, + const u32 mask, const u32 val, u8 size) +{ + int ret; + + mutex_lock(&adis->state_lock); + ret = __adis_update_bits_base(adis, reg, mask, val, size); + mutex_unlock(&adis->state_lock); + return ret; +} + +/** + * adis_update_bits() - Wrapper macro for adis_update_bits_base - Locked version + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @mask: Bitmask to change + * @val: Value to be written + * + * This macro evaluates the sizeof of @val at compile time and calls + * adis_update_bits_base() accordingly. Be aware that using MACROS/DEFINES for + * @val can lead to undesired behavior if the register to update is 16bit. + */ +#define adis_update_bits(adis, reg, mask, val) ({ \ + BUILD_BUG_ON(sizeof(val) == 1 || sizeof(val) == 8); \ + __builtin_choose_expr(sizeof(val) == 4, \ + adis_update_bits_base(adis, reg, mask, val, 4), \ + adis_update_bits_base(adis, reg, mask, val, 2)); \ +}) + +/** + * adis_update_bits() - Wrapper macro for adis_update_bits_base + * @adis: The adis device + * @reg: The address of the lower of the two registers + * @mask: Bitmask to change + * @val: Value to be written + * + * This macro evaluates the sizeof of @val at compile time and calls + * adis_update_bits_base() accordingly. Be aware that using MACROS/DEFINES for + * @val can lead to undesired behavior if the register to update is 16bit. + */ +#define __adis_update_bits(adis, reg, mask, val) ({ \ + BUILD_BUG_ON(sizeof(val) == 1 || sizeof(val) == 8); \ + __builtin_choose_expr(sizeof(val) == 4, \ + __adis_update_bits_base(adis, reg, mask, val, 4), \ + __adis_update_bits_base(adis, reg, mask, val, 2)); \ +}) + int adis_enable_irq(struct adis *adis, bool enable); int __adis_check_status(struct adis *adis); int __adis_initial_startup(struct adis *adis); @@ -441,18 +504,25 @@ int adis_single_conversion(struct iio_dev *indio_dev, * @en burst mode enabled * @reg_cmd register command that triggers burst * @extra_len extra length to account in the SPI RX buffer + * @burst_max_len holds the maximum burst size when the device supports + * more than one burst mode with different sizes */ struct adis_burst { bool en; unsigned int reg_cmd; - unsigned int extra_len; + const u32 extra_len; + const u32 burst_max_len; }; +int +devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, + irq_handler_t trigger_handler); int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)); void adis_cleanup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev); +int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev); void adis_remove_trigger(struct adis *adis); @@ -461,6 +531,13 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, #else /* CONFIG_IIO_BUFFER */ +static inline int +devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, + irq_handler_t trigger_handler) +{ + return 0; +} + static inline int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, irqreturn_t (*trigger_handler)(int, void *)) { @@ -472,6 +549,12 @@ static inline void adis_cleanup_buffer_and_trigger(struct adis *adis, { } +static inline int devm_adis_probe_trigger(struct adis *adis, + struct iio_dev *indio_dev) +{ + return 0; +} + static inline int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) { |