]> Pileus Git - ~andy/linux/blob - drivers/iio/magnetometer/st_magn_core.c
Merge branch 'x86-debug-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[~andy/linux] / 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 /* DEFAULT VALUE FOR SENSORS */
30 #define ST_MAGN_DEFAULT_OUT_X_L_ADDR            0X04
31 #define ST_MAGN_DEFAULT_OUT_Y_L_ADDR            0X08
32 #define ST_MAGN_DEFAULT_OUT_Z_L_ADDR            0X06
33
34 /* FULLSCALE */
35 #define ST_MAGN_FS_AVL_1300MG                   1300
36 #define ST_MAGN_FS_AVL_1900MG                   1900
37 #define ST_MAGN_FS_AVL_2500MG                   2500
38 #define ST_MAGN_FS_AVL_4000MG                   4000
39 #define ST_MAGN_FS_AVL_4700MG                   4700
40 #define ST_MAGN_FS_AVL_5600MG                   5600
41 #define ST_MAGN_FS_AVL_8000MG                   8000
42 #define ST_MAGN_FS_AVL_8100MG                   8100
43 #define ST_MAGN_FS_AVL_10000MG                  10000
44
45 /* CUSTOM VALUES FOR SENSOR 1 */
46 #define ST_MAGN_1_WAI_EXP                       0x3c
47 #define ST_MAGN_1_ODR_ADDR                      0x00
48 #define ST_MAGN_1_ODR_MASK                      0x1c
49 #define ST_MAGN_1_ODR_AVL_1HZ_VAL               0x00
50 #define ST_MAGN_1_ODR_AVL_2HZ_VAL               0x01
51 #define ST_MAGN_1_ODR_AVL_3HZ_VAL               0x02
52 #define ST_MAGN_1_ODR_AVL_8HZ_VAL               0x03
53 #define ST_MAGN_1_ODR_AVL_15HZ_VAL              0x04
54 #define ST_MAGN_1_ODR_AVL_30HZ_VAL              0x05
55 #define ST_MAGN_1_ODR_AVL_75HZ_VAL              0x06
56 #define ST_MAGN_1_ODR_AVL_220HZ_VAL             0x07
57 #define ST_MAGN_1_PW_ADDR                       0x02
58 #define ST_MAGN_1_PW_MASK                       0x03
59 #define ST_MAGN_1_PW_ON                         0x00
60 #define ST_MAGN_1_PW_OFF                        0x03
61 #define ST_MAGN_1_FS_ADDR                       0x01
62 #define ST_MAGN_1_FS_MASK                       0xe0
63 #define ST_MAGN_1_FS_AVL_1300_VAL               0x01
64 #define ST_MAGN_1_FS_AVL_1900_VAL               0x02
65 #define ST_MAGN_1_FS_AVL_2500_VAL               0x03
66 #define ST_MAGN_1_FS_AVL_4000_VAL               0x04
67 #define ST_MAGN_1_FS_AVL_4700_VAL               0x05
68 #define ST_MAGN_1_FS_AVL_5600_VAL               0x06
69 #define ST_MAGN_1_FS_AVL_8100_VAL               0x07
70 #define ST_MAGN_1_FS_AVL_1300_GAIN_XY           1100
71 #define ST_MAGN_1_FS_AVL_1900_GAIN_XY           855
72 #define ST_MAGN_1_FS_AVL_2500_GAIN_XY           670
73 #define ST_MAGN_1_FS_AVL_4000_GAIN_XY           450
74 #define ST_MAGN_1_FS_AVL_4700_GAIN_XY           400
75 #define ST_MAGN_1_FS_AVL_5600_GAIN_XY           330
76 #define ST_MAGN_1_FS_AVL_8100_GAIN_XY           230
77 #define ST_MAGN_1_FS_AVL_1300_GAIN_Z            980
78 #define ST_MAGN_1_FS_AVL_1900_GAIN_Z            760
79 #define ST_MAGN_1_FS_AVL_2500_GAIN_Z            600
80 #define ST_MAGN_1_FS_AVL_4000_GAIN_Z            400
81 #define ST_MAGN_1_FS_AVL_4700_GAIN_Z            355
82 #define ST_MAGN_1_FS_AVL_5600_GAIN_Z            295
83 #define ST_MAGN_1_FS_AVL_8100_GAIN_Z            205
84 #define ST_MAGN_1_MULTIREAD_BIT                 false
85
86 /* CUSTOM VALUES FOR SENSOR 2 */
87 #define ST_MAGN_2_WAI_EXP                       0x3d
88 #define ST_MAGN_2_ODR_ADDR                      0x20
89 #define ST_MAGN_2_ODR_MASK                      0x1c
90 #define ST_MAGN_2_ODR_AVL_1HZ_VAL               0x00
91 #define ST_MAGN_2_ODR_AVL_2HZ_VAL               0x01
92 #define ST_MAGN_2_ODR_AVL_3HZ_VAL               0x02
93 #define ST_MAGN_2_ODR_AVL_5HZ_VAL               0x03
94 #define ST_MAGN_2_ODR_AVL_10HZ_VAL              0x04
95 #define ST_MAGN_2_ODR_AVL_20HZ_VAL              0x05
96 #define ST_MAGN_2_ODR_AVL_40HZ_VAL              0x06
97 #define ST_MAGN_2_ODR_AVL_80HZ_VAL              0x07
98 #define ST_MAGN_2_PW_ADDR                       0x22
99 #define ST_MAGN_2_PW_MASK                       0x03
100 #define ST_MAGN_2_PW_ON                         0x00
101 #define ST_MAGN_2_PW_OFF                        0x03
102 #define ST_MAGN_2_FS_ADDR                       0x21
103 #define ST_MAGN_2_FS_MASK                       0x60
104 #define ST_MAGN_2_FS_AVL_4000_VAL               0x00
105 #define ST_MAGN_2_FS_AVL_8000_VAL               0x01
106 #define ST_MAGN_2_FS_AVL_10000_VAL              0x02
107 #define ST_MAGN_2_FS_AVL_4000_GAIN              430
108 #define ST_MAGN_2_FS_AVL_8000_GAIN              230
109 #define ST_MAGN_2_FS_AVL_10000_GAIN             230
110 #define ST_MAGN_2_MULTIREAD_BIT                 false
111 #define ST_MAGN_2_OUT_X_L_ADDR                  0x28
112 #define ST_MAGN_2_OUT_Y_L_ADDR                  0x2a
113 #define ST_MAGN_2_OUT_Z_L_ADDR                  0x2c
114
115 static const struct iio_chan_spec st_magn_16bit_channels[] = {
116         ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
117                 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_X_L_ADDR),
118         ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
119                 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Y_L_ADDR),
120         ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
121                 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_DEFAULT_OUT_Z_L_ADDR),
122         IIO_CHAN_SOFT_TIMESTAMP(3)
123 };
124
125 static const struct iio_chan_spec st_magn_2_16bit_channels[] = {
126         ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_X, IIO_MOD_X, IIO_LE,
127                 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_X_L_ADDR),
128         ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Y, IIO_MOD_Y, IIO_LE,
129                 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Y_L_ADDR),
130         ST_SENSORS_LSM_CHANNELS(IIO_MAGN, ST_SENSORS_SCAN_Z, IIO_MOD_Z, IIO_LE,
131                 ST_SENSORS_DEFAULT_16_REALBITS, ST_MAGN_2_OUT_Z_L_ADDR),
132         IIO_CHAN_SOFT_TIMESTAMP(3)
133 };
134
135 static const struct st_sensors st_magn_sensors[] = {
136         {
137                 .wai = ST_MAGN_1_WAI_EXP,
138                 .sensors_supported = {
139                         [0] = LSM303DLHC_MAGN_DEV_NAME,
140                         [1] = LSM303DLM_MAGN_DEV_NAME,
141                 },
142                 .ch = (struct iio_chan_spec *)st_magn_16bit_channels,
143                 .odr = {
144                         .addr = ST_MAGN_1_ODR_ADDR,
145                         .mask = ST_MAGN_1_ODR_MASK,
146                         .odr_avl = {
147                                 { 1, ST_MAGN_1_ODR_AVL_1HZ_VAL, },
148                                 { 2, ST_MAGN_1_ODR_AVL_2HZ_VAL, },
149                                 { 3, ST_MAGN_1_ODR_AVL_3HZ_VAL, },
150                                 { 8, ST_MAGN_1_ODR_AVL_8HZ_VAL, },
151                                 { 15, ST_MAGN_1_ODR_AVL_15HZ_VAL, },
152                                 { 30, ST_MAGN_1_ODR_AVL_30HZ_VAL, },
153                                 { 75, ST_MAGN_1_ODR_AVL_75HZ_VAL, },
154                                 { 220, ST_MAGN_1_ODR_AVL_220HZ_VAL, },
155                         },
156                 },
157                 .pw = {
158                         .addr = ST_MAGN_1_PW_ADDR,
159                         .mask = ST_MAGN_1_PW_MASK,
160                         .value_on = ST_MAGN_1_PW_ON,
161                         .value_off = ST_MAGN_1_PW_OFF,
162                 },
163                 .fs = {
164                         .addr = ST_MAGN_1_FS_ADDR,
165                         .mask = ST_MAGN_1_FS_MASK,
166                         .fs_avl = {
167                                 [0] = {
168                                         .num = ST_MAGN_FS_AVL_1300MG,
169                                         .value = ST_MAGN_1_FS_AVL_1300_VAL,
170                                         .gain = ST_MAGN_1_FS_AVL_1300_GAIN_XY,
171                                         .gain2 = ST_MAGN_1_FS_AVL_1300_GAIN_Z,
172                                 },
173                                 [1] = {
174                                         .num = ST_MAGN_FS_AVL_1900MG,
175                                         .value = ST_MAGN_1_FS_AVL_1900_VAL,
176                                         .gain = ST_MAGN_1_FS_AVL_1900_GAIN_XY,
177                                         .gain2 = ST_MAGN_1_FS_AVL_1900_GAIN_Z,
178                                 },
179                                 [2] = {
180                                         .num = ST_MAGN_FS_AVL_2500MG,
181                                         .value = ST_MAGN_1_FS_AVL_2500_VAL,
182                                         .gain = ST_MAGN_1_FS_AVL_2500_GAIN_XY,
183                                         .gain2 = ST_MAGN_1_FS_AVL_2500_GAIN_Z,
184                                 },
185                                 [3] = {
186                                         .num = ST_MAGN_FS_AVL_4000MG,
187                                         .value = ST_MAGN_1_FS_AVL_4000_VAL,
188                                         .gain = ST_MAGN_1_FS_AVL_4000_GAIN_XY,
189                                         .gain2 = ST_MAGN_1_FS_AVL_4000_GAIN_Z,
190                                 },
191                                 [4] = {
192                                         .num = ST_MAGN_FS_AVL_4700MG,
193                                         .value = ST_MAGN_1_FS_AVL_4700_VAL,
194                                         .gain = ST_MAGN_1_FS_AVL_4700_GAIN_XY,
195                                         .gain2 = ST_MAGN_1_FS_AVL_4700_GAIN_Z,
196                                 },
197                                 [5] = {
198                                         .num = ST_MAGN_FS_AVL_5600MG,
199                                         .value = ST_MAGN_1_FS_AVL_5600_VAL,
200                                         .gain = ST_MAGN_1_FS_AVL_5600_GAIN_XY,
201                                         .gain2 = ST_MAGN_1_FS_AVL_5600_GAIN_Z,
202                                 },
203                                 [6] = {
204                                         .num = ST_MAGN_FS_AVL_8100MG,
205                                         .value = ST_MAGN_1_FS_AVL_8100_VAL,
206                                         .gain = ST_MAGN_1_FS_AVL_8100_GAIN_XY,
207                                         .gain2 = ST_MAGN_1_FS_AVL_8100_GAIN_Z,
208                                 },
209                         },
210                 },
211                 .multi_read_bit = ST_MAGN_1_MULTIREAD_BIT,
212                 .bootime = 2,
213         },
214         {
215                 .wai = ST_MAGN_2_WAI_EXP,
216                 .sensors_supported = {
217                         [0] = LIS3MDL_MAGN_DEV_NAME,
218                 },
219                 .ch = (struct iio_chan_spec *)st_magn_2_16bit_channels,
220                 .odr = {
221                         .addr = ST_MAGN_2_ODR_ADDR,
222                         .mask = ST_MAGN_2_ODR_MASK,
223                         .odr_avl = {
224                                 { 1, ST_MAGN_2_ODR_AVL_1HZ_VAL, },
225                                 { 2, ST_MAGN_2_ODR_AVL_2HZ_VAL, },
226                                 { 3, ST_MAGN_2_ODR_AVL_3HZ_VAL, },
227                                 { 5, ST_MAGN_2_ODR_AVL_5HZ_VAL, },
228                                 { 10, ST_MAGN_2_ODR_AVL_10HZ_VAL, },
229                                 { 20, ST_MAGN_2_ODR_AVL_20HZ_VAL, },
230                                 { 40, ST_MAGN_2_ODR_AVL_40HZ_VAL, },
231                                 { 80, ST_MAGN_2_ODR_AVL_80HZ_VAL, },
232                         },
233                 },
234                 .pw = {
235                         .addr = ST_MAGN_2_PW_ADDR,
236                         .mask = ST_MAGN_2_PW_MASK,
237                         .value_on = ST_MAGN_2_PW_ON,
238                         .value_off = ST_MAGN_2_PW_OFF,
239                 },
240                 .fs = {
241                         .addr = ST_MAGN_2_FS_ADDR,
242                         .mask = ST_MAGN_2_FS_MASK,
243                         .fs_avl = {
244                                 [0] = {
245                                         .num = ST_MAGN_FS_AVL_4000MG,
246                                         .value = ST_MAGN_2_FS_AVL_4000_VAL,
247                                         .gain = ST_MAGN_2_FS_AVL_4000_GAIN,
248                                 },
249                                 [1] = {
250                                         .num = ST_MAGN_FS_AVL_8000MG,
251                                         .value = ST_MAGN_2_FS_AVL_8000_VAL,
252                                         .gain = ST_MAGN_2_FS_AVL_8000_GAIN,
253                                 },
254                                 [2] = {
255                                         .num = ST_MAGN_FS_AVL_10000MG,
256                                         .value = ST_MAGN_2_FS_AVL_10000_VAL,
257                                         .gain = ST_MAGN_2_FS_AVL_10000_GAIN,
258                                 },
259                         },
260                 },
261                 .multi_read_bit = ST_MAGN_2_MULTIREAD_BIT,
262                 .bootime = 2,
263         },
264 };
265
266 static int st_magn_read_raw(struct iio_dev *indio_dev,
267                         struct iio_chan_spec const *ch, int *val,
268                                                         int *val2, long mask)
269 {
270         int err;
271         struct st_sensor_data *mdata = iio_priv(indio_dev);
272
273         switch (mask) {
274         case IIO_CHAN_INFO_RAW:
275                 err = st_sensors_read_info_raw(indio_dev, ch, val);
276                 if (err < 0)
277                         goto read_error;
278
279                 return IIO_VAL_INT;
280         case IIO_CHAN_INFO_SCALE:
281                 *val = 0;
282                 if ((ch->scan_index == ST_SENSORS_SCAN_Z) &&
283                                         (mdata->current_fullscale->gain2 != 0))
284                         *val2 = mdata->current_fullscale->gain2;
285                 else
286                         *val2 = mdata->current_fullscale->gain;
287                 return IIO_VAL_INT_PLUS_MICRO;
288         default:
289                 return -EINVAL;
290         }
291
292 read_error:
293         return err;
294 }
295
296 static int st_magn_write_raw(struct iio_dev *indio_dev,
297                 struct iio_chan_spec const *chan, int val, int val2, long mask)
298 {
299         int err;
300
301         switch (mask) {
302         case IIO_CHAN_INFO_SCALE:
303                 err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
304                 break;
305         default:
306                 err = -EINVAL;
307         }
308
309         return err;
310 }
311
312 static ST_SENSOR_DEV_ATTR_SAMP_FREQ();
313 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
314 static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_magn_scale_available);
315
316 static struct attribute *st_magn_attributes[] = {
317         &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
318         &iio_dev_attr_in_magn_scale_available.dev_attr.attr,
319         &iio_dev_attr_sampling_frequency.dev_attr.attr,
320         NULL,
321 };
322
323 static const struct attribute_group st_magn_attribute_group = {
324         .attrs = st_magn_attributes,
325 };
326
327 static const struct iio_info magn_info = {
328         .driver_module = THIS_MODULE,
329         .attrs = &st_magn_attribute_group,
330         .read_raw = &st_magn_read_raw,
331         .write_raw = &st_magn_write_raw,
332 };
333
334 int st_magn_common_probe(struct iio_dev *indio_dev)
335 {
336         int err;
337         struct st_sensor_data *mdata = iio_priv(indio_dev);
338
339         indio_dev->modes = INDIO_DIRECT_MODE;
340         indio_dev->info = &magn_info;
341
342         err = st_sensors_check_device_support(indio_dev,
343                                 ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
344         if (err < 0)
345                 goto st_magn_common_probe_error;
346
347         mdata->multiread_bit = mdata->sensor->multi_read_bit;
348         indio_dev->channels = mdata->sensor->ch;
349         indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
350
351         mdata->current_fullscale = (struct st_sensor_fullscale_avl *)
352                                                 &mdata->sensor->fs.fs_avl[0];
353         mdata->odr = mdata->sensor->odr.odr_avl[0].hz;
354
355         err = st_sensors_init_sensor(indio_dev);
356         if (err < 0)
357                 goto st_magn_common_probe_error;
358
359         if (mdata->get_irq_data_ready(indio_dev) > 0) {
360                 err = st_magn_allocate_ring(indio_dev);
361                 if (err < 0)
362                         goto st_magn_common_probe_error;
363                 err = st_sensors_allocate_trigger(indio_dev, NULL);
364                 if (err < 0)
365                         goto st_magn_probe_trigger_error;
366         }
367
368         err = iio_device_register(indio_dev);
369         if (err)
370                 goto st_magn_device_register_error;
371
372         return err;
373
374 st_magn_device_register_error:
375         if (mdata->get_irq_data_ready(indio_dev) > 0)
376                 st_sensors_deallocate_trigger(indio_dev);
377 st_magn_probe_trigger_error:
378         if (mdata->get_irq_data_ready(indio_dev) > 0)
379                 st_magn_deallocate_ring(indio_dev);
380 st_magn_common_probe_error:
381         return err;
382 }
383 EXPORT_SYMBOL(st_magn_common_probe);
384
385 void st_magn_common_remove(struct iio_dev *indio_dev)
386 {
387         struct st_sensor_data *mdata = iio_priv(indio_dev);
388
389         iio_device_unregister(indio_dev);
390         if (mdata->get_irq_data_ready(indio_dev) > 0) {
391                 st_sensors_deallocate_trigger(indio_dev);
392                 st_magn_deallocate_ring(indio_dev);
393         }
394         iio_device_free(indio_dev);
395 }
396 EXPORT_SYMBOL(st_magn_common_remove);
397
398 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
399 MODULE_DESCRIPTION("STMicroelectronics magnetometers driver");
400 MODULE_LICENSE("GPL v2");