linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] iio: pressure: Add support for Honeywell HSC SPI sensors
@ 2018-10-26 18:14 Carlos Iglesias
  2018-10-26 18:14 ` [PATCH 1/2] dt-bindings: " Carlos Iglesias
  2018-10-26 18:14 ` [PATCH 2/2] " Carlos Iglesias
  0 siblings, 2 replies; 7+ messages in thread
From: Carlos Iglesias @ 2018-10-26 18:14 UTC (permalink / raw)
  To: linux-kernel, jic23, robh+dt, mark.rutland
  Cc: knaack.h, lars, pmeerw, linux-iio, devicetree, Dan O'Donovan,
	Carlos Iglesias

Hi all,

The Honeywell HSC is a series of pressure sensors that provide different
pressure ranges and measurement types (absolute, differential, gauge). The
available output types are analog, I2C or SPI (see [1]).

This driver provides support for a limited set of the HSC sensor models,
namely the absolute pressure sensors with SPI interface.

References:
[1] Datasheet https://sensing.honeywell.com/honeywell-sensing-trustability-hsc-series-high-accuracy-board-mount-pressure-sensors-50099148-a-en.pdf
[2] SPI Communications with Honeywell Digital Output Pressure Sensors https://sensing.honeywell.com/spi-comms-digital-ouptu-pressure-sensors-tn-008202-3-en-final-30may12.pdf

Carlos Iglesias (2):
  dt-bindings: iio: pressure: Add support for Honeywell HSC SPI sensors
  iio: pressure: Add support for Honeywell HSC SPI sensors

 .../bindings/iio/pressure/hsc_spi.txt         |  85 +++
 MAINTAINERS                                   |   6 +
 drivers/iio/pressure/Kconfig                  |  10 +
 drivers/iio/pressure/Makefile                 |   2 +
 drivers/iio/pressure/hsc_spi.c                | 543 ++++++++++++++++++
 5 files changed, 646 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
 create mode 100644 drivers/iio/pressure/hsc_spi.c

-- 
2.19.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] dt-bindings: iio: pressure: Add support for Honeywell HSC SPI sensors
  2018-10-26 18:14 [PATCH 0/2] iio: pressure: Add support for Honeywell HSC SPI sensors Carlos Iglesias
@ 2018-10-26 18:14 ` Carlos Iglesias
  2018-10-28 17:38   ` Jonathan Cameron
  2018-11-06 21:29   ` Rob Herring
  2018-10-26 18:14 ` [PATCH 2/2] " Carlos Iglesias
  1 sibling, 2 replies; 7+ messages in thread
From: Carlos Iglesias @ 2018-10-26 18:14 UTC (permalink / raw)
  To: linux-kernel, jic23, robh+dt, mark.rutland
  Cc: knaack.h, lars, pmeerw, linux-iio, devicetree, Dan O'Donovan,
	Carlos Iglesias

Add device tree bindings for the HSC pressure sensors.

Signed-off-by: Carlos Iglesias <carlos.iglesias@emutex.com>
---
 .../bindings/iio/pressure/hsc_spi.txt         | 85 +++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt

diff --git a/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt b/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
new file mode 100644
index 000000000000..2302d6eef7c7
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
@@ -0,0 +1,85 @@
+Honeywell HSC Series of Pressure Sensors
+
+Pressure sensors from Honeywell with analog, I2C and SPI interfaces
+
+Required properties:
+- compatible: selects the sensor model; must be one of the following
+	"honeywell,hsc001baa"
+	"honeywell,hsc001bab"
+	"honeywell,hsc001bac"
+	"honeywell,hsc001baf"
+	"honeywell,hsc1_6baa"
+	"honeywell,hsc1_6bab"
+	"honeywell,hsc1_6bac"
+	"honeywell,hsc1_6baf"
+	"honeywell,hsc2_5baa"
+	"honeywell,hsc2_5bab"
+	"honeywell,hsc2_5bac"
+	"honeywell,hsc2_5baf"
+	"honeywell,hsc004baa"
+	"honeywell,hsc004bab"
+	"honeywell,hsc004bac"
+	"honeywell,hsc004baf"
+	"honeywell,hsc006baa"
+	"honeywell,hsc006bab"
+	"honeywell,hsc006bac"
+	"honeywell,hsc006baf"
+	"honeywell,hsc010baa"
+	"honeywell,hsc010bab"
+	"honeywell,hsc010bac"
+	"honeywell,hsc010baf"
+	"honeywell,hsc100kaa"
+	"honeywell,hsc100kab"
+	"honeywell,hsc100kac"
+	"honeywell,hsc100kaf"
+	"honeywell,hsc160kaa"
+	"honeywell,hsc160kab"
+	"honeywell,hsc160kac"
+	"honeywell,hsc160kaf"
+	"honeywell,hsc250kaa"
+	"honeywell,hsc250kab"
+	"honeywell,hsc250kac"
+	"honeywell,hsc250kaf"
+	"honeywell,hsc400kaa"
+	"honeywell,hsc400kab"
+	"honeywell,hsc400kac"
+	"honeywell,hsc400kaf"
+	"honeywell,hsc600kaa"
+	"honeywell,hsc600kab"
+	"honeywell,hsc600kac"
+	"honeywell,hsc600kaf"
+	"honeywell,hsc001gaa"
+	"honeywell,hsc001gab"
+	"honeywell,hsc001gac"
+	"honeywell,hsc001gaf"
+	"honeywell,hsc015paa"
+	"honeywell,hsc015pab"
+	"honeywell,hsc015pac"
+	"honeywell,hsc015paf"
+	"honeywell,hsc030paa"
+	"honeywell,hsc030pab"
+	"honeywell,hsc030pac"
+	"honeywell,hsc030paf"
+	"honeywell,hsc060paa"
+	"honeywell,hsc060pab"
+	"honeywell,hsc060pac"
+	"honeywell,hsc060paf"
+	"honeywell,hsc100paa"
+	"honeywell,hsc100pab"
+	"honeywell,hsc100pac"
+	"honeywell,hsc100paf"
+	"honeywell,hsc150paa"
+	"honeywell,hsc150pab"
+	"honeywell,hsc150pac"
+	"honeywell,hsc150paf"
+- reg: the SPI chip select number used by the sensor.
+- spi-max-frequency: maximum clock frequency (Hz) used for the SPI bus.
+  The maximum value supported by the sensors is 400000.
+
+Example:
+
+	hsc_spi0: hsc@0 {
+		compatible = "honeywell,hsc010baa";
+		reg = <0>;
+		spi-max-frequency = <400000>;
+	};
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] iio: pressure: Add support for Honeywell HSC SPI sensors
  2018-10-26 18:14 [PATCH 0/2] iio: pressure: Add support for Honeywell HSC SPI sensors Carlos Iglesias
  2018-10-26 18:14 ` [PATCH 1/2] dt-bindings: " Carlos Iglesias
@ 2018-10-26 18:14 ` Carlos Iglesias
  2018-10-28 18:44   ` Jonathan Cameron
  1 sibling, 1 reply; 7+ messages in thread
From: Carlos Iglesias @ 2018-10-26 18:14 UTC (permalink / raw)
  To: linux-kernel, jic23, robh+dt, mark.rutland
  Cc: knaack.h, lars, pmeerw, linux-iio, devicetree, Dan O'Donovan,
	Carlos Iglesias

Add device driver for the HSC pressure sensors with SPI interface.
In addition to the main measurement -pressure- these sensors also
provide temperature measurement.

Signed-off-by: Carlos Iglesias <carlos.iglesias@emutex.com>
---
 MAINTAINERS                    |   6 +
 drivers/iio/pressure/Kconfig   |  10 +
 drivers/iio/pressure/Makefile  |   2 +
 drivers/iio/pressure/hsc_spi.c | 543 +++++++++++++++++++++++++++++++++
 4 files changed, 561 insertions(+)
 create mode 100644 drivers/iio/pressure/hsc_spi.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 556f902b3766..a4af4cbd4b0f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6696,6 +6696,12 @@ W:	http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
 S:	Maintained
 F:	fs/hpfs/
 
+HSC SERIES PRESSURE SENSORS
+M;	Carlos Iglesias <carlos.iglesias@emutex.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
+F:	drivers/iio/pressure/hsc_spi.c
+
 HSI SUBSYSTEM
 M:	Sebastian Reichel <sre@kernel.org>
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi.git
diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
index eaa7cfcb4c2a..593663d4ffa8 100644
--- a/drivers/iio/pressure/Kconfig
+++ b/drivers/iio/pressure/Kconfig
@@ -227,4 +227,14 @@ config ZPA2326_SPI
 	tristate
 	select REGMAP_SPI
 
+config HSC_SPI
+	tristate "Honeywell HSC pressure sensors (SPI)"
+	depends on SPI_MASTER
+	help
+	  Say yes here to build support for the Honeywell HSC range of
+	  pressure sensors (SPI interface only).
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called hsc_spi.
+
 endmenu
diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
index c2058d7b2f93..b1db2116e9f6 100644
--- a/drivers/iio/pressure/Makefile
+++ b/drivers/iio/pressure/Makefile
@@ -31,3 +31,5 @@ obj-$(CONFIG_ZPA2326_SPI) += zpa2326_spi.o
 
 obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o
 obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o
+
+obj-$(CONFIG_HSC_SPI) += hsc_spi.o
diff --git a/drivers/iio/pressure/hsc_spi.c b/drivers/iio/pressure/hsc_spi.c
new file mode 100644
index 000000000000..efe45a09da8f
--- /dev/null
+++ b/drivers/iio/pressure/hsc_spi.c
@@ -0,0 +1,543 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * hsc_spi.c - Driver for Honeywell HSC pressure sensors with
+ *             SPI interface
+ *
+ * Copyright (c) 2018 Carlos Iglesias <carlos.iglesias@emutex.com>
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/iio/iio.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/spi/spi.h>
+
+#define HSC_MAX_SPI_FREQ_HZ	400000
+
+#define HSC_TEMP_BITS		11
+#define HSC_PRESS_BITS		14
+#define HSC_TEMP_MASK		(0x7FF)
+#define HSC_TEMP_SHIFT		(5)
+
+#define HSC_STATUS_S0		BIT(14)
+#define HSC_STATUS_S1		BIT(15)
+#define HSC_STATUS_MSK		((HSC_STATUS_S0) | (HSC_STATUS_S1))
+#define HSC_STATUS_CMD		HSC_STATUS_S0
+#define HSC_STATUS_STALE	HSC_STATUS_S1
+#define HSC_STATUS_DIAG		((HSC_STATUS_S0) | (HSC_STATUS_S1))
+
+static inline int hsc_status_error(struct device dev, int val)
+{
+	int st_check = val & HSC_STATUS_MSK;
+
+	if (st_check) {
+		switch (st_check) {
+		case HSC_STATUS_CMD:
+			dev_warn(&dev, "%s:Device in COMMAND MODE\n",
+				 __func__);
+			return -EIO;
+		case HSC_STATUS_STALE:
+			dev_warn(&dev, "%s:Stale data - sampling too fast?\n",
+				 __func__);
+			return -EAGAIN;
+		case HSC_STATUS_DIAG:
+			dev_warn(&dev, "%s:Calibration signature changed\n",
+				 __func__);
+			return -EIO;
+		default:
+			dev_err(&dev, "%s:Invalid status code (%d)\n",
+				__func__, st_check);
+			return -EIO;
+		}
+	}
+
+	return 0;
+}
+
+enum hsc_variant {
+	/* Note: Only the absolute range sensors are supported */
+	HSC001BAA, HSC001BAB, HSC001BAC, HSC001BAF,
+	HSC1_6BAA, HSC1_6BAB, HSC1_6BAC, HSC1_6BAF,
+	HSC2_5BAA, HSC2_5BAB, HSC2_5BAC, HSC2_5BAF,
+	HSC004BAA, HSC004BAB, HSC004BAC, HSC004BAF,
+	HSC006BAA, HSC006BAB, HSC006BAC, HSC006BAF,
+	HSC010BAA, HSC010BAB, HSC010BAC, HSC010BAF,
+
+	HSC100KAA, HSC100KAB, HSC100KAC, HSC100KAF,
+	HSC160KAA, HSC160KAB, HSC160KAC, HSC160KAF,
+	HSC250KAA, HSC250KAB, HSC250KAC, HSC250KAF,
+	HSC400KAA, HSC400KAB, HSC400KAC, HSC400KAF,
+	HSC600KAA, HSC600KAB, HSC600KAC, HSC600KAF,
+	HSC001GAA, HSC001GAB, HSC001GAC, HSC001GAF,
+
+	HSC015PAA, HSC015PAB, HSC015PAC, HSC015PAF,
+	HSC030PAA, HSC030PAB, HSC030PAC, HSC030PAF,
+	HSC060PAA, HSC060PAB, HSC060PAC, HSC060PAF,
+	HSC100PAA, HSC100PAB, HSC100PAC, HSC100PAF,
+	HSC150PAA, HSC150PAB, HSC150PAC, HSC150PAF,
+};
+
+enum hsc_meas_channel {
+	HSC_CH_PRESSURE,
+	HSC_CH_TEMPERATURE
+};
+
+struct hsc_config {
+	int pmin;	/* Lower pressure limit */
+	int pmax;	/* Upper pressure limit */
+	int rmin;	/* Lower transfer function limit (%) */
+	int rmax;	/* Upper transfer function limit (%) */
+	int knum;	/* Pressure kPa conversion factor (numerator) */
+	int kden;	/* Pressure kPa conversion factor /denominator) */
+};
+
+struct hsc_fract_val {
+	int num;	/* numerator */
+	int den;	/* denominator */
+};
+
+struct hsc_state {
+	struct device *dev;
+	struct spi_device *spi_dev;
+	struct spi_transfer spi_xfer;
+	struct spi_message spi_msg;
+	__be16 rx_buf[2];
+
+	/* Model-dependent values */
+	struct hsc_fract_val scale;
+	struct hsc_fract_val offset;
+};
+
+#define HSC_CONFIG(_pmin, _pmax, _rmin, _rmax, _knum, _kden) {	\
+		.pmin = (_pmin),				\
+		.pmax = (_pmax),				\
+		.rmin = (_rmin),				\
+		.rmax = (_rmax),				\
+		.knum = (_knum),				\
+		.kden = (_kden),				\
+	}
+
+static struct hsc_config hsc_cfg[] = {
+	/* Absolute range, mbar */
+	[HSC001BAA] = HSC_CONFIG(0, 1000, 10, 90, 1, 10),
+	[HSC001BAB] = HSC_CONFIG(0, 1000, 5, 95, 1, 10),
+	[HSC001BAC] = HSC_CONFIG(0, 1000, 5, 85, 1, 10),
+	[HSC001BAF] = HSC_CONFIG(0, 1000, 4, 94, 1, 10),
+	[HSC1_6BAA] = HSC_CONFIG(0, 1600, 10, 90, 1, 10),
+	[HSC1_6BAB] = HSC_CONFIG(0, 1600, 5, 95, 1, 10),
+	[HSC1_6BAC] = HSC_CONFIG(0, 1600, 5, 85, 1, 10),
+	[HSC1_6BAF] = HSC_CONFIG(0, 1600, 4, 94, 1, 10),
+	[HSC2_5BAA] = HSC_CONFIG(0, 2500, 10, 90, 1, 10),
+	[HSC2_5BAB] = HSC_CONFIG(0, 2500, 5, 95, 1, 10),
+	[HSC2_5BAC] = HSC_CONFIG(0, 2500, 5, 85, 1, 10),
+	[HSC2_5BAF] = HSC_CONFIG(0, 2500, 4, 94, 1, 10),
+	[HSC004BAA] = HSC_CONFIG(0, 4000, 10, 90, 1, 10),
+	[HSC004BAB] = HSC_CONFIG(0, 4000, 5, 95, 1, 10),
+	[HSC004BAC] = HSC_CONFIG(0, 4000, 5, 85, 1, 10),
+	[HSC004BAF] = HSC_CONFIG(0, 4000, 4, 94, 1, 10),
+	[HSC006BAA] = HSC_CONFIG(0, 6000, 10, 90, 1, 10),
+	[HSC006BAB] = HSC_CONFIG(0, 6000, 5, 95, 1, 10),
+	[HSC006BAC] = HSC_CONFIG(0, 6000, 5, 85, 1, 10),
+	[HSC006BAF] = HSC_CONFIG(0, 6000, 4, 94, 1, 10),
+	[HSC010BAA] = HSC_CONFIG(0, 10000, 10, 90, 1, 10),
+	[HSC010BAB] = HSC_CONFIG(0, 10000, 5, 95, 1, 10),
+	[HSC010BAC] = HSC_CONFIG(0, 10000, 5, 85, 1, 10),
+	[HSC010BAF] = HSC_CONFIG(0, 10000, 4, 94, 1, 10),
+	/* Absolute range, kPa */
+	[HSC100KAA] = HSC_CONFIG(0, 100, 10, 90, 1, 1),
+	[HSC100KAB] = HSC_CONFIG(0, 100, 5, 95, 1, 1),
+	[HSC100KAC] = HSC_CONFIG(0, 100, 5, 85, 1, 1),
+	[HSC100KAF] = HSC_CONFIG(0, 100, 4, 94, 1, 1),
+	[HSC160KAA] = HSC_CONFIG(0, 160, 10, 90, 1, 1),
+	[HSC160KAB] = HSC_CONFIG(0, 160, 5, 95, 1, 1),
+	[HSC160KAC] = HSC_CONFIG(0, 160, 5, 85, 1, 1),
+	[HSC160KAF] = HSC_CONFIG(0, 160, 4, 94, 1, 1),
+	[HSC250KAA] = HSC_CONFIG(0, 250, 10, 90, 1, 1),
+	[HSC250KAB] = HSC_CONFIG(0, 250, 5, 95, 1, 1),
+	[HSC250KAC] = HSC_CONFIG(0, 250, 5, 85, 1, 1),
+	[HSC250KAF] = HSC_CONFIG(0, 250, 4, 94, 1, 1),
+	[HSC400KAA] = HSC_CONFIG(0, 400, 10, 90, 1, 1),
+	[HSC400KAB] = HSC_CONFIG(0, 400, 5, 95, 1, 1),
+	[HSC400KAC] = HSC_CONFIG(0, 400, 5, 85, 1, 1),
+	[HSC400KAF] = HSC_CONFIG(0, 400, 4, 94, 1, 1),
+	[HSC600KAA] = HSC_CONFIG(0, 600, 10, 90, 1, 1),
+	[HSC600KAB] = HSC_CONFIG(0, 600, 5, 95, 1, 1),
+	[HSC600KAC] = HSC_CONFIG(0, 600, 5, 85, 1, 1),
+	[HSC600KAF] = HSC_CONFIG(0, 600, 4, 94, 1, 1),
+	[HSC001GAA] = HSC_CONFIG(0, 1000, 10, 90, 1, 1),
+	[HSC001GAB] = HSC_CONFIG(0, 1000, 5, 95, 1, 1),
+	[HSC001GAC] = HSC_CONFIG(0, 1000, 5, 85, 1, 1),
+	[HSC001GAF] = HSC_CONFIG(0, 1000, 4, 94, 1, 1),
+	/* Absolute range, psi */
+	[HSC015PAA] = HSC_CONFIG(0, 15, 10, 90, 6895, 1000),
+	[HSC015PAB] = HSC_CONFIG(0, 15, 5, 95, 6895, 1000),
+	[HSC015PAC] = HSC_CONFIG(0, 15, 5, 85, 6895, 1000),
+	[HSC015PAF] = HSC_CONFIG(0, 15, 4, 94, 6895, 1000),
+	[HSC030PAA] = HSC_CONFIG(0, 30, 10, 90, 6895, 1000),
+	[HSC030PAB] = HSC_CONFIG(0, 30, 5, 95, 6895, 1000),
+	[HSC030PAC] = HSC_CONFIG(0, 30, 5, 85, 6895, 1000),
+	[HSC030PAF] = HSC_CONFIG(0, 30, 4, 94, 6895, 1000),
+	[HSC060PAA] = HSC_CONFIG(0, 60, 10, 90, 6895, 1000),
+	[HSC060PAB] = HSC_CONFIG(0, 60, 5, 95, 6895, 1000),
+	[HSC060PAC] = HSC_CONFIG(0, 60, 5, 85, 6895, 1000),
+	[HSC060PAF] = HSC_CONFIG(0, 60, 4, 94, 6895, 1000),
+	[HSC100PAA] = HSC_CONFIG(0, 100, 10, 90, 6895, 1000),
+	[HSC100PAB] = HSC_CONFIG(0, 100, 5, 95, 6895, 1000),
+	[HSC100PAC] = HSC_CONFIG(0, 100, 5, 85, 6895, 1000),
+	[HSC100PAF] = HSC_CONFIG(0, 100, 4, 94, 6895, 1000),
+	[HSC150PAA] = HSC_CONFIG(0, 150, 10, 90, 6895, 1000),
+	[HSC150PAB] = HSC_CONFIG(0, 150, 5, 95, 6895, 1000),
+	[HSC150PAC] = HSC_CONFIG(0, 150, 5, 85, 6895, 1000),
+	[HSC150PAF] = HSC_CONFIG(0, 150, 4, 94, 6895, 1000),
+};
+
+static const struct iio_chan_spec hsc_channels[] = {
+	{
+		.type = IIO_PRESSURE,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				      BIT(IIO_CHAN_INFO_OFFSET) |
+				      BIT(IIO_CHAN_INFO_SCALE),
+		.channel = HSC_CH_PRESSURE,
+		.scan_type = {
+			.sign = 'u',
+			.realbits = HSC_PRESS_BITS,
+			.storagebits = 16,
+			.shift = 0,
+			.endianness = IIO_BE,
+		}
+	},
+	{
+		.type = IIO_TEMP,
+		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+				      BIT(IIO_CHAN_INFO_OFFSET) |
+				      BIT(IIO_CHAN_INFO_SCALE),
+		.channel = HSC_CH_TEMPERATURE,
+		.scan_type = {
+			.sign = 'u',
+			.realbits = HSC_TEMP_BITS,
+			.storagebits = 16,
+			.shift = HSC_TEMP_SHIFT,
+			.endianness = IIO_BE,
+		}
+	}
+};
+
+static int hsc_get_pressure(struct hsc_state *state)
+{
+	int ret = 0;
+	int error;
+
+	state->spi_xfer.len = 2;
+	ret = spi_sync(state->spi_dev, &state->spi_msg);
+	if (ret)
+		return ret;
+
+	ret = be16_to_cpu(state->rx_buf[0]);
+
+	error = hsc_status_error(state->spi_dev->dev, ret);
+	if (error)
+		return error;
+
+	return ret;
+}
+
+static int hsc_get_temperature(struct hsc_state *state)
+{
+	int ret;
+	int error;
+
+	state->spi_xfer.len = 4;
+	ret = spi_sync(state->spi_dev, &state->spi_msg);
+	if (ret)
+		return ret;
+
+	ret = be16_to_cpu(state->rx_buf[0]);
+	error = hsc_status_error(state->spi_dev->dev, ret);
+	if (error)
+		return error;
+
+	ret = be16_to_cpu(state->rx_buf[1]);
+	ret = (ret >> HSC_TEMP_SHIFT) & HSC_TEMP_MASK;
+
+	return ret;
+}
+
+static int hsc_read_raw(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan, int *val,
+			int *val2, long mask)
+{
+	struct hsc_state *state = iio_priv(indio_dev);
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		switch (chan->channel) {
+		case HSC_CH_PRESSURE:
+			ret = hsc_get_pressure(state);
+			if (ret < 0)
+				break;
+			*val = ret;
+			ret = IIO_VAL_INT;
+			break;
+		case HSC_CH_TEMPERATURE:
+			ret = hsc_get_temperature(state);
+			if (ret < 0)
+				break;
+			*val = ret;
+			ret = IIO_VAL_INT;
+			break;
+		default:
+			ret = -EINVAL;
+			dev_err(state->dev,
+				"%s - IIO_CHAN_INFO_RAW-bad channel (%d)\n",
+				__func__, chan->channel);
+			break;
+		}
+		break;
+	case IIO_CHAN_INFO_OFFSET:
+		switch (chan->channel) {
+		case HSC_CH_PRESSURE:
+			*val = state->offset.num;
+			*val2 = state->offset.den;
+			ret = IIO_VAL_FRACTIONAL;
+			break;
+		case HSC_CH_TEMPERATURE:
+			*val = BIT(HSC_TEMP_BITS) - 1;
+			*val2 = -200 / 50;
+			ret = IIO_VAL_FRACTIONAL;
+			break;
+		default:
+			dev_err(state->dev,
+				"%s - IIO_CHAN_INFO_OFFSET-bad channel (%d)\n",
+				__func__, chan->channel);
+			ret = -EINVAL;
+			break;
+		}
+		break;
+	case IIO_CHAN_INFO_SCALE:
+		switch (chan->channel) {
+		case HSC_CH_PRESSURE:		/* output unit is kPa */
+			*val = state->scale.num;
+			*val2 = state->scale.den;
+			ret = IIO_VAL_FRACTIONAL;
+			break;
+		case HSC_CH_TEMPERATURE:  /* output unit is milli Celsius */
+			*val = 200 * 1000;
+			*val2 = BIT(HSC_TEMP_BITS) - 1;
+			ret = IIO_VAL_FRACTIONAL;
+			break;
+		default:
+			dev_err(state->dev,
+				"%s - IIO_CHAN_INFO_SCALE-bad channel (%d)\n",
+				__func__, chan->channel);
+			ret = -EINVAL;
+			break;
+		}
+		break;
+	default:
+		dev_err(state->dev, "%s - mask = %ld (INVALID)\n",
+			__func__, mask);
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+static const struct iio_info hsc_info = {
+	.read_raw = hsc_read_raw,
+};
+
+static void hsc_init_device(struct iio_dev *indio_dev)
+{
+	struct hsc_state *state = iio_priv(indio_dev);
+	const struct hsc_config *cfg = of_device_get_match_data(state->dev);
+
+	/* Pressure offset value */
+	state->offset.num = BIT(HSC_PRESS_BITS) *
+			    (cfg->pmin * cfg->rmax - cfg->pmax * cfg->rmin);
+	state->offset.den = 100 * (cfg->pmax - cfg->pmin);
+
+	/* Pressure scale value */
+	state->scale.num = 100 * cfg->knum * (cfg->pmax - cfg->pmin);
+	state->scale.den = BIT(HSC_PRESS_BITS) *
+			   cfg->kden * (cfg->rmax - cfg->rmin);
+}
+
+static int hsc_spi_probe(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct hsc_state *state;
+	struct iio_dev *indio_dev;
+	int ret;
+
+	if (spi->max_speed_hz > HSC_MAX_SPI_FREQ_HZ) {
+		dev_warn(dev, "SPI CLK, %d Hz exceeds %d Hz - changed to max\n",
+			spi->max_speed_hz,
+			HSC_MAX_SPI_FREQ_HZ);
+		spi->max_speed_hz = HSC_MAX_SPI_FREQ_HZ;
+	}
+
+	spi->bits_per_word = 8;
+	spi->mode = SPI_MODE_0;
+
+	ret = spi_setup(spi);
+	if (ret < 0) {
+		dev_err(dev, "%s - Error in spi_setup()\n", __func__);
+		return ret;
+	}
+
+	indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
+	if (!indio_dev) {
+		dev_err(dev, "%s - Error allocating iio_device\n", __func__);
+		return -ENOMEM;
+	}
+
+	state = iio_priv(indio_dev);
+	spi_set_drvdata(spi, state);
+	state->spi_dev = spi;
+	state->dev = dev;
+
+	indio_dev->dev.parent = dev;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->info = &hsc_info;
+	indio_dev->channels = hsc_channels;
+	indio_dev->num_channels = ARRAY_SIZE(hsc_channels);
+
+	state->spi_xfer.rx_buf = &state->rx_buf[0];
+	state->spi_xfer.tx_buf = NULL;
+	state->spi_xfer.cs_change = 0;
+	spi_message_init(&state->spi_msg);
+	spi_message_add_tail(&state->spi_xfer, &state->spi_msg);
+
+	hsc_init_device(indio_dev);
+
+	ret = iio_device_register(indio_dev);
+	if (ret < 0)
+		dev_err(dev, "iio_device_register failed: %d\n", ret);
+
+	dev_dbg(dev, "%s - scale = %d/%d, offset = %d/%d\n", __func__,
+		state->scale.num, state->scale.den,
+		state->offset.num, state->offset.den);
+
+	return ret;
+}
+
+static int hsc_spi_remove(struct spi_device *spi)
+{
+	struct device *dev = &spi->dev;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
+	iio_device_unregister(indio_dev);
+
+	return 0;
+}
+
+static const struct of_device_id hsc_of_match[] = {
+	{ .compatible = "honeywell,hsc001baa", .data = &hsc_cfg[HSC001BAA] },
+	{ .compatible = "honeywell,hsc001bab", .data = &hsc_cfg[HSC001BAB] },
+	{ .compatible = "honeywell,hsc001bac", .data = &hsc_cfg[HSC001BAC] },
+	{ .compatible = "honeywell,hsc001baf", .data = &hsc_cfg[HSC001BAF] },
+
+	{ .compatible = "honeywell,hsc1_6baa", .data = &hsc_cfg[HSC1_6BAA] },
+	{ .compatible = "honeywell,hsc1_6bab", .data = &hsc_cfg[HSC1_6BAB] },
+	{ .compatible = "honeywell,hsc1_6bac", .data = &hsc_cfg[HSC1_6BAC] },
+	{ .compatible = "honeywell,hsc1_6baf", .data = &hsc_cfg[HSC1_6BAF] },
+
+	{ .compatible = "honeywell,hsc2_5baa", .data = &hsc_cfg[HSC2_5BAA] },
+	{ .compatible = "honeywell,hsc2_5bab", .data = &hsc_cfg[HSC2_5BAB] },
+	{ .compatible = "honeywell,hsc2_5bac", .data = &hsc_cfg[HSC2_5BAC] },
+	{ .compatible = "honeywell,hsc2_5baf", .data = &hsc_cfg[HSC2_5BAF] },
+
+	{ .compatible = "honeywell,hsc004baa", .data = &hsc_cfg[HSC004BAA] },
+	{ .compatible = "honeywell,hsc004bab", .data = &hsc_cfg[HSC004BAB] },
+	{ .compatible = "honeywell,hsc004bac", .data = &hsc_cfg[HSC004BAC] },
+	{ .compatible = "honeywell,hsc004baf", .data = &hsc_cfg[HSC004BAF] },
+
+	{ .compatible = "honeywell,hsc006baa", .data = &hsc_cfg[HSC006BAA] },
+	{ .compatible = "honeywell,hsc006bab", .data = &hsc_cfg[HSC006BAB] },
+	{ .compatible = "honeywell,hsc006bac", .data = &hsc_cfg[HSC006BAC] },
+	{ .compatible = "honeywell,hsc006baf", .data = &hsc_cfg[HSC006BAF] },
+
+	{ .compatible = "honeywell,hsc010baa", .data = &hsc_cfg[HSC010BAA] },
+	{ .compatible = "honeywell,hsc010bab", .data = &hsc_cfg[HSC010BAB] },
+	{ .compatible = "honeywell,hsc010bac", .data = &hsc_cfg[HSC010BAC] },
+	{ .compatible = "honeywell,hsc010baf", .data = &hsc_cfg[HSC010BAF] },
+
+	{ .compatible = "honeywell,hsc100kaa", .data = &hsc_cfg[HSC100KAA] },
+	{ .compatible = "honeywell,hsc100kab", .data = &hsc_cfg[HSC100KAB] },
+	{ .compatible = "honeywell,hsc100kac", .data = &hsc_cfg[HSC100KAC] },
+	{ .compatible = "honeywell,hsc100kaf", .data = &hsc_cfg[HSC100KAF] },
+
+	{ .compatible = "honeywell,hsc160kaa", .data = &hsc_cfg[HSC160KAA] },
+	{ .compatible = "honeywell,hsc160kab", .data = &hsc_cfg[HSC160KAB] },
+	{ .compatible = "honeywell,hsc160kac", .data = &hsc_cfg[HSC160KAC] },
+	{ .compatible = "honeywell,hsc160kaf", .data = &hsc_cfg[HSC160KAF] },
+
+	{ .compatible = "honeywell,hsc250kaa", .data = &hsc_cfg[HSC250KAA] },
+	{ .compatible = "honeywell,hsc250kab", .data = &hsc_cfg[HSC250KAB] },
+	{ .compatible = "honeywell,hsc250kac", .data = &hsc_cfg[HSC250KAC] },
+	{ .compatible = "honeywell,hsc250kaf", .data = &hsc_cfg[HSC250KAF] },
+
+	{ .compatible = "honeywell,hsc400kaa", .data = &hsc_cfg[HSC400KAA] },
+	{ .compatible = "honeywell,hsc400kab", .data = &hsc_cfg[HSC400KAB] },
+	{ .compatible = "honeywell,hsc400kac", .data = &hsc_cfg[HSC400KAC] },
+	{ .compatible = "honeywell,hsc400kaf", .data = &hsc_cfg[HSC400KAF] },
+
+	{ .compatible = "honeywell,hsc600kaa", .data = &hsc_cfg[HSC600KAA] },
+	{ .compatible = "honeywell,hsc600kab", .data = &hsc_cfg[HSC600KAB] },
+	{ .compatible = "honeywell,hsc600kac", .data = &hsc_cfg[HSC600KAC] },
+	{ .compatible = "honeywell,hsc600kaf", .data = &hsc_cfg[HSC600KAF] },
+
+	{ .compatible = "honeywell,hsc001gaa", .data = &hsc_cfg[HSC001GAA] },
+	{ .compatible = "honeywell,hsc001gab", .data = &hsc_cfg[HSC001GAB] },
+	{ .compatible = "honeywell,hsc001gac", .data = &hsc_cfg[HSC001GAC] },
+	{ .compatible = "honeywell,hsc001gaf", .data = &hsc_cfg[HSC001GAF] },
+
+	{ .compatible = "honeywell,hsc015paa", .data = &hsc_cfg[HSC015PAA] },
+	{ .compatible = "honeywell,hsc015pab", .data = &hsc_cfg[HSC015PAB] },
+	{ .compatible = "honeywell,hsc015pac", .data = &hsc_cfg[HSC015PAC] },
+	{ .compatible = "honeywell,hsc015paf", .data = &hsc_cfg[HSC015PAF] },
+
+	{ .compatible = "honeywell,hsc030paa", .data = &hsc_cfg[HSC030PAA] },
+	{ .compatible = "honeywell,hsc030pab", .data = &hsc_cfg[HSC030PAB] },
+	{ .compatible = "honeywell,hsc030pac", .data = &hsc_cfg[HSC030PAC] },
+	{ .compatible = "honeywell,hsc030paf", .data = &hsc_cfg[HSC030PAF] },
+
+	{ .compatible = "honeywell,hsc060paa", .data = &hsc_cfg[HSC060PAA] },
+	{ .compatible = "honeywell,hsc060pab", .data = &hsc_cfg[HSC060PAB] },
+	{ .compatible = "honeywell,hsc060pac", .data = &hsc_cfg[HSC060PAC] },
+	{ .compatible = "honeywell,hsc060paf", .data = &hsc_cfg[HSC060PAF] },
+
+	{ .compatible = "honeywell,hsc100paa", .data = &hsc_cfg[HSC100PAA] },
+	{ .compatible = "honeywell,hsc100pab", .data = &hsc_cfg[HSC100PAB] },
+	{ .compatible = "honeywell,hsc100pac", .data = &hsc_cfg[HSC100PAC] },
+	{ .compatible = "honeywell,hsc100paf", .data = &hsc_cfg[HSC100PAF] },
+
+	{ .compatible = "honeywell,hsc150paa", .data = &hsc_cfg[HSC150PAA] },
+	{ .compatible = "honeywell,hsc150pab", .data = &hsc_cfg[HSC150PAB] },
+	{ .compatible = "honeywell,hsc150pac", .data = &hsc_cfg[HSC150PAC] },
+	{ .compatible = "honeywell,hsc150paf", .data = &hsc_cfg[HSC150PAF] },
+
+	{ },
+};
+MODULE_DEVICE_TABLE(of, hsc_of_match);
+
+static struct spi_driver hsc_spi_driver = {
+	.probe = hsc_spi_probe,
+	.remove = hsc_spi_remove,
+	.driver = {
+		.name = "hsc_spi_pressure_sensor",
+		.of_match_table = hsc_of_match,
+	},
+};
+
+module_spi_driver(hsc_spi_driver);
+
+MODULE_AUTHOR("Carlos Iglesias <carlosiglesias@emutex.com>");
+MODULE_DESCRIPTION("Honeywell HSC SPI pressure sensor driver");
+MODULE_LICENSE("GPL v2");
-- 
2.19.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] dt-bindings: iio: pressure: Add support for Honeywell HSC SPI sensors
  2018-10-26 18:14 ` [PATCH 1/2] dt-bindings: " Carlos Iglesias
@ 2018-10-28 17:38   ` Jonathan Cameron
       [not found]     ` <0dbb2254-8035-b498-6302-26bc3a2219ca@emutex.com>
  2018-11-06 21:29   ` Rob Herring
  1 sibling, 1 reply; 7+ messages in thread
From: Jonathan Cameron @ 2018-10-28 17:38 UTC (permalink / raw)
  To: Carlos Iglesias
  Cc: linux-kernel, robh+dt, mark.rutland, knaack.h, lars, pmeerw,
	linux-iio, devicetree, Dan O'Donovan

On Fri, 26 Oct 2018 18:14:36 +0000
Carlos Iglesias <carlos.iglesias@emutex.com> wrote:

> Add device tree bindings for the HSC pressure sensors.
> 
> Signed-off-by: Carlos Iglesias <carlos.iglesias@emutex.com>
> ---
>  .../bindings/iio/pressure/hsc_spi.txt         | 85 +++++++++++++++++++
>  1 file changed, 85 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> 
> diff --git a/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt b/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> new file mode 100644
> index 000000000000..2302d6eef7c7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> @@ -0,0 +1,85 @@
> +Honeywell HSC Series of Pressure Sensors
> +
> +Pressure sensors from Honeywell with analog, I2C and SPI interfaces
> +
> +Required properties:
> +- compatible: selects the sensor model; must be one of the following
> +	"honeywell,hsc001baa"
> +	"honeywell,hsc001bab"
> +	"honeywell,hsc001bac"
> +	"honeywell,hsc001baf"
> +	"honeywell,hsc1_6baa"
> +	"honeywell,hsc1_6bab"
> +	"honeywell,hsc1_6bac"
> +	"honeywell,hsc1_6baf"
> +	"honeywell,hsc2_5baa"
> +	"honeywell,hsc2_5bab"
> +	"honeywell,hsc2_5bac"
> +	"honeywell,hsc2_5baf"
> +	"honeywell,hsc004baa"
> +	"honeywell,hsc004bab"
> +	"honeywell,hsc004bac"
> +	"honeywell,hsc004baf"
> +	"honeywell,hsc006baa"
> +	"honeywell,hsc006bab"
> +	"honeywell,hsc006bac"
> +	"honeywell,hsc006baf"
> +	"honeywell,hsc010baa"
> +	"honeywell,hsc010bab"
> +	"honeywell,hsc010bac"
> +	"honeywell,hsc010baf"
> +	"honeywell,hsc100kaa"
> +	"honeywell,hsc100kab"
> +	"honeywell,hsc100kac"
> +	"honeywell,hsc100kaf"
> +	"honeywell,hsc160kaa"
> +	"honeywell,hsc160kab"
> +	"honeywell,hsc160kac"
> +	"honeywell,hsc160kaf"
> +	"honeywell,hsc250kaa"
> +	"honeywell,hsc250kab"
> +	"honeywell,hsc250kac"
> +	"honeywell,hsc250kaf"
> +	"honeywell,hsc400kaa"
> +	"honeywell,hsc400kab"
> +	"honeywell,hsc400kac"
> +	"honeywell,hsc400kaf"
> +	"honeywell,hsc600kaa"
> +	"honeywell,hsc600kab"
> +	"honeywell,hsc600kac"
> +	"honeywell,hsc600kaf"
> +	"honeywell,hsc001gaa"
> +	"honeywell,hsc001gab"
> +	"honeywell,hsc001gac"
> +	"honeywell,hsc001gaf"
> +	"honeywell,hsc015paa"
> +	"honeywell,hsc015pab"
> +	"honeywell,hsc015pac"
> +	"honeywell,hsc015paf"
> +	"honeywell,hsc030paa"
> +	"honeywell,hsc030pab"
> +	"honeywell,hsc030pac"
> +	"honeywell,hsc030paf"
> +	"honeywell,hsc060paa"
> +	"honeywell,hsc060pab"
> +	"honeywell,hsc060pac"
> +	"honeywell,hsc060paf"
> +	"honeywell,hsc100paa"
> +	"honeywell,hsc100pab"
> +	"honeywell,hsc100pac"
> +	"honeywell,hsc100paf"
> +	"honeywell,hsc150paa"
> +	"honeywell,hsc150pab"
> +	"honeywell,hsc150pac"
> +	"honeywell,hsc150paf"
> +- reg: the SPI chip select number used by the sensor.
> +- spi-max-frequency: maximum clock frequency (Hz) used for the SPI bus.
> +  The maximum value supported by the sensors is 400000.
As Rob pointed out in a few reviews this week, the devicetree binding
for this should only be applying a tighter bound than either the
device or the bus master. So something introduced by the board
layout for example, or a level convertor..

Jonathan
> +
> +Example:
> +
> +	hsc_spi0: hsc@0 {
> +		compatible = "honeywell,hsc010baa";
> +		reg = <0>;
> +		spi-max-frequency = <400000>;
> +	};


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] iio: pressure: Add support for Honeywell HSC SPI sensors
  2018-10-26 18:14 ` [PATCH 2/2] " Carlos Iglesias
@ 2018-10-28 18:44   ` Jonathan Cameron
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cameron @ 2018-10-28 18:44 UTC (permalink / raw)
  To: Carlos Iglesias
  Cc: linux-kernel, robh+dt, mark.rutland, knaack.h, lars, pmeerw,
	linux-iio, devicetree, Dan O'Donovan

On Fri, 26 Oct 2018 18:14:37 +0000
Carlos Iglesias <carlos.iglesias@emutex.com> wrote:

> Add device driver for the HSC pressure sensors with SPI interface.
> In addition to the main measurement -pressure- these sensors also
> provide temperature measurement.
> 
> Signed-off-by: Carlos Iglesias <carlos.iglesias@emutex.com>

Hi Carlos,

A few minor things inline.  Note that the spi buffer isn't currently
dma safe which may result in some really hard to find bugs (I've chased
these in the past and they can be really rare and tricky to track down!)

Jonathan
> ---
>  MAINTAINERS                    |   6 +
>  drivers/iio/pressure/Kconfig   |  10 +
>  drivers/iio/pressure/Makefile  |   2 +
>  drivers/iio/pressure/hsc_spi.c | 543 +++++++++++++++++++++++++++++++++
>  4 files changed, 561 insertions(+)
>  create mode 100644 drivers/iio/pressure/hsc_spi.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 556f902b3766..a4af4cbd4b0f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6696,6 +6696,12 @@ W:	http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi
>  S:	Maintained
>  F:	fs/hpfs/
>  
> +HSC SERIES PRESSURE SENSORS
> +M;	Carlos Iglesias <carlos.iglesias@emutex.com>
> +S:	Maintained
> +F:	Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> +F:	drivers/iio/pressure/hsc_spi.c
> +
>  HSI SUBSYSTEM
>  M:	Sebastian Reichel <sre@kernel.org>
>  T:	git git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-hsi.git
> diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
> index eaa7cfcb4c2a..593663d4ffa8 100644
> --- a/drivers/iio/pressure/Kconfig
> +++ b/drivers/iio/pressure/Kconfig
> @@ -227,4 +227,14 @@ config ZPA2326_SPI
>  	tristate
>  	select REGMAP_SPI
>  
> +config HSC_SPI
> +	tristate "Honeywell HSC pressure sensors (SPI)"
> +	depends on SPI_MASTER
> +	help
> +	  Say yes here to build support for the Honeywell HSC range of
> +	  pressure sensors (SPI interface only).
> +
> +	  To compile this driver as a module, choose M here: the module will
> +	  be called hsc_spi.
> +
>  endmenu
> diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
> index c2058d7b2f93..b1db2116e9f6 100644
> --- a/drivers/iio/pressure/Makefile
> +++ b/drivers/iio/pressure/Makefile
> @@ -31,3 +31,5 @@ obj-$(CONFIG_ZPA2326_SPI) += zpa2326_spi.o
>  
>  obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o
>  obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o
> +
> +obj-$(CONFIG_HSC_SPI) += hsc_spi.o
> diff --git a/drivers/iio/pressure/hsc_spi.c b/drivers/iio/pressure/hsc_spi.c
> new file mode 100644
> index 000000000000..efe45a09da8f
> --- /dev/null
> +++ b/drivers/iio/pressure/hsc_spi.c
> @@ -0,0 +1,543 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * hsc_spi.c - Driver for Honeywell HSC pressure sensors with
> + *             SPI interface
> + *
> + * Copyright (c) 2018 Carlos Iglesias <carlos.iglesias@emutex.com>
> + */
> +
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/iio/iio.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of_platform.h>
> +#include <linux/spi/spi.h>
> +
> +#define HSC_MAX_SPI_FREQ_HZ	400000
> +
> +#define HSC_TEMP_BITS		11
> +#define HSC_PRESS_BITS		14
> +#define HSC_TEMP_MASK		(0x7FF)
> +#define HSC_TEMP_SHIFT		(5)
> +
> +#define HSC_STATUS_S0		BIT(14)
> +#define HSC_STATUS_S1		BIT(15)
> +#define HSC_STATUS_MSK		((HSC_STATUS_S0) | (HSC_STATUS_S1))
> +#define HSC_STATUS_CMD		HSC_STATUS_S0
> +#define HSC_STATUS_STALE	HSC_STATUS_S1
> +#define HSC_STATUS_DIAG		((HSC_STATUS_S0) | (HSC_STATUS_S1))
> +
> +static inline int hsc_status_error(struct device dev, int val)
> +{
> +	int st_check = val & HSC_STATUS_MSK;
> +
> +	if (st_check) {
> +		switch (st_check) {
> +		case HSC_STATUS_CMD:
> +			dev_warn(&dev, "%s:Device in COMMAND MODE\n",
> +				 __func__);
> +			return -EIO;
> +		case HSC_STATUS_STALE:
> +			dev_warn(&dev, "%s:Stale data - sampling too fast?\n",
> +				 __func__);
> +			return -EAGAIN;
> +		case HSC_STATUS_DIAG:
> +			dev_warn(&dev, "%s:Calibration signature changed\n",
> +				 __func__);
> +			return -EIO;
> +		default:
> +			dev_err(&dev, "%s:Invalid status code (%d)\n",
> +				__func__, st_check);
> +			return -EIO;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +enum hsc_variant {
> +	/* Note: Only the absolute range sensors are supported */
> +	HSC001BAA, HSC001BAB, HSC001BAC, HSC001BAF,
> +	HSC1_6BAA, HSC1_6BAB, HSC1_6BAC, HSC1_6BAF,
> +	HSC2_5BAA, HSC2_5BAB, HSC2_5BAC, HSC2_5BAF,
> +	HSC004BAA, HSC004BAB, HSC004BAC, HSC004BAF,
> +	HSC006BAA, HSC006BAB, HSC006BAC, HSC006BAF,
> +	HSC010BAA, HSC010BAB, HSC010BAC, HSC010BAF,
> +
> +	HSC100KAA, HSC100KAB, HSC100KAC, HSC100KAF,
> +	HSC160KAA, HSC160KAB, HSC160KAC, HSC160KAF,
> +	HSC250KAA, HSC250KAB, HSC250KAC, HSC250KAF,
> +	HSC400KAA, HSC400KAB, HSC400KAC, HSC400KAF,
> +	HSC600KAA, HSC600KAB, HSC600KAC, HSC600KAF,
> +	HSC001GAA, HSC001GAB, HSC001GAC, HSC001GAF,
> +
> +	HSC015PAA, HSC015PAB, HSC015PAC, HSC015PAF,
> +	HSC030PAA, HSC030PAB, HSC030PAC, HSC030PAF,
> +	HSC060PAA, HSC060PAB, HSC060PAC, HSC060PAF,
> +	HSC100PAA, HSC100PAB, HSC100PAC, HSC100PAF,
> +	HSC150PAA, HSC150PAB, HSC150PAC, HSC150PAF,
> +};
> +
> +enum hsc_meas_channel {
> +	HSC_CH_PRESSURE,
> +	HSC_CH_TEMPERATURE
> +};
> +
> +struct hsc_config {
> +	int pmin;	/* Lower pressure limit */
> +	int pmax;	/* Upper pressure limit */
> +	int rmin;	/* Lower transfer function limit (%) */
> +	int rmax;	/* Upper transfer function limit (%) */
> +	int knum;	/* Pressure kPa conversion factor (numerator) */
> +	int kden;	/* Pressure kPa conversion factor /denominator) */
> +};
> +
> +struct hsc_fract_val {
> +	int num;	/* numerator */
> +	int den;	/* denominator */
> +};
> +
> +struct hsc_state {
> +	struct device *dev;
> +	struct spi_device *spi_dev;
> +	struct spi_transfer spi_xfer;
> +	struct spi_message spi_msg;
> +	__be16 rx_buf[2];
This is not a safe buffer for DMA as it shares its cacheline with other data.
Easiest option is to put it at the end of this structure and mark it
__cacheline_aligned.

We make sure that the private data is always appropriately aligned to allow
this to work.
> +
> +	/* Model-dependent values */
> +	struct hsc_fract_val scale;
> +	struct hsc_fract_val offset;
> +};
> +
> +#define HSC_CONFIG(_pmin, _pmax, _rmin, _rmax, _knum, _kden) {	\
> +		.pmin = (_pmin),				\
> +		.pmax = (_pmax),				\
> +		.rmin = (_rmin),				\
> +		.rmax = (_rmax),				\
> +		.knum = (_knum),				\
> +		.kden = (_kden),				\
> +	}
> +
> +static struct hsc_config hsc_cfg[] = {
> +	/* Absolute range, mbar */
> +	[HSC001BAA] = HSC_CONFIG(0, 1000, 10, 90, 1, 10),
> +	[HSC001BAB] = HSC_CONFIG(0, 1000, 5, 95, 1, 10),
> +	[HSC001BAC] = HSC_CONFIG(0, 1000, 5, 85, 1, 10),
> +	[HSC001BAF] = HSC_CONFIG(0, 1000, 4, 94, 1, 10),
> +	[HSC1_6BAA] = HSC_CONFIG(0, 1600, 10, 90, 1, 10),
> +	[HSC1_6BAB] = HSC_CONFIG(0, 1600, 5, 95, 1, 10),
> +	[HSC1_6BAC] = HSC_CONFIG(0, 1600, 5, 85, 1, 10),
> +	[HSC1_6BAF] = HSC_CONFIG(0, 1600, 4, 94, 1, 10),
> +	[HSC2_5BAA] = HSC_CONFIG(0, 2500, 10, 90, 1, 10),
> +	[HSC2_5BAB] = HSC_CONFIG(0, 2500, 5, 95, 1, 10),
> +	[HSC2_5BAC] = HSC_CONFIG(0, 2500, 5, 85, 1, 10),
> +	[HSC2_5BAF] = HSC_CONFIG(0, 2500, 4, 94, 1, 10),
> +	[HSC004BAA] = HSC_CONFIG(0, 4000, 10, 90, 1, 10),
> +	[HSC004BAB] = HSC_CONFIG(0, 4000, 5, 95, 1, 10),
> +	[HSC004BAC] = HSC_CONFIG(0, 4000, 5, 85, 1, 10),
> +	[HSC004BAF] = HSC_CONFIG(0, 4000, 4, 94, 1, 10),
> +	[HSC006BAA] = HSC_CONFIG(0, 6000, 10, 90, 1, 10),
> +	[HSC006BAB] = HSC_CONFIG(0, 6000, 5, 95, 1, 10),
> +	[HSC006BAC] = HSC_CONFIG(0, 6000, 5, 85, 1, 10),
> +	[HSC006BAF] = HSC_CONFIG(0, 6000, 4, 94, 1, 10),
> +	[HSC010BAA] = HSC_CONFIG(0, 10000, 10, 90, 1, 10),
> +	[HSC010BAB] = HSC_CONFIG(0, 10000, 5, 95, 1, 10),
> +	[HSC010BAC] = HSC_CONFIG(0, 10000, 5, 85, 1, 10),
> +	[HSC010BAF] = HSC_CONFIG(0, 10000, 4, 94, 1, 10),
> +	/* Absolute range, kPa */
> +	[HSC100KAA] = HSC_CONFIG(0, 100, 10, 90, 1, 1),
> +	[HSC100KAB] = HSC_CONFIG(0, 100, 5, 95, 1, 1),
> +	[HSC100KAC] = HSC_CONFIG(0, 100, 5, 85, 1, 1),
> +	[HSC100KAF] = HSC_CONFIG(0, 100, 4, 94, 1, 1),
> +	[HSC160KAA] = HSC_CONFIG(0, 160, 10, 90, 1, 1),
> +	[HSC160KAB] = HSC_CONFIG(0, 160, 5, 95, 1, 1),
> +	[HSC160KAC] = HSC_CONFIG(0, 160, 5, 85, 1, 1),
> +	[HSC160KAF] = HSC_CONFIG(0, 160, 4, 94, 1, 1),
> +	[HSC250KAA] = HSC_CONFIG(0, 250, 10, 90, 1, 1),
> +	[HSC250KAB] = HSC_CONFIG(0, 250, 5, 95, 1, 1),
> +	[HSC250KAC] = HSC_CONFIG(0, 250, 5, 85, 1, 1),
> +	[HSC250KAF] = HSC_CONFIG(0, 250, 4, 94, 1, 1),
> +	[HSC400KAA] = HSC_CONFIG(0, 400, 10, 90, 1, 1),
> +	[HSC400KAB] = HSC_CONFIG(0, 400, 5, 95, 1, 1),
> +	[HSC400KAC] = HSC_CONFIG(0, 400, 5, 85, 1, 1),
> +	[HSC400KAF] = HSC_CONFIG(0, 400, 4, 94, 1, 1),
> +	[HSC600KAA] = HSC_CONFIG(0, 600, 10, 90, 1, 1),
> +	[HSC600KAB] = HSC_CONFIG(0, 600, 5, 95, 1, 1),
> +	[HSC600KAC] = HSC_CONFIG(0, 600, 5, 85, 1, 1),
> +	[HSC600KAF] = HSC_CONFIG(0, 600, 4, 94, 1, 1),
> +	[HSC001GAA] = HSC_CONFIG(0, 1000, 10, 90, 1, 1),
> +	[HSC001GAB] = HSC_CONFIG(0, 1000, 5, 95, 1, 1),
> +	[HSC001GAC] = HSC_CONFIG(0, 1000, 5, 85, 1, 1),
> +	[HSC001GAF] = HSC_CONFIG(0, 1000, 4, 94, 1, 1),
> +	/* Absolute range, psi */
> +	[HSC015PAA] = HSC_CONFIG(0, 15, 10, 90, 6895, 1000),
> +	[HSC015PAB] = HSC_CONFIG(0, 15, 5, 95, 6895, 1000),
> +	[HSC015PAC] = HSC_CONFIG(0, 15, 5, 85, 6895, 1000),
> +	[HSC015PAF] = HSC_CONFIG(0, 15, 4, 94, 6895, 1000),
> +	[HSC030PAA] = HSC_CONFIG(0, 30, 10, 90, 6895, 1000),
> +	[HSC030PAB] = HSC_CONFIG(0, 30, 5, 95, 6895, 1000),
> +	[HSC030PAC] = HSC_CONFIG(0, 30, 5, 85, 6895, 1000),
> +	[HSC030PAF] = HSC_CONFIG(0, 30, 4, 94, 6895, 1000),
> +	[HSC060PAA] = HSC_CONFIG(0, 60, 10, 90, 6895, 1000),
> +	[HSC060PAB] = HSC_CONFIG(0, 60, 5, 95, 6895, 1000),
> +	[HSC060PAC] = HSC_CONFIG(0, 60, 5, 85, 6895, 1000),
> +	[HSC060PAF] = HSC_CONFIG(0, 60, 4, 94, 6895, 1000),
> +	[HSC100PAA] = HSC_CONFIG(0, 100, 10, 90, 6895, 1000),
> +	[HSC100PAB] = HSC_CONFIG(0, 100, 5, 95, 6895, 1000),
> +	[HSC100PAC] = HSC_CONFIG(0, 100, 5, 85, 6895, 1000),
> +	[HSC100PAF] = HSC_CONFIG(0, 100, 4, 94, 6895, 1000),
> +	[HSC150PAA] = HSC_CONFIG(0, 150, 10, 90, 6895, 1000),
> +	[HSC150PAB] = HSC_CONFIG(0, 150, 5, 95, 6895, 1000),
> +	[HSC150PAC] = HSC_CONFIG(0, 150, 5, 85, 6895, 1000),
> +	[HSC150PAF] = HSC_CONFIG(0, 150, 4, 94, 6895, 1000),
> +};
> +
> +static const struct iio_chan_spec hsc_channels[] = {
> +	{
> +		.type = IIO_PRESSURE,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_OFFSET) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +		.channel = HSC_CH_PRESSURE,
> +		.scan_type = {
> +			.sign = 'u',
> +			.realbits = HSC_PRESS_BITS,
> +			.storagebits = 16,
> +			.shift = 0,
Shift default is 0 so no need to have this.

> +			.endianness = IIO_BE,
> +		}
> +	},
> +	{
> +		.type = IIO_TEMP,
> +		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> +				      BIT(IIO_CHAN_INFO_OFFSET) |
> +				      BIT(IIO_CHAN_INFO_SCALE),
> +		.channel = HSC_CH_TEMPERATURE,
> +		.scan_type = {
> +			.sign = 'u',
> +			.realbits = HSC_TEMP_BITS,
> +			.storagebits = 16,
> +			.shift = HSC_TEMP_SHIFT,
> +			.endianness = IIO_BE,
> +		}
> +	}
> +};
> +
> +static int hsc_get_pressure(struct hsc_state *state)
> +{
> +	int ret = 0;
Always set below, so should not init here.

> +	int error;
> +
> +	state->spi_xfer.len = 2;
> +	ret = spi_sync(state->spi_dev, &state->spi_msg);
> +	if (ret)
> +		return ret;
> +
> +	ret = be16_to_cpu(state->rx_buf[0]);
> +
> +	error = hsc_status_error(state->spi_dev->dev, ret);
> +	if (error)
> +		return error;
> +
> +	return ret;
> +}
> +
> +static int hsc_get_temperature(struct hsc_state *state)
> +{
> +	int ret;
> +	int error;
> +
> +	state->spi_xfer.len = 4;
> +	ret = spi_sync(state->spi_dev, &state->spi_msg);
> +	if (ret)
> +		return ret;
As mentioned below I'm not sure the complexity of the spi_sync
instead of spi_read is worthwhile here.
> +
> +	ret = be16_to_cpu(state->rx_buf[0]);
Perhaps just have this inline in the function call.
(there are a few other instances of this, so perhaps all of them)
> +	error = hsc_status_error(state->spi_dev->dev, ret);
> +	if (error)
> +		return error;
> +
> +	ret = be16_to_cpu(state->rx_buf[1]);
Perhaps just put this inline in the next statement?
> +	ret = (ret >> HSC_TEMP_SHIFT) & HSC_TEMP_MASK;
> +
> +	return ret;
return (ret >> HSC_TEMP_SHIFT) & HSC_TEMP_MASK;

> +}
> +
> +static int hsc_read_raw(struct iio_dev *indio_dev,
> +			struct iio_chan_spec const *chan, int *val,
> +			int *val2, long mask)
> +{
> +	struct hsc_state *state = iio_priv(indio_dev);
> +	int ret;
> +
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		switch (chan->channel) {
> +		case HSC_CH_PRESSURE:
> +			ret = hsc_get_pressure(state);
> +			if (ret < 0)
> +				break;
> +			*val = ret;
> +			ret = IIO_VAL_INT;
return IIO_VAL_INT;
> +			break;
> +		case HSC_CH_TEMPERATURE:
> +			ret = hsc_get_temperature(state);
> +			if (ret < 0)
> +				break;
> +			*val = ret;
> +			ret = IIO_VAL_INT;
return IIO_VAL_INT;

> +			break;
> +		default:
> +			ret = -EINVAL;
> +			dev_err(state->dev,
> +				"%s - IIO_CHAN_INFO_RAW-bad channel (%d)\n",
> +				__func__, chan->channel);
> +			break;
return -EINVAL;

> +		}
> +		break;
> +	case IIO_CHAN_INFO_OFFSET:
> +		switch (chan->channel) {
> +		case HSC_CH_PRESSURE:
> +			*val = state->offset.num;
> +			*val2 = state->offset.den;
> +			ret = IIO_VAL_FRACTIONAL;
> +			break;
> +		case HSC_CH_TEMPERATURE:
> +			*val = BIT(HSC_TEMP_BITS) - 1;
> +			*val2 = -200 / 50;
> +			ret = IIO_VAL_FRACTIONAL;
> +			break;
> +		default:
> +			dev_err(state->dev,
> +				"%s - IIO_CHAN_INFO_OFFSET-bad channel (%d)\n",
> +				__func__, chan->channel);
> +			ret = -EINVAL;
> +			break;
> +		}
> +		break;
> +	case IIO_CHAN_INFO_SCALE:
> +		switch (chan->channel) {
> +		case HSC_CH_PRESSURE:		/* output unit is kPa */
> +			*val = state->scale.num;
> +			*val2 = state->scale.den;
> +			ret = IIO_VAL_FRACTIONAL;
> +			break;
> +		case HSC_CH_TEMPERATURE:  /* output unit is milli Celsius */
> +			*val = 200 * 1000;
> +			*val2 = BIT(HSC_TEMP_BITS) - 1;
> +			ret = IIO_VAL_FRACTIONAL;
> +			break;
> +		default:
> +			dev_err(state->dev,
> +				"%s - IIO_CHAN_INFO_SCALE-bad channel (%d)\n",
> +				__func__, chan->channel);
> +			ret = -EINVAL;
> +			break;
> +		}
> +		break;
> +	default:
> +		dev_err(state->dev, "%s - mask = %ld (INVALID)\n",
> +			__func__, mask);
> +		ret = -EINVAL;
return -EINVAL;
> +		break;
> +	}
> +
> +	return ret;
With direct returns everywhere above, no need to return ret here as you can't
get here.

> +}
> +
> +static const struct iio_info hsc_info = {
> +	.read_raw = hsc_read_raw,
> +};
> +
> +static void hsc_init_device(struct iio_dev *indio_dev)
This function seems a little oddly named given it doesn't do anything
to the device at all. Perhaps hsc_init_device_params?
Or more likely you can come up with something better than that.

> +{
> +	struct hsc_state *state = iio_priv(indio_dev);
> +	const struct hsc_config *cfg = of_device_get_match_data(state->dev);
> +
> +	/* Pressure offset value */
> +	state->offset.num = BIT(HSC_PRESS_BITS) *
> +			    (cfg->pmin * cfg->rmax - cfg->pmax * cfg->rmin);
> +	state->offset.den = 100 * (cfg->pmax - cfg->pmin);
> +
> +	/* Pressure scale value */
> +	state->scale.num = 100 * cfg->knum * (cfg->pmax - cfg->pmin);
> +	state->scale.den = BIT(HSC_PRESS_BITS) *
> +			   cfg->kden * (cfg->rmax - cfg->rmin);
> +}
> +
> +static int hsc_spi_probe(struct spi_device *spi)
> +{
> +	struct device *dev = &spi->dev;
> +	struct hsc_state *state;
> +	struct iio_dev *indio_dev;
> +	int ret;
> +
> +	if (spi->max_speed_hz > HSC_MAX_SPI_FREQ_HZ) {
> +		dev_warn(dev, "SPI CLK, %d Hz exceeds %d Hz - changed to max\n",
> +			spi->max_speed_hz,
> +			HSC_MAX_SPI_FREQ_HZ);
> +		spi->max_speed_hz = HSC_MAX_SPI_FREQ_HZ;
> +	}
> +
> +	spi->bits_per_word = 8;
> +	spi->mode = SPI_MODE_0;
> +
> +	ret = spi_setup(spi);
> +	if (ret < 0) {
> +		dev_err(dev, "%s - Error in spi_setup()\n", __func__);
> +		return ret;
> +	}
> +
> +	indio_dev = devm_iio_device_alloc(dev, sizeof(*state));
> +	if (!indio_dev) {
> +		dev_err(dev, "%s - Error allocating iio_device\n", __func__);
> +		return -ENOMEM;
> +	}
> +
> +	state = iio_priv(indio_dev);
> +	spi_set_drvdata(spi, state);
> +	state->spi_dev = spi;
> +	state->dev = dev;
This seems a little excessive as you can get it from spi_dev->dev where ever it
is needed.

> +
> +	indio_dev->dev.parent = dev;
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +	indio_dev->info = &hsc_info;
> +	indio_dev->channels = hsc_channels;
> +	indio_dev->num_channels = ARRAY_SIZE(hsc_channels);
> +
> +	state->spi_xfer.rx_buf = &state->rx_buf[0];
> +	state->spi_xfer.tx_buf = NULL;
Null is the default so should be no need to set it.
(state is kzalloc)

> +	state->spi_xfer.cs_change = 0;

I would assume that was the default and doesn't need setting...

> +	spi_message_init(&state->spi_msg);
> +	spi_message_add_tail(&state->spi_xfer, &state->spi_msg);
Is this worthwhile doing over a simple spi_read without precreating
the message etc?

> +
> +	hsc_init_device(indio_dev);
> +
> +	ret = iio_device_register(indio_dev);
> +	if (ret < 0)
> +		dev_err(dev, "iio_device_register failed: %d\n", ret);
> +
> +	dev_dbg(dev, "%s - scale = %d/%d, offset = %d/%d\n", __func__,
> +		state->scale.num, state->scale.den,
> +		state->offset.num, state->offset.den);
> +
> +	return ret;
> +}
> +
> +static int hsc_spi_remove(struct spi_device *spi)
> +{
> +	struct device *dev = &spi->dev;
> +	struct iio_dev *indio_dev = dev_get_drvdata(dev);
> +
> +	iio_device_unregister(indio_dev);
If all you have in a remove function is iio_device_unregister, then
it implies you could have used devm_iio_device_register and not had
a remove function at all.

It's fairly unusual that there isn't 'something' to do, but perhaps not
if the interface is very simple, or you are doing tight power control
around individual readings.

> +
> +	return 0;
> +}
> +
> +static const struct of_device_id hsc_of_match[] = {
> +	{ .compatible = "honeywell,hsc001baa", .data = &hsc_cfg[HSC001BAA] },
> +	{ .compatible = "honeywell,hsc001bab", .data = &hsc_cfg[HSC001BAB] },
> +	{ .compatible = "honeywell,hsc001bac", .data = &hsc_cfg[HSC001BAC] },
> +	{ .compatible = "honeywell,hsc001baf", .data = &hsc_cfg[HSC001BAF] },
> +
> +	{ .compatible = "honeywell,hsc1_6baa", .data = &hsc_cfg[HSC1_6BAA] },
> +	{ .compatible = "honeywell,hsc1_6bab", .data = &hsc_cfg[HSC1_6BAB] },
> +	{ .compatible = "honeywell,hsc1_6bac", .data = &hsc_cfg[HSC1_6BAC] },
> +	{ .compatible = "honeywell,hsc1_6baf", .data = &hsc_cfg[HSC1_6BAF] },
> +
> +	{ .compatible = "honeywell,hsc2_5baa", .data = &hsc_cfg[HSC2_5BAA] },
> +	{ .compatible = "honeywell,hsc2_5bab", .data = &hsc_cfg[HSC2_5BAB] },
> +	{ .compatible = "honeywell,hsc2_5bac", .data = &hsc_cfg[HSC2_5BAC] },
> +	{ .compatible = "honeywell,hsc2_5baf", .data = &hsc_cfg[HSC2_5BAF] },
> +
> +	{ .compatible = "honeywell,hsc004baa", .data = &hsc_cfg[HSC004BAA] },
> +	{ .compatible = "honeywell,hsc004bab", .data = &hsc_cfg[HSC004BAB] },
> +	{ .compatible = "honeywell,hsc004bac", .data = &hsc_cfg[HSC004BAC] },
> +	{ .compatible = "honeywell,hsc004baf", .data = &hsc_cfg[HSC004BAF] },
> +
> +	{ .compatible = "honeywell,hsc006baa", .data = &hsc_cfg[HSC006BAA] },
> +	{ .compatible = "honeywell,hsc006bab", .data = &hsc_cfg[HSC006BAB] },
> +	{ .compatible = "honeywell,hsc006bac", .data = &hsc_cfg[HSC006BAC] },
> +	{ .compatible = "honeywell,hsc006baf", .data = &hsc_cfg[HSC006BAF] },
> +
> +	{ .compatible = "honeywell,hsc010baa", .data = &hsc_cfg[HSC010BAA] },
> +	{ .compatible = "honeywell,hsc010bab", .data = &hsc_cfg[HSC010BAB] },
> +	{ .compatible = "honeywell,hsc010bac", .data = &hsc_cfg[HSC010BAC] },
> +	{ .compatible = "honeywell,hsc010baf", .data = &hsc_cfg[HSC010BAF] },
> +
> +	{ .compatible = "honeywell,hsc100kaa", .data = &hsc_cfg[HSC100KAA] },
> +	{ .compatible = "honeywell,hsc100kab", .data = &hsc_cfg[HSC100KAB] },
> +	{ .compatible = "honeywell,hsc100kac", .data = &hsc_cfg[HSC100KAC] },
> +	{ .compatible = "honeywell,hsc100kaf", .data = &hsc_cfg[HSC100KAF] },
> +
> +	{ .compatible = "honeywell,hsc160kaa", .data = &hsc_cfg[HSC160KAA] },
> +	{ .compatible = "honeywell,hsc160kab", .data = &hsc_cfg[HSC160KAB] },
> +	{ .compatible = "honeywell,hsc160kac", .data = &hsc_cfg[HSC160KAC] },
> +	{ .compatible = "honeywell,hsc160kaf", .data = &hsc_cfg[HSC160KAF] },
> +
> +	{ .compatible = "honeywell,hsc250kaa", .data = &hsc_cfg[HSC250KAA] },
> +	{ .compatible = "honeywell,hsc250kab", .data = &hsc_cfg[HSC250KAB] },
> +	{ .compatible = "honeywell,hsc250kac", .data = &hsc_cfg[HSC250KAC] },
> +	{ .compatible = "honeywell,hsc250kaf", .data = &hsc_cfg[HSC250KAF] },
> +
> +	{ .compatible = "honeywell,hsc400kaa", .data = &hsc_cfg[HSC400KAA] },
> +	{ .compatible = "honeywell,hsc400kab", .data = &hsc_cfg[HSC400KAB] },
> +	{ .compatible = "honeywell,hsc400kac", .data = &hsc_cfg[HSC400KAC] },
> +	{ .compatible = "honeywell,hsc400kaf", .data = &hsc_cfg[HSC400KAF] },
> +
> +	{ .compatible = "honeywell,hsc600kaa", .data = &hsc_cfg[HSC600KAA] },
> +	{ .compatible = "honeywell,hsc600kab", .data = &hsc_cfg[HSC600KAB] },
> +	{ .compatible = "honeywell,hsc600kac", .data = &hsc_cfg[HSC600KAC] },
> +	{ .compatible = "honeywell,hsc600kaf", .data = &hsc_cfg[HSC600KAF] },
> +
> +	{ .compatible = "honeywell,hsc001gaa", .data = &hsc_cfg[HSC001GAA] },
> +	{ .compatible = "honeywell,hsc001gab", .data = &hsc_cfg[HSC001GAB] },
> +	{ .compatible = "honeywell,hsc001gac", .data = &hsc_cfg[HSC001GAC] },
> +	{ .compatible = "honeywell,hsc001gaf", .data = &hsc_cfg[HSC001GAF] },
> +
> +	{ .compatible = "honeywell,hsc015paa", .data = &hsc_cfg[HSC015PAA] },
> +	{ .compatible = "honeywell,hsc015pab", .data = &hsc_cfg[HSC015PAB] },
> +	{ .compatible = "honeywell,hsc015pac", .data = &hsc_cfg[HSC015PAC] },
> +	{ .compatible = "honeywell,hsc015paf", .data = &hsc_cfg[HSC015PAF] },
> +
> +	{ .compatible = "honeywell,hsc030paa", .data = &hsc_cfg[HSC030PAA] },
> +	{ .compatible = "honeywell,hsc030pab", .data = &hsc_cfg[HSC030PAB] },
> +	{ .compatible = "honeywell,hsc030pac", .data = &hsc_cfg[HSC030PAC] },
> +	{ .compatible = "honeywell,hsc030paf", .data = &hsc_cfg[HSC030PAF] },
> +
> +	{ .compatible = "honeywell,hsc060paa", .data = &hsc_cfg[HSC060PAA] },
> +	{ .compatible = "honeywell,hsc060pab", .data = &hsc_cfg[HSC060PAB] },
> +	{ .compatible = "honeywell,hsc060pac", .data = &hsc_cfg[HSC060PAC] },
> +	{ .compatible = "honeywell,hsc060paf", .data = &hsc_cfg[HSC060PAF] },
> +
> +	{ .compatible = "honeywell,hsc100paa", .data = &hsc_cfg[HSC100PAA] },
> +	{ .compatible = "honeywell,hsc100pab", .data = &hsc_cfg[HSC100PAB] },
> +	{ .compatible = "honeywell,hsc100pac", .data = &hsc_cfg[HSC100PAC] },
> +	{ .compatible = "honeywell,hsc100paf", .data = &hsc_cfg[HSC100PAF] },
> +
> +	{ .compatible = "honeywell,hsc150paa", .data = &hsc_cfg[HSC150PAA] },
> +	{ .compatible = "honeywell,hsc150pab", .data = &hsc_cfg[HSC150PAB] },
> +	{ .compatible = "honeywell,hsc150pac", .data = &hsc_cfg[HSC150PAC] },
> +	{ .compatible = "honeywell,hsc150paf", .data = &hsc_cfg[HSC150PAF] },
> +
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(of, hsc_of_match);
> +
> +static struct spi_driver hsc_spi_driver = {
> +	.probe = hsc_spi_probe,
> +	.remove = hsc_spi_remove,
> +	.driver = {
> +		.name = "hsc_spi_pressure_sensor",
> +		.of_match_table = hsc_of_match,
> +	},
> +};
> +
> +module_spi_driver(hsc_spi_driver);
> +
> +MODULE_AUTHOR("Carlos Iglesias <carlosiglesias@emutex.com>");
> +MODULE_DESCRIPTION("Honeywell HSC SPI pressure sensor driver");
> +MODULE_LICENSE("GPL v2");


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] dt-bindings: iio: pressure: Add support for Honeywell HSC SPI sensors
       [not found]     ` <0dbb2254-8035-b498-6302-26bc3a2219ca@emutex.com>
@ 2018-11-03 10:36       ` Jonathan Cameron
  0 siblings, 0 replies; 7+ messages in thread
From: Jonathan Cameron @ 2018-11-03 10:36 UTC (permalink / raw)
  To: Carlos Iglesias
  Cc: linux-kernel, robh+dt, mark.rutland, knaack.h, lars, pmeerw,
	linux-iio, devicetree, Dan O'Donovan

Rob, just to draw your attention, some discussion around
spi-max-frequency that you might want to look at below.


On Tue, 30 Oct 2018 15:56:58 +0000
Carlos Iglesias <carlos.iglesias@emutex.com> wrote:

> Please see comments inline below.
Hi Carlos,

Please try to use an email client (or configure yours to do it)
that adds indentation to each level of reply.  It's somewhat
fiddly to separate the different parts of the conversation!

> 
> On 10/28/18 5:38 PM, Jonathan Cameron wrote:
> 
> On Fri, 26 Oct 2018 18:14:36 +0000
> Carlos Iglesias <carlos.iglesias@emutex.com><mailto:carlos.iglesias@emutex.com> wrote:
> 
> 
> 
> Add device tree bindings for the HSC pressure sensors.
> 
> Signed-off-by: Carlos Iglesias <carlos.iglesias@emutex.com><mailto:carlos.iglesias@emutex.com>
> ---
>  .../bindings/iio/pressure/hsc_spi.txt         | 85 +++++++++++++++++++
>  1 file changed, 85 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> 
> diff --git a/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt b/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> new file mode 100644
> index 000000000000..2302d6eef7c7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> @@ -0,0 +1,85 @@
> +Honeywell HSC Series of Pressure Sensors
> +
> +Pressure sensors from Honeywell with analog, I2C and SPI interfaces
> +
> +Required properties:
> +- compatible: selects the sensor model; must be one of the following
> +       "honeywell,hsc001baa"
> +       "honeywell,hsc001bab"
> +       "honeywell,hsc001bac"
> +       "honeywell,hsc001baf"
> +       "honeywell,hsc1_6baa"
> +       "honeywell,hsc1_6bab"
> +       "honeywell,hsc1_6bac"
> +       "honeywell,hsc1_6baf"
> +       "honeywell,hsc2_5baa"
> +       "honeywell,hsc2_5bab"
> +       "honeywell,hsc2_5bac"
> +       "honeywell,hsc2_5baf"
> +       "honeywell,hsc004baa"
> +       "honeywell,hsc004bab"
> +       "honeywell,hsc004bac"
> +       "honeywell,hsc004baf"
> +       "honeywell,hsc006baa"
> +       "honeywell,hsc006bab"
> +       "honeywell,hsc006bac"
> +       "honeywell,hsc006baf"
> +       "honeywell,hsc010baa"
> +       "honeywell,hsc010bab"
> +       "honeywell,hsc010bac"
> +       "honeywell,hsc010baf"
> +       "honeywell,hsc100kaa"
> +       "honeywell,hsc100kab"
> +       "honeywell,hsc100kac"
> +       "honeywell,hsc100kaf"
> +       "honeywell,hsc160kaa"
> +       "honeywell,hsc160kab"
> +       "honeywell,hsc160kac"
> +       "honeywell,hsc160kaf"
> +       "honeywell,hsc250kaa"
> +       "honeywell,hsc250kab"
> +       "honeywell,hsc250kac"
> +       "honeywell,hsc250kaf"
> +       "honeywell,hsc400kaa"
> +       "honeywell,hsc400kab"
> +       "honeywell,hsc400kac"
> +       "honeywell,hsc400kaf"
> +       "honeywell,hsc600kaa"
> +       "honeywell,hsc600kab"
> +       "honeywell,hsc600kac"
> +       "honeywell,hsc600kaf"
> +       "honeywell,hsc001gaa"
> +       "honeywell,hsc001gab"
> +       "honeywell,hsc001gac"
> +       "honeywell,hsc001gaf"
> +       "honeywell,hsc015paa"
> +       "honeywell,hsc015pab"
> +       "honeywell,hsc015pac"
> +       "honeywell,hsc015paf"
> +       "honeywell,hsc030paa"
> +       "honeywell,hsc030pab"
> +       "honeywell,hsc030pac"
> +       "honeywell,hsc030paf"
> +       "honeywell,hsc060paa"
> +       "honeywell,hsc060pab"
> +       "honeywell,hsc060pac"
> +       "honeywell,hsc060paf"
> +       "honeywell,hsc100paa"
> +       "honeywell,hsc100pab"
> +       "honeywell,hsc100pac"
> +       "honeywell,hsc100paf"
> +       "honeywell,hsc150paa"
> +       "honeywell,hsc150pab"
> +       "honeywell,hsc150pac"
> +       "honeywell,hsc150paf"
> +- reg: the SPI chip select number used by the sensor.
> +- spi-max-frequency: maximum clock frequency (Hz) used for the SPI bus.
> +  The maximum value supported by the sensors is 400000.
> 
> 
> As Rob pointed out in a few reviews this week, the devicetree binding
> for this should only be applying a tighter bound than either the
> device or the bus master. So something introduced by the board
> layout for example, or a level convertor..
> 
> Jonathan
> 
> Checking the devicetree bindings files of other spi sensors I see a frequent approach is to include a reference to Documentation/devicetree/bindings/spi/spi-bus.txt, for example:
> 
> Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt apply. In particular, "reg" and "spi-max-frequency" properties must be given.
The point is that spi-max-frequency doesn't actually need to be given.  If the
fine with which ever is lower of that supported by the device and that supported
by the master then it will use that without spi-max-frequency being provided.

I agree this wasn't previously my understanding but it does make sense. No
obvious reason why this value would need providing by DT unless there is
a board issue that neither of the 'ends' can see.

We might want to look at cleaning this up in general through the bindings
(and making sure device drivers apply there own maximums).  Rob
is this a worthwhile cleanup?

> 
> Maybe it would be a better option to place such a note instead of the "reg" and "spi-max-frequency" points. What do you think?
> 
> Sorry, I was not aware of Rob Herring's previous comments on this topic, I am not subscribed to the LKML.

Sure, I wasn't aware of them until that day anyway ;)

Thanks,

Jonathan

> 
> 
> 
> 
> +
> +Example:
> +
> +       hsc_spi0: hsc@0 {
> +               compatible = "honeywell,hsc010baa";
> +               reg = <0>;
> +               spi-max-frequency = <400000>;
> +       };
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] dt-bindings: iio: pressure: Add support for Honeywell HSC SPI sensors
  2018-10-26 18:14 ` [PATCH 1/2] dt-bindings: " Carlos Iglesias
  2018-10-28 17:38   ` Jonathan Cameron
@ 2018-11-06 21:29   ` Rob Herring
  1 sibling, 0 replies; 7+ messages in thread
From: Rob Herring @ 2018-11-06 21:29 UTC (permalink / raw)
  To: Carlos Iglesias
  Cc: linux-kernel, jic23, mark.rutland, knaack.h, lars, pmeerw,
	linux-iio, devicetree, Dan O'Donovan

On Fri, Oct 26, 2018 at 06:14:36PM +0000, Carlos Iglesias wrote:
> Add device tree bindings for the HSC pressure sensors.
> 
> Signed-off-by: Carlos Iglesias <carlos.iglesias@emutex.com>
> ---
>  .../bindings/iio/pressure/hsc_spi.txt         | 85 +++++++++++++++++++
>  1 file changed, 85 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> 
> diff --git a/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt b/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> new file mode 100644
> index 000000000000..2302d6eef7c7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/pressure/hsc_spi.txt
> @@ -0,0 +1,85 @@
> +Honeywell HSC Series of Pressure Sensors
> +
> +Pressure sensors from Honeywell with analog, I2C and SPI interfaces

But you named the file with 'spi'. You expect 
> +
> +Required properties:
> +- compatible: selects the sensor model; must be one of the following
> +	"honeywell,hsc001baa"
> +	"honeywell,hsc001bab"
> +	"honeywell,hsc001bac"
> +	"honeywell,hsc001baf"

I normally tell people to imply things from compatible strings, but this 
may be a good case where some properties make sense. The last letter 
appears to be 'transfer function'. Maybe even the pressure range should 
be a property. I think it depends if there's any other s/w visible 
differences.

Plus this list doesn't even include the differential or gage parts and 
those lists are longer.

> +	"honeywell,hsc1_6baa"
> +	"honeywell,hsc1_6bab"
> +	"honeywell,hsc1_6bac"
> +	"honeywell,hsc1_6baf"
> +	"honeywell,hsc2_5baa"
> +	"honeywell,hsc2_5bab"
> +	"honeywell,hsc2_5bac"
> +	"honeywell,hsc2_5baf"
> +	"honeywell,hsc004baa"
> +	"honeywell,hsc004bab"
> +	"honeywell,hsc004bac"
> +	"honeywell,hsc004baf"
> +	"honeywell,hsc006baa"
> +	"honeywell,hsc006bab"
> +	"honeywell,hsc006bac"
> +	"honeywell,hsc006baf"
> +	"honeywell,hsc010baa"
> +	"honeywell,hsc010bab"
> +	"honeywell,hsc010bac"
> +	"honeywell,hsc010baf"
> +	"honeywell,hsc100kaa"
> +	"honeywell,hsc100kab"
> +	"honeywell,hsc100kac"
> +	"honeywell,hsc100kaf"
> +	"honeywell,hsc160kaa"
> +	"honeywell,hsc160kab"
> +	"honeywell,hsc160kac"
> +	"honeywell,hsc160kaf"
> +	"honeywell,hsc250kaa"
> +	"honeywell,hsc250kab"
> +	"honeywell,hsc250kac"
> +	"honeywell,hsc250kaf"
> +	"honeywell,hsc400kaa"
> +	"honeywell,hsc400kab"
> +	"honeywell,hsc400kac"
> +	"honeywell,hsc400kaf"
> +	"honeywell,hsc600kaa"
> +	"honeywell,hsc600kab"
> +	"honeywell,hsc600kac"
> +	"honeywell,hsc600kaf"
> +	"honeywell,hsc001gaa"
> +	"honeywell,hsc001gab"
> +	"honeywell,hsc001gac"
> +	"honeywell,hsc001gaf"
> +	"honeywell,hsc015paa"
> +	"honeywell,hsc015pab"
> +	"honeywell,hsc015pac"
> +	"honeywell,hsc015paf"
> +	"honeywell,hsc030paa"
> +	"honeywell,hsc030pab"
> +	"honeywell,hsc030pac"
> +	"honeywell,hsc030paf"
> +	"honeywell,hsc060paa"
> +	"honeywell,hsc060pab"
> +	"honeywell,hsc060pac"
> +	"honeywell,hsc060paf"
> +	"honeywell,hsc100paa"
> +	"honeywell,hsc100pab"
> +	"honeywell,hsc100pac"
> +	"honeywell,hsc100paf"
> +	"honeywell,hsc150paa"
> +	"honeywell,hsc150pab"
> +	"honeywell,hsc150pac"
> +	"honeywell,hsc150paf"
> +- reg: the SPI chip select number used by the sensor.
> +- spi-max-frequency: maximum clock frequency (Hz) used for the SPI bus.
> +  The maximum value supported by the sensors is 400000.
> +
> +Example:
> +
> +	hsc_spi0: hsc@0 {

pressure-sensor@0

> +		compatible = "honeywell,hsc010baa";
> +		reg = <0>;
> +		spi-max-frequency = <400000>;
> +	};
> -- 
> 2.19.1
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-11-06 21:29 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-26 18:14 [PATCH 0/2] iio: pressure: Add support for Honeywell HSC SPI sensors Carlos Iglesias
2018-10-26 18:14 ` [PATCH 1/2] dt-bindings: " Carlos Iglesias
2018-10-28 17:38   ` Jonathan Cameron
     [not found]     ` <0dbb2254-8035-b498-6302-26bc3a2219ca@emutex.com>
2018-11-03 10:36       ` Jonathan Cameron
2018-11-06 21:29   ` Rob Herring
2018-10-26 18:14 ` [PATCH 2/2] " Carlos Iglesias
2018-10-28 18:44   ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).