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