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