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