1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * STMicroelectronics pressures driver
4 *
5 * Copyright 2013 STMicroelectronics Inc.
6 *
7 * Denis Ciocca <denis.ciocca@st.com>
8 */
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include <linux/errno.h>
14 #include <linux/types.h>
15 #include <linux/interrupt.h>
16 #include <linux/i2c.h>
17 #include <linux/irq.h>
18 #include <linux/delay.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
21 #include <linux/iio/trigger.h>
22 #include <linux/iio/buffer.h>
23 #include <asm/unaligned.h>
24
25 #include <linux/iio/common/st_sensors.h>
26 #include "st_pressure.h"
27
28 /*
29 * About determining pressure scaling factors
30 * ------------------------------------------
31 *
32 * Datasheets specify typical pressure sensitivity so that pressure is computed
33 * according to the following equation :
34 * pressure[mBar] = raw / sensitivity
35 * where :
36 * raw the 24 bits long raw sampled pressure
37 * sensitivity a scaling factor specified by the datasheet in LSB/mBar
38 *
39 * IIO ABI expects pressure to be expressed as kPascal, hence pressure should be
40 * computed according to :
41 * pressure[kPascal] = pressure[mBar] / 10
42 * = raw / (sensitivity * 10) (1)
43 *
44 * Finally, st_press_read_raw() returns pressure scaling factor as an
45 * IIO_VAL_INT_PLUS_NANO with a zero integral part and "gain" as decimal part.
46 * Therefore, from (1), "gain" becomes :
47 * gain = 10^9 / (sensitivity * 10)
48 * = 10^8 / sensitivity
49 *
50 * About determining temperature scaling factors and offsets
51 * ---------------------------------------------------------
52 *
53 * Datasheets specify typical temperature sensitivity and offset so that
54 * temperature is computed according to the following equation :
55 * temp[Celsius] = offset[Celsius] + (raw / sensitivity)
56 * where :
57 * raw the 16 bits long raw sampled temperature
58 * offset a constant specified by the datasheet in degree Celsius
59 * (sometimes zero)
60 * sensitivity a scaling factor specified by the datasheet in LSB/Celsius
61 *
62 * IIO ABI expects temperature to be expressed as milli degree Celsius such as
63 * user space should compute temperature according to :
64 * temp[mCelsius] = temp[Celsius] * 10^3
65 * = (offset[Celsius] + (raw / sensitivity)) * 10^3
66 * = ((offset[Celsius] * sensitivity) + raw) *
67 * (10^3 / sensitivity) (2)
68 *
69 * IIO ABI expects user space to apply offset and scaling factors to raw samples
70 * according to :
71 * temp[mCelsius] = (OFFSET + raw) * SCALE
72 * where :
73 * OFFSET an arbitrary constant exposed by device
74 * SCALE an arbitrary scaling factor exposed by device
75 *
76 * Matching OFFSET and SCALE with members of (2) gives :
77 * OFFSET = offset[Celsius] * sensitivity (3)
78 * SCALE = 10^3 / sensitivity (4)
79 *
80 * st_press_read_raw() returns temperature scaling factor as an
81 * IIO_VAL_FRACTIONAL with a 10^3 numerator and "gain2" as denominator.
82 * Therefore, from (3), "gain2" becomes :
83 * gain2 = sensitivity
84 *
85 * When declared within channel, i.e. for a non zero specified offset,
86 * st_press_read_raw() will return the latter as an IIO_VAL_FRACTIONAL such as :
87 * numerator = OFFSET * 10^3
88 * denominator = 10^3
89 * giving from (4):
90 * numerator = offset[Celsius] * 10^3 * sensitivity
91 * = offset[mCelsius] * gain2
92 */
93
94 #define MCELSIUS_PER_CELSIUS 1000
95
96 /* Default pressure sensitivity */
97 #define ST_PRESS_LSB_PER_MBAR 4096UL
98 #define ST_PRESS_KPASCAL_NANO_SCALE (100000000UL / \
99 ST_PRESS_LSB_PER_MBAR)
100
101 /* Default temperature sensitivity */
102 #define ST_PRESS_LSB_PER_CELSIUS 480UL
103 #define ST_PRESS_MILLI_CELSIUS_OFFSET 42500UL
104
105 /* FULLSCALE */
106 #define ST_PRESS_FS_AVL_1100MB 1100
107 #define ST_PRESS_FS_AVL_1260MB 1260
108
109 #define ST_PRESS_1_OUT_XL_ADDR 0x28
110 #define ST_TEMP_1_OUT_L_ADDR 0x2b
111
112 /* LPS001WP pressure resolution */
113 #define ST_PRESS_LPS001WP_LSB_PER_MBAR 16UL
114 /* LPS001WP temperature resolution */
115 #define ST_PRESS_LPS001WP_LSB_PER_CELSIUS 64UL
116 /* LPS001WP pressure gain */
117 #define ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN \
118 (100000000UL / ST_PRESS_LPS001WP_LSB_PER_MBAR)
119 /* LPS001WP pressure and temp L addresses */
120 #define ST_PRESS_LPS001WP_OUT_L_ADDR 0x28
121 #define ST_TEMP_LPS001WP_OUT_L_ADDR 0x2a
122
123 /* LPS25H pressure and temp L addresses */
124 #define ST_PRESS_LPS25H_OUT_XL_ADDR 0x28
125 #define ST_TEMP_LPS25H_OUT_L_ADDR 0x2b
126
127 /* LPS22HB temperature sensitivity */
128 #define ST_PRESS_LPS22HB_LSB_PER_CELSIUS 100UL
129
130 static const struct iio_chan_spec st_press_1_channels[] = {
131 {
132 .type = IIO_PRESSURE,
133 .address = ST_PRESS_1_OUT_XL_ADDR,
134 .scan_index = 0,
135 .scan_type = {
136 .sign = 's',
137 .realbits = 24,
138 .storagebits = 32,
139 .endianness = IIO_LE,
140 },
141 .info_mask_separate =
142 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
143 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
144 },
145 {
146 .type = IIO_TEMP,
147 .address = ST_TEMP_1_OUT_L_ADDR,
148 .scan_index = 1,
149 .scan_type = {
150 .sign = 's',
151 .realbits = 16,
152 .storagebits = 16,
153 .endianness = IIO_LE,
154 },
155 .info_mask_separate =
156 BIT(IIO_CHAN_INFO_RAW) |
157 BIT(IIO_CHAN_INFO_SCALE) |
158 BIT(IIO_CHAN_INFO_OFFSET),
159 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
160 },
161 IIO_CHAN_SOFT_TIMESTAMP(2)
162 };
163
164 static const struct iio_chan_spec st_press_lps001wp_channels[] = {
165 {
166 .type = IIO_PRESSURE,
167 .address = ST_PRESS_LPS001WP_OUT_L_ADDR,
168 .scan_index = 0,
169 .scan_type = {
170 .sign = 's',
171 .realbits = 16,
172 .storagebits = 16,
173 .endianness = IIO_LE,
174 },
175 .info_mask_separate =
176 BIT(IIO_CHAN_INFO_RAW) |
177 BIT(IIO_CHAN_INFO_SCALE),
178 },
179 {
180 .type = IIO_TEMP,
181 .address = ST_TEMP_LPS001WP_OUT_L_ADDR,
182 .scan_index = 1,
183 .scan_type = {
184 .sign = 's',
185 .realbits = 16,
186 .storagebits = 16,
187 .endianness = IIO_LE,
188 },
189 .info_mask_separate =
190 BIT(IIO_CHAN_INFO_RAW) |
191 BIT(IIO_CHAN_INFO_SCALE),
192 },
193 IIO_CHAN_SOFT_TIMESTAMP(2)
194 };
195
196 static const struct iio_chan_spec st_press_lps22hb_channels[] = {
197 {
198 .type = IIO_PRESSURE,
199 .address = ST_PRESS_1_OUT_XL_ADDR,
200 .scan_index = 0,
201 .scan_type = {
202 .sign = 's',
203 .realbits = 24,
204 .storagebits = 32,
205 .endianness = IIO_LE,
206 },
207 .info_mask_separate =
208 BIT(IIO_CHAN_INFO_RAW) |
209 BIT(IIO_CHAN_INFO_SCALE),
210 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
211 },
212 {
213 .type = IIO_TEMP,
214 .address = ST_TEMP_1_OUT_L_ADDR,
215 .scan_index = 1,
216 .scan_type = {
217 .sign = 's',
218 .realbits = 16,
219 .storagebits = 16,
220 .endianness = IIO_LE,
221 },
222 .info_mask_separate =
223 BIT(IIO_CHAN_INFO_RAW) |
224 BIT(IIO_CHAN_INFO_SCALE),
225 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
226 },
227 IIO_CHAN_SOFT_TIMESTAMP(2)
228 };
229
230 static const struct st_sensor_settings st_press_sensors_settings[] = {
231 {
232 /*
233 * CUSTOM VALUES FOR LPS331AP SENSOR
234 * See LPS331AP datasheet:
235 * http://www2.st.com/resource/en/datasheet/lps331ap.pdf
236 */
237 .wai = 0xbb,
238 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
239 .sensors_supported = {
240 [0] = LPS331AP_PRESS_DEV_NAME,
241 },
242 .ch = (struct iio_chan_spec *)st_press_1_channels,
243 .num_ch = ARRAY_SIZE(st_press_1_channels),
244 .odr = {
245 .addr = 0x20,
246 .mask = 0x70,
247 .odr_avl = {
248 { .hz = 1, .value = 0x01 },
249 { .hz = 7, .value = 0x05 },
250 { .hz = 13, .value = 0x06 },
251 { .hz = 25, .value = 0x07 },
252 },
253 },
254 .pw = {
255 .addr = 0x20,
256 .mask = 0x80,
257 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
258 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
259 },
260 .fs = {
261 .addr = 0x23,
262 .mask = 0x30,
263 .fs_avl = {
264 /*
265 * Pressure and temperature sensitivity values
266 * as defined in table 3 of LPS331AP datasheet.
267 */
268 [0] = {
269 .num = ST_PRESS_FS_AVL_1260MB,
270 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
271 .gain2 = ST_PRESS_LSB_PER_CELSIUS,
272 },
273 },
274 },
275 .bdu = {
276 .addr = 0x20,
277 .mask = 0x04,
278 },
279 .drdy_irq = {
280 .int1 = {
281 .addr = 0x22,
282 .mask = 0x04,
283 .addr_od = 0x22,
284 .mask_od = 0x40,
285 },
286 .int2 = {
287 .addr = 0x22,
288 .mask = 0x20,
289 .addr_od = 0x22,
290 .mask_od = 0x40,
291 },
292 .addr_ihl = 0x22,
293 .mask_ihl = 0x80,
294 .stat_drdy = {
295 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
296 .mask = 0x03,
297 },
298 },
299 .sim = {
300 .addr = 0x20,
301 .value = BIT(0),
302 },
303 .multi_read_bit = true,
304 .bootime = 2,
305 },
306 {
307 /*
308 * CUSTOM VALUES FOR LPS001WP SENSOR
309 */
310 .wai = 0xba,
311 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
312 .sensors_supported = {
313 [0] = LPS001WP_PRESS_DEV_NAME,
314 },
315 .ch = (struct iio_chan_spec *)st_press_lps001wp_channels,
316 .num_ch = ARRAY_SIZE(st_press_lps001wp_channels),
317 .odr = {
318 .addr = 0x20,
319 .mask = 0x30,
320 .odr_avl = {
321 { .hz = 1, .value = 0x01 },
322 { .hz = 7, .value = 0x02 },
323 { .hz = 13, .value = 0x03 },
324 },
325 },
326 .pw = {
327 .addr = 0x20,
328 .mask = 0x40,
329 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
330 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
331 },
332 .fs = {
333 .fs_avl = {
334 /*
335 * Pressure and temperature resolution values
336 * as defined in table 3 of LPS001WP datasheet.
337 */
338 [0] = {
339 .num = ST_PRESS_FS_AVL_1100MB,
340 .gain = ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN,
341 .gain2 = ST_PRESS_LPS001WP_LSB_PER_CELSIUS,
342 },
343 },
344 },
345 .bdu = {
346 .addr = 0x20,
347 .mask = 0x04,
348 },
349 .sim = {
350 .addr = 0x20,
351 .value = BIT(0),
352 },
353 .multi_read_bit = true,
354 .bootime = 2,
355 },
356 {
357 /*
358 * CUSTOM VALUES FOR LPS25H SENSOR
359 * See LPS25H datasheet:
360 * http://www2.st.com/resource/en/datasheet/lps25h.pdf
361 */
362 .wai = 0xbd,
363 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
364 .sensors_supported = {
365 [0] = LPS25H_PRESS_DEV_NAME,
366 },
367 .ch = (struct iio_chan_spec *)st_press_1_channels,
368 .num_ch = ARRAY_SIZE(st_press_1_channels),
369 .odr = {
370 .addr = 0x20,
371 .mask = 0x70,
372 .odr_avl = {
373 { .hz = 1, .value = 0x01 },
374 { .hz = 7, .value = 0x02 },
375 { .hz = 13, .value = 0x03 },
376 { .hz = 25, .value = 0x04 },
377 },
378 },
379 .pw = {
380 .addr = 0x20,
381 .mask = 0x80,
382 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
383 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
384 },
385 .fs = {
386 .fs_avl = {
387 /*
388 * Pressure and temperature sensitivity values
389 * as defined in table 3 of LPS25H datasheet.
390 */
391 [0] = {
392 .num = ST_PRESS_FS_AVL_1260MB,
393 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
394 .gain2 = ST_PRESS_LSB_PER_CELSIUS,
395 },
396 },
397 },
398 .bdu = {
399 .addr = 0x20,
400 .mask = 0x04,
401 },
402 .drdy_irq = {
403 .int1 = {
404 .addr = 0x23,
405 .mask = 0x01,
406 .addr_od = 0x22,
407 .mask_od = 0x40,
408 },
409 .addr_ihl = 0x22,
410 .mask_ihl = 0x80,
411 .stat_drdy = {
412 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
413 .mask = 0x03,
414 },
415 },
416 .sim = {
417 .addr = 0x20,
418 .value = BIT(0),
419 },
420 .multi_read_bit = true,
421 .bootime = 2,
422 },
423 {
424 /*
425 * CUSTOM VALUES FOR LPS22HB SENSOR
426 * See LPS22HB datasheet:
427 * http://www2.st.com/resource/en/datasheet/lps22hb.pdf
428 */
429 .wai = 0xb1,
430 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
431 .sensors_supported = {
432 [0] = LPS22HB_PRESS_DEV_NAME,
433 [1] = LPS33HW_PRESS_DEV_NAME,
434 [2] = LPS35HW_PRESS_DEV_NAME,
435 },
436 .ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
437 .num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
438 .odr = {
439 .addr = 0x10,
440 .mask = 0x70,
441 .odr_avl = {
442 { .hz = 1, .value = 0x01 },
443 { .hz = 10, .value = 0x02 },
444 { .hz = 25, .value = 0x03 },
445 { .hz = 50, .value = 0x04 },
446 { .hz = 75, .value = 0x05 },
447 },
448 },
449 .pw = {
450 .addr = 0x10,
451 .mask = 0x70,
452 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
453 },
454 .fs = {
455 .fs_avl = {
456 /*
457 * Pressure and temperature sensitivity values
458 * as defined in table 3 of LPS22HB datasheet.
459 */
460 [0] = {
461 .num = ST_PRESS_FS_AVL_1260MB,
462 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
463 .gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
464 },
465 },
466 },
467 .bdu = {
468 .addr = 0x10,
469 .mask = 0x02,
470 },
471 .drdy_irq = {
472 .int1 = {
473 .addr = 0x12,
474 .mask = 0x04,
475 .addr_od = 0x12,
476 .mask_od = 0x40,
477 },
478 .addr_ihl = 0x12,
479 .mask_ihl = 0x80,
480 .stat_drdy = {
481 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
482 .mask = 0x03,
483 },
484 },
485 .sim = {
486 .addr = 0x10,
487 .value = BIT(0),
488 },
489 .multi_read_bit = false,
490 .bootime = 2,
491 },
492 {
493 /*
494 * CUSTOM VALUES FOR LPS22HH SENSOR
495 * See LPS22HH datasheet:
496 * http://www2.st.com/resource/en/datasheet/lps22hh.pdf
497 */
498 .wai = 0xb3,
499 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
500 .sensors_supported = {
501 [0] = LPS22HH_PRESS_DEV_NAME,
502 },
503 .ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
504 .num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
505 .odr = {
506 .addr = 0x10,
507 .mask = 0x70,
508 .odr_avl = {
509 { .hz = 1, .value = 0x01 },
510 { .hz = 10, .value = 0x02 },
511 { .hz = 25, .value = 0x03 },
512 { .hz = 50, .value = 0x04 },
513 { .hz = 75, .value = 0x05 },
514 { .hz = 100, .value = 0x06 },
515 { .hz = 200, .value = 0x07 },
516 },
517 },
518 .pw = {
519 .addr = 0x10,
520 .mask = 0x70,
521 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
522 },
523 .fs = {
524 .fs_avl = {
525 /*
526 * Pressure and temperature sensitivity values
527 * as defined in table 3 of LPS22HH datasheet.
528 */
529 [0] = {
530 .num = ST_PRESS_FS_AVL_1260MB,
531 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
532 .gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
533 },
534 },
535 },
536 .bdu = {
537 .addr = 0x10,
538 .mask = BIT(1),
539 },
540 .drdy_irq = {
541 .int1 = {
542 .addr = 0x12,
543 .mask = BIT(2),
544 .addr_od = 0x11,
545 .mask_od = BIT(5),
546 },
547 .addr_ihl = 0x11,
548 .mask_ihl = BIT(6),
549 .stat_drdy = {
550 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
551 .mask = 0x03,
552 },
553 },
554 .sim = {
555 .addr = 0x10,
556 .value = BIT(0),
557 },
558 .multi_read_bit = false,
559 .bootime = 2,
560 },
561 };
562
st_press_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * ch,int val,int val2,long mask)563 static int st_press_write_raw(struct iio_dev *indio_dev,
564 struct iio_chan_spec const *ch,
565 int val,
566 int val2,
567 long mask)
568 {
569 int err;
570
571 switch (mask) {
572 case IIO_CHAN_INFO_SAMP_FREQ:
573 if (val2)
574 return -EINVAL;
575 mutex_lock(&indio_dev->mlock);
576 err = st_sensors_set_odr(indio_dev, val);
577 mutex_unlock(&indio_dev->mlock);
578 return err;
579 default:
580 return -EINVAL;
581 }
582 }
583
st_press_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * ch,int * val,int * val2,long mask)584 static int st_press_read_raw(struct iio_dev *indio_dev,
585 struct iio_chan_spec const *ch, int *val,
586 int *val2, long mask)
587 {
588 int err;
589 struct st_sensor_data *press_data = iio_priv(indio_dev);
590
591 switch (mask) {
592 case IIO_CHAN_INFO_RAW:
593 err = st_sensors_read_info_raw(indio_dev, ch, val);
594 if (err < 0)
595 goto read_error;
596
597 return IIO_VAL_INT;
598 case IIO_CHAN_INFO_SCALE:
599 switch (ch->type) {
600 case IIO_PRESSURE:
601 *val = 0;
602 *val2 = press_data->current_fullscale->gain;
603 return IIO_VAL_INT_PLUS_NANO;
604 case IIO_TEMP:
605 *val = MCELSIUS_PER_CELSIUS;
606 *val2 = press_data->current_fullscale->gain2;
607 return IIO_VAL_FRACTIONAL;
608 default:
609 err = -EINVAL;
610 goto read_error;
611 }
612
613 case IIO_CHAN_INFO_OFFSET:
614 switch (ch->type) {
615 case IIO_TEMP:
616 *val = ST_PRESS_MILLI_CELSIUS_OFFSET *
617 press_data->current_fullscale->gain2;
618 *val2 = MCELSIUS_PER_CELSIUS;
619 break;
620 default:
621 err = -EINVAL;
622 goto read_error;
623 }
624
625 return IIO_VAL_FRACTIONAL;
626 case IIO_CHAN_INFO_SAMP_FREQ:
627 *val = press_data->odr;
628 return IIO_VAL_INT;
629 default:
630 return -EINVAL;
631 }
632
633 read_error:
634 return err;
635 }
636
637 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
638
639 static struct attribute *st_press_attributes[] = {
640 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
641 NULL,
642 };
643
644 static const struct attribute_group st_press_attribute_group = {
645 .attrs = st_press_attributes,
646 };
647
648 static const struct iio_info press_info = {
649 .attrs = &st_press_attribute_group,
650 .read_raw = &st_press_read_raw,
651 .write_raw = &st_press_write_raw,
652 .debugfs_reg_access = &st_sensors_debugfs_reg_access,
653 };
654
655 #ifdef CONFIG_IIO_TRIGGER
656 static const struct iio_trigger_ops st_press_trigger_ops = {
657 .set_trigger_state = ST_PRESS_TRIGGER_SET_STATE,
658 .validate_device = st_sensors_validate_device,
659 };
660 #define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops)
661 #else
662 #define ST_PRESS_TRIGGER_OPS NULL
663 #endif
664
665 /*
666 * st_press_get_settings() - get sensor settings from device name
667 * @name: device name buffer reference.
668 *
669 * Return: valid reference on success, NULL otherwise.
670 */
st_press_get_settings(const char * name)671 const struct st_sensor_settings *st_press_get_settings(const char *name)
672 {
673 int index = st_sensors_get_settings_index(name,
674 st_press_sensors_settings,
675 ARRAY_SIZE(st_press_sensors_settings));
676 if (index < 0)
677 return NULL;
678
679 return &st_press_sensors_settings[index];
680 }
681 EXPORT_SYMBOL(st_press_get_settings);
682
st_press_common_probe(struct iio_dev * indio_dev)683 int st_press_common_probe(struct iio_dev *indio_dev)
684 {
685 struct st_sensor_data *press_data = iio_priv(indio_dev);
686 struct st_sensors_platform_data *pdata = dev_get_platdata(press_data->dev);
687 int err;
688
689 indio_dev->modes = INDIO_DIRECT_MODE;
690 indio_dev->info = &press_info;
691
692 err = st_sensors_verify_id(indio_dev);
693 if (err < 0)
694 return err;
695
696 /*
697 * Skip timestamping channel while declaring available channels to
698 * common st_sensor layer. Look at st_sensors_get_buffer_element() to
699 * see how timestamps are explicitly pushed as last samples block
700 * element.
701 */
702 press_data->num_data_channels = press_data->sensor_settings->num_ch - 1;
703 indio_dev->channels = press_data->sensor_settings->ch;
704 indio_dev->num_channels = press_data->sensor_settings->num_ch;
705
706 press_data->current_fullscale = &press_data->sensor_settings->fs.fs_avl[0];
707
708 press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
709
710 /* Some devices don't support a data ready pin. */
711 if (!pdata && (press_data->sensor_settings->drdy_irq.int1.addr ||
712 press_data->sensor_settings->drdy_irq.int2.addr))
713 pdata = (struct st_sensors_platform_data *)&default_press_pdata;
714
715 err = st_sensors_init_sensor(indio_dev, pdata);
716 if (err < 0)
717 return err;
718
719 err = st_press_allocate_ring(indio_dev);
720 if (err < 0)
721 return err;
722
723 if (press_data->irq > 0) {
724 err = st_sensors_allocate_trigger(indio_dev,
725 ST_PRESS_TRIGGER_OPS);
726 if (err < 0)
727 goto st_press_probe_trigger_error;
728 }
729
730 err = iio_device_register(indio_dev);
731 if (err)
732 goto st_press_device_register_error;
733
734 dev_info(&indio_dev->dev, "registered pressure sensor %s\n",
735 indio_dev->name);
736
737 return err;
738
739 st_press_device_register_error:
740 if (press_data->irq > 0)
741 st_sensors_deallocate_trigger(indio_dev);
742 st_press_probe_trigger_error:
743 st_press_deallocate_ring(indio_dev);
744 return err;
745 }
746 EXPORT_SYMBOL(st_press_common_probe);
747
st_press_common_remove(struct iio_dev * indio_dev)748 void st_press_common_remove(struct iio_dev *indio_dev)
749 {
750 struct st_sensor_data *press_data = iio_priv(indio_dev);
751
752 iio_device_unregister(indio_dev);
753 if (press_data->irq > 0)
754 st_sensors_deallocate_trigger(indio_dev);
755
756 st_press_deallocate_ring(indio_dev);
757 }
758 EXPORT_SYMBOL(st_press_common_remove);
759
760 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
761 MODULE_DESCRIPTION("STMicroelectronics pressures driver");
762 MODULE_LICENSE("GPL v2");
763