Introduce driver for Murata ZPA2326 pressure and temperature sensor: http://www.murata.com/en-us/products/productdetail?partno=ZPA2326-0311A-R 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. + + 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 + * 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 + * 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. */ +#define ZPA_CONVERSION_TIMEOUT (HZ / 5) + +/* Registers map. */ +#define ZPA_REF_P_XL_REG ((u8)0x8) +#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); + 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. */ + 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"); + + 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: + * 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; + u64 timestamp; + } 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); + if (err) { + zpa_warn(indio_dev, "failed to fetch pressure (%d)", + 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 + * 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(); + } +} + +/* 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(); + } +} + +/* Current hardware sampling frequency sysfs getter. */ +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, + .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); + 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"); -- 2.1.4 -- 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