11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 203b262f2SGregor Boirie /* 303b262f2SGregor Boirie * Murata ZPA2326 pressure and temperature sensor IIO driver 403b262f2SGregor Boirie * 503b262f2SGregor Boirie * Copyright (c) 2016 Parrot S.A. 603b262f2SGregor Boirie * 703b262f2SGregor Boirie * Author: Gregor Boirie <gregor.boirie@parrot.com> 803b262f2SGregor Boirie */ 903b262f2SGregor Boirie 1003b262f2SGregor Boirie /** 1103b262f2SGregor Boirie * DOC: ZPA2326 theory of operations 1203b262f2SGregor Boirie * 1303b262f2SGregor Boirie * This driver supports %INDIO_DIRECT_MODE and %INDIO_BUFFER_TRIGGERED IIO 1403b262f2SGregor Boirie * modes. 1503b262f2SGregor Boirie * A internal hardware trigger is also implemented to dispatch registered IIO 1603b262f2SGregor Boirie * trigger consumers upon "sample ready" interrupts. 1703b262f2SGregor Boirie * 1803b262f2SGregor Boirie * ZPA2326 hardware supports 2 sampling mode: one shot and continuous. 1903b262f2SGregor Boirie * 2003b262f2SGregor Boirie * A complete one shot sampling cycle gets device out of low power mode, 2103b262f2SGregor Boirie * performs pressure and temperature measurements, then automatically switches 2203b262f2SGregor Boirie * back to low power mode. It is meant for on demand sampling with optimal power 2303b262f2SGregor Boirie * saving at the cost of lower sampling rate and higher software overhead. 2403b262f2SGregor Boirie * This is a natural candidate for IIO read_raw hook implementation 2503b262f2SGregor Boirie * (%INDIO_DIRECT_MODE). It is also used for triggered buffering support to 2603b262f2SGregor Boirie * ensure explicit synchronization with external trigger events 2703b262f2SGregor Boirie * (%INDIO_BUFFER_TRIGGERED). 2803b262f2SGregor Boirie * 2903b262f2SGregor Boirie * The continuous mode works according to a periodic hardware measurement 3003b262f2SGregor Boirie * process continuously pushing samples into an internal hardware FIFO (for 3103b262f2SGregor Boirie * pressure samples only). Measurement cycle completion may be signaled by a 3203b262f2SGregor Boirie * "sample ready" interrupt. 3303b262f2SGregor Boirie * Typical software sequence of operations : 3403b262f2SGregor Boirie * - get device out of low power mode, 3503b262f2SGregor Boirie * - setup hardware sampling period, 3603b262f2SGregor Boirie * - at end of period, upon data ready interrupt: pop pressure samples out of 3703b262f2SGregor Boirie * hardware FIFO and fetch temperature sample 3803b262f2SGregor Boirie * - when no longer needed, stop sampling process by putting device into 3903b262f2SGregor Boirie * low power mode. 4003b262f2SGregor Boirie * This mode is used to implement %INDIO_BUFFER_TRIGGERED mode if device tree 4103b262f2SGregor Boirie * declares a valid interrupt line. In this case, the internal hardware trigger 4203b262f2SGregor Boirie * drives acquisition. 4303b262f2SGregor Boirie * 4403b262f2SGregor Boirie * Note that hardware sampling frequency is taken into account only when 4503b262f2SGregor Boirie * internal hardware trigger is attached as the highest sampling rate seems to 4603b262f2SGregor Boirie * be the most energy efficient. 4703b262f2SGregor Boirie * 4803b262f2SGregor Boirie * TODO: 4903b262f2SGregor Boirie * preset pressure threshold crossing / IIO events ; 5003b262f2SGregor Boirie * differential pressure sampling ; 5103b262f2SGregor Boirie * hardware samples averaging. 5203b262f2SGregor Boirie */ 5303b262f2SGregor Boirie 5403b262f2SGregor Boirie #include <linux/module.h> 5503b262f2SGregor Boirie #include <linux/kernel.h> 5603b262f2SGregor Boirie #include <linux/delay.h> 5703b262f2SGregor Boirie #include <linux/interrupt.h> 5803b262f2SGregor Boirie #include <linux/regulator/consumer.h> 5903b262f2SGregor Boirie #include <linux/pm_runtime.h> 6003b262f2SGregor Boirie #include <linux/regmap.h> 6103b262f2SGregor Boirie #include <linux/iio/iio.h> 6203b262f2SGregor Boirie #include <linux/iio/sysfs.h> 6303b262f2SGregor Boirie #include <linux/iio/buffer.h> 6403b262f2SGregor Boirie #include <linux/iio/trigger.h> 6503b262f2SGregor Boirie #include <linux/iio/trigger_consumer.h> 6603b262f2SGregor Boirie #include <linux/iio/triggered_buffer.h> 67e8ee40e7SAndy Shevchenko #include <asm/unaligned.h> 6803b262f2SGregor Boirie #include "zpa2326.h" 6903b262f2SGregor Boirie 7003b262f2SGregor Boirie /* 200 ms should be enough for the longest conversion time in one-shot mode. */ 7103b262f2SGregor Boirie #define ZPA2326_CONVERSION_JIFFIES (HZ / 5) 7203b262f2SGregor Boirie 7303b262f2SGregor Boirie /* There should be a 1 ms delay (Tpup) after getting out of reset. */ 7403b262f2SGregor Boirie #define ZPA2326_TPUP_USEC_MIN (1000) 7503b262f2SGregor Boirie #define ZPA2326_TPUP_USEC_MAX (2000) 7603b262f2SGregor Boirie 7703b262f2SGregor Boirie /** 7803b262f2SGregor Boirie * struct zpa2326_frequency - Hardware sampling frequency descriptor 7903b262f2SGregor Boirie * @hz : Frequency in Hertz. 8003b262f2SGregor Boirie * @odr: Output Data Rate word as expected by %ZPA2326_CTRL_REG3_REG. 8103b262f2SGregor Boirie */ 8203b262f2SGregor Boirie struct zpa2326_frequency { 8303b262f2SGregor Boirie int hz; 8403b262f2SGregor Boirie u16 odr; 8503b262f2SGregor Boirie }; 8603b262f2SGregor Boirie 8703b262f2SGregor Boirie /* 8803b262f2SGregor Boirie * Keep these in strict ascending order: last array entry is expected to 8903b262f2SGregor Boirie * correspond to the highest sampling frequency. 9003b262f2SGregor Boirie */ 9103b262f2SGregor Boirie static const struct zpa2326_frequency zpa2326_sampling_frequencies[] = { 9203b262f2SGregor Boirie { .hz = 1, .odr = 1 << ZPA2326_CTRL_REG3_ODR_SHIFT }, 9303b262f2SGregor Boirie { .hz = 5, .odr = 5 << ZPA2326_CTRL_REG3_ODR_SHIFT }, 9403b262f2SGregor Boirie { .hz = 11, .odr = 6 << ZPA2326_CTRL_REG3_ODR_SHIFT }, 9503b262f2SGregor Boirie { .hz = 23, .odr = 7 << ZPA2326_CTRL_REG3_ODR_SHIFT }, 9603b262f2SGregor Boirie }; 9703b262f2SGregor Boirie 9803b262f2SGregor Boirie /* Return the highest hardware sampling frequency available. */ 9903b262f2SGregor Boirie static const struct zpa2326_frequency *zpa2326_highest_frequency(void) 10003b262f2SGregor Boirie { 10103b262f2SGregor Boirie return &zpa2326_sampling_frequencies[ 10203b262f2SGregor Boirie ARRAY_SIZE(zpa2326_sampling_frequencies) - 1]; 10303b262f2SGregor Boirie } 10403b262f2SGregor Boirie 10503b262f2SGregor Boirie /** 10644f14695SJonathan Cameron * struct zpa2326_private - Per-device internal private state 10703b262f2SGregor Boirie * @timestamp: Buffered samples ready datum. 10803b262f2SGregor Boirie * @regmap: Underlying I2C / SPI bus adapter used to abstract slave register 10903b262f2SGregor Boirie * accesses. 11003b262f2SGregor Boirie * @result: Allows sampling logic to get completion status of operations 11103b262f2SGregor Boirie * that interrupt handlers perform asynchronously. 11203b262f2SGregor Boirie * @data_ready: Interrupt handler uses this to wake user context up at sampling 11303b262f2SGregor Boirie * operation completion. 11403b262f2SGregor Boirie * @trigger: Optional hardware / interrupt driven trigger used to notify 11503b262f2SGregor Boirie * external devices a new sample is ready. 11603b262f2SGregor Boirie * @waken: Flag indicating whether or not device has just been powered on. 11703b262f2SGregor Boirie * @irq: Optional interrupt line: negative or zero if not declared into 11803b262f2SGregor Boirie * DT, in which case sampling logic keeps polling status register 11903b262f2SGregor Boirie * to detect completion. 12003b262f2SGregor Boirie * @frequency: Current hardware sampling frequency. 12103b262f2SGregor Boirie * @vref: Power / voltage reference. 12203b262f2SGregor Boirie * @vdd: Power supply. 12303b262f2SGregor Boirie */ 12403b262f2SGregor Boirie struct zpa2326_private { 12503b262f2SGregor Boirie s64 timestamp; 12603b262f2SGregor Boirie struct regmap *regmap; 12703b262f2SGregor Boirie int result; 12803b262f2SGregor Boirie struct completion data_ready; 12903b262f2SGregor Boirie struct iio_trigger *trigger; 13003b262f2SGregor Boirie bool waken; 13103b262f2SGregor Boirie int irq; 13203b262f2SGregor Boirie const struct zpa2326_frequency *frequency; 13303b262f2SGregor Boirie struct regulator *vref; 13403b262f2SGregor Boirie struct regulator *vdd; 13503b262f2SGregor Boirie }; 13603b262f2SGregor Boirie 137eed3089fSJoe Perches #define zpa2326_err(idev, fmt, ...) \ 138eed3089fSJoe Perches dev_err(idev->dev.parent, fmt "\n", ##__VA_ARGS__) 13903b262f2SGregor Boirie 140eed3089fSJoe Perches #define zpa2326_warn(idev, fmt, ...) \ 141eed3089fSJoe Perches dev_warn(idev->dev.parent, fmt "\n", ##__VA_ARGS__) 14203b262f2SGregor Boirie 143eed3089fSJoe Perches #define zpa2326_dbg(idev, fmt, ...) \ 144eed3089fSJoe Perches dev_dbg(idev->dev.parent, fmt "\n", ##__VA_ARGS__) 14503b262f2SGregor Boirie 14603b262f2SGregor Boirie bool zpa2326_isreg_writeable(struct device *dev, unsigned int reg) 14703b262f2SGregor Boirie { 14803b262f2SGregor Boirie switch (reg) { 14903b262f2SGregor Boirie case ZPA2326_REF_P_XL_REG: 15003b262f2SGregor Boirie case ZPA2326_REF_P_L_REG: 15103b262f2SGregor Boirie case ZPA2326_REF_P_H_REG: 15203b262f2SGregor Boirie case ZPA2326_RES_CONF_REG: 15303b262f2SGregor Boirie case ZPA2326_CTRL_REG0_REG: 15403b262f2SGregor Boirie case ZPA2326_CTRL_REG1_REG: 15503b262f2SGregor Boirie case ZPA2326_CTRL_REG2_REG: 15603b262f2SGregor Boirie case ZPA2326_CTRL_REG3_REG: 15703b262f2SGregor Boirie case ZPA2326_THS_P_LOW_REG: 15803b262f2SGregor Boirie case ZPA2326_THS_P_HIGH_REG: 15903b262f2SGregor Boirie return true; 16003b262f2SGregor Boirie 16103b262f2SGregor Boirie default: 16203b262f2SGregor Boirie return false; 16303b262f2SGregor Boirie } 16403b262f2SGregor Boirie } 16503b262f2SGregor Boirie EXPORT_SYMBOL_GPL(zpa2326_isreg_writeable); 16603b262f2SGregor Boirie 16703b262f2SGregor Boirie bool zpa2326_isreg_readable(struct device *dev, unsigned int reg) 16803b262f2SGregor Boirie { 16903b262f2SGregor Boirie switch (reg) { 17003b262f2SGregor Boirie case ZPA2326_REF_P_XL_REG: 17103b262f2SGregor Boirie case ZPA2326_REF_P_L_REG: 17203b262f2SGregor Boirie case ZPA2326_REF_P_H_REG: 17303b262f2SGregor Boirie case ZPA2326_DEVICE_ID_REG: 17403b262f2SGregor Boirie case ZPA2326_RES_CONF_REG: 17503b262f2SGregor Boirie case ZPA2326_CTRL_REG0_REG: 17603b262f2SGregor Boirie case ZPA2326_CTRL_REG1_REG: 17703b262f2SGregor Boirie case ZPA2326_CTRL_REG2_REG: 17803b262f2SGregor Boirie case ZPA2326_CTRL_REG3_REG: 17903b262f2SGregor Boirie case ZPA2326_INT_SOURCE_REG: 18003b262f2SGregor Boirie case ZPA2326_THS_P_LOW_REG: 18103b262f2SGregor Boirie case ZPA2326_THS_P_HIGH_REG: 18203b262f2SGregor Boirie case ZPA2326_STATUS_REG: 18303b262f2SGregor Boirie case ZPA2326_PRESS_OUT_XL_REG: 18403b262f2SGregor Boirie case ZPA2326_PRESS_OUT_L_REG: 18503b262f2SGregor Boirie case ZPA2326_PRESS_OUT_H_REG: 18603b262f2SGregor Boirie case ZPA2326_TEMP_OUT_L_REG: 18703b262f2SGregor Boirie case ZPA2326_TEMP_OUT_H_REG: 18803b262f2SGregor Boirie return true; 18903b262f2SGregor Boirie 19003b262f2SGregor Boirie default: 19103b262f2SGregor Boirie return false; 19203b262f2SGregor Boirie } 19303b262f2SGregor Boirie } 19403b262f2SGregor Boirie EXPORT_SYMBOL_GPL(zpa2326_isreg_readable); 19503b262f2SGregor Boirie 19603b262f2SGregor Boirie bool zpa2326_isreg_precious(struct device *dev, unsigned int reg) 19703b262f2SGregor Boirie { 19803b262f2SGregor Boirie switch (reg) { 19903b262f2SGregor Boirie case ZPA2326_INT_SOURCE_REG: 20003b262f2SGregor Boirie case ZPA2326_PRESS_OUT_H_REG: 20103b262f2SGregor Boirie return true; 20203b262f2SGregor Boirie 20303b262f2SGregor Boirie default: 20403b262f2SGregor Boirie return false; 20503b262f2SGregor Boirie } 20603b262f2SGregor Boirie } 20703b262f2SGregor Boirie EXPORT_SYMBOL_GPL(zpa2326_isreg_precious); 20803b262f2SGregor Boirie 20903b262f2SGregor Boirie /** 21003b262f2SGregor Boirie * zpa2326_enable_device() - Enable device, i.e. get out of low power mode. 21103b262f2SGregor Boirie * @indio_dev: The IIO device associated with the hardware to enable. 21203b262f2SGregor Boirie * 21303b262f2SGregor Boirie * Required to access complete register space and to perform any sampling 21403b262f2SGregor Boirie * or control operations. 21503b262f2SGregor Boirie * 21603b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 21703b262f2SGregor Boirie */ 21803b262f2SGregor Boirie static int zpa2326_enable_device(const struct iio_dev *indio_dev) 21903b262f2SGregor Boirie { 22003b262f2SGregor Boirie int err; 22103b262f2SGregor Boirie 22203b262f2SGregor Boirie err = regmap_write(((struct zpa2326_private *) 22303b262f2SGregor Boirie iio_priv(indio_dev))->regmap, 22403b262f2SGregor Boirie ZPA2326_CTRL_REG0_REG, ZPA2326_CTRL_REG0_ENABLE); 22503b262f2SGregor Boirie if (err) { 22603b262f2SGregor Boirie zpa2326_err(indio_dev, "failed to enable device (%d)", err); 22703b262f2SGregor Boirie return err; 22803b262f2SGregor Boirie } 22903b262f2SGregor Boirie 23003b262f2SGregor Boirie zpa2326_dbg(indio_dev, "enabled"); 23103b262f2SGregor Boirie 23203b262f2SGregor Boirie return 0; 23303b262f2SGregor Boirie } 23403b262f2SGregor Boirie 23503b262f2SGregor Boirie /** 23603b262f2SGregor Boirie * zpa2326_sleep() - Disable device, i.e. switch to low power mode. 23703b262f2SGregor Boirie * @indio_dev: The IIO device associated with the hardware to disable. 23803b262f2SGregor Boirie * 23903b262f2SGregor Boirie * Only %ZPA2326_DEVICE_ID_REG and %ZPA2326_CTRL_REG0_REG registers may be 24003b262f2SGregor Boirie * accessed once device is in the disabled state. 24103b262f2SGregor Boirie * 24203b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 24303b262f2SGregor Boirie */ 24403b262f2SGregor Boirie static int zpa2326_sleep(const struct iio_dev *indio_dev) 24503b262f2SGregor Boirie { 24603b262f2SGregor Boirie int err; 24703b262f2SGregor Boirie 24803b262f2SGregor Boirie err = regmap_write(((struct zpa2326_private *) 24903b262f2SGregor Boirie iio_priv(indio_dev))->regmap, 25003b262f2SGregor Boirie ZPA2326_CTRL_REG0_REG, 0); 25103b262f2SGregor Boirie if (err) { 25203b262f2SGregor Boirie zpa2326_err(indio_dev, "failed to sleep (%d)", err); 25303b262f2SGregor Boirie return err; 25403b262f2SGregor Boirie } 25503b262f2SGregor Boirie 25603b262f2SGregor Boirie zpa2326_dbg(indio_dev, "sleeping"); 25703b262f2SGregor Boirie 25803b262f2SGregor Boirie return 0; 25903b262f2SGregor Boirie } 26003b262f2SGregor Boirie 26103b262f2SGregor Boirie /** 26203b262f2SGregor Boirie * zpa2326_reset_device() - Reset device to default hardware state. 26303b262f2SGregor Boirie * @indio_dev: The IIO device associated with the hardware to reset. 26403b262f2SGregor Boirie * 26503b262f2SGregor Boirie * Disable sampling and empty hardware FIFO. 26603b262f2SGregor Boirie * Device must be enabled before reset, i.e. not in low power mode. 26703b262f2SGregor Boirie * 26803b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 26903b262f2SGregor Boirie */ 27003b262f2SGregor Boirie static int zpa2326_reset_device(const struct iio_dev *indio_dev) 27103b262f2SGregor Boirie { 27203b262f2SGregor Boirie int err; 27303b262f2SGregor Boirie 27403b262f2SGregor Boirie err = regmap_write(((struct zpa2326_private *) 27503b262f2SGregor Boirie iio_priv(indio_dev))->regmap, 27603b262f2SGregor Boirie ZPA2326_CTRL_REG2_REG, ZPA2326_CTRL_REG2_SWRESET); 27703b262f2SGregor Boirie if (err) { 27803b262f2SGregor Boirie zpa2326_err(indio_dev, "failed to reset device (%d)", err); 27903b262f2SGregor Boirie return err; 28003b262f2SGregor Boirie } 28103b262f2SGregor Boirie 28203b262f2SGregor Boirie usleep_range(ZPA2326_TPUP_USEC_MIN, ZPA2326_TPUP_USEC_MAX); 28303b262f2SGregor Boirie 28403b262f2SGregor Boirie zpa2326_dbg(indio_dev, "reset"); 28503b262f2SGregor Boirie 28603b262f2SGregor Boirie return 0; 28703b262f2SGregor Boirie } 28803b262f2SGregor Boirie 28903b262f2SGregor Boirie /** 29003b262f2SGregor Boirie * zpa2326_start_oneshot() - Start a single sampling cycle, i.e. in one shot 29103b262f2SGregor Boirie * mode. 29203b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 29303b262f2SGregor Boirie * 29403b262f2SGregor Boirie * Device must have been previously enabled and configured for one shot mode. 29503b262f2SGregor Boirie * Device will be switched back to low power mode at end of cycle. 29603b262f2SGregor Boirie * 29703b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 29803b262f2SGregor Boirie */ 29903b262f2SGregor Boirie static int zpa2326_start_oneshot(const struct iio_dev *indio_dev) 30003b262f2SGregor Boirie { 30103b262f2SGregor Boirie int err; 30203b262f2SGregor Boirie 30303b262f2SGregor Boirie err = regmap_write(((struct zpa2326_private *) 30403b262f2SGregor Boirie iio_priv(indio_dev))->regmap, 30503b262f2SGregor Boirie ZPA2326_CTRL_REG0_REG, 30603b262f2SGregor Boirie ZPA2326_CTRL_REG0_ENABLE | 30703b262f2SGregor Boirie ZPA2326_CTRL_REG0_ONE_SHOT); 30803b262f2SGregor Boirie if (err) { 30903b262f2SGregor Boirie zpa2326_err(indio_dev, "failed to start one shot cycle (%d)", 31003b262f2SGregor Boirie err); 31103b262f2SGregor Boirie return err; 31203b262f2SGregor Boirie } 31303b262f2SGregor Boirie 31403b262f2SGregor Boirie zpa2326_dbg(indio_dev, "one shot cycle started"); 31503b262f2SGregor Boirie 31603b262f2SGregor Boirie return 0; 31703b262f2SGregor Boirie } 31803b262f2SGregor Boirie 31903b262f2SGregor Boirie /** 32003b262f2SGregor Boirie * zpa2326_power_on() - Power on device to allow subsequent configuration. 32103b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 32203b262f2SGregor Boirie * @private: Internal private state related to @indio_dev. 32303b262f2SGregor Boirie * 32403b262f2SGregor Boirie * Sampling will be disabled, preventing strange things from happening in our 32503b262f2SGregor Boirie * back. Hardware FIFO content will be cleared. 32603b262f2SGregor Boirie * When successful, device will be left in the enabled state to allow further 32703b262f2SGregor Boirie * configuration. 32803b262f2SGregor Boirie * 32903b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 33003b262f2SGregor Boirie */ 33103b262f2SGregor Boirie static int zpa2326_power_on(const struct iio_dev *indio_dev, 33203b262f2SGregor Boirie const struct zpa2326_private *private) 33303b262f2SGregor Boirie { 33403b262f2SGregor Boirie int err; 33503b262f2SGregor Boirie 33603b262f2SGregor Boirie err = regulator_enable(private->vref); 33703b262f2SGregor Boirie if (err) 33803b262f2SGregor Boirie return err; 33903b262f2SGregor Boirie 34003b262f2SGregor Boirie err = regulator_enable(private->vdd); 34103b262f2SGregor Boirie if (err) 34203b262f2SGregor Boirie goto vref; 34303b262f2SGregor Boirie 34403b262f2SGregor Boirie zpa2326_dbg(indio_dev, "powered on"); 34503b262f2SGregor Boirie 34603b262f2SGregor Boirie err = zpa2326_enable_device(indio_dev); 34703b262f2SGregor Boirie if (err) 34803b262f2SGregor Boirie goto vdd; 34903b262f2SGregor Boirie 35003b262f2SGregor Boirie err = zpa2326_reset_device(indio_dev); 35103b262f2SGregor Boirie if (err) 35203b262f2SGregor Boirie goto sleep; 35303b262f2SGregor Boirie 35403b262f2SGregor Boirie return 0; 35503b262f2SGregor Boirie 35603b262f2SGregor Boirie sleep: 35703b262f2SGregor Boirie zpa2326_sleep(indio_dev); 35803b262f2SGregor Boirie vdd: 35903b262f2SGregor Boirie regulator_disable(private->vdd); 36003b262f2SGregor Boirie vref: 36103b262f2SGregor Boirie regulator_disable(private->vref); 36203b262f2SGregor Boirie 36303b262f2SGregor Boirie zpa2326_dbg(indio_dev, "powered off"); 36403b262f2SGregor Boirie 36503b262f2SGregor Boirie return err; 36603b262f2SGregor Boirie } 36703b262f2SGregor Boirie 36803b262f2SGregor Boirie /** 36903b262f2SGregor Boirie * zpa2326_power_off() - Power off device, i.e. disable attached power 37003b262f2SGregor Boirie * regulators. 37103b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 37203b262f2SGregor Boirie * @private: Internal private state related to @indio_dev. 37303b262f2SGregor Boirie * 37403b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 37503b262f2SGregor Boirie */ 37603b262f2SGregor Boirie static void zpa2326_power_off(const struct iio_dev *indio_dev, 37703b262f2SGregor Boirie const struct zpa2326_private *private) 37803b262f2SGregor Boirie { 37903b262f2SGregor Boirie regulator_disable(private->vdd); 38003b262f2SGregor Boirie regulator_disable(private->vref); 38103b262f2SGregor Boirie 38203b262f2SGregor Boirie zpa2326_dbg(indio_dev, "powered off"); 38303b262f2SGregor Boirie } 38403b262f2SGregor Boirie 38503b262f2SGregor Boirie /** 38603b262f2SGregor Boirie * zpa2326_config_oneshot() - Setup device for one shot / on demand mode. 38703b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 38803b262f2SGregor Boirie * @irq: Optional interrupt line the hardware uses to notify new data 38903b262f2SGregor Boirie * samples are ready. Negative or zero values indicate no interrupts 39003b262f2SGregor Boirie * are available, meaning polling is required. 39103b262f2SGregor Boirie * 39203b262f2SGregor Boirie * Output Data Rate is configured for the highest possible rate so that 39303b262f2SGregor Boirie * conversion time and power consumption are reduced to a minimum. 39403b262f2SGregor Boirie * Note that hardware internal averaging machinery (not implemented in this 39503b262f2SGregor Boirie * driver) is not applicable in this mode. 39603b262f2SGregor Boirie * 39703b262f2SGregor Boirie * Device must have been previously enabled before calling 39803b262f2SGregor Boirie * zpa2326_config_oneshot(). 39903b262f2SGregor Boirie * 40003b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 40103b262f2SGregor Boirie */ 40203b262f2SGregor Boirie static int zpa2326_config_oneshot(const struct iio_dev *indio_dev, 40303b262f2SGregor Boirie int irq) 40403b262f2SGregor Boirie { 40503b262f2SGregor Boirie struct regmap *regs = ((struct zpa2326_private *) 40603b262f2SGregor Boirie iio_priv(indio_dev))->regmap; 40703b262f2SGregor Boirie const struct zpa2326_frequency *freq = zpa2326_highest_frequency(); 40803b262f2SGregor Boirie int err; 40903b262f2SGregor Boirie 41003b262f2SGregor Boirie /* Setup highest available Output Data Rate for one shot mode. */ 41103b262f2SGregor Boirie err = regmap_write(regs, ZPA2326_CTRL_REG3_REG, freq->odr); 41203b262f2SGregor Boirie if (err) 41303b262f2SGregor Boirie return err; 41403b262f2SGregor Boirie 41503b262f2SGregor Boirie if (irq > 0) { 41603b262f2SGregor Boirie /* Request interrupt when new sample is available. */ 41703b262f2SGregor Boirie err = regmap_write(regs, ZPA2326_CTRL_REG1_REG, 41803b262f2SGregor Boirie (u8)~ZPA2326_CTRL_REG1_MASK_DATA_READY); 41903b262f2SGregor Boirie 42003b262f2SGregor Boirie if (err) { 42103b262f2SGregor Boirie dev_err(indio_dev->dev.parent, 42203b262f2SGregor Boirie "failed to setup one shot mode (%d)", err); 42303b262f2SGregor Boirie return err; 42403b262f2SGregor Boirie } 42503b262f2SGregor Boirie } 42603b262f2SGregor Boirie 42703b262f2SGregor Boirie zpa2326_dbg(indio_dev, "one shot mode setup @%dHz", freq->hz); 42803b262f2SGregor Boirie 42903b262f2SGregor Boirie return 0; 43003b262f2SGregor Boirie } 43103b262f2SGregor Boirie 43203b262f2SGregor Boirie /** 43303b262f2SGregor Boirie * zpa2326_clear_fifo() - Clear remaining entries in hardware FIFO. 43403b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 43503b262f2SGregor Boirie * @min_count: Number of samples present within hardware FIFO. 43603b262f2SGregor Boirie * 43703b262f2SGregor Boirie * @min_count argument is a hint corresponding to the known minimum number of 43803b262f2SGregor Boirie * samples currently living in the FIFO. This allows to reduce the number of bus 43903b262f2SGregor Boirie * accesses by skipping status register read operation as long as we know for 44003b262f2SGregor Boirie * sure there are still entries left. 44103b262f2SGregor Boirie * 44203b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 44303b262f2SGregor Boirie */ 44403b262f2SGregor Boirie static int zpa2326_clear_fifo(const struct iio_dev *indio_dev, 44503b262f2SGregor Boirie unsigned int min_count) 44603b262f2SGregor Boirie { 44703b262f2SGregor Boirie struct regmap *regs = ((struct zpa2326_private *) 44803b262f2SGregor Boirie iio_priv(indio_dev))->regmap; 44903b262f2SGregor Boirie int err; 45003b262f2SGregor Boirie unsigned int val; 45103b262f2SGregor Boirie 45203b262f2SGregor Boirie if (!min_count) { 45303b262f2SGregor Boirie /* 45403b262f2SGregor Boirie * No hint: read status register to determine whether FIFO is 45503b262f2SGregor Boirie * empty or not. 45603b262f2SGregor Boirie */ 45703b262f2SGregor Boirie err = regmap_read(regs, ZPA2326_STATUS_REG, &val); 45803b262f2SGregor Boirie 45903b262f2SGregor Boirie if (err < 0) 46003b262f2SGregor Boirie goto err; 46103b262f2SGregor Boirie 46203b262f2SGregor Boirie if (val & ZPA2326_STATUS_FIFO_E) 46303b262f2SGregor Boirie /* Fifo is empty: nothing to trash. */ 46403b262f2SGregor Boirie return 0; 46503b262f2SGregor Boirie } 46603b262f2SGregor Boirie 46703b262f2SGregor Boirie /* Clear FIFO. */ 46803b262f2SGregor Boirie do { 46903b262f2SGregor Boirie /* 47003b262f2SGregor Boirie * A single fetch from pressure MSB register is enough to pop 47103b262f2SGregor Boirie * values out of FIFO. 47203b262f2SGregor Boirie */ 47303b262f2SGregor Boirie err = regmap_read(regs, ZPA2326_PRESS_OUT_H_REG, &val); 47403b262f2SGregor Boirie if (err < 0) 47503b262f2SGregor Boirie goto err; 47603b262f2SGregor Boirie 47703b262f2SGregor Boirie if (min_count) { 47803b262f2SGregor Boirie /* 47903b262f2SGregor Boirie * We know for sure there are at least min_count entries 48003b262f2SGregor Boirie * left in FIFO. Skip status register read. 48103b262f2SGregor Boirie */ 48203b262f2SGregor Boirie min_count--; 48303b262f2SGregor Boirie continue; 48403b262f2SGregor Boirie } 48503b262f2SGregor Boirie 48603b262f2SGregor Boirie err = regmap_read(regs, ZPA2326_STATUS_REG, &val); 48703b262f2SGregor Boirie if (err < 0) 48803b262f2SGregor Boirie goto err; 48903b262f2SGregor Boirie 49003b262f2SGregor Boirie } while (!(val & ZPA2326_STATUS_FIFO_E)); 49103b262f2SGregor Boirie 49203b262f2SGregor Boirie zpa2326_dbg(indio_dev, "FIFO cleared"); 49303b262f2SGregor Boirie 49403b262f2SGregor Boirie return 0; 49503b262f2SGregor Boirie 49603b262f2SGregor Boirie err: 49703b262f2SGregor Boirie zpa2326_err(indio_dev, "failed to clear FIFO (%d)", err); 49803b262f2SGregor Boirie 49903b262f2SGregor Boirie return err; 50003b262f2SGregor Boirie } 50103b262f2SGregor Boirie 50203b262f2SGregor Boirie /** 50303b262f2SGregor Boirie * zpa2326_dequeue_pressure() - Retrieve the most recent pressure sample from 50403b262f2SGregor Boirie * hardware FIFO. 50503b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 50603b262f2SGregor Boirie * @pressure: Sampled pressure output. 50703b262f2SGregor Boirie * 50803b262f2SGregor Boirie * Note that ZPA2326 hardware FIFO stores pressure samples only. 50903b262f2SGregor Boirie * 51003b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 51103b262f2SGregor Boirie */ 51203b262f2SGregor Boirie static int zpa2326_dequeue_pressure(const struct iio_dev *indio_dev, 51303b262f2SGregor Boirie u32 *pressure) 51403b262f2SGregor Boirie { 51503b262f2SGregor Boirie struct regmap *regs = ((struct zpa2326_private *) 51603b262f2SGregor Boirie iio_priv(indio_dev))->regmap; 51703b262f2SGregor Boirie unsigned int val; 51803b262f2SGregor Boirie int err; 51903b262f2SGregor Boirie int cleared = -1; 52003b262f2SGregor Boirie 52103b262f2SGregor Boirie err = regmap_read(regs, ZPA2326_STATUS_REG, &val); 52203b262f2SGregor Boirie if (err < 0) 52303b262f2SGregor Boirie return err; 52403b262f2SGregor Boirie 52503b262f2SGregor Boirie *pressure = 0; 52603b262f2SGregor Boirie 52703b262f2SGregor Boirie if (val & ZPA2326_STATUS_P_OR) { 52803b262f2SGregor Boirie /* 52903b262f2SGregor Boirie * Fifo overrun : first sample dequeued from FIFO is the 53003b262f2SGregor Boirie * newest. 53103b262f2SGregor Boirie */ 53203b262f2SGregor Boirie zpa2326_warn(indio_dev, "FIFO overflow"); 53303b262f2SGregor Boirie 53403b262f2SGregor Boirie err = regmap_bulk_read(regs, ZPA2326_PRESS_OUT_XL_REG, pressure, 53503b262f2SGregor Boirie 3); 53603b262f2SGregor Boirie if (err) 53703b262f2SGregor Boirie return err; 53803b262f2SGregor Boirie 53903b262f2SGregor Boirie #define ZPA2326_FIFO_DEPTH (16U) 54003b262f2SGregor Boirie /* Hardware FIFO may hold no more than 16 pressure samples. */ 54103b262f2SGregor Boirie return zpa2326_clear_fifo(indio_dev, ZPA2326_FIFO_DEPTH - 1); 54203b262f2SGregor Boirie } 54303b262f2SGregor Boirie 54403b262f2SGregor Boirie /* 54503b262f2SGregor Boirie * Fifo has not overflown : retrieve newest sample. We need to pop 54603b262f2SGregor Boirie * values out until FIFO is empty : last fetched pressure is the newest. 54703b262f2SGregor Boirie * In nominal cases, we should find a single queued sample only. 54803b262f2SGregor Boirie */ 54903b262f2SGregor Boirie do { 55003b262f2SGregor Boirie err = regmap_bulk_read(regs, ZPA2326_PRESS_OUT_XL_REG, pressure, 55103b262f2SGregor Boirie 3); 55203b262f2SGregor Boirie if (err) 55303b262f2SGregor Boirie return err; 55403b262f2SGregor Boirie 55503b262f2SGregor Boirie err = regmap_read(regs, ZPA2326_STATUS_REG, &val); 55603b262f2SGregor Boirie if (err < 0) 55703b262f2SGregor Boirie return err; 55803b262f2SGregor Boirie 55903b262f2SGregor Boirie cleared++; 56003b262f2SGregor Boirie } while (!(val & ZPA2326_STATUS_FIFO_E)); 56103b262f2SGregor Boirie 56203b262f2SGregor Boirie if (cleared) 56303b262f2SGregor Boirie /* 56403b262f2SGregor Boirie * Samples were pushed by hardware during previous rounds but we 56503b262f2SGregor Boirie * didn't consume them fast enough: inform user. 56603b262f2SGregor Boirie */ 56703b262f2SGregor Boirie zpa2326_dbg(indio_dev, "cleared %d FIFO entries", cleared); 56803b262f2SGregor Boirie 56903b262f2SGregor Boirie return 0; 57003b262f2SGregor Boirie } 57103b262f2SGregor Boirie 57203b262f2SGregor Boirie /** 57303b262f2SGregor Boirie * zpa2326_fill_sample_buffer() - Enqueue new channel samples to IIO buffer. 57403b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 57503b262f2SGregor Boirie * @private: Internal private state related to @indio_dev. 57603b262f2SGregor Boirie * 57703b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 57803b262f2SGregor Boirie */ 57903b262f2SGregor Boirie static int zpa2326_fill_sample_buffer(struct iio_dev *indio_dev, 58003b262f2SGregor Boirie const struct zpa2326_private *private) 58103b262f2SGregor Boirie { 58203b262f2SGregor Boirie struct { 58303b262f2SGregor Boirie u32 pressure; 58403b262f2SGregor Boirie u16 temperature; 58503b262f2SGregor Boirie u64 timestamp; 58603b262f2SGregor Boirie } sample; 58703b262f2SGregor Boirie int err; 58803b262f2SGregor Boirie 58903b262f2SGregor Boirie if (test_bit(0, indio_dev->active_scan_mask)) { 59003b262f2SGregor Boirie /* Get current pressure from hardware FIFO. */ 59103b262f2SGregor Boirie err = zpa2326_dequeue_pressure(indio_dev, &sample.pressure); 59203b262f2SGregor Boirie if (err) { 59303b262f2SGregor Boirie zpa2326_warn(indio_dev, "failed to fetch pressure (%d)", 59403b262f2SGregor Boirie err); 59503b262f2SGregor Boirie return err; 59603b262f2SGregor Boirie } 59703b262f2SGregor Boirie } 59803b262f2SGregor Boirie 59903b262f2SGregor Boirie if (test_bit(1, indio_dev->active_scan_mask)) { 60003b262f2SGregor Boirie /* Get current temperature. */ 60103b262f2SGregor Boirie err = regmap_bulk_read(private->regmap, ZPA2326_TEMP_OUT_L_REG, 60203b262f2SGregor Boirie &sample.temperature, 2); 60303b262f2SGregor Boirie if (err) { 60403b262f2SGregor Boirie zpa2326_warn(indio_dev, 60503b262f2SGregor Boirie "failed to fetch temperature (%d)", err); 60603b262f2SGregor Boirie return err; 60703b262f2SGregor Boirie } 60803b262f2SGregor Boirie } 60903b262f2SGregor Boirie 61003b262f2SGregor Boirie /* 61103b262f2SGregor Boirie * Now push samples using timestamp stored either : 61203b262f2SGregor Boirie * - by hardware interrupt handler if interrupt is available: see 61303b262f2SGregor Boirie * zpa2326_handle_irq(), 61403b262f2SGregor Boirie * - or oneshot completion polling machinery : see 61503b262f2SGregor Boirie * zpa2326_trigger_handler(). 61603b262f2SGregor Boirie */ 61703b262f2SGregor Boirie zpa2326_dbg(indio_dev, "filling raw samples buffer"); 61803b262f2SGregor Boirie 61903b262f2SGregor Boirie iio_push_to_buffers_with_timestamp(indio_dev, &sample, 62003b262f2SGregor Boirie private->timestamp); 62103b262f2SGregor Boirie 62203b262f2SGregor Boirie return 0; 62303b262f2SGregor Boirie } 62403b262f2SGregor Boirie 62503b262f2SGregor Boirie #ifdef CONFIG_PM 62603b262f2SGregor Boirie static int zpa2326_runtime_suspend(struct device *parent) 62703b262f2SGregor Boirie { 62803b262f2SGregor Boirie const struct iio_dev *indio_dev = dev_get_drvdata(parent); 62903b262f2SGregor Boirie 63003b262f2SGregor Boirie if (pm_runtime_autosuspend_expiration(parent)) 63103b262f2SGregor Boirie /* Userspace changed autosuspend delay. */ 63203b262f2SGregor Boirie return -EAGAIN; 63303b262f2SGregor Boirie 63403b262f2SGregor Boirie zpa2326_power_off(indio_dev, iio_priv(indio_dev)); 63503b262f2SGregor Boirie 63603b262f2SGregor Boirie return 0; 63703b262f2SGregor Boirie } 63803b262f2SGregor Boirie 63903b262f2SGregor Boirie static int zpa2326_runtime_resume(struct device *parent) 64003b262f2SGregor Boirie { 64103b262f2SGregor Boirie const struct iio_dev *indio_dev = dev_get_drvdata(parent); 64203b262f2SGregor Boirie 64303b262f2SGregor Boirie return zpa2326_power_on(indio_dev, iio_priv(indio_dev)); 64403b262f2SGregor Boirie } 64503b262f2SGregor Boirie 64603b262f2SGregor Boirie const struct dev_pm_ops zpa2326_pm_ops = { 64703b262f2SGregor Boirie SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 64803b262f2SGregor Boirie pm_runtime_force_resume) 64903b262f2SGregor Boirie SET_RUNTIME_PM_OPS(zpa2326_runtime_suspend, zpa2326_runtime_resume, 65003b262f2SGregor Boirie NULL) 65103b262f2SGregor Boirie }; 65203b262f2SGregor Boirie EXPORT_SYMBOL_GPL(zpa2326_pm_ops); 65303b262f2SGregor Boirie 65403b262f2SGregor Boirie /** 65503b262f2SGregor Boirie * zpa2326_resume() - Request the PM layer to power supply the device. 65603b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 65703b262f2SGregor Boirie * 65803b262f2SGregor Boirie * Return: 65903b262f2SGregor Boirie * < 0 - a negative error code meaning failure ; 66003b262f2SGregor Boirie * 0 - success, device has just been powered up ; 66103b262f2SGregor Boirie * 1 - success, device was already powered. 66203b262f2SGregor Boirie */ 66303b262f2SGregor Boirie static int zpa2326_resume(const struct iio_dev *indio_dev) 66403b262f2SGregor Boirie { 66503b262f2SGregor Boirie int err; 66603b262f2SGregor Boirie 66703b262f2SGregor Boirie err = pm_runtime_get_sync(indio_dev->dev.parent); 668d88de040SNavid Emamdoost if (err < 0) { 669d88de040SNavid Emamdoost pm_runtime_put(indio_dev->dev.parent); 67003b262f2SGregor Boirie return err; 671d88de040SNavid Emamdoost } 67203b262f2SGregor Boirie 67303b262f2SGregor Boirie if (err > 0) { 67403b262f2SGregor Boirie /* 67503b262f2SGregor Boirie * Device was already power supplied: get it out of low power 67603b262f2SGregor Boirie * mode and inform caller. 67703b262f2SGregor Boirie */ 67803b262f2SGregor Boirie zpa2326_enable_device(indio_dev); 67903b262f2SGregor Boirie return 1; 68003b262f2SGregor Boirie } 68103b262f2SGregor Boirie 68203b262f2SGregor Boirie /* Inform caller device has just been brought back to life. */ 68303b262f2SGregor Boirie return 0; 68403b262f2SGregor Boirie } 68503b262f2SGregor Boirie 68603b262f2SGregor Boirie /** 68703b262f2SGregor Boirie * zpa2326_suspend() - Schedule a power down using autosuspend feature of PM 68803b262f2SGregor Boirie * layer. 68903b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 69003b262f2SGregor Boirie * 69103b262f2SGregor Boirie * Device is switched to low power mode at first to save power even when 69203b262f2SGregor Boirie * attached regulator is a "dummy" one. 69303b262f2SGregor Boirie */ 69403b262f2SGregor Boirie static void zpa2326_suspend(struct iio_dev *indio_dev) 69503b262f2SGregor Boirie { 69603b262f2SGregor Boirie struct device *parent = indio_dev->dev.parent; 69703b262f2SGregor Boirie 69803b262f2SGregor Boirie zpa2326_sleep(indio_dev); 69903b262f2SGregor Boirie 70003b262f2SGregor Boirie pm_runtime_mark_last_busy(parent); 70103b262f2SGregor Boirie pm_runtime_put_autosuspend(parent); 70203b262f2SGregor Boirie } 70303b262f2SGregor Boirie 70403b262f2SGregor Boirie static void zpa2326_init_runtime(struct device *parent) 70503b262f2SGregor Boirie { 70603b262f2SGregor Boirie pm_runtime_get_noresume(parent); 70703b262f2SGregor Boirie pm_runtime_set_active(parent); 70803b262f2SGregor Boirie pm_runtime_enable(parent); 70903b262f2SGregor Boirie pm_runtime_set_autosuspend_delay(parent, 1000); 71003b262f2SGregor Boirie pm_runtime_use_autosuspend(parent); 71103b262f2SGregor Boirie pm_runtime_mark_last_busy(parent); 71203b262f2SGregor Boirie pm_runtime_put_autosuspend(parent); 71303b262f2SGregor Boirie } 71403b262f2SGregor Boirie 71503b262f2SGregor Boirie static void zpa2326_fini_runtime(struct device *parent) 71603b262f2SGregor Boirie { 71703b262f2SGregor Boirie pm_runtime_disable(parent); 71803b262f2SGregor Boirie pm_runtime_set_suspended(parent); 71903b262f2SGregor Boirie } 72003b262f2SGregor Boirie #else /* !CONFIG_PM */ 72103b262f2SGregor Boirie static int zpa2326_resume(const struct iio_dev *indio_dev) 72203b262f2SGregor Boirie { 72303b262f2SGregor Boirie zpa2326_enable_device(indio_dev); 72403b262f2SGregor Boirie 72503b262f2SGregor Boirie return 0; 72603b262f2SGregor Boirie } 72703b262f2SGregor Boirie 72803b262f2SGregor Boirie static void zpa2326_suspend(struct iio_dev *indio_dev) 72903b262f2SGregor Boirie { 73003b262f2SGregor Boirie zpa2326_sleep(indio_dev); 73103b262f2SGregor Boirie } 73203b262f2SGregor Boirie 73303b262f2SGregor Boirie #define zpa2326_init_runtime(_parent) 73403b262f2SGregor Boirie #define zpa2326_fini_runtime(_parent) 73503b262f2SGregor Boirie #endif /* !CONFIG_PM */ 73603b262f2SGregor Boirie 73703b262f2SGregor Boirie /** 73803b262f2SGregor Boirie * zpa2326_handle_irq() - Process hardware interrupts. 73903b262f2SGregor Boirie * @irq: Interrupt line the hardware uses to notify new data has arrived. 74003b262f2SGregor Boirie * @data: The IIO device associated with the sampling hardware. 74103b262f2SGregor Boirie * 74203b262f2SGregor Boirie * Timestamp buffered samples as soon as possible then schedule threaded bottom 74303b262f2SGregor Boirie * half. 74403b262f2SGregor Boirie * 74503b262f2SGregor Boirie * Return: Always successful. 74603b262f2SGregor Boirie */ 74703b262f2SGregor Boirie static irqreturn_t zpa2326_handle_irq(int irq, void *data) 74803b262f2SGregor Boirie { 749af873b0dSsimran singhal struct iio_dev *indio_dev = data; 75003b262f2SGregor Boirie 75103b262f2SGregor Boirie if (iio_buffer_enabled(indio_dev)) { 75203b262f2SGregor Boirie /* Timestamping needed for buffered sampling only. */ 75303b262f2SGregor Boirie ((struct zpa2326_private *) 75403b262f2SGregor Boirie iio_priv(indio_dev))->timestamp = iio_get_time_ns(indio_dev); 75503b262f2SGregor Boirie } 75603b262f2SGregor Boirie 75703b262f2SGregor Boirie return IRQ_WAKE_THREAD; 75803b262f2SGregor Boirie } 75903b262f2SGregor Boirie 76003b262f2SGregor Boirie /** 76103b262f2SGregor Boirie * zpa2326_handle_threaded_irq() - Interrupt bottom-half handler. 76203b262f2SGregor Boirie * @irq: Interrupt line the hardware uses to notify new data has arrived. 76303b262f2SGregor Boirie * @data: The IIO device associated with the sampling hardware. 76403b262f2SGregor Boirie * 76503b262f2SGregor Boirie * Mainly ensures interrupt is caused by a real "new sample available" 76603b262f2SGregor Boirie * condition. This relies upon the ability to perform blocking / sleeping bus 76703b262f2SGregor Boirie * accesses to slave's registers. This is why zpa2326_handle_threaded_irq() is 76803b262f2SGregor Boirie * called from within a thread, i.e. not called from hard interrupt context. 76903b262f2SGregor Boirie * 77003b262f2SGregor Boirie * When device is using its own internal hardware trigger in continuous sampling 77103b262f2SGregor Boirie * mode, data are available into hardware FIFO once interrupt has occurred. All 77203b262f2SGregor Boirie * we have to do is to dispatch the trigger, which in turn will fetch data and 77303b262f2SGregor Boirie * fill IIO buffer. 77403b262f2SGregor Boirie * 77503b262f2SGregor Boirie * When not using its own internal hardware trigger, the device has been 77603b262f2SGregor Boirie * configured in one-shot mode either by an external trigger or the IIO read_raw 77703b262f2SGregor Boirie * hook. This means one of the latter is currently waiting for sampling 77803b262f2SGregor Boirie * completion, in which case we must simply wake it up. 77903b262f2SGregor Boirie * 78003b262f2SGregor Boirie * See zpa2326_trigger_handler(). 78103b262f2SGregor Boirie * 78203b262f2SGregor Boirie * Return: 78303b262f2SGregor Boirie * %IRQ_NONE - no consistent interrupt happened ; 78403b262f2SGregor Boirie * %IRQ_HANDLED - there was new samples available. 78503b262f2SGregor Boirie */ 78603b262f2SGregor Boirie static irqreturn_t zpa2326_handle_threaded_irq(int irq, void *data) 78703b262f2SGregor Boirie { 788af873b0dSsimran singhal struct iio_dev *indio_dev = data; 78903b262f2SGregor Boirie struct zpa2326_private *priv = iio_priv(indio_dev); 79003b262f2SGregor Boirie unsigned int val; 79103b262f2SGregor Boirie bool cont; 79203b262f2SGregor Boirie irqreturn_t ret = IRQ_NONE; 79303b262f2SGregor Boirie 79403b262f2SGregor Boirie /* 79503b262f2SGregor Boirie * Are we using our own internal trigger in triggered buffer mode, i.e., 79603b262f2SGregor Boirie * currently working in continuous sampling mode ? 79703b262f2SGregor Boirie */ 79803b262f2SGregor Boirie cont = (iio_buffer_enabled(indio_dev) && 79903b262f2SGregor Boirie iio_trigger_using_own(indio_dev)); 80003b262f2SGregor Boirie 80103b262f2SGregor Boirie /* 80203b262f2SGregor Boirie * Device works according to a level interrupt scheme: reading interrupt 80303b262f2SGregor Boirie * status de-asserts interrupt line. 80403b262f2SGregor Boirie */ 80503b262f2SGregor Boirie priv->result = regmap_read(priv->regmap, ZPA2326_INT_SOURCE_REG, &val); 80603b262f2SGregor Boirie if (priv->result < 0) { 80703b262f2SGregor Boirie if (cont) 80803b262f2SGregor Boirie return IRQ_NONE; 80903b262f2SGregor Boirie 81003b262f2SGregor Boirie goto complete; 81103b262f2SGregor Boirie } 81203b262f2SGregor Boirie 81303b262f2SGregor Boirie /* Data ready is the only interrupt source we requested. */ 81403b262f2SGregor Boirie if (!(val & ZPA2326_INT_SOURCE_DATA_READY)) { 81503b262f2SGregor Boirie /* 81603b262f2SGregor Boirie * Interrupt happened but no new sample available: likely caused 81703b262f2SGregor Boirie * by spurious interrupts, in which case, returning IRQ_NONE 81803b262f2SGregor Boirie * allows to benefit from the generic spurious interrupts 81903b262f2SGregor Boirie * handling. 82003b262f2SGregor Boirie */ 82103b262f2SGregor Boirie zpa2326_warn(indio_dev, "unexpected interrupt status %02x", 82203b262f2SGregor Boirie val); 82303b262f2SGregor Boirie 82403b262f2SGregor Boirie if (cont) 82503b262f2SGregor Boirie return IRQ_NONE; 82603b262f2SGregor Boirie 82703b262f2SGregor Boirie priv->result = -ENODATA; 82803b262f2SGregor Boirie goto complete; 82903b262f2SGregor Boirie } 83003b262f2SGregor Boirie 83103b262f2SGregor Boirie /* New sample available: dispatch internal trigger consumers. */ 83203b262f2SGregor Boirie iio_trigger_poll_chained(priv->trigger); 83303b262f2SGregor Boirie 83403b262f2SGregor Boirie if (cont) 83503b262f2SGregor Boirie /* 83603b262f2SGregor Boirie * Internal hardware trigger has been scheduled above : it will 83703b262f2SGregor Boirie * fetch data on its own. 83803b262f2SGregor Boirie */ 83903b262f2SGregor Boirie return IRQ_HANDLED; 84003b262f2SGregor Boirie 84103b262f2SGregor Boirie ret = IRQ_HANDLED; 84203b262f2SGregor Boirie 84303b262f2SGregor Boirie complete: 84403b262f2SGregor Boirie /* 84503b262f2SGregor Boirie * Wake up direct or externaly triggered buffer mode waiters: see 84603b262f2SGregor Boirie * zpa2326_sample_oneshot() and zpa2326_trigger_handler(). 84703b262f2SGregor Boirie */ 84803b262f2SGregor Boirie complete(&priv->data_ready); 84903b262f2SGregor Boirie 85003b262f2SGregor Boirie return ret; 85103b262f2SGregor Boirie } 85203b262f2SGregor Boirie 85303b262f2SGregor Boirie /** 85403b262f2SGregor Boirie * zpa2326_wait_oneshot_completion() - Wait for oneshot data ready interrupt. 85503b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 85603b262f2SGregor Boirie * @private: Internal private state related to @indio_dev. 85703b262f2SGregor Boirie * 85803b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 85903b262f2SGregor Boirie */ 86003b262f2SGregor Boirie static int zpa2326_wait_oneshot_completion(const struct iio_dev *indio_dev, 86103b262f2SGregor Boirie struct zpa2326_private *private) 86203b262f2SGregor Boirie { 86303b262f2SGregor Boirie unsigned int val; 864e7215fe4SNicholas Mc Guire long timeout; 86503b262f2SGregor Boirie 86603b262f2SGregor Boirie zpa2326_dbg(indio_dev, "waiting for one shot completion interrupt"); 86703b262f2SGregor Boirie 868e7215fe4SNicholas Mc Guire timeout = wait_for_completion_interruptible_timeout( 86903b262f2SGregor Boirie &private->data_ready, ZPA2326_CONVERSION_JIFFIES); 870e7215fe4SNicholas Mc Guire if (timeout > 0) 87103b262f2SGregor Boirie /* 87203b262f2SGregor Boirie * Interrupt handler completed before timeout: return operation 87303b262f2SGregor Boirie * status. 87403b262f2SGregor Boirie */ 87503b262f2SGregor Boirie return private->result; 87603b262f2SGregor Boirie 87703b262f2SGregor Boirie /* Clear all interrupts just to be sure. */ 87803b262f2SGregor Boirie regmap_read(private->regmap, ZPA2326_INT_SOURCE_REG, &val); 87903b262f2SGregor Boirie 880e7215fe4SNicholas Mc Guire if (!timeout) { 88103b262f2SGregor Boirie /* Timed out. */ 882e7215fe4SNicholas Mc Guire zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)", 883e7215fe4SNicholas Mc Guire timeout); 884f61dfff2SGeert Uytterhoeven return -ETIME; 885e7215fe4SNicholas Mc Guire } 88603b262f2SGregor Boirie 887f61dfff2SGeert Uytterhoeven zpa2326_warn(indio_dev, "wait for one shot interrupt cancelled"); 888f61dfff2SGeert Uytterhoeven return -ERESTARTSYS; 88903b262f2SGregor Boirie } 89003b262f2SGregor Boirie 89103b262f2SGregor Boirie static int zpa2326_init_managed_irq(struct device *parent, 89203b262f2SGregor Boirie struct iio_dev *indio_dev, 89303b262f2SGregor Boirie struct zpa2326_private *private, 89403b262f2SGregor Boirie int irq) 89503b262f2SGregor Boirie { 89603b262f2SGregor Boirie int err; 89703b262f2SGregor Boirie 89803b262f2SGregor Boirie private->irq = irq; 89903b262f2SGregor Boirie 90003b262f2SGregor Boirie if (irq <= 0) { 90103b262f2SGregor Boirie /* 90203b262f2SGregor Boirie * Platform declared no interrupt line: device will be polled 90303b262f2SGregor Boirie * for data availability. 90403b262f2SGregor Boirie */ 90503b262f2SGregor Boirie dev_info(parent, "no interrupt found, running in polling mode"); 90603b262f2SGregor Boirie return 0; 90703b262f2SGregor Boirie } 90803b262f2SGregor Boirie 90903b262f2SGregor Boirie init_completion(&private->data_ready); 91003b262f2SGregor Boirie 91103b262f2SGregor Boirie /* Request handler to be scheduled into threaded interrupt context. */ 91203b262f2SGregor Boirie err = devm_request_threaded_irq(parent, irq, zpa2326_handle_irq, 91303b262f2SGregor Boirie zpa2326_handle_threaded_irq, 91403b262f2SGregor Boirie IRQF_TRIGGER_RISING | IRQF_ONESHOT, 91503b262f2SGregor Boirie dev_name(parent), indio_dev); 91603b262f2SGregor Boirie if (err) { 91703b262f2SGregor Boirie dev_err(parent, "failed to request interrupt %d (%d)", irq, 91803b262f2SGregor Boirie err); 91903b262f2SGregor Boirie return err; 92003b262f2SGregor Boirie } 92103b262f2SGregor Boirie 92203b262f2SGregor Boirie dev_info(parent, "using interrupt %d", irq); 92303b262f2SGregor Boirie 92403b262f2SGregor Boirie return 0; 92503b262f2SGregor Boirie } 92603b262f2SGregor Boirie 92703b262f2SGregor Boirie /** 92803b262f2SGregor Boirie * zpa2326_poll_oneshot_completion() - Actively poll for one shot data ready. 92903b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 93003b262f2SGregor Boirie * 93103b262f2SGregor Boirie * Loop over registers content to detect end of sampling cycle. Used when DT 93203b262f2SGregor Boirie * declared no valid interrupt lines. 93303b262f2SGregor Boirie * 93403b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 93503b262f2SGregor Boirie */ 93603b262f2SGregor Boirie static int zpa2326_poll_oneshot_completion(const struct iio_dev *indio_dev) 93703b262f2SGregor Boirie { 93803b262f2SGregor Boirie unsigned long tmout = jiffies + ZPA2326_CONVERSION_JIFFIES; 93903b262f2SGregor Boirie struct regmap *regs = ((struct zpa2326_private *) 94003b262f2SGregor Boirie iio_priv(indio_dev))->regmap; 94103b262f2SGregor Boirie unsigned int val; 94203b262f2SGregor Boirie int err; 94303b262f2SGregor Boirie 94403b262f2SGregor Boirie zpa2326_dbg(indio_dev, "polling for one shot completion"); 94503b262f2SGregor Boirie 94603b262f2SGregor Boirie /* 94703b262f2SGregor Boirie * At least, 100 ms is needed for the device to complete its one-shot 94803b262f2SGregor Boirie * cycle. 94903b262f2SGregor Boirie */ 95003b262f2SGregor Boirie if (msleep_interruptible(100)) 95103b262f2SGregor Boirie return -ERESTARTSYS; 95203b262f2SGregor Boirie 95303b262f2SGregor Boirie /* Poll for conversion completion in hardware. */ 95403b262f2SGregor Boirie while (true) { 95503b262f2SGregor Boirie err = regmap_read(regs, ZPA2326_CTRL_REG0_REG, &val); 95603b262f2SGregor Boirie if (err < 0) 95703b262f2SGregor Boirie goto err; 95803b262f2SGregor Boirie 95903b262f2SGregor Boirie if (!(val & ZPA2326_CTRL_REG0_ONE_SHOT)) 96003b262f2SGregor Boirie /* One-shot bit self clears at conversion end. */ 96103b262f2SGregor Boirie break; 96203b262f2SGregor Boirie 96303b262f2SGregor Boirie if (time_after(jiffies, tmout)) { 96403b262f2SGregor Boirie /* Prevent from waiting forever : let's time out. */ 96503b262f2SGregor Boirie err = -ETIME; 96603b262f2SGregor Boirie goto err; 96703b262f2SGregor Boirie } 96803b262f2SGregor Boirie 96903b262f2SGregor Boirie usleep_range(10000, 20000); 97003b262f2SGregor Boirie } 97103b262f2SGregor Boirie 97203b262f2SGregor Boirie /* 97303b262f2SGregor Boirie * In oneshot mode, pressure sample availability guarantees that 97403b262f2SGregor Boirie * temperature conversion has also completed : just check pressure 97503b262f2SGregor Boirie * status bit to keep things simple. 97603b262f2SGregor Boirie */ 97703b262f2SGregor Boirie err = regmap_read(regs, ZPA2326_STATUS_REG, &val); 97803b262f2SGregor Boirie if (err < 0) 97903b262f2SGregor Boirie goto err; 98003b262f2SGregor Boirie 98103b262f2SGregor Boirie if (!(val & ZPA2326_STATUS_P_DA)) { 98203b262f2SGregor Boirie /* No sample available. */ 98303b262f2SGregor Boirie err = -ENODATA; 98403b262f2SGregor Boirie goto err; 98503b262f2SGregor Boirie } 98603b262f2SGregor Boirie 98703b262f2SGregor Boirie return 0; 98803b262f2SGregor Boirie 98903b262f2SGregor Boirie err: 99003b262f2SGregor Boirie zpa2326_warn(indio_dev, "failed to poll one shot completion (%d)", err); 99103b262f2SGregor Boirie 99203b262f2SGregor Boirie return err; 99303b262f2SGregor Boirie } 99403b262f2SGregor Boirie 99503b262f2SGregor Boirie /** 99603b262f2SGregor Boirie * zpa2326_fetch_raw_sample() - Retrieve a raw sample and convert it to CPU 99703b262f2SGregor Boirie * endianness. 99803b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 99903b262f2SGregor Boirie * @type: Type of measurement / channel to fetch from. 100003b262f2SGregor Boirie * @value: Sample output. 100103b262f2SGregor Boirie * 100203b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 100303b262f2SGregor Boirie */ 100403b262f2SGregor Boirie static int zpa2326_fetch_raw_sample(const struct iio_dev *indio_dev, 100503b262f2SGregor Boirie enum iio_chan_type type, 100603b262f2SGregor Boirie int *value) 100703b262f2SGregor Boirie { 100803b262f2SGregor Boirie struct regmap *regs = ((struct zpa2326_private *) 100903b262f2SGregor Boirie iio_priv(indio_dev))->regmap; 101003b262f2SGregor Boirie int err; 1011e8ee40e7SAndy Shevchenko u8 v[3]; 101203b262f2SGregor Boirie 101303b262f2SGregor Boirie switch (type) { 101403b262f2SGregor Boirie case IIO_PRESSURE: 101503b262f2SGregor Boirie zpa2326_dbg(indio_dev, "fetching raw pressure sample"); 101603b262f2SGregor Boirie 1017e8ee40e7SAndy Shevchenko err = regmap_bulk_read(regs, ZPA2326_PRESS_OUT_XL_REG, v, sizeof(v)); 101803b262f2SGregor Boirie if (err) { 101903b262f2SGregor Boirie zpa2326_warn(indio_dev, "failed to fetch pressure (%d)", 102003b262f2SGregor Boirie err); 102103b262f2SGregor Boirie return err; 102203b262f2SGregor Boirie } 102303b262f2SGregor Boirie 1024e8ee40e7SAndy Shevchenko *value = get_unaligned_le24(&v[0]); 102503b262f2SGregor Boirie 102603b262f2SGregor Boirie return IIO_VAL_INT; 102703b262f2SGregor Boirie 102803b262f2SGregor Boirie case IIO_TEMP: 102903b262f2SGregor Boirie zpa2326_dbg(indio_dev, "fetching raw temperature sample"); 103003b262f2SGregor Boirie 103103b262f2SGregor Boirie err = regmap_bulk_read(regs, ZPA2326_TEMP_OUT_L_REG, value, 2); 103203b262f2SGregor Boirie if (err) { 103303b262f2SGregor Boirie zpa2326_warn(indio_dev, 103403b262f2SGregor Boirie "failed to fetch temperature (%d)", err); 103503b262f2SGregor Boirie return err; 103603b262f2SGregor Boirie } 103703b262f2SGregor Boirie 103803b262f2SGregor Boirie /* Temperature is a 16 bits wide little-endian signed int. */ 103903b262f2SGregor Boirie *value = (int)le16_to_cpup((__le16 *)value); 104003b262f2SGregor Boirie 104103b262f2SGregor Boirie return IIO_VAL_INT; 104203b262f2SGregor Boirie 104303b262f2SGregor Boirie default: 104403b262f2SGregor Boirie return -EINVAL; 104503b262f2SGregor Boirie } 104603b262f2SGregor Boirie } 104703b262f2SGregor Boirie 104803b262f2SGregor Boirie /** 104903b262f2SGregor Boirie * zpa2326_sample_oneshot() - Perform a complete one shot sampling cycle. 105003b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 105103b262f2SGregor Boirie * @type: Type of measurement / channel to fetch from. 105203b262f2SGregor Boirie * @value: Sample output. 105303b262f2SGregor Boirie * 105403b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 105503b262f2SGregor Boirie */ 105603b262f2SGregor Boirie static int zpa2326_sample_oneshot(struct iio_dev *indio_dev, 105703b262f2SGregor Boirie enum iio_chan_type type, 105803b262f2SGregor Boirie int *value) 105903b262f2SGregor Boirie { 106003b262f2SGregor Boirie int ret; 106103b262f2SGregor Boirie struct zpa2326_private *priv; 106203b262f2SGregor Boirie 106303b262f2SGregor Boirie ret = iio_device_claim_direct_mode(indio_dev); 106403b262f2SGregor Boirie if (ret) 106503b262f2SGregor Boirie return ret; 106603b262f2SGregor Boirie 106703b262f2SGregor Boirie ret = zpa2326_resume(indio_dev); 106803b262f2SGregor Boirie if (ret < 0) 106903b262f2SGregor Boirie goto release; 107003b262f2SGregor Boirie 107103b262f2SGregor Boirie priv = iio_priv(indio_dev); 107203b262f2SGregor Boirie 107303b262f2SGregor Boirie if (ret > 0) { 107403b262f2SGregor Boirie /* 107503b262f2SGregor Boirie * We were already power supplied. Just clear hardware FIFO to 107603b262f2SGregor Boirie * get rid of samples acquired during previous rounds (if any). 107703b262f2SGregor Boirie * Sampling operation always generates both temperature and 107803b262f2SGregor Boirie * pressure samples. The latter are always enqueued into 107903b262f2SGregor Boirie * hardware FIFO. This may lead to situations were pressure 108003b262f2SGregor Boirie * samples still sit into FIFO when previous cycle(s) fetched 108103b262f2SGregor Boirie * temperature data only. 108203b262f2SGregor Boirie * Hence, we need to clear hardware FIFO content to prevent from 108303b262f2SGregor Boirie * getting outdated values at the end of current cycle. 108403b262f2SGregor Boirie */ 108503b262f2SGregor Boirie if (type == IIO_PRESSURE) { 108603b262f2SGregor Boirie ret = zpa2326_clear_fifo(indio_dev, 0); 108703b262f2SGregor Boirie if (ret) 108803b262f2SGregor Boirie goto suspend; 108903b262f2SGregor Boirie } 109003b262f2SGregor Boirie } else { 109103b262f2SGregor Boirie /* 109203b262f2SGregor Boirie * We have just been power supplied, i.e. device is in default 109303b262f2SGregor Boirie * "out of reset" state, meaning we need to reconfigure it 109403b262f2SGregor Boirie * entirely. 109503b262f2SGregor Boirie */ 109603b262f2SGregor Boirie ret = zpa2326_config_oneshot(indio_dev, priv->irq); 109703b262f2SGregor Boirie if (ret) 109803b262f2SGregor Boirie goto suspend; 109903b262f2SGregor Boirie } 110003b262f2SGregor Boirie 110103b262f2SGregor Boirie /* Start a sampling cycle in oneshot mode. */ 110203b262f2SGregor Boirie ret = zpa2326_start_oneshot(indio_dev); 110303b262f2SGregor Boirie if (ret) 110403b262f2SGregor Boirie goto suspend; 110503b262f2SGregor Boirie 110603b262f2SGregor Boirie /* Wait for sampling cycle to complete. */ 110703b262f2SGregor Boirie if (priv->irq > 0) 110803b262f2SGregor Boirie ret = zpa2326_wait_oneshot_completion(indio_dev, priv); 110903b262f2SGregor Boirie else 111003b262f2SGregor Boirie ret = zpa2326_poll_oneshot_completion(indio_dev); 111103b262f2SGregor Boirie 111203b262f2SGregor Boirie if (ret) 111303b262f2SGregor Boirie goto suspend; 111403b262f2SGregor Boirie 111503b262f2SGregor Boirie /* Retrieve raw sample value and convert it to CPU endianness. */ 111603b262f2SGregor Boirie ret = zpa2326_fetch_raw_sample(indio_dev, type, value); 111703b262f2SGregor Boirie 111803b262f2SGregor Boirie suspend: 111903b262f2SGregor Boirie zpa2326_suspend(indio_dev); 112003b262f2SGregor Boirie release: 112103b262f2SGregor Boirie iio_device_release_direct_mode(indio_dev); 112203b262f2SGregor Boirie 112303b262f2SGregor Boirie return ret; 112403b262f2SGregor Boirie } 112503b262f2SGregor Boirie 112603b262f2SGregor Boirie /** 112703b262f2SGregor Boirie * zpa2326_trigger_handler() - Perform an IIO buffered sampling round in one 112803b262f2SGregor Boirie * shot mode. 112903b262f2SGregor Boirie * @irq: The software interrupt assigned to @data 113003b262f2SGregor Boirie * @data: The IIO poll function dispatched by external trigger our device is 113103b262f2SGregor Boirie * attached to. 113203b262f2SGregor Boirie * 113303b262f2SGregor Boirie * Bottom-half handler called by the IIO trigger to which our device is 113403b262f2SGregor Boirie * currently attached. Allows us to synchronize this device buffered sampling 113503b262f2SGregor Boirie * either with external events (such as timer expiration, external device sample 113603b262f2SGregor Boirie * ready, etc...) or with its own interrupt (internal hardware trigger). 113703b262f2SGregor Boirie * 113803b262f2SGregor Boirie * When using an external trigger, basically run the same sequence of operations 113903b262f2SGregor Boirie * as for zpa2326_sample_oneshot() with the following hereafter. Hardware FIFO 114003b262f2SGregor Boirie * is not cleared since already done at buffering enable time and samples 114103b262f2SGregor Boirie * dequeueing always retrieves the most recent value. 114203b262f2SGregor Boirie * 114303b262f2SGregor Boirie * Otherwise, when internal hardware trigger has dispatched us, just fetch data 114403b262f2SGregor Boirie * from hardware FIFO. 114503b262f2SGregor Boirie * 114603b262f2SGregor Boirie * Fetched data will pushed unprocessed to IIO buffer since samples conversion 114703b262f2SGregor Boirie * is delegated to userspace in buffered mode (endianness, etc...). 114803b262f2SGregor Boirie * 114903b262f2SGregor Boirie * Return: 115003b262f2SGregor Boirie * %IRQ_NONE - no consistent interrupt happened ; 115103b262f2SGregor Boirie * %IRQ_HANDLED - there was new samples available. 115203b262f2SGregor Boirie */ 115303b262f2SGregor Boirie static irqreturn_t zpa2326_trigger_handler(int irq, void *data) 115403b262f2SGregor Boirie { 115503b262f2SGregor Boirie struct iio_dev *indio_dev = ((struct iio_poll_func *) 115603b262f2SGregor Boirie data)->indio_dev; 115703b262f2SGregor Boirie struct zpa2326_private *priv = iio_priv(indio_dev); 115803b262f2SGregor Boirie bool cont; 115903b262f2SGregor Boirie 116003b262f2SGregor Boirie /* 116103b262f2SGregor Boirie * We have been dispatched, meaning we are in triggered buffer mode. 116203b262f2SGregor Boirie * Using our own internal trigger implies we are currently in continuous 116303b262f2SGregor Boirie * hardware sampling mode. 116403b262f2SGregor Boirie */ 116503b262f2SGregor Boirie cont = iio_trigger_using_own(indio_dev); 116603b262f2SGregor Boirie 116703b262f2SGregor Boirie if (!cont) { 116803b262f2SGregor Boirie /* On demand sampling : start a one shot cycle. */ 116903b262f2SGregor Boirie if (zpa2326_start_oneshot(indio_dev)) 117003b262f2SGregor Boirie goto out; 117103b262f2SGregor Boirie 117203b262f2SGregor Boirie /* Wait for sampling cycle to complete. */ 117303b262f2SGregor Boirie if (priv->irq <= 0) { 117403b262f2SGregor Boirie /* No interrupt available: poll for completion. */ 117503b262f2SGregor Boirie if (zpa2326_poll_oneshot_completion(indio_dev)) 117603b262f2SGregor Boirie goto out; 117703b262f2SGregor Boirie 117803b262f2SGregor Boirie /* Only timestamp sample once it is ready. */ 117903b262f2SGregor Boirie priv->timestamp = iio_get_time_ns(indio_dev); 118003b262f2SGregor Boirie } else { 118103b262f2SGregor Boirie /* Interrupt handlers will timestamp for us. */ 118203b262f2SGregor Boirie if (zpa2326_wait_oneshot_completion(indio_dev, priv)) 118303b262f2SGregor Boirie goto out; 118403b262f2SGregor Boirie } 118503b262f2SGregor Boirie } 118603b262f2SGregor Boirie 118703b262f2SGregor Boirie /* Enqueue to IIO buffer / userspace. */ 118803b262f2SGregor Boirie zpa2326_fill_sample_buffer(indio_dev, priv); 118903b262f2SGregor Boirie 119003b262f2SGregor Boirie out: 119103b262f2SGregor Boirie if (!cont) 119203b262f2SGregor Boirie /* Don't switch to low power if sampling continuously. */ 119303b262f2SGregor Boirie zpa2326_sleep(indio_dev); 119403b262f2SGregor Boirie 119503b262f2SGregor Boirie /* Inform attached trigger we are done. */ 119603b262f2SGregor Boirie iio_trigger_notify_done(indio_dev->trig); 119703b262f2SGregor Boirie 119803b262f2SGregor Boirie return IRQ_HANDLED; 119903b262f2SGregor Boirie } 120003b262f2SGregor Boirie 120103b262f2SGregor Boirie /** 120203b262f2SGregor Boirie * zpa2326_preenable_buffer() - Prepare device for configuring triggered 120303b262f2SGregor Boirie * sampling 120403b262f2SGregor Boirie * modes. 120503b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 120603b262f2SGregor Boirie * 120703b262f2SGregor Boirie * Basically power up device. 120803b262f2SGregor Boirie * Called with IIO device's lock held. 120903b262f2SGregor Boirie * 121003b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 121103b262f2SGregor Boirie */ 121203b262f2SGregor Boirie static int zpa2326_preenable_buffer(struct iio_dev *indio_dev) 121303b262f2SGregor Boirie { 121403b262f2SGregor Boirie int ret = zpa2326_resume(indio_dev); 121503b262f2SGregor Boirie 121603b262f2SGregor Boirie if (ret < 0) 121703b262f2SGregor Boirie return ret; 121803b262f2SGregor Boirie 121903b262f2SGregor Boirie /* Tell zpa2326_postenable_buffer() if we have just been powered on. */ 122003b262f2SGregor Boirie ((struct zpa2326_private *) 122103b262f2SGregor Boirie iio_priv(indio_dev))->waken = iio_priv(indio_dev); 122203b262f2SGregor Boirie 122303b262f2SGregor Boirie return 0; 122403b262f2SGregor Boirie } 122503b262f2SGregor Boirie 122603b262f2SGregor Boirie /** 122703b262f2SGregor Boirie * zpa2326_postenable_buffer() - Configure device for triggered sampling. 122803b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 122903b262f2SGregor Boirie * 123003b262f2SGregor Boirie * Basically setup one-shot mode if plugging external trigger. 123103b262f2SGregor Boirie * Otherwise, let internal trigger configure continuous sampling : 123203b262f2SGregor Boirie * see zpa2326_set_trigger_state(). 123303b262f2SGregor Boirie * 123403b262f2SGregor Boirie * If an error is returned, IIO layer will call our postdisable hook for us, 123503b262f2SGregor Boirie * i.e. no need to explicitly power device off here. 123603b262f2SGregor Boirie * Called with IIO device's lock held. 123703b262f2SGregor Boirie * 123803b262f2SGregor Boirie * Called with IIO device's lock held. 123903b262f2SGregor Boirie * 124003b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 124103b262f2SGregor Boirie */ 124203b262f2SGregor Boirie static int zpa2326_postenable_buffer(struct iio_dev *indio_dev) 124303b262f2SGregor Boirie { 124403b262f2SGregor Boirie const struct zpa2326_private *priv = iio_priv(indio_dev); 124503b262f2SGregor Boirie int err; 124603b262f2SGregor Boirie 124703b262f2SGregor Boirie if (!priv->waken) { 124803b262f2SGregor Boirie /* 124903b262f2SGregor Boirie * We were already power supplied. Just clear hardware FIFO to 125003b262f2SGregor Boirie * get rid of samples acquired during previous rounds (if any). 125103b262f2SGregor Boirie */ 125203b262f2SGregor Boirie err = zpa2326_clear_fifo(indio_dev, 0); 1253f11d59d8SLars-Peter Clausen if (err) { 1254f11d59d8SLars-Peter Clausen zpa2326_err(indio_dev, 1255f11d59d8SLars-Peter Clausen "failed to enable buffering (%d)", err); 1256f11d59d8SLars-Peter Clausen return err; 1257f11d59d8SLars-Peter Clausen } 125803b262f2SGregor Boirie } 125903b262f2SGregor Boirie 126003b262f2SGregor Boirie if (!iio_trigger_using_own(indio_dev) && priv->waken) { 126103b262f2SGregor Boirie /* 126203b262f2SGregor Boirie * We are using an external trigger and we have just been 126303b262f2SGregor Boirie * powered up: reconfigure one-shot mode. 126403b262f2SGregor Boirie */ 126503b262f2SGregor Boirie err = zpa2326_config_oneshot(indio_dev, priv->irq); 1266f11d59d8SLars-Peter Clausen if (err) { 1267f11d59d8SLars-Peter Clausen zpa2326_err(indio_dev, 1268f11d59d8SLars-Peter Clausen "failed to enable buffering (%d)", err); 1269f11d59d8SLars-Peter Clausen return err; 1270f11d59d8SLars-Peter Clausen } 127103b262f2SGregor Boirie } 127203b262f2SGregor Boirie 127303b262f2SGregor Boirie return 0; 127403b262f2SGregor Boirie } 127503b262f2SGregor Boirie 127603b262f2SGregor Boirie static int zpa2326_postdisable_buffer(struct iio_dev *indio_dev) 127703b262f2SGregor Boirie { 127803b262f2SGregor Boirie zpa2326_suspend(indio_dev); 127903b262f2SGregor Boirie 128003b262f2SGregor Boirie return 0; 128103b262f2SGregor Boirie } 128203b262f2SGregor Boirie 128303b262f2SGregor Boirie static const struct iio_buffer_setup_ops zpa2326_buffer_setup_ops = { 128403b262f2SGregor Boirie .preenable = zpa2326_preenable_buffer, 128503b262f2SGregor Boirie .postenable = zpa2326_postenable_buffer, 128603b262f2SGregor Boirie .postdisable = zpa2326_postdisable_buffer 128703b262f2SGregor Boirie }; 128803b262f2SGregor Boirie 128903b262f2SGregor Boirie /** 129003b262f2SGregor Boirie * zpa2326_set_trigger_state() - Start / stop continuous sampling. 129103b262f2SGregor Boirie * @trig: The trigger being attached to IIO device associated with the sampling 129203b262f2SGregor Boirie * hardware. 129303b262f2SGregor Boirie * @state: Tell whether to start (true) or stop (false) 129403b262f2SGregor Boirie * 129503b262f2SGregor Boirie * Basically enable / disable hardware continuous sampling mode. 129603b262f2SGregor Boirie * 129703b262f2SGregor Boirie * Called with IIO device's lock held at postenable() or predisable() time. 129803b262f2SGregor Boirie * 129903b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 130003b262f2SGregor Boirie */ 130103b262f2SGregor Boirie static int zpa2326_set_trigger_state(struct iio_trigger *trig, bool state) 130203b262f2SGregor Boirie { 130303b262f2SGregor Boirie const struct iio_dev *indio_dev = dev_get_drvdata( 130403b262f2SGregor Boirie trig->dev.parent); 130503b262f2SGregor Boirie const struct zpa2326_private *priv = iio_priv(indio_dev); 130603b262f2SGregor Boirie int err; 130703b262f2SGregor Boirie 130803b262f2SGregor Boirie if (!state) { 130903b262f2SGregor Boirie /* 131003b262f2SGregor Boirie * Switch trigger off : in case of failure, interrupt is left 131103b262f2SGregor Boirie * disabled in order to prevent handler from accessing released 131203b262f2SGregor Boirie * resources. 131303b262f2SGregor Boirie */ 131403b262f2SGregor Boirie unsigned int val; 131503b262f2SGregor Boirie 131603b262f2SGregor Boirie /* 131703b262f2SGregor Boirie * As device is working in continuous mode, handlers may be 131803b262f2SGregor Boirie * accessing resources we are currently freeing... 131903b262f2SGregor Boirie * Prevent this by disabling interrupt handlers and ensure 132003b262f2SGregor Boirie * the device will generate no more interrupts unless explicitly 132103b262f2SGregor Boirie * required to, i.e. by restoring back to default one shot mode. 132203b262f2SGregor Boirie */ 132303b262f2SGregor Boirie disable_irq(priv->irq); 132403b262f2SGregor Boirie 132503b262f2SGregor Boirie /* 132603b262f2SGregor Boirie * Disable continuous sampling mode to restore settings for 132703b262f2SGregor Boirie * one shot / direct sampling operations. 132803b262f2SGregor Boirie */ 132903b262f2SGregor Boirie err = regmap_write(priv->regmap, ZPA2326_CTRL_REG3_REG, 133003b262f2SGregor Boirie zpa2326_highest_frequency()->odr); 133103b262f2SGregor Boirie if (err) 133203b262f2SGregor Boirie return err; 133303b262f2SGregor Boirie 133403b262f2SGregor Boirie /* 133503b262f2SGregor Boirie * Now that device won't generate interrupts on its own, 133603b262f2SGregor Boirie * acknowledge any currently active interrupts (may happen on 133703b262f2SGregor Boirie * rare occasions while stopping continuous mode). 133803b262f2SGregor Boirie */ 133903b262f2SGregor Boirie err = regmap_read(priv->regmap, ZPA2326_INT_SOURCE_REG, &val); 134003b262f2SGregor Boirie if (err < 0) 134103b262f2SGregor Boirie return err; 134203b262f2SGregor Boirie 134303b262f2SGregor Boirie /* 134403b262f2SGregor Boirie * Re-enable interrupts only if we can guarantee the device will 134503b262f2SGregor Boirie * generate no more interrupts to prevent handlers from 134603b262f2SGregor Boirie * accessing released resources. 134703b262f2SGregor Boirie */ 134803b262f2SGregor Boirie enable_irq(priv->irq); 134903b262f2SGregor Boirie 135003b262f2SGregor Boirie zpa2326_dbg(indio_dev, "continuous mode stopped"); 135103b262f2SGregor Boirie } else { 135203b262f2SGregor Boirie /* 135303b262f2SGregor Boirie * Switch trigger on : start continuous sampling at required 135403b262f2SGregor Boirie * frequency. 135503b262f2SGregor Boirie */ 135603b262f2SGregor Boirie 135703b262f2SGregor Boirie if (priv->waken) { 135803b262f2SGregor Boirie /* Enable interrupt if getting out of reset. */ 135903b262f2SGregor Boirie err = regmap_write(priv->regmap, ZPA2326_CTRL_REG1_REG, 136003b262f2SGregor Boirie (u8) 136103b262f2SGregor Boirie ~ZPA2326_CTRL_REG1_MASK_DATA_READY); 136203b262f2SGregor Boirie if (err) 136303b262f2SGregor Boirie return err; 136403b262f2SGregor Boirie } 136503b262f2SGregor Boirie 136603b262f2SGregor Boirie /* Enable continuous sampling at specified frequency. */ 136703b262f2SGregor Boirie err = regmap_write(priv->regmap, ZPA2326_CTRL_REG3_REG, 136803b262f2SGregor Boirie ZPA2326_CTRL_REG3_ENABLE_MEAS | 136903b262f2SGregor Boirie priv->frequency->odr); 137003b262f2SGregor Boirie if (err) 137103b262f2SGregor Boirie return err; 137203b262f2SGregor Boirie 137303b262f2SGregor Boirie zpa2326_dbg(indio_dev, "continuous mode setup @%dHz", 137403b262f2SGregor Boirie priv->frequency->hz); 137503b262f2SGregor Boirie } 137603b262f2SGregor Boirie 137703b262f2SGregor Boirie return 0; 137803b262f2SGregor Boirie } 137903b262f2SGregor Boirie 138003b262f2SGregor Boirie static const struct iio_trigger_ops zpa2326_trigger_ops = { 138103b262f2SGregor Boirie .set_trigger_state = zpa2326_set_trigger_state, 138203b262f2SGregor Boirie }; 138303b262f2SGregor Boirie 138403b262f2SGregor Boirie /** 138544f14695SJonathan Cameron * zpa2326_init_managed_trigger() - Create interrupt driven / hardware trigger 138603b262f2SGregor Boirie * allowing to notify external devices a new sample is 138703b262f2SGregor Boirie * ready. 138803b262f2SGregor Boirie * @parent: Hardware sampling device @indio_dev is a child of. 138903b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 139003b262f2SGregor Boirie * @private: Internal private state related to @indio_dev. 139103b262f2SGregor Boirie * @irq: Optional interrupt line the hardware uses to notify new data 139203b262f2SGregor Boirie * samples are ready. Negative or zero values indicate no interrupts 139303b262f2SGregor Boirie * are available, meaning polling is required. 139403b262f2SGregor Boirie * 139503b262f2SGregor Boirie * Only relevant when DT declares a valid interrupt line. 139603b262f2SGregor Boirie * 139703b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 139803b262f2SGregor Boirie */ 139903b262f2SGregor Boirie static int zpa2326_init_managed_trigger(struct device *parent, 140003b262f2SGregor Boirie struct iio_dev *indio_dev, 140103b262f2SGregor Boirie struct zpa2326_private *private, 140203b262f2SGregor Boirie int irq) 140303b262f2SGregor Boirie { 140403b262f2SGregor Boirie struct iio_trigger *trigger; 140503b262f2SGregor Boirie int ret; 140603b262f2SGregor Boirie 140703b262f2SGregor Boirie if (irq <= 0) 140803b262f2SGregor Boirie return 0; 140903b262f2SGregor Boirie 141003b262f2SGregor Boirie trigger = devm_iio_trigger_alloc(parent, "%s-dev%d", 1411*15ea2878SJonathan Cameron indio_dev->name, 1412*15ea2878SJonathan Cameron iio_device_id(indio_dev)); 141303b262f2SGregor Boirie if (!trigger) 141403b262f2SGregor Boirie return -ENOMEM; 141503b262f2SGregor Boirie 141603b262f2SGregor Boirie /* Basic setup. */ 141703b262f2SGregor Boirie trigger->ops = &zpa2326_trigger_ops; 141803b262f2SGregor Boirie 141903b262f2SGregor Boirie private->trigger = trigger; 142003b262f2SGregor Boirie 142103b262f2SGregor Boirie /* Register to triggers space. */ 142203b262f2SGregor Boirie ret = devm_iio_trigger_register(parent, trigger); 142303b262f2SGregor Boirie if (ret) 142403b262f2SGregor Boirie dev_err(parent, "failed to register hardware trigger (%d)", 142503b262f2SGregor Boirie ret); 142603b262f2SGregor Boirie 142703b262f2SGregor Boirie return ret; 142803b262f2SGregor Boirie } 142903b262f2SGregor Boirie 143003b262f2SGregor Boirie static int zpa2326_get_frequency(const struct iio_dev *indio_dev) 143103b262f2SGregor Boirie { 143203b262f2SGregor Boirie return ((struct zpa2326_private *)iio_priv(indio_dev))->frequency->hz; 143303b262f2SGregor Boirie } 143403b262f2SGregor Boirie 143503b262f2SGregor Boirie static int zpa2326_set_frequency(struct iio_dev *indio_dev, int hz) 143603b262f2SGregor Boirie { 143703b262f2SGregor Boirie struct zpa2326_private *priv = iio_priv(indio_dev); 143803b262f2SGregor Boirie int freq; 143903b262f2SGregor Boirie int err; 144003b262f2SGregor Boirie 144103b262f2SGregor Boirie /* Check if requested frequency is supported. */ 144203b262f2SGregor Boirie for (freq = 0; freq < ARRAY_SIZE(zpa2326_sampling_frequencies); freq++) 144303b262f2SGregor Boirie if (zpa2326_sampling_frequencies[freq].hz == hz) 144403b262f2SGregor Boirie break; 144503b262f2SGregor Boirie if (freq == ARRAY_SIZE(zpa2326_sampling_frequencies)) 144603b262f2SGregor Boirie return -EINVAL; 144703b262f2SGregor Boirie 144803b262f2SGregor Boirie /* Don't allow changing frequency if buffered sampling is ongoing. */ 144903b262f2SGregor Boirie err = iio_device_claim_direct_mode(indio_dev); 145003b262f2SGregor Boirie if (err) 145103b262f2SGregor Boirie return err; 145203b262f2SGregor Boirie 145303b262f2SGregor Boirie priv->frequency = &zpa2326_sampling_frequencies[freq]; 145403b262f2SGregor Boirie 145503b262f2SGregor Boirie iio_device_release_direct_mode(indio_dev); 145603b262f2SGregor Boirie 145703b262f2SGregor Boirie return 0; 145803b262f2SGregor Boirie } 145903b262f2SGregor Boirie 146003b262f2SGregor Boirie /* Expose supported hardware sampling frequencies (Hz) through sysfs. */ 146103b262f2SGregor Boirie static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1 5 11 23"); 146203b262f2SGregor Boirie 146303b262f2SGregor Boirie static struct attribute *zpa2326_attributes[] = { 146403b262f2SGregor Boirie &iio_const_attr_sampling_frequency_available.dev_attr.attr, 146503b262f2SGregor Boirie NULL 146603b262f2SGregor Boirie }; 146703b262f2SGregor Boirie 146803b262f2SGregor Boirie static const struct attribute_group zpa2326_attribute_group = { 146903b262f2SGregor Boirie .attrs = zpa2326_attributes, 147003b262f2SGregor Boirie }; 147103b262f2SGregor Boirie 147203b262f2SGregor Boirie static int zpa2326_read_raw(struct iio_dev *indio_dev, 147303b262f2SGregor Boirie struct iio_chan_spec const *chan, 147403b262f2SGregor Boirie int *val, 147503b262f2SGregor Boirie int *val2, 147603b262f2SGregor Boirie long mask) 147703b262f2SGregor Boirie { 147803b262f2SGregor Boirie switch (mask) { 147903b262f2SGregor Boirie case IIO_CHAN_INFO_RAW: 148003b262f2SGregor Boirie return zpa2326_sample_oneshot(indio_dev, chan->type, val); 148103b262f2SGregor Boirie 148203b262f2SGregor Boirie case IIO_CHAN_INFO_SCALE: 148303b262f2SGregor Boirie switch (chan->type) { 148403b262f2SGregor Boirie case IIO_PRESSURE: 148503b262f2SGregor Boirie /* 148603b262f2SGregor Boirie * Pressure resolution is 1/64 Pascal. Scale to kPascal 148703b262f2SGregor Boirie * as required by IIO ABI. 148803b262f2SGregor Boirie */ 148903b262f2SGregor Boirie *val = 1; 149003b262f2SGregor Boirie *val2 = 64000; 149103b262f2SGregor Boirie return IIO_VAL_FRACTIONAL; 149203b262f2SGregor Boirie 149303b262f2SGregor Boirie case IIO_TEMP: 149403b262f2SGregor Boirie /* 149503b262f2SGregor Boirie * Temperature follows the equation: 149603b262f2SGregor Boirie * Temp[degC] = Tempcode * 0.00649 - 176.83 149703b262f2SGregor Boirie * where: 149803b262f2SGregor Boirie * Tempcode is composed the raw sampled 16 bits. 149903b262f2SGregor Boirie * 150003b262f2SGregor Boirie * Hence, to produce a temperature in milli-degrees 150103b262f2SGregor Boirie * Celsius according to IIO ABI, we need to apply the 150203b262f2SGregor Boirie * following equation to raw samples: 150303b262f2SGregor Boirie * Temp[milli degC] = (Tempcode + Offset) * Scale 150403b262f2SGregor Boirie * where: 150503b262f2SGregor Boirie * Offset = -176.83 / 0.00649 150603b262f2SGregor Boirie * Scale = 0.00649 * 1000 150703b262f2SGregor Boirie */ 150803b262f2SGregor Boirie *val = 6; 150903b262f2SGregor Boirie *val2 = 490000; 151003b262f2SGregor Boirie return IIO_VAL_INT_PLUS_MICRO; 151103b262f2SGregor Boirie 151203b262f2SGregor Boirie default: 151303b262f2SGregor Boirie return -EINVAL; 151403b262f2SGregor Boirie } 151503b262f2SGregor Boirie 151603b262f2SGregor Boirie case IIO_CHAN_INFO_OFFSET: 151703b262f2SGregor Boirie switch (chan->type) { 151803b262f2SGregor Boirie case IIO_TEMP: 151903b262f2SGregor Boirie *val = -17683000; 152003b262f2SGregor Boirie *val2 = 649; 152103b262f2SGregor Boirie return IIO_VAL_FRACTIONAL; 152203b262f2SGregor Boirie 152303b262f2SGregor Boirie default: 152403b262f2SGregor Boirie return -EINVAL; 152503b262f2SGregor Boirie } 152603b262f2SGregor Boirie 152703b262f2SGregor Boirie case IIO_CHAN_INFO_SAMP_FREQ: 152803b262f2SGregor Boirie *val = zpa2326_get_frequency(indio_dev); 152903b262f2SGregor Boirie return IIO_VAL_INT; 153003b262f2SGregor Boirie 153103b262f2SGregor Boirie default: 153203b262f2SGregor Boirie return -EINVAL; 153303b262f2SGregor Boirie } 153403b262f2SGregor Boirie } 153503b262f2SGregor Boirie 153603b262f2SGregor Boirie static int zpa2326_write_raw(struct iio_dev *indio_dev, 153703b262f2SGregor Boirie const struct iio_chan_spec *chan, 153803b262f2SGregor Boirie int val, 153903b262f2SGregor Boirie int val2, 154003b262f2SGregor Boirie long mask) 154103b262f2SGregor Boirie { 154203b262f2SGregor Boirie if ((mask != IIO_CHAN_INFO_SAMP_FREQ) || val2) 154303b262f2SGregor Boirie return -EINVAL; 154403b262f2SGregor Boirie 154503b262f2SGregor Boirie return zpa2326_set_frequency(indio_dev, val); 154603b262f2SGregor Boirie } 154703b262f2SGregor Boirie 154803b262f2SGregor Boirie static const struct iio_chan_spec zpa2326_channels[] = { 154903b262f2SGregor Boirie [0] = { 155003b262f2SGregor Boirie .type = IIO_PRESSURE, 155103b262f2SGregor Boirie .scan_index = 0, 155203b262f2SGregor Boirie .scan_type = { 155303b262f2SGregor Boirie .sign = 'u', 155403b262f2SGregor Boirie .realbits = 24, 155503b262f2SGregor Boirie .storagebits = 32, 155603b262f2SGregor Boirie .endianness = IIO_LE, 155703b262f2SGregor Boirie }, 155803b262f2SGregor Boirie .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 155903b262f2SGregor Boirie BIT(IIO_CHAN_INFO_SCALE), 156003b262f2SGregor Boirie .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), 156103b262f2SGregor Boirie }, 156203b262f2SGregor Boirie [1] = { 156303b262f2SGregor Boirie .type = IIO_TEMP, 156403b262f2SGregor Boirie .scan_index = 1, 156503b262f2SGregor Boirie .scan_type = { 156603b262f2SGregor Boirie .sign = 's', 156703b262f2SGregor Boirie .realbits = 16, 156803b262f2SGregor Boirie .storagebits = 16, 156903b262f2SGregor Boirie .endianness = IIO_LE, 157003b262f2SGregor Boirie }, 157103b262f2SGregor Boirie .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 157203b262f2SGregor Boirie BIT(IIO_CHAN_INFO_SCALE) | 157303b262f2SGregor Boirie BIT(IIO_CHAN_INFO_OFFSET), 157403b262f2SGregor Boirie .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), 157503b262f2SGregor Boirie }, 157603b262f2SGregor Boirie [2] = IIO_CHAN_SOFT_TIMESTAMP(2), 157703b262f2SGregor Boirie }; 157803b262f2SGregor Boirie 157903b262f2SGregor Boirie static const struct iio_info zpa2326_info = { 158003b262f2SGregor Boirie .attrs = &zpa2326_attribute_group, 158103b262f2SGregor Boirie .read_raw = zpa2326_read_raw, 158203b262f2SGregor Boirie .write_raw = zpa2326_write_raw, 158303b262f2SGregor Boirie }; 158403b262f2SGregor Boirie 158503b262f2SGregor Boirie static struct iio_dev *zpa2326_create_managed_iiodev(struct device *device, 158603b262f2SGregor Boirie const char *name, 158703b262f2SGregor Boirie struct regmap *regmap) 158803b262f2SGregor Boirie { 158903b262f2SGregor Boirie struct iio_dev *indio_dev; 159003b262f2SGregor Boirie 159103b262f2SGregor Boirie /* Allocate space to hold IIO device internal state. */ 159203b262f2SGregor Boirie indio_dev = devm_iio_device_alloc(device, 159303b262f2SGregor Boirie sizeof(struct zpa2326_private)); 159403b262f2SGregor Boirie if (!indio_dev) 159503b262f2SGregor Boirie return NULL; 159603b262f2SGregor Boirie 159703b262f2SGregor Boirie /* Setup for userspace synchronous on demand sampling. */ 159803b262f2SGregor Boirie indio_dev->modes = INDIO_DIRECT_MODE; 159903b262f2SGregor Boirie indio_dev->channels = zpa2326_channels; 160003b262f2SGregor Boirie indio_dev->num_channels = ARRAY_SIZE(zpa2326_channels); 160103b262f2SGregor Boirie indio_dev->name = name; 160203b262f2SGregor Boirie indio_dev->info = &zpa2326_info; 160303b262f2SGregor Boirie 160403b262f2SGregor Boirie return indio_dev; 160503b262f2SGregor Boirie } 160603b262f2SGregor Boirie 160703b262f2SGregor Boirie int zpa2326_probe(struct device *parent, 160803b262f2SGregor Boirie const char *name, 160903b262f2SGregor Boirie int irq, 161003b262f2SGregor Boirie unsigned int hwid, 161103b262f2SGregor Boirie struct regmap *regmap) 161203b262f2SGregor Boirie { 161303b262f2SGregor Boirie struct iio_dev *indio_dev; 161403b262f2SGregor Boirie struct zpa2326_private *priv; 161503b262f2SGregor Boirie int err; 161603b262f2SGregor Boirie unsigned int id; 161703b262f2SGregor Boirie 161803b262f2SGregor Boirie indio_dev = zpa2326_create_managed_iiodev(parent, name, regmap); 161903b262f2SGregor Boirie if (!indio_dev) 162003b262f2SGregor Boirie return -ENOMEM; 162103b262f2SGregor Boirie 162203b262f2SGregor Boirie priv = iio_priv(indio_dev); 162303b262f2SGregor Boirie 162403b262f2SGregor Boirie priv->vref = devm_regulator_get(parent, "vref"); 162503b262f2SGregor Boirie if (IS_ERR(priv->vref)) 162603b262f2SGregor Boirie return PTR_ERR(priv->vref); 162703b262f2SGregor Boirie 162803b262f2SGregor Boirie priv->vdd = devm_regulator_get(parent, "vdd"); 162903b262f2SGregor Boirie if (IS_ERR(priv->vdd)) 163003b262f2SGregor Boirie return PTR_ERR(priv->vdd); 163103b262f2SGregor Boirie 163203b262f2SGregor Boirie /* Set default hardware sampling frequency to highest rate supported. */ 163303b262f2SGregor Boirie priv->frequency = zpa2326_highest_frequency(); 163403b262f2SGregor Boirie 163503b262f2SGregor Boirie /* 163603b262f2SGregor Boirie * Plug device's underlying bus abstraction : this MUST be set before 163703b262f2SGregor Boirie * registering interrupt handlers since an interrupt might happen if 163803b262f2SGregor Boirie * power up sequence is not properly applied. 163903b262f2SGregor Boirie */ 164003b262f2SGregor Boirie priv->regmap = regmap; 164103b262f2SGregor Boirie 164203b262f2SGregor Boirie err = devm_iio_triggered_buffer_setup(parent, indio_dev, NULL, 164303b262f2SGregor Boirie zpa2326_trigger_handler, 164403b262f2SGregor Boirie &zpa2326_buffer_setup_ops); 164503b262f2SGregor Boirie if (err) 164603b262f2SGregor Boirie return err; 164703b262f2SGregor Boirie 164803b262f2SGregor Boirie err = zpa2326_init_managed_trigger(parent, indio_dev, priv, irq); 164903b262f2SGregor Boirie if (err) 165003b262f2SGregor Boirie return err; 165103b262f2SGregor Boirie 165203b262f2SGregor Boirie err = zpa2326_init_managed_irq(parent, indio_dev, priv, irq); 165303b262f2SGregor Boirie if (err) 165403b262f2SGregor Boirie return err; 165503b262f2SGregor Boirie 165603b262f2SGregor Boirie /* Power up to check device ID and perform initial hardware setup. */ 165703b262f2SGregor Boirie err = zpa2326_power_on(indio_dev, priv); 165803b262f2SGregor Boirie if (err) 165903b262f2SGregor Boirie return err; 166003b262f2SGregor Boirie 166103b262f2SGregor Boirie /* Read id register to check we are talking to the right slave. */ 166203b262f2SGregor Boirie err = regmap_read(regmap, ZPA2326_DEVICE_ID_REG, &id); 166303b262f2SGregor Boirie if (err) 166403b262f2SGregor Boirie goto sleep; 166503b262f2SGregor Boirie 166603b262f2SGregor Boirie if (id != hwid) { 166703b262f2SGregor Boirie dev_err(parent, "found device with unexpected id %02x", id); 166803b262f2SGregor Boirie err = -ENODEV; 166903b262f2SGregor Boirie goto sleep; 167003b262f2SGregor Boirie } 167103b262f2SGregor Boirie 167203b262f2SGregor Boirie err = zpa2326_config_oneshot(indio_dev, irq); 167303b262f2SGregor Boirie if (err) 167403b262f2SGregor Boirie goto sleep; 167503b262f2SGregor Boirie 167603b262f2SGregor Boirie /* Setup done : go sleeping. Device will be awaken upon user request. */ 167703b262f2SGregor Boirie err = zpa2326_sleep(indio_dev); 167803b262f2SGregor Boirie if (err) 167903b262f2SGregor Boirie goto poweroff; 168003b262f2SGregor Boirie 168103b262f2SGregor Boirie dev_set_drvdata(parent, indio_dev); 168203b262f2SGregor Boirie 168303b262f2SGregor Boirie zpa2326_init_runtime(parent); 168403b262f2SGregor Boirie 168503b262f2SGregor Boirie err = iio_device_register(indio_dev); 168603b262f2SGregor Boirie if (err) { 168703b262f2SGregor Boirie zpa2326_fini_runtime(parent); 168803b262f2SGregor Boirie goto poweroff; 168903b262f2SGregor Boirie } 169003b262f2SGregor Boirie 169103b262f2SGregor Boirie return 0; 169203b262f2SGregor Boirie 169303b262f2SGregor Boirie sleep: 169403b262f2SGregor Boirie /* Put to sleep just in case power regulators are "dummy" ones. */ 169503b262f2SGregor Boirie zpa2326_sleep(indio_dev); 169603b262f2SGregor Boirie poweroff: 169703b262f2SGregor Boirie zpa2326_power_off(indio_dev, priv); 169803b262f2SGregor Boirie 169903b262f2SGregor Boirie return err; 170003b262f2SGregor Boirie } 170103b262f2SGregor Boirie EXPORT_SYMBOL_GPL(zpa2326_probe); 170203b262f2SGregor Boirie 170303b262f2SGregor Boirie void zpa2326_remove(const struct device *parent) 170403b262f2SGregor Boirie { 170503b262f2SGregor Boirie struct iio_dev *indio_dev = dev_get_drvdata(parent); 170603b262f2SGregor Boirie 170703b262f2SGregor Boirie iio_device_unregister(indio_dev); 170803b262f2SGregor Boirie zpa2326_fini_runtime(indio_dev->dev.parent); 170903b262f2SGregor Boirie zpa2326_sleep(indio_dev); 171003b262f2SGregor Boirie zpa2326_power_off(indio_dev, iio_priv(indio_dev)); 171103b262f2SGregor Boirie } 171203b262f2SGregor Boirie EXPORT_SYMBOL_GPL(zpa2326_remove); 171303b262f2SGregor Boirie 171403b262f2SGregor Boirie MODULE_AUTHOR("Gregor Boirie <gregor.boirie@parrot.com>"); 171503b262f2SGregor Boirie MODULE_DESCRIPTION("Core driver for Murata ZPA2326 pressure sensor"); 171603b262f2SGregor Boirie MODULE_LICENSE("GPL v2"); 1717