These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / iio / magnetometer / st_magn_core.c
1 /*
2  * STMicroelectronics magnetometers driver
3  *
4  * Copyright 2012-2013 STMicroelectronics Inc.
5  *
6  * Denis Ciocca <denis.ciocca@st.com>
7  *
8  * Licensed under the GPL-2.
9  */
10
11 #include <linux/kernel.h>
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/errno.h>
15 #include <linux/types.h>
16 #include <linux/mutex.h>
17 #include <linux/interrupt.h>
18 #include <linux/i2c.h>
19 #include <linux/gpio.h>
20 #include <linux/irq.h>
21 #include <linux/delay.h>
22 #include <linux/iio/iio.h>
23 #include <linux/iio/sysfs.h>
24 #include <linux/iio/buffer.h>
25
26 #include <linux/iio/common/st_sensors.h>
27 #include "st_magn.h"
28
29 #define ST_MAGN_NUMBER_DATA_CHANNELS            3
30
31 /* DEFAULT VALUE FOR SENSORS */
32 #define ST_MAGN_DEFAULT_OUT_X_H_ADDR            0X03
33 #define ST_MAGN_DEFAULT_OUT_Y_H_ADDR            0X07
34 #define ST_MAGN_DEFAULT_OUT_Z_H_ADDR            0X05
35
36 /* FULLSCALE */
37 #define ST_MAGN_FS_AVL_1300MG                   1300
38 #define ST_MAGN_FS_AVL_1900MG                   1900
39 #define ST_MAGN_FS_AVL_2500MG                   2500
40 #define ST_MAGN_FS_AVL_4000MG                   4000
41 #define ST_MAGN_FS_AVL_4700MG                   4700
42 #define ST_MAGN_FS_AVL_5600MG                   5600
43 #define ST_MAGN_FS_AVL_8000MG                   8000
44 #define ST_MAGN_FS_AVL_8100MG                   8100
45 #define ST_MAGN_FS_AVL_12000MG                  12000
46 #define ST_MAGN_FS_AVL_15000MG                  15000
47 #define ST_MAGN_FS_AVL_16000MG                  16000
48
49 /* CUSTOM VALUES FOR SENSOR 0 */
50 #define ST_MAGN_0_ODR_ADDR                      0x00
51 #define ST_MAGN_0_ODR_MASK                      0x1c
52 #define ST_MAGN_0_ODR_AVL_1HZ_VAL               0x00
53 #define ST_MAGN_0_ODR_AVL_2HZ_VAL               0x01
54 #define ST_MAGN_0_ODR_AVL_3HZ_VAL               0x02
55 #define ST_MAGN_0_ODR_AVL_8HZ_VAL               0x03
56 #define ST_MAGN_0_ODR_AVL_15HZ_VAL              0x04
57 #define ST_MAGN_0_ODR_AVL_30HZ_VAL              0x05
58 #define ST_MAGN_0_ODR_AVL_75HZ_VAL              0x06
59 #define ST_MAGN_0_ODR_AVL_220HZ_VAL             0x07
60 #define ST_MAGN_0_PW_ADDR                       0x02
61 #define ST_MAGN_0_PW_MASK                       0x03
62 #define ST_MAGN_0_PW_ON                         0x00
63 #define ST_MAGN_0_PW_OFF                        0x03
64 #define ST_MAGN_0_FS_ADDR                       0x01
65 #define ST_MAGN_0_FS_MASK                       0xe0
66 #define ST_MAGN_0_FS_AVL_1300_VAL               0x01
67 #define ST_MAGN_0_FS_AVL_1900_VAL               0x02
68 #define ST_MAGN_0_FS_AVL_2500_VAL               0x03
69 #define ST_MAGN_0_FS_AVL_4000_VAL               0x04
70 #define ST_MAGN_0_FS_AVL_4700_VAL               0x05
71 #define ST_MAGN_0_FS_AVL_5600_VAL               0x06
72 #define ST_MAGN_0_FS_AVL_8100_VAL               0x07
73 #define ST_MAGN_0_FS_AVL_1300_GAIN_XY           1100
74 #define ST_MAGN_0_FS_AVL_1900_GAIN_XY           855
75 #define ST_MAGN_0_FS_AVL_2500_GAIN_XY           670
76 #define ST_MAGN_0_FS_AVL_4000_GAIN_XY           450
77 #define ST_MAGN_0_FS_AVL_4700_GAIN_XY           400
78 #define ST_MAGN_0_FS_AVL_5600_GAIN_XY           330
79 #define ST_MAGN_0_FS_AVL_8100_GAIN_XY           230
80 #define ST_MAGN_0_FS_AVL_1300_GAIN_Z            980
81 #define ST_MAGN_0_FS_AVL_1900_GAIN_Z            760
82 #define ST_MAGN_0_FS_AVL_2500_GAIN_Z            600
83 #define ST_MAGN_0_FS_AVL_4000_GAIN_Z            400
84 #define ST_MAGN_0_FS_AVL_4700_GAIN_Z            355
85 #define ST_MAGN_0_FS_AVL_5600_GAIN_Z            295
86 #define ST_MAGN_0_FS_AVL_8100_GAIN_Z            205
87 #define ST_MAGN_0_MULTIREAD_BIT                 false
88
89 /* CUSTOM VALUES FOR SENSOR 1 */
90 #define ST_MAGN_1_WAI_EXP                       0x3c
91 #define ST_MAGN_1_ODR_ADDR                      0x00
92 #define ST_MAGN_1_ODR_MASK                      0x1c
93 #define ST_MAGN_1_ODR_AVL_1HZ_VAL               0x00
94 #define ST_MAGN_1_ODR_AVL_2HZ_VAL               0x01
95 #define ST_MAGN_1_ODR_AVL_3HZ_VAL               0x02
96 #define ST_MAGN_1_ODR_AVL_8HZ_VAL               0x03
97 #define ST_MAGN_1_ODR_AVL_15HZ_VAL              0x04
98 #define ST_MAGN_1_ODR_AVL_30HZ_VAL              0x05
99 #define ST_MAGN_1_ODR_AVL_75HZ_VAL              0x06
100 #define ST_MAGN_1_ODR_AVL_220HZ_VAL             0x07
101 #define ST_MAGN_1_PW_ADDR                       0x02
102 #define ST_MAGN_1_PW_MASK                       0x03
103 #define ST_MAGN_1_PW_ON                         0x00
104 #define ST_MAGN_1_PW_OFF                        0x03
105 #define ST_MAGN_1_FS_ADDR                       0x01
106 #define ST_MAGN_1_FS_MASK                       0xe0
107 #define ST_MAGN_1_FS_AVL_1300_VAL               0x01
108 #define ST_MAGN_1_FS_AVL_1900_VAL               0x02
109 #define ST_MAGN_1_FS_AVL_2500_VAL               0x03
110 #define ST_MAGN_1_FS_AVL_4000_VAL               0x04
111 #define ST_MAGN_1_FS_AVL_4700_VAL               0x05
112 #define ST_MAGN_1_FS_AVL_5600_VAL               0x06
113 #define ST_MAGN_1_FS_AVL_8100_VAL               0x07
114 #define ST_MAGN_1_FS_AVL_1300_GAIN_XY           909
115 #define ST_MAGN_1_FS_AVL_1900_GAIN_XY           1169
116 #define ST_MAGN_1_FS_AVL_2500_GAIN_XY           1492
117 #define ST_MAGN_1_FS_AVL_4000_GAIN_XY           2222
118 #define ST_MAGN_1_FS_AVL_4700_GAIN_XY           2500
119 #define ST_MAGN_1_FS_AVL_5600_GAIN_XY           3030
120 #define ST_MAGN_1_FS_AVL_8100_GAIN_XY           4347
121 #define ST_MAGN_1_FS_AVL_1300_GAIN_Z            1020
122 #define ST_MAGN_1_FS_AVL_1900_GAIN_Z            1315
123 #define ST_MAGN_1_FS_AVL_2500_GAIN_Z            1666
124 #define ST_MAGN_1_FS_AVL_4000_GAIN_Z            2500
125 #define ST_MAGN_1_FS_AVL_4700_GAIN_Z            2816
126 #define ST_MAGN_1_FS_AVL_5600_GAIN_Z            3389
127 #define ST_MAGN_1_FS_AVL_8100_GAIN_Z            4878
128 #define ST_MAGN_1_MULTIREAD_BIT                 false
129
130 /* CUSTOM VALUES FOR SENSOR 2 */
131 #define ST_MAGN_2_WAI_EXP                       0x3d
132 #define ST_MAGN_2_ODR_ADDR                      0x20
133 #define ST_MAGN_2_ODR_MASK                      0x1c
134 #define ST_MAGN_2_ODR_AVL_1HZ_VAL               0x00
135 #define ST_MAGN_2_ODR_AVL_2HZ_VAL               0x01
136 #define ST_MAGN_2_ODR_AVL_3HZ_VAL               0x02
137 #define ST_MAGN_2_ODR_AVL_5HZ_VAL               0x03
138 #define ST_MAGN_2_ODR_AVL_10HZ_VAL              0x04
139 #define ST_MAGN_2_ODR_AVL_20HZ_VAL              0x05
140 #define ST_MAGN_2_ODR_AVL_40HZ_VAL              0x06
141 #define ST_MAGN_2_ODR_AVL_80HZ_VAL              0x07
142 #define ST_MAGN_2_PW_ADDR                       0x22
143 #define ST_MAGN_2_PW_MASK                       0x03
144 #define ST_MAGN_2_PW_ON                         0x00
145 #define ST_MAGN_2_PW_OFF                        0x03
146 #define ST_MAGN_2_FS_ADDR                       0x21
147 #define ST_MAGN_2_FS_MASK                       0x60
148 #define ST_MAGN_2_FS_AVL_4000_VAL               0x00
149 #define ST_MAGN_2_FS_AVL_8000_VAL               0x01
150 #define ST_MAGN_2_FS_AVL_12000_VAL              0x02
151 #define ST_MAGN_2_FS_AVL_16000_VAL              0x03
152 #define ST_MAGN_2_FS_AVL_4000_GAIN              146
153 #define ST_MAGN_2_FS_AVL_8000_GAIN              292
154 #define ST_MAGN_2_FS_AVL_12000_GAIN             438
155 #define ST_MAGN_2_FS_AVL_16000_GAIN             584
156 #define ST_MAGN_2_MULTIREAD_BIT                 false
157 #define ST_MAGN_2_OUT_X_L_ADDR                  0x28
158 #define ST_MAGN_2_OUT_Y_L_ADDR                  0x2a
159 #define ST_MAGN_2_OUT_Z_L_ADDR                  0x2c
160
161 /* CUSTOM VALUES FOR SENSOR 3 */
162 #define ST_MAGN_3_WAI_ADDR                      0x4f
163 #define ST_MAGN_3_WAI_EXP                       0x40
164 #define ST_MAGN_3_ODR_ADDR                      0x60
165 #define ST_MAGN_3_ODR_MASK                      0x0c
166 #define ST_MAGN_3_ODR_AVL_10HZ_VAL              0x00
167 #define ST_MAGN_3_ODR_AVL_20HZ_VAL              0x01
168 #define ST_MAGN_3_ODR_AVL_50HZ_VAL              0x02
169 #define ST_MAGN_3_ODR_AVL_100HZ_VAL             0x03
170 #define ST_MAGN_3_PW_ADDR                       0x60
171 #define ST_MAGN_3_PW_MASK                       0x03
172 #define ST_MAGN_3_PW_ON                         0x00
173 #define ST_MAGN_3_PW_OFF                        0x03
174 #define ST_MAGN_3_BDU_ADDR                      0x62
175 #define ST_MAGN_3_BDU_MASK                      0x10
176 #define ST_MAGN_3_DRDY_IRQ_ADDR                 0x62
177 #define ST_MAGN_3_DRDY_INT_MASK                 0x01
178 #define ST_MAGN_3_FS_AVL_15000_GAIN             1500
179 #define ST_MAGN_3_MULTIREAD_BIT                 false
180 #define ST_MAGN_3_OUT_X_L_ADDR                  0x68
181 #define ST_MAGN_3_OUT_Y_L_ADDR                  0x6a
182 #define ST_MAGN_3_OUT_Z_L_ADDR                  0x6c
183
184 static const struct iio_chan_spec st_magn_16bit_channels[] = {
185         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
186                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
187                         ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_BE, 16, 16,
188                         ST_MAGN_DEFAULT_OUT_X_H_ADDR),
189         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
190                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
191                         ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_BE, 16, 16,
192                         ST_MAGN_DEFAULT_OUT_Y_H_ADDR),
193         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
194                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
195                         ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_BE, 16, 16,
196                         ST_MAGN_DEFAULT_OUT_Z_H_ADDR),
197         IIO_CHAN_SOFT_TIMESTAMP(3)
198 };
199
200 static const struct iio_chan_spec st_magn_2_16bit_channels[] = {
201         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
202                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
203                         ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
204                         ST_MAGN_2_OUT_X_L_ADDR),
205         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
206                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
207                         ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
208                         ST_MAGN_2_OUT_Y_L_ADDR),
209         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
210                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
211                         ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
212                         ST_MAGN_2_OUT_Z_L_ADDR),
213         IIO_CHAN_SOFT_TIMESTAMP(3)
214 };
215
216 static const struct iio_chan_spec st_magn_3_16bit_channels[] = {
217         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
218                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
219                         ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
220                         ST_MAGN_3_OUT_X_L_ADDR),
221         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
222                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
223                         ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
224                         ST_MAGN_3_OUT_Y_L_ADDR),
225         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
226                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
227                         ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
228                         ST_MAGN_3_OUT_Z_L_ADDR),
229         IIO_CHAN_SOFT_TIMESTAMP(3)
230 };
231
232 static const struct st_sensor_settings st_magn_sensors_settings[] = {
233         {
234                 .wai = 0, /* This sensor has no valid WhoAmI report 0 */
235                 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
236                 .sensors_supported = {
237                         [0] = LSM303DLH_MAGN_DEV_NAME,
238                 },
239                 .ch = (struct iio_chan_spec *)st_magn_16bit_channels,
240                 .odr = {
241                         .addr = ST_MAGN_0_ODR_ADDR,
242                         .mask = ST_MAGN_0_ODR_MASK,
243                         .odr_avl = {
244                                 { 1, ST_MAGN_0_ODR_AVL_1HZ_VAL, },
245                                 { 2, ST_MAGN_0_ODR_AVL_2HZ_VAL, },
246                                 { 3, ST_MAGN_0_ODR_AVL_3HZ_VAL, },
247                                 { 8, ST_MAGN_0_ODR_AVL_8HZ_VAL, },
248                                 { 15, ST_MAGN_0_ODR_AVL_15HZ_VAL, },
249                                 { 30, ST_MAGN_0_ODR_AVL_30HZ_VAL, },
250                                 { 75, ST_MAGN_0_ODR_AVL_75HZ_VAL, },
251                         },
252                 },
253                 .pw = {
254                         .addr = ST_MAGN_0_PW_ADDR,
255                         .mask = ST_MAGN_0_PW_MASK,
256                         .value_on = ST_MAGN_0_PW_ON,
257                         .value_off = ST_MAGN_0_PW_OFF,
258                 },
259                 .fs = {
260                         .addr = ST_MAGN_0_FS_ADDR,
261                         .mask = ST_MAGN_0_FS_MASK,
262                         .fs_avl = {
263                                 [0] = {
264                                         .num = ST_MAGN_FS_AVL_1300MG,
265                                         .value = ST_MAGN_0_FS_AVL_1300_VAL,
266                                         .gain = ST_MAGN_0_FS_AVL_1300_GAIN_XY,
267                                         .gain2 = ST_MAGN_0_FS_AVL_1300_GAIN_Z,
268                                 },
269                                 [1] = {
270                                         .num = ST_MAGN_FS_AVL_1900MG,
271                                         .value = ST_MAGN_0_FS_AVL_1900_VAL,
272                                         .gain = ST_MAGN_0_FS_AVL_1900_GAIN_XY,
273                                         .gain2 = ST_MAGN_0_FS_AVL_1900_GAIN_Z,
274                                 },
275                                 [2] = {
276                                         .num = ST_MAGN_FS_AVL_2500MG,
277                                         .value = ST_MAGN_0_FS_AVL_2500_VAL,
278                                         .gain = ST_MAGN_0_FS_AVL_2500_GAIN_XY,
279                                         .gain2 = ST_MAGN_0_FS_AVL_2500_GAIN_Z,
280                                 },
281                                 [3] = {
282                                         .num = ST_MAGN_FS_AVL_4000MG,
283                                         .value = ST_MAGN_0_FS_AVL_4000_VAL,
284                                         .gain = ST_MAGN_0_FS_AVL_4000_GAIN_XY,
285                                         .gain2 = ST_MAGN_0_FS_AVL_4000_GAIN_Z,
286                                 },
287                                 [4] = {
288                                         .num = ST_MAGN_FS_AVL_4700MG,
289                                         .value = ST_MAGN_0_FS_AVL_4700_VAL,
290                                         .gain = ST_MAGN_0_FS_AVL_4700_GAIN_XY,
291                                         .gain2 = ST_MAGN_0_FS_AVL_4700_GAIN_Z,
292                                 },
293                                 [5] = {
294                                         .num = ST_MAGN_FS_AVL_5600MG,
295                                         .value = ST_MAGN_0_FS_AVL_5600_VAL,
296                                         .gain = ST_MAGN_0_FS_AVL_5600_GAIN_XY,
297                                         .gain2 = ST_MAGN_0_FS_AVL_5600_GAIN_Z,
298                                 },
299                                 [6] = {
300                                         .num = ST_MAGN_FS_AVL_8100MG,
301                                         .value = ST_MAGN_0_FS_AVL_8100_VAL,
302                                         .gain = ST_MAGN_0_FS_AVL_8100_GAIN_XY,
303                                         .gain2 = ST_MAGN_0_FS_AVL_8100_GAIN_Z,
304                                 },
305                         },
306                 },
307                 .multi_read_bit = ST_MAGN_0_MULTIREAD_BIT,
308                 .bootime = 2,
309         },
310         {
311                 .wai = ST_MAGN_1_WAI_EXP,
312                 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
313                 .sensors_supported = {
314                         [0] = LSM303DLHC_MAGN_DEV_NAME,
315                         [1] = LSM303DLM_MAGN_DEV_NAME,
316                 },
317                 .ch = (struct iio_chan_spec *)st_magn_16bit_channels,
318                 .odr = {
319                         .addr = ST_MAGN_1_ODR_ADDR,
320                         .mask = ST_MAGN_1_ODR_MASK,
321                         .odr_avl = {
322                                 { 1, ST_MAGN_1_ODR_AVL_1HZ_VAL, },
323                                 { 2, ST_MAGN_1_ODR_AVL_2HZ_VAL, },
324                                 { 3, ST_MAGN_1_ODR_AVL_3HZ_VAL, },
325                                 { 8, ST_MAGN_1_ODR_AVL_8HZ_VAL, },
326                                 { 15, ST_MAGN_1_ODR_AVL_15HZ_VAL, },
327                                 { 30, ST_MAGN_1_ODR_AVL_30HZ_VAL, },
328                                 { 75, ST_MAGN_1_ODR_AVL_75HZ_VAL, },
329                                 { 220, ST_MAGN_1_ODR_AVL_220HZ_VAL, },
330                         },
331                 },
332                 .pw = {
333                         .addr = ST_MAGN_1_PW_ADDR,
334                         .mask = ST_MAGN_1_PW_MASK,
335                         .value_on = ST_MAGN_1_PW_ON,
336                         .value_off = ST_MAGN_1_PW_OFF,
337                 },
338                 .fs = {
339                         .addr = ST_MAGN_1_FS_ADDR,
340                         .mask = ST_MAGN_1_FS_MASK,
341                         .fs_avl = {
342                                 [0] = {
343                                         .num = ST_MAGN_FS_AVL_1300MG,
344                                         .value = ST_MAGN_1_FS_AVL_1300_VAL,
345                                         .gain = ST_MAGN_1_FS_AVL_1300_GAIN_XY,
346                                         .gain2 = ST_MAGN_1_FS_AVL_1300_GAIN_Z,
347                                 },
348                                 [1] = {
349                                         .num = ST_MAGN_FS_AVL_1900MG,
350                                         .value = ST_MAGN_1_FS_AVL_1900_VAL,
351                                         .gain = ST_MAGN_1_FS_AVL_1900_GAIN_XY,
352                                         .gain2 = ST_MAGN_1_FS_AVL_1900_GAIN_Z,
353                                 },
354                                 [2] = {
355                                         .num = ST_MAGN_FS_AVL_2500MG,
356                                         .value = ST_MAGN_1_FS_AVL_2500_VAL,
357                                         .gain = ST_MAGN_1_FS_AVL_2500_GAIN_XY,
358                                         .gain2 = ST_MAGN_1_FS_AVL_2500_GAIN_Z,
359                                 },
360                                 [3] = {
361                                         .num = ST_MAGN_FS_AVL_4000MG,
362                                         .value = ST_MAGN_1_FS_AVL_4000_VAL,
363                                         .gain = ST_MAGN_1_FS_AVL_4000_GAIN_XY,
364                                         .gain2 = ST_MAGN_1_FS_AVL_4000_GAIN_Z,
365                                 },
366                                 [4] = {
367                                         .num = ST_MAGN_FS_AVL_4700MG,
368                                         .value = ST_MAGN_1_FS_AVL_4700_VAL,
369                                         .gain = ST_MAGN_1_FS_AVL_4700_GAIN_XY,
370                                         .gain2 = ST_MAGN_1_FS_AVL_4700_GAIN_Z,
371                                 },
372                                 [5] = {
373                                         .num = ST_MAGN_FS_AVL_5600MG,
374                                         .value = ST_MAGN_1_FS_AVL_5600_VAL,
375                                         .gain = ST_MAGN_1_FS_AVL_5600_GAIN_XY,
376                                         .gain2 = ST_MAGN_1_FS_AVL_5600_GAIN_Z,
377                                 },
378                                 [6] = {
379                                         .num = ST_MAGN_FS_AVL_8100MG,
380                                         .value = ST_MAGN_1_FS_AVL_8100_VAL,
381                                         .gain = ST_MAGN_1_FS_AVL_8100_GAIN_XY,
382                                         .gain2 = ST_MAGN_1_FS_AVL_8100_GAIN_Z,
383                                 },
384                         },
385                 },
386                 .multi_read_bit = ST_MAGN_1_MULTIREAD_BIT,
387                 .bootime = 2,
388         },
389         {
390                 .wai = ST_MAGN_2_WAI_EXP,
391                 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
392                 .sensors_supported = {
393                         [0] = LIS3MDL_MAGN_DEV_NAME,
394                 },
395                 .ch = (struct iio_chan_spec *)st_magn_2_16bit_channels,
396                 .odr = {
397                         .addr = ST_MAGN_2_ODR_ADDR,
398                         .mask = ST_MAGN_2_ODR_MASK,
399                         .odr_avl = {
400                                 { 1, ST_MAGN_2_ODR_AVL_1HZ_VAL, },
401                                 { 2, ST_MAGN_2_ODR_AVL_2HZ_VAL, },
402                                 { 3, ST_MAGN_2_ODR_AVL_3HZ_VAL, },
403                                 { 5, ST_MAGN_2_ODR_AVL_5HZ_VAL, },
404                                 { 10, ST_MAGN_2_ODR_AVL_10HZ_VAL, },
405                                 { 20, ST_MAGN_2_ODR_AVL_20HZ_VAL, },
406                                 { 40, ST_MAGN_2_ODR_AVL_40HZ_VAL, },
407                                 { 80, ST_MAGN_2_ODR_AVL_80HZ_VAL, },
408                         },
409                 },
410                 .pw = {
411                         .addr = ST_MAGN_2_PW_ADDR,
412                         .mask = ST_MAGN_2_PW_MASK,
413                         .value_on = ST_MAGN_2_PW_ON,
414                         .value_off = ST_MAGN_2_PW_OFF,
415                 },
416                 .fs = {
417                         .addr = ST_MAGN_2_FS_ADDR,
418                         .mask = ST_MAGN_2_FS_MASK,
419                         .fs_avl = {
420                                 [0] = {
421                                         .num = ST_MAGN_FS_AVL_4000MG,
422                                         .value = ST_MAGN_2_FS_AVL_4000_VAL,
423                                         .gain = ST_MAGN_2_FS_AVL_4000_GAIN,
424                                 },
425                                 [1] = {
426                                         .num = ST_MAGN_FS_AVL_8000MG,
427                                         .value = ST_MAGN_2_FS_AVL_8000_VAL,
428                                         .gain = ST_MAGN_2_FS_AVL_8000_GAIN,
429                                 },
430                                 [2] = {
431                                         .num = ST_MAGN_FS_AVL_12000MG,
432                                         .value = ST_MAGN_2_FS_AVL_12000_VAL,
433                                         .gain = ST_MAGN_2_FS_AVL_12000_GAIN,
434                                 },
435                                 [3] = {
436                                         .num = ST_MAGN_FS_AVL_16000MG,
437                                         .value = ST_MAGN_2_FS_AVL_16000_VAL,
438                                         .gain = ST_MAGN_2_FS_AVL_16000_GAIN,
439                                 },
440                         },
441                 },
442                 .multi_read_bit = ST_MAGN_2_MULTIREAD_BIT,
443                 .bootime = 2,
444         },
445         {
446                 .wai = ST_MAGN_3_WAI_EXP,
447                 .wai_addr = ST_MAGN_3_WAI_ADDR,
448                 .sensors_supported = {
449                         [0] = LSM303AGR_MAGN_DEV_NAME,
450                 },
451                 .ch = (struct iio_chan_spec *)st_magn_3_16bit_channels,
452                 .odr = {
453                         .addr = ST_MAGN_3_ODR_ADDR,
454                         .mask = ST_MAGN_3_ODR_MASK,
455                         .odr_avl = {
456                                 { 10, ST_MAGN_3_ODR_AVL_10HZ_VAL, },
457                                 { 20, ST_MAGN_3_ODR_AVL_20HZ_VAL, },
458                                 { 50, ST_MAGN_3_ODR_AVL_50HZ_VAL, },
459                                 { 100, ST_MAGN_3_ODR_AVL_100HZ_VAL, },
460                         },
461                 },
462                 .pw = {
463                         .addr = ST_MAGN_3_PW_ADDR,
464                         .mask = ST_MAGN_3_PW_MASK,
465                         .value_on = ST_MAGN_3_PW_ON,
466                         .value_off = ST_MAGN_3_PW_OFF,
467                 },
468                 .fs = {
469                         .fs_avl = {
470                                 [0] = {
471                                         .num = ST_MAGN_FS_AVL_15000MG,
472                                         .gain = ST_MAGN_3_FS_AVL_15000_GAIN,
473                                 },
474                         },
475                 },
476                 .bdu = {
477                         .addr = ST_MAGN_3_BDU_ADDR,
478                         .mask = ST_MAGN_3_BDU_MASK,
479                 },
480                 .drdy_irq = {
481                         .addr = ST_MAGN_3_DRDY_IRQ_ADDR,
482                         .mask_int1 = ST_MAGN_3_DRDY_INT_MASK,
483                 },
484                 .multi_read_bit = ST_MAGN_3_MULTIREAD_BIT,
485                 .bootime = 2,
486         },
487 };
488
489 static int st_magn_read_raw(struct iio_dev *indio_dev,
490                         struct iio_chan_spec const *ch, int *val,
491                                                         int *val2, long mask)
492 {
493         int err;
494         struct st_sensor_data *mdata = iio_priv(indio_dev);
495
496         switch (mask) {
497         case IIO_CHAN_INFO_RAW:
498                 err = st_sensors_read_info_raw(indio_dev, ch, val);
499                 if (err < 0)
500                         goto read_error;
501
502                 return IIO_VAL_INT;
503         case IIO_CHAN_INFO_SCALE:
504                 *val = 0;
505                 if ((ch->scan_index == ST_SENSORS_SCAN_Z) &&
506                                         (mdata->current_fullscale->gain2 != 0))
507                         *val2 = mdata->current_fullscale->gain2;
508                 else
509                         *val2 = mdata->current_fullscale->gain;
510                 return IIO_VAL_INT_PLUS_MICRO;
511         case IIO_CHAN_INFO_SAMP_FREQ:
512                 *val = mdata->odr;
513                 return IIO_VAL_INT;
514         default:
515                 return -EINVAL;
516         }
517
518 read_error:
519         return err;
520 }
521
522 static int st_magn_write_raw(struct iio_dev *indio_dev,
523                 struct iio_chan_spec const *chan, int val, int val2, long mask)
524 {
525         int err;
526
527         switch (mask) {
528         case IIO_CHAN_INFO_SCALE:
529                 err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
530                 break;
531         case IIO_CHAN_INFO_SAMP_FREQ:
532                 if (val2)
533                         return -EINVAL;
534                 mutex_lock(&indio_dev->mlock);
535                 err = st_sensors_set_odr(indio_dev, val);
536                 mutex_unlock(&indio_dev->mlock);
537                 return err;
538         default:
539                 err = -EINVAL;
540         }
541
542         return err;
543 }
544
545 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
546 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available);
547
548 static struct attribute *st_magn_attributes[] = {
549         &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
550         &iio_dev_attr_in_magn_scale_available.dev_attr.attr,
551         NULL,
552 };
553
554 static const struct attribute_group st_magn_attribute_group = {
555         .attrs = st_magn_attributes,
556 };
557
558 static const struct iio_info magn_info = {
559         .driver_module = THIS_MODULE,
560         .attrs = &st_magn_attribute_group,
561         .read_raw = &st_magn_read_raw,
562         .write_raw = &st_magn_write_raw,
563         .debugfs_reg_access = &st_sensors_debugfs_reg_access,
564 };
565
566 #ifdef CONFIG_IIO_TRIGGER
567 static const struct iio_trigger_ops st_magn_trigger_ops = {
568         .owner = THIS_MODULE,
569         .set_trigger_state = ST_MAGN_TRIGGER_SET_STATE,
570 };
571 #define ST_MAGN_TRIGGER_OPS (&st_magn_trigger_ops)
572 #else
573 #define ST_MAGN_TRIGGER_OPS NULL
574 #endif
575
576 int st_magn_common_probe(struct iio_dev *indio_dev)
577 {
578         struct st_sensor_data *mdata = iio_priv(indio_dev);
579         int irq = mdata->get_irq_data_ready(indio_dev);
580         int err;
581
582         indio_dev->modes = INDIO_DIRECT_MODE;
583         indio_dev->info = &magn_info;
584         mutex_init(&mdata->tb.buf_lock);
585
586         st_sensors_power_enable(indio_dev);
587
588         err = st_sensors_check_device_support(indio_dev,
589                                         ARRAY_SIZE(st_magn_sensors_settings),
590                                         st_magn_sensors_settings);
591         if (err < 0)
592                 return err;
593
594         mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS;
595         mdata->multiread_bit = mdata->sensor_settings->multi_read_bit;
596         indio_dev->channels = mdata->sensor_settings->ch;
597         indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
598
599         mdata->current_fullscale = (struct st_sensor_fullscale_avl *)
600                                         &mdata->sensor_settings->fs.fs_avl[0];
601         mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz;
602
603         err = st_sensors_init_sensor(indio_dev, NULL);
604         if (err < 0)
605                 return err;
606
607         err = st_magn_allocate_ring(indio_dev);
608         if (err < 0)
609                 return err;
610
611         if (irq > 0) {
612                 err = st_sensors_allocate_trigger(indio_dev,
613                                                 ST_MAGN_TRIGGER_OPS);
614                 if (err < 0)
615                         goto st_magn_probe_trigger_error;
616         }
617
618         err = iio_device_register(indio_dev);
619         if (err)
620                 goto st_magn_device_register_error;
621
622         dev_info(&indio_dev->dev, "registered magnetometer %s\n",
623                  indio_dev->name);
624
625         return 0;
626
627 st_magn_device_register_error:
628         if (irq > 0)
629                 st_sensors_deallocate_trigger(indio_dev);
630 st_magn_probe_trigger_error:
631         st_magn_deallocate_ring(indio_dev);
632
633         return err;
634 }
635 EXPORT_SYMBOL(st_magn_common_probe);
636
637 void st_magn_common_remove(struct iio_dev *indio_dev)
638 {
639         struct st_sensor_data *mdata = iio_priv(indio_dev);
640
641         st_sensors_power_disable(indio_dev);
642
643         iio_device_unregister(indio_dev);
644         if (mdata->get_irq_data_ready(indio_dev) > 0)
645                 st_sensors_deallocate_trigger(indio_dev);
646
647         st_magn_deallocate_ring(indio_dev);
648 }
649 EXPORT_SYMBOL(st_magn_common_remove);
650
651 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
652 MODULE_DESCRIPTION("STMicroelectronics magnetometers driver");
653 MODULE_LICENSE("GPL v2");