OSDN Git Service

iio: imu: st_lsm6dsx: introduce ST_LSM6DSX_ID_EXT sensor ids
[uclinux-h8/linux.git] / drivers / iio / imu / st_lsm6dsx / st_lsm6dsx.h
1 /*
2  * STMicroelectronics st_lsm6dsx sensor driver
3  *
4  * Copyright 2016 STMicroelectronics Inc.
5  *
6  * Lorenzo Bianconi <lorenzo.bianconi@st.com>
7  * Denis Ciocca <denis.ciocca@st.com>
8  *
9  * Licensed under the GPL-2.
10  */
11
12 #ifndef ST_LSM6DSX_H
13 #define ST_LSM6DSX_H
14
15 #include <linux/device.h>
16
17 #define ST_LSM6DS3_DEV_NAME     "lsm6ds3"
18 #define ST_LSM6DS3H_DEV_NAME    "lsm6ds3h"
19 #define ST_LSM6DSL_DEV_NAME     "lsm6dsl"
20 #define ST_LSM6DSM_DEV_NAME     "lsm6dsm"
21 #define ST_ISM330DLC_DEV_NAME   "ism330dlc"
22 #define ST_LSM6DSO_DEV_NAME     "lsm6dso"
23
24 enum st_lsm6dsx_hw_id {
25         ST_LSM6DS3_ID,
26         ST_LSM6DS3H_ID,
27         ST_LSM6DSL_ID,
28         ST_LSM6DSM_ID,
29         ST_ISM330DLC_ID,
30         ST_LSM6DSO_ID,
31         ST_LSM6DSX_MAX_ID,
32 };
33
34 #define ST_LSM6DSX_BUFF_SIZE            512
35 #define ST_LSM6DSX_CHAN_SIZE            2
36 #define ST_LSM6DSX_SAMPLE_SIZE          6
37 #define ST_LSM6DSX_TAG_SIZE             1
38 #define ST_LSM6DSX_TAGGED_SAMPLE_SIZE   (ST_LSM6DSX_SAMPLE_SIZE + \
39                                          ST_LSM6DSX_TAG_SIZE)
40 #define ST_LSM6DSX_MAX_WORD_LEN         ((32 / ST_LSM6DSX_SAMPLE_SIZE) * \
41                                          ST_LSM6DSX_SAMPLE_SIZE)
42 #define ST_LSM6DSX_MAX_TAGGED_WORD_LEN  ((32 / ST_LSM6DSX_TAGGED_SAMPLE_SIZE) \
43                                          * ST_LSM6DSX_TAGGED_SAMPLE_SIZE)
44 #define ST_LSM6DSX_SHIFT_VAL(val, mask) (((val) << __ffs(mask)) & (mask))
45
46 struct st_lsm6dsx_reg {
47         u8 addr;
48         u8 mask;
49 };
50
51 struct st_lsm6dsx_hw;
52
53 /**
54  * struct st_lsm6dsx_fifo_ops - ST IMU FIFO settings
55  * @read_fifo: Read FIFO callback.
56  * @fifo_th: FIFO threshold register info (addr + mask).
57  * @fifo_diff: FIFO diff status register info (addr + mask).
58  * @th_wl: FIFO threshold word length.
59  */
60 struct st_lsm6dsx_fifo_ops {
61         int (*read_fifo)(struct st_lsm6dsx_hw *hw);
62         struct {
63                 u8 addr;
64                 u16 mask;
65         } fifo_th;
66         struct {
67                 u8 addr;
68                 u16 mask;
69         } fifo_diff;
70         u8 th_wl;
71 };
72
73 /**
74  * struct st_lsm6dsx_hw_ts_settings - ST IMU hw timer settings
75  * @timer_en: Hw timer enable register info (addr + mask).
76  * @hr_timer: Hw timer resolution register info (addr + mask).
77  * @fifo_en: Hw timer FIFO enable register info (addr + mask).
78  * @decimator: Hw timer FIFO decimator register info (addr + mask).
79  */
80 struct st_lsm6dsx_hw_ts_settings {
81         struct st_lsm6dsx_reg timer_en;
82         struct st_lsm6dsx_reg hr_timer;
83         struct st_lsm6dsx_reg fifo_en;
84         struct st_lsm6dsx_reg decimator;
85 };
86
87 /**
88  * struct st_lsm6dsx_settings - ST IMU sensor settings
89  * @wai: Sensor WhoAmI default value.
90  * @max_fifo_size: Sensor max fifo length in FIFO words.
91  * @id: List of hw id supported by the driver configuration.
92  * @decimator: List of decimator register info (addr + mask).
93  * @batch: List of FIFO batching register info (addr + mask).
94  * @fifo_ops: Sensor hw FIFO parameters.
95  * @ts_settings: Hw timer related settings.
96  */
97 struct st_lsm6dsx_settings {
98         u8 wai;
99         u16 max_fifo_size;
100         enum st_lsm6dsx_hw_id id[ST_LSM6DSX_MAX_ID];
101         struct st_lsm6dsx_reg decimator[ST_LSM6DSX_MAX_ID];
102         struct st_lsm6dsx_reg batch[ST_LSM6DSX_MAX_ID];
103         struct st_lsm6dsx_fifo_ops fifo_ops;
104         struct st_lsm6dsx_hw_ts_settings ts_settings;
105 };
106
107 enum st_lsm6dsx_sensor_id {
108         ST_LSM6DSX_ID_GYRO,
109         ST_LSM6DSX_ID_ACC,
110         ST_LSM6DSX_ID_EXT0,
111         ST_LSM6DSX_ID_EXT1,
112         ST_LSM6DSX_ID_EXT2,
113         ST_LSM6DSX_ID_MAX,
114 };
115
116 enum st_lsm6dsx_fifo_mode {
117         ST_LSM6DSX_FIFO_BYPASS = 0x0,
118         ST_LSM6DSX_FIFO_CONT = 0x6,
119 };
120
121 /**
122  * struct st_lsm6dsx_sensor - ST IMU sensor instance
123  * @name: Sensor name.
124  * @id: Sensor identifier.
125  * @hw: Pointer to instance of struct st_lsm6dsx_hw.
126  * @gain: Configured sensor sensitivity.
127  * @odr: Output data rate of the sensor [Hz].
128  * @watermark: Sensor watermark level.
129  * @sip: Number of samples in a given pattern.
130  * @decimator: FIFO decimation factor.
131  * @ts_ref: Sensor timestamp reference for hw one.
132  */
133 struct st_lsm6dsx_sensor {
134         char name[32];
135         enum st_lsm6dsx_sensor_id id;
136         struct st_lsm6dsx_hw *hw;
137
138         u32 gain;
139         u16 odr;
140
141         u16 watermark;
142         u8 sip;
143         u8 decimator;
144         s64 ts_ref;
145 };
146
147 /**
148  * struct st_lsm6dsx_hw - ST IMU MEMS hw instance
149  * @dev: Pointer to instance of struct device (I2C or SPI).
150  * @regmap: Register map of the device.
151  * @irq: Device interrupt line (I2C or SPI).
152  * @fifo_lock: Mutex to prevent concurrent access to the hw FIFO.
153  * @conf_lock: Mutex to prevent concurrent FIFO configuration update.
154  * @page_lock: Mutex to prevent concurrent memory page configuration.
155  * @fifo_mode: FIFO operating mode supported by the device.
156  * @enable_mask: Enabled sensor bitmask.
157  * @ts_sip: Total number of timestamp samples in a given pattern.
158  * @sip: Total number of samples (acc/gyro/ts) in a given pattern.
159  * @buff: Device read buffer.
160  * @iio_devs: Pointers to acc/gyro iio_dev instances.
161  * @settings: Pointer to the specific sensor settings in use.
162  */
163 struct st_lsm6dsx_hw {
164         struct device *dev;
165         struct regmap *regmap;
166         int irq;
167
168         struct mutex fifo_lock;
169         struct mutex conf_lock;
170         struct mutex page_lock;
171
172         enum st_lsm6dsx_fifo_mode fifo_mode;
173         u8 enable_mask;
174         u8 ts_sip;
175         u8 sip;
176
177         u8 *buff;
178
179         struct iio_dev *iio_devs[ST_LSM6DSX_ID_MAX];
180
181         const struct st_lsm6dsx_settings *settings;
182 };
183
184 extern const struct dev_pm_ops st_lsm6dsx_pm_ops;
185
186 int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, const char *name,
187                      struct regmap *regmap);
188 int st_lsm6dsx_sensor_enable(struct st_lsm6dsx_sensor *sensor);
189 int st_lsm6dsx_sensor_disable(struct st_lsm6dsx_sensor *sensor);
190 int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw);
191 int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val);
192 int st_lsm6dsx_update_watermark(struct st_lsm6dsx_sensor *sensor,
193                                 u16 watermark);
194 int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw);
195 int st_lsm6dsx_set_fifo_mode(struct st_lsm6dsx_hw *hw,
196                              enum st_lsm6dsx_fifo_mode fifo_mode);
197 int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw);
198 int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw);
199 int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val);
200
201 static inline int
202 st_lsm6dsx_update_bits_locked(struct st_lsm6dsx_hw *hw, unsigned int addr,
203                               unsigned int mask, unsigned int val)
204 {
205         int err;
206
207         mutex_lock(&hw->page_lock);
208         err = regmap_update_bits(hw->regmap, addr, mask, val);
209         mutex_unlock(&hw->page_lock);
210
211         return err;
212 }
213
214 static inline int
215 st_lsm6dsx_read_locked(struct st_lsm6dsx_hw *hw, unsigned int addr,
216                        void *val, unsigned int len)
217 {
218         int err;
219
220         mutex_lock(&hw->page_lock);
221         err = regmap_bulk_read(hw->regmap, addr, val, len);
222         mutex_unlock(&hw->page_lock);
223
224         return err;
225 }
226
227 static inline int
228 st_lsm6dsx_write_locked(struct st_lsm6dsx_hw *hw, unsigned int addr,
229                         unsigned int val)
230 {
231         int err;
232
233         mutex_lock(&hw->page_lock);
234         err = regmap_write(hw->regmap, addr, val);
235         mutex_unlock(&hw->page_lock);
236
237         return err;
238 }
239
240 #endif /* ST_LSM6DSX_H */