1 // SPDX-License-Identifier: GPL-2.0-only
3 * Honeywell TruStability HSC Series pressure/temperature sensor
5 * Copyright (c) 2023 Petre Rodan <petre.rodan@subdimension.ro>
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
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>
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>
31 #include <linux/unaligned.h>
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.
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)
45 struct hsc_func_spec
{
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
56 static 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 },
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
96 static 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",
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
144 struct hsc_range_config
{
149 /* All min max limits have been converted to pascals */
150 static 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 },
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
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
280 * 11 - diagnostic condition
282 static bool hsc_measurement_is_valid(struct hsc_data
*data
)
284 return !(data
->buffer
[0] & HSC_STATUS_MASK
);
287 static int hsc_get_measurement(struct hsc_data
*data
)
289 const struct hsc_chip_data
*chip
= data
->chip
;
292 ret
= data
->recv_cb(data
);
296 data
->is_valid
= chip
->valid(data
);
303 static irqreturn_t
hsc_trigger_handler(int irq
, void *private)
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
);
310 ret
= hsc_get_measurement(data
);
314 memcpy(&data
->scan
.chan
[0], &data
->buffer
[0], 2);
315 memcpy(&data
->scan
.chan
[1], &data
->buffer
[2], 2);
317 iio_push_to_buffers_with_timestamp(indio_dev
, &data
->scan
,
318 iio_get_time_ns(indio_dev
));
321 iio_trigger_notify_done(indio_dev
->trig
);
328 * value = (conv + offset) * scale
330 * datasheet provides the following formula for determining the temperature
331 * temp[C] = conv * a + b
332 * where a = 200/2047; b = -50
334 * temp[C] = (conv + (b/a)) * a * (1000)
336 * scale = a * 1000 = .097703957 * 1000 = 97.703957
337 * offset = b/a = -50 / .097703957 = -50000000 / 97704
339 * based on the datasheet
340 * pressure = (conv - Omin) * Q + Pmin =
341 * ((conv - Omin) + Pmin/Q) * Q
343 * scale = Q = (Pmax - Pmin) / (Omax - Omin)
344 * offset = Pmin/Q - Omin = Pmin * (Omax - Omin) / (Pmax - Pmin) - Omin
346 static int hsc_read_raw(struct iio_dev
*indio_dev
,
347 struct iio_chan_spec
const *channel
, int *val
,
348 int *val2
, long mask
)
350 struct hsc_data
*data
= iio_priv(indio_dev
);
355 case IIO_CHAN_INFO_RAW
:
356 ret
= hsc_get_measurement(data
);
360 recvd
= get_unaligned_be32(data
->buffer
);
361 switch (channel
->type
) {
363 *val
= FIELD_GET(HSC_PRESSURE_MASK
, recvd
);
366 *val
= FIELD_GET(HSC_TEMPERATURE_MASK
, recvd
);
372 case IIO_CHAN_INFO_SCALE
:
373 switch (channel
->type
) {
377 return IIO_VAL_INT_PLUS_MICRO
;
379 *val
= data
->p_scale
;
380 *val2
= data
->p_scale_dec
;
381 return IIO_VAL_INT_PLUS_NANO
;
386 case IIO_CHAN_INFO_OFFSET
:
387 switch (channel
->type
) {
391 return IIO_VAL_FRACTIONAL
;
393 *val
= data
->p_offset
;
394 *val2
= data
->p_offset_dec
;
395 return IIO_VAL_INT_PLUS_MICRO
;
405 static const struct iio_chan_spec hsc_channels
[] = {
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
),
416 .endianness
= IIO_BE
,
421 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
) |
422 BIT(IIO_CHAN_INFO_SCALE
) |
423 BIT(IIO_CHAN_INFO_OFFSET
),
430 .endianness
= IIO_BE
,
433 IIO_CHAN_SOFT_TIMESTAMP(2),
436 static const struct iio_info hsc_info
= {
437 .read_raw
= hsc_read_raw
,
440 static const struct hsc_chip_data hsc_chip
= {
441 .valid
= hsc_measurement_is_valid
,
442 .channels
= hsc_channels
,
443 .num_channels
= ARRAY_SIZE(hsc_channels
),
446 int hsc_common_probe(struct device
*dev
, hsc_recv_fn recv
)
448 struct hsc_data
*hsc
;
449 struct iio_dev
*indio_dev
;
454 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*hsc
));
458 hsc
= iio_priv(indio_dev
);
460 hsc
->chip
= &hsc_chip
;
464 ret
= device_property_read_u32(dev
, "honeywell,transfer-function",
467 return dev_err_probe(dev
, ret
,
468 "honeywell,transfer-function could not be read\n");
469 if (hsc
->function
> HSC_FUNCTION_F
)
470 return dev_err_probe(dev
, -EINVAL
,
471 "honeywell,transfer-function %d invalid\n",
474 ret
= device_property_read_string(dev
, "honeywell,pressure-triplet",
477 return dev_err_probe(dev
, ret
,
478 "honeywell,pressure-triplet could not be read\n");
480 if (str_has_prefix(triplet
, "NA")) {
481 ret
= device_property_read_u32(dev
, "honeywell,pmin-pascal",
484 return dev_err_probe(dev
, ret
,
485 "honeywell,pmin-pascal could not be read\n");
487 ret
= device_property_read_u32(dev
, "honeywell,pmax-pascal",
490 return dev_err_probe(dev
, ret
,
491 "honeywell,pmax-pascal could not be read\n");
493 ret
= device_property_match_property_string(dev
,
494 "honeywell,pressure-triplet",
495 hsc_triplet_variants
,
498 return dev_err_probe(dev
, -EINVAL
,
499 "honeywell,pressure-triplet is invalid\n");
501 hsc
->pmin
= hsc_range_config
[ret
].pmin
;
502 hsc
->pmax
= hsc_range_config
[ret
].pmax
;
505 if (hsc
->pmin
>= hsc
->pmax
)
506 return dev_err_probe(dev
, -EINVAL
,
507 "pressure limits are invalid\n");
509 ret
= devm_regulator_get_enable(dev
, "vdd");
511 return dev_err_probe(dev
, ret
, "can't get vdd supply\n");
513 hsc
->outmin
= hsc_func_spec
[hsc
->function
].output_min
;
514 hsc
->outmax
= hsc_func_spec
[hsc
->function
].output_max
;
516 tmp
= div_s64(((s64
)(hsc
->pmax
- hsc
->pmin
)) * MICRO
,
517 hsc
->outmax
- hsc
->outmin
);
518 hsc
->p_scale
= div_s64_rem(tmp
, NANO
, &hsc
->p_scale_dec
);
519 tmp
= div_s64(((s64
)hsc
->pmin
* (s64
)(hsc
->outmax
- hsc
->outmin
)) * MICRO
,
520 hsc
->pmax
- hsc
->pmin
);
521 tmp
-= (s64
)hsc
->outmin
* MICRO
;
522 hsc
->p_offset
= div_s64_rem(tmp
, MICRO
, &hsc
->p_offset_dec
);
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
;
530 ret
= devm_iio_triggered_buffer_setup(dev
, indio_dev
, NULL
,
531 hsc_trigger_handler
, NULL
);
535 return devm_iio_device_register(dev
, indio_dev
);
537 EXPORT_SYMBOL_NS(hsc_common_probe
, "IIO_HONEYWELL_HSC030PA");
539 MODULE_AUTHOR("Petre Rodan <petre.rodan@subdimension.ro>");
540 MODULE_DESCRIPTION("Honeywell HSC and SSC pressure sensor core driver");
541 MODULE_LICENSE("GPL");