Re: [PATCH v1 3/3] iio:pressure: initial zpa2326 barometer support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> Introduce driver for Murata ZPA2326 pressure and temperature sensor:
> http://www.murata.com/en-us/products/productdetail?partno=ZPA2326-0311A-R

comments below
 
> Signed-off-by: Gregor Boirie <gregor.boirie@xxxxxxxxxx>
> ---
>  .../devicetree/bindings/iio/pressure/zpa2326.txt   |   23 +
>  drivers/iio/pressure/Kconfig                       |   33 +
>  drivers/iio/pressure/Makefile                      |    3 +
>  drivers/iio/pressure/zpa2326.c                     | 1766 ++++++++++++++++++++
>  drivers/iio/pressure/zpa2326.h                     |   76 +
>  drivers/iio/pressure/zpa2326_i2c.c                 |  188 +++
>  drivers/iio/pressure/zpa2326_spi.c                 |  184 ++
>  7 files changed, 2273 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/iio/pressure/zpa2326.txt
>  create mode 100644 drivers/iio/pressure/zpa2326.c
>  create mode 100644 drivers/iio/pressure/zpa2326.h
>  create mode 100644 drivers/iio/pressure/zpa2326_i2c.c
>  create mode 100644 drivers/iio/pressure/zpa2326_spi.c
> 
> diff --git a/Documentation/devicetree/bindings/iio/pressure/zpa2326.txt b/Documentation/devicetree/bindings/iio/pressure/zpa2326.txt
> new file mode 100644
> index 0000000..4b92906
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/pressure/zpa2326.txt
> @@ -0,0 +1,23 @@
> +Murata ZPA2326 pressure sensor
> +
> +Pressure sensor from Murata with SPI and I2C bus interfaces.
> +
> +Required properties:
> +- compatible: "murata,zpa2326"
> +- reg: the I2C address or SPI chip select the device will respond to
> +
> +Optional properties:
> +- interrupt-parent: should be the phandle for the interrupt controller
> +- interrupts: interrupt mapping for IRQ
> +- vdd-supply: an optional regulator that needs to be on to provide VDD
> +  power to the sensor
> +
> +Example:
> +
> +zpa2326@5c {
> +	compatible = "murata,zpa2326";
> +	reg = <0x5c>;
> +	interrupt-parent = <&gpio>;
> +	interrupts = <12>;
> +	vdd-supply = <&ldo_1v8_gnss>;
> +};
> diff --git a/drivers/iio/pressure/Kconfig b/drivers/iio/pressure/Kconfig
> index d130cdc..a3db56f 100644
> --- a/drivers/iio/pressure/Kconfig
> +++ b/drivers/iio/pressure/Kconfig
> @@ -187,4 +187,37 @@ config HP206C
>  	  This driver can also be built as a module. If so, the module will
>  	  be called hp206c.
>  
> +config ZPA2326
> +	tristate "Murata ZPA2326 pressure sensor driver"
> +	depends on I2C || SPI
> +	select IIO_BUFFER
> +	select IIO_TRIGGERED_BUFFER
> +	help
> +	  Say Y here to build support for the Murata ZPA2326 pressure and
> +	  temperature sensor.
> +
> +	  To compile this driver as a module, choose M here: the module will
> +	  be called zpa2326.
> +
> +config ZPA2326_I2C
> +	tristate "support I2C bus connection"
> +	depends on I2C && ZPA2326
> +	help
> +	  Say Y here to build I2C bus support for the Murata ZPA2326 pressure
> +	  and temperature sensor.
> +
> +	  To compile this driver as a module, choose M here: the module will
> +	  be called zpa2326_i2c.
> +
> +config ZPA2326_SPI
> +	tristate "support SPI bus connection"
> +	depends on SPI && ZPA2326
> +	help
> +	  Say Y here to build SPI bus support for the Murata ZPA2326 pressure
> +	  and temperature sensor.
> +
> +	  To compile this driver as a module, choose M here: the module will
> +	  be called zpa2326_spi.
> +

drop extra newline

> +
>  endmenu
> diff --git a/drivers/iio/pressure/Makefile b/drivers/iio/pressure/Makefile
> index 7f395be..fff7718 100644
> --- a/drivers/iio/pressure/Makefile
> +++ b/drivers/iio/pressure/Makefile
> @@ -22,6 +22,9 @@ st_pressure-y := st_pressure_core.o
>  st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o
>  obj-$(CONFIG_T5403) += t5403.o
>  obj-$(CONFIG_HP206C) += hp206c.o
> +obj-$(CONFIG_ZPA2326) += zpa2326.o
> +obj-$(CONFIG_ZPA2326_I2C) += zpa2326_i2c.o
> +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
> diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c
> new file mode 100644
> index 0000000..7b76c34
> --- /dev/null
> +++ b/drivers/iio/pressure/zpa2326.c
> @@ -0,0 +1,1766 @@
> +/*
> + * Murata ZPA2326 pressure and temperature sensor IIO driver
> + *
> + * Copyright (c) 2016 Parrot S.A.
> + *
> + * Author: Gregor Boirie <gregor.boirie@xxxxxxxxxx>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + *
> + *
> + * README:
> + * ------
> + *
> + * This driver supports the following IIO modes: INDIO_DIRECT_MODE,
> + * INDIO_BUFFER_SOFTWARE and INDIO_BUFFER_TRIGGERED.
> + * A hardware trigger is also implemented to dispatch registered IIO trigger
> + * consumers upon "sample ready" interrupts.
> + *
> + * ZPA2326 hardware supports 2 sampling mode: one shot and continuous.
> + *
> + * A complete one shot sampling cycle gets device out of low power mode,
> + * performs pressure and temperature measurements, then automatically switch

switches

> + * back to low power mode. It is meant for on demand sampling with optimal power
> + * saving at the cost of lower sampling rate and higher software overhead.
> + * This is a natural candidate for IIO read_raw hook implementation
> + * (INDIO_DIRECT_MODE). It is also used for triggered buffering support to
> + * ensure explicit synchronization with external trigger events
> + * (INDIO_BUFFER_TRIGGERED).
> + *
> + * The continuous mode works according to a periodic hardware measurement
> + * process continuously pushing samples into an internal hardware fifo (for
> + * pressure samples only). Measurement cycle completion may be signaled by a
> + * "sample ready" interrupt.
> + * Typical software sequence of operations :
> + * - get device out of low power mode,
> + * - setup hardware sampling period,
> + * - at end of period, upon data ready interrupt: pop pressure samples out of
> + *   hardware fifo and fetch temperature sample
> + * - when no longer needed, stop sampling process by putting device into
> + *   low power mode.
> + * This mode is used to implement INDIO_BUFFER_SOFTWARE mode if device tree
> + * declares a valid interrupt line. It is not compatible with triggers driven

trigger

> + * acquisition.
> + *
> + * Note that hardware sampling frequency is taken into account for
> + * INDIO_BUFFER_SOFTWARE mode only as the highest sampling rate seems to be the
> + * most energy efficient.
> + *
> + * TODO:
> + *   - preset pressure threshold crossing / IIO events
> + *   - differential pressure sampling
> + *   - hardware samples averaging
> + */
> +
> +/* Comment out to enable really verbose logging. */
> +/*#define DEBUG*/
> +
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/trigger.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
> +#include "zpa2326.h"
> +
> +/* 200 ms should be enought for the longest conversion time in one-shot mode. */

enough

> +#define ZPA_CONVERSION_TIMEOUT (HZ / 5)

ZPA2326_ prefix would be expected by convention

> +
> +/* Registers map. */

Register map

> +#define ZPA_REF_P_XL_REG                     ((u8)0x8)

do we really need u8 here? why?

> +#define ZPA_REF_P_L_REG                      ((u8)0x9)
> +#define ZPA_REF_P_H_REG                      ((u8)0xa)
> +#define ZPA_RES_CONF_REG                     ((u8)0x10)
> +#define ZPA_CTRL_REG0_REG                    ((u8)0x20)
> +#	define ZPA_CTRL_REG0_ONE_SHOT        BIT(0)
> +#	define ZPA_CTRL_REG0_ENABLE          BIT(1)
> +#define ZPA_CTRL_REG1_REG                    ((u8)0x21)
> +#	define ZPA_CTRL_REG1_MASK_DATA_READY ((u8)BIT(2))
> +#define ZPA_CTRL_REG2_REG                    ((u8)0x22)
> +#	define ZPA_CTRL_REG2_SWRESET         BIT(2)
> +#define ZPA_CTRL_REG3_REG                    ((u8)0x23)
> +#	define ZPA_CTRL_REG3_ODR_SHIFT       (4)
> +#	define ZPA_CTRL_REG3_ENABLE_MEAS     BIT(7)
> +#define ZPA_INT_SOURCE_REG                   ((u8)0x24)
> +#	define ZPA_INT_SOURCE_DATA_READY     BIT(2)
> +#define ZPA_THS_P_LOW_REG                    ((u8)0x25)
> +#define ZPA_THS_P_HIGH_REG                   ((u8)0x26)
> +#define ZPA_STATUS_REG                       ((u8)0x27)
> +#	define ZPA_STATUS_P_DA               BIT(1)
> +#	define ZPA_STATUS_FIFO_E             BIT(2)
> +#	define ZPA_STATUS_P_OR               BIT(5)
> +#define ZPA_PRESS_OUT_XL_REG                 ((u8)0x28)
> +#define ZPA_PRESS_OUT_L_REG                  ((u8)0x29)
> +#define ZPA_PRESS_OUT_H_REG                  ((u8)0x2a)
> +#define ZPA_TEMP_OUT_L_REG                   ((u8)0x2b)
> +#define ZPA_TEMP_OUT_H_REG                   ((u8)0x2c)
> +
> +/* Hardware sampling frequency descriptor. */
> +struct zpa_frequency {
> +	/* Stringified frequency in Hertz. */
> +	const char *hz;
> +	/* Output Data Rate word as expected by ZPA_CTRL_REG3_REG. */
> +	u16         odr;
> +};
> +
> +/*
> + * Keep these in strict ascending order: last array entry is expected to
> + * correspond to the highest sampling frequency.
> + */
> +static const struct zpa_frequency zpa_sampling_frequencies[] = {
> +	{ .hz = "1",  .odr = 1 << ZPA_CTRL_REG3_ODR_SHIFT },
> +	{ .hz = "5",  .odr = 5 << ZPA_CTRL_REG3_ODR_SHIFT },
> +	{ .hz = "11", .odr = 6 << ZPA_CTRL_REG3_ODR_SHIFT },
> +	{ .hz = "23", .odr = 7 << ZPA_CTRL_REG3_ODR_SHIFT },
> +};
> +
> +/* Return the highest hardware sampling frequency available. */
> +static const struct zpa_frequency *zpa_highest_frequency(void)
> +{
> +	return &zpa_sampling_frequencies[ARRAY_SIZE(zpa_sampling_frequencies) -
> +					 1];
> +}
> +
> +/* Per-device internal private state. */
> +struct zpa_private {
> +	/* Buffered samples ready datum. */
> +	s64                         timestamp;
> +	/*
> +	 * Underlying I2C / SPI bus adapter used to abstract slave register
> +	 * accesses.
> +	 */
> +	const struct zpa_bus       *bus;
> +	/*
> +	 * Interrupt handler stores sampling operation status here for user
> +	 * context usage.
> +	 */
> +	int                         result;
> +	/*
> +	 * Interrupt handler uses this to wake user context up at sampling
> +	 * operation completion.
> +	 */
> +	struct completion           data_ready;
> +	/*
> +	 * Optional hardware / interrupt driven trigger used to notify external
> +	 * devices a new sample is ready.
> +	 */
> +	struct iio_trigger         *trigger;
> +	/* Flag indicating whether or not device has just been powered on. */
> +	bool                        waken;
> +	/*
> +	 * Optional interrupt line: negative if not declared into DT, in
> +	 * which case user context keeps polling status register to detect
> +	 * sampling completion.
> +	 */
> +	int                         irq;
> +	/* Current hardware sampling frequency. */
> +	const struct zpa_frequency *frequency;
> +	/* Optional power supply. */
> +	struct regulator           *vdd;
> +};
> +
> +/******************************************************************************
> + * Various helpers
> + ******************************************************************************/
> +
> +#define zpa_err(_idev, _format, _arg...) \
> +	dev_err(zpa_iio2slave(_idev), _format, ##_arg)
> +
> +#define zpa_warn(_idev, _format, _arg...) \
> +	dev_warn(zpa_iio2slave(_idev), _format, ##_arg)
> +
> +#define zpa_dbg(_idev, _format, _arg...) \
> +	dev_dbg(zpa_iio2slave(_idev), _format, ##_arg)
> +
> +static struct zpa_private *zpa_iio2priv(const struct iio_dev *indio_dev)
> +{
> +	return (struct zpa_private *)iio_priv(indio_dev);
> +}
> +
> +/*
> + * Fetch single byte from slave register.
> + * indio_dev: IIO device the slave is attached to.
> + * address:   address of register to read from.
> + *
> + * Returns the fetched byte when successful, a negative error code otherwise.
> + */
> +static int zpa_read_byte(const struct iio_dev *indio_dev, u8 address)
> +{
> +	return zpa_iio2priv(indio_dev)->bus->zpa_read_byte(indio_dev, address);
> +}
> +
> +/*
> + * Store single byte to slave register.
> + * indio_dev: IIO device the slave is attached to
> + * address:   address of register to write to
> + *
> + * Returns: zero when successful, a negative error code otherwise.
> + */
> +static int zpa_write_byte(const struct iio_dev *indio_dev, u8 address, u8 value)
> +{
> +	return zpa_iio2priv(indio_dev)->bus->zpa_write_byte(indio_dev, address,
> +							    value);
> +}
> +
> +/*
> + * Fetch multiple bytes from a block of contiguous slave registers.
> + * indio_dev: IIO device the slave is attached to.
> + * address:   start address of contiguous registers block to read from.
> + * length:    number of bytes to fetch.
> + * value:     location to store fetched data into.
> + *
> + * Returns: zero when successful, a negative error code otherwise.
> + */
> +static int zpa_read_block(const struct iio_dev *indio_dev,
> +			  u8                    address,
> +			  u8                    length,
> +			  u8                   *value)
> +{
> +	return zpa_iio2priv(indio_dev)->bus->zpa_read_block(indio_dev, address,
> +							    length, value);
> +}
> +
> +/******************************************************************************
> + * Device operations handling
> + ******************************************************************************/
> +
> +/*
> + * Enable device, i.e. get out of low power mode.
> + *
> + * Required to access complete register space and to perform any sampling
> + * or control operations.
> + */
> +static int zpa_enable_device(const struct iio_dev *indio_dev)
> +{
> +	int err = zpa_write_byte(indio_dev, ZPA_CTRL_REG0_REG,
> +				 ZPA_CTRL_REG0_ENABLE);
> +	if (err) {
> +		zpa_err(indio_dev, "failed to enable device (%d)", err);

I think messages should end with \n

> +		return err;
> +	}
> +
> +	zpa_dbg(indio_dev, "enabled");
> +	return 0;
> +}
> +
> +/*
> + * Disable device, i.e. switch to low power mode.
> + *
> + * Only ZPA_DEVICE_ID_REG and ZPA_CTRL_REG0_REG registers may be accessed once
> + * device is in the disabled state.
> + */
> +static int zpa_disable_device(const struct iio_dev *indio_dev)
> +{
> +	int err = zpa_write_byte(indio_dev, ZPA_CTRL_REG0_REG, 0);
> +
> +	if (err) {
> +		zpa_err(indio_dev, "failed to disable device (%d)", err);
> +		return err;
> +	}
> +
> +	zpa_dbg(indio_dev, "disabled");
> +	return 0;
> +}
> +
> +/*
> + * Reset device to default hardware state.
> + *
> + * Disable sampling and empty hardware fifo.
> + * Device must be enabled before reset, i.e. not in low power mode.
> + */
> +static int zpa_reset_device(const struct iio_dev *indio_dev)
> +{
> +	int err = zpa_write_byte(indio_dev, ZPA_CTRL_REG2_REG,
> +				 ZPA_CTRL_REG2_SWRESET);
> +	if (err) {
> +		zpa_err(indio_dev, "failed to reset device (%d)", err);
> +		return err;
> +	}
> +
> +	/* There should be a 1 ms (Tpup) after getting out of reset. */

add 'delay' maybe

> +	usleep_range(1000, 2000);
> +
> +	zpa_dbg(indio_dev, "reset");
> +	return 0;
> +}
> +
> +/*
> + * Start a single sampling cycle, i.e. in one shot mode.
> + *
> + * Device must have been previously enabled and configured for one shot mode.
> + * Device will automatically switch back to low power mode at end of cycle.
> + */
> +static int zpa_start_oneshot(const struct iio_dev *indio_dev)
> +{
> +	int err = zpa_write_byte(indio_dev, ZPA_CTRL_REG0_REG,
> +				 ZPA_CTRL_REG0_ENABLE | ZPA_CTRL_REG0_ONE_SHOT);
> +	if (err) {
> +		zpa_err(indio_dev, "failed to start one shot cycle (%d)", err);
> +		return err;
> +	}
> +
> +	zpa_dbg(indio_dev, "one shot cycle started");
> +	return 0;
> +}
> +
> +/*
> + * Power on device to allow subsequent configuration.
> + *
> + * Sampling will be disabled, preventing strange things from happening in our
> + * back. Hardware fifo content will be cleared.
> + * When successful, device will be left in the enabled state to allow further
> + * configuration.
> + */
> +static int zpa_power_on(const struct iio_dev     *indio_dev,
> +			const struct zpa_private *private)
> +{
> +	int err = regulator_enable(private->vdd);
> +
> +	if (err)
> +		return err;
> +
> +	zpa_dbg(indio_dev, "powered on");
> +
> +	err = zpa_enable_device(indio_dev);
> +	if (err)
> +		goto off;
> +
> +	err = zpa_reset_device(indio_dev);
> +	if (err)
> +		goto disable;
> +
> +	return 0;
> +
> +disable:
> +	zpa_disable_device(indio_dev);
> +off:
> +	regulator_disable(private->vdd);
> +
> +	zpa_dbg(indio_dev, "powered off");
> +	return err;
> +}
> +
> +/* Power off device, i.e. disable attached power regulator. */
> +static int zpa_power_off(const struct iio_dev     *indio_dev,
> +			 const struct zpa_private *private)
> +{
> +	int err = regulator_disable(private->vdd);
> +
> +	zpa_dbg(indio_dev, "powered off");
> +

inconsistent newline

> +	return err;
> +}
> +
> +/*
> + * Setup device for one shot / on demand mode.
> + *
> + * Output Data Rate is configured for the highest possible rate so that
> + * conversion time and power consumption are reduced to a minimum.
> + * Note that hardware internal averaging machinery (not implemented in this
> + * driver) is not applicable in this mode.
> + *
> + * Device must have been previously enabled before calling zpa_config_oneshot().
> + */
> +static int zpa_config_oneshot(const struct iio_dev *indio_dev,
> +			      int                   irq)
> +{
> +	const struct zpa_frequency *freq = zpa_highest_frequency();
> +	int                         err;
> +
> +	/* Setup highest available Output Data Rate for one shot mode. */
> +	err = zpa_write_byte(indio_dev, ZPA_CTRL_REG3_REG, freq->odr);
> +	if (err)
> +		return err;
> +
> +	if (irq > 0)
> +		/* Request interrupt when new sample is available. */
> +		err = zpa_write_byte(indio_dev, ZPA_CTRL_REG1_REG,
> +				     ~ZPA_CTRL_REG1_MASK_DATA_READY);
> +	if (err) {
> +		dev_err(zpa_iio2slave(indio_dev),
> +			"failed to setup one shot mode (%d)", err);
> +		return err;
> +	}
> +
> +	dev_dbg(zpa_iio2slave(indio_dev), "one shot mode setup @%sHz",
> +		freq->hz);
> +
> +	return 0;
> +}
> +
> +/*
> + * Clear remaining entries in hardware fifo.
> + *
> + * min_count argument is a hint corresponding to the known minimum number of
> + * samples currently living in the fifo. This allows to reduce the number of bus
> + * accesses by skipping status register read operation as long as we know for
> + * sure there are still entries left.
> + */
> +static int zpa_clear_fifo(const struct iio_dev *indio_dev,
> +			  unsigned int          min_count)
> +{
> +	int err;
> +
> +	if (!min_count) {
> +		/*
> +		 * No hint: read status register to determine whether fifo is
> +		 * empty or not.
> +		 */
> +		err = zpa_read_byte(indio_dev, ZPA_STATUS_REG);
> +		if (err < 0)
> +			goto err;
> +
> +		if (err & ZPA_STATUS_FIFO_E)
> +			/* Fifo is empty: nothing to trash. */
> +			return 0;
> +	}
> +
> +	/* Clear fifo. */
> +	do {
> +		/*
> +		 * A single fetch from pressure MSB register is enought to pop
> +		 * values out of fifo.
> +		 */
> +		err = zpa_read_byte(indio_dev, ZPA_PRESS_OUT_H_REG);
> +		if (err < 0)
> +			goto err;
> +
> +		if (min_count) {
> +			/*
> +			 * We know for sure there are at least min_count entries
> +			 * left in fifo. Skip status register read.
> +			 */
> +			min_count--;
> +			continue;
> +		}
> +
> +		err = zpa_read_byte(indio_dev, ZPA_STATUS_REG);
> +		if (err < 0)
> +			goto err;
> +
> +	} while (!(err & ZPA_STATUS_FIFO_E));
> +
> +	zpa_dbg(indio_dev, "fifo cleared");
> +	return 0;
> +
> +err:
> +	zpa_err(indio_dev, "failed to clear fifo (%d)", err);
> +	return err;
> +}
> +
> +/*
> + * Retrieve the most recent pressure sample from hardware fifo.
> + *
> + * Note that ZPA2326 hardware fifo stores pressure samples only.
> + */
> +static int zpa_dequeue_pressure(const struct iio_dev *indio_dev, u32 *pressure)
> +{
> +	int err = zpa_read_byte(indio_dev, ZPA_STATUS_REG);
> +
> +	if (err < 0)
> +		return err;
> +
> +	if (!(err & ZPA_STATUS_P_OR)) {
> +		/*
> +		 * Fifo has not overflown : retrieve newest sample. We need to
> +		 * pop values out until fifo is empty : last fetched pressure is
> +		 * the newest.
> +		 * In nominal cases, we should find a single queued sample only.
> +		 */
> +		int cleared = -1;
> +
> +		do {
> +			err = zpa_read_block(indio_dev, ZPA_PRESS_OUT_XL_REG, 3,
> +					     (u8 *)pressure);
> +			if (err)
> +				return err;
> +
> +			err = zpa_read_byte(indio_dev, ZPA_STATUS_REG);
> +			if (err < 0)
> +				return err;
> +
> +			cleared++;
> +		} while (!(err & ZPA_STATUS_FIFO_E));
> +
> +		if (cleared)
> +			/*
> +			 * Samples were pushed by hardware during previous
> +			 * rounds but we didn't consume them fast enought:

enough

> +			 * inform user.
> +			 */
> +			zpa_warn(indio_dev, "cleared %d fifo entries", cleared);
> +
> +		return 0;
> +	}
> +
> +	/* Fifo overrun : first sample dequeued from fifo is the newest. */
> +	zpa_warn(indio_dev, "fifo overflow");
> +
> +	err = zpa_read_block(indio_dev, ZPA_PRESS_OUT_XL_REG, 3,
> +			     (u8 *)pressure);
> +	if (err)
> +		return err;
> +
> +#define ZPA_FIFO_DEPTH (16U)
> +	/* Hardware fifo may hold no more than 16 pressure samples. */
> +	return zpa_clear_fifo(indio_dev, ZPA_FIFO_DEPTH - 1);
> +}
> +
> +/* Enqueue new channel samples to IIO buffer. */
> +static int zpa_fill_sample_buffer(struct iio_dev           *indio_dev,
> +				  const struct zpa_private *private)
> +{
> +	struct {
> +		u32 pressure;
> +		u16 temperature;

timestamp should be 8-byte aligned, padding needed

> +		u64 timestamp;
> +	}   sample;

extra spaces before 'sample'

> +	int err;
> +
> +	if (test_bit(0, indio_dev->active_scan_mask)) {
> +		/* Get current pressure from hardware fifo. */
> +		err = zpa_dequeue_pressure(indio_dev, &sample.pressure);

pressure is 4 bytes, but only 3 bytes are read; one byte uninitialized?

> +		if (err) {
> +			zpa_warn(indio_dev, "failed to fetch pressure (%d)",

here and elsewhere: why zpa_warn() on error?

> +				 err);
> +			return err;
> +		}
> +	}
> +
> +	if (test_bit(1, indio_dev->active_scan_mask)) {
> +		/* Get current temperature. */
> +		err = zpa_read_block(indio_dev, ZPA_TEMP_OUT_L_REG, 2,
> +				     (u8 *)&sample.temperature);
> +		if (err) {
> +			zpa_warn(indio_dev, "failed to fetch temperature (%d)",
> +				 err);
> +			return err;
> +		}
> +	}
> +
> +	/*
> +	 * Now push samples using timestamp stored either :
> +	 *   - by hardware interrupt handler if interrupt is available: see
> +	 *     zpa_handle_irq(),
> +	 *   - or oneshot completion polling machinery : see
> +	 *     zpa_trigger_oneshot().
> +	 */
> +	iio_push_to_buffers_with_timestamp(indio_dev, &sample,
> +					   private->timestamp);
> +	return 0;
> +}
> +
> +/******************************************************************************
> + * Power management
> + ******************************************************************************/
> +
> +#ifdef CONFIG_PM
> +static int zpa_runtime_suspend(struct device *slave)
> +{
> +	const struct iio_dev *indio_dev = dev_get_drvdata(slave);
> +
> +	if (pm_runtime_autosuspend_expiration(slave))
> +		/* Userspace changed autosuspend delay. */
> +		return -EAGAIN;
> +
> +	return zpa_power_off(indio_dev, zpa_iio2priv(indio_dev));
> +}
> +
> +static int zpa_runtime_resume(struct device *slave)
> +{
> +	const struct iio_dev *indio_dev = dev_get_drvdata(slave);
> +
> +	return zpa_power_on(indio_dev, zpa_iio2priv(indio_dev));
> +}
> +
> +const struct dev_pm_ops zpa_pm_ops = {
> +	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
> +				pm_runtime_force_resume)
> +	SET_RUNTIME_PM_OPS(zpa_runtime_suspend, zpa_runtime_resume, NULL)
> +};
> +EXPORT_SYMBOL_GPL(zpa_pm_ops);
> +
> +/* Request the PM layer to power supply the device. */
> +static int zpa_resume(const struct iio_dev *indio_dev)
> +{
> +	struct device *slave = zpa_iio2slave(indio_dev);
> +	int            err = pm_runtime_get_sync(slave);
> +
> +	if (err < 0)
> +		goto put;
> +
> +	if (err > 0) {
> +		/*
> +		 * Device was already power supplied: get it out of low power
> +		 * mode.
> +		 */
> +		err = zpa_enable_device(indio_dev);
> +		if (err)
> +			goto put;
> +
> +		/* Inform caller device was already power supplied. */
> +		return 1;
> +	}
> +
> +	/* Inform caller device has just been brought back to life. */
> +	return 0;
> +
> +put:
> +	pm_runtime_put_noidle(slave);
> +	return err;
> +}
> +
> +/*
> + * Schedule a power down using autosuspend feature of PM layer.
> + *
> + * Device is switched to low power mode at first to save power even when
> + * attached regulator is a "dummy" one.
> + */
> +static int zpa_suspend(const struct iio_dev *indio_dev)
> +{
> +	struct device *slave = zpa_iio2slave(indio_dev);
> +	int            err = zpa_disable_device(indio_dev);
> +
> +	pm_runtime_mark_last_busy(slave);
> +
> +	if (err)
> +		goto err;
> +
> +	err = pm_runtime_put_autosuspend(slave);
> +	if (err) {
> +		dev_warn(slave, "failed to autosuspend (%d)", err);
> +		goto err;
> +	}
> +
> +	return 0;
> +
> +err:
> +	pm_runtime_put_noidle(slave);
> +	return err;
> +}
> +
> +/* Setup runtime power management with autosuspend support. */
> +static void zpa_init_runtime(struct device *slave)
> +{
> +	pm_runtime_get_noresume(slave);
> +	pm_runtime_set_active(slave);
> +	pm_runtime_enable(slave);
> +	pm_runtime_set_autosuspend_delay(slave, 1000);
> +	pm_runtime_use_autosuspend(slave);
> +	pm_runtime_mark_last_busy(slave);
> +	pm_runtime_put_autosuspend(slave);
> +}
> +
> +static void zpa_fini_runtime(struct device *slave)
> +{
> +	pm_runtime_disable(slave);
> +	pm_runtime_set_suspended(slave);
> +}
> +#else /* !CONFIG_PM */
> +static int zpa_resume(const struct iio_dev *indio_dev)
> +{
> +	return zpa_enable_device(indio_dev);
> +}
> +
> +static int zpa_suspend(const struct iio_dev *indio_dev)
> +{
> +	return zpa_disable_device(indio_dev);
> +}
> +
> +#define zpa_init_runtime(_slave)
> +#define zpa_fini_runtime(_slave)
> +#endif /* !CONFIG_PM */
> +
> +/******************************************************************************
> + * Interrupt handling
> + ******************************************************************************/
> +
> +/*
> + * Hardware interrupt handler.
> + *
> + * Timestamps buffered samples as soon as possible then schedule threaded bottom

Timestamp

> + * half.
> + */
> +static irqreturn_t zpa_handle_irq(int irq, void *data)
> +{
> +	struct iio_dev *indio_dev = (struct iio_dev *)data;
> +
> +	if (iio_buffer_enabled(indio_dev)) {
> +		struct zpa_private *priv = zpa_iio2priv(indio_dev);
> +
> +		/* Timestamping needed for buffered sampling only. */
> +		priv->timestamp = iio_get_time_ns(indio_dev);
> +	}
> +
> +	return IRQ_WAKE_THREAD;
> +}
> +
> +/*
> + * Fetch interrupt status and acknowledge all interrupts.
> + *
> + * Called from threaded interrupt context.
> + */
> +static int zpa_acknowledge_irq(const struct iio_dev     *indio_dev,
> +			       const struct zpa_private *private)
> +{
> +	/*
> +	 * Device works according to a level interrupt scheme: reading interrupt
> +	 * status de-asserts interrupt line.
> +	 */
> +	int err = zpa_read_byte(indio_dev, ZPA_INT_SOURCE_REG);
> +
> +	if (err < 0)
> +		return err;
> +
> +	/* Data ready is the only interrupt source we requested. */
> +	if (!(err & ZPA_INT_SOURCE_DATA_READY)) {
> +		zpa_warn(indio_dev, "unexpected interrupt status %02x", err);
> +		return -ENODATA;
> +	}
> +
> +	/* New sample available: notify our internal trigger consumers. */
> +	iio_trigger_poll_chained(private->trigger);
> +
> +	return 0;
> +}
> +
> +/*
> + * Interrupt bottom-half handler.
> + *
> + * Mainly ensures interrupt is caused by a real "new sample available"
> + * condition. This relies upon the ability to perform blocking / sleeping bus
> + * accesses to slave's registers. This is why zpa_handle_threaded_irq() is
> + * called from within a thread, i.e. not called from hard interrupt context.
> + */
> +static irqreturn_t zpa_handle_threaded_irq(int irq, void *data)
> +{
> +	struct iio_dev     *indio_dev = (struct iio_dev *)data;
> +	struct zpa_private *priv = zpa_iio2priv(indio_dev);
> +	irqreturn_t         ret = IRQ_NONE;
> +
> +	priv->result = zpa_acknowledge_irq(indio_dev, priv);
> +
> +	if (indio_dev->currentmode == INDIO_BUFFER_SOFTWARE) {
> +		/* Continuous sampling enabled. */
> +
> +		if (!priv->result)
> +			/* Populate IIO buffer */
> +			zpa_fill_sample_buffer(indio_dev, priv);
> +		/*
> +		 * Tell power management layer we've just used the device to
> +		 * prevent from autosuspending to early.
> +		 */
> +		pm_runtime_mark_last_busy(zpa_iio2slave(indio_dev));
> +
> +		return (!priv->result) ? IRQ_HANDLED : IRQ_NONE;
> +	}
> +
> +	if (priv->result)
> +		/*
> +		 * Interrupt happened but no new sample available: likely caused
> +		 * by spurious interrupts, in which case, returning IRQ_NONE
> +		 * allows to benefit from the generic spurious interrupts
> +		 * handling.
> +		 */
> +		goto complete;
> +
> +	if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED)
> +		priv->result = zpa_fill_sample_buffer(indio_dev, priv);
> +
> +	ret = IRQ_HANDLED;
> +
> +complete:
> +	/*
> +	 * Wake up direct or triggered buffer mode waiters: see
> +	 * zpa_sample_oneshot() and zpa_trigger_oneshot().
> +	 */
> +	complete(&priv->data_ready);
> +	return ret;
> +}
> +
> +/* Wait for oneshot data ready interrupt. */
> +static int zpa_wait_oneshot_completion(const struct iio_dev *indio_dev,
> +				       struct zpa_private   *private)
> +{
> +	int err = wait_for_completion_interruptible_timeout(
> +			&private->data_ready, ZPA_CONVERSION_TIMEOUT);
> +
> +	if (err > 0)
> +		/*
> +		 * Interrupt handler completed before timeout: return operation
> +		 * status.
> +		 */
> +		return private->result;
> +
> +	/* Clear all interrupts just to be sure. */
> +	zpa_read_byte(indio_dev, ZPA_INT_SOURCE_REG);
> +
> +	if (!err)
> +		/* Timed out. */
> +		err = -ETIME;
> +
> +	if (err != -ERESTARTSYS)
> +		zpa_warn(indio_dev, "no one shot interrupt occurred (%d)", err);
> +
> +	return err;
> +}
> +
> +/* Setup interrupt handling. */
> +static int zpa_init_irq(struct device      *slave,
> +			struct iio_dev     *indio_dev,
> +			struct zpa_private *private,
> +			int                 irq)
> +{
> +	int err;
> +
> +	if (irq <= 0) {
> +		/*
> +		 * Platform declared no interrupt line: device will be polled
> +		 * for data availability.
> +		 */
> +		private->irq = -1;
> +		dev_info(slave, "no interrupt found, running in polling mode");
> +		return 0;
> +	}
> +
> +	private->irq = irq;
> +	init_completion(&private->data_ready);
> +
> +	/* Request handler to be scheduled into threaded interrupt context. */
> +	err = devm_request_threaded_irq(slave, irq, zpa_handle_irq,
> +					zpa_handle_threaded_irq,
> +					IRQF_TRIGGER_RISING | IRQF_ONESHOT,
> +					dev_name(slave), indio_dev);
> +	if (err) {
> +		dev_err(slave, "failed to request interrupt %d (%d)", irq, err);
> +		return err;
> +	}
> +
> +	dev_info(slave, "using interrupt %d", irq);
> +	return 0;
> +}
> +
> +/******************************************************************************
> + * Direct sampling
> + ******************************************************************************/
> +
> +/*
> + * Ensure exclusive access to prevent from modifying device setup in the back of
> + * ongoing operations.
> + * In the mean time, power on device to get access to the complete register map.
> + */
> +static int zpa_claim_direct_mode(struct iio_dev *indio_dev)
> +{
> +	/* Gain exclusive access for userspace usage. */
> +	int err = iio_device_claim_direct_mode(indio_dev);
> +
> +	if (err)
> +		return err;
> +
> +	/* Bring device back to life. */
> +	err = zpa_resume(indio_dev);
> +	if (err < 0)
> +		goto release;
> +
> +	return err;
> +
> +release:
> +	/* Relinquish exclusive access. */
> +	iio_device_release_direct_mode(indio_dev);
> +	return err;
> +}
> +
> +/* Release exclusive acces to device. Device is also powered down. */
> +static void zpa_release_direct_mode(struct iio_dev *indio_dev)
> +{
> +	zpa_suspend(indio_dev);
> +	iio_device_release_direct_mode(indio_dev);
> +}
> +
> +/* Actively poll for one shot data ready. */
> +static int zpa_poll_oneshot_completion(const struct iio_dev *indio_dev)
> +{
> +	unsigned long tmout = jiffies + ZPA_CONVERSION_TIMEOUT;
> +	int           err;
> +
> +	/*
> +	 * At least, 100 ms is needed for the device to complete its one-shot
> +	 * cycle.
> +	 */
> +	if (msleep_interruptible(100))
> +		return -ERESTARTSYS;
> +
> +	/* Poll for conversion completion in hardware. */
> +	while (true) {
> +		err = zpa_read_byte(indio_dev, ZPA_CTRL_REG0_REG);
> +		if (err < 0)
> +			goto err;
> +
> +		if (!(err & ZPA_CTRL_REG0_ONE_SHOT))
> +			/* One-shot bit self clears at conversion end. */
> +			break;
> +
> +		if (time_after(jiffies, tmout)) {
> +			/* Prevent from waiting forever : let's time out. */
> +			err = -ETIME;
> +			goto err;
> +		}
> +
> +		usleep_range(10000, 20000);
> +	}
> +
> +	/*
> +	 * In oneshot mode, pressure sample availability guarantees that
> +	 * temperature conversion has also completed : just check pressure
> +	 * status bit to keep things simple.
> +	 */
> +	err = zpa_read_byte(indio_dev, ZPA_STATUS_REG);
> +	if (err < 0)
> +		goto err;
> +
> +	if (!(err & ZPA_STATUS_P_DA)) {
> +		/* No sample available. */
> +		err = -ENODATA;
> +		goto err;
> +	}
> +
> +	return 0;
> +
> +err:
> +	zpa_warn(indio_dev, "failed to poll one shot completion (%d)", err);
> +	return err;
> +}
> +
> +/* Retrieve a raw sample and convert it to CPU endianness. */
> +static int zpa_fetch_raw_sample(const struct iio_dev *indio_dev,
> +				enum iio_chan_type    type,
> +				int                  *value)
> +{
> +	int err;
> +
> +	switch (type) {
> +	case IIO_PRESSURE:
> +		zpa_dbg(indio_dev, "fetching raw pressure sample");
> +
> +		err = zpa_read_block(indio_dev, ZPA_PRESS_OUT_XL_REG, 3,
> +				     (u8 *)value);
> +		if (err) {
> +			zpa_warn(indio_dev, "failed to fetch pressure (%d)",
> +				 err);
> +			return err;
> +		}
> +
> +		/* Pressure is a 24 bits wide little-endian unsigned int. */
> +		*value = (((u8 *)value)[2] << 16) | (((u8 *)value)[1] << 8) |
> +			 ((u8 *)value)[0];
> +
> +		return IIO_VAL_INT;
> +
> +	case IIO_TEMP:
> +		zpa_dbg(indio_dev, "fetching raw temperature sample");
> +
> +		err = zpa_read_block(indio_dev, ZPA_TEMP_OUT_L_REG, 2,
> +				     (u8 *)value);
> +		if (err) {
> +			zpa_warn(indio_dev, "failed to fetch temperature (%d)",
> +				 err);
> +			return err;
> +		}
> +
> +		/* Temperature is a 16 bits wide little-endian signed int. */
> +		*value = (int)le16_to_cpup((__le16 *)value);
> +
> +		return IIO_VAL_INT;
> +
> +	default:
> +		BUG();

return -EINVAL

> +	}
> +}
> +
> +/* Perform a complete one shot sampling cycle. */
> +static int zpa_sample_oneshot(struct iio_dev     *indio_dev,
> +			      enum iio_chan_type  type,
> +			      int                *value)
> +{
> +	/* Gain exclusive access to device. */
> +	int                 err = zpa_claim_direct_mode(indio_dev);
> +	struct zpa_private *priv = zpa_iio2priv(indio_dev);
> +
> +	if (err < 0)
> +		return err;
> +
> +	if (err > 0) {
> +		/*
> +		 * We were already power supplied. Just clear hardware fifo to
> +		 * get rid of samples acquired during previous rounds (if any).
> +		 * Sampling operation always generates both temperature and
> +		 * pressure samples. The latter are always enqueued into
> +		 * hardware fifo. This may lead to situations were pressure
> +		 * samples still sit into fifo when previous cycle(s) fetched
> +		 * temperature data only.
> +		 * Hence, we need to clear hardware fifo content to prevent from
> +		 * getting outdated values at the end of current cycle.
> +		 */
> +		if (type == IIO_PRESSURE) {
> +			err = zpa_clear_fifo(indio_dev, 0);
> +			if (err)
> +				goto release;
> +		}
> +	} else {
> +		/*
> +		 * We have just been power supplied, i.e. device is in default
> +		 * "out of reset" state, meaning we need to reconfigure it
> +		 * entirely.
> +		 */
> +		err = zpa_config_oneshot(indio_dev, priv->irq);
> +		if (err)
> +			goto release;
> +	}
> +
> +	/* Start a sampling cycle in oneshot mode. */
> +	err = zpa_start_oneshot(indio_dev);
> +	if (err)
> +		goto release;
> +
> +	/* Wait for sampling cycle to complete. */
> +	zpa_dbg(indio_dev, "waiting for one shot completion");
> +
> +	if (priv->irq > 0)
> +		err = zpa_wait_oneshot_completion(indio_dev, priv);
> +	else
> +		err = zpa_poll_oneshot_completion(indio_dev);
> +
> +	if (err)
> +		goto release;
> +
> +	/* Retrieve raw sample value and convert it to CPU endianness. */
> +	err = zpa_fetch_raw_sample(indio_dev, type, value);
> +
> +release:
> +	zpa_release_direct_mode(indio_dev);
> +	return err;
> +}
> +
> +/******************************************************************************
> + * Buffering handling
> + ******************************************************************************/
> +
> +/*
> + * Reject external trigger attachment if setting up continuous hardware sampling
> + * mode.
> + */
> +static int zpa_validate_trigger(struct iio_dev     *indio_dev,
> +				struct iio_trigger *trigger)
> +{
> +	int ret = 0;
> +
> +	mutex_lock(&indio_dev->mlock);
> +
> +	if (indio_dev->currentmode == INDIO_BUFFER_SOFTWARE)
> +		ret = -EBUSY;
> +
> +	mutex_unlock(&indio_dev->mlock);
> +
> +	return ret;
> +}
> +
> +/* Finalize one shot cycle processing in triggered sampling mode. */
> +static void zpa_complete_oneshot_trigger(const struct iio_dev *indio_dev)
> +{
> +	/*
> +	 * Tell power management layer we've just used the device to prevent
> +	 * from autosuspending to early.
> +	 */
> +	pm_runtime_mark_last_busy(zpa_iio2slave(indio_dev));
> +
> +	/* Inform attached trigger we are done. */
> +	iio_trigger_notify_done(indio_dev->trig);
> +}
> +
> +/*
> + * Perform an IIO buffered sampling round in one shot mode.
> + *
> + * Handler called by the IIO trigger currently attached to device. Allows to
> + * synchronize this device buffered sampling with external events (such as timer
> + * expiration, external device sample ready, etc...).
> + * Basically run the same sequence of operations as for zpa_sample_oneshot()
> + * with the following exceptions:
> + *   - hardware fifo is not cleared since already done at buffering enable time
> + *     and samples dequeueing always retrieves the most recent value,
> + *   - samples endianness is not processed since delegated to userspace in
> + *     buffered mode.
> + */
> +static irqreturn_t zpa_trigger_oneshot(int irq, void *data)
> +{
> +	struct iio_poll_func *pf = data;
> +	struct iio_dev       *indio_dev = pf->indio_dev;
> +	struct zpa_private   *priv = zpa_iio2priv(indio_dev);
> +
> +	/* Start a one shot sampling cycle. */
> +	if (zpa_start_oneshot(indio_dev))
> +		goto err;
> +
> +	if (priv->irq <= 0) {
> +		/* No interrupt available: poll for sampling completion. */
> +		if (zpa_poll_oneshot_completion(indio_dev))
> +			goto disable;
> +
> +		/* Only timestamp sample once it is ready. */
> +		priv->timestamp = iio_get_time_ns(indio_dev);
> +
> +		/* Enqueue to IIO buffer / userspace. */
> +		zpa_fill_sample_buffer(indio_dev, priv);
> +	} else {
> +		/* Interrupt handlers will timestamp and get samples for us. */
> +		if (zpa_wait_oneshot_completion(indio_dev, priv))
> +			goto disable;
> +	}
> +
> +	zpa_complete_oneshot_trigger(indio_dev);
> +	return IRQ_HANDLED;
> +
> +disable:
> +	zpa_disable_device(indio_dev);
> +err:
> +	zpa_complete_oneshot_trigger(indio_dev);
> +	return IRQ_NONE;
> +}
> +
> +/*
> + * Get device ready for configuration of continuous / triggered sampling modes.
> + *
> + * Called with IIO device's lock held.
> + */
> +static int zpa_preenable_ring(struct iio_dev *indio_dev)
> +{
> +	int err = zpa_resume(indio_dev);
> +
> +	if (err < 0)
> +		return err;
> +
> +	if (err > 0) {
> +		/*
> +		 * We were already power supplied. Just clear hardware fifo to
> +		 * get rid of samples acquired during previous rounds (if any).
> +		 */
> +		err = zpa_clear_fifo(indio_dev, 0);
> +		if (err) {
> +			zpa_suspend(indio_dev);
> +			return err;
> +		}
> +
> +		zpa_iio2priv(indio_dev)->waken = false;
> +		return 0;
> +	}
> +
> +	/* Tell zpa_postenable_ring() we have just been powered on. */
> +	zpa_iio2priv(indio_dev)->waken = true;
> +	return 0;
> +}
> +
> +/*
> + * Configure and start continuous / triggered sampling.
> + *
> + * Called with IIO device's lock held.
> + * If an error is returned, IIO layer will call our postdisable hook for us,
> + * i.e. no need to explicitly power device off here.
> + */
> +static int zpa_postenable_ring(struct iio_dev *indio_dev)
> +{
> +	const struct zpa_private *priv = zpa_iio2priv(indio_dev);
> +	int                       err;
> +
> +	if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
> +		/* Prepare device for triggered buffering usage. */
> +
> +		if (priv->waken) {
> +			/*
> +			 * We have just been power supplied, i.e. device is in
> +			 * default "out of reset" state, meaning we need to
> +			 * properly reconfigure it for on trigger demand usage.
> +			 */
> +			err = zpa_config_oneshot(indio_dev, priv->irq);
> +			if (err)
> +				return err;
> +		}
> +
> +		/* Plug our own trigger event handler. */
> +		err = iio_triggered_buffer_postenable(indio_dev);
> +		if (err)
> +			return err;
> +
> +		/*
> +		 * Switch back to low power. A complete one shot sampling cycle
> +		 * will be started upon trigger notification.
> +		 */
> +		return zpa_disable_device(indio_dev);
> +	}
> +
> +	/* Prepare then start continuous sampling session. */
> +
> +	if (priv->waken) {
> +		/*
> +		 * We have just been power supplied, i.e. device is in default
> +		 * "out of reset" state, meaning we need to unmask data ready
> +		 * interrupt to process new samples.
> +		 */
> +		err = zpa_write_byte(indio_dev, ZPA_CTRL_REG1_REG,
> +				     ~ZPA_CTRL_REG1_MASK_DATA_READY);
> +		if (err)
> +			goto err;
> +	}
> +
> +	/* Start continuous sampling at required frequency. */
> +	err = zpa_write_byte(indio_dev, ZPA_CTRL_REG3_REG,
> +			     ZPA_CTRL_REG3_ENABLE_MEAS | priv->frequency->odr);
> +	if (err)
> +		goto err;
> +
> +	zpa_dbg(indio_dev, "continuous mode setup @%sHz", priv->frequency->hz);
> +	return 0;
> +
> +err:
> +	zpa_err(indio_dev, "failed to setup continuous mode (%d)", err);
> +	return err;
> +}
> +
> +/*
> + * Stop continuous / triggered sampling.
> + *
> + * Called with IIO device's lock held.
> + */
> +static int zpa_predisable_ring(struct iio_dev *indio_dev)
> +{
> +	if (indio_dev->currentmode == INDIO_BUFFER_SOFTWARE) {
> +		int irq = zpa_iio2priv(indio_dev)->irq;
> +		int err;
> +
> +		/*
> +		 * As device is working in continuous mode, handlers may be
> +		 * accessing resources we are currently freeing...
> +		 * Prevent this by disabling interrupt handlers and ensure
> +		 * the device will generate no more interrupts unless explicitly
> +		 * required to, i.e. by restoring back to default one shot mode.
> +		 */
> +		disable_irq(irq);
> +
> +		/*
> +		 * Disable continuous sampling mode to restore settings for
> +		 * one shot / direct sampling operations.
> +		 */
> +		err = zpa_write_byte(indio_dev, ZPA_CTRL_REG3_REG,
> +				     zpa_highest_frequency()->odr);
> +		if (err)
> +			goto err;
> +
> +		/*
> +		 * Now that device won't generate interrupts on its own,
> +		 * acknowledge any currently active interrupts (may happen on
> +		 * rare occasions while stopping continuous mode).
> +		 */
> +		err = zpa_read_byte(indio_dev, ZPA_INT_SOURCE_REG);
> +		if (err < 0)
> +			goto err;
> +
> +		/*
> +		 * Re-enable interrupts only if we can guarantee the device will
> +		 * generate no more interrupts to prevent handlers from
> +		 * accessing released resources.
> +		 */
> +		enable_irq(irq);
> +		return 0;
> +
> +err:
> +		zpa_err(indio_dev,
> +			"failed to stop buffering, leaving interrupt disabled... (%d)",
> +			err);
> +		return err;
> +	}
> +
> +	/* Triggered buffering: unplug our own trigger event handler. */
> +	return iio_triggered_buffer_predisable(indio_dev);
> +}
> +
> +/* Called with IIO device's lock held. */
> +static int zpa_postdisable_ring(struct iio_dev *indio_dev)
> +{
> +	return zpa_suspend(indio_dev);
> +}
> +
> +static const struct iio_buffer_setup_ops zpa_ring_setup_ops = {
> +	.preenable   = zpa_preenable_ring,
> +	.postenable  = zpa_postenable_ring,
> +	.predisable  = zpa_predisable_ring,
> +	.postdisable = zpa_postdisable_ring,
> +};
> +
> +/* Setup buffered sampling. */
> +static int zpa_init_ring(struct device  *slave,
> +			 struct iio_dev *indio_dev,
> +			 int             irq)
> +{
> +	int err = devm_iio_triggered_buffer_setup(slave, indio_dev, NULL,
> +						  zpa_trigger_oneshot,
> +						  &zpa_ring_setup_ops);
> +	if (err)
> +		return err;
> +
> +	if (irq > 0)
> +		/* Allow continuous hardware sampling if interrupt available. */
> +		indio_dev->modes |= INDIO_BUFFER_SOFTWARE;
> +
> +	return 0;
> +}
> +
> +/******************************************************************************
> + * Hardware trigger handling
> + ******************************************************************************/
> +
> +/*
> + * Using our own interrupt driven trigger to start a triggered buffer sampling
> + * round is pure nonsense: use continuous hardware sampling mode instead, i.e.
> + * INDIO_BUFFER_SOFTWARE. Or synchronize against an external trigger / device.
> + */
> +static int zpa_validate_device(struct iio_trigger *trigger,
> +			       struct iio_dev     *indio_dev)
> +{
> +	if (indio_dev == (struct iio_dev *)iio_trigger_get_drvdata(trigger))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static const struct iio_trigger_ops zpa_trigger_ops = {
> +	.owner             = THIS_MODULE,
> +	.validate_device   = zpa_validate_device,
> +};
> +
> +/*
> + * Create an interrupt driven / hardware trigger allowing to notify external
> + * devices a new sample is ready.
> + */
> +static int zpa_init_trigger(struct device      *slave,
> +			    struct iio_dev     *indio_dev,
> +			    struct zpa_private *private,
> +			    int                 irq)
> +{
> +	struct iio_trigger *trigger;
> +	int                 err;
> +
> +	if (irq <= 0)
> +		return 0;
> +
> +	trigger = devm_iio_trigger_alloc(slave, "%s-sample-ready-dev%d",
> +					 indio_dev->name, indio_dev->id);
> +	if (!trigger)
> +		return -ENOMEM;
> +
> +	/* Basic setup. */
> +	trigger->dev.parent = slave;
> +	trigger->ops = &zpa_trigger_ops;
> +	iio_trigger_set_drvdata(trigger, indio_dev);
> +
> +	private->trigger = trigger;
> +
> +	/* Register to triggers space. */
> +	err = devm_iio_trigger_register(slave, trigger);
> +	if (err)
> +		dev_err(slave, "failed to register hardware trigger (%d)", err);
> +
> +	return err;
> +}
> +
> +/******************************************************************************
> + * Debugfs stuff
> + *
> + * Note this is mostly unusable with power management enabled systems since
> + * registers content is lost during power off -> on transitions.
> + ******************************************************************************/
> +
> +#if defined(CONFIG_DEBUG_FS)
> +#define zpa_debugfs_ptr(_ptr) _ptr
> +
> +static int zpa_debugfs_read(struct iio_dev *indio_dev,
> +			    u8              reg,
> +			    unsigned int   *value)
> +{
> +	int err;
> +
> +	switch (reg) {
> +	case ZPA_REF_P_XL_REG:
> +	case ZPA_REF_P_L_REG:
> +	case ZPA_REF_P_H_REG:
> +	case ZPA_DEVICE_ID_REG:
> +	case ZPA_RES_CONF_REG:
> +	case ZPA_CTRL_REG0_REG:
> +	case ZPA_CTRL_REG1_REG:
> +	case ZPA_CTRL_REG2_REG:
> +	case ZPA_CTRL_REG3_REG:
> +	case ZPA_INT_SOURCE_REG: /* Will acknowledge interrupts. */
> +	case ZPA_THS_P_LOW_REG:
> +	case ZPA_THS_P_HIGH_REG:
> +	case ZPA_STATUS_REG:
> +	case ZPA_PRESS_OUT_XL_REG:
> +	case ZPA_PRESS_OUT_L_REG:
> +	case ZPA_PRESS_OUT_H_REG:  /* Will pop samples out of hardware fifo. */
> +	case ZPA_TEMP_OUT_L_REG:
> +	case ZPA_TEMP_OUT_H_REG:
> +		break;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	err = zpa_claim_direct_mode(indio_dev);
> +	if (err < 0)
> +		return err;
> +
> +	err = zpa_read_byte(indio_dev, reg);
> +	if (err < 0)
> +		goto release;
> +
> +	*value = err;
> +	err = 0;
> +
> +release:
> +	zpa_release_direct_mode(indio_dev);
> +	return err;
> +}
> +
> +static int zpa_debugfs_write(struct iio_dev *indio_dev,
> +			     u8              reg,
> +			     unsigned int    value)
> +{
> +	int err;
> +
> +	switch (reg) {
> +	/* Read only registers */
> +	case ZPA_DEVICE_ID_REG:
> +	case ZPA_INT_SOURCE_REG:
> +	case ZPA_STATUS_REG:
> +	case ZPA_PRESS_OUT_XL_REG:
> +	case ZPA_PRESS_OUT_L_REG:
> +	case ZPA_PRESS_OUT_H_REG:
> +	case ZPA_TEMP_OUT_L_REG:
> +	case ZPA_TEMP_OUT_H_REG:
> +		return -EPERM;
> +
> +	/* Read/write registers */
> +	case ZPA_REF_P_XL_REG:
> +	case ZPA_REF_P_L_REG:
> +	case ZPA_REF_P_H_REG:
> +	case ZPA_RES_CONF_REG:
> +	case ZPA_CTRL_REG0_REG:
> +	case ZPA_CTRL_REG1_REG:
> +	case ZPA_CTRL_REG2_REG:
> +	case ZPA_CTRL_REG3_REG:
> +	case ZPA_THS_P_LOW_REG:
> +	case ZPA_THS_P_HIGH_REG:
> +		break;
> +
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	if (value > U8_MAX)
> +		return -ERANGE;
> +
> +	err = zpa_claim_direct_mode(indio_dev);
> +	if (err < 0)
> +		return err;
> +
> +	err = zpa_write_byte(indio_dev, reg, value);
> +
> +	zpa_release_direct_mode(indio_dev);
> +	return err;
> +}
> +
> +static int zpa_debugfs_reg_access(struct iio_dev *indio_dev,
> +				  unsigned int    reg,
> +				  unsigned int    writeval,
> +				  unsigned int   *readval)
> +{
> +	if (readval)
> +		return zpa_debugfs_read(indio_dev, reg, readval);
> +
> +	return zpa_debugfs_write(indio_dev, reg, writeval);
> +}
> +#else
> +#define zpa_debugfs_ptr(_ptr) NULL
> +#endif
> +
> +/******************************************************************************
> + * IIO device handling
> + ******************************************************************************/
> +
> +static int zpa_read_raw(struct iio_dev             *indio_dev,
> +			struct iio_chan_spec const *chan,
> +			int                        *val,
> +			int                        *val2,
> +			long                        mask)
> +{
> +	switch (mask) {
> +	case IIO_CHAN_INFO_RAW:
> +		return zpa_sample_oneshot(indio_dev, chan->type, val);
> +
> +	case IIO_CHAN_INFO_SCALE:
> +		switch (chan->type) {
> +		case IIO_PRESSURE:
> +			/*
> +			 * Pressure resolution is 1/64 Pascal. Scale to kPascal
> +			 * as required by IIO ABI.
> +			 */
> +			*val = 0;
> +			*val2 = 1000000 / 64;
> +			return IIO_VAL_INT_PLUS_NANO;
> +
> +		case IIO_TEMP:
> +			/*
> +			 * Temperature follows the equation:
> +			 *     Temp[degC] = Tempcode * 0.00649 - 176.83
> +			 * where:
> +			 *     Tempcode is composed the raw sampled 16 bits.
> +			 *
> +			 * Hence, to produce a temperature in milli-degrees
> +			 * Celsius according to IIO ABI, we need to apply the
> +			 * following equation to raw samples:
> +			 *     Temp[milli degC] = (Tempcode + Offset) * Scale
> +			 * where:
> +			 *     Offset = -176.83 / 0.00649
> +			 *     Scale = 0.00649 * 1000
> +			 */
> +			*val = 6;
> +			*val2 = 490000;
> +			return IIO_VAL_INT_PLUS_MICRO;
> +
> +		default:
> +			BUG();
> +		}
> +
> +	case IIO_CHAN_INFO_OFFSET:
> +		BUG_ON(chan->type != IIO_TEMP);
> +		*val = -17683000 / 649;
> +		*val2 = ((17683000 % 649) * 1000000000ULL) / 649ULL;
> +		return IIO_VAL_INT_PLUS_NANO;
> +
> +	default:
> +		BUG();

return -EINVAL

> +	}
> +}
> +
> +/* Current hardware sampling frequency sysfs getter. */

comment is pretty obvious

> +static ssize_t zpa_show_frequency(struct device           *dev,
> +				  struct device_attribute *attr,
> +				  char                    *buf)
> +{
> +	const struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> +
> +	return sprintf(buf, "%s\n", zpa_iio2priv(indio_dev)->frequency->hz);
> +}
> +
> +/* Current hardware sampling frequency sysfs setter. */
> +static ssize_t zpa_store_frequency(struct device           *dev,
> +				   struct device_attribute *attr,
> +				   const char              *buf,
> +				   size_t                   len)
> +{
> +	struct iio_dev     *indio_dev = dev_to_iio_dev(dev);
> +	struct zpa_private *priv = zpa_iio2priv(indio_dev);
> +	int                 f, err;
> +
> +	/* Check if requested frequency is supported. */
> +	for (f = 0; f < ARRAY_SIZE(zpa_sampling_frequencies); f++)
> +		if (sysfs_streq(zpa_sampling_frequencies[f].hz, buf))
> +			break;
> +	if (f == ARRAY_SIZE(zpa_sampling_frequencies))
> +		return -EINVAL;
> +
> +	/* Don't allow changing frequency if buffered sampling is ongoing. */
> +	err = iio_device_claim_direct_mode(indio_dev);
> +	if (err)
> +		return err;
> +
> +	priv->frequency = &zpa_sampling_frequencies[f];
> +
> +	iio_device_release_direct_mode(indio_dev);
> +
> +	return len;
> +}
> +
> +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
> +			      zpa_show_frequency,
> +			      zpa_store_frequency);
> +
> +/* Expose supported hardware sampling frequencies (Hz) through sysfs. */
> +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1 5 11 23");
> +
> +static struct attribute *zpa_attributes[] = {
> +	&iio_dev_attr_sampling_frequency.dev_attr.attr,
> +	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
> +	NULL
> +};
> +
> +static const struct attribute_group zpa_attribute_group = {
> +	.attrs = zpa_attributes,
> +};
> +
> +static const struct iio_chan_spec zpa_channels[] = {
> +	[0] = {
> +		.type                   = IIO_PRESSURE,
> +		.channel                = 0,

.channel is not needed since channels are not indexed

> +		.scan_index             = 0,
> +		.scan_type              = {
> +			.sign                   = 'u',
> +			.realbits               = 24,
> +			.storagebits            = 32,
> +			.endianness             = IIO_LE,
> +		},
> +		.info_mask_separate     = BIT(IIO_CHAN_INFO_RAW) |
> +					  BIT(IIO_CHAN_INFO_SCALE),
> +	},
> +	[1] = {
> +		.type                   = IIO_TEMP,
> +		.channel                = 1,
> +		.scan_index             = 1,
> +		.scan_type              = {
> +			.sign                   = 's',
> +			.realbits               = 16,
> +			.storagebits            = 16,
> +			.endianness             = IIO_LE,
> +		},
> +		.info_mask_separate     = BIT(IIO_CHAN_INFO_RAW) |
> +					  BIT(IIO_CHAN_INFO_SCALE) |
> +					  BIT(IIO_CHAN_INFO_OFFSET),
> +	},
> +	[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
> +};
> +
> +static const struct iio_info zpa_info = {
> +	.driver_module      = THIS_MODULE,
> +	.attrs              = &zpa_attribute_group,
> +	.read_raw           = zpa_read_raw,
> +	.debugfs_reg_access = zpa_debugfs_ptr(zpa_debugfs_reg_access),
> +	.validate_trigger   = zpa_validate_trigger,
> +};
> +
> +/* Allocate and initialize a basic ZPA IIO device. */
> +static struct iio_dev *zpa_create_iio(struct device        *device,
> +				      const char           *name,
> +				      const struct zpa_bus *bus)
> +{
> +	struct iio_dev *indio_dev;
> +
> +	/* Allocate space to hold IIO device internal state. */
> +	indio_dev = devm_iio_device_alloc(device, sizeof(struct zpa_private));
> +	if (!indio_dev)
> +		return NULL;
> +
> +	/* Setup for userspace synchronous on demand sampling. */
> +	indio_dev->modes = INDIO_DIRECT_MODE;
> +	indio_dev->dev.parent = device;
> +	indio_dev->channels = zpa_channels;
> +	indio_dev->num_channels = ARRAY_SIZE(zpa_channels);
> +	indio_dev->name = name;
> +	indio_dev->info = &zpa_info;
> +
> +	/* Plug device's underlying bus abstraction. */
> +	zpa_iio2priv(indio_dev)->bus = bus;
> +
> +	/* Init hardware sampling frequency to highest rate supported. */
> +	zpa_iio2priv(indio_dev)->frequency = zpa_highest_frequency();
> +
> +	return indio_dev;
> +}
> +
> +int zpa_probe(struct device        *slave,
> +	      const char           *name,
> +	      int                   irq,
> +	      const struct zpa_bus *bus)
> +{
> +	struct iio_dev     *indio_dev = zpa_create_iio(slave, name, bus);
> +	struct zpa_private *priv;
> +	int                 err;
> +
> +	if (!indio_dev)
> +		return -ENOMEM;
> +
> +	priv = zpa_iio2priv(indio_dev);
> +
> +	priv->vdd = devm_regulator_get(slave, "vdd");
> +	if (IS_ERR(priv->vdd))
> +		return PTR_ERR(priv->vdd);
> +
> +	err = zpa_power_on(indio_dev, priv);
> +	if (err)
> +		return err;
> +
> +	err = zpa_init_ring(slave, indio_dev, irq);
> +	if (err)
> +		goto disable;
> +
> +	err = zpa_init_trigger(slave, indio_dev, priv, irq);
> +	if (err)
> +		goto disable;
> +
> +	err = zpa_init_irq(slave, indio_dev, priv, irq);
> +	if (err)
> +		goto disable;
> +
> +	err = zpa_config_oneshot(indio_dev, irq);
> +	if (err)
> +		goto disable;
> +
> +	err = zpa_disable_device(indio_dev);
> +	if (err)
> +		goto off;
> +
> +	dev_set_drvdata(slave, indio_dev);
> +
> +	zpa_init_runtime(slave);
> +
> +	err = devm_iio_device_register(slave, indio_dev);

can't use devm_ register if there is a non-empty remove()


> +	if (err) {
> +		zpa_fini_runtime(slave);
> +		goto off;
> +	}
> +
> +	dev_dbg(slave, "%s barometer ready", name);
> +	return 0;
> +
> +disable:
> +	zpa_disable_device(indio_dev);
> +off:
> +	zpa_power_off(indio_dev, priv);
> +	return err;
> +}
> +EXPORT_SYMBOL_GPL(zpa_probe);
> +
> +int zpa_remove(const struct device *slave)
> +{
> +	const struct iio_dev *indio_dev = dev_get_drvdata(slave);
> +
> +	zpa_fini_runtime(zpa_iio2slave(indio_dev));
> +	zpa_disable_device(indio_dev);
> +	zpa_power_off(indio_dev, zpa_iio2priv(indio_dev));
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(zpa_remove);
> +
> +MODULE_AUTHOR("Gregor Boirie <gregor.boirie@xxxxxxxxxx>");
> +MODULE_DESCRIPTION("Core driver for Murata ZPA2326 pressure sensor");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iio/pressure/zpa2326.h b/drivers/iio/pressure/zpa2326.h
> new file mode 100644
> index 0000000..df105cb
> --- /dev/null
> +++ b/drivers/iio/pressure/zpa2326.h
> @@ -0,0 +1,76 @@
> +/*
> + * Murata ZPA2326 pressure and temperature sensor IIO driver
> + *
> + * Copyright (c) 2016 Parrot S.A.
> + *
> + * Author: Gregor Boirie <gregor.boirie@xxxxxxxxxx>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + */
> +
> +#ifndef _ZPA2326_H
> +#define _ZPA2326_H
> +
> +#include <linux/iio/iio.h>
> +
> +#define ZPA_DEVICE_ID_REG              ((u8)0xf)
> +#define ZPA_DEVICE_ID                  (0xb9)
> +
> +/*
> + * struct zpa_bus - underlying I2C / SPI bus adapter for zpa2326 driver
> + * @zpa_read_byte:  fetch and return a single byte from slave register
> + * @zpa_write_byte: store a single byte to slave register
> + * @zpa_read_block: fetch data block from multiple contiguous slave registers
> + *
> + * Abtract slave register accesses.
> + */
> +struct zpa_bus {
> +	int (*zpa_read_byte)(const struct iio_dev *indio_dev, u8 address);
> +	int (*zpa_write_byte)(const struct iio_dev *indio_dev,
> +			      u8                    address,
> +			      u8                    value);
> +	int (*zpa_read_block)(const struct iio_dev *indio_dev,
> +			      u8                    address,
> +			      u8                    length,
> +			      u8                   *value);
> +};
> +
> +static inline struct device *zpa_iio2slave(const struct iio_dev *indio_dev)
> +{
> +	return indio_dev->dev.parent;
> +}
> +
> +/*
> + * zpa_probe() - instantiate and register core zpa2326 IIO device
> + * @slave: device the IIO device will be a child of
> + * @name:  arbitrary name identify the device
> + * @irq:   interrupt line, negative if none
> + * @bus:   underlying bus adapter
> + */
> +int zpa_probe(struct device        *slave,
> +	      const char           *name,
> +	      int                   irq,
> +	      const struct zpa_bus *bus);
> +
> +/*
> + * zpa_remove() - unregister and destroy core zpa2326 IIO device
> + * @slave: device the IIO device to remove is a child of
> + */
> +int zpa_remove(const struct device *slave);
> +
> +#ifdef CONFIG_PM
> +#include <linux/pm.h>
> +extern const struct dev_pm_ops zpa_pm_ops;
> +#define ZPA_PM_OPS (&zpa_pm_ops)
> +#else
> +#define ZPA_PM_OPS (NULL)
> +#endif
> +
> +#endif
> diff --git a/drivers/iio/pressure/zpa2326_i2c.c b/drivers/iio/pressure/zpa2326_i2c.c
> new file mode 100644
> index 0000000..f43c41a
> --- /dev/null
> +++ b/drivers/iio/pressure/zpa2326_i2c.c
> @@ -0,0 +1,188 @@
> +/*
> + * Murata ZPA2326 I2C pressure and temperature sensor driver
> + *
> + * Copyright (c) 2016 Parrot S.A.
> + *
> + * Author: Gregor Boirie <gregor.boirie@xxxxxxxxxx>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/i2c.h>
> +#include <linux/of_device.h>
> +#include "zpa2326.h"
> +
> +static const struct i2c_client *zpa_iio2client(const struct iio_dev *indio_dev)
> +{
> +	return to_i2c_client(zpa_iio2slave(indio_dev));
> +}
> +
> +static int zpa_write_i2c_byte(const struct iio_dev *indio_dev, u8 address,
> +			      u8 value)
> +{
> +	int                      err;
> +	const struct i2c_client *client = zpa_iio2client(indio_dev);
> +	u8                       buf[] = { address, value };
> +	struct i2c_msg           msg = {
> +		.addr  = client->addr,
> +		.flags = client->flags,
> +		.len   = ARRAY_SIZE(buf),
> +		.buf   = buf
> +	};
> +
> +	err = i2c_transfer(client->adapter, &msg, 1);
> +	if (err < 0)
> +		return err;
> +
> +	if (err != 1)
> +		return -ENOMSG;
> +
> +	return 0;
> +}
> +
> +static int _zpa_read_i2c_byte(const struct i2c_client *client, u8 address)
> +{
> +	int            err;
> +	u8             byte;
> +	struct i2c_msg msg[] = {
> +		[0] = {
> +			.addr  = client->addr,
> +			.flags = client->flags,
> +			.len   = 1,
> +			.buf   = &address
> +		},
> +		[1] = {
> +			.addr  = client->addr,
> +			.flags = client->flags | I2C_M_RD,
> +			.len   = 1,
> +			.buf   = &byte
> +		}
> +	};
> +
> +	err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
> +	if (err < 0)
> +		return err;
> +
> +	if (err != ARRAY_SIZE(msg))
> +		return -ENOMSG;
> +
> +	return (int)byte;
> +}
> +
> +static int zpa_read_i2c_byte(const struct iio_dev *indio_dev, u8 address)
> +{
> +	return _zpa_read_i2c_byte(zpa_iio2client(indio_dev), address);
> +}
> +
> +static int zpa_read_i2c_block(const struct iio_dev *indio_dev,
> +			      u8                    address,
> +			      u8                    length,
> +			      u8                   *value)
> +{
> +	int                      err;
> +	const struct i2c_client *client = zpa_iio2client(indio_dev);
> +	struct i2c_msg           msg[] = {
> +		[0] = {
> +			.addr  = client->addr,
> +			.flags = client->flags,
> +			.len   = 1,
> +			.buf   = &address,
> +		},
> +		[1] = {
> +			.addr  = client->addr,
> +			.flags = client->flags | I2C_M_RD,
> +			.len   = length,
> +			.buf   = value
> +		}
> +	};
> +
> +	/* Set MSB to request register address auto increment. */
> +	address |= (1U << 7);
> +
> +	err = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
> +	if (err < 0)
> +		return err;
> +
> +	if (err != ARRAY_SIZE(msg))
> +		return -ENOMSG;
> +
> +	return 0;
> +}
> +
> +static const struct zpa_bus zpa_i2c_bus = {
> +	.zpa_read_byte  = &zpa_read_i2c_byte,
> +	.zpa_write_byte = &zpa_write_i2c_byte,
> +	.zpa_read_block = &zpa_read_i2c_block,
> +};
> +
> +static int zpa_probe_i2c(struct i2c_client          *client,
> +			 const struct i2c_device_id *id)
> +{
> +	int err;
> +
> +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
> +		return -ENODEV;
> +
> +	/*
> +	 * Read identification register to check we are talking to the right
> +	 * slave.
> +	 */
> +	err = _zpa_read_i2c_byte(client, ZPA_DEVICE_ID_REG);
> +	if (err < 0)
> +		return err;
> +
> +	/* Identification register bit 1 mirrors device address bit 0. */
> +#define ZPA_SA0(_addr)          (_addr & BIT(0))
> +#define ZPA_DEVICE_ID_SA0_SHIFT (1)
> +	if (err != (ZPA_DEVICE_ID |
> +		    (ZPA_SA0(client->addr) << ZPA_DEVICE_ID_SA0_SHIFT))) {
> +		dev_err(&client->dev,
> +			"found unexpected device with id %02x", err);
> +		return -ENODEV;
> +	}
> +
> +	return zpa_probe(&client->dev, id->name, client->irq, &zpa_i2c_bus);
> +}
> +
> +static int zpa_remove_i2c(struct i2c_client *client)
> +{
> +	return zpa_remove(&client->dev);
> +}
> +
> +static const struct i2c_device_id zpa_i2c_ids[] = {
> +	{ "zpa2326", 0 },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(i2c, zpa_i2c_ids);
> +
> +#if defined(CONFIG_OF)
> +static const struct of_device_id zpa_i2c_matches[] = {
> +	{ .compatible = "murata,zpa2326" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, zpa_i2c_matches);
> +#endif
> +
> +static struct i2c_driver zpa_i2c_driver = {
> +	.driver = {
> +		.name           = "zpa2326-i2c",
> +		.of_match_table = of_match_ptr(zpa_i2c_matches),
> +		.pm             = ZPA_PM_OPS,
> +	},
> +	.probe    = zpa_probe_i2c,
> +	.remove   = zpa_remove_i2c,
> +	.id_table = zpa_i2c_ids,
> +};
> +module_i2c_driver(zpa_i2c_driver);
> +
> +MODULE_AUTHOR("Gregor Boirie <gregor.boirie@xxxxxxxxxx>");
> +MODULE_DESCRIPTION("I2C driver for Murata ZPA2326 pressure sensor");
> +MODULE_LICENSE("GPL v2");
> diff --git a/drivers/iio/pressure/zpa2326_spi.c b/drivers/iio/pressure/zpa2326_spi.c
> new file mode 100644
> index 0000000..a86e3b9
> --- /dev/null
> +++ b/drivers/iio/pressure/zpa2326_spi.c
> @@ -0,0 +1,184 @@
> +/*
> + * Murata ZPA2326 SPI pressure and temperature sensor driver
> + *
> + * Copyright (c) 2016 Parrot S.A.
> + *
> + * Author: Gregor Boirie <gregor.boirie@xxxxxxxxxx>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> + * more details.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/spi/spi.h>
> +#include <linux/of_device.h>
> +#include "zpa2326.h"
> +
> +/* Address bit 7 must be set to request a register read operation. */
> +#define ZPA_SPI_ADDR_RD       BIT(7)
> +/* Address bit 6 must be set to request register address auto increment. */
> +#define ZPA_SPI_ADDR_AUTO_INC BIT(6)
> +
> +static struct spi_device *zpa_iio2spidev(const struct iio_dev *indio_dev)
> +{
> +	return to_spi_device(zpa_iio2slave(indio_dev));
> +}
> +
> +static int zpa_write_spi_byte(const struct iio_dev *indio_dev,
> +			      u8                    address,
> +			      u8                    value)
> +{
> +	struct spi_transfer xfer;
> +	u8                  buf[] = { address, value };
> +
> +	/* Zero-initialize to ensure forward compatibility. */
> +	memset(&xfer, 0, sizeof(xfer));
> +
> +	/*
> +	 * Register address write cycle followed by register content write
> +	 * cycle.
> +	 */
> +	xfer.tx_buf = buf;
> +	xfer.len = sizeof(buf);
> +
> +	return spi_sync_transfer(zpa_iio2spidev(indio_dev), &xfer, 1);
> +}
> +
> +static int _zpa_read_spi_byte(struct spi_device *slave, u8 address)
> +{
> +	struct spi_transfer xfer[2];
> +	u8                  buf;
> +	int                 err;
> +
> +	/* Request read cycle. */
> +	address |= ZPA_SPI_ADDR_RD;
> +
> +	/* Zero-initialize to ensure forward compatibility. */
> +	memset(xfer, 0, sizeof(xfer));
> +
> +	/* Register address write cycle. */
> +	xfer[0].tx_buf = &address;
> +	xfer[0].len = sizeof(address);
> +
> +	/* Register content read cycle. */
> +	xfer[1].rx_buf = &buf;
> +	xfer[1].len = sizeof(buf);
> +
> +	err = spi_sync_transfer(slave, xfer, ARRAY_SIZE(xfer));
> +	if (err)
> +		return err;
> +
> +	return buf;
> +}
> +
> +static int zpa_read_spi_byte(const struct iio_dev *indio_dev, u8 address)
> +{
> +	return _zpa_read_spi_byte(zpa_iio2spidev(indio_dev), address);
> +}
> +
> +static int zpa_read_spi_block(const struct iio_dev *indio_dev,
> +			      u8                    address,
> +			      u8                    length,
> +			      u8                   *value)
> +{
> +	struct spi_transfer xfer[2];
> +
> +	/* Request read cycle with register address auto increment. */
> +	address |= ZPA_SPI_ADDR_RD | ZPA_SPI_ADDR_AUTO_INC;
> +
> +	/* Zero-initialize to ensure forward compatibility. */
> +	memset(xfer, 0, sizeof(xfer));
> +
> +	/* First register address write cycle. */
> +	xfer[0].tx_buf = &address;
> +	xfer[0].len = sizeof(address);
> +
> +	/* Registers content read cycle (auto-increment). */
> +	xfer[1].rx_buf = value;
> +	xfer[1].len = length;
> +
> +	return spi_sync_transfer(zpa_iio2spidev(indio_dev), xfer,
> +				 ARRAY_SIZE(xfer));
> +}
> +
> +static const struct zpa_bus zpa_spi_bus = {
> +	.zpa_read_byte  = &zpa_read_spi_byte,
> +	.zpa_write_byte = &zpa_write_spi_byte,
> +	.zpa_read_block = &zpa_read_spi_block,
> +};
> +
> +static int zpa_probe_spi(struct spi_device *slave)
> +{
> +	int err;
> +
> +	/*
> +	 * Enforce SPI slave settings to prevent from DT misconfiguration.
> +	 *
> +	 * Clock is idle high. Sampling happens on trailing edge, i.e., rising
> +	 * edge. Maximum bus frequency is 1 mHz. Registers are 8 bits wide.
> +	 */
> +	slave->mode = SPI_MODE_3;
> +	slave->max_speed_hz = min(slave->max_speed_hz, 1000U * 1000U);
> +	slave->bits_per_word = 8;
> +	err = spi_setup(slave);
> +	if (err < 0)
> +		return err;
> +
> +	/*
> +	 * Read identification register to check we are talking to the right
> +	 * slave.
> +	 */
> +	err = _zpa_read_spi_byte(slave, ZPA_DEVICE_ID_REG);
> +	if (err < 0)
> +		return err;
> +
> +	if (err != ZPA_DEVICE_ID) {
> +		dev_err(&slave->dev,
> +			"found unexpected device with id %02x", err);
> +		return -ENODEV;
> +	}
> +
> +	return zpa_probe(&slave->dev, spi_get_device_id(slave)->name,
> +			 slave->irq, &zpa_spi_bus);
> +}
> +
> +static int zpa_remove_spi(struct spi_device *slave)
> +{
> +	return zpa_remove(&slave->dev);
> +}
> +
> +static const struct spi_device_id zpa_spi_ids[] = {
> +	{ "zpa2326", 0 },
> +	{ },
> +};
> +MODULE_DEVICE_TABLE(spi, zpa_spi_ids);
> +
> +#if defined(CONFIG_OF)
> +static const struct of_device_id zpa_spi_matches[] = {
> +	{ .compatible = "murata,zpa2326" },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, zpa_spi_matches);
> +#endif
> +
> +static struct spi_driver zpa_spi_driver = {
> +	.driver = {
> +		.name           = "zpa2326-spi",
> +		.of_match_table = of_match_ptr(zpa_spi_matches),
> +		.pm             = ZPA_PM_OPS,
> +	},
> +	.probe    = zpa_probe_spi,
> +	.remove   = zpa_remove_spi,
> +	.id_table = zpa_spi_ids,
> +};
> +module_spi_driver(zpa_spi_driver);
> +
> +MODULE_AUTHOR("Gregor Boirie <gregor.boirie@xxxxxxxxxx>");
> +MODULE_DESCRIPTION("SPI driver for Murata ZPA2326 pressure sensor");
> +MODULE_LICENSE("GPL v2");
> 

-- 

Peter Meerwald-Stadler
+43-664-2444418 (mobile)
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux