// SPDX-License-Identifier: GPL-2.0-or-later /* * MPRLS0025PA - Honeywell MicroPressure pressure sensor series driver * * Copyright (c) Andreas Klinger <[email protected]> * * Data sheet: * 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 * */ #include <linux/array_size.h> #include <linux/bitfield.h> #include <linux/bits.h> #include <linux/math64.h> #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/property.h> #include <linux/units.h> #include <linux/gpio/consumer.h> #include <linux/iio/buffer.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> #include <linux/regulator/consumer.h> #include <linux/unaligned.h> #include "mprls0025pa.h" /* bits in status byte */ #define MPR_ST_POWER … #define MPR_ST_BUSY … #define MPR_ST_MEMORY … #define MPR_ST_MATH … #define MPR_ST_ERR_FLAG … /* * support _RAW sysfs interface: * * Calculation formula from the datasheet: * pressure = (press_cnt - outputmin) * scale + pmin * with: * * pressure - measured pressure in Pascal * * press_cnt - raw value read from sensor * * pmin - minimum pressure range value of sensor (data->pmin) * * pmax - maximum pressure range value of sensor (data->pmax) * * outputmin - minimum numerical range raw value delivered by sensor * (mpr_func_spec.output_min) * * outputmax - maximum numerical range raw value delivered by sensor * (mpr_func_spec.output_max) * * scale - (pmax - pmin) / (outputmax - outputmin) * * formula of the userspace: * pressure = (raw + offset) * scale * * Values given to the userspace in sysfs interface: * * raw - press_cnt * * offset - (-1 * outputmin) - pmin / scale * note: With all sensors from the datasheet pmin = 0 * which reduces the offset to (-1 * outputmin) */ /* * transfer function A: 10% to 90% of 2^24 * transfer function B: 2.5% to 22.5% of 2^24 * transfer function C: 20% to 80% of 2^24 */ struct mpr_func_spec { … }; static const struct mpr_func_spec mpr_func_spec[] = …; enum mpr_variants { … }; static const char * const mpr_triplet_variants[MPR_VARIANTS_MAX] = …; /** * struct mpr_range_config - list of pressure ranges based on nomenclature * @pmin: lowest pressure that can be measured * @pmax: highest pressure that can be measured */ struct mpr_range_config { … }; /* All min max limits have been converted to pascals */ static const struct mpr_range_config mpr_range_config[MPR_VARIANTS_MAX] = …; static const struct iio_chan_spec mpr_channels[] = …; static void mpr_reset(struct mpr_data *data) { … } /** * mpr_read_pressure() - Read pressure value from sensor * @data: Pointer to private data struct. * @press: Output value read from sensor. * * Reading from the sensor by sending and receiving telegrams. * * If there is an end of conversion (EOC) interrupt registered the function * waits for a maximum of one second for the interrupt. * * Context: The function can sleep and data->lock should be held when calling it * Return: * * 0 - OK, the pressure value could be read * * -ETIMEDOUT - Timeout while waiting for the EOC interrupt or busy flag is * still set after nloops attempts of reading */ static int mpr_read_pressure(struct mpr_data *data, s32 *press) { … } static irqreturn_t mpr_eoc_handler(int irq, void *p) { … } static irqreturn_t mpr_trigger_handler(int irq, void *p) { … } static int mpr_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) { … } static const struct iio_info mpr_info = …; int mpr_common_probe(struct device *dev, const struct mpr_ops *ops, int irq) { … } EXPORT_SYMBOL_NS(…); MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;