1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * Honeywell TruStability HSC Series pressure/temperature sensor
4 *
5 * Copyright (c) 2023 Petre Rodan <petre.rodan@subdimension.ro>
6 *
7 * 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
8 */
9
10#include <linux/array_size.h>
11#include <linux/bitfield.h>
12#include <linux/bits.h>
13#include <linux/cleanup.h>
14#include <linux/init.h>
15#include <linux/math64.h>
16#include <linux/mod_devicetable.h>
17#include <linux/module.h>
18#include <linux/printk.h>
19#include <linux/property.h>
20#include <linux/regulator/consumer.h>
21#include <linux/string.h>
22#include <linux/types.h>
23#include <linux/units.h>
24
25#include <linux/iio/buffer.h>
26#include <linux/iio/iio.h>
27#include <linux/iio/sysfs.h>
28#include <linux/iio/trigger_consumer.h>
29#include <linux/iio/triggered_buffer.h>
30
31#include <asm/unaligned.h>
32
33#include "hsc030pa.h"
34
35/*
36 * HSC_PRESSURE_TRIPLET_LEN - length for the string that defines the
37 * pressure range, measurement unit and type as per the part nomenclature.
38 * Consult honeywell,pressure-triplet in the bindings file for details.
39 */
40#define HSC_PRESSURE_TRIPLET_LEN 6
41#define HSC_STATUS_MASK GENMASK(7, 6)
42#define HSC_TEMPERATURE_MASK GENMASK(15, 5)
43#define HSC_PRESSURE_MASK GENMASK(29, 16)
44
45struct hsc_func_spec {
46 u32 output_min;
47 u32 output_max;
48};
49
50/*
51 * function A: 10% - 90% of 2^14
52 * function B: 5% - 95% of 2^14
53 * function C: 5% - 85% of 2^14
54 * function F: 4% - 94% of 2^14
55 */
56static const struct hsc_func_spec hsc_func_spec[] = {
57 [HSC_FUNCTION_A] = { .output_min = 1638, .output_max = 14746 },
58 [HSC_FUNCTION_B] = { .output_min = 819, .output_max = 15565 },
59 [HSC_FUNCTION_C] = { .output_min = 819, .output_max = 13926 },
60 [HSC_FUNCTION_F] = { .output_min = 655, .output_max = 15401 },
61};
62
63enum hsc_variants {
64 HSC001BA = 0x00, HSC1_6BA = 0x01, HSC2_5BA = 0x02, HSC004BA = 0x03,
65 HSC006BA = 0x04, HSC010BA = 0x05, HSC1_6MD = 0x06, HSC2_5MD = 0x07,
66 HSC004MD = 0x08, HSC006MD = 0x09, HSC010MD = 0x0a, HSC016MD = 0x0b,
67 HSC025MD = 0x0c, HSC040MD = 0x0d, HSC060MD = 0x0e, HSC100MD = 0x0f,
68 HSC160MD = 0x10, HSC250MD = 0x11, HSC400MD = 0x12, HSC600MD = 0x13,
69 HSC001BD = 0x14, HSC1_6BD = 0x15, HSC2_5BD = 0x16, HSC004BD = 0x17,
70 HSC2_5MG = 0x18, HSC004MG = 0x19, HSC006MG = 0x1a, HSC010MG = 0x1b,
71 HSC016MG = 0x1c, HSC025MG = 0x1d, HSC040MG = 0x1e, HSC060MG = 0x1f,
72 HSC100MG = 0x20, HSC160MG = 0x21, HSC250MG = 0x22, HSC400MG = 0x23,
73 HSC600MG = 0x24, HSC001BG = 0x25, HSC1_6BG = 0x26, HSC2_5BG = 0x27,
74 HSC004BG = 0x28, HSC006BG = 0x29, HSC010BG = 0x2a, HSC100KA = 0x2b,
75 HSC160KA = 0x2c, HSC250KA = 0x2d, HSC400KA = 0x2e, HSC600KA = 0x2f,
76 HSC001GA = 0x30, HSC160LD = 0x31, HSC250LD = 0x32, HSC400LD = 0x33,
77 HSC600LD = 0x34, HSC001KD = 0x35, HSC1_6KD = 0x36, HSC2_5KD = 0x37,
78 HSC004KD = 0x38, HSC006KD = 0x39, HSC010KD = 0x3a, HSC016KD = 0x3b,
79 HSC025KD = 0x3c, HSC040KD = 0x3d, HSC060KD = 0x3e, HSC100KD = 0x3f,
80 HSC160KD = 0x40, HSC250KD = 0x41, HSC400KD = 0x42, HSC250LG = 0x43,
81 HSC400LG = 0x44, HSC600LG = 0x45, HSC001KG = 0x46, HSC1_6KG = 0x47,
82 HSC2_5KG = 0x48, HSC004KG = 0x49, HSC006KG = 0x4a, HSC010KG = 0x4b,
83 HSC016KG = 0x4c, HSC025KG = 0x4d, HSC040KG = 0x4e, HSC060KG = 0x4f,
84 HSC100KG = 0x50, HSC160KG = 0x51, HSC250KG = 0x52, HSC400KG = 0x53,
85 HSC600KG = 0x54, HSC001GG = 0x55, HSC015PA = 0x56, HSC030PA = 0x57,
86 HSC060PA = 0x58, HSC100PA = 0x59, HSC150PA = 0x5a, HSC0_5ND = 0x5b,
87 HSC001ND = 0x5c, HSC002ND = 0x5d, HSC004ND = 0x5e, HSC005ND = 0x5f,
88 HSC010ND = 0x60, HSC020ND = 0x61, HSC030ND = 0x62, HSC001PD = 0x63,
89 HSC005PD = 0x64, HSC015PD = 0x65, HSC030PD = 0x66, HSC060PD = 0x67,
90 HSC001NG = 0x68, HSC002NG = 0x69, HSC004NG = 0x6a, HSC005NG = 0x6b,
91 HSC010NG = 0x6c, HSC020NG = 0x6d, HSC030NG = 0x6e, HSC001PG = 0x6f,
92 HSC005PG = 0x70, HSC015PG = 0x71, HSC030PG = 0x72, HSC060PG = 0x73,
93 HSC100PG = 0x74, HSC150PG = 0x75, HSC_VARIANTS_MAX
94};
95
96static const char * const hsc_triplet_variants[HSC_VARIANTS_MAX] = {
97 [HSC001BA] = "001BA", [HSC1_6BA] = "1.6BA", [HSC2_5BA] = "2.5BA",
98 [HSC004BA] = "004BA", [HSC006BA] = "006BA", [HSC010BA] = "010BA",
99 [HSC1_6MD] = "1.6MD", [HSC2_5MD] = "2.5MD", [HSC004MD] = "004MD",
100 [HSC006MD] = "006MD", [HSC010MD] = "010MD", [HSC016MD] = "016MD",
101 [HSC025MD] = "025MD", [HSC040MD] = "040MD", [HSC060MD] = "060MD",
102 [HSC100MD] = "100MD", [HSC160MD] = "160MD", [HSC250MD] = "250MD",
103 [HSC400MD] = "400MD", [HSC600MD] = "600MD", [HSC001BD] = "001BD",
104 [HSC1_6BD] = "1.6BD", [HSC2_5BD] = "2.5BD", [HSC004BD] = "004BD",
105 [HSC2_5MG] = "2.5MG", [HSC004MG] = "004MG", [HSC006MG] = "006MG",
106 [HSC010MG] = "010MG", [HSC016MG] = "016MG", [HSC025MG] = "025MG",
107 [HSC040MG] = "040MG", [HSC060MG] = "060MG", [HSC100MG] = "100MG",
108 [HSC160MG] = "160MG", [HSC250MG] = "250MG", [HSC400MG] = "400MG",
109 [HSC600MG] = "600MG", [HSC001BG] = "001BG", [HSC1_6BG] = "1.6BG",
110 [HSC2_5BG] = "2.5BG", [HSC004BG] = "004BG", [HSC006BG] = "006BG",
111 [HSC010BG] = "010BG", [HSC100KA] = "100KA", [HSC160KA] = "160KA",
112 [HSC250KA] = "250KA", [HSC400KA] = "400KA", [HSC600KA] = "600KA",
113 [HSC001GA] = "001GA", [HSC160LD] = "160LD", [HSC250LD] = "250LD",
114 [HSC400LD] = "400LD", [HSC600LD] = "600LD", [HSC001KD] = "001KD",
115 [HSC1_6KD] = "1.6KD", [HSC2_5KD] = "2.5KD", [HSC004KD] = "004KD",
116 [HSC006KD] = "006KD", [HSC010KD] = "010KD", [HSC016KD] = "016KD",
117 [HSC025KD] = "025KD", [HSC040KD] = "040KD", [HSC060KD] = "060KD",
118 [HSC100KD] = "100KD", [HSC160KD] = "160KD", [HSC250KD] = "250KD",
119 [HSC400KD] = "400KD", [HSC250LG] = "250LG", [HSC400LG] = "400LG",
120 [HSC600LG] = "600LG", [HSC001KG] = "001KG", [HSC1_6KG] = "1.6KG",
121 [HSC2_5KG] = "2.5KG", [HSC004KG] = "004KG", [HSC006KG] = "006KG",
122 [HSC010KG] = "010KG", [HSC016KG] = "016KG", [HSC025KG] = "025KG",
123 [HSC040KG] = "040KG", [HSC060KG] = "060KG", [HSC100KG] = "100KG",
124 [HSC160KG] = "160KG", [HSC250KG] = "250KG", [HSC400KG] = "400KG",
125 [HSC600KG] = "600KG", [HSC001GG] = "001GG", [HSC015PA] = "015PA",
126 [HSC030PA] = "030PA", [HSC060PA] = "060PA", [HSC100PA] = "100PA",
127 [HSC150PA] = "150PA", [HSC0_5ND] = "0.5ND", [HSC001ND] = "001ND",
128 [HSC002ND] = "002ND", [HSC004ND] = "004ND", [HSC005ND] = "005ND",
129 [HSC010ND] = "010ND", [HSC020ND] = "020ND", [HSC030ND] = "030ND",
130 [HSC001PD] = "001PD", [HSC005PD] = "005PD", [HSC015PD] = "015PD",
131 [HSC030PD] = "030PD", [HSC060PD] = "060PD", [HSC001NG] = "001NG",
132 [HSC002NG] = "002NG", [HSC004NG] = "004NG", [HSC005NG] = "005NG",
133 [HSC010NG] = "010NG", [HSC020NG] = "020NG", [HSC030NG] = "030NG",
134 [HSC001PG] = "001PG", [HSC005PG] = "005PG", [HSC015PG] = "015PG",
135 [HSC030PG] = "030PG", [HSC060PG] = "060PG", [HSC100PG] = "100PG",
136 [HSC150PG] = "150PG",
137};
138
139/**
140 * struct hsc_range_config - list of pressure ranges based on nomenclature
141 * @pmin: lowest pressure that can be measured
142 * @pmax: highest pressure that can be measured
143 */
144struct hsc_range_config {
145 const s32 pmin;
146 const s32 pmax;
147};
148
149/* All min max limits have been converted to pascals */
150static const struct hsc_range_config hsc_range_config[HSC_VARIANTS_MAX] = {
151 [HSC001BA] = { .pmin = 0, .pmax = 100000 },
152 [HSC1_6BA] = { .pmin = 0, .pmax = 160000 },
153 [HSC2_5BA] = { .pmin = 0, .pmax = 250000 },
154 [HSC004BA] = { .pmin = 0, .pmax = 400000 },
155 [HSC006BA] = { .pmin = 0, .pmax = 600000 },
156 [HSC010BA] = { .pmin = 0, .pmax = 1000000 },
157 [HSC1_6MD] = { .pmin = -160, .pmax = 160 },
158 [HSC2_5MD] = { .pmin = -250, .pmax = 250 },
159 [HSC004MD] = { .pmin = -400, .pmax = 400 },
160 [HSC006MD] = { .pmin = -600, .pmax = 600 },
161 [HSC010MD] = { .pmin = -1000, .pmax = 1000 },
162 [HSC016MD] = { .pmin = -1600, .pmax = 1600 },
163 [HSC025MD] = { .pmin = -2500, .pmax = 2500 },
164 [HSC040MD] = { .pmin = -4000, .pmax = 4000 },
165 [HSC060MD] = { .pmin = -6000, .pmax = 6000 },
166 [HSC100MD] = { .pmin = -10000, .pmax = 10000 },
167 [HSC160MD] = { .pmin = -16000, .pmax = 16000 },
168 [HSC250MD] = { .pmin = -25000, .pmax = 25000 },
169 [HSC400MD] = { .pmin = -40000, .pmax = 40000 },
170 [HSC600MD] = { .pmin = -60000, .pmax = 60000 },
171 [HSC001BD] = { .pmin = -100000, .pmax = 100000 },
172 [HSC1_6BD] = { .pmin = -160000, .pmax = 160000 },
173 [HSC2_5BD] = { .pmin = -250000, .pmax = 250000 },
174 [HSC004BD] = { .pmin = -400000, .pmax = 400000 },
175 [HSC2_5MG] = { .pmin = 0, .pmax = 250 },
176 [HSC004MG] = { .pmin = 0, .pmax = 400 },
177 [HSC006MG] = { .pmin = 0, .pmax = 600 },
178 [HSC010MG] = { .pmin = 0, .pmax = 1000 },
179 [HSC016MG] = { .pmin = 0, .pmax = 1600 },
180 [HSC025MG] = { .pmin = 0, .pmax = 2500 },
181 [HSC040MG] = { .pmin = 0, .pmax = 4000 },
182 [HSC060MG] = { .pmin = 0, .pmax = 6000 },
183 [HSC100MG] = { .pmin = 0, .pmax = 10000 },
184 [HSC160MG] = { .pmin = 0, .pmax = 16000 },
185 [HSC250MG] = { .pmin = 0, .pmax = 25000 },
186 [HSC400MG] = { .pmin = 0, .pmax = 40000 },
187 [HSC600MG] = { .pmin = 0, .pmax = 60000 },
188 [HSC001BG] = { .pmin = 0, .pmax = 100000 },
189 [HSC1_6BG] = { .pmin = 0, .pmax = 160000 },
190 [HSC2_5BG] = { .pmin = 0, .pmax = 250000 },
191 [HSC004BG] = { .pmin = 0, .pmax = 400000 },
192 [HSC006BG] = { .pmin = 0, .pmax = 600000 },
193 [HSC010BG] = { .pmin = 0, .pmax = 1000000 },
194 [HSC100KA] = { .pmin = 0, .pmax = 100000 },
195 [HSC160KA] = { .pmin = 0, .pmax = 160000 },
196 [HSC250KA] = { .pmin = 0, .pmax = 250000 },
197 [HSC400KA] = { .pmin = 0, .pmax = 400000 },
198 [HSC600KA] = { .pmin = 0, .pmax = 600000 },
199 [HSC001GA] = { .pmin = 0, .pmax = 1000000 },
200 [HSC160LD] = { .pmin = -160, .pmax = 160 },
201 [HSC250LD] = { .pmin = -250, .pmax = 250 },
202 [HSC400LD] = { .pmin = -400, .pmax = 400 },
203 [HSC600LD] = { .pmin = -600, .pmax = 600 },
204 [HSC001KD] = { .pmin = -1000, .pmax = 1000 },
205 [HSC1_6KD] = { .pmin = -1600, .pmax = 1600 },
206 [HSC2_5KD] = { .pmin = -2500, .pmax = 2500 },
207 [HSC004KD] = { .pmin = -4000, .pmax = 4000 },
208 [HSC006KD] = { .pmin = -6000, .pmax = 6000 },
209 [HSC010KD] = { .pmin = -10000, .pmax = 10000 },
210 [HSC016KD] = { .pmin = -16000, .pmax = 16000 },
211 [HSC025KD] = { .pmin = -25000, .pmax = 25000 },
212 [HSC040KD] = { .pmin = -40000, .pmax = 40000 },
213 [HSC060KD] = { .pmin = -60000, .pmax = 60000 },
214 [HSC100KD] = { .pmin = -100000, .pmax = 100000 },
215 [HSC160KD] = { .pmin = -160000, .pmax = 160000 },
216 [HSC250KD] = { .pmin = -250000, .pmax = 250000 },
217 [HSC400KD] = { .pmin = -400000, .pmax = 400000 },
218 [HSC250LG] = { .pmin = 0, .pmax = 250 },
219 [HSC400LG] = { .pmin = 0, .pmax = 400 },
220 [HSC600LG] = { .pmin = 0, .pmax = 600 },
221 [HSC001KG] = { .pmin = 0, .pmax = 1000 },
222 [HSC1_6KG] = { .pmin = 0, .pmax = 1600 },
223 [HSC2_5KG] = { .pmin = 0, .pmax = 2500 },
224 [HSC004KG] = { .pmin = 0, .pmax = 4000 },
225 [HSC006KG] = { .pmin = 0, .pmax = 6000 },
226 [HSC010KG] = { .pmin = 0, .pmax = 10000 },
227 [HSC016KG] = { .pmin = 0, .pmax = 16000 },
228 [HSC025KG] = { .pmin = 0, .pmax = 25000 },
229 [HSC040KG] = { .pmin = 0, .pmax = 40000 },
230 [HSC060KG] = { .pmin = 0, .pmax = 60000 },
231 [HSC100KG] = { .pmin = 0, .pmax = 100000 },
232 [HSC160KG] = { .pmin = 0, .pmax = 160000 },
233 [HSC250KG] = { .pmin = 0, .pmax = 250000 },
234 [HSC400KG] = { .pmin = 0, .pmax = 400000 },
235 [HSC600KG] = { .pmin = 0, .pmax = 600000 },
236 [HSC001GG] = { .pmin = 0, .pmax = 1000000 },
237 [HSC015PA] = { .pmin = 0, .pmax = 103421 },
238 [HSC030PA] = { .pmin = 0, .pmax = 206843 },
239 [HSC060PA] = { .pmin = 0, .pmax = 413685 },
240 [HSC100PA] = { .pmin = 0, .pmax = 689476 },
241 [HSC150PA] = { .pmin = 0, .pmax = 1034214 },
242 [HSC0_5ND] = { .pmin = -125, .pmax = 125 },
243 [HSC001ND] = { .pmin = -249, .pmax = 249 },
244 [HSC002ND] = { .pmin = -498, .pmax = 498 },
245 [HSC004ND] = { .pmin = -996, .pmax = 996 },
246 [HSC005ND] = { .pmin = -1245, .pmax = 1245 },
247 [HSC010ND] = { .pmin = -2491, .pmax = 2491 },
248 [HSC020ND] = { .pmin = -4982, .pmax = 4982 },
249 [HSC030ND] = { .pmin = -7473, .pmax = 7473 },
250 [HSC001PD] = { .pmin = -6895, .pmax = 6895 },
251 [HSC005PD] = { .pmin = -34474, .pmax = 34474 },
252 [HSC015PD] = { .pmin = -103421, .pmax = 103421 },
253 [HSC030PD] = { .pmin = -206843, .pmax = 206843 },
254 [HSC060PD] = { .pmin = -413685, .pmax = 413685 },
255 [HSC001NG] = { .pmin = 0, .pmax = 249 },
256 [HSC002NG] = { .pmin = 0, .pmax = 498 },
257 [HSC004NG] = { .pmin = 0, .pmax = 996 },
258 [HSC005NG] = { .pmin = 0, .pmax = 1245 },
259 [HSC010NG] = { .pmin = 0, .pmax = 2491 },
260 [HSC020NG] = { .pmin = 0, .pmax = 4982 },
261 [HSC030NG] = { .pmin = 0, .pmax = 7473 },
262 [HSC001PG] = { .pmin = 0, .pmax = 6895 },
263 [HSC005PG] = { .pmin = 0, .pmax = 34474 },
264 [HSC015PG] = { .pmin = 0, .pmax = 103421 },
265 [HSC030PG] = { .pmin = 0, .pmax = 206843 },
266 [HSC060PG] = { .pmin = 0, .pmax = 413685 },
267 [HSC100PG] = { .pmin = 0, .pmax = 689476 },
268 [HSC150PG] = { .pmin = 0, .pmax = 1034214 },
269};
270
271/**
272 * hsc_measurement_is_valid() - validate last conversion via status bits
273 * @data: structure containing instantiated sensor data
274 * Return: true only if both status bits are zero
275 *
276 * the two MSB from the first transfered byte contain a status code
277 * 00 - normal operation, valid data
278 * 01 - device in factory programming mode
279 * 10 - stale data
280 * 11 - diagnostic condition
281 */
282static bool hsc_measurement_is_valid(struct hsc_data *data)
283{
284 return !(data->buffer[0] & HSC_STATUS_MASK);
285}
286
287static int hsc_get_measurement(struct hsc_data *data)
288{
289 const struct hsc_chip_data *chip = data->chip;
290 int ret;
291
292 ret = data->recv_cb(data);
293 if (ret < 0)
294 return ret;
295
296 data->is_valid = chip->valid(data);
297 if (!data->is_valid)
298 return -EAGAIN;
299
300 return 0;
301}
302
303static irqreturn_t hsc_trigger_handler(int irq, void *private)
304{
305 struct iio_poll_func *pf = private;
306 struct iio_dev *indio_dev = pf->indio_dev;
307 struct hsc_data *data = iio_priv(indio_dev);
308 int ret;
309
310 ret = hsc_get_measurement(data);
311 if (ret)
312 goto error;
313
314 memcpy(&data->scan.chan[0], &data->buffer[0], 2);
315 memcpy(&data->scan.chan[1], &data->buffer[2], 2);
316
317 iio_push_to_buffers_with_timestamp(indio_dev, data: &data->scan,
318 timestamp: iio_get_time_ns(indio_dev));
319
320error:
321 iio_trigger_notify_done(trig: indio_dev->trig);
322
323 return IRQ_HANDLED;
324}
325
326/*
327 * IIO ABI expects
328 * value = (conv + offset) * scale
329 *
330 * datasheet provides the following formula for determining the temperature
331 * temp[C] = conv * a + b
332 * where a = 200/2047; b = -50
333 *
334 * temp[C] = (conv + (b/a)) * a * (1000)
335 * =>
336 * scale = a * 1000 = .097703957 * 1000 = 97.703957
337 * offset = b/a = -50 / .097703957 = -50000000 / 97704
338 *
339 * based on the datasheet
340 * pressure = (conv - Omin) * Q + Pmin =
341 * ((conv - Omin) + Pmin/Q) * Q
342 * =>
343 * scale = Q = (Pmax - Pmin) / (Omax - Omin)
344 * offset = Pmin/Q - Omin = Pmin * (Omax - Omin) / (Pmax - Pmin) - Omin
345 */
346static int hsc_read_raw(struct iio_dev *indio_dev,
347 struct iio_chan_spec const *channel, int *val,
348 int *val2, long mask)
349{
350 struct hsc_data *data = iio_priv(indio_dev);
351 int ret;
352 u32 recvd;
353
354 switch (mask) {
355 case IIO_CHAN_INFO_RAW:
356 ret = hsc_get_measurement(data);
357 if (ret)
358 return ret;
359
360 recvd = get_unaligned_be32(p: data->buffer);
361 switch (channel->type) {
362 case IIO_PRESSURE:
363 *val = FIELD_GET(HSC_PRESSURE_MASK, recvd);
364 return IIO_VAL_INT;
365 case IIO_TEMP:
366 *val = FIELD_GET(HSC_TEMPERATURE_MASK, recvd);
367 return IIO_VAL_INT;
368 default:
369 return -EINVAL;
370 }
371
372 case IIO_CHAN_INFO_SCALE:
373 switch (channel->type) {
374 case IIO_TEMP:
375 *val = 97;
376 *val2 = 703957;
377 return IIO_VAL_INT_PLUS_MICRO;
378 case IIO_PRESSURE:
379 *val = data->p_scale;
380 *val2 = data->p_scale_dec;
381 return IIO_VAL_INT_PLUS_NANO;
382 default:
383 return -EINVAL;
384 }
385
386 case IIO_CHAN_INFO_OFFSET:
387 switch (channel->type) {
388 case IIO_TEMP:
389 *val = -50000000;
390 *val2 = 97704;
391 return IIO_VAL_FRACTIONAL;
392 case IIO_PRESSURE:
393 *val = data->p_offset;
394 *val2 = data->p_offset_dec;
395 return IIO_VAL_INT_PLUS_MICRO;
396 default:
397 return -EINVAL;
398 }
399
400 default:
401 return -EINVAL;
402 }
403}
404
405static const struct iio_chan_spec hsc_channels[] = {
406 {
407 .type = IIO_PRESSURE,
408 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
409 BIT(IIO_CHAN_INFO_SCALE) |
410 BIT(IIO_CHAN_INFO_OFFSET),
411 .scan_index = 0,
412 .scan_type = {
413 .sign = 'u',
414 .realbits = 14,
415 .storagebits = 16,
416 .endianness = IIO_BE,
417 },
418 },
419 {
420 .type = IIO_TEMP,
421 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
422 BIT(IIO_CHAN_INFO_SCALE) |
423 BIT(IIO_CHAN_INFO_OFFSET),
424 .scan_index = 1,
425 .scan_type = {
426 .sign = 'u',
427 .realbits = 11,
428 .storagebits = 16,
429 .shift = 5,
430 .endianness = IIO_BE,
431 },
432 },
433 IIO_CHAN_SOFT_TIMESTAMP(2),
434};
435
436static const struct iio_info hsc_info = {
437 .read_raw = hsc_read_raw,
438};
439
440static const struct hsc_chip_data hsc_chip = {
441 .valid = hsc_measurement_is_valid,
442 .channels = hsc_channels,
443 .num_channels = ARRAY_SIZE(hsc_channels),
444};
445
446int hsc_common_probe(struct device *dev, hsc_recv_fn recv)
447{
448 struct hsc_data *hsc;
449 struct iio_dev *indio_dev;
450 const char *triplet;
451 s64 tmp;
452 int ret;
453
454 indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*hsc));
455 if (!indio_dev)
456 return -ENOMEM;
457
458 hsc = iio_priv(indio_dev);
459
460 hsc->chip = &hsc_chip;
461 hsc->recv_cb = recv;
462 hsc->dev = dev;
463
464 ret = device_property_read_u32(dev, propname: "honeywell,transfer-function",
465 val: &hsc->function);
466 if (ret)
467 return dev_err_probe(dev, err: ret,
468 fmt: "honeywell,transfer-function could not be read\n");
469 if (hsc->function > HSC_FUNCTION_F)
470 return dev_err_probe(dev, err: -EINVAL,
471 fmt: "honeywell,transfer-function %d invalid\n",
472 hsc->function);
473
474 ret = device_property_read_string(dev, propname: "honeywell,pressure-triplet",
475 val: &triplet);
476 if (ret)
477 return dev_err_probe(dev, err: ret,
478 fmt: "honeywell,pressure-triplet could not be read\n");
479
480 if (str_has_prefix(str: triplet, prefix: "NA")) {
481 ret = device_property_read_u32(dev, propname: "honeywell,pmin-pascal",
482 val: &hsc->pmin);
483 if (ret)
484 return dev_err_probe(dev, err: ret,
485 fmt: "honeywell,pmin-pascal could not be read\n");
486
487 ret = device_property_read_u32(dev, propname: "honeywell,pmax-pascal",
488 val: &hsc->pmax);
489 if (ret)
490 return dev_err_probe(dev, err: ret,
491 fmt: "honeywell,pmax-pascal could not be read\n");
492 } else {
493 ret = device_property_match_property_string(dev,
494 propname: "honeywell,pressure-triplet",
495 array: hsc_triplet_variants,
496 n: HSC_VARIANTS_MAX);
497 if (ret < 0)
498 return dev_err_probe(dev, err: -EINVAL,
499 fmt: "honeywell,pressure-triplet is invalid\n");
500
501 hsc->pmin = hsc_range_config[ret].pmin;
502 hsc->pmax = hsc_range_config[ret].pmax;
503 }
504
505 if (hsc->pmin >= hsc->pmax)
506 return dev_err_probe(dev, err: -EINVAL,
507 fmt: "pressure limits are invalid\n");
508
509 ret = devm_regulator_get_enable(dev, id: "vdd");
510 if (ret)
511 return dev_err_probe(dev, err: ret, fmt: "can't get vdd supply\n");
512
513 hsc->outmin = hsc_func_spec[hsc->function].output_min;
514 hsc->outmax = hsc_func_spec[hsc->function].output_max;
515
516 tmp = div_s64(dividend: ((s64)(hsc->pmax - hsc->pmin)) * MICRO,
517 divisor: hsc->outmax - hsc->outmin);
518 hsc->p_scale = div_s64_rem(dividend: tmp, NANO, remainder: &hsc->p_scale_dec);
519 tmp = div_s64(dividend: ((s64)hsc->pmin * (s64)(hsc->outmax - hsc->outmin)) * MICRO,
520 divisor: hsc->pmax - hsc->pmin);
521 tmp -= (s64)hsc->outmin * MICRO;
522 hsc->p_offset = div_s64_rem(dividend: tmp, MICRO, remainder: &hsc->p_offset_dec);
523
524 indio_dev->name = "hsc030pa";
525 indio_dev->modes = INDIO_DIRECT_MODE;
526 indio_dev->info = &hsc_info;
527 indio_dev->channels = hsc->chip->channels;
528 indio_dev->num_channels = hsc->chip->num_channels;
529
530 ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
531 hsc_trigger_handler, NULL);
532 if (ret)
533 return ret;
534
535 return devm_iio_device_register(dev, indio_dev);
536}
537EXPORT_SYMBOL_NS(hsc_common_probe, IIO_HONEYWELL_HSC030PA);
538
539MODULE_AUTHOR("Petre Rodan <petre.rodan@subdimension.ro>");
540MODULE_DESCRIPTION("Honeywell HSC and SSC pressure sensor core driver");
541MODULE_LICENSE("GPL");
542

source code of linux/drivers/iio/pressure/hsc030pa.c