1
2
3
4
5
6
7
8
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/trigger.h>
25#include <linux/iio/buffer.h>
26#include <asm/unaligned.h>
27
28#include <linux/iio/common/st_sensors.h>
29#include "st_pressure.h"
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97#define MCELSIUS_PER_CELSIUS 1000
98
99
100#define ST_PRESS_LSB_PER_MBAR 4096UL
101#define ST_PRESS_KPASCAL_NANO_SCALE (100000000UL / \
102 ST_PRESS_LSB_PER_MBAR)
103
104
105#define ST_PRESS_LSB_PER_CELSIUS 480UL
106#define ST_PRESS_MILLI_CELSIUS_OFFSET 42500UL
107
108
109#define ST_PRESS_FS_AVL_1100MB 1100
110#define ST_PRESS_FS_AVL_1260MB 1260
111
112#define ST_PRESS_1_OUT_XL_ADDR 0x28
113#define ST_TEMP_1_OUT_L_ADDR 0x2b
114
115
116
117
118
119
120#define ST_PRESS_LPS331AP_WAI_EXP 0xbb
121#define ST_PRESS_LPS331AP_ODR_ADDR 0x20
122#define ST_PRESS_LPS331AP_ODR_MASK 0x70
123#define ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL 0x01
124#define ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL 0x05
125#define ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL 0x06
126#define ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL 0x07
127#define ST_PRESS_LPS331AP_PW_ADDR 0x20
128#define ST_PRESS_LPS331AP_PW_MASK 0x80
129#define ST_PRESS_LPS331AP_FS_ADDR 0x23
130#define ST_PRESS_LPS331AP_FS_MASK 0x30
131#define ST_PRESS_LPS331AP_BDU_ADDR 0x20
132#define ST_PRESS_LPS331AP_BDU_MASK 0x04
133#define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR 0x22
134#define ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK 0x04
135#define ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK 0x20
136#define ST_PRESS_LPS331AP_IHL_IRQ_ADDR 0x22
137#define ST_PRESS_LPS331AP_IHL_IRQ_MASK 0x80
138#define ST_PRESS_LPS331AP_OD_IRQ_ADDR 0x22
139#define ST_PRESS_LPS331AP_OD_IRQ_MASK 0x40
140#define ST_PRESS_LPS331AP_MULTIREAD_BIT true
141
142
143
144
145
146
147#define ST_PRESS_LPS001WP_LSB_PER_MBAR 16UL
148
149#define ST_PRESS_LPS001WP_LSB_PER_CELSIUS 64UL
150
151#define ST_PRESS_LPS001WP_WAI_EXP 0xba
152#define ST_PRESS_LPS001WP_ODR_ADDR 0x20
153#define ST_PRESS_LPS001WP_ODR_MASK 0x30
154#define ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL 0x01
155#define ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL 0x02
156#define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL 0x03
157#define ST_PRESS_LPS001WP_PW_ADDR 0x20
158#define ST_PRESS_LPS001WP_PW_MASK 0x40
159#define ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN \
160 (100000000UL / ST_PRESS_LPS001WP_LSB_PER_MBAR)
161#define ST_PRESS_LPS001WP_BDU_ADDR 0x20
162#define ST_PRESS_LPS001WP_BDU_MASK 0x04
163#define ST_PRESS_LPS001WP_MULTIREAD_BIT true
164#define ST_PRESS_LPS001WP_OUT_L_ADDR 0x28
165#define ST_TEMP_LPS001WP_OUT_L_ADDR 0x2a
166
167
168
169
170
171
172#define ST_PRESS_LPS25H_WAI_EXP 0xbd
173#define ST_PRESS_LPS25H_ODR_ADDR 0x20
174#define ST_PRESS_LPS25H_ODR_MASK 0x70
175#define ST_PRESS_LPS25H_ODR_AVL_1HZ_VAL 0x01
176#define ST_PRESS_LPS25H_ODR_AVL_7HZ_VAL 0x02
177#define ST_PRESS_LPS25H_ODR_AVL_13HZ_VAL 0x03
178#define ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL 0x04
179#define ST_PRESS_LPS25H_PW_ADDR 0x20
180#define ST_PRESS_LPS25H_PW_MASK 0x80
181#define ST_PRESS_LPS25H_BDU_ADDR 0x20
182#define ST_PRESS_LPS25H_BDU_MASK 0x04
183#define ST_PRESS_LPS25H_DRDY_IRQ_ADDR 0x23
184#define ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK 0x01
185#define ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK 0x10
186#define ST_PRESS_LPS25H_IHL_IRQ_ADDR 0x22
187#define ST_PRESS_LPS25H_IHL_IRQ_MASK 0x80
188#define ST_PRESS_LPS25H_OD_IRQ_ADDR 0x22
189#define ST_PRESS_LPS25H_OD_IRQ_MASK 0x40
190#define ST_PRESS_LPS25H_MULTIREAD_BIT true
191#define ST_PRESS_LPS25H_OUT_XL_ADDR 0x28
192#define ST_TEMP_LPS25H_OUT_L_ADDR 0x2b
193
194
195
196
197
198
199
200
201#define ST_PRESS_LPS22HB_LSB_PER_CELSIUS 100UL
202
203#define ST_PRESS_LPS22HB_WAI_EXP 0xb1
204#define ST_PRESS_LPS22HB_ODR_ADDR 0x10
205#define ST_PRESS_LPS22HB_ODR_MASK 0x70
206#define ST_PRESS_LPS22HB_ODR_AVL_1HZ_VAL 0x01
207#define ST_PRESS_LPS22HB_ODR_AVL_10HZ_VAL 0x02
208#define ST_PRESS_LPS22HB_ODR_AVL_25HZ_VAL 0x03
209#define ST_PRESS_LPS22HB_ODR_AVL_50HZ_VAL 0x04
210#define ST_PRESS_LPS22HB_ODR_AVL_75HZ_VAL 0x05
211#define ST_PRESS_LPS22HB_PW_ADDR 0x10
212#define ST_PRESS_LPS22HB_PW_MASK 0x70
213#define ST_PRESS_LPS22HB_BDU_ADDR 0x10
214#define ST_PRESS_LPS22HB_BDU_MASK 0x02
215#define ST_PRESS_LPS22HB_DRDY_IRQ_ADDR 0x12
216#define ST_PRESS_LPS22HB_DRDY_IRQ_INT1_MASK 0x04
217#define ST_PRESS_LPS22HB_DRDY_IRQ_INT2_MASK 0x08
218#define ST_PRESS_LPS22HB_IHL_IRQ_ADDR 0x12
219#define ST_PRESS_LPS22HB_IHL_IRQ_MASK 0x80
220#define ST_PRESS_LPS22HB_OD_IRQ_ADDR 0x12
221#define ST_PRESS_LPS22HB_OD_IRQ_MASK 0x40
222#define ST_PRESS_LPS22HB_MULTIREAD_BIT true
223
224static const struct iio_chan_spec st_press_1_channels[] = {
225 {
226 .type = IIO_PRESSURE,
227 .address = ST_PRESS_1_OUT_XL_ADDR,
228 .scan_index = 0,
229 .scan_type = {
230 .sign = 'u',
231 .realbits = 24,
232 .storagebits = 32,
233 .endianness = IIO_LE,
234 },
235 .info_mask_separate =
236 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
237 },
238 {
239 .type = IIO_TEMP,
240 .address = ST_TEMP_1_OUT_L_ADDR,
241 .scan_index = 1,
242 .scan_type = {
243 .sign = 'u',
244 .realbits = 16,
245 .storagebits = 16,
246 .endianness = IIO_LE,
247 },
248 .info_mask_separate =
249 BIT(IIO_CHAN_INFO_RAW) |
250 BIT(IIO_CHAN_INFO_SCALE) |
251 BIT(IIO_CHAN_INFO_OFFSET),
252 },
253 IIO_CHAN_SOFT_TIMESTAMP(2)
254};
255
256static const struct iio_chan_spec st_press_lps001wp_channels[] = {
257 {
258 .type = IIO_PRESSURE,
259 .address = ST_PRESS_LPS001WP_OUT_L_ADDR,
260 .scan_index = 0,
261 .scan_type = {
262 .sign = 'u',
263 .realbits = 16,
264 .storagebits = 16,
265 .endianness = IIO_LE,
266 },
267 .info_mask_separate =
268 BIT(IIO_CHAN_INFO_RAW) |
269 BIT(IIO_CHAN_INFO_SCALE),
270 },
271 {
272 .type = IIO_TEMP,
273 .address = ST_TEMP_LPS001WP_OUT_L_ADDR,
274 .scan_index = 1,
275 .scan_type = {
276 .sign = 'u',
277 .realbits = 16,
278 .storagebits = 16,
279 .endianness = IIO_LE,
280 },
281 .info_mask_separate =
282 BIT(IIO_CHAN_INFO_RAW) |
283 BIT(IIO_CHAN_INFO_SCALE),
284 },
285 IIO_CHAN_SOFT_TIMESTAMP(2)
286};
287
288static const struct iio_chan_spec st_press_lps22hb_channels[] = {
289 {
290 .type = IIO_PRESSURE,
291 .address = ST_PRESS_1_OUT_XL_ADDR,
292 .scan_index = 0,
293 .scan_type = {
294 .sign = 'u',
295 .realbits = 24,
296 .storagebits = 32,
297 .endianness = IIO_LE,
298 },
299 .info_mask_separate =
300 BIT(IIO_CHAN_INFO_RAW) |
301 BIT(IIO_CHAN_INFO_SCALE),
302 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
303 },
304 {
305 .type = IIO_TEMP,
306 .address = ST_TEMP_1_OUT_L_ADDR,
307 .scan_index = 1,
308 .scan_type = {
309 .sign = 's',
310 .realbits = 16,
311 .storagebits = 16,
312 .endianness = IIO_LE,
313 },
314 .info_mask_separate =
315 BIT(IIO_CHAN_INFO_RAW) |
316 BIT(IIO_CHAN_INFO_SCALE),
317 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
318 },
319 IIO_CHAN_SOFT_TIMESTAMP(2)
320};
321
322static const struct st_sensor_settings st_press_sensors_settings[] = {
323 {
324 .wai = ST_PRESS_LPS331AP_WAI_EXP,
325 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
326 .sensors_supported = {
327 [0] = LPS331AP_PRESS_DEV_NAME,
328 },
329 .ch = (struct iio_chan_spec *)st_press_1_channels,
330 .num_ch = ARRAY_SIZE(st_press_1_channels),
331 .odr = {
332 .addr = ST_PRESS_LPS331AP_ODR_ADDR,
333 .mask = ST_PRESS_LPS331AP_ODR_MASK,
334 .odr_avl = {
335 { 1, ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL, },
336 { 7, ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL, },
337 { 13, ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL, },
338 { 25, ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL, },
339 },
340 },
341 .pw = {
342 .addr = ST_PRESS_LPS331AP_PW_ADDR,
343 .mask = ST_PRESS_LPS331AP_PW_MASK,
344 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
345 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
346 },
347 .fs = {
348 .addr = ST_PRESS_LPS331AP_FS_ADDR,
349 .mask = ST_PRESS_LPS331AP_FS_MASK,
350 .fs_avl = {
351
352
353
354
355 [0] = {
356 .num = ST_PRESS_FS_AVL_1260MB,
357 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
358 .gain2 = ST_PRESS_LSB_PER_CELSIUS,
359 },
360 },
361 },
362 .bdu = {
363 .addr = ST_PRESS_LPS331AP_BDU_ADDR,
364 .mask = ST_PRESS_LPS331AP_BDU_MASK,
365 },
366 .drdy_irq = {
367 .addr = ST_PRESS_LPS331AP_DRDY_IRQ_ADDR,
368 .mask_int1 = ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK,
369 .mask_int2 = ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK,
370 .addr_ihl = ST_PRESS_LPS331AP_IHL_IRQ_ADDR,
371 .mask_ihl = ST_PRESS_LPS331AP_IHL_IRQ_MASK,
372 .addr_od = ST_PRESS_LPS331AP_OD_IRQ_ADDR,
373 .mask_od = ST_PRESS_LPS331AP_OD_IRQ_MASK,
374 .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
375 },
376 .multi_read_bit = ST_PRESS_LPS331AP_MULTIREAD_BIT,
377 .bootime = 2,
378 },
379 {
380 .wai = ST_PRESS_LPS001WP_WAI_EXP,
381 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
382 .sensors_supported = {
383 [0] = LPS001WP_PRESS_DEV_NAME,
384 },
385 .ch = (struct iio_chan_spec *)st_press_lps001wp_channels,
386 .num_ch = ARRAY_SIZE(st_press_lps001wp_channels),
387 .odr = {
388 .addr = ST_PRESS_LPS001WP_ODR_ADDR,
389 .mask = ST_PRESS_LPS001WP_ODR_MASK,
390 .odr_avl = {
391 { 1, ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL, },
392 { 7, ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL, },
393 { 13, ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL, },
394 },
395 },
396 .pw = {
397 .addr = ST_PRESS_LPS001WP_PW_ADDR,
398 .mask = ST_PRESS_LPS001WP_PW_MASK,
399 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
400 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
401 },
402 .fs = {
403 .fs_avl = {
404
405
406
407
408 [0] = {
409 .num = ST_PRESS_FS_AVL_1100MB,
410 .gain = ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN,
411 .gain2 = ST_PRESS_LPS001WP_LSB_PER_CELSIUS,
412 },
413 },
414 },
415 .bdu = {
416 .addr = ST_PRESS_LPS001WP_BDU_ADDR,
417 .mask = ST_PRESS_LPS001WP_BDU_MASK,
418 },
419 .drdy_irq = {
420 .addr = 0,
421 },
422 .multi_read_bit = ST_PRESS_LPS001WP_MULTIREAD_BIT,
423 .bootime = 2,
424 },
425 {
426 .wai = ST_PRESS_LPS25H_WAI_EXP,
427 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
428 .sensors_supported = {
429 [0] = LPS25H_PRESS_DEV_NAME,
430 },
431 .ch = (struct iio_chan_spec *)st_press_1_channels,
432 .num_ch = ARRAY_SIZE(st_press_1_channels),
433 .odr = {
434 .addr = ST_PRESS_LPS25H_ODR_ADDR,
435 .mask = ST_PRESS_LPS25H_ODR_MASK,
436 .odr_avl = {
437 { 1, ST_PRESS_LPS25H_ODR_AVL_1HZ_VAL, },
438 { 7, ST_PRESS_LPS25H_ODR_AVL_7HZ_VAL, },
439 { 13, ST_PRESS_LPS25H_ODR_AVL_13HZ_VAL, },
440 { 25, ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL, },
441 },
442 },
443 .pw = {
444 .addr = ST_PRESS_LPS25H_PW_ADDR,
445 .mask = ST_PRESS_LPS25H_PW_MASK,
446 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
447 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
448 },
449 .fs = {
450 .fs_avl = {
451
452
453
454
455 [0] = {
456 .num = ST_PRESS_FS_AVL_1260MB,
457 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
458 .gain2 = ST_PRESS_LSB_PER_CELSIUS,
459 },
460 },
461 },
462 .bdu = {
463 .addr = ST_PRESS_LPS25H_BDU_ADDR,
464 .mask = ST_PRESS_LPS25H_BDU_MASK,
465 },
466 .drdy_irq = {
467 .addr = ST_PRESS_LPS25H_DRDY_IRQ_ADDR,
468 .mask_int1 = ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK,
469 .mask_int2 = ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK,
470 .addr_ihl = ST_PRESS_LPS25H_IHL_IRQ_ADDR,
471 .mask_ihl = ST_PRESS_LPS25H_IHL_IRQ_MASK,
472 .addr_od = ST_PRESS_LPS25H_OD_IRQ_ADDR,
473 .mask_od = ST_PRESS_LPS25H_OD_IRQ_MASK,
474 .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
475 },
476 .multi_read_bit = ST_PRESS_LPS25H_MULTIREAD_BIT,
477 .bootime = 2,
478 },
479 {
480 .wai = ST_PRESS_LPS22HB_WAI_EXP,
481 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
482 .sensors_supported = {
483 [0] = LPS22HB_PRESS_DEV_NAME,
484 },
485 .ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
486 .num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
487 .odr = {
488 .addr = ST_PRESS_LPS22HB_ODR_ADDR,
489 .mask = ST_PRESS_LPS22HB_ODR_MASK,
490 .odr_avl = {
491 { 1, ST_PRESS_LPS22HB_ODR_AVL_1HZ_VAL, },
492 { 10, ST_PRESS_LPS22HB_ODR_AVL_10HZ_VAL, },
493 { 25, ST_PRESS_LPS22HB_ODR_AVL_25HZ_VAL, },
494 { 50, ST_PRESS_LPS22HB_ODR_AVL_50HZ_VAL, },
495 { 75, ST_PRESS_LPS22HB_ODR_AVL_75HZ_VAL, },
496 },
497 },
498 .pw = {
499 .addr = ST_PRESS_LPS22HB_PW_ADDR,
500 .mask = ST_PRESS_LPS22HB_PW_MASK,
501 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
502 },
503 .fs = {
504 .fs_avl = {
505
506
507
508
509 [0] = {
510 .num = ST_PRESS_FS_AVL_1260MB,
511 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
512 .gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
513 },
514 },
515 },
516 .bdu = {
517 .addr = ST_PRESS_LPS22HB_BDU_ADDR,
518 .mask = ST_PRESS_LPS22HB_BDU_MASK,
519 },
520 .drdy_irq = {
521 .addr = ST_PRESS_LPS22HB_DRDY_IRQ_ADDR,
522 .mask_int1 = ST_PRESS_LPS22HB_DRDY_IRQ_INT1_MASK,
523 .mask_int2 = ST_PRESS_LPS22HB_DRDY_IRQ_INT2_MASK,
524 .addr_ihl = ST_PRESS_LPS22HB_IHL_IRQ_ADDR,
525 .mask_ihl = ST_PRESS_LPS22HB_IHL_IRQ_MASK,
526 .addr_od = ST_PRESS_LPS22HB_OD_IRQ_ADDR,
527 .mask_od = ST_PRESS_LPS22HB_OD_IRQ_MASK,
528 .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
529 },
530 .multi_read_bit = ST_PRESS_LPS22HB_MULTIREAD_BIT,
531 },
532};
533
534static int st_press_write_raw(struct iio_dev *indio_dev,
535 struct iio_chan_spec const *ch,
536 int val,
537 int val2,
538 long mask)
539{
540 int err;
541
542 switch (mask) {
543 case IIO_CHAN_INFO_SAMP_FREQ:
544 if (val2)
545 return -EINVAL;
546 mutex_lock(&indio_dev->mlock);
547 err = st_sensors_set_odr(indio_dev, val);
548 mutex_unlock(&indio_dev->mlock);
549 return err;
550 default:
551 return -EINVAL;
552 }
553}
554
555static int st_press_read_raw(struct iio_dev *indio_dev,
556 struct iio_chan_spec const *ch, int *val,
557 int *val2, long mask)
558{
559 int err;
560 struct st_sensor_data *press_data = iio_priv(indio_dev);
561
562 switch (mask) {
563 case IIO_CHAN_INFO_RAW:
564 err = st_sensors_read_info_raw(indio_dev, ch, val);
565 if (err < 0)
566 goto read_error;
567
568 return IIO_VAL_INT;
569 case IIO_CHAN_INFO_SCALE:
570 switch (ch->type) {
571 case IIO_PRESSURE:
572 *val = 0;
573 *val2 = press_data->current_fullscale->gain;
574 return IIO_VAL_INT_PLUS_NANO;
575 case IIO_TEMP:
576 *val = MCELSIUS_PER_CELSIUS;
577 *val2 = press_data->current_fullscale->gain2;
578 return IIO_VAL_FRACTIONAL;
579 default:
580 err = -EINVAL;
581 goto read_error;
582 }
583
584 case IIO_CHAN_INFO_OFFSET:
585 switch (ch->type) {
586 case IIO_TEMP:
587 *val = ST_PRESS_MILLI_CELSIUS_OFFSET *
588 press_data->current_fullscale->gain2;
589 *val2 = MCELSIUS_PER_CELSIUS;
590 break;
591 default:
592 err = -EINVAL;
593 goto read_error;
594 }
595
596 return IIO_VAL_FRACTIONAL;
597 case IIO_CHAN_INFO_SAMP_FREQ:
598 *val = press_data->odr;
599 return IIO_VAL_INT;
600 default:
601 return -EINVAL;
602 }
603
604read_error:
605 return err;
606}
607
608static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
609
610static struct attribute *st_press_attributes[] = {
611 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
612 NULL,
613};
614
615static const struct attribute_group st_press_attribute_group = {
616 .attrs = st_press_attributes,
617};
618
619static const struct iio_info press_info = {
620 .driver_module = THIS_MODULE,
621 .attrs = &st_press_attribute_group,
622 .read_raw = &st_press_read_raw,
623 .write_raw = &st_press_write_raw,
624 .debugfs_reg_access = &st_sensors_debugfs_reg_access,
625};
626
627#ifdef CONFIG_IIO_TRIGGER
628static const struct iio_trigger_ops st_press_trigger_ops = {
629 .owner = THIS_MODULE,
630 .set_trigger_state = ST_PRESS_TRIGGER_SET_STATE,
631 .validate_device = st_sensors_validate_device,
632};
633#define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops)
634#else
635#define ST_PRESS_TRIGGER_OPS NULL
636#endif
637
638int st_press_common_probe(struct iio_dev *indio_dev)
639{
640 struct st_sensor_data *press_data = iio_priv(indio_dev);
641 int irq = press_data->get_irq_data_ready(indio_dev);
642 int err;
643
644 indio_dev->modes = INDIO_DIRECT_MODE;
645 indio_dev->info = &press_info;
646 mutex_init(&press_data->tb.buf_lock);
647
648 err = st_sensors_power_enable(indio_dev);
649 if (err)
650 return err;
651
652 err = st_sensors_check_device_support(indio_dev,
653 ARRAY_SIZE(st_press_sensors_settings),
654 st_press_sensors_settings);
655 if (err < 0)
656 goto st_press_power_off;
657
658
659
660
661
662
663
664 press_data->num_data_channels = press_data->sensor_settings->num_ch - 1;
665 press_data->multiread_bit = press_data->sensor_settings->multi_read_bit;
666 indio_dev->channels = press_data->sensor_settings->ch;
667 indio_dev->num_channels = press_data->sensor_settings->num_ch;
668
669 press_data->current_fullscale =
670 (struct st_sensor_fullscale_avl *)
671 &press_data->sensor_settings->fs.fs_avl[0];
672
673 press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
674
675
676 if (!press_data->dev->platform_data &&
677 press_data->sensor_settings->drdy_irq.addr)
678 press_data->dev->platform_data =
679 (struct st_sensors_platform_data *)&default_press_pdata;
680
681 err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data);
682 if (err < 0)
683 goto st_press_power_off;
684
685 err = st_press_allocate_ring(indio_dev);
686 if (err < 0)
687 goto st_press_power_off;
688
689 if (irq > 0) {
690 err = st_sensors_allocate_trigger(indio_dev,
691 ST_PRESS_TRIGGER_OPS);
692 if (err < 0)
693 goto st_press_probe_trigger_error;
694 }
695
696 err = iio_device_register(indio_dev);
697 if (err)
698 goto st_press_device_register_error;
699
700 dev_info(&indio_dev->dev, "registered pressure sensor %s\n",
701 indio_dev->name);
702
703 return err;
704
705st_press_device_register_error:
706 if (irq > 0)
707 st_sensors_deallocate_trigger(indio_dev);
708st_press_probe_trigger_error:
709 st_press_deallocate_ring(indio_dev);
710st_press_power_off:
711 st_sensors_power_disable(indio_dev);
712
713 return err;
714}
715EXPORT_SYMBOL(st_press_common_probe);
716
717void st_press_common_remove(struct iio_dev *indio_dev)
718{
719 struct st_sensor_data *press_data = iio_priv(indio_dev);
720
721 st_sensors_power_disable(indio_dev);
722
723 iio_device_unregister(indio_dev);
724 if (press_data->get_irq_data_ready(indio_dev) > 0)
725 st_sensors_deallocate_trigger(indio_dev);
726
727 st_press_deallocate_ring(indio_dev);
728}
729EXPORT_SYMBOL(st_press_common_remove);
730
731MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
732MODULE_DESCRIPTION("STMicroelectronics pressures driver");
733MODULE_LICENSE("GPL v2");
734