hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * STMicroelectronics st_lsm6dsr sensor driver
 *
 * Copyright 2020 STMicroelectronics Inc.
 *
 * Lorenzo Bianconi <lorenzo.bianconi@st.com>
 */
 
#ifndef ST_LSM6DSR_H
#define ST_LSM6DSR_H
 
#include <linux/device.h>
#include <linux/iio/iio.h>
#include <linux/delay.h>
 
#define ST_LSM6DSR_MAX_ODR            833
#define ST_LSM6DSR_ODR_LIST_SIZE        8
#define ST_LSM6DSR_ODR_EXPAND(odr, uodr)    ((odr * 1000000) + uodr)
 
#define ST_LSM6DSR_DEV_NAME            "lsm6dsr"
 
#define ST_LSM6DSR_REG_FUNC_CFG_ACCESS_ADDR    0x01
#define ST_LSM6DSR_REG_SHUB_REG_MASK        BIT(6)
#define ST_LSM6DSR_REG_FUNC_CFG_MASK        BIT(7)
 
#define ST_LSM6DSR_REG_FIFO_CTRL1_ADDR        0x07
#define ST_LSM6DSR_REG_FIFO_CTRL2_ADDR        0x08
#define ST_LSM6DSR_REG_FIFO_WTM_MASK        GENMASK(8, 0)
#define ST_LSM6DSR_REG_FIFO_WTM8_MASK        BIT(0)
 
#define ST_LSM6DSR_REG_FIFO_CTRL3_ADDR        0x09
#define ST_LSM6DSR_REG_BDR_XL_MASK        GENMASK(3, 0)
#define ST_LSM6DSR_REG_BDR_GY_MASK        GENMASK(7, 4)
 
#define ST_LSM6DSR_REG_FIFO_CTRL4_ADDR        0x0a
#define ST_LSM6DSR_REG_FIFO_MODE_MASK        GENMASK(2, 0)
#define ST_LSM6DSR_REG_ODR_T_BATCH_MASK        GENMASK(5, 4)
#define ST_LSM6DSR_REG_DEC_TS_MASK        GENMASK(7, 6)
 
#define ST_LSM6DSR_REG_INT1_CTRL_ADDR        0x0d
#define ST_LSM6DSR_REG_INT2_CTRL_ADDR        0x0e
#define ST_LSM6DSR_REG_INT_FIFO_TH_MASK        BIT(3)
 
#define ST_LSM6DSR_REG_WHOAMI_ADDR        0x0f
#define ST_LSM6DSR_WHOAMI_VAL            0x6b
 
#define ST_LSM6DSR_CTRL1_XL_ADDR        0x10
#define ST_LSM6DSR_CTRL2_G_ADDR            0x11
#define ST_LSM6DSR_REG_CTRL3_C_ADDR        0x12
#define ST_LSM6DSR_REG_SW_RESET_MASK        BIT(0)
#define ST_LSM6DSR_REG_PP_OD_MASK        BIT(4)
#define ST_LSM6DSR_REG_H_LACTIVE_MASK        BIT(5)
#define ST_LSM6DSR_REG_BDU_MASK            BIT(6)
#define ST_LSM6DSR_REG_BOOT_MASK        BIT(7)
 
#define ST_LSM6DSR_REG_CTRL4_C_ADDR        0x13
#define ST_LSM6DSR_REG_DRDY_MASK        BIT(3)
 
#define ST_LSM6DSR_REG_CTRL5_C_ADDR        0x14
#define ST_LSM6DSR_REG_ROUNDING_MASK        GENMASK(6, 5)
 
#define ST_LSM6DSR_REG_CTRL9_XL_ADDR        0x18
#define ST_LSM6DSR_REG_I3C_DISABLE_MASK        BIT(1)
 
#define ST_LSM6DSR_REG_CTRL10_C_ADDR        0x19
#define ST_LSM6DSR_REG_TIMESTAMP_EN_MASK    BIT(5)
 
#define ST_LSM6DSR_REG_OUT_TEMP_L_ADDR        0x20
 
#define ST_LSM6DSR_REG_OUTX_L_G_ADDR        0x22
#define ST_LSM6DSR_REG_OUTY_L_G_ADDR        0x24
#define ST_LSM6DSR_REG_OUTZ_L_G_ADDR        0x26
 
#define ST_LSM6DSR_REG_OUTX_L_A_ADDR        0x28
#define ST_LSM6DSR_REG_OUTY_L_A_ADDR        0x2a
#define ST_LSM6DSR_REG_OUTZ_L_A_ADDR        0x2c
 
#define ST_LSM6DSR_REG_FIFO_STATUS1_ADDR    0x3a
#define ST_LSM6DSR_REG_FIFO_STATUS_DIFF        GENMASK(9, 0)
 
#define ST_LSM6DSR_REG_TIMESTAMP0_ADDR        0x40
#define ST_LSM6DSR_REG_TIMESTAMP2_ADDR        0x42
 
#define ST_LSM6DSR_REG_TAP_CFG0_ADDR        0x56
#define ST_LSM6DSR_REG_TAP_X_EN_MASK        BIT(3)
#define ST_LSM6DSR_REG_TAP_Y_EN_MASK        BIT(2)
#define ST_LSM6DSR_REG_TAP_Z_EN_MASK        BIT(1)
#define ST_LSM6DSR_REG_LIR_MASK            BIT(0)
 
#define ST_LSM6DSR_REG_MD1_CFG_ADDR        0x5e
#define ST_LSM6DSR_REG_MD2_CFG_ADDR        0x5f
#define ST_LSM6DSR_REG_INT2_TIMESTAMP_MASK    BIT(0)
#define ST_LSM6DSR_REG_INT_EMB_FUNC_MASK    BIT(1)
 
#define ST_LSM6DSR_INTERNAL_FREQ_FINE        0x63
 
#define ST_LSM6DSR_REG_FIFO_DATA_OUT_TAG_ADDR    0x78
 
/* embedded registers */
#define ST_LSM6DSR_REG_EMB_FUNC_INT1_ADDR    0x0a
#define ST_LSM6DSR_REG_EMB_FUNC_INT2_ADDR    0x0e
 
/* Timestamp Tick 25us/LSB */
#define ST_LSM6DSR_TS_DELTA_NS            25000ULL
 
#define ST_LSM6DSR_TEMP_GAIN            256
#define ST_LSM6DSR_TEMP_FS_GAIN            (1000000 / ST_LSM6DSR_TEMP_GAIN)
#define ST_LSM6DSR_TEMP_OFFSET            6400
 
#define ST_LSM6DSR_SAMPLE_SIZE            6
#define ST_LSM6DSR_TS_SAMPLE_SIZE        4
#define ST_LSM6DSR_TAG_SIZE            1
#define ST_LSM6DSR_FIFO_SAMPLE_SIZE        (ST_LSM6DSR_SAMPLE_SIZE + \
                        ST_LSM6DSR_TAG_SIZE)
#define ST_LSM6DSR_MAX_FIFO_DEPTH        416
 
#define ST_LSM6DSR_DATA_CHANNEL(chan_type, addr, mod, ch2, scan_idx,    \
               rb, sb, sg)                \
{                                    \
   .type = chan_type,                        \
   .address = addr,                        \
   .modified = mod,                        \
   .channel2 = ch2,                        \
   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |            \
                 BIT(IIO_CHAN_INFO_SCALE),            \
   .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),    \
   .scan_index = scan_idx,                        \
   .scan_type = {                            \
       .sign = sg,                        \
       .realbits = rb,                        \
       .storagebits = sb,                    \
       .endianness = IIO_LE,                    \
   },                                \
}
 
static const struct iio_event_spec st_lsm6dsr_flush_event = {
#ifdef CONFIG_NO_GKI
   .type = IIO_EV_TYPE_FIFO_FLUSH,
   .dir = IIO_EV_DIR_EITHER,
#endif
};
 
static const struct iio_event_spec st_lsm6dsr_thr_event = {
   .type = IIO_EV_TYPE_THRESH,
   .dir = IIO_EV_DIR_RISING,
   .mask_separate = BIT(IIO_EV_INFO_ENABLE),
};
 
#define ST_LSM6DSR_EVENT_CHANNEL(ctype, etype)        \
{                            \
   .type = ctype,                    \
   .modified = 0,                    \
   .scan_index = -1,                \
   .indexed = -1,                    \
   .event_spec = &st_lsm6dsr_##etype##_event,    \
   .num_event_specs = 1,                \
}
 
#define ST_LSM6DSR_RX_MAX_LENGTH        64
#define ST_LSM6DSR_TX_MAX_LENGTH        16
 
/**
 * @struct st_lsm6dsr_transfer_buffer
 * @brief Buffer support for data transfer
 *
 * rx_buf: Data receive buffer.
 * tx_buf: Data transmit buffer.
 */
struct st_lsm6dsr_transfer_buffer {
   u8 rx_buf[ST_LSM6DSR_RX_MAX_LENGTH];
   u8 tx_buf[ST_LSM6DSR_TX_MAX_LENGTH] ____cacheline_aligned;
};
 
/**
 * @struct st_lsm6dsr_transfer_function
 * @brief Bus Transfer Function
 *
 * read: Bus read function to get register value from sensor.
 * write: Bus write function to set register value to sensor.
 */
struct st_lsm6dsr_transfer_function {
   int (*read)(struct device *dev, u8 addr, int len, u8 *data);
   int (*write)(struct device *dev, u8 addr, int len, const u8 *data);
};
 
/**
 * @struct st_lsm6dsr_reg
 * @brief Generic sensor register description
 *
 * addr: Register arress value.
 * mask: Register bitmask.
 */
struct st_lsm6dsr_reg {
   u8 addr;
   u8 mask;
};
 
enum st_lsm6dsr_suspend_resume_register {
   ST_LSM6DSR_CTRL1_XL_REG = 0,
   ST_LSM6DSR_CTRL2_G_REG,
   ST_LSM6DSR_REG_CTRL3_C_REG,
   ST_LSM6DSR_REG_CTRL4_C_REG,
   ST_LSM6DSR_REG_CTRL5_C_REG,
   ST_LSM6DSR_REG_CTRL10_C_REG,
   ST_LSM6DSR_REG_TAP_CFG0_REG,
   ST_LSM6DSR_REG_INT1_CTRL_REG,
   ST_LSM6DSR_REG_INT2_CTRL_REG,
   ST_LSM6DSR_REG_FIFO_CTRL1_REG,
   ST_LSM6DSR_REG_FIFO_CTRL2_REG,
   ST_LSM6DSR_REG_FIFO_CTRL3_REG,
   ST_LSM6DSR_REG_FIFO_CTRL4_REG,
   ST_LSM6DSR_SUSPEND_RESUME_REGS,
};
 
struct st_lsm6dsr_suspend_resume_entry {
   u8 addr;
   u8 val;
   u8 mask;
};
 
/**
 * @struct st_lsm6dsr_odr
 * @brief ODR sensor table entry
 *
 * In the ODR table the possible ODR supported by sensor can be defined in the
 * following format:
 *    .odr_avl[0] = {   0, 0,       0x00 },
 *    .odr_avl[1] = {  12, 500000,  0x01 }, ..... it means 12.5 Hz
 *    .odr_avl[2] = {  26, 0,       0x02 }, ..... it means 26.0 Hz
 *
 * hz: Most significant part of ODR value (in Hz).
 * uhz: Least significant part of ODR value (in micro Hz).
 * val: Register value tu set ODR.
 */
struct st_lsm6dsr_odr {
   int hz;
   int uhz;
   u8 val;
};
 
/**
 * @struct st_lsm6dsr_odr_table_entry
 * @brief ODR sensor table
 *
 * odr_size: ODR table size.
 * reg: Sensor register description for ODR (address and mask).
 * odr_avl: All supported ODR values.
 */
struct st_lsm6dsr_odr_table_entry {
   u8 odr_size;
   struct st_lsm6dsr_reg reg;
   struct st_lsm6dsr_odr odr_avl[ST_LSM6DSR_ODR_LIST_SIZE];
};
 
/**
 * @struct st_lsm6dsr_fs
 * @brief Full scale entry
 *
 * reg: Sensor register description for FS (address and mask).
 * gain: The gain to obtain data value from raw data (LSB).
 * val: Register value.
 */
struct st_lsm6dsr_fs {
   struct st_lsm6dsr_reg reg;
   u32 gain;
   u8 val;
};
 
/**
 * @struct st_lsm6dsr_fs_table_entry
 * @brief Full scale table
 *
 * size: Full scale number of entry.
 * fs_avl: Full scale entry.
 */
#define ST_LSM6DSR_FS_LIST_SIZE            5
#define ST_LSM6DSR_FS_ACC_LIST_SIZE        4
#define ST_LSM6DSR_FS_GYRO_LIST_SIZE        5
#define ST_LSM6DSR_FS_TEMP_LIST_SIZE        1
struct st_lsm6dsr_fs_table_entry {
   u8 size;
   struct st_lsm6dsr_fs fs_avl[ST_LSM6DSR_FS_LIST_SIZE];
};
 
#define ST_LSM6DSR_ACC_FS_2G_GAIN    IIO_G_TO_M_S_2(61)//
#define ST_LSM6DSR_ACC_FS_4G_GAIN    IIO_G_TO_M_S_2(61)//(122)
#define ST_LSM6DSR_ACC_FS_8G_GAIN    IIO_G_TO_M_S_2(61)//(244)
#define ST_LSM6DSR_ACC_FS_16G_GAIN    IIO_G_TO_M_S_2(61)//(488)
 
#define ST_LSM6DSR_GYRO_FS_250_GAIN    IIO_DEGREE_TO_RAD(8750)//
#define ST_LSM6DSR_GYRO_FS_500_GAIN    IIO_DEGREE_TO_RAD(8750)//(17500)
#define ST_LSM6DSR_GYRO_FS_1000_GAIN    IIO_DEGREE_TO_RAD(8750)//(35000)
#define ST_LSM6DSR_GYRO_FS_2000_GAIN    IIO_DEGREE_TO_RAD(8750)//(70000)
#define ST_LSM6DSR_GYRO_FS_4000_GAIN    IIO_DEGREE_TO_RAD(8750)//(140000)
 
struct st_lsm6dsr_ext_dev_info {
   const struct st_lsm6dsr_ext_dev_settings *ext_dev_settings;
   u8 ext_dev_i2c_addr;
};
 
/**
 * @enum st_lsm6dsr_sensor_id
 * @brief Sensor Identifier
 */
enum st_lsm6dsr_sensor_id {
   ST_LSM6DSR_ID_GYRO,
   ST_LSM6DSR_ID_ACC,
   ST_LSM6DSR_ID_TEMP,
   ST_LSM6DSR_ID_EXT0,
   ST_LSM6DSR_ID_EXT1,
   ST_LSM6DSR_ID_STEP_COUNTER,
   ST_LSM6DSR_ID_STEP_DETECTOR,
   ST_LSM6DSR_ID_SIGN_MOTION,
   ST_LSM6DSR_ID_GLANCE,
   ST_LSM6DSR_ID_MOTION,
   ST_LSM6DSR_ID_NO_MOTION,
   ST_LSM6DSR_ID_WAKEUP,
   ST_LSM6DSR_ID_PICKUP,
   ST_LSM6DSR_ID_ORIENTATION,
   ST_LSM6DSR_ID_WRIST_TILT,
   ST_LSM6DSR_ID_TILT,
   ST_LSM6DSR_ID_MAX,
};
 
/**
 * @enum st_lsm6dsr_sensor_id
 * @brief Sensor Table Identifier
 */
static const enum st_lsm6dsr_sensor_id st_lsm6dsr_main_sensor_list[] = {
    [0] = ST_LSM6DSR_ID_GYRO,
    [1] = ST_LSM6DSR_ID_ACC,
    [2] = ST_LSM6DSR_ID_TEMP,
    [3] = ST_LSM6DSR_ID_STEP_COUNTER,
    [4] = ST_LSM6DSR_ID_STEP_DETECTOR,
    [5] = ST_LSM6DSR_ID_SIGN_MOTION,
    [6] = ST_LSM6DSR_ID_GLANCE,
    [7] = ST_LSM6DSR_ID_MOTION,
    [8] = ST_LSM6DSR_ID_NO_MOTION,
    [9] = ST_LSM6DSR_ID_WAKEUP,
   [10] = ST_LSM6DSR_ID_PICKUP,
   [11] = ST_LSM6DSR_ID_ORIENTATION,
   [12] = ST_LSM6DSR_ID_WRIST_TILT,
   [13] = ST_LSM6DSR_ID_TILT,
};
 
/**
 * @enum st_lsm6dsr_fifo_mode
 * @brief FIFO Modes
 */
enum st_lsm6dsr_fifo_mode {
   ST_LSM6DSR_FIFO_BYPASS = 0x0,
   ST_LSM6DSR_FIFO_CONT = 0x6,
};
 
/**
 * @enum st_lsm6dsr_fifo_mode - FIFO Buffer Status
 */
enum st_lsm6dsr_fifo_status {
   ST_LSM6DSR_HW_FLUSH,
   ST_LSM6DSR_HW_OPERATIONAL,
};
 
/**
 * @struct st_lsm6dsr_sensor
 * @brief ST IMU sensor instance
 *
 * id: Sensor identifier
 * hw: Pointer to instance of struct st_lsm6dsr_hw
 * ext_dev_info: Sensor hub i2c slave settings.
 * trig: Sensor iio trigger.
 * gain: Configured sensor sensitivity
 * odr: Output data rate of the sensor [Hz]
 * uodr: Output data rate of the sensor [uHz]
 * offset: Sensor data offset
 * decimator: Sensor decimator
 * dec_counter: Sensor decimator counter
 * old_data: Saved sensor data
 * max_watermark: Max supported watermark level
 * watermark: Sensor watermark level
 * batch_reg: Sensor reg/mask for FIFO batching register
 * last_fifo_timestamp: Store last sample timestamp in FIFO, used by flush
 */
struct st_lsm6dsr_sensor {
   enum st_lsm6dsr_sensor_id id;
   struct st_lsm6dsr_hw *hw;
 
   struct st_lsm6dsr_ext_dev_info ext_dev_info;
 
   struct iio_trigger *trig;
 
   u32 gain;
   int odr;
   int uodr;
 
   u32 offset;
   u8 decimator;
   u8 dec_counter;
 
   u16 max_watermark;
   u16 watermark;
 
   struct st_lsm6dsr_reg batch_reg;
   s64 last_fifo_timestamp;
};
 
/**
 * @struct st_lsm6dsr_hw
 * @brief ST IMU MEMS hw instance
 *
 * dev: Pointer to instance of struct device (I2C or SPI).
 * irq: Device interrupt line (I2C or SPI).
 * lock: Mutex to protect read and write operations.
 * fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
 * page_lock: Mutex to prevent concurrent memory page configuration.
 * fifo_mode: FIFO operating mode supported by the device.
 * state: hw operational state.
 * enable_mask: Enabled sensor bitmask.
 * fsm_enable_mask: FSM Enabled sensor bitmask.
 * embfunc_pg0_irq_reg: Embedded function irq configuration register (page 0).
 * embfunc_irq_reg: Embedded function irq configuration register (other).
 * ext_data_len: Number of i2c slave devices connected to I2C master.
 * odr: Timestamp sample ODR [Hz]
 * uodr: Timestamp sample ODR [uHz]
 * ts_offset: Hw timestamp offset.
 * hw_ts: Latest hw timestamp from the sensor.
 * hw_ts_high: Manage timestamp rollover
 * tsample:
 * hw_ts_old:
 * delta_ts: Delta time between two consecutive interrupts.
 * delta_hw_ts:
 * ts: Latest timestamp from irq handler.
 * iio_devs: Pointers to acc/gyro iio_dev instances.
 * tf: Transfer function structure used by I/O operations.
 * tb: Transfer buffers used by SPI I/O operations.
 */
struct st_lsm6dsr_hw {
   struct device *dev;
   int irq;
 
   struct mutex lock;
   struct mutex fifo_lock;
   struct mutex page_lock;
 
   enum st_lsm6dsr_fifo_mode fifo_mode;
   unsigned long state;
   u32 enable_mask;
   u32 requested_mask;
   u32 suspend_mask;
 
   u16 fsm_enable_mask;
   u8 embfunc_irq_reg;
   u8 embfunc_pg0_irq_reg;
 
   u8 ext_data_len;
 
   int odr;
   int uodr;
 
   s64 ts_offset;
   u64 ts_delta_ns;
   s64 hw_ts;
   u32 val_ts_old;
   u32 hw_ts_high;
   s64 tsample;
   s64 delta_ts;
   s64 ts;
 
   struct iio_dev *iio_devs[ST_LSM6DSR_ID_MAX];
 
   const struct st_lsm6dsr_transfer_function *tf;
   struct st_lsm6dsr_transfer_buffer tb;
};
 
/**
 * @struct dev_pm_ops
 * @brief Power management callback function structure
 */
extern const struct dev_pm_ops st_lsm6dsr_pm_ops;
 
static inline int st_lsm6dsr_read_atomic(struct st_lsm6dsr_hw *hw, u8 addr,
                    int len, u8 *data)
{
   int err;
 
   mutex_lock(&hw->page_lock);
   err = hw->tf->read(hw->dev, addr, len, data);
   mutex_unlock(&hw->page_lock);
 
   return err;
}
 
static inline int st_lsm6dsr_write_atomic(struct st_lsm6dsr_hw *hw, u8 addr,
                     int len, u8 *data)
{
   int err;
 
   mutex_lock(&hw->page_lock);
   err = hw->tf->write(hw->dev, addr, len, data);
   mutex_unlock(&hw->page_lock);
 
   return err;
}
 
int __st_lsm6dsr_write_with_mask(struct st_lsm6dsr_hw *hw, u8 addr, u8 mask,
                u8 val);
static inline int st_lsm6dsr_write_with_mask(struct st_lsm6dsr_hw *hw, u8 addr,
                        u8 mask, u8 val)
{
   int err;
 
   mutex_lock(&hw->page_lock);
   err = __st_lsm6dsr_write_with_mask(hw, addr, mask, val);
   mutex_unlock(&hw->page_lock);
 
   return err;
}
 
static inline int st_lsm6dsr_set_page_access(struct st_lsm6dsr_hw *hw,
                        u8 mask, u8 data)
{
   int err;
 
   err = __st_lsm6dsr_write_with_mask(hw,
                      ST_LSM6DSR_REG_FUNC_CFG_ACCESS_ADDR,
                      mask, data);
   usleep_range(100, 150);
 
   return err;
}
 
static inline bool st_lsm6dsr_is_fifo_enabled(struct st_lsm6dsr_hw *hw)
{
   return hw->enable_mask & (BIT(ST_LSM6DSR_ID_STEP_COUNTER) |
                 BIT(ST_LSM6DSR_ID_GYRO)      |
                 BIT(ST_LSM6DSR_ID_ACC)      |
                 BIT(ST_LSM6DSR_ID_EXT0)      |
                 BIT(ST_LSM6DSR_ID_EXT1));
}
 
int st_lsm6dsr_probe(struct device *dev, int irq,
            const struct st_lsm6dsr_transfer_function *tf_ops);
int st_lsm6dsr_remove(struct device *dev);
int st_lsm6dsr_shub_set_enable(struct st_lsm6dsr_sensor *sensor, bool enable);
int st_lsm6dsr_shub_probe(struct st_lsm6dsr_hw *hw);
int st_lsm6dsr_sensor_set_enable(struct st_lsm6dsr_sensor *sensor,
                bool enable);
int st_lsm6dsr_irq_setup(struct st_lsm6dsr_hw *hw);
int st_lsm6dsr_buffers_setup(struct st_lsm6dsr_hw *hw);
int st_lsm6dsr_deallocate_buffers(struct st_lsm6dsr_hw *hw);
int st_lsm6dsr_get_odr_val(enum st_lsm6dsr_sensor_id id, int odr, int uodr,
              int *podr, int *puodr, u8 *val);
int st_lsm6dsr_update_watermark(struct st_lsm6dsr_sensor *sensor,
               u16 watermark);
ssize_t st_lsm6dsr_flush_fifo(struct device *dev,
                 struct device_attribute *attr,
                 const char *buf, size_t size);
ssize_t st_lsm6dsr_get_max_watermark(struct device *dev,
                    struct device_attribute *attr,
                    char *buf);
ssize_t st_lsm6dsr_get_watermark(struct device *dev,
                struct device_attribute *attr,
                char *buf);
ssize_t st_lsm6dsr_set_watermark(struct device *dev,
                struct device_attribute *attr,
                const char *buf, size_t size);
int st_lsm6dsr_set_page_access(struct st_lsm6dsr_hw *hw, u8 mask, u8 data);
int st_lsm6dsr_suspend_fifo(struct st_lsm6dsr_hw *hw);
int st_lsm6dsr_set_fifo_mode(struct st_lsm6dsr_hw *hw,
                enum st_lsm6dsr_fifo_mode fifo_mode);
int __st_lsm6dsr_set_sensor_batching_odr(struct st_lsm6dsr_sensor *sensor,
                    bool enable);
int st_lsm6dsr_fsm_init(struct st_lsm6dsr_hw *hw);
int st_lsm6dsr_fsm_get_orientation(struct st_lsm6dsr_hw *hw, u8 *data);
int st_lsm6dsr_embfunc_sensor_set_enable(struct st_lsm6dsr_sensor *sensor,
                    bool enable);
int st_lsm6dsr_step_counter_set_enable(struct st_lsm6dsr_sensor *sensor,
                      bool enable);
int st_lsm6dsr_reset_step_counter(struct iio_dev *iio_dev);
int st_lsm6dsr_update_batching(struct iio_dev *iio_dev, bool enable);
int st_lsm6dsr_reset_hwts(struct st_lsm6dsr_hw *hw);
#endif /* ST_LSM6DSR_H */