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