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