summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/iio/imu/adis.h87
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)
{