xref: /linux/drivers/iio/flow/slf3s.c (revision 67f8bc848ee31831336bd478e57d2f993551902e)
1*d240b0b8SWadim Mueller // SPDX-License-Identifier: GPL-2.0
2*d240b0b8SWadim Mueller /*
3*d240b0b8SWadim Mueller  * Sensirion SLF3S liquid flow sensor driver.
4*d240b0b8SWadim Mueller  *
5*d240b0b8SWadim Mueller  * Supports the SLF3S-0600F, SLF3S-1300F and SLF3S-4000B liquid-flow
6*d240b0b8SWadim Mueller  * sensors over I2C.  Each measurement frame returns a 16-bit signed
7*d240b0b8SWadim Mueller  * flow value, a 16-bit signed temperature value and a status word,
8*d240b0b8SWadim Mueller  * each protected by a CRC-8 byte.
9*d240b0b8SWadim Mueller  *
10*d240b0b8SWadim Mueller  * The active calibration medium (water or isopropyl alcohol) is
11*d240b0b8SWadim Mueller  * runtime-switchable via the in_volumeflow_medium sysfs attribute and
12*d240b0b8SWadim Mueller  * defaults to water.
13*d240b0b8SWadim Mueller  *
14*d240b0b8SWadim Mueller  * Datasheet: https://sensirion.com/products/catalog/SLF3S-0600F/
15*d240b0b8SWadim Mueller  *
16*d240b0b8SWadim Mueller  * Copyright (C) 2026 CMBlu Energy GmbH
17*d240b0b8SWadim Mueller  * Author: Wadim Mueller <wafgo01@gmail.com>
18*d240b0b8SWadim Mueller  */
19*d240b0b8SWadim Mueller 
20*d240b0b8SWadim Mueller #include <linux/array_size.h>
21*d240b0b8SWadim Mueller #include <linux/bitops.h>
22*d240b0b8SWadim Mueller #include <linux/cleanup.h>
23*d240b0b8SWadim Mueller #include <linux/crc8.h>
24*d240b0b8SWadim Mueller #include <linux/delay.h>
25*d240b0b8SWadim Mueller #include <linux/dev_printk.h>
26*d240b0b8SWadim Mueller #include <linux/device.h>
27*d240b0b8SWadim Mueller #include <linux/err.h>
28*d240b0b8SWadim Mueller #include <linux/errno.h>
29*d240b0b8SWadim Mueller #include <linux/i2c.h>
30*d240b0b8SWadim Mueller #include <linux/math.h>
31*d240b0b8SWadim Mueller #include <linux/math64.h>
32*d240b0b8SWadim Mueller #include <linux/module.h>
33*d240b0b8SWadim Mueller #include <linux/mutex.h>
34*d240b0b8SWadim Mueller #include <linux/pm.h>
35*d240b0b8SWadim Mueller #include <linux/regulator/consumer.h>
36*d240b0b8SWadim Mueller #include <linux/types.h>
37*d240b0b8SWadim Mueller #include <linux/unaligned.h>
38*d240b0b8SWadim Mueller #include <linux/units.h>
39*d240b0b8SWadim Mueller 
40*d240b0b8SWadim Mueller #include <linux/iio/iio.h>
41*d240b0b8SWadim Mueller 
42*d240b0b8SWadim Mueller #define SLF3S_CRC8_POLY			0x31
43*d240b0b8SWadim Mueller #define SLF3S_CRC8_INIT			0xff
44*d240b0b8SWadim Mueller 
45*d240b0b8SWadim Mueller #define SLF3S_PRODUCT_ID_LEN		18
46*d240b0b8SWadim Mueller #define SLF3S_PRODUCT_FAMILY_BYTE	1
47*d240b0b8SWadim Mueller #define SLF3S_PRODUCT_SUBTYPE_BYTE	3
48*d240b0b8SWadim Mueller #define SLF3S_PRODUCT_FAMILY_ID		0x03
49*d240b0b8SWadim Mueller 
50*d240b0b8SWadim Mueller /* Datasheet section 2.2: tPU = 25 ms max from power-on to first cmd. */
51*d240b0b8SWadim Mueller #define SLF3S_POWER_UP_DELAY_US		(25 * USEC_PER_MSEC)
52*d240b0b8SWadim Mueller /* Datasheet section 2.2: tw = 60 ms typical until first valid sample. */
53*d240b0b8SWadim Mueller #define SLF3S_MEAS_START_DELAY_US	(60 * USEC_PER_MSEC)
54*d240b0b8SWadim Mueller 
55*d240b0b8SWadim Mueller static const u8 slf3s_cmd_prep_pid[]	= { 0x36, 0x7c };
56*d240b0b8SWadim Mueller static const u8 slf3s_cmd_read_pid[]	= { 0xe1, 0x02 };
57*d240b0b8SWadim Mueller static const u8 slf3s_cmd_start_water[]	= { 0x36, 0x08 };
58*d240b0b8SWadim Mueller static const u8 slf3s_cmd_start_ipa[]	= { 0x36, 0x15 };
59*d240b0b8SWadim Mueller static const u8 slf3s_cmd_stop_meas[]	= { 0x3f, 0xf9 };
60*d240b0b8SWadim Mueller 
61*d240b0b8SWadim Mueller enum slf3s_medium {
62*d240b0b8SWadim Mueller 	SLF3S_MEDIUM_WATER,
63*d240b0b8SWadim Mueller 	SLF3S_MEDIUM_IPA,
64*d240b0b8SWadim Mueller };
65*d240b0b8SWadim Mueller 
66*d240b0b8SWadim Mueller static const char * const slf3s_medium_modes[] = {
67*d240b0b8SWadim Mueller 	[SLF3S_MEDIUM_WATER]	= "water",
68*d240b0b8SWadim Mueller 	[SLF3S_MEDIUM_IPA]	= "ipa",
69*d240b0b8SWadim Mueller };
70*d240b0b8SWadim Mueller 
71*d240b0b8SWadim Mueller enum slf3s_variant_id {
72*d240b0b8SWadim Mueller 	SLF3S_0600F,
73*d240b0b8SWadim Mueller 	SLF3S_1300F,
74*d240b0b8SWadim Mueller 	SLF3S_4000B,
75*d240b0b8SWadim Mueller };
76*d240b0b8SWadim Mueller 
77*d240b0b8SWadim Mueller /**
78*d240b0b8SWadim Mueller  * struct slf3s_variant - per-variant calibration constants
79*d240b0b8SWadim Mueller  * @sub_type:	product-info sub-type byte returned by the sensor
80*d240b0b8SWadim Mueller  * @name:	name reported via @iio_dev.name
81*d240b0b8SWadim Mueller  * @scale:	flow scale in l/s per LSB
82*d240b0b8SWadim Mueller  */
83*d240b0b8SWadim Mueller struct slf3s_variant {
84*d240b0b8SWadim Mueller 	u8 sub_type;
85*d240b0b8SWadim Mueller 	const char *name;
86*d240b0b8SWadim Mueller 	struct s32_fract scale;
87*d240b0b8SWadim Mueller };
88*d240b0b8SWadim Mueller 
89*d240b0b8SWadim Mueller static const struct slf3s_variant slf3s_variants[] = {
90*d240b0b8SWadim Mueller 	[SLF3S_0600F] = {
91*d240b0b8SWadim Mueller 		.sub_type	= 0x03,
92*d240b0b8SWadim Mueller 		.name		= "slf3s-0600f",
93*d240b0b8SWadim Mueller 		.scale		= { .numerator = 1, .denominator = 600 * MICRO },
94*d240b0b8SWadim Mueller 	},
95*d240b0b8SWadim Mueller 	[SLF3S_1300F] = {
96*d240b0b8SWadim Mueller 		.sub_type	= 0x02,
97*d240b0b8SWadim Mueller 		.name		= "slf3s-1300f",
98*d240b0b8SWadim Mueller 		.scale		= { .numerator = 1, .denominator = 30 * MICRO },
99*d240b0b8SWadim Mueller 	},
100*d240b0b8SWadim Mueller 	[SLF3S_4000B] = {
101*d240b0b8SWadim Mueller 		.sub_type	= 0x05,
102*d240b0b8SWadim Mueller 		.name		= "slf3s-4000b",
103*d240b0b8SWadim Mueller 		.scale		= { .numerator = 1, .denominator = 1920 * MILLI },
104*d240b0b8SWadim Mueller 	},
105*d240b0b8SWadim Mueller };
106*d240b0b8SWadim Mueller 
107*d240b0b8SWadim Mueller /**
108*d240b0b8SWadim Mueller  * struct slf3s_data - per-device state
109*d240b0b8SWadim Mueller  * @client:	I2C client this instance is bound to
110*d240b0b8SWadim Mueller  * @vdd:	supply regulator, disabled while suspended
111*d240b0b8SWadim Mueller  * @variant:	pointer into @slf3s_variants for the detected device
112*d240b0b8SWadim Mueller  * @medium:	currently active calibration medium
113*d240b0b8SWadim Mueller  * @lock:	serialises the multi-step command/response exchanges
114*d240b0b8SWadim Mueller  * @crc_table:	pre-computed CRC-8 lookup table for SLF3S_CRC8_POLY
115*d240b0b8SWadim Mueller  */
116*d240b0b8SWadim Mueller struct slf3s_data {
117*d240b0b8SWadim Mueller 	struct i2c_client *client;
118*d240b0b8SWadim Mueller 	struct regulator *vdd;
119*d240b0b8SWadim Mueller 	const struct slf3s_variant *variant;
120*d240b0b8SWadim Mueller 	enum slf3s_medium medium;
121*d240b0b8SWadim Mueller 	struct mutex lock;
122*d240b0b8SWadim Mueller 	u8 crc_table[CRC8_TABLE_SIZE];
123*d240b0b8SWadim Mueller };
124*d240b0b8SWadim Mueller 
125*d240b0b8SWadim Mueller static int slf3s_send_cmd(struct i2c_client *client, const u8 *cmd)
126*d240b0b8SWadim Mueller {
127*d240b0b8SWadim Mueller 	int ret;
128*d240b0b8SWadim Mueller 
129*d240b0b8SWadim Mueller 	ret = i2c_master_send(client, cmd, 2);
130*d240b0b8SWadim Mueller 	if (ret < 0)
131*d240b0b8SWadim Mueller 		return ret;
132*d240b0b8SWadim Mueller 	if (ret != 2)
133*d240b0b8SWadim Mueller 		return -EIO;
134*d240b0b8SWadim Mueller 
135*d240b0b8SWadim Mueller 	return 0;
136*d240b0b8SWadim Mueller }
137*d240b0b8SWadim Mueller 
138*d240b0b8SWadim Mueller /* Start continuous measurement and wait until the first sample is valid. */
139*d240b0b8SWadim Mueller static int slf3s_start_meas(struct slf3s_data *sf, enum slf3s_medium medium)
140*d240b0b8SWadim Mueller {
141*d240b0b8SWadim Mueller 	const u8 *cmd = (medium == SLF3S_MEDIUM_IPA) ? slf3s_cmd_start_ipa
142*d240b0b8SWadim Mueller 						     : slf3s_cmd_start_water;
143*d240b0b8SWadim Mueller 	int ret;
144*d240b0b8SWadim Mueller 
145*d240b0b8SWadim Mueller 	ret = slf3s_send_cmd(sf->client, cmd);
146*d240b0b8SWadim Mueller 	if (ret)
147*d240b0b8SWadim Mueller 		return ret;
148*d240b0b8SWadim Mueller 
149*d240b0b8SWadim Mueller 	fsleep(SLF3S_MEAS_START_DELAY_US);
150*d240b0b8SWadim Mueller 
151*d240b0b8SWadim Mueller 	return 0;
152*d240b0b8SWadim Mueller }
153*d240b0b8SWadim Mueller 
154*d240b0b8SWadim Mueller static bool slf3s_crc_valid(const struct slf3s_data *sf, const u8 *block)
155*d240b0b8SWadim Mueller {
156*d240b0b8SWadim Mueller 	return crc8(sf->crc_table, block, 2, SLF3S_CRC8_INIT) == block[2];
157*d240b0b8SWadim Mueller }
158*d240b0b8SWadim Mueller 
159*d240b0b8SWadim Mueller /*
160*d240b0b8SWadim Mueller  * Read the product-info block and pick the matching variant.  The
161*d240b0b8SWadim Mueller  * sub-type byte returned by the sensor is the source of truth; a
162*d240b0b8SWadim Mueller  * DT-supplied compatible only seeds an initial guess and is overridden
163*d240b0b8SWadim Mueller  * on mismatch (with an informational message so misconfigured device
164*d240b0b8SWadim Mueller  * trees are easy to spot).
165*d240b0b8SWadim Mueller  *
166*d240b0b8SWadim Mueller  * Bus / CRC failures are real errors and fail probe.  An unknown
167*d240b0b8SWadim Mueller  * sub-type byte falls back to the variant named in the device tree /
168*d240b0b8SWadim Mueller  * I2C table, so a drop-in replacement part that lists one of the known
169*d240b0b8SWadim Mueller  * compatibles keeps working on an older kernel that does not know its
170*d240b0b8SWadim Mueller  * sub-type yet.  Without any match data probe fails since no
171*d240b0b8SWadim Mueller  * meaningful scale can be published.
172*d240b0b8SWadim Mueller  */
173*d240b0b8SWadim Mueller static int slf3s_detect_variant(struct slf3s_data *sf)
174*d240b0b8SWadim Mueller {
175*d240b0b8SWadim Mueller 	struct i2c_client *client = sf->client;
176*d240b0b8SWadim Mueller 	u8 buf[SLF3S_PRODUCT_ID_LEN];
177*d240b0b8SWadim Mueller 	int ret;
178*d240b0b8SWadim Mueller 
179*d240b0b8SWadim Mueller 	ret = slf3s_send_cmd(client, slf3s_cmd_prep_pid);
180*d240b0b8SWadim Mueller 	if (ret)
181*d240b0b8SWadim Mueller 		return ret;
182*d240b0b8SWadim Mueller 
183*d240b0b8SWadim Mueller 	ret = slf3s_send_cmd(client, slf3s_cmd_read_pid);
184*d240b0b8SWadim Mueller 	if (ret)
185*d240b0b8SWadim Mueller 		return ret;
186*d240b0b8SWadim Mueller 
187*d240b0b8SWadim Mueller 	ret = i2c_master_recv(client, buf, sizeof(buf));
188*d240b0b8SWadim Mueller 	if (ret < 0)
189*d240b0b8SWadim Mueller 		return ret;
190*d240b0b8SWadim Mueller 	if (ret != sizeof(buf))
191*d240b0b8SWadim Mueller 		return -EIO;
192*d240b0b8SWadim Mueller 
193*d240b0b8SWadim Mueller 	for (unsigned int i = 0; i < SLF3S_PRODUCT_ID_LEN; i += 3) {
194*d240b0b8SWadim Mueller 		if (!slf3s_crc_valid(sf, &buf[i]))
195*d240b0b8SWadim Mueller 			return -EIO;
196*d240b0b8SWadim Mueller 	}
197*d240b0b8SWadim Mueller 
198*d240b0b8SWadim Mueller 	if (buf[SLF3S_PRODUCT_FAMILY_BYTE] != SLF3S_PRODUCT_FAMILY_ID)
199*d240b0b8SWadim Mueller 		dev_info(&client->dev,
200*d240b0b8SWadim Mueller 			 "unexpected family byte 0x%02x (expected 0x%02x)\n",
201*d240b0b8SWadim Mueller 			 buf[SLF3S_PRODUCT_FAMILY_BYTE],
202*d240b0b8SWadim Mueller 			 SLF3S_PRODUCT_FAMILY_ID);
203*d240b0b8SWadim Mueller 
204*d240b0b8SWadim Mueller 	for (unsigned int i = 0; i < ARRAY_SIZE(slf3s_variants); i++) {
205*d240b0b8SWadim Mueller 		if (buf[SLF3S_PRODUCT_SUBTYPE_BYTE] !=
206*d240b0b8SWadim Mueller 		    slf3s_variants[i].sub_type)
207*d240b0b8SWadim Mueller 			continue;
208*d240b0b8SWadim Mueller 
209*d240b0b8SWadim Mueller 		if (sf->variant && sf->variant != &slf3s_variants[i])
210*d240b0b8SWadim Mueller 			dev_info(&client->dev,
211*d240b0b8SWadim Mueller 				 "DT compatible says %s but sensor reports %s; using the latter\n",
212*d240b0b8SWadim Mueller 				 sf->variant->name,
213*d240b0b8SWadim Mueller 				 slf3s_variants[i].name);
214*d240b0b8SWadim Mueller 
215*d240b0b8SWadim Mueller 		sf->variant = &slf3s_variants[i];
216*d240b0b8SWadim Mueller 
217*d240b0b8SWadim Mueller 		return 0;
218*d240b0b8SWadim Mueller 	}
219*d240b0b8SWadim Mueller 
220*d240b0b8SWadim Mueller 	if (sf->variant) {
221*d240b0b8SWadim Mueller 		dev_warn(&client->dev,
222*d240b0b8SWadim Mueller 			 "unknown SLF3S sub-type 0x%02x, assuming %s\n",
223*d240b0b8SWadim Mueller 			 buf[SLF3S_PRODUCT_SUBTYPE_BYTE], sf->variant->name);
224*d240b0b8SWadim Mueller 		return 0;
225*d240b0b8SWadim Mueller 	}
226*d240b0b8SWadim Mueller 
227*d240b0b8SWadim Mueller 	dev_err(&client->dev, "unknown SLF3S sub-type 0x%02x\n",
228*d240b0b8SWadim Mueller 		buf[SLF3S_PRODUCT_SUBTYPE_BYTE]);
229*d240b0b8SWadim Mueller 
230*d240b0b8SWadim Mueller 	return -ENODEV;
231*d240b0b8SWadim Mueller }
232*d240b0b8SWadim Mueller 
233*d240b0b8SWadim Mueller static int slf3s_read_sample(struct slf3s_data *sf, int *flow, int *temp)
234*d240b0b8SWadim Mueller {
235*d240b0b8SWadim Mueller 	/*
236*d240b0b8SWadim Mueller 	 * A measurement frame is flow, temperature and a signaling-flags
237*d240b0b8SWadim Mueller 	 * word, each followed by a CRC byte.  Only flow and temperature are
238*d240b0b8SWadim Mueller 	 * used, so the read is stopped after their two words (6 bytes).
239*d240b0b8SWadim Mueller 	 */
240*d240b0b8SWadim Mueller 	u8 buf[6];
241*d240b0b8SWadim Mueller 	int ret;
242*d240b0b8SWadim Mueller 
243*d240b0b8SWadim Mueller 	ret = i2c_master_recv(sf->client, buf, sizeof(buf));
244*d240b0b8SWadim Mueller 	if (ret < 0)
245*d240b0b8SWadim Mueller 		return ret;
246*d240b0b8SWadim Mueller 	if (ret != sizeof(buf))
247*d240b0b8SWadim Mueller 		return -EIO;
248*d240b0b8SWadim Mueller 
249*d240b0b8SWadim Mueller 	for (unsigned int i = 0; i < sizeof(buf); i += 3) {
250*d240b0b8SWadim Mueller 		if (!slf3s_crc_valid(sf, &buf[i]))
251*d240b0b8SWadim Mueller 			return -EIO;
252*d240b0b8SWadim Mueller 	}
253*d240b0b8SWadim Mueller 
254*d240b0b8SWadim Mueller 	*flow = sign_extend32(get_unaligned_be16(&buf[0]), 15);
255*d240b0b8SWadim Mueller 	*temp = sign_extend32(get_unaligned_be16(&buf[3]), 15);
256*d240b0b8SWadim Mueller 
257*d240b0b8SWadim Mueller 	return 0;
258*d240b0b8SWadim Mueller }
259*d240b0b8SWadim Mueller 
260*d240b0b8SWadim Mueller static int slf3s_get_medium(struct iio_dev *indio_dev,
261*d240b0b8SWadim Mueller 			    const struct iio_chan_spec *chan)
262*d240b0b8SWadim Mueller {
263*d240b0b8SWadim Mueller 	struct slf3s_data *sf = iio_priv(indio_dev);
264*d240b0b8SWadim Mueller 
265*d240b0b8SWadim Mueller 	return sf->medium;
266*d240b0b8SWadim Mueller }
267*d240b0b8SWadim Mueller 
268*d240b0b8SWadim Mueller static int slf3s_set_medium(struct iio_dev *indio_dev,
269*d240b0b8SWadim Mueller 			    const struct iio_chan_spec *chan, unsigned int mode)
270*d240b0b8SWadim Mueller {
271*d240b0b8SWadim Mueller 	struct slf3s_data *sf = iio_priv(indio_dev);
272*d240b0b8SWadim Mueller 	int ret;
273*d240b0b8SWadim Mueller 
274*d240b0b8SWadim Mueller 	guard(mutex)(&sf->lock);
275*d240b0b8SWadim Mueller 
276*d240b0b8SWadim Mueller 	ret = slf3s_send_cmd(sf->client, slf3s_cmd_stop_meas);
277*d240b0b8SWadim Mueller 	if (ret)
278*d240b0b8SWadim Mueller 		return ret;
279*d240b0b8SWadim Mueller 
280*d240b0b8SWadim Mueller 	ret = slf3s_start_meas(sf, mode);
281*d240b0b8SWadim Mueller 	if (ret) {
282*d240b0b8SWadim Mueller 		/*
283*d240b0b8SWadim Mueller 		 * Try to restart with the previous medium so the sensor is
284*d240b0b8SWadim Mueller 		 * not left idle, which would fail all subsequent reads.
285*d240b0b8SWadim Mueller 		 */
286*d240b0b8SWadim Mueller 		if (slf3s_start_meas(sf, sf->medium))
287*d240b0b8SWadim Mueller 			dev_warn(&sf->client->dev,
288*d240b0b8SWadim Mueller 				 "failed to restart measurement, reads will fail until a medium is set\n");
289*d240b0b8SWadim Mueller 		return ret;
290*d240b0b8SWadim Mueller 	}
291*d240b0b8SWadim Mueller 
292*d240b0b8SWadim Mueller 	sf->medium = mode;
293*d240b0b8SWadim Mueller 
294*d240b0b8SWadim Mueller 	return 0;
295*d240b0b8SWadim Mueller }
296*d240b0b8SWadim Mueller 
297*d240b0b8SWadim Mueller static const struct iio_enum slf3s_medium_enum = {
298*d240b0b8SWadim Mueller 	.items		= slf3s_medium_modes,
299*d240b0b8SWadim Mueller 	.num_items	= ARRAY_SIZE(slf3s_medium_modes),
300*d240b0b8SWadim Mueller 	.get		= slf3s_get_medium,
301*d240b0b8SWadim Mueller 	.set		= slf3s_set_medium,
302*d240b0b8SWadim Mueller };
303*d240b0b8SWadim Mueller 
304*d240b0b8SWadim Mueller static const struct iio_chan_spec_ext_info slf3s_ext_info[] = {
305*d240b0b8SWadim Mueller 	IIO_ENUM("medium", IIO_SHARED_BY_TYPE, &slf3s_medium_enum),
306*d240b0b8SWadim Mueller 	IIO_ENUM_AVAILABLE("medium", IIO_SHARED_BY_TYPE, &slf3s_medium_enum),
307*d240b0b8SWadim Mueller 	{ }
308*d240b0b8SWadim Mueller };
309*d240b0b8SWadim Mueller 
310*d240b0b8SWadim Mueller static const struct iio_chan_spec slf3s_channels[] = {
311*d240b0b8SWadim Mueller 	{
312*d240b0b8SWadim Mueller 		.type = IIO_VOLUMEFLOW,
313*d240b0b8SWadim Mueller 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
314*d240b0b8SWadim Mueller 				      BIT(IIO_CHAN_INFO_SCALE),
315*d240b0b8SWadim Mueller 		.ext_info = slf3s_ext_info,
316*d240b0b8SWadim Mueller 	},
317*d240b0b8SWadim Mueller 	{
318*d240b0b8SWadim Mueller 		.type = IIO_TEMP,
319*d240b0b8SWadim Mueller 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
320*d240b0b8SWadim Mueller 				      BIT(IIO_CHAN_INFO_SCALE),
321*d240b0b8SWadim Mueller 	},
322*d240b0b8SWadim Mueller };
323*d240b0b8SWadim Mueller 
324*d240b0b8SWadim Mueller static int slf3s_read_raw(struct iio_dev *indio_dev,
325*d240b0b8SWadim Mueller 			  struct iio_chan_spec const *chan, int *val,
326*d240b0b8SWadim Mueller 			  int *val2, long mask)
327*d240b0b8SWadim Mueller {
328*d240b0b8SWadim Mueller 	struct slf3s_data *sf = iio_priv(indio_dev);
329*d240b0b8SWadim Mueller 	int flow, temp, ret;
330*d240b0b8SWadim Mueller 
331*d240b0b8SWadim Mueller 	switch (mask) {
332*d240b0b8SWadim Mueller 	case IIO_CHAN_INFO_RAW:
333*d240b0b8SWadim Mueller 		scoped_guard(mutex, &sf->lock)
334*d240b0b8SWadim Mueller 			ret = slf3s_read_sample(sf, &flow, &temp);
335*d240b0b8SWadim Mueller 		if (ret)
336*d240b0b8SWadim Mueller 			return ret;
337*d240b0b8SWadim Mueller 
338*d240b0b8SWadim Mueller 		*val = (chan->type == IIO_VOLUMEFLOW) ? flow : temp;
339*d240b0b8SWadim Mueller 
340*d240b0b8SWadim Mueller 		return IIO_VAL_INT;
341*d240b0b8SWadim Mueller 	case IIO_CHAN_INFO_SCALE:
342*d240b0b8SWadim Mueller 		if (chan->type == IIO_VOLUMEFLOW) {
343*d240b0b8SWadim Mueller 			/*
344*d240b0b8SWadim Mueller 			 * The variant scale is the flow per LSB in l/s, but
345*d240b0b8SWadim Mueller 			 * IIO reports volume flow in m^3/s (1 l = 1e-3 m^3).
346*d240b0b8SWadim Mueller 			 * These values are tiny (~1.67e-12 m^3/s for the
347*d240b0b8SWadim Mueller 			 * SLF3S-0600F), so emit a 64-bit fixed-point value with
348*d240b0b8SWadim Mueller 			 * femto (1e-15) resolution to preserve precision.
349*d240b0b8SWadim Mueller 			 * Converting l/s to m^3/s (/ MILLI) and scaling to femto
350*d240b0b8SWadim Mueller 			 * (* FEMTO) leaves a net * (FEMTO / MILLI) factor.
351*d240b0b8SWadim Mueller 			 */
352*d240b0b8SWadim Mueller 			const struct slf3s_variant *v = sf->variant;
353*d240b0b8SWadim Mueller 			s64 num = (s64)v->scale.numerator * (FEMTO / MILLI);
354*d240b0b8SWadim Mueller 			s64 scale = DIV_S64_ROUND_CLOSEST(num,
355*d240b0b8SWadim Mueller 							  v->scale.denominator);
356*d240b0b8SWadim Mueller 
357*d240b0b8SWadim Mueller 			iio_val_s64_decompose(scale, val, val2);
358*d240b0b8SWadim Mueller 
359*d240b0b8SWadim Mueller 			return IIO_VAL_DECIMAL64_FEMTO;
360*d240b0b8SWadim Mueller 		}
361*d240b0b8SWadim Mueller 		/* Temperature LSB = 1/200 degC; IIO_TEMP wants milli-degC. */
362*d240b0b8SWadim Mueller 		*val = MILLIDEGREE_PER_DEGREE / 200;
363*d240b0b8SWadim Mueller 
364*d240b0b8SWadim Mueller 		return IIO_VAL_INT;
365*d240b0b8SWadim Mueller 	default:
366*d240b0b8SWadim Mueller 		return -EINVAL;
367*d240b0b8SWadim Mueller 	}
368*d240b0b8SWadim Mueller }
369*d240b0b8SWadim Mueller 
370*d240b0b8SWadim Mueller static const struct iio_info slf3s_info = {
371*d240b0b8SWadim Mueller 	.read_raw = slf3s_read_raw,
372*d240b0b8SWadim Mueller };
373*d240b0b8SWadim Mueller 
374*d240b0b8SWadim Mueller static void slf3s_stop_meas(void *data)
375*d240b0b8SWadim Mueller {
376*d240b0b8SWadim Mueller 	struct slf3s_data *sf = data;
377*d240b0b8SWadim Mueller 
378*d240b0b8SWadim Mueller 	slf3s_send_cmd(sf->client, slf3s_cmd_stop_meas);
379*d240b0b8SWadim Mueller }
380*d240b0b8SWadim Mueller 
381*d240b0b8SWadim Mueller static void slf3s_disable_vdd(void *data)
382*d240b0b8SWadim Mueller {
383*d240b0b8SWadim Mueller 	struct slf3s_data *sf = data;
384*d240b0b8SWadim Mueller 
385*d240b0b8SWadim Mueller 	regulator_disable(sf->vdd);
386*d240b0b8SWadim Mueller }
387*d240b0b8SWadim Mueller 
388*d240b0b8SWadim Mueller static int slf3s_probe(struct i2c_client *client)
389*d240b0b8SWadim Mueller {
390*d240b0b8SWadim Mueller 	struct device *dev = &client->dev;
391*d240b0b8SWadim Mueller 	struct iio_dev *indio_dev;
392*d240b0b8SWadim Mueller 	struct slf3s_data *sf;
393*d240b0b8SWadim Mueller 	int ret;
394*d240b0b8SWadim Mueller 
395*d240b0b8SWadim Mueller 	indio_dev = devm_iio_device_alloc(dev, sizeof(*sf));
396*d240b0b8SWadim Mueller 	if (!indio_dev)
397*d240b0b8SWadim Mueller 		return -ENOMEM;
398*d240b0b8SWadim Mueller 
399*d240b0b8SWadim Mueller 	sf = iio_priv(indio_dev);
400*d240b0b8SWadim Mueller 	sf->client = client;
401*d240b0b8SWadim Mueller 	i2c_set_clientdata(client, indio_dev);
402*d240b0b8SWadim Mueller 	sf->variant = i2c_get_match_data(client);
403*d240b0b8SWadim Mueller 	sf->medium = SLF3S_MEDIUM_WATER;
404*d240b0b8SWadim Mueller 	crc8_populate_msb(sf->crc_table, SLF3S_CRC8_POLY);
405*d240b0b8SWadim Mueller 
406*d240b0b8SWadim Mueller 	ret = devm_mutex_init(dev, &sf->lock);
407*d240b0b8SWadim Mueller 	if (ret)
408*d240b0b8SWadim Mueller 		return ret;
409*d240b0b8SWadim Mueller 
410*d240b0b8SWadim Mueller 	sf->vdd = devm_regulator_get(dev, "vdd");
411*d240b0b8SWadim Mueller 	if (IS_ERR(sf->vdd))
412*d240b0b8SWadim Mueller 		return dev_err_probe(dev, PTR_ERR(sf->vdd),
413*d240b0b8SWadim Mueller 				     "failed to get vdd supply\n");
414*d240b0b8SWadim Mueller 
415*d240b0b8SWadim Mueller 	ret = regulator_enable(sf->vdd);
416*d240b0b8SWadim Mueller 	if (ret)
417*d240b0b8SWadim Mueller 		return dev_err_probe(dev, ret, "failed to enable vdd supply\n");
418*d240b0b8SWadim Mueller 
419*d240b0b8SWadim Mueller 	ret = devm_add_action_or_reset(dev, slf3s_disable_vdd, sf);
420*d240b0b8SWadim Mueller 	if (ret)
421*d240b0b8SWadim Mueller 		return ret;
422*d240b0b8SWadim Mueller 
423*d240b0b8SWadim Mueller 	fsleep(SLF3S_POWER_UP_DELAY_US);
424*d240b0b8SWadim Mueller 
425*d240b0b8SWadim Mueller 	/*
426*d240b0b8SWadim Mueller 	 * The sensor may still be in continuous measurement mode from a
427*d240b0b8SWadim Mueller 	 * previous boot (warm reboot / kexec); in that case it would NACK
428*d240b0b8SWadim Mueller 	 * the product-id command below.  Stop it first and ignore the error
429*d240b0b8SWadim Mueller 	 * if it was already idle.
430*d240b0b8SWadim Mueller 	 */
431*d240b0b8SWadim Mueller 	slf3s_send_cmd(client, slf3s_cmd_stop_meas);
432*d240b0b8SWadim Mueller 
433*d240b0b8SWadim Mueller 	ret = slf3s_detect_variant(sf);
434*d240b0b8SWadim Mueller 	if (ret)
435*d240b0b8SWadim Mueller 		return dev_err_probe(dev, ret, "product info read failed\n");
436*d240b0b8SWadim Mueller 
437*d240b0b8SWadim Mueller 	ret = slf3s_start_meas(sf, sf->medium);
438*d240b0b8SWadim Mueller 	if (ret)
439*d240b0b8SWadim Mueller 		return dev_err_probe(dev, ret,
440*d240b0b8SWadim Mueller 				     "failed to start measurement\n");
441*d240b0b8SWadim Mueller 
442*d240b0b8SWadim Mueller 	ret = devm_add_action_or_reset(dev, slf3s_stop_meas, sf);
443*d240b0b8SWadim Mueller 	if (ret)
444*d240b0b8SWadim Mueller 		return ret;
445*d240b0b8SWadim Mueller 
446*d240b0b8SWadim Mueller 	indio_dev->name = sf->variant->name;
447*d240b0b8SWadim Mueller 	indio_dev->channels = slf3s_channels;
448*d240b0b8SWadim Mueller 	indio_dev->num_channels = ARRAY_SIZE(slf3s_channels);
449*d240b0b8SWadim Mueller 	indio_dev->info = &slf3s_info;
450*d240b0b8SWadim Mueller 	indio_dev->modes = INDIO_DIRECT_MODE;
451*d240b0b8SWadim Mueller 
452*d240b0b8SWadim Mueller 	return devm_iio_device_register(dev, indio_dev);
453*d240b0b8SWadim Mueller }
454*d240b0b8SWadim Mueller 
455*d240b0b8SWadim Mueller /*
456*d240b0b8SWadim Mueller  * The sensor has no low-power state of its own, so stop the measurement
457*d240b0b8SWadim Mueller  * and cut the supply while suspended.  Resume powers it back up, waits
458*d240b0b8SWadim Mueller  * out the power-up time and restarts with the medium that was active
459*d240b0b8SWadim Mueller  * before.
460*d240b0b8SWadim Mueller  */
461*d240b0b8SWadim Mueller static int slf3s_suspend(struct device *dev)
462*d240b0b8SWadim Mueller {
463*d240b0b8SWadim Mueller 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
464*d240b0b8SWadim Mueller 	struct slf3s_data *sf = iio_priv(indio_dev);
465*d240b0b8SWadim Mueller 	int ret;
466*d240b0b8SWadim Mueller 
467*d240b0b8SWadim Mueller 	guard(mutex)(&sf->lock);
468*d240b0b8SWadim Mueller 
469*d240b0b8SWadim Mueller 	ret = slf3s_send_cmd(sf->client, slf3s_cmd_stop_meas);
470*d240b0b8SWadim Mueller 	if (ret)
471*d240b0b8SWadim Mueller 		return ret;
472*d240b0b8SWadim Mueller 
473*d240b0b8SWadim Mueller 	return regulator_disable(sf->vdd);
474*d240b0b8SWadim Mueller }
475*d240b0b8SWadim Mueller 
476*d240b0b8SWadim Mueller static int slf3s_resume(struct device *dev)
477*d240b0b8SWadim Mueller {
478*d240b0b8SWadim Mueller 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
479*d240b0b8SWadim Mueller 	struct slf3s_data *sf = iio_priv(indio_dev);
480*d240b0b8SWadim Mueller 	int ret;
481*d240b0b8SWadim Mueller 
482*d240b0b8SWadim Mueller 	guard(mutex)(&sf->lock);
483*d240b0b8SWadim Mueller 
484*d240b0b8SWadim Mueller 	ret = regulator_enable(sf->vdd);
485*d240b0b8SWadim Mueller 	if (ret)
486*d240b0b8SWadim Mueller 		return ret;
487*d240b0b8SWadim Mueller 
488*d240b0b8SWadim Mueller 	fsleep(SLF3S_POWER_UP_DELAY_US);
489*d240b0b8SWadim Mueller 
490*d240b0b8SWadim Mueller 	return slf3s_start_meas(sf, sf->medium);
491*d240b0b8SWadim Mueller }
492*d240b0b8SWadim Mueller 
493*d240b0b8SWadim Mueller static DEFINE_SIMPLE_DEV_PM_OPS(slf3s_pm_ops, slf3s_suspend, slf3s_resume);
494*d240b0b8SWadim Mueller 
495*d240b0b8SWadim Mueller static const struct i2c_device_id slf3s_id[] = {
496*d240b0b8SWadim Mueller 	{
497*d240b0b8SWadim Mueller 		.name = "slf3s-0600f",
498*d240b0b8SWadim Mueller 		.driver_data = (kernel_ulong_t)&slf3s_variants[SLF3S_0600F],
499*d240b0b8SWadim Mueller 	},
500*d240b0b8SWadim Mueller 	{
501*d240b0b8SWadim Mueller 		.name = "slf3s-1300f",
502*d240b0b8SWadim Mueller 		.driver_data = (kernel_ulong_t)&slf3s_variants[SLF3S_1300F],
503*d240b0b8SWadim Mueller 	},
504*d240b0b8SWadim Mueller 	{
505*d240b0b8SWadim Mueller 		.name = "slf3s-4000b",
506*d240b0b8SWadim Mueller 		.driver_data = (kernel_ulong_t)&slf3s_variants[SLF3S_4000B],
507*d240b0b8SWadim Mueller 	},
508*d240b0b8SWadim Mueller 	{ }
509*d240b0b8SWadim Mueller };
510*d240b0b8SWadim Mueller MODULE_DEVICE_TABLE(i2c, slf3s_id);
511*d240b0b8SWadim Mueller 
512*d240b0b8SWadim Mueller static const struct of_device_id slf3s_of_match[] = {
513*d240b0b8SWadim Mueller 	{
514*d240b0b8SWadim Mueller 		.compatible = "sensirion,slf3s-0600f",
515*d240b0b8SWadim Mueller 		.data = &slf3s_variants[SLF3S_0600F],
516*d240b0b8SWadim Mueller 	},
517*d240b0b8SWadim Mueller 	{
518*d240b0b8SWadim Mueller 		.compatible = "sensirion,slf3s-1300f",
519*d240b0b8SWadim Mueller 		.data = &slf3s_variants[SLF3S_1300F],
520*d240b0b8SWadim Mueller 	},
521*d240b0b8SWadim Mueller 	{
522*d240b0b8SWadim Mueller 		.compatible = "sensirion,slf3s-4000b",
523*d240b0b8SWadim Mueller 		.data = &slf3s_variants[SLF3S_4000B],
524*d240b0b8SWadim Mueller 	},
525*d240b0b8SWadim Mueller 	{ }
526*d240b0b8SWadim Mueller };
527*d240b0b8SWadim Mueller MODULE_DEVICE_TABLE(of, slf3s_of_match);
528*d240b0b8SWadim Mueller 
529*d240b0b8SWadim Mueller static struct i2c_driver slf3s_driver = {
530*d240b0b8SWadim Mueller 	.driver = {
531*d240b0b8SWadim Mueller 		.name		= "slf3s",
532*d240b0b8SWadim Mueller 		.of_match_table	= slf3s_of_match,
533*d240b0b8SWadim Mueller 		.pm		= pm_sleep_ptr(&slf3s_pm_ops),
534*d240b0b8SWadim Mueller 	},
535*d240b0b8SWadim Mueller 	.probe		= slf3s_probe,
536*d240b0b8SWadim Mueller 	.id_table	= slf3s_id,
537*d240b0b8SWadim Mueller };
538*d240b0b8SWadim Mueller module_i2c_driver(slf3s_driver);
539*d240b0b8SWadim Mueller 
540*d240b0b8SWadim Mueller MODULE_AUTHOR("Wadim Mueller <wafgo01@gmail.com>");
541*d240b0b8SWadim Mueller MODULE_DESCRIPTION("Sensirion SLF3S liquid flow sensor driver");
542*d240b0b8SWadim Mueller MODULE_LICENSE("GPL");
543