1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * MPRLS0025PA - Honeywell MicroPressure pressure sensor series driver
5 * Copyright (c) Andreas Klinger <ak@it-klinger.de>
8 * https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/micropressure-mpr-series/documents/sps-siot-mpr-series-datasheet-32332628-ciid-172626.pdf
12 #include <linux/array_size.h>
13 #include <linux/bitfield.h>
14 #include <linux/bits.h>
15 #include <linux/math64.h>
16 #include <linux/mod_devicetable.h>
17 #include <linux/module.h>
18 #include <linux/property.h>
19 #include <linux/units.h>
21 #include <linux/gpio/consumer.h>
23 #include <linux/iio/buffer.h>
24 #include <linux/iio/trigger_consumer.h>
25 #include <linux/iio/triggered_buffer.h>
27 #include <linux/regulator/consumer.h>
29 #include <linux/unaligned.h>
31 #include "mprls0025pa.h"
33 /* bits in status byte */
34 #define MPR_ST_POWER BIT(6) /* device is powered */
35 #define MPR_ST_BUSY BIT(5) /* device is busy */
36 #define MPR_ST_MEMORY BIT(2) /* integrity test passed */
37 #define MPR_ST_MATH BIT(0) /* internal math saturation */
39 #define MPR_ST_ERR_FLAG (MPR_ST_BUSY | MPR_ST_MEMORY | MPR_ST_MATH)
42 * support _RAW sysfs interface:
44 * Calculation formula from the datasheet:
45 * pressure = (press_cnt - outputmin) * scale + pmin
47 * * pressure - measured pressure in Pascal
48 * * press_cnt - raw value read from sensor
49 * * pmin - minimum pressure range value of sensor (data->pmin)
50 * * pmax - maximum pressure range value of sensor (data->pmax)
51 * * outputmin - minimum numerical range raw value delivered by sensor
52 * (mpr_func_spec.output_min)
53 * * outputmax - maximum numerical range raw value delivered by sensor
54 * (mpr_func_spec.output_max)
55 * * scale - (pmax - pmin) / (outputmax - outputmin)
57 * formula of the userspace:
58 * pressure = (raw + offset) * scale
60 * Values given to the userspace in sysfs interface:
62 * * offset - (-1 * outputmin) - pmin / scale
63 * note: With all sensors from the datasheet pmin = 0
64 * which reduces the offset to (-1 * outputmin)
68 * transfer function A: 10% to 90% of 2^24
69 * transfer function B: 2.5% to 22.5% of 2^24
70 * transfer function C: 20% to 80% of 2^24
72 struct mpr_func_spec
{
77 static const struct mpr_func_spec mpr_func_spec
[] = {
78 [MPR_FUNCTION_A
] = { .output_min
= 1677722, .output_max
= 15099494 },
79 [MPR_FUNCTION_B
] = { .output_min
= 419430, .output_max
= 3774874 },
80 [MPR_FUNCTION_C
] = { .output_min
= 3355443, .output_max
= 13421773 },
84 MPR0001BA
= 0x00, MPR01_6BA
= 0x01, MPR02_5BA
= 0x02, MPR0060MG
= 0x03,
85 MPR0100MG
= 0x04, MPR0160MG
= 0x05, MPR0250MG
= 0x06, MPR0400MG
= 0x07,
86 MPR0600MG
= 0x08, MPR0001BG
= 0x09, MPR01_6BG
= 0x0a, MPR02_5BG
= 0x0b,
87 MPR0100KA
= 0x0c, MPR0160KA
= 0x0d, MPR0250KA
= 0x0e, MPR0006KG
= 0x0f,
88 MPR0010KG
= 0x10, MPR0016KG
= 0x11, MPR0025KG
= 0x12, MPR0040KG
= 0x13,
89 MPR0060KG
= 0x14, MPR0100KG
= 0x15, MPR0160KG
= 0x16, MPR0250KG
= 0x17,
90 MPR0015PA
= 0x18, MPR0025PA
= 0x19, MPR0030PA
= 0x1a, MPR0001PG
= 0x1b,
91 MPR0005PG
= 0x1c, MPR0015PG
= 0x1d, MPR0030PG
= 0x1e, MPR0300YG
= 0x1f,
95 static const char * const mpr_triplet_variants
[MPR_VARIANTS_MAX
] = {
96 [MPR0001BA
] = "0001BA", [MPR01_6BA
] = "01.6BA", [MPR02_5BA
] = "02.5BA",
97 [MPR0060MG
] = "0060MG", [MPR0100MG
] = "0100MG", [MPR0160MG
] = "0160MG",
98 [MPR0250MG
] = "0250MG", [MPR0400MG
] = "0400MG", [MPR0600MG
] = "0600MG",
99 [MPR0001BG
] = "0001BG", [MPR01_6BG
] = "01.6BG", [MPR02_5BG
] = "02.5BG",
100 [MPR0100KA
] = "0100KA", [MPR0160KA
] = "0160KA", [MPR0250KA
] = "0250KA",
101 [MPR0006KG
] = "0006KG", [MPR0010KG
] = "0010KG", [MPR0016KG
] = "0016KG",
102 [MPR0025KG
] = "0025KG", [MPR0040KG
] = "0040KG", [MPR0060KG
] = "0060KG",
103 [MPR0100KG
] = "0100KG", [MPR0160KG
] = "0160KG", [MPR0250KG
] = "0250KG",
104 [MPR0015PA
] = "0015PA", [MPR0025PA
] = "0025PA", [MPR0030PA
] = "0030PA",
105 [MPR0001PG
] = "0001PG", [MPR0005PG
] = "0005PG", [MPR0015PG
] = "0015PG",
106 [MPR0030PG
] = "0030PG", [MPR0300YG
] = "0300YG"
110 * struct mpr_range_config - list of pressure ranges based on nomenclature
111 * @pmin: lowest pressure that can be measured
112 * @pmax: highest pressure that can be measured
114 struct mpr_range_config
{
119 /* All min max limits have been converted to pascals */
120 static const struct mpr_range_config mpr_range_config
[MPR_VARIANTS_MAX
] = {
121 [MPR0001BA
] = { .pmin
= 0, .pmax
= 100000 },
122 [MPR01_6BA
] = { .pmin
= 0, .pmax
= 160000 },
123 [MPR02_5BA
] = { .pmin
= 0, .pmax
= 250000 },
124 [MPR0060MG
] = { .pmin
= 0, .pmax
= 6000 },
125 [MPR0100MG
] = { .pmin
= 0, .pmax
= 10000 },
126 [MPR0160MG
] = { .pmin
= 0, .pmax
= 16000 },
127 [MPR0250MG
] = { .pmin
= 0, .pmax
= 25000 },
128 [MPR0400MG
] = { .pmin
= 0, .pmax
= 40000 },
129 [MPR0600MG
] = { .pmin
= 0, .pmax
= 60000 },
130 [MPR0001BG
] = { .pmin
= 0, .pmax
= 100000 },
131 [MPR01_6BG
] = { .pmin
= 0, .pmax
= 160000 },
132 [MPR02_5BG
] = { .pmin
= 0, .pmax
= 250000 },
133 [MPR0100KA
] = { .pmin
= 0, .pmax
= 100000 },
134 [MPR0160KA
] = { .pmin
= 0, .pmax
= 160000 },
135 [MPR0250KA
] = { .pmin
= 0, .pmax
= 250000 },
136 [MPR0006KG
] = { .pmin
= 0, .pmax
= 6000 },
137 [MPR0010KG
] = { .pmin
= 0, .pmax
= 10000 },
138 [MPR0016KG
] = { .pmin
= 0, .pmax
= 16000 },
139 [MPR0025KG
] = { .pmin
= 0, .pmax
= 25000 },
140 [MPR0040KG
] = { .pmin
= 0, .pmax
= 40000 },
141 [MPR0060KG
] = { .pmin
= 0, .pmax
= 60000 },
142 [MPR0100KG
] = { .pmin
= 0, .pmax
= 100000 },
143 [MPR0160KG
] = { .pmin
= 0, .pmax
= 160000 },
144 [MPR0250KG
] = { .pmin
= 0, .pmax
= 250000 },
145 [MPR0015PA
] = { .pmin
= 0, .pmax
= 103421 },
146 [MPR0025PA
] = { .pmin
= 0, .pmax
= 172369 },
147 [MPR0030PA
] = { .pmin
= 0, .pmax
= 206843 },
148 [MPR0001PG
] = { .pmin
= 0, .pmax
= 6895 },
149 [MPR0005PG
] = { .pmin
= 0, .pmax
= 34474 },
150 [MPR0015PG
] = { .pmin
= 0, .pmax
= 103421 },
151 [MPR0030PG
] = { .pmin
= 0, .pmax
= 206843 },
152 [MPR0300YG
] = { .pmin
= 0, .pmax
= 39997 }
155 static const struct iio_chan_spec mpr_channels
[] = {
157 .type
= IIO_PRESSURE
,
158 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
159 BIT(IIO_CHAN_INFO_SCALE
) |
160 BIT(IIO_CHAN_INFO_OFFSET
),
166 .endianness
= IIO_CPU
,
169 IIO_CHAN_SOFT_TIMESTAMP(1),
172 static void mpr_reset(struct mpr_data
*data
)
174 if (data
->gpiod_reset
) {
175 gpiod_set_value(data
->gpiod_reset
, 0);
177 gpiod_set_value(data
->gpiod_reset
, 1);
182 * mpr_read_pressure() - Read pressure value from sensor
183 * @data: Pointer to private data struct.
184 * @press: Output value read from sensor.
186 * Reading from the sensor by sending and receiving telegrams.
188 * If there is an end of conversion (EOC) interrupt registered the function
189 * waits for a maximum of one second for the interrupt.
191 * Context: The function can sleep and data->lock should be held when calling it
193 * * 0 - OK, the pressure value could be read
194 * * -ETIMEDOUT - Timeout while waiting for the EOC interrupt or busy flag is
195 * still set after nloops attempts of reading
197 static int mpr_read_pressure(struct mpr_data
*data
, s32
*press
)
199 struct device
*dev
= data
->dev
;
203 reinit_completion(&data
->completion
);
205 ret
= data
->ops
->write(data
, MPR_CMD_SYNC
, MPR_PKT_SYNC_LEN
);
207 dev_err(dev
, "error while writing ret: %d\n", ret
);
212 ret
= wait_for_completion_timeout(&data
->completion
, HZ
);
214 dev_err(dev
, "timeout while waiting for eoc irq\n");
218 /* wait until status indicates data is ready */
219 for (i
= 0; i
< nloops
; i
++) {
221 * datasheet only says to wait at least 5 ms for the
222 * data but leave the maximum response time open
223 * --> let's try it nloops (10) times which seems to be
226 usleep_range(5000, 10000);
227 ret
= data
->ops
->read(data
, MPR_CMD_NOP
, 1);
230 "error while reading, status: %d\n",
234 if (!(data
->buffer
[0] & MPR_ST_ERR_FLAG
))
238 dev_err(dev
, "timeout while reading\n");
243 ret
= data
->ops
->read(data
, MPR_CMD_NOP
, MPR_PKT_NOP_LEN
);
247 if (data
->buffer
[0] & MPR_ST_ERR_FLAG
) {
249 "unexpected status byte %02x\n", data
->buffer
[0]);
253 *press
= get_unaligned_be24(&data
->buffer
[1]);
255 dev_dbg(dev
, "received: %*ph cnt: %d\n", ret
, data
->buffer
, *press
);
260 static irqreturn_t
mpr_eoc_handler(int irq
, void *p
)
262 struct mpr_data
*data
= p
;
264 complete(&data
->completion
);
269 static irqreturn_t
mpr_trigger_handler(int irq
, void *p
)
272 struct iio_poll_func
*pf
= p
;
273 struct iio_dev
*indio_dev
= pf
->indio_dev
;
274 struct mpr_data
*data
= iio_priv(indio_dev
);
276 mutex_lock(&data
->lock
);
277 ret
= mpr_read_pressure(data
, &data
->chan
.pres
);
281 iio_push_to_buffers_with_timestamp(indio_dev
, &data
->chan
,
282 iio_get_time_ns(indio_dev
));
285 mutex_unlock(&data
->lock
);
286 iio_trigger_notify_done(indio_dev
->trig
);
291 static int mpr_read_raw(struct iio_dev
*indio_dev
,
292 struct iio_chan_spec
const *chan
, int *val
, int *val2
, long mask
)
296 struct mpr_data
*data
= iio_priv(indio_dev
);
298 if (chan
->type
!= IIO_PRESSURE
)
302 case IIO_CHAN_INFO_RAW
:
303 mutex_lock(&data
->lock
);
304 ret
= mpr_read_pressure(data
, &pressure
);
305 mutex_unlock(&data
->lock
);
310 case IIO_CHAN_INFO_SCALE
:
312 *val2
= data
->scale2
;
313 return IIO_VAL_INT_PLUS_NANO
;
314 case IIO_CHAN_INFO_OFFSET
:
316 *val2
= data
->offset2
;
317 return IIO_VAL_INT_PLUS_NANO
;
323 static const struct iio_info mpr_info
= {
324 .read_raw
= &mpr_read_raw
,
327 int mpr_common_probe(struct device
*dev
, const struct mpr_ops
*ops
, int irq
)
330 struct mpr_data
*data
;
331 struct iio_dev
*indio_dev
;
336 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*data
));
340 data
= iio_priv(indio_dev
);
345 mutex_init(&data
->lock
);
346 init_completion(&data
->completion
);
348 indio_dev
->name
= "mprls0025pa";
349 indio_dev
->info
= &mpr_info
;
350 indio_dev
->channels
= mpr_channels
;
351 indio_dev
->num_channels
= ARRAY_SIZE(mpr_channels
);
352 indio_dev
->modes
= INDIO_DIRECT_MODE
;
354 ret
= devm_regulator_get_enable(dev
, "vdd");
356 return dev_err_probe(dev
, ret
,
357 "can't get and enable vdd supply\n");
359 ret
= data
->ops
->init(data
->dev
);
363 ret
= device_property_read_u32(dev
,
364 "honeywell,transfer-function", &func
);
366 return dev_err_probe(dev
, ret
,
367 "honeywell,transfer-function could not be read\n");
368 data
->function
= func
- 1;
369 if (data
->function
> MPR_FUNCTION_C
)
370 return dev_err_probe(dev
, -EINVAL
,
371 "honeywell,transfer-function %d invalid\n",
374 ret
= device_property_read_string(dev
, "honeywell,pressure-triplet",
377 ret
= device_property_read_u32(dev
, "honeywell,pmin-pascal",
380 return dev_err_probe(dev
, ret
,
381 "honeywell,pmin-pascal could not be read\n");
383 ret
= device_property_read_u32(dev
, "honeywell,pmax-pascal",
386 return dev_err_probe(dev
, ret
,
387 "honeywell,pmax-pascal could not be read\n");
389 ret
= device_property_match_property_string(dev
,
390 "honeywell,pressure-triplet",
391 mpr_triplet_variants
,
394 return dev_err_probe(dev
, -EINVAL
,
395 "honeywell,pressure-triplet is invalid\n");
397 data
->pmin
= mpr_range_config
[ret
].pmin
;
398 data
->pmax
= mpr_range_config
[ret
].pmax
;
401 if (data
->pmin
>= data
->pmax
)
402 return dev_err_probe(dev
, -EINVAL
,
403 "pressure limits are invalid\n");
405 data
->outmin
= mpr_func_spec
[data
->function
].output_min
;
406 data
->outmax
= mpr_func_spec
[data
->function
].output_max
;
408 /* use 64 bit calculation for preserving a reasonable precision */
409 scale
= div_s64(((s64
)(data
->pmax
- data
->pmin
)) * NANO
,
410 data
->outmax
- data
->outmin
);
411 data
->scale
= div_s64_rem(scale
, NANO
, &data
->scale2
);
413 * multiply with NANO before dividing by scale and later divide by NANO
416 offset
= ((-1LL) * (s64
)data
->outmin
) * NANO
-
417 div_s64(div_s64((s64
)data
->pmin
* NANO
, scale
), NANO
);
418 data
->offset
= div_s64_rem(offset
, NANO
, &data
->offset2
);
421 ret
= devm_request_irq(dev
, data
->irq
, mpr_eoc_handler
,
426 return dev_err_probe(dev
, ret
,
427 "request irq %d failed\n", data
->irq
);
430 data
->gpiod_reset
= devm_gpiod_get_optional(dev
, "reset",
432 if (IS_ERR(data
->gpiod_reset
))
433 return dev_err_probe(dev
, PTR_ERR(data
->gpiod_reset
),
434 "request reset-gpio failed\n");
438 ret
= devm_iio_triggered_buffer_setup(dev
, indio_dev
, NULL
,
439 mpr_trigger_handler
, NULL
);
441 return dev_err_probe(dev
, ret
,
442 "iio triggered buffer setup failed\n");
444 ret
= devm_iio_device_register(dev
, indio_dev
);
446 return dev_err_probe(dev
, ret
,
447 "unable to register iio device\n");
451 EXPORT_SYMBOL_NS(mpr_common_probe
, IIO_HONEYWELL_MPRLS0025PA
);
453 MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
454 MODULE_DESCRIPTION("Honeywell MPR pressure sensor core driver");
455 MODULE_LICENSE("GPL");