]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/iio/magnetometer/st_magn_core.c
Merge branch 'for-4.8/core' of git://git.kernel.dk/linux-block
[karo-tx-linux.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_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_IHL_IRQ_ADDR                  0x63
179 #define ST_MAGN_3_IHL_IRQ_MASK                  0x04
180 #define ST_MAGN_3_FS_AVL_15000_GAIN             1500
181 #define ST_MAGN_3_MULTIREAD_BIT                 false
182 #define ST_MAGN_3_OUT_X_L_ADDR                  0x68
183 #define ST_MAGN_3_OUT_Y_L_ADDR                  0x6a
184 #define ST_MAGN_3_OUT_Z_L_ADDR                  0x6c
185
186 static const struct iio_chan_spec st_magn_16bit_channels[] = {
187         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
188                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
189                         ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_BE, 16, 16,
190                         ST_MAGN_DEFAULT_OUT_X_H_ADDR),
191         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
192                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
193                         ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_BE, 16, 16,
194                         ST_MAGN_DEFAULT_OUT_Y_H_ADDR),
195         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
196                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
197                         ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_BE, 16, 16,
198                         ST_MAGN_DEFAULT_OUT_Z_H_ADDR),
199         IIO_CHAN_SOFT_TIMESTAMP(3)
200 };
201
202 static const struct iio_chan_spec st_magn_2_16bit_channels[] = {
203         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
204                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
205                         ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
206                         ST_MAGN_2_OUT_X_L_ADDR),
207         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
208                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
209                         ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
210                         ST_MAGN_2_OUT_Y_L_ADDR),
211         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
212                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
213                         ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
214                         ST_MAGN_2_OUT_Z_L_ADDR),
215         IIO_CHAN_SOFT_TIMESTAMP(3)
216 };
217
218 static const struct iio_chan_spec st_magn_3_16bit_channels[] = {
219         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
220                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
221                         ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
222                         ST_MAGN_3_OUT_X_L_ADDR),
223         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
224                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
225                         ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
226                         ST_MAGN_3_OUT_Y_L_ADDR),
227         ST_SENSORS_LSM_CHANNELS(IIO_MAGN,
228                         BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
229                         ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
230                         ST_MAGN_3_OUT_Z_L_ADDR),
231         IIO_CHAN_SOFT_TIMESTAMP(3)
232 };
233
234 static const struct st_sensor_settings st_magn_sensors_settings[] = {
235         {
236                 .wai = 0, /* This sensor has no valid WhoAmI report 0 */
237                 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
238                 .sensors_supported = {
239                         [0] = LSM303DLH_MAGN_DEV_NAME,
240                 },
241                 .ch = (struct iio_chan_spec *)st_magn_16bit_channels,
242                 .odr = {
243                         .addr = ST_MAGN_0_ODR_ADDR,
244                         .mask = ST_MAGN_0_ODR_MASK,
245                         .odr_avl = {
246                                 { 1, ST_MAGN_0_ODR_AVL_1HZ_VAL, },
247                                 { 2, ST_MAGN_0_ODR_AVL_2HZ_VAL, },
248                                 { 3, ST_MAGN_0_ODR_AVL_3HZ_VAL, },
249                                 { 8, ST_MAGN_0_ODR_AVL_8HZ_VAL, },
250                                 { 15, ST_MAGN_0_ODR_AVL_15HZ_VAL, },
251                                 { 30, ST_MAGN_0_ODR_AVL_30HZ_VAL, },
252                                 { 75, ST_MAGN_0_ODR_AVL_75HZ_VAL, },
253                         },
254                 },
255                 .pw = {
256                         .addr = ST_MAGN_0_PW_ADDR,
257                         .mask = ST_MAGN_0_PW_MASK,
258                         .value_on = ST_MAGN_0_PW_ON,
259                         .value_off = ST_MAGN_0_PW_OFF,
260                 },
261                 .fs = {
262                         .addr = ST_MAGN_0_FS_ADDR,
263                         .mask = ST_MAGN_0_FS_MASK,
264                         .fs_avl = {
265                                 [0] = {
266                                         .num = ST_MAGN_FS_AVL_1300MG,
267                                         .value = ST_MAGN_0_FS_AVL_1300_VAL,
268                                         .gain = ST_MAGN_0_FS_AVL_1300_GAIN_XY,
269                                         .gain2 = ST_MAGN_0_FS_AVL_1300_GAIN_Z,
270                                 },
271                                 [1] = {
272                                         .num = ST_MAGN_FS_AVL_1900MG,
273                                         .value = ST_MAGN_0_FS_AVL_1900_VAL,
274                                         .gain = ST_MAGN_0_FS_AVL_1900_GAIN_XY,
275                                         .gain2 = ST_MAGN_0_FS_AVL_1900_GAIN_Z,
276                                 },
277                                 [2] = {
278                                         .num = ST_MAGN_FS_AVL_2500MG,
279                                         .value = ST_MAGN_0_FS_AVL_2500_VAL,
280                                         .gain = ST_MAGN_0_FS_AVL_2500_GAIN_XY,
281                                         .gain2 = ST_MAGN_0_FS_AVL_2500_GAIN_Z,
282                                 },
283                                 [3] = {
284                                         .num = ST_MAGN_FS_AVL_4000MG,
285                                         .value = ST_MAGN_0_FS_AVL_4000_VAL,
286                                         .gain = ST_MAGN_0_FS_AVL_4000_GAIN_XY,
287                                         .gain2 = ST_MAGN_0_FS_AVL_4000_GAIN_Z,
288                                 },
289                                 [4] = {
290                                         .num = ST_MAGN_FS_AVL_4700MG,
291                                         .value = ST_MAGN_0_FS_AVL_4700_VAL,
292                                         .gain = ST_MAGN_0_FS_AVL_4700_GAIN_XY,
293                                         .gain2 = ST_MAGN_0_FS_AVL_4700_GAIN_Z,
294                                 },
295                                 [5] = {
296                                         .num = ST_MAGN_FS_AVL_5600MG,
297                                         .value = ST_MAGN_0_FS_AVL_5600_VAL,
298                                         .gain = ST_MAGN_0_FS_AVL_5600_GAIN_XY,
299                                         .gain2 = ST_MAGN_0_FS_AVL_5600_GAIN_Z,
300                                 },
301                                 [6] = {
302                                         .num = ST_MAGN_FS_AVL_8100MG,
303                                         .value = ST_MAGN_0_FS_AVL_8100_VAL,
304                                         .gain = ST_MAGN_0_FS_AVL_8100_GAIN_XY,
305                                         .gain2 = ST_MAGN_0_FS_AVL_8100_GAIN_Z,
306                                 },
307                         },
308                 },
309                 .multi_read_bit = ST_MAGN_0_MULTIREAD_BIT,
310                 .bootime = 2,
311         },
312         {
313                 .wai = ST_MAGN_1_WAI_EXP,
314                 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
315                 .sensors_supported = {
316                         [0] = LSM303DLHC_MAGN_DEV_NAME,
317                         [1] = LSM303DLM_MAGN_DEV_NAME,
318                 },
319                 .ch = (struct iio_chan_spec *)st_magn_16bit_channels,
320                 .odr = {
321                         .addr = ST_MAGN_1_ODR_ADDR,
322                         .mask = ST_MAGN_1_ODR_MASK,
323                         .odr_avl = {
324                                 { 1, ST_MAGN_1_ODR_AVL_1HZ_VAL, },
325                                 { 2, ST_MAGN_1_ODR_AVL_2HZ_VAL, },
326                                 { 3, ST_MAGN_1_ODR_AVL_3HZ_VAL, },
327                                 { 8, ST_MAGN_1_ODR_AVL_8HZ_VAL, },
328                                 { 15, ST_MAGN_1_ODR_AVL_15HZ_VAL, },
329                                 { 30, ST_MAGN_1_ODR_AVL_30HZ_VAL, },
330                                 { 75, ST_MAGN_1_ODR_AVL_75HZ_VAL, },
331                                 { 220, ST_MAGN_1_ODR_AVL_220HZ_VAL, },
332                         },
333                 },
334                 .pw = {
335                         .addr = ST_MAGN_1_PW_ADDR,
336                         .mask = ST_MAGN_1_PW_MASK,
337                         .value_on = ST_MAGN_1_PW_ON,
338                         .value_off = ST_MAGN_1_PW_OFF,
339                 },
340                 .fs = {
341                         .addr = ST_MAGN_1_FS_ADDR,
342                         .mask = ST_MAGN_1_FS_MASK,
343                         .fs_avl = {
344                                 [0] = {
345                                         .num = ST_MAGN_FS_AVL_1300MG,
346                                         .value = ST_MAGN_1_FS_AVL_1300_VAL,
347                                         .gain = ST_MAGN_1_FS_AVL_1300_GAIN_XY,
348                                         .gain2 = ST_MAGN_1_FS_AVL_1300_GAIN_Z,
349                                 },
350                                 [1] = {
351                                         .num = ST_MAGN_FS_AVL_1900MG,
352                                         .value = ST_MAGN_1_FS_AVL_1900_VAL,
353                                         .gain = ST_MAGN_1_FS_AVL_1900_GAIN_XY,
354                                         .gain2 = ST_MAGN_1_FS_AVL_1900_GAIN_Z,
355                                 },
356                                 [2] = {
357                                         .num = ST_MAGN_FS_AVL_2500MG,
358                                         .value = ST_MAGN_1_FS_AVL_2500_VAL,
359                                         .gain = ST_MAGN_1_FS_AVL_2500_GAIN_XY,
360                                         .gain2 = ST_MAGN_1_FS_AVL_2500_GAIN_Z,
361                                 },
362                                 [3] = {
363                                         .num = ST_MAGN_FS_AVL_4000MG,
364                                         .value = ST_MAGN_1_FS_AVL_4000_VAL,
365                                         .gain = ST_MAGN_1_FS_AVL_4000_GAIN_XY,
366                                         .gain2 = ST_MAGN_1_FS_AVL_4000_GAIN_Z,
367                                 },
368                                 [4] = {
369                                         .num = ST_MAGN_FS_AVL_4700MG,
370                                         .value = ST_MAGN_1_FS_AVL_4700_VAL,
371                                         .gain = ST_MAGN_1_FS_AVL_4700_GAIN_XY,
372                                         .gain2 = ST_MAGN_1_FS_AVL_4700_GAIN_Z,
373                                 },
374                                 [5] = {
375                                         .num = ST_MAGN_FS_AVL_5600MG,
376                                         .value = ST_MAGN_1_FS_AVL_5600_VAL,
377                                         .gain = ST_MAGN_1_FS_AVL_5600_GAIN_XY,
378                                         .gain2 = ST_MAGN_1_FS_AVL_5600_GAIN_Z,
379                                 },
380                                 [6] = {
381                                         .num = ST_MAGN_FS_AVL_8100MG,
382                                         .value = ST_MAGN_1_FS_AVL_8100_VAL,
383                                         .gain = ST_MAGN_1_FS_AVL_8100_GAIN_XY,
384                                         .gain2 = ST_MAGN_1_FS_AVL_8100_GAIN_Z,
385                                 },
386                         },
387                 },
388                 .multi_read_bit = ST_MAGN_1_MULTIREAD_BIT,
389                 .bootime = 2,
390         },
391         {
392                 .wai = ST_MAGN_2_WAI_EXP,
393                 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
394                 .sensors_supported = {
395                         [0] = LIS3MDL_MAGN_DEV_NAME,
396                 },
397                 .ch = (struct iio_chan_spec *)st_magn_2_16bit_channels,
398                 .odr = {
399                         .addr = ST_MAGN_2_ODR_ADDR,
400                         .mask = ST_MAGN_2_ODR_MASK,
401                         .odr_avl = {
402                                 { 1, ST_MAGN_2_ODR_AVL_1HZ_VAL, },
403                                 { 2, ST_MAGN_2_ODR_AVL_2HZ_VAL, },
404                                 { 3, ST_MAGN_2_ODR_AVL_3HZ_VAL, },
405                                 { 5, ST_MAGN_2_ODR_AVL_5HZ_VAL, },
406                                 { 10, ST_MAGN_2_ODR_AVL_10HZ_VAL, },
407                                 { 20, ST_MAGN_2_ODR_AVL_20HZ_VAL, },
408                                 { 40, ST_MAGN_2_ODR_AVL_40HZ_VAL, },
409                                 { 80, ST_MAGN_2_ODR_AVL_80HZ_VAL, },
410                         },
411                 },
412                 .pw = {
413                         .addr = ST_MAGN_2_PW_ADDR,
414                         .mask = ST_MAGN_2_PW_MASK,
415                         .value_on = ST_MAGN_2_PW_ON,
416                         .value_off = ST_MAGN_2_PW_OFF,
417                 },
418                 .fs = {
419                         .addr = ST_MAGN_2_FS_ADDR,
420                         .mask = ST_MAGN_2_FS_MASK,
421                         .fs_avl = {
422                                 [0] = {
423                                         .num = ST_MAGN_FS_AVL_4000MG,
424                                         .value = ST_MAGN_2_FS_AVL_4000_VAL,
425                                         .gain = ST_MAGN_2_FS_AVL_4000_GAIN,
426                                 },
427                                 [1] = {
428                                         .num = ST_MAGN_FS_AVL_8000MG,
429                                         .value = ST_MAGN_2_FS_AVL_8000_VAL,
430                                         .gain = ST_MAGN_2_FS_AVL_8000_GAIN,
431                                 },
432                                 [2] = {
433                                         .num = ST_MAGN_FS_AVL_12000MG,
434                                         .value = ST_MAGN_2_FS_AVL_12000_VAL,
435                                         .gain = ST_MAGN_2_FS_AVL_12000_GAIN,
436                                 },
437                                 [3] = {
438                                         .num = ST_MAGN_FS_AVL_16000MG,
439                                         .value = ST_MAGN_2_FS_AVL_16000_VAL,
440                                         .gain = ST_MAGN_2_FS_AVL_16000_GAIN,
441                                 },
442                         },
443                 },
444                 .multi_read_bit = ST_MAGN_2_MULTIREAD_BIT,
445                 .bootime = 2,
446         },
447         {
448                 .wai = ST_MAGN_3_WAI_EXP,
449                 .wai_addr = ST_MAGN_3_WAI_ADDR,
450                 .sensors_supported = {
451                         [0] = LSM303AGR_MAGN_DEV_NAME,
452                 },
453                 .ch = (struct iio_chan_spec *)st_magn_3_16bit_channels,
454                 .odr = {
455                         .addr = ST_MAGN_3_ODR_ADDR,
456                         .mask = ST_MAGN_3_ODR_MASK,
457                         .odr_avl = {
458                                 { 10, ST_MAGN_3_ODR_AVL_10HZ_VAL, },
459                                 { 20, ST_MAGN_3_ODR_AVL_20HZ_VAL, },
460                                 { 50, ST_MAGN_3_ODR_AVL_50HZ_VAL, },
461                                 { 100, ST_MAGN_3_ODR_AVL_100HZ_VAL, },
462                         },
463                 },
464                 .pw = {
465                         .addr = ST_MAGN_3_PW_ADDR,
466                         .mask = ST_MAGN_3_PW_MASK,
467                         .value_on = ST_MAGN_3_PW_ON,
468                         .value_off = ST_MAGN_3_PW_OFF,
469                 },
470                 .fs = {
471                         .fs_avl = {
472                                 [0] = {
473                                         .num = ST_MAGN_FS_AVL_15000MG,
474                                         .gain = ST_MAGN_3_FS_AVL_15000_GAIN,
475                                 },
476                         },
477                 },
478                 .bdu = {
479                         .addr = ST_MAGN_3_BDU_ADDR,
480                         .mask = ST_MAGN_3_BDU_MASK,
481                 },
482                 .drdy_irq = {
483                         .addr = ST_MAGN_3_DRDY_IRQ_ADDR,
484                         .mask_int1 = ST_MAGN_3_DRDY_INT_MASK,
485                         .addr_ihl = ST_MAGN_3_IHL_IRQ_ADDR,
486                         .mask_ihl = ST_MAGN_3_IHL_IRQ_MASK,
487                         .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
488                 },
489                 .multi_read_bit = ST_MAGN_3_MULTIREAD_BIT,
490                 .bootime = 2,
491         },
492 };
493
494 static int st_magn_read_raw(struct iio_dev *indio_dev,
495                         struct iio_chan_spec const *ch, int *val,
496                                                         int *val2, long mask)
497 {
498         int err;
499         struct st_sensor_data *mdata = iio_priv(indio_dev);
500
501         switch (mask) {
502         case IIO_CHAN_INFO_RAW:
503                 err = st_sensors_read_info_raw(indio_dev, ch, val);
504                 if (err < 0)
505                         goto read_error;
506
507                 return IIO_VAL_INT;
508         case IIO_CHAN_INFO_SCALE:
509                 *val = 0;
510                 if ((ch->scan_index == ST_SENSORS_SCAN_Z) &&
511                                         (mdata->current_fullscale->gain2 != 0))
512                         *val2 = mdata->current_fullscale->gain2;
513                 else
514                         *val2 = mdata->current_fullscale->gain;
515                 return IIO_VAL_INT_PLUS_MICRO;
516         case IIO_CHAN_INFO_SAMP_FREQ:
517                 *val = mdata->odr;
518                 return IIO_VAL_INT;
519         default:
520                 return -EINVAL;
521         }
522
523 read_error:
524         return err;
525 }
526
527 static int st_magn_write_raw(struct iio_dev *indio_dev,
528                 struct iio_chan_spec const *chan, int val, int val2, long mask)
529 {
530         int err;
531
532         switch (mask) {
533         case IIO_CHAN_INFO_SCALE:
534                 err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
535                 break;
536         case IIO_CHAN_INFO_SAMP_FREQ:
537                 if (val2)
538                         return -EINVAL;
539                 mutex_lock(&indio_dev->mlock);
540                 err = st_sensors_set_odr(indio_dev, val);
541                 mutex_unlock(&indio_dev->mlock);
542                 return err;
543         default:
544                 err = -EINVAL;
545         }
546
547         return err;
548 }
549
550 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
551 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available);
552
553 static struct attribute *st_magn_attributes[] = {
554         &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
555         &iio_dev_attr_in_magn_scale_available.dev_attr.attr,
556         NULL,
557 };
558
559 static const struct attribute_group st_magn_attribute_group = {
560         .attrs = st_magn_attributes,
561 };
562
563 static const struct iio_info magn_info = {
564         .driver_module = THIS_MODULE,
565         .attrs = &st_magn_attribute_group,
566         .read_raw = &st_magn_read_raw,
567         .write_raw = &st_magn_write_raw,
568         .debugfs_reg_access = &st_sensors_debugfs_reg_access,
569 };
570
571 #ifdef CONFIG_IIO_TRIGGER
572 static const struct iio_trigger_ops st_magn_trigger_ops = {
573         .owner = THIS_MODULE,
574         .set_trigger_state = ST_MAGN_TRIGGER_SET_STATE,
575         .validate_device = st_sensors_validate_device,
576 };
577 #define ST_MAGN_TRIGGER_OPS (&st_magn_trigger_ops)
578 #else
579 #define ST_MAGN_TRIGGER_OPS NULL
580 #endif
581
582 int st_magn_common_probe(struct iio_dev *indio_dev)
583 {
584         struct st_sensor_data *mdata = iio_priv(indio_dev);
585         int irq = mdata->get_irq_data_ready(indio_dev);
586         int err;
587
588         indio_dev->modes = INDIO_DIRECT_MODE;
589         indio_dev->info = &magn_info;
590         mutex_init(&mdata->tb.buf_lock);
591
592         err = st_sensors_power_enable(indio_dev);
593         if (err)
594                 return err;
595
596         err = st_sensors_check_device_support(indio_dev,
597                                         ARRAY_SIZE(st_magn_sensors_settings),
598                                         st_magn_sensors_settings);
599         if (err < 0)
600                 goto st_magn_power_off;
601
602         mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS;
603         mdata->multiread_bit = mdata->sensor_settings->multi_read_bit;
604         indio_dev->channels = mdata->sensor_settings->ch;
605         indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
606
607         mdata->current_fullscale = (struct st_sensor_fullscale_avl *)
608                                         &mdata->sensor_settings->fs.fs_avl[0];
609         mdata->odr = mdata->sensor_settings->odr.odr_avl[0].hz;
610
611         err = st_sensors_init_sensor(indio_dev, NULL);
612         if (err < 0)
613                 goto st_magn_power_off;
614
615         err = st_magn_allocate_ring(indio_dev);
616         if (err < 0)
617                 goto st_magn_power_off;
618
619         if (irq > 0) {
620                 err = st_sensors_allocate_trigger(indio_dev,
621                                                 ST_MAGN_TRIGGER_OPS);
622                 if (err < 0)
623                         goto st_magn_probe_trigger_error;
624         }
625
626         err = iio_device_register(indio_dev);
627         if (err)
628                 goto st_magn_device_register_error;
629
630         dev_info(&indio_dev->dev, "registered magnetometer %s\n",
631                  indio_dev->name);
632
633         return 0;
634
635 st_magn_device_register_error:
636         if (irq > 0)
637                 st_sensors_deallocate_trigger(indio_dev);
638 st_magn_probe_trigger_error:
639         st_magn_deallocate_ring(indio_dev);
640 st_magn_power_off:
641         st_sensors_power_disable(indio_dev);
642
643         return err;
644 }
645 EXPORT_SYMBOL(st_magn_common_probe);
646
647 void st_magn_common_remove(struct iio_dev *indio_dev)
648 {
649         struct st_sensor_data *mdata = iio_priv(indio_dev);
650
651         st_sensors_power_disable(indio_dev);
652
653         iio_device_unregister(indio_dev);
654         if (mdata->get_irq_data_ready(indio_dev) > 0)
655                 st_sensors_deallocate_trigger(indio_dev);
656
657         st_magn_deallocate_ring(indio_dev);
658 }
659 EXPORT_SYMBOL(st_magn_common_remove);
660
661 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
662 MODULE_DESCRIPTION("STMicroelectronics magnetometers driver");
663 MODULE_LICENSE("GPL v2");