// SPDX-License-Identifier: GPL-2.0-only /* * Honeywell TruStability HSC Series pressure/temperature sensor * * Copyright (c) 2023 Petre Rodan <[email protected]> * * Datasheet: https://prod-edam.honeywell.com/content/dam/honeywell-edam/sps/siot/en-us/products/sensors/pressure-sensors/board-mount-pressure-sensors/trustability-hsc-series/documents/sps-siot-trustability-hsc-series-high-accuracy-board-mount-pressure-sensors-50099148-a-en-ciid-151133.pdf */ #include <linux/array_size.h> #include <linux/bitfield.h> #include <linux/bits.h> #include <linux/cleanup.h> #include <linux/init.h> #include <linux/math64.h> #include <linux/mod_devicetable.h> #include <linux/module.h> #include <linux/printk.h> #include <linux/property.h> #include <linux/regulator/consumer.h> #include <linux/string.h> #include <linux/types.h> #include <linux/units.h> #include <linux/iio/buffer.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/trigger_consumer.h> #include <linux/iio/triggered_buffer.h> #include <linux/unaligned.h> #include "hsc030pa.h" /* * HSC_PRESSURE_TRIPLET_LEN - length for the string that defines the * pressure range, measurement unit and type as per the part nomenclature. * Consult honeywell,pressure-triplet in the bindings file for details. */ #define HSC_PRESSURE_TRIPLET_LEN … #define HSC_STATUS_MASK … #define HSC_TEMPERATURE_MASK … #define HSC_PRESSURE_MASK … struct hsc_func_spec { … }; /* * function A: 10% - 90% of 2^14 * function B: 5% - 95% of 2^14 * function C: 5% - 85% of 2^14 * function F: 4% - 94% of 2^14 */ static const struct hsc_func_spec hsc_func_spec[] = …; enum hsc_variants { … }; static const char * const hsc_triplet_variants[HSC_VARIANTS_MAX] = …; /** * struct hsc_range_config - list of pressure ranges based on nomenclature * @pmin: lowest pressure that can be measured * @pmax: highest pressure that can be measured */ struct hsc_range_config { … }; /* All min max limits have been converted to pascals */ static const struct hsc_range_config hsc_range_config[HSC_VARIANTS_MAX] = …; /** * hsc_measurement_is_valid() - validate last conversion via status bits * @data: structure containing instantiated sensor data * Return: true only if both status bits are zero * * the two MSB from the first transfered byte contain a status code * 00 - normal operation, valid data * 01 - device in factory programming mode * 10 - stale data * 11 - diagnostic condition */ static bool hsc_measurement_is_valid(struct hsc_data *data) { … } static int hsc_get_measurement(struct hsc_data *data) { … } static irqreturn_t hsc_trigger_handler(int irq, void *private) { … } /* * IIO ABI expects * value = (conv + offset) * scale * * datasheet provides the following formula for determining the temperature * temp[C] = conv * a + b * where a = 200/2047; b = -50 * * temp[C] = (conv + (b/a)) * a * (1000) * => * scale = a * 1000 = .097703957 * 1000 = 97.703957 * offset = b/a = -50 / .097703957 = -50000000 / 97704 * * based on the datasheet * pressure = (conv - Omin) * Q + Pmin = * ((conv - Omin) + Pmin/Q) * Q * => * scale = Q = (Pmax - Pmin) / (Omax - Omin) * offset = Pmin/Q - Omin = Pmin * (Omax - Omin) / (Pmax - Pmin) - Omin */ static int hsc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *channel, int *val, int *val2, long mask) { … } static const struct iio_chan_spec hsc_channels[] = …; static const struct iio_info hsc_info = …; static const struct hsc_chip_data hsc_chip = …; int hsc_common_probe(struct device *dev, hsc_recv_fn recv) { … } EXPORT_SYMBOL_NS(…); MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;