iio: flow: Sensirion SLF3S liquid flow sensor
Subsystems (3)
Wadim Mueller
maintainerv6 cover iio: flow: Sensirion SLF3S liquid flow sensor
Hi all,
this series adds a driver for the Sensirion SLF3S family of I2C liquid flow sensors (SLF3S-0600F / -1300F / -4000B) and a new IIO_VOLUMEFLOW channel type.
First of all: sorry for the noise. Patch 4/4 of v5 never made it to the list or to patchwork - it got lost on the way out from the machine I sent v5 from, as Jonathan noticed:
https://lore.kernel.org/linux-iio/20260720032927.14fc4f9f@jic23-huawei/
So this v6 is mostly a resend of v5 with the driver patch actually included, plus the binding change we converged on in the meantime. The driver changes that were listed in the v5 changelog are repeated below, since nobody got to see them.
The series is based on iio.git testing, which already contains Rodrigo Alencar's IIO_VAL_DECIMAL64_* core formatting work; patch 3/4 adds the IIO_VAL_DECIMAL64_FEMTO format type on top of it.
Changes since v5
----------------
* 4/4 is included this time - v5 only had 1-3 on the list
* dt-bindings: dropped the fallback compatible entirely; each variant now has its own compatible, per the conclusion of the v4 discussion between Krzysztof and Jonathan. Since the driver has to look at the product-information register anyway, a fallback buys nothing, while separate compatibles let a future drop-in part claim a known compatible and work on older kernels
* dt-bindings: dropped Krzysztof's Reviewed-by, since the compatible schema changed
* dt-bindings: commit message and example updated accordingly
* driver: reworded the slf3s_detect_variant() comment and the commit message, which referred to the now-gone fallback compatible. The behaviour is unchanged: an unknown sub-type still falls back to the variant named in the device tree / I2C table
* rebased onto current iio.git testing
Changes since v4 (from the v5 posting, repeated because 4/4 was lost)
---------------------------------------------------------------------
* driver: include err.h for PTR_ERR() and math.h for struct s32_fract, per Andy
* driver: fold the per-variant scale_num/scale_den pair into a struct s32_fract, per Andy
* driver: add enum slf3s_variant_id and use it for the variant table and the I2C/OF match tables instead of bare indices, per Andy
* driver: slf3s_send_cmd(): drop the "at_least 2" parameter annotation, decouple the ret assignment from its declaration and check errors first, per Andy
* driver: use sizeof() instead of ARRAY_SIZE() for the measurement byte buffer, per Andy
* driver: parenthesise the (FEMTO / MILLI) factor so it folds into a single constant multiplication, per Andy
* driver: derive the temperature scale from MILLIDEGREE_PER_DEGREE instead of a bare 1000, per Andy
* driver: checked the struct slf3s_data layout (re Andy's pahole question): the non-pointer members total 260 bytes, so one 4-byte hole remains for any member order; left as is
* driver: drop the inline comment on the mutex that duplicated the kernel-doc, per Jonathan (checkpatch still moans about it)
* driver: fix the duplicated argument in the DT/sensor variant mismatch dev_info(), per Jonathan
* driver: reformat the i2c_device_id/of_device_id tables to one member per line, per Jonathan
* MAINTAINERS: updated Maxwell's address in the R: entry to [email protected], as he requested on the v4 thread
The signaling-flags word (air-in-line / high-flow / smoothing status) in each measurement frame is intentionally not read; exposing it can be a later follow-up.
v5: https://lore.kernel.org/linux-iio/[email protected]/
v4: https://lore.kernel.org/linux-iio/[email protected]/
Thanks,
Wadim
Wadim Mueller (4):
iio: types: add IIO_VOLUMEFLOW channel type
dt-bindings: iio: flow: add Sensirion SLF3S liquid flow sensor
iio: core: add IIO_VAL_DECIMAL64_FEMTO format type
iio: flow: add Sensirion SLF3S liquid flow sensor driver
Documentation/ABI/testing/sysfs-bus-iio | 11 + Documentation/ABI/testing/sysfs-bus-iio-flow | 21 + .../bindings/iio/flow/sensirion,slf3s.yaml | 55 ++ MAINTAINERS | 8 + drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/flow/Kconfig | 22 + drivers/iio/flow/Makefile | 7 + drivers/iio/flow/slf3s.c | 543 ++++++++++++++++++ drivers/iio/industrialio-core.c | 3 + include/linux/iio/types.h | 1 + include/uapi/linux/iio/types.h | 1 + tools/iio/iio_event_monitor.c | 2 + 13 files changed, 676 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-flow create mode 100644 Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml create mode 100644 drivers/iio/flow/Kconfig create mode 100644 drivers/iio/flow/Makefile create mode 100644 drivers/iio/flow/slf3s.c
base-commit: e0484d62e8e1cff75b210938be835ea6221bda59
Signature · 1 line
2.52.0
Wadim Mueller
maintainerPATCH v6 1/4 iio: types: add IIO_VOLUMEFLOW channel type
Add a new IIO channel type for liquid volumetric flow sensors. The unit exposed via the standard _scale attribute is cubic metres per second (m^3/s), following the SI convention used by the other IIO channel types.
Update iio-core's name table, the iio_event_monitor whitelist and the sysfs-bus-iio ABI document to match. The new _scale attribute is folded into the existing shared _scale block; only the per-type _raw needs a fresh entry.
--- Documentation/ABI/testing/sysfs-bus-iio | 11 +++++++++++ drivers/iio/industrialio-core.c | 1 + include/uapi/linux/iio/types.h | 1 + tools/iio/iio_event_monitor.c | 2 ++ 4 files changed, 15 insertions(+)
Documentation/ABI/testing/sysfs-bus-iio +11 -0
@@ -507,6 +507,8 @@ What: /sys/bus/iio/devices/iio:deviceX/in_intensity_red_scale What: /sys/bus/iio/devices/iio:deviceX/in_intensity_green_scale What: /sys/bus/iio/devices/iio:deviceX/in_intensity_blue_scale What: /sys/bus/iio/devices/iio:deviceX/in_concentration_co2_scale +What: /sys/bus/iio/devices/iio:deviceX/in_volumeflow_scale +What: /sys/bus/iio/devices/iio:deviceX/in_volumeflowY_scale KernelVersion: 2.6.35 Contact: [email protected] Description:
@@ -2497,3 +2499,12 @@ Description: seconds, expressed as: - a range specified as "[min step max]" + +What: /sys/bus/iio/devices/iio:deviceX/in_volumeflow_raw +What: /sys/bus/iio/devices/iio:deviceX/in_volumeflowY_raw +KernelVersion: 7.3 +Contact: [email protected] +Description: + Raw (unscaled) volumetric flow rate reading from the channel. + To convert to standard units (cubic metres per second, m^3/s) + apply the channel's _scale (and _offset, when present).
drivers/iio/industrialio-core.c +1 -0
@@ -99,6 +99,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_ATTENTION] = "attention", [IIO_ALTCURRENT] = "altcurrent", [IIO_COVERAGE] = "coverage", + [IIO_VOLUMEFLOW] = "volumeflow", };static const char *const iio_modifier_names[] = {
include/uapi/linux/iio/types.h +1 -0
@@ -54,6 +54,7 @@ enum iio_chan_type {IIO_ATTENTION ,IIO_ALTCURRENT ,IIO_COVERAGE , + IIO_VOLUMEFLOW, }; enum iio_modifier {
tools/iio/iio_event_monitor.c +2 -0
@@ -66,6 +66,7 @@ static const char * const iio_chan_type_name_spec[] = { [IIO_ATTENTION] = "attention", [IIO_ALTCURRENT] = "altcurrent", [IIO_COVERAGE] = "coverage", + [IIO_VOLUMEFLOW] = "volumeflow", };static const char *const iio_ev_type_text[] = {
@@ -196,6 +197,7 @@ static bool event_is_known(struct iio_event_data *event)case IIO_ATTENTION :case IIO_ALTCURRENT :case IIO_COVERAGE : +case IIO_VOLUMEFLOW :break ;default :return false;
Signature · 1 line
2.52.0
Re: [PATCH v6 1/4] iio: types: add IIO_VOLUMEFLOW channel type
Quoted 5 lines · On Tue, 28 Jul 2026 23:49:40 +0200 Wadim Mueller <[email protected]> wrote:
Add a new IIO channel type for liquid volumetric flow sensors. The unit exposed via the standard
_scaleattribute is cubic metres per second (m^3/s), following the SI convention used by the other IIO channel types.
Quoted 7 lines
Update iio-core's name table, the
iio_event_monitorwhitelist and the sysfs-bus-iio ABI document to match. The new_scaleattribute is folded into the existing shared_scaleblock; only the per-type_rawneeds a fresh entry.Signed-off-by Wadim Mueller <[email protected]>---
Since there's still time for additional tags (and this patch has none)
Signature · 2 lines
Kind regards, Joshua Crofts
Wadim Mueller
maintainerPATCH v6 2/4 dt-bindings: iio: flow: add Sensirion SLF3S liquid flow sensor
In reply to Wadim MuellerDocument the bindings for the Sensirion SLF3S family of digital liquid-flow sensors on I2C. The family currently covers the SLF3S-0600F, SLF3S-1300F and SLF3S-4000B variants.
All variants share the same register map and differ only in the flow scale factor and the calibrated measurement range, which the driver reads back from the product-information register. Since that lookup is needed in any case, a fallback compatible would buy nothing, so each variant gets its own compatible without a fallback. A future drop-in compatible part can then claim one of these compatibles and work on kernels that do not know its product ID yet.
The active calibration medium (water / IPA) is runtime-switchable via the in_volumeflow_medium sysfs attribute and therefore not a DT property.
--- .../bindings/iio/flow/sensirion,slf3s.yaml | 55 +++++++++++++++++++ MAINTAINERS | 7 +++ 2 files changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml
Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml new file +55 -0
@@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/flow/sensirion,slf3s.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sensirion SLF3S liquid flow sensor + +maintainers: + - Wadim Mueller <[email protected]> + +description: + Family of digital liquid-flow sensors from Sensirion with I2C interface. All + family members share the same register map; sub-types differ only in the flow + scale factor and the calibrated measurement range. The sub-type can be + identified from the product-information register. + +properties: + compatible: + enum: + - sensirion,slf3s-0600f + - sensirion,slf3s-1300f + - sensirion,slf3s-4000b + + reg: + maxItems: 1 + + vdd-supply: true + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - vdd-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + flow-sensor@8 { + compatible = "sensirion,slf3s-0600f"; + reg = <0x08>; + vdd-supply = <®_3v3>; + interrupt-parent = <&gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + }; + };
MAINTAINERS +7 -0
@@ -24583,6 +24583,13 @@ S: Maintained F: Documentation/ABI/testing/sysfs-bus-iio-chemical-sgp40 F: drivers/iio/chemical/sgp40.c +SENSIRION SLF3S LIQUID FLOW SENSOR DRIVER +M: Wadim Mueller <[email protected]> +R: Maxwell Doose <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml + SENSIRION SPS30 AIR POLLUTION SENSOR DRIVER M: Tomasz Duszynski <[email protected]> S: Maintained
Signature · 1 line
2.52.0
[email protected]
AI reviewRe: [PATCH v6 2/4] dt-bindings: iio: flow: add Sensirion SLF3S liquid flow sensor
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Low] Hardware mismatch: The DT binding documents an `interrupts` property for a 4-pin device that lacks…
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] Hardware mismatch: The DT binding documents an interrupts property for a 4-pin device that lacks a physical interrupt pin. --
--- Patch [2]: [PATCH v6 2/4] dt-bindings: iio: flow: add Sensirion SLF3S liquid flow sensor --- commit 926be8ca8c587fafce9ef5ee2b44bb20052e203d
Author: Wadim Mueller <[email protected]>
dt-bindings: iio: flow: add Sensirion SLF3S liquid flow sensor
This commit documents the device tree bindings for the Sensirion SLF3S family of digital liquid-flow sensors on I2C. The driver covers multiple variants which differ only in flow scale factor and calibrated measurement range.
Quoted 5 lines
Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml new file +0
-0
[ ... ]
Quoted 4 lines
Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml new file +4
-0+properties: + compatible: + enum: + - sensirion,slf3s-0600f
Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml line 31
Quoted 10 lines
Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml new file +10
-0+ - sensirion,slf3s-1300f + - sensirion,slf3s-4000b + + reg: + maxItems: 1 + + vdd-supply: true + + interrupts: + maxItems: 1
[Severity: Low]
Is this interrupts property accurate for the hardware?
The SLF3S sensors are 4-pin devices (VDD, GND, SDA, and SCL) and do not appear to have a physical interrupt pin. Documenting it here might mislead device tree authors into configuring phantom interrupts.
Quoted 12 lines
Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml new file +12
-0+ +required: + - compatible + - reg + - vdd-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> +
Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml line 53
Quoted 10 lines
Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml new file +10
-0+ i2c { + #address-cells = <1>; + #size-cells = <0>; + + flow-sensor@8 { + compatible = "sensirion,slf3s-0600f"; + reg = <0x08>; + vdd-supply = <®_3v3>; + interrupt-parent = <&gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>;
[Severity: Low]
Could these interrupt properties be removed from the example, since the hardware does not have an interrupt pin?
Quoted 2 lines
Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml new file +2
-0+ }; + };
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
Jonathan Cameron
maintainerRe: [PATCH v6 2/4] dt-bindings: iio: flow: add Sensirion SLF3S liquid flow sensor
In reply to Wadim MuellerQuoted 3 lines · On Tue, 28 Jul 2026 23:49:41 +0200 Wadim Mueller <[email protected]> wrote:
Document the bindings for the Sensirion SLF3S family of digital liquid-flow sensors on I2C. The family currently covers the SLF3S-0600F, SLF3S-1300F and SLF3S-4000B variants.
FWIW there is a false positive from Sashiko on this where it says there is no interrupt pin. I'll guess that it found a datasheet talking about one packaging option perhaps?
The first one I checked has the interrupt pin.
Jonathan
Quoted 99 lines
All variants share the same register map and differ only in the flow scale factor and the calibrated measurement range, which the driver reads back from the product-information register. Since that lookup is needed in any case, a fallback compatible would buy nothing, so each variant gets its own compatible without a fallback. A future drop-in compatible part can then claim one of these compatibles and work on kernels that do not know its product ID yet.
The active calibration medium (water / IPA) is runtime-switchable via the
in_volumeflow_mediumsysfs attribute and therefore not a DT property.Signed-off-by Wadim Mueller <[email protected]>--- .../bindings/iio/flow/sensirion,slf3s.yaml | 55 +++++++++++++++++++ MAINTAINERS | 7 +++ 2 files changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yamlDocumentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml new file +55
-0@@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/flow/sensirion,slf3s.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sensirion SLF3S liquid flow sensor + +maintainers: + - Wadim Mueller <[email protected]> + +description: + Family of digital liquid-flow sensors from Sensirion with I2C interface. All + family members share the same register map; sub-types differ only in the flow + scale factor and the calibrated measurement range. The sub-type can be + identified from the product-information register. + +properties: + compatible: + enum: + - sensirion,slf3s-0600f + - sensirion,slf3s-1300f + - sensirion,slf3s-4000b + + reg: + maxItems: 1 + + vdd-supply: true + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - vdd-supply + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + flow-sensor@8 { + compatible = "sensirion,slf3s-0600f"; + reg = <0x08>; + vdd-supply = <®_3v3>; + interrupt-parent = <&gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + }; + };MAINTAINERS +7
-0@@ -24583,6 +24583,13 @@ S: Maintained F: Documentation/ABI/testing/sysfs-bus-iio-chemical-sgp40 F: drivers/iio/chemical/sgp40.c +SENSIRION SLF3S LIQUID FLOW SENSOR DRIVER +M: Wadim Mueller <[email protected]> +R: Maxwell Doose <[email protected]> +L: [email protected] +S: Maintained +F: Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml + SENSIRION SPS30 AIR POLLUTION SENSOR DRIVER M: Tomasz Duszynski <[email protected]> S: Maintained
Re: [PATCH v6 2/4] dt-bindings: iio: flow: add Sensirion SLF3S liquid flow sensor
In reply to Wadim MuellerQuoted 16 lines · Wadim Mueller
Document the bindings for the Sensirion SLF3S family of digital liquid-flow sensors on I2C. The family currently covers the SLF3S-0600F, SLF3S-1300F and SLF3S-4000B variants.
All variants share the same register map and differ only in the flow scale factor and the calibrated measurement range, which the driver reads back from the product-information register. Since that lookup is needed in any case, a fallback compatible would buy nothing, so each variant gets its own compatible without a fallback. A future drop-in compatible part can then claim one of these compatibles and work on kernels that do not know its product ID yet.
The active calibration medium (water / IPA) is runtime-switchable via the
in_volumeflow_mediumsysfs attribute and therefore not a DT property.
Quoted 6 lines
Signed-off-by Wadim Mueller <[email protected]>--- .../bindings/iio/flow/sensirion,slf3s.yaml | 55 +++++++++++++++++++ MAINTAINERS | 7 +++ 2 files changed, 62 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml
Best regards,
Krzysztof
Wadim Mueller
maintainerPATCH v6 3/4 iio: core: add IIO_VAL_DECIMAL64_FEMTO format type
In reply to Wadim MuellerExtend the IIO_VAL_DECIMAL64_* family with a femto-scaled variant (scale 15), following the existing MILLI/MICRO/NANO/PICO pattern. Both the read formatting path in __iio_format_value() and the write parsing path in iio_write_channel_info() (via kstrtodec64()) already derive their scale from "type - IIO_VAL_DECIMAL64_BASE", so the new type only needs to be added to the respective switch cases.
This is needed by drivers reporting very small SI quantities where the existing pico scale loses precision. For example the Sensirion SLF3S liquid flow sensor reports its volume-flow scale in m^3/s, where the SLF3S-0600F scale is ~1.667e-12 m^3/s: at pico scale only a single significant digit survives, whereas femto scale preserves the full sensor resolution.
--- drivers/iio/industrialio-core.c | 2 ++ include/linux/iio/types.h | 1 + 2 files changed, 3 insertions(+)
drivers/iio/industrialio-core.c +2 -0
@@ -715,6 +715,7 @@ static ssize_t __iio_format_value(char *buf, size_t offset, unsigned int type,case IIO_VAL_DECIMAL64_MICRO :case IIO_VAL_DECIMAL64_NANO :case IIO_VAL_DECIMAL64_PICO : +case IIO_VAL_DECIMAL64_FEMTO : {int scale = type -IIO_VAL_DECIMAL64_BASE ;s64 frac;
@@ -1032,6 +1033,7 @@ static ssize_t iio_write_channel_info(struct device *dev,case IIO_VAL_DECIMAL64_MICRO :case IIO_VAL_DECIMAL64_NANO :case IIO_VAL_DECIMAL64_PICO : +case IIO_VAL_DECIMAL64_FEMTO : dec_scale = type -IIO_VAL_DECIMAL64_BASE ; fallthrough;case IIO_VAL_INT_64 :
include/linux/iio/types.h +1 -0
@@ -42,6 +42,7 @@ enum iio_event_info {#define IIO_VAL_DECIMAL64_MICRO (IIO_VAL_DECIMAL64_BASE + 6)#define IIO_VAL_DECIMAL64_NANO (IIO_VAL_DECIMAL64_BASE + 9)#define IIO_VAL_DECIMAL64_PICO (IIO_VAL_DECIMAL64_BASE + 12) +#define IIO_VAL_DECIMAL64_FEMTO (IIO_VAL_DECIMAL64_BASE + 15)static inline s64 iio_val_s64_compose (s32 val0,s32 val1) {
Signature · 1 line
2.52.0
David Lechner
reviewerRe: [PATCH v6 3/4] iio: core: add IIO_VAL_DECIMAL64_FEMTO format type
Quoted 46 lines · Wadim Mueller
Extend the IIO_VAL_DECIMAL64_* family with a femto-scaled variant (scale 15), following the existing MILLI/MICRO/NANO/PICO pattern. Both the read formatting path in
__iio_format_value()and the write parsing path iniio_write_channel_info()(viakstrtodec64()) already derive their scale from "type -IIO_VAL_DECIMAL64_BASE", so the new type only needs to be added to the respective switch cases.This is needed by drivers reporting very small SI quantities where the existing pico scale loses precision. For example the Sensirion SLF3S liquid flow sensor reports its volume-flow scale in m^3/s, where the SLF3S-0600F scale is ~1.667e-12 m^3/s: at pico scale only a single significant digit survives, whereas femto scale preserves the full sensor resolution.
Signed-off-by Wadim Mueller <[email protected]>Reviewed-by Rodrigo Alencar <[email protected]>--- drivers/iio/industrialio-core.c | 2 ++ include/linux/iio/types.h | 1 + 2 files changed, 3 insertions(+)drivers/iio/industrialio-core.c +2
-0@@ -715,6 +715,7 @@ static ssize_t __iio_format_value(char *buf, size_t offset, unsigned int type,case IIO_VAL_DECIMAL64_MICRO :case IIO_VAL_DECIMAL64_NANO :case IIO_VAL_DECIMAL64_PICO : +case IIO_VAL_DECIMAL64_FEMTO : {int scale = type -IIO_VAL_DECIMAL64_BASE ;s64 frac;@@ -1032,6 +1033,7 @@ static ssize_t iio_write_channel_info(struct device *dev,case IIO_VAL_DECIMAL64_MICRO :case IIO_VAL_DECIMAL64_NANO :case IIO_VAL_DECIMAL64_PICO : +case IIO_VAL_DECIMAL64_FEMTO : dec_scale = type -IIO_VAL_DECIMAL64_BASE ; fallthrough;case IIO_VAL_INT_64 :include/linux/iio/types.h +0
-0
include/linux/iio/types.h enum iio_event_info { · line 48
Quoted 7 lines
include/linux/iio/types.h +1
-0@@ -42,6 +42,7 @@ enum iio_event_info {#define IIO_VAL_DECIMAL64_MICRO (IIO_VAL_DECIMAL64_BASE + 6)#define IIO_VAL_DECIMAL64_NANO (IIO_VAL_DECIMAL64_BASE + 9)#define IIO_VAL_DECIMAL64_PICO (IIO_VAL_DECIMAL64_BASE + 12) +#define IIO_VAL_DECIMAL64_FEMTO (IIO_VAL_DECIMAL64_BASE + 15)static inline s64 iio_val_s64_compose (s32 val0,s32 val1) {
Would be nice to add this to drivers/iio/test/iio-test-format.c too.
Jonathan Cameron
maintainerRe: [PATCH v6 3/4] iio: core: add IIO_VAL_DECIMAL64_FEMTO format type
Quoted 52 lines · On Sun, 2 Aug 2026 11:01:28 -0500 David Lechner <[email protected]> wrote:
Quoted 51 lines · Wadim Mueller
Extend the IIO_VAL_DECIMAL64_* family with a femto-scaled variant (scale 15), following the existing MILLI/MICRO/NANO/PICO pattern. Both the read formatting path in
__iio_format_value()and the write parsing path iniio_write_channel_info()(viakstrtodec64()) already derive their scale from "type -IIO_VAL_DECIMAL64_BASE", so the new type only needs to be added to the respective switch cases.This is needed by drivers reporting very small SI quantities where the existing pico scale loses precision. For example the Sensirion SLF3S liquid flow sensor reports its volume-flow scale in m^3/s, where the SLF3S-0600F scale is ~1.667e-12 m^3/s: at pico scale only a single significant digit survives, whereas femto scale preserves the full sensor resolution.
Signed-off-by Wadim Mueller <[email protected]>Reviewed-by Rodrigo Alencar <[email protected]>--- drivers/iio/industrialio-core.c | 2 ++ include/linux/iio/types.h | 1 + 2 files changed, 3 insertions(+)drivers/iio/industrialio-core.c +2
-0@@ -715,6 +715,7 @@ static ssize_t __iio_format_value(char *buf, size_t offset, unsigned int type,case IIO_VAL_DECIMAL64_MICRO :case IIO_VAL_DECIMAL64_NANO :case IIO_VAL_DECIMAL64_PICO : +case IIO_VAL_DECIMAL64_FEMTO : {int scale = type -IIO_VAL_DECIMAL64_BASE ;s64 frac;@@ -1032,6 +1033,7 @@ static ssize_t iio_write_channel_info(struct device *dev,case IIO_VAL_DECIMAL64_MICRO :case IIO_VAL_DECIMAL64_NANO :case IIO_VAL_DECIMAL64_PICO : +case IIO_VAL_DECIMAL64_FEMTO : dec_scale = type -IIO_VAL_DECIMAL64_BASE ; fallthrough;case IIO_VAL_INT_64 :include/linux/iio/types.h +1
-0@@ -42,6 +42,7 @@ enum iio_event_info {#define IIO_VAL_DECIMAL64_MICRO (IIO_VAL_DECIMAL64_BASE + 6)#define IIO_VAL_DECIMAL64_NANO (IIO_VAL_DECIMAL64_BASE + 9)#define IIO_VAL_DECIMAL64_PICO (IIO_VAL_DECIMAL64_BASE + 12) +#define IIO_VAL_DECIMAL64_FEMTO (IIO_VAL_DECIMAL64_BASE + 15)
Quoted 4 lines
include/linux/iio/types.h enum iio_event_info { · line 48
Quoted 2 lines
include/linux/iio/types.h +0
-0static inline s64 iio_val_s64_compose (s32 val0,s32 val1) {Would be nice to add this to
drivers/iio/test/iio-test-format.ctoo.
Good point. I somehow keep forgetting we now have tests!
That can be a follow up patch
Jonathan
Quoted 1 line
Wadim Mueller
maintainerPATCH v6 4/4 iio: flow: add Sensirion SLF3S liquid flow sensor driver
In reply to Wadim MuellerAdd a driver for the Sensirion SLF3S family of digital liquid-flow sensors on I2C. Currently supported variants are SLF3S-0600F, SLF3S-1300F and SLF3S-4000B; they share the same register map and differ only in flow-scale factor and calibrated measurement range. The variant (and therefore the scale) is auto-detected from the product-information register at probe time; a sensor reporting an unknown sub-type falls back to the variant named in the device tree / I2C table, so a drop-in replacement part keeps working on a kernel that does not know its sub-type yet.
Each measurement frame returns a 16-bit signed flow value, a 16-bit signed temperature reading and a status word, each protected by a CRC-8 byte. The driver exposes the flow rate as IIO_VOLUMEFLOW and the temperature as IIO_TEMP via the standard IIO read_raw / read_scale interface.
The volume-flow scale is reported in m^3/s. As the per-LSB scale is on the order of 1e-12 m^3/s, it is emitted as a 64-bit fixed-point value with femto (1e-15) resolution (IIO_VAL_DECIMAL64_FEMTO) so the small SI value keeps full precision. This relies on the IIO_VAL_DECIMAL64_FEMTO format type added earlier in this series.
The active calibration medium can be switched at runtime between the factory-calibrated water and isopropyl-alcohol modes via the in_volumeflow_medium sysfs attribute; the sensor starts in water mode after probe.
The sensor has no low-power state of its own, so system suspend stops the measurement and disables the vdd supply; resume powers the sensor back up, waits out the power-up time and restarts the measurement with the previously active medium, following the scd30/scd4x precedent.
This driver also creates the drivers/iio/flow/ subdirectory and the corresponding Kconfig/Makefile glue.
--- Documentation/ABI/testing/sysfs-bus-iio-flow | 21 + MAINTAINERS | 1 + drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/flow/Kconfig | 22 + drivers/iio/flow/Makefile | 7 + drivers/iio/flow/slf3s.c | 543 +++++++++++++++++++ 7 files changed, 596 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-flow create mode 100644 drivers/iio/flow/Kconfig create mode 100644 drivers/iio/flow/Makefile create mode 100644 drivers/iio/flow/slf3s.c
Documentation/ABI/testing/sysfs-bus-iio-flow new file +21 -0
@@ -0,0 +1,21 @@ +What: /sys/bus/iio/devices/iio:deviceX/in_volumeflow_medium +What: /sys/bus/iio/devices/iio:deviceX/in_volumeflowY_medium +KernelVersion: 7.3 +Contact: [email protected] +Description: + The calibration medium the flow sensor uses to convert its + raw reading into a volumetric flow rate. Liquid flow sensors + are factory-calibrated per medium, so the selected medium has + to match the fluid actually flowing through the sensor for the + reported flow rate to be correct. + + Reading returns the currently active medium; writing one of the + strings listed in in_volumeflow_medium_available selects it. + +What: /sys/bus/iio/devices/iio:deviceX/in_volumeflow_medium_available +What: /sys/bus/iio/devices/iio:deviceX/in_volumeflowY_medium_available +KernelVersion: 7.3 +Contact: [email protected] +Description: + Space separated list of the calibration media supported by the + device, e.g. "water ipa".
MAINTAINERS +1 -0
@@ -24589,6 +24589,7 @@ R: Maxwell Doose <[email protected]> L: [email protected] S: Maintained F: Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml +F: drivers/iio/flow/slf3s.c SENSIRION SPS30 AIR POLLUTION SENSOR DRIVER M: Tomasz Duszynski <[email protected]>
drivers/iio/Kconfig +1 -0
@@ -92,6 +92,7 @@ source "drivers/iio/common/Kconfig" source "drivers/iio/dac/Kconfig" source "drivers/iio/dummy/Kconfig" source "drivers/iio/filter/Kconfig" +source "drivers/iio/flow/Kconfig" source "drivers/iio/frequency/Kconfig" source "drivers/iio/gyro/Kconfig" source "drivers/iio/health/Kconfig"
drivers/iio/Makefile +1 -0
@@ -29,6 +29,7 @@ obj-y += dac/ obj-y += dummy/ obj-y += gyro/ obj-y += filter/ +obj-y += flow/ obj-y += frequency/ obj-y += health/ obj-y += humidity/
drivers/iio/flow/Kconfig new file +22 -0
@@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Liquid / gas flow sensor drivers +# +# When adding new entries keep the list in alphabetical order + +menu "Flow sensors" + +config SENSIRION_SLF3S + tristate "Sensirion SLF3S liquid flow sensor" + depends on I2C + select CRC8 + help + Say yes here to build support for the Sensirion SLF3S family of + digital liquid-flow sensors (SLF3S-0600F, SLF3S-1300F and + SLF3S-4000B). The driver reports the volumetric flow rate and the + embedded temperature reading via the standard IIO interface. + + To compile this driver as a module, choose M here: the module + will be called slf3s. + +endmenu
drivers/iio/flow/Makefile new file +7 -0
@@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for industrial I/O flow sensor drivers +# + +# When adding new entries keep the list in alphabetical order +obj-$(CONFIG_SENSIRION_SLF3S) += slf3s.o
drivers/iio/flow/slf3s.c new file +543 -0
543 lines not on this page · raw message
Signature · 1 line
2.52.0
Re: [PATCH v6 4/4] iio: flow: add Sensirion SLF3S liquid flow sensor driver
Hello,
drivers/iio/flow/slf3s.c line 32
Quoted 3 lines · Wadim Mueller
drivers/iio/flow/slf3s.c new file +2
-0+#include <linux/i2c.h> +#include <linux/mod_devicetable.h>
<linux/i2c.h> already makes sure that of_device_id and i2c_device_id are available and <linux/mod_devicetable.h> will go away soon.
So please drop the latter #include.
Best regards
Uwe
Jonathan Cameron
maintainerRe: [PATCH v6 4/4] iio: flow: add Sensirion SLF3S liquid flow sensor driver
Quoted 9 lines · On Wed, 29 Jul 2026 14:21:15 +0200 Uwe Kleine-König…
Hello,
drivers/iio/flow/slf3s.c line 32
Quoted 3 lines · Wadim Mueller
drivers/iio/flow/slf3s.c new file +2
-0+#include <linux/i2c.h> +#include <linux/mod_devicetable.h> <
linux/i2c.h> already makes sure thatof_device_idandi2c_device_idare available and <linux/mod_devicetable.h> will go away soon.
I tidied this up whilst applying
Quoted 5 lines
So please drop the latter #include.
Best regards
Uwe
David Lechner
reviewerRe: [PATCH v6 4/4] iio: flow: add Sensirion SLF3S liquid flow sensor driver
In reply to Wadim MuellerQuoted 10 lines · Wadim Mueller
Add a driver for the Sensirion SLF3S family of digital liquid-flow sensors on I2C. Currently supported variants are SLF3S-0600F, SLF3S-1300F and SLF3S-4000B; they share the same register map and differ only in flow-scale factor and calibrated measurement range. The variant (and therefore the scale) is auto-detected from the product-information register at probe time; a sensor reporting an unknown sub-type falls back to the variant named in the device tree / I2C table, so a drop-in replacement part keeps working on a kernel that does not know its sub-type yet.
...
drivers/iio/flow/slf3s.c line 165
Quoted 11 lines
drivers/iio/flow/slf3s.c new file +11
-0+static bool slf3s_crc_valid (const struct slf3s_data *sf,const u8 *block) +{ +return crc8 (sf->crc_table, block,2 ,SLF3S_CRC8_INIT ) == block[2 ]; +} + +/* +* Read the product-info block and pick the matching variant. The +* sub-type byte returned by the sensor is the source of truth; a +* DT-supplied compatible only seeds an initial guess and is overridden +* on mismatch (with an informational message so misconfigured device +* trees are easy to spot).
In the past, Jonathan has always argued that the devicetree should be trusted more than what the device self-reports. This seems a departure from that. Why are we making an exception here?
We have to trust that the devicetree is correct for everything else that can't self-detect anyway.
Jonathan Cameron
maintainerRe: [PATCH v6 4/4] iio: flow: add Sensirion SLF3S liquid flow sensor driver
Quoted 30 lines · On Sun, 2 Aug 2026 11:07:27 -0500 David Lechner <[email protected]> wrote:
Quoted 10 lines · Wadim Mueller
Add a driver for the Sensirion SLF3S family of digital liquid-flow sensors on I2C. Currently supported variants are SLF3S-0600F, SLF3S-1300F and SLF3S-4000B; they share the same register map and differ only in flow-scale factor and calibrated measurement range. The variant (and therefore the scale) is auto-detected from the product-information register at probe time; a sensor reporting an unknown sub-type falls back to the variant named in the device tree / I2C table, so a drop-in replacement part keeps working on a kernel that does not know its sub-type yet.
...
drivers/iio/flow/slf3s.c line 165
Quoted 11 lines
drivers/iio/flow/slf3s.c new file +11
-0+static bool slf3s_crc_valid (const struct slf3s_data *sf,const u8 *block) +{ +return crc8 (sf->crc_table, block,2 ,SLF3S_CRC8_INIT ) == block[2 ]; +} + +/* +* Read the product-info block and pick the matching variant. The +* sub-type byte returned by the sensor is the source of truth; a +* DT-supplied compatible only seeds an initial guess and is overridden +* on mismatch (with an informational message so misconfigured device +* trees are easy to spot). In the past, Jonathan has always argued that the devicetree should be trusted more than what the device self-reports. This seems a departure from that. Why are we making an exception here?
Quoted 3 lines
We have to trust that the devicetree is correct for everything else that can't self-detect anyway.
Hi David
It's a slightly fuzzy boundary and I wouldn't ask anyone to spend effort adding support for detection of where it differs from what firmware reports. However, we have had a number of drivers do this in the past and as long as it has a fallback to just believe the DT if you don't have better info, I'm happy with this approach.
This is different from not believing firmware if the software has no reason to believe it is wrong - i.e. the fallback compatible thing.
Jonathan
Quoted 1 line
Jonathan Cameron
maintainerQuoted 5 lines · On Tue, 28 Jul 2026 23:49:39 +0200 Wadim Mueller <[email protected]> wrote:
Hi all,
this series adds a driver for the Sensirion SLF3S family of I2C liquid flow sensors (SLF3S-0600F / -1300F / -4000B) and a new
IIO_VOLUMEFLOWchannel type.
I'm going to apply this now, but as it will be in my testing branch (which I do rebase) for a few days fully welcome any additional comments or tags.
Applied to the testing branch of iio.git
Thanks,
Jonathan
Quoted 101 lines
First of all: sorry for the noise. Patch 4/4 of v5 never made it to the list or to patchwork - it got lost on the way out from the machine I sent v5 from, as Jonathan noticed:
https://lore.kernel.org/linux-iio/20260720032927.14fc4f9f@jic23-huawei/
So this v6 is mostly a resend of v5 with the driver patch actually included, plus the binding change we converged on in the meantime. The driver changes that were listed in the v5 changelog are repeated below, since nobody got to see them.
The series is based on iio.git testing, which already contains Rodrigo Alencar's IIO_VAL_DECIMAL64_* core formatting work; patch 3/4 adds the
IIO_VAL_DECIMAL64_FEMTOformat type on top of it.Changes since v5
----------------
* 4/4 is included this time - v5 only had 1-3 on the list
* dt-bindings: dropped the fallback compatible entirely; each variant now has its own compatible, per the conclusion of the v4 discussion between Krzysztof and Jonathan. Since the driver has to look at the product-information register anyway, a fallback buys nothing, while separate compatibles let a future drop-in part claim a known compatible and work on older kernels
* dt-bindings: dropped Krzysztof's Reviewed-by, since the compatible schema changed
* dt-bindings: commit message and example updated accordingly
* driver: reworded theslf3s_detect_variant()comment and the commit message, which referred to the now-gone fallback compatible. The behaviour is unchanged: an unknown sub-type still falls back to the variant named in the device tree / I2C table
* rebased onto current iio.git testingChanges since v4 (from the v5 posting, repeated because 4/4 was lost)
---------------------------------------------------------------------
* driver: includeerr.hforPTR_ERR()andmath.hfor structs32_fract, per Andy
* driver: fold the per-variant scale_num/scale_den pair into a structs32_fract, per Andy
* driver: add enumslf3s_variant_idand use it for the variant table and the I2C/OF match tables instead of bare indices, per Andy
* driver:slf3s_send_cmd(): drop the "at_least2" parameter annotation, decouple the ret assignment from its declaration and check errors first, per Andy
* driver: usesizeof()instead ofARRAY_SIZE()for the measurement byte buffer, per Andy
* driver: parenthesise the (FEMTO / MILLI) factor so it folds into a single constant multiplication, per Andy
* driver: derive the temperature scale fromMILLIDEGREE_PER_DEGREEinstead of a bare 1000, per Andy
* driver: checked the structslf3s_datalayout (re Andy's pahole question): the non-pointer members total 260 bytes, so one 4-byte hole remains for any member order; left as is
* driver: drop the inline comment on the mutex that duplicated the kernel-doc, per Jonathan (checkpatch still moans about it)
* driver: fix the duplicated argument in the DT/sensor variant mismatchdev_info(), per Jonathan
* driver: reformat the i2c_device_id/of_device_id tables to one member per line, per Jonathan
*MAINTAINERS: updated Maxwell's address in the R: entry to [email protected], as he requested on the v4 threadThe signaling-flags word (air-in-line / high-flow / smoothing status) in each measurement frame is intentionally not read; exposing it can be a later follow-up.
v5: https://lore.kernel.org/linux-iio/[email protected]/
v4: https://lore.kernel.org/linux-iio/[email protected]/Thanks,
WadimWadim Mueller (4):
iio: types: addIIO_VOLUMEFLOWchannel type
dt-bindings: iio: flow: add Sensirion SLF3S liquid flow sensor
iio: core: addIIO_VAL_DECIMAL64_FEMTOformat type
iio: flow: add Sensirion SLF3S liquid flow sensor driverDocumentation/ABI/testing/sysfs-bus-iio | 11 + Documentation/ABI/testing/sysfs-bus-iio-flow | 21 + .../bindings/iio/flow/sensirion,slf3s.yaml | 55 ++ MAINTAINERS | 8 + drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/flow/Kconfig | 22 + drivers/iio/flow/Makefile | 7 + drivers/iio/flow/slf3s.c | 543 ++++++++++++++++++ drivers/iio/industrialio-core.c | 3 + include/linux/iio/types.h | 1 + include/uapi/linux/iio/types.h | 1 + tools/iio/iio_event_monitor.c | 2 + 13 files changed, 676 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-flow create mode 100644 Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml create mode 100644 drivers/iio/flow/Kconfig create mode 100644 drivers/iio/flow/Makefile create mode 100644 drivers/iio/flow/slf3s.cbase-commit:
e0484d62e8e1cff75b210938be835ea6221bda59
Jonathan Cameron
maintainerQuoted 9 lines · On Sun, 2 Aug 2026 00:50:42 +0100 Jonathan Cameron <[email protected]> wrote:
Quoted 5 lines · On Tue, 28 Jul 2026 23:49:39 +0200 Wadim Mueller <[email protected]> wrote:
Hi all,
this series adds a driver for the Sensirion SLF3S family of I2C liquid flow sensors (SLF3S-0600F / -1300F / -4000B) and a new
IIO_VOLUMEFLOWchannel type.
Quoted 5 lines
I'm going to apply this now, but as it will be in my testing branch (which I do rebase) for a few days fully welcome any additional comments or tags.
Applied to the testing branch of iio.git
Tags updated and now pushed out as the togreg branch as well
Thanks,
J
Quoted 107 lines
Thanks,
Jonathan
Quoted 101 lines
First of all: sorry for the noise. Patch 4/4 of v5 never made it to the list or to patchwork - it got lost on the way out from the machine I sent v5 from, as Jonathan noticed:
https://lore.kernel.org/linux-iio/20260720032927.14fc4f9f@jic23-huawei/
So this v6 is mostly a resend of v5 with the driver patch actually included, plus the binding change we converged on in the meantime. The driver changes that were listed in the v5 changelog are repeated below, since nobody got to see them.
The series is based on iio.git testing, which already contains Rodrigo Alencar's IIO_VAL_DECIMAL64_* core formatting work; patch 3/4 adds the
IIO_VAL_DECIMAL64_FEMTOformat type on top of it.Changes since v5
----------------
* 4/4 is included this time - v5 only had 1-3 on the list
* dt-bindings: dropped the fallback compatible entirely; each variant now has its own compatible, per the conclusion of the v4 discussion between Krzysztof and Jonathan. Since the driver has to look at the product-information register anyway, a fallback buys nothing, while separate compatibles let a future drop-in part claim a known compatible and work on older kernels
* dt-bindings: dropped Krzysztof's Reviewed-by, since the compatible schema changed
* dt-bindings: commit message and example updated accordingly
* driver: reworded theslf3s_detect_variant()comment and the commit message, which referred to the now-gone fallback compatible. The behaviour is unchanged: an unknown sub-type still falls back to the variant named in the device tree / I2C table
* rebased onto current iio.git testingChanges since v4 (from the v5 posting, repeated because 4/4 was lost)
---------------------------------------------------------------------
* driver: includeerr.hforPTR_ERR()andmath.hfor structs32_fract, per Andy
* driver: fold the per-variant scale_num/scale_den pair into a structs32_fract, per Andy
* driver: add enumslf3s_variant_idand use it for the variant table and the I2C/OF match tables instead of bare indices, per Andy
* driver:slf3s_send_cmd(): drop the "at_least2" parameter annotation, decouple the ret assignment from its declaration and check errors first, per Andy
* driver: usesizeof()instead ofARRAY_SIZE()for the measurement byte buffer, per Andy
* driver: parenthesise the (FEMTO / MILLI) factor so it folds into a single constant multiplication, per Andy
* driver: derive the temperature scale fromMILLIDEGREE_PER_DEGREEinstead of a bare 1000, per Andy
* driver: checked the structslf3s_datalayout (re Andy's pahole question): the non-pointer members total 260 bytes, so one 4-byte hole remains for any member order; left as is
* driver: drop the inline comment on the mutex that duplicated the kernel-doc, per Jonathan (checkpatch still moans about it)
* driver: fix the duplicated argument in the DT/sensor variant mismatchdev_info(), per Jonathan
* driver: reformat the i2c_device_id/of_device_id tables to one member per line, per Jonathan
*MAINTAINERS: updated Maxwell's address in the R: entry to [email protected], as he requested on the v4 threadThe signaling-flags word (air-in-line / high-flow / smoothing status) in each measurement frame is intentionally not read; exposing it can be a later follow-up.
v5: https://lore.kernel.org/linux-iio/[email protected]/
v4: https://lore.kernel.org/linux-iio/[email protected]/Thanks,
WadimWadim Mueller (4):
iio: types: addIIO_VOLUMEFLOWchannel type
dt-bindings: iio: flow: add Sensirion SLF3S liquid flow sensor
iio: core: addIIO_VAL_DECIMAL64_FEMTOformat type
iio: flow: add Sensirion SLF3S liquid flow sensor driverDocumentation/ABI/testing/sysfs-bus-iio | 11 + Documentation/ABI/testing/sysfs-bus-iio-flow | 21 + .../bindings/iio/flow/sensirion,slf3s.yaml | 55 ++ MAINTAINERS | 8 + drivers/iio/Kconfig | 1 + drivers/iio/Makefile | 1 + drivers/iio/flow/Kconfig | 22 + drivers/iio/flow/Makefile | 7 + drivers/iio/flow/slf3s.c | 543 ++++++++++++++++++ drivers/iio/industrialio-core.c | 3 + include/linux/iio/types.h | 1 + include/uapi/linux/iio/types.h | 1 + tools/iio/iio_event_monitor.c | 2 + 13 files changed, 676 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-flow create mode 100644 Documentation/devicetree/bindings/iio/flow/sensirion,slf3s.yaml create mode 100644 drivers/iio/flow/Kconfig create mode 100644 drivers/iio/flow/Makefile create mode 100644 drivers/iio/flow/slf3s.cbase-commit:
e0484d62e8e1cff75b210938be835ea6221bda59