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 144eed3089fSJoe Perches #define zpa2326_err(idev, fmt, ...) \ 145eed3089fSJoe Perches dev_err(idev->dev.parent, fmt "\n", ##__VA_ARGS__) 14603b262f2SGregor Boirie 147eed3089fSJoe Perches #define zpa2326_warn(idev, fmt, ...) \ 148eed3089fSJoe Perches dev_warn(idev->dev.parent, fmt "\n", ##__VA_ARGS__) 14903b262f2SGregor Boirie 150eed3089fSJoe Perches #define zpa2326_dbg(idev, fmt, ...) \ 151eed3089fSJoe 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 unsigned int val; 869e7215fe4SNicholas Mc Guire long timeout; 87003b262f2SGregor Boirie 87103b262f2SGregor Boirie zpa2326_dbg(indio_dev, "waiting for one shot completion interrupt"); 87203b262f2SGregor Boirie 873e7215fe4SNicholas Mc Guire timeout = wait_for_completion_interruptible_timeout( 87403b262f2SGregor Boirie &private->data_ready, ZPA2326_CONVERSION_JIFFIES); 875e7215fe4SNicholas Mc Guire if (timeout > 0) 87603b262f2SGregor Boirie /* 87703b262f2SGregor Boirie * Interrupt handler completed before timeout: return operation 87803b262f2SGregor Boirie * status. 87903b262f2SGregor Boirie */ 88003b262f2SGregor Boirie return private->result; 88103b262f2SGregor Boirie 88203b262f2SGregor Boirie /* Clear all interrupts just to be sure. */ 88303b262f2SGregor Boirie regmap_read(private->regmap, ZPA2326_INT_SOURCE_REG, &val); 88403b262f2SGregor Boirie 885e7215fe4SNicholas Mc Guire if (!timeout) { 88603b262f2SGregor Boirie /* Timed out. */ 887e7215fe4SNicholas Mc Guire zpa2326_warn(indio_dev, "no one shot interrupt occurred (%ld)", 888e7215fe4SNicholas Mc Guire timeout); 889*f61dfff2SGeert Uytterhoeven return -ETIME; 890e7215fe4SNicholas Mc Guire } 89103b262f2SGregor Boirie 892*f61dfff2SGeert Uytterhoeven zpa2326_warn(indio_dev, "wait for one shot interrupt cancelled"); 893*f61dfff2SGeert Uytterhoeven return -ERESTARTSYS; 89403b262f2SGregor Boirie } 89503b262f2SGregor Boirie 89603b262f2SGregor Boirie static int zpa2326_init_managed_irq(struct device *parent, 89703b262f2SGregor Boirie struct iio_dev *indio_dev, 89803b262f2SGregor Boirie struct zpa2326_private *private, 89903b262f2SGregor Boirie int irq) 90003b262f2SGregor Boirie { 90103b262f2SGregor Boirie int err; 90203b262f2SGregor Boirie 90303b262f2SGregor Boirie private->irq = irq; 90403b262f2SGregor Boirie 90503b262f2SGregor Boirie if (irq <= 0) { 90603b262f2SGregor Boirie /* 90703b262f2SGregor Boirie * Platform declared no interrupt line: device will be polled 90803b262f2SGregor Boirie * for data availability. 90903b262f2SGregor Boirie */ 91003b262f2SGregor Boirie dev_info(parent, "no interrupt found, running in polling mode"); 91103b262f2SGregor Boirie return 0; 91203b262f2SGregor Boirie } 91303b262f2SGregor Boirie 91403b262f2SGregor Boirie init_completion(&private->data_ready); 91503b262f2SGregor Boirie 91603b262f2SGregor Boirie /* Request handler to be scheduled into threaded interrupt context. */ 91703b262f2SGregor Boirie err = devm_request_threaded_irq(parent, irq, zpa2326_handle_irq, 91803b262f2SGregor Boirie zpa2326_handle_threaded_irq, 91903b262f2SGregor Boirie IRQF_TRIGGER_RISING | IRQF_ONESHOT, 92003b262f2SGregor Boirie dev_name(parent), indio_dev); 92103b262f2SGregor Boirie if (err) { 92203b262f2SGregor Boirie dev_err(parent, "failed to request interrupt %d (%d)", irq, 92303b262f2SGregor Boirie err); 92403b262f2SGregor Boirie return err; 92503b262f2SGregor Boirie } 92603b262f2SGregor Boirie 92703b262f2SGregor Boirie dev_info(parent, "using interrupt %d", irq); 92803b262f2SGregor Boirie 92903b262f2SGregor Boirie return 0; 93003b262f2SGregor Boirie } 93103b262f2SGregor Boirie 93203b262f2SGregor Boirie /** 93303b262f2SGregor Boirie * zpa2326_poll_oneshot_completion() - Actively poll for one shot data ready. 93403b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 93503b262f2SGregor Boirie * 93603b262f2SGregor Boirie * Loop over registers content to detect end of sampling cycle. Used when DT 93703b262f2SGregor Boirie * declared no valid interrupt lines. 93803b262f2SGregor Boirie * 93903b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 94003b262f2SGregor Boirie */ 94103b262f2SGregor Boirie static int zpa2326_poll_oneshot_completion(const struct iio_dev *indio_dev) 94203b262f2SGregor Boirie { 94303b262f2SGregor Boirie unsigned long tmout = jiffies + ZPA2326_CONVERSION_JIFFIES; 94403b262f2SGregor Boirie struct regmap *regs = ((struct zpa2326_private *) 94503b262f2SGregor Boirie iio_priv(indio_dev))->regmap; 94603b262f2SGregor Boirie unsigned int val; 94703b262f2SGregor Boirie int err; 94803b262f2SGregor Boirie 94903b262f2SGregor Boirie zpa2326_dbg(indio_dev, "polling for one shot completion"); 95003b262f2SGregor Boirie 95103b262f2SGregor Boirie /* 95203b262f2SGregor Boirie * At least, 100 ms is needed for the device to complete its one-shot 95303b262f2SGregor Boirie * cycle. 95403b262f2SGregor Boirie */ 95503b262f2SGregor Boirie if (msleep_interruptible(100)) 95603b262f2SGregor Boirie return -ERESTARTSYS; 95703b262f2SGregor Boirie 95803b262f2SGregor Boirie /* Poll for conversion completion in hardware. */ 95903b262f2SGregor Boirie while (true) { 96003b262f2SGregor Boirie err = regmap_read(regs, ZPA2326_CTRL_REG0_REG, &val); 96103b262f2SGregor Boirie if (err < 0) 96203b262f2SGregor Boirie goto err; 96303b262f2SGregor Boirie 96403b262f2SGregor Boirie if (!(val & ZPA2326_CTRL_REG0_ONE_SHOT)) 96503b262f2SGregor Boirie /* One-shot bit self clears at conversion end. */ 96603b262f2SGregor Boirie break; 96703b262f2SGregor Boirie 96803b262f2SGregor Boirie if (time_after(jiffies, tmout)) { 96903b262f2SGregor Boirie /* Prevent from waiting forever : let's time out. */ 97003b262f2SGregor Boirie err = -ETIME; 97103b262f2SGregor Boirie goto err; 97203b262f2SGregor Boirie } 97303b262f2SGregor Boirie 97403b262f2SGregor Boirie usleep_range(10000, 20000); 97503b262f2SGregor Boirie } 97603b262f2SGregor Boirie 97703b262f2SGregor Boirie /* 97803b262f2SGregor Boirie * In oneshot mode, pressure sample availability guarantees that 97903b262f2SGregor Boirie * temperature conversion has also completed : just check pressure 98003b262f2SGregor Boirie * status bit to keep things simple. 98103b262f2SGregor Boirie */ 98203b262f2SGregor Boirie err = regmap_read(regs, ZPA2326_STATUS_REG, &val); 98303b262f2SGregor Boirie if (err < 0) 98403b262f2SGregor Boirie goto err; 98503b262f2SGregor Boirie 98603b262f2SGregor Boirie if (!(val & ZPA2326_STATUS_P_DA)) { 98703b262f2SGregor Boirie /* No sample available. */ 98803b262f2SGregor Boirie err = -ENODATA; 98903b262f2SGregor Boirie goto err; 99003b262f2SGregor Boirie } 99103b262f2SGregor Boirie 99203b262f2SGregor Boirie return 0; 99303b262f2SGregor Boirie 99403b262f2SGregor Boirie err: 99503b262f2SGregor Boirie zpa2326_warn(indio_dev, "failed to poll one shot completion (%d)", err); 99603b262f2SGregor Boirie 99703b262f2SGregor Boirie return err; 99803b262f2SGregor Boirie } 99903b262f2SGregor Boirie 100003b262f2SGregor Boirie /** 100103b262f2SGregor Boirie * zpa2326_fetch_raw_sample() - Retrieve a raw sample and convert it to CPU 100203b262f2SGregor Boirie * endianness. 100303b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 100403b262f2SGregor Boirie * @type: Type of measurement / channel to fetch from. 100503b262f2SGregor Boirie * @value: Sample output. 100603b262f2SGregor Boirie * 100703b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 100803b262f2SGregor Boirie */ 100903b262f2SGregor Boirie static int zpa2326_fetch_raw_sample(const struct iio_dev *indio_dev, 101003b262f2SGregor Boirie enum iio_chan_type type, 101103b262f2SGregor Boirie int *value) 101203b262f2SGregor Boirie { 101303b262f2SGregor Boirie struct regmap *regs = ((struct zpa2326_private *) 101403b262f2SGregor Boirie iio_priv(indio_dev))->regmap; 101503b262f2SGregor Boirie int err; 101603b262f2SGregor Boirie 101703b262f2SGregor Boirie switch (type) { 101803b262f2SGregor Boirie case IIO_PRESSURE: 101903b262f2SGregor Boirie zpa2326_dbg(indio_dev, "fetching raw pressure sample"); 102003b262f2SGregor Boirie 102103b262f2SGregor Boirie err = regmap_bulk_read(regs, ZPA2326_PRESS_OUT_XL_REG, value, 102203b262f2SGregor Boirie 3); 102303b262f2SGregor Boirie if (err) { 102403b262f2SGregor Boirie zpa2326_warn(indio_dev, "failed to fetch pressure (%d)", 102503b262f2SGregor Boirie err); 102603b262f2SGregor Boirie return err; 102703b262f2SGregor Boirie } 102803b262f2SGregor Boirie 102903b262f2SGregor Boirie /* Pressure is a 24 bits wide little-endian unsigned int. */ 103003b262f2SGregor Boirie *value = (((u8 *)value)[2] << 16) | (((u8 *)value)[1] << 8) | 103103b262f2SGregor Boirie ((u8 *)value)[0]; 103203b262f2SGregor Boirie 103303b262f2SGregor Boirie return IIO_VAL_INT; 103403b262f2SGregor Boirie 103503b262f2SGregor Boirie case IIO_TEMP: 103603b262f2SGregor Boirie zpa2326_dbg(indio_dev, "fetching raw temperature sample"); 103703b262f2SGregor Boirie 103803b262f2SGregor Boirie err = regmap_bulk_read(regs, ZPA2326_TEMP_OUT_L_REG, value, 2); 103903b262f2SGregor Boirie if (err) { 104003b262f2SGregor Boirie zpa2326_warn(indio_dev, 104103b262f2SGregor Boirie "failed to fetch temperature (%d)", err); 104203b262f2SGregor Boirie return err; 104303b262f2SGregor Boirie } 104403b262f2SGregor Boirie 104503b262f2SGregor Boirie /* Temperature is a 16 bits wide little-endian signed int. */ 104603b262f2SGregor Boirie *value = (int)le16_to_cpup((__le16 *)value); 104703b262f2SGregor Boirie 104803b262f2SGregor Boirie return IIO_VAL_INT; 104903b262f2SGregor Boirie 105003b262f2SGregor Boirie default: 105103b262f2SGregor Boirie return -EINVAL; 105203b262f2SGregor Boirie } 105303b262f2SGregor Boirie } 105403b262f2SGregor Boirie 105503b262f2SGregor Boirie /** 105603b262f2SGregor Boirie * zpa2326_sample_oneshot() - Perform a complete one shot sampling cycle. 105703b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 105803b262f2SGregor Boirie * @type: Type of measurement / channel to fetch from. 105903b262f2SGregor Boirie * @value: Sample output. 106003b262f2SGregor Boirie * 106103b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 106203b262f2SGregor Boirie */ 106303b262f2SGregor Boirie static int zpa2326_sample_oneshot(struct iio_dev *indio_dev, 106403b262f2SGregor Boirie enum iio_chan_type type, 106503b262f2SGregor Boirie int *value) 106603b262f2SGregor Boirie { 106703b262f2SGregor Boirie int ret; 106803b262f2SGregor Boirie struct zpa2326_private *priv; 106903b262f2SGregor Boirie 107003b262f2SGregor Boirie ret = iio_device_claim_direct_mode(indio_dev); 107103b262f2SGregor Boirie if (ret) 107203b262f2SGregor Boirie return ret; 107303b262f2SGregor Boirie 107403b262f2SGregor Boirie ret = zpa2326_resume(indio_dev); 107503b262f2SGregor Boirie if (ret < 0) 107603b262f2SGregor Boirie goto release; 107703b262f2SGregor Boirie 107803b262f2SGregor Boirie priv = iio_priv(indio_dev); 107903b262f2SGregor Boirie 108003b262f2SGregor Boirie if (ret > 0) { 108103b262f2SGregor Boirie /* 108203b262f2SGregor Boirie * We were already power supplied. Just clear hardware FIFO to 108303b262f2SGregor Boirie * get rid of samples acquired during previous rounds (if any). 108403b262f2SGregor Boirie * Sampling operation always generates both temperature and 108503b262f2SGregor Boirie * pressure samples. The latter are always enqueued into 108603b262f2SGregor Boirie * hardware FIFO. This may lead to situations were pressure 108703b262f2SGregor Boirie * samples still sit into FIFO when previous cycle(s) fetched 108803b262f2SGregor Boirie * temperature data only. 108903b262f2SGregor Boirie * Hence, we need to clear hardware FIFO content to prevent from 109003b262f2SGregor Boirie * getting outdated values at the end of current cycle. 109103b262f2SGregor Boirie */ 109203b262f2SGregor Boirie if (type == IIO_PRESSURE) { 109303b262f2SGregor Boirie ret = zpa2326_clear_fifo(indio_dev, 0); 109403b262f2SGregor Boirie if (ret) 109503b262f2SGregor Boirie goto suspend; 109603b262f2SGregor Boirie } 109703b262f2SGregor Boirie } else { 109803b262f2SGregor Boirie /* 109903b262f2SGregor Boirie * We have just been power supplied, i.e. device is in default 110003b262f2SGregor Boirie * "out of reset" state, meaning we need to reconfigure it 110103b262f2SGregor Boirie * entirely. 110203b262f2SGregor Boirie */ 110303b262f2SGregor Boirie ret = zpa2326_config_oneshot(indio_dev, priv->irq); 110403b262f2SGregor Boirie if (ret) 110503b262f2SGregor Boirie goto suspend; 110603b262f2SGregor Boirie } 110703b262f2SGregor Boirie 110803b262f2SGregor Boirie /* Start a sampling cycle in oneshot mode. */ 110903b262f2SGregor Boirie ret = zpa2326_start_oneshot(indio_dev); 111003b262f2SGregor Boirie if (ret) 111103b262f2SGregor Boirie goto suspend; 111203b262f2SGregor Boirie 111303b262f2SGregor Boirie /* Wait for sampling cycle to complete. */ 111403b262f2SGregor Boirie if (priv->irq > 0) 111503b262f2SGregor Boirie ret = zpa2326_wait_oneshot_completion(indio_dev, priv); 111603b262f2SGregor Boirie else 111703b262f2SGregor Boirie ret = zpa2326_poll_oneshot_completion(indio_dev); 111803b262f2SGregor Boirie 111903b262f2SGregor Boirie if (ret) 112003b262f2SGregor Boirie goto suspend; 112103b262f2SGregor Boirie 112203b262f2SGregor Boirie /* Retrieve raw sample value and convert it to CPU endianness. */ 112303b262f2SGregor Boirie ret = zpa2326_fetch_raw_sample(indio_dev, type, value); 112403b262f2SGregor Boirie 112503b262f2SGregor Boirie suspend: 112603b262f2SGregor Boirie zpa2326_suspend(indio_dev); 112703b262f2SGregor Boirie release: 112803b262f2SGregor Boirie iio_device_release_direct_mode(indio_dev); 112903b262f2SGregor Boirie 113003b262f2SGregor Boirie return ret; 113103b262f2SGregor Boirie } 113203b262f2SGregor Boirie 113303b262f2SGregor Boirie /** 113403b262f2SGregor Boirie * zpa2326_trigger_handler() - Perform an IIO buffered sampling round in one 113503b262f2SGregor Boirie * shot mode. 113603b262f2SGregor Boirie * @irq: The software interrupt assigned to @data 113703b262f2SGregor Boirie * @data: The IIO poll function dispatched by external trigger our device is 113803b262f2SGregor Boirie * attached to. 113903b262f2SGregor Boirie * 114003b262f2SGregor Boirie * Bottom-half handler called by the IIO trigger to which our device is 114103b262f2SGregor Boirie * currently attached. Allows us to synchronize this device buffered sampling 114203b262f2SGregor Boirie * either with external events (such as timer expiration, external device sample 114303b262f2SGregor Boirie * ready, etc...) or with its own interrupt (internal hardware trigger). 114403b262f2SGregor Boirie * 114503b262f2SGregor Boirie * When using an external trigger, basically run the same sequence of operations 114603b262f2SGregor Boirie * as for zpa2326_sample_oneshot() with the following hereafter. Hardware FIFO 114703b262f2SGregor Boirie * is not cleared since already done at buffering enable time and samples 114803b262f2SGregor Boirie * dequeueing always retrieves the most recent value. 114903b262f2SGregor Boirie * 115003b262f2SGregor Boirie * Otherwise, when internal hardware trigger has dispatched us, just fetch data 115103b262f2SGregor Boirie * from hardware FIFO. 115203b262f2SGregor Boirie * 115303b262f2SGregor Boirie * Fetched data will pushed unprocessed to IIO buffer since samples conversion 115403b262f2SGregor Boirie * is delegated to userspace in buffered mode (endianness, etc...). 115503b262f2SGregor Boirie * 115603b262f2SGregor Boirie * Return: 115703b262f2SGregor Boirie * %IRQ_NONE - no consistent interrupt happened ; 115803b262f2SGregor Boirie * %IRQ_HANDLED - there was new samples available. 115903b262f2SGregor Boirie */ 116003b262f2SGregor Boirie static irqreturn_t zpa2326_trigger_handler(int irq, void *data) 116103b262f2SGregor Boirie { 116203b262f2SGregor Boirie struct iio_dev *indio_dev = ((struct iio_poll_func *) 116303b262f2SGregor Boirie data)->indio_dev; 116403b262f2SGregor Boirie struct zpa2326_private *priv = iio_priv(indio_dev); 116503b262f2SGregor Boirie bool cont; 116603b262f2SGregor Boirie 116703b262f2SGregor Boirie /* 116803b262f2SGregor Boirie * We have been dispatched, meaning we are in triggered buffer mode. 116903b262f2SGregor Boirie * Using our own internal trigger implies we are currently in continuous 117003b262f2SGregor Boirie * hardware sampling mode. 117103b262f2SGregor Boirie */ 117203b262f2SGregor Boirie cont = iio_trigger_using_own(indio_dev); 117303b262f2SGregor Boirie 117403b262f2SGregor Boirie if (!cont) { 117503b262f2SGregor Boirie /* On demand sampling : start a one shot cycle. */ 117603b262f2SGregor Boirie if (zpa2326_start_oneshot(indio_dev)) 117703b262f2SGregor Boirie goto out; 117803b262f2SGregor Boirie 117903b262f2SGregor Boirie /* Wait for sampling cycle to complete. */ 118003b262f2SGregor Boirie if (priv->irq <= 0) { 118103b262f2SGregor Boirie /* No interrupt available: poll for completion. */ 118203b262f2SGregor Boirie if (zpa2326_poll_oneshot_completion(indio_dev)) 118303b262f2SGregor Boirie goto out; 118403b262f2SGregor Boirie 118503b262f2SGregor Boirie /* Only timestamp sample once it is ready. */ 118603b262f2SGregor Boirie priv->timestamp = iio_get_time_ns(indio_dev); 118703b262f2SGregor Boirie } else { 118803b262f2SGregor Boirie /* Interrupt handlers will timestamp for us. */ 118903b262f2SGregor Boirie if (zpa2326_wait_oneshot_completion(indio_dev, priv)) 119003b262f2SGregor Boirie goto out; 119103b262f2SGregor Boirie } 119203b262f2SGregor Boirie } 119303b262f2SGregor Boirie 119403b262f2SGregor Boirie /* Enqueue to IIO buffer / userspace. */ 119503b262f2SGregor Boirie zpa2326_fill_sample_buffer(indio_dev, priv); 119603b262f2SGregor Boirie 119703b262f2SGregor Boirie out: 119803b262f2SGregor Boirie if (!cont) 119903b262f2SGregor Boirie /* Don't switch to low power if sampling continuously. */ 120003b262f2SGregor Boirie zpa2326_sleep(indio_dev); 120103b262f2SGregor Boirie 120203b262f2SGregor Boirie /* Inform attached trigger we are done. */ 120303b262f2SGregor Boirie iio_trigger_notify_done(indio_dev->trig); 120403b262f2SGregor Boirie 120503b262f2SGregor Boirie return IRQ_HANDLED; 120603b262f2SGregor Boirie } 120703b262f2SGregor Boirie 120803b262f2SGregor Boirie /** 120903b262f2SGregor Boirie * zpa2326_preenable_buffer() - Prepare device for configuring triggered 121003b262f2SGregor Boirie * sampling 121103b262f2SGregor Boirie * modes. 121203b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 121303b262f2SGregor Boirie * 121403b262f2SGregor Boirie * Basically power up device. 121503b262f2SGregor Boirie * Called with IIO device's lock held. 121603b262f2SGregor Boirie * 121703b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 121803b262f2SGregor Boirie */ 121903b262f2SGregor Boirie static int zpa2326_preenable_buffer(struct iio_dev *indio_dev) 122003b262f2SGregor Boirie { 122103b262f2SGregor Boirie int ret = zpa2326_resume(indio_dev); 122203b262f2SGregor Boirie 122303b262f2SGregor Boirie if (ret < 0) 122403b262f2SGregor Boirie return ret; 122503b262f2SGregor Boirie 122603b262f2SGregor Boirie /* Tell zpa2326_postenable_buffer() if we have just been powered on. */ 122703b262f2SGregor Boirie ((struct zpa2326_private *) 122803b262f2SGregor Boirie iio_priv(indio_dev))->waken = iio_priv(indio_dev); 122903b262f2SGregor Boirie 123003b262f2SGregor Boirie return 0; 123103b262f2SGregor Boirie } 123203b262f2SGregor Boirie 123303b262f2SGregor Boirie /** 123403b262f2SGregor Boirie * zpa2326_postenable_buffer() - Configure device for triggered sampling. 123503b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 123603b262f2SGregor Boirie * 123703b262f2SGregor Boirie * Basically setup one-shot mode if plugging external trigger. 123803b262f2SGregor Boirie * Otherwise, let internal trigger configure continuous sampling : 123903b262f2SGregor Boirie * see zpa2326_set_trigger_state(). 124003b262f2SGregor Boirie * 124103b262f2SGregor Boirie * If an error is returned, IIO layer will call our postdisable hook for us, 124203b262f2SGregor Boirie * i.e. no need to explicitly power device off here. 124303b262f2SGregor Boirie * Called with IIO device's lock held. 124403b262f2SGregor Boirie * 124503b262f2SGregor Boirie * Called with IIO device's lock held. 124603b262f2SGregor Boirie * 124703b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 124803b262f2SGregor Boirie */ 124903b262f2SGregor Boirie static int zpa2326_postenable_buffer(struct iio_dev *indio_dev) 125003b262f2SGregor Boirie { 125103b262f2SGregor Boirie const struct zpa2326_private *priv = iio_priv(indio_dev); 125203b262f2SGregor Boirie int err; 125303b262f2SGregor Boirie 125403b262f2SGregor Boirie if (!priv->waken) { 125503b262f2SGregor Boirie /* 125603b262f2SGregor Boirie * We were already power supplied. Just clear hardware FIFO to 125703b262f2SGregor Boirie * get rid of samples acquired during previous rounds (if any). 125803b262f2SGregor Boirie */ 125903b262f2SGregor Boirie err = zpa2326_clear_fifo(indio_dev, 0); 126003b262f2SGregor Boirie if (err) 126103b262f2SGregor Boirie goto err; 126203b262f2SGregor Boirie } 126303b262f2SGregor Boirie 126403b262f2SGregor Boirie if (!iio_trigger_using_own(indio_dev) && priv->waken) { 126503b262f2SGregor Boirie /* 126603b262f2SGregor Boirie * We are using an external trigger and we have just been 126703b262f2SGregor Boirie * powered up: reconfigure one-shot mode. 126803b262f2SGregor Boirie */ 126903b262f2SGregor Boirie err = zpa2326_config_oneshot(indio_dev, priv->irq); 127003b262f2SGregor Boirie if (err) 127103b262f2SGregor Boirie goto err; 127203b262f2SGregor Boirie } 127303b262f2SGregor Boirie 127403b262f2SGregor Boirie /* Plug our own trigger event handler. */ 127503b262f2SGregor Boirie err = iio_triggered_buffer_postenable(indio_dev); 127603b262f2SGregor Boirie if (err) 127703b262f2SGregor Boirie goto err; 127803b262f2SGregor Boirie 127903b262f2SGregor Boirie return 0; 128003b262f2SGregor Boirie 128103b262f2SGregor Boirie err: 128203b262f2SGregor Boirie zpa2326_err(indio_dev, "failed to enable buffering (%d)", err); 128303b262f2SGregor Boirie 128403b262f2SGregor Boirie return err; 128503b262f2SGregor Boirie } 128603b262f2SGregor Boirie 128703b262f2SGregor Boirie static int zpa2326_postdisable_buffer(struct iio_dev *indio_dev) 128803b262f2SGregor Boirie { 128903b262f2SGregor Boirie zpa2326_suspend(indio_dev); 129003b262f2SGregor Boirie 129103b262f2SGregor Boirie return 0; 129203b262f2SGregor Boirie } 129303b262f2SGregor Boirie 129403b262f2SGregor Boirie static const struct iio_buffer_setup_ops zpa2326_buffer_setup_ops = { 129503b262f2SGregor Boirie .preenable = zpa2326_preenable_buffer, 129603b262f2SGregor Boirie .postenable = zpa2326_postenable_buffer, 129703b262f2SGregor Boirie .predisable = iio_triggered_buffer_predisable, 129803b262f2SGregor Boirie .postdisable = zpa2326_postdisable_buffer 129903b262f2SGregor Boirie }; 130003b262f2SGregor Boirie 130103b262f2SGregor Boirie /** 130203b262f2SGregor Boirie * zpa2326_set_trigger_state() - Start / stop continuous sampling. 130303b262f2SGregor Boirie * @trig: The trigger being attached to IIO device associated with the sampling 130403b262f2SGregor Boirie * hardware. 130503b262f2SGregor Boirie * @state: Tell whether to start (true) or stop (false) 130603b262f2SGregor Boirie * 130703b262f2SGregor Boirie * Basically enable / disable hardware continuous sampling mode. 130803b262f2SGregor Boirie * 130903b262f2SGregor Boirie * Called with IIO device's lock held at postenable() or predisable() time. 131003b262f2SGregor Boirie * 131103b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 131203b262f2SGregor Boirie */ 131303b262f2SGregor Boirie static int zpa2326_set_trigger_state(struct iio_trigger *trig, bool state) 131403b262f2SGregor Boirie { 131503b262f2SGregor Boirie const struct iio_dev *indio_dev = dev_get_drvdata( 131603b262f2SGregor Boirie trig->dev.parent); 131703b262f2SGregor Boirie const struct zpa2326_private *priv = iio_priv(indio_dev); 131803b262f2SGregor Boirie int err; 131903b262f2SGregor Boirie 132003b262f2SGregor Boirie if (!state) { 132103b262f2SGregor Boirie /* 132203b262f2SGregor Boirie * Switch trigger off : in case of failure, interrupt is left 132303b262f2SGregor Boirie * disabled in order to prevent handler from accessing released 132403b262f2SGregor Boirie * resources. 132503b262f2SGregor Boirie */ 132603b262f2SGregor Boirie unsigned int val; 132703b262f2SGregor Boirie 132803b262f2SGregor Boirie /* 132903b262f2SGregor Boirie * As device is working in continuous mode, handlers may be 133003b262f2SGregor Boirie * accessing resources we are currently freeing... 133103b262f2SGregor Boirie * Prevent this by disabling interrupt handlers and ensure 133203b262f2SGregor Boirie * the device will generate no more interrupts unless explicitly 133303b262f2SGregor Boirie * required to, i.e. by restoring back to default one shot mode. 133403b262f2SGregor Boirie */ 133503b262f2SGregor Boirie disable_irq(priv->irq); 133603b262f2SGregor Boirie 133703b262f2SGregor Boirie /* 133803b262f2SGregor Boirie * Disable continuous sampling mode to restore settings for 133903b262f2SGregor Boirie * one shot / direct sampling operations. 134003b262f2SGregor Boirie */ 134103b262f2SGregor Boirie err = regmap_write(priv->regmap, ZPA2326_CTRL_REG3_REG, 134203b262f2SGregor Boirie zpa2326_highest_frequency()->odr); 134303b262f2SGregor Boirie if (err) 134403b262f2SGregor Boirie return err; 134503b262f2SGregor Boirie 134603b262f2SGregor Boirie /* 134703b262f2SGregor Boirie * Now that device won't generate interrupts on its own, 134803b262f2SGregor Boirie * acknowledge any currently active interrupts (may happen on 134903b262f2SGregor Boirie * rare occasions while stopping continuous mode). 135003b262f2SGregor Boirie */ 135103b262f2SGregor Boirie err = regmap_read(priv->regmap, ZPA2326_INT_SOURCE_REG, &val); 135203b262f2SGregor Boirie if (err < 0) 135303b262f2SGregor Boirie return err; 135403b262f2SGregor Boirie 135503b262f2SGregor Boirie /* 135603b262f2SGregor Boirie * Re-enable interrupts only if we can guarantee the device will 135703b262f2SGregor Boirie * generate no more interrupts to prevent handlers from 135803b262f2SGregor Boirie * accessing released resources. 135903b262f2SGregor Boirie */ 136003b262f2SGregor Boirie enable_irq(priv->irq); 136103b262f2SGregor Boirie 136203b262f2SGregor Boirie zpa2326_dbg(indio_dev, "continuous mode stopped"); 136303b262f2SGregor Boirie } else { 136403b262f2SGregor Boirie /* 136503b262f2SGregor Boirie * Switch trigger on : start continuous sampling at required 136603b262f2SGregor Boirie * frequency. 136703b262f2SGregor Boirie */ 136803b262f2SGregor Boirie 136903b262f2SGregor Boirie if (priv->waken) { 137003b262f2SGregor Boirie /* Enable interrupt if getting out of reset. */ 137103b262f2SGregor Boirie err = regmap_write(priv->regmap, ZPA2326_CTRL_REG1_REG, 137203b262f2SGregor Boirie (u8) 137303b262f2SGregor Boirie ~ZPA2326_CTRL_REG1_MASK_DATA_READY); 137403b262f2SGregor Boirie if (err) 137503b262f2SGregor Boirie return err; 137603b262f2SGregor Boirie } 137703b262f2SGregor Boirie 137803b262f2SGregor Boirie /* Enable continuous sampling at specified frequency. */ 137903b262f2SGregor Boirie err = regmap_write(priv->regmap, ZPA2326_CTRL_REG3_REG, 138003b262f2SGregor Boirie ZPA2326_CTRL_REG3_ENABLE_MEAS | 138103b262f2SGregor Boirie priv->frequency->odr); 138203b262f2SGregor Boirie if (err) 138303b262f2SGregor Boirie return err; 138403b262f2SGregor Boirie 138503b262f2SGregor Boirie zpa2326_dbg(indio_dev, "continuous mode setup @%dHz", 138603b262f2SGregor Boirie priv->frequency->hz); 138703b262f2SGregor Boirie } 138803b262f2SGregor Boirie 138903b262f2SGregor Boirie return 0; 139003b262f2SGregor Boirie } 139103b262f2SGregor Boirie 139203b262f2SGregor Boirie static const struct iio_trigger_ops zpa2326_trigger_ops = { 139303b262f2SGregor Boirie .owner = THIS_MODULE, 139403b262f2SGregor Boirie .set_trigger_state = zpa2326_set_trigger_state, 139503b262f2SGregor Boirie }; 139603b262f2SGregor Boirie 139703b262f2SGregor Boirie /** 139803b262f2SGregor Boirie * zpa2326_init_trigger() - Create an interrupt driven / hardware trigger 139903b262f2SGregor Boirie * allowing to notify external devices a new sample is 140003b262f2SGregor Boirie * ready. 140103b262f2SGregor Boirie * @parent: Hardware sampling device @indio_dev is a child of. 140203b262f2SGregor Boirie * @indio_dev: The IIO device associated with the sampling hardware. 140303b262f2SGregor Boirie * @private: Internal private state related to @indio_dev. 140403b262f2SGregor Boirie * @irq: Optional interrupt line the hardware uses to notify new data 140503b262f2SGregor Boirie * samples are ready. Negative or zero values indicate no interrupts 140603b262f2SGregor Boirie * are available, meaning polling is required. 140703b262f2SGregor Boirie * 140803b262f2SGregor Boirie * Only relevant when DT declares a valid interrupt line. 140903b262f2SGregor Boirie * 141003b262f2SGregor Boirie * Return: Zero when successful, a negative error code otherwise. 141103b262f2SGregor Boirie */ 141203b262f2SGregor Boirie static int zpa2326_init_managed_trigger(struct device *parent, 141303b262f2SGregor Boirie struct iio_dev *indio_dev, 141403b262f2SGregor Boirie struct zpa2326_private *private, 141503b262f2SGregor Boirie int irq) 141603b262f2SGregor Boirie { 141703b262f2SGregor Boirie struct iio_trigger *trigger; 141803b262f2SGregor Boirie int ret; 141903b262f2SGregor Boirie 142003b262f2SGregor Boirie if (irq <= 0) 142103b262f2SGregor Boirie return 0; 142203b262f2SGregor Boirie 142303b262f2SGregor Boirie trigger = devm_iio_trigger_alloc(parent, "%s-dev%d", 142403b262f2SGregor Boirie indio_dev->name, indio_dev->id); 142503b262f2SGregor Boirie if (!trigger) 142603b262f2SGregor Boirie return -ENOMEM; 142703b262f2SGregor Boirie 142803b262f2SGregor Boirie /* Basic setup. */ 142903b262f2SGregor Boirie trigger->dev.parent = parent; 143003b262f2SGregor Boirie trigger->ops = &zpa2326_trigger_ops; 143103b262f2SGregor Boirie 143203b262f2SGregor Boirie private->trigger = trigger; 143303b262f2SGregor Boirie 143403b262f2SGregor Boirie /* Register to triggers space. */ 143503b262f2SGregor Boirie ret = devm_iio_trigger_register(parent, trigger); 143603b262f2SGregor Boirie if (ret) 143703b262f2SGregor Boirie dev_err(parent, "failed to register hardware trigger (%d)", 143803b262f2SGregor Boirie ret); 143903b262f2SGregor Boirie 144003b262f2SGregor Boirie return ret; 144103b262f2SGregor Boirie } 144203b262f2SGregor Boirie 144303b262f2SGregor Boirie static int zpa2326_get_frequency(const struct iio_dev *indio_dev) 144403b262f2SGregor Boirie { 144503b262f2SGregor Boirie return ((struct zpa2326_private *)iio_priv(indio_dev))->frequency->hz; 144603b262f2SGregor Boirie } 144703b262f2SGregor Boirie 144803b262f2SGregor Boirie static int zpa2326_set_frequency(struct iio_dev *indio_dev, int hz) 144903b262f2SGregor Boirie { 145003b262f2SGregor Boirie struct zpa2326_private *priv = iio_priv(indio_dev); 145103b262f2SGregor Boirie int freq; 145203b262f2SGregor Boirie int err; 145303b262f2SGregor Boirie 145403b262f2SGregor Boirie /* Check if requested frequency is supported. */ 145503b262f2SGregor Boirie for (freq = 0; freq < ARRAY_SIZE(zpa2326_sampling_frequencies); freq++) 145603b262f2SGregor Boirie if (zpa2326_sampling_frequencies[freq].hz == hz) 145703b262f2SGregor Boirie break; 145803b262f2SGregor Boirie if (freq == ARRAY_SIZE(zpa2326_sampling_frequencies)) 145903b262f2SGregor Boirie return -EINVAL; 146003b262f2SGregor Boirie 146103b262f2SGregor Boirie /* Don't allow changing frequency if buffered sampling is ongoing. */ 146203b262f2SGregor Boirie err = iio_device_claim_direct_mode(indio_dev); 146303b262f2SGregor Boirie if (err) 146403b262f2SGregor Boirie return err; 146503b262f2SGregor Boirie 146603b262f2SGregor Boirie priv->frequency = &zpa2326_sampling_frequencies[freq]; 146703b262f2SGregor Boirie 146803b262f2SGregor Boirie iio_device_release_direct_mode(indio_dev); 146903b262f2SGregor Boirie 147003b262f2SGregor Boirie return 0; 147103b262f2SGregor Boirie } 147203b262f2SGregor Boirie 147303b262f2SGregor Boirie /* Expose supported hardware sampling frequencies (Hz) through sysfs. */ 147403b262f2SGregor Boirie static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("1 5 11 23"); 147503b262f2SGregor Boirie 147603b262f2SGregor Boirie static struct attribute *zpa2326_attributes[] = { 147703b262f2SGregor Boirie &iio_const_attr_sampling_frequency_available.dev_attr.attr, 147803b262f2SGregor Boirie NULL 147903b262f2SGregor Boirie }; 148003b262f2SGregor Boirie 148103b262f2SGregor Boirie static const struct attribute_group zpa2326_attribute_group = { 148203b262f2SGregor Boirie .attrs = zpa2326_attributes, 148303b262f2SGregor Boirie }; 148403b262f2SGregor Boirie 148503b262f2SGregor Boirie static int zpa2326_read_raw(struct iio_dev *indio_dev, 148603b262f2SGregor Boirie struct iio_chan_spec const *chan, 148703b262f2SGregor Boirie int *val, 148803b262f2SGregor Boirie int *val2, 148903b262f2SGregor Boirie long mask) 149003b262f2SGregor Boirie { 149103b262f2SGregor Boirie switch (mask) { 149203b262f2SGregor Boirie case IIO_CHAN_INFO_RAW: 149303b262f2SGregor Boirie return zpa2326_sample_oneshot(indio_dev, chan->type, val); 149403b262f2SGregor Boirie 149503b262f2SGregor Boirie case IIO_CHAN_INFO_SCALE: 149603b262f2SGregor Boirie switch (chan->type) { 149703b262f2SGregor Boirie case IIO_PRESSURE: 149803b262f2SGregor Boirie /* 149903b262f2SGregor Boirie * Pressure resolution is 1/64 Pascal. Scale to kPascal 150003b262f2SGregor Boirie * as required by IIO ABI. 150103b262f2SGregor Boirie */ 150203b262f2SGregor Boirie *val = 1; 150303b262f2SGregor Boirie *val2 = 64000; 150403b262f2SGregor Boirie return IIO_VAL_FRACTIONAL; 150503b262f2SGregor Boirie 150603b262f2SGregor Boirie case IIO_TEMP: 150703b262f2SGregor Boirie /* 150803b262f2SGregor Boirie * Temperature follows the equation: 150903b262f2SGregor Boirie * Temp[degC] = Tempcode * 0.00649 - 176.83 151003b262f2SGregor Boirie * where: 151103b262f2SGregor Boirie * Tempcode is composed the raw sampled 16 bits. 151203b262f2SGregor Boirie * 151303b262f2SGregor Boirie * Hence, to produce a temperature in milli-degrees 151403b262f2SGregor Boirie * Celsius according to IIO ABI, we need to apply the 151503b262f2SGregor Boirie * following equation to raw samples: 151603b262f2SGregor Boirie * Temp[milli degC] = (Tempcode + Offset) * Scale 151703b262f2SGregor Boirie * where: 151803b262f2SGregor Boirie * Offset = -176.83 / 0.00649 151903b262f2SGregor Boirie * Scale = 0.00649 * 1000 152003b262f2SGregor Boirie */ 152103b262f2SGregor Boirie *val = 6; 152203b262f2SGregor Boirie *val2 = 490000; 152303b262f2SGregor Boirie return IIO_VAL_INT_PLUS_MICRO; 152403b262f2SGregor Boirie 152503b262f2SGregor Boirie default: 152603b262f2SGregor Boirie return -EINVAL; 152703b262f2SGregor Boirie } 152803b262f2SGregor Boirie 152903b262f2SGregor Boirie case IIO_CHAN_INFO_OFFSET: 153003b262f2SGregor Boirie switch (chan->type) { 153103b262f2SGregor Boirie case IIO_TEMP: 153203b262f2SGregor Boirie *val = -17683000; 153303b262f2SGregor Boirie *val2 = 649; 153403b262f2SGregor Boirie return IIO_VAL_FRACTIONAL; 153503b262f2SGregor Boirie 153603b262f2SGregor Boirie default: 153703b262f2SGregor Boirie return -EINVAL; 153803b262f2SGregor Boirie } 153903b262f2SGregor Boirie 154003b262f2SGregor Boirie case IIO_CHAN_INFO_SAMP_FREQ: 154103b262f2SGregor Boirie *val = zpa2326_get_frequency(indio_dev); 154203b262f2SGregor Boirie return IIO_VAL_INT; 154303b262f2SGregor Boirie 154403b262f2SGregor Boirie default: 154503b262f2SGregor Boirie return -EINVAL; 154603b262f2SGregor Boirie } 154703b262f2SGregor Boirie } 154803b262f2SGregor Boirie 154903b262f2SGregor Boirie static int zpa2326_write_raw(struct iio_dev *indio_dev, 155003b262f2SGregor Boirie const struct iio_chan_spec *chan, 155103b262f2SGregor Boirie int val, 155203b262f2SGregor Boirie int val2, 155303b262f2SGregor Boirie long mask) 155403b262f2SGregor Boirie { 155503b262f2SGregor Boirie if ((mask != IIO_CHAN_INFO_SAMP_FREQ) || val2) 155603b262f2SGregor Boirie return -EINVAL; 155703b262f2SGregor Boirie 155803b262f2SGregor Boirie return zpa2326_set_frequency(indio_dev, val); 155903b262f2SGregor Boirie } 156003b262f2SGregor Boirie 156103b262f2SGregor Boirie static const struct iio_chan_spec zpa2326_channels[] = { 156203b262f2SGregor Boirie [0] = { 156303b262f2SGregor Boirie .type = IIO_PRESSURE, 156403b262f2SGregor Boirie .scan_index = 0, 156503b262f2SGregor Boirie .scan_type = { 156603b262f2SGregor Boirie .sign = 'u', 156703b262f2SGregor Boirie .realbits = 24, 156803b262f2SGregor Boirie .storagebits = 32, 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 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), 157403b262f2SGregor Boirie }, 157503b262f2SGregor Boirie [1] = { 157603b262f2SGregor Boirie .type = IIO_TEMP, 157703b262f2SGregor Boirie .scan_index = 1, 157803b262f2SGregor Boirie .scan_type = { 157903b262f2SGregor Boirie .sign = 's', 158003b262f2SGregor Boirie .realbits = 16, 158103b262f2SGregor Boirie .storagebits = 16, 158203b262f2SGregor Boirie .endianness = IIO_LE, 158303b262f2SGregor Boirie }, 158403b262f2SGregor Boirie .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 158503b262f2SGregor Boirie BIT(IIO_CHAN_INFO_SCALE) | 158603b262f2SGregor Boirie BIT(IIO_CHAN_INFO_OFFSET), 158703b262f2SGregor Boirie .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), 158803b262f2SGregor Boirie }, 158903b262f2SGregor Boirie [2] = IIO_CHAN_SOFT_TIMESTAMP(2), 159003b262f2SGregor Boirie }; 159103b262f2SGregor Boirie 159203b262f2SGregor Boirie static const struct iio_info zpa2326_info = { 159303b262f2SGregor Boirie .driver_module = THIS_MODULE, 159403b262f2SGregor Boirie .attrs = &zpa2326_attribute_group, 159503b262f2SGregor Boirie .read_raw = zpa2326_read_raw, 159603b262f2SGregor Boirie .write_raw = zpa2326_write_raw, 159703b262f2SGregor Boirie }; 159803b262f2SGregor Boirie 159903b262f2SGregor Boirie static struct iio_dev *zpa2326_create_managed_iiodev(struct device *device, 160003b262f2SGregor Boirie const char *name, 160103b262f2SGregor Boirie struct regmap *regmap) 160203b262f2SGregor Boirie { 160303b262f2SGregor Boirie struct iio_dev *indio_dev; 160403b262f2SGregor Boirie 160503b262f2SGregor Boirie /* Allocate space to hold IIO device internal state. */ 160603b262f2SGregor Boirie indio_dev = devm_iio_device_alloc(device, 160703b262f2SGregor Boirie sizeof(struct zpa2326_private)); 160803b262f2SGregor Boirie if (!indio_dev) 160903b262f2SGregor Boirie return NULL; 161003b262f2SGregor Boirie 161103b262f2SGregor Boirie /* Setup for userspace synchronous on demand sampling. */ 161203b262f2SGregor Boirie indio_dev->modes = INDIO_DIRECT_MODE; 161303b262f2SGregor Boirie indio_dev->dev.parent = device; 161403b262f2SGregor Boirie indio_dev->channels = zpa2326_channels; 161503b262f2SGregor Boirie indio_dev->num_channels = ARRAY_SIZE(zpa2326_channels); 161603b262f2SGregor Boirie indio_dev->name = name; 161703b262f2SGregor Boirie indio_dev->info = &zpa2326_info; 161803b262f2SGregor Boirie 161903b262f2SGregor Boirie return indio_dev; 162003b262f2SGregor Boirie } 162103b262f2SGregor Boirie 162203b262f2SGregor Boirie int zpa2326_probe(struct device *parent, 162303b262f2SGregor Boirie const char *name, 162403b262f2SGregor Boirie int irq, 162503b262f2SGregor Boirie unsigned int hwid, 162603b262f2SGregor Boirie struct regmap *regmap) 162703b262f2SGregor Boirie { 162803b262f2SGregor Boirie struct iio_dev *indio_dev; 162903b262f2SGregor Boirie struct zpa2326_private *priv; 163003b262f2SGregor Boirie int err; 163103b262f2SGregor Boirie unsigned int id; 163203b262f2SGregor Boirie 163303b262f2SGregor Boirie indio_dev = zpa2326_create_managed_iiodev(parent, name, regmap); 163403b262f2SGregor Boirie if (!indio_dev) 163503b262f2SGregor Boirie return -ENOMEM; 163603b262f2SGregor Boirie 163703b262f2SGregor Boirie priv = iio_priv(indio_dev); 163803b262f2SGregor Boirie 163903b262f2SGregor Boirie priv->vref = devm_regulator_get(parent, "vref"); 164003b262f2SGregor Boirie if (IS_ERR(priv->vref)) 164103b262f2SGregor Boirie return PTR_ERR(priv->vref); 164203b262f2SGregor Boirie 164303b262f2SGregor Boirie priv->vdd = devm_regulator_get(parent, "vdd"); 164403b262f2SGregor Boirie if (IS_ERR(priv->vdd)) 164503b262f2SGregor Boirie return PTR_ERR(priv->vdd); 164603b262f2SGregor Boirie 164703b262f2SGregor Boirie /* Set default hardware sampling frequency to highest rate supported. */ 164803b262f2SGregor Boirie priv->frequency = zpa2326_highest_frequency(); 164903b262f2SGregor Boirie 165003b262f2SGregor Boirie /* 165103b262f2SGregor Boirie * Plug device's underlying bus abstraction : this MUST be set before 165203b262f2SGregor Boirie * registering interrupt handlers since an interrupt might happen if 165303b262f2SGregor Boirie * power up sequence is not properly applied. 165403b262f2SGregor Boirie */ 165503b262f2SGregor Boirie priv->regmap = regmap; 165603b262f2SGregor Boirie 165703b262f2SGregor Boirie err = devm_iio_triggered_buffer_setup(parent, indio_dev, NULL, 165803b262f2SGregor Boirie zpa2326_trigger_handler, 165903b262f2SGregor Boirie &zpa2326_buffer_setup_ops); 166003b262f2SGregor Boirie if (err) 166103b262f2SGregor Boirie return err; 166203b262f2SGregor Boirie 166303b262f2SGregor Boirie err = zpa2326_init_managed_trigger(parent, indio_dev, priv, irq); 166403b262f2SGregor Boirie if (err) 166503b262f2SGregor Boirie return err; 166603b262f2SGregor Boirie 166703b262f2SGregor Boirie err = zpa2326_init_managed_irq(parent, indio_dev, priv, irq); 166803b262f2SGregor Boirie if (err) 166903b262f2SGregor Boirie return err; 167003b262f2SGregor Boirie 167103b262f2SGregor Boirie /* Power up to check device ID and perform initial hardware setup. */ 167203b262f2SGregor Boirie err = zpa2326_power_on(indio_dev, priv); 167303b262f2SGregor Boirie if (err) 167403b262f2SGregor Boirie return err; 167503b262f2SGregor Boirie 167603b262f2SGregor Boirie /* Read id register to check we are talking to the right slave. */ 167703b262f2SGregor Boirie err = regmap_read(regmap, ZPA2326_DEVICE_ID_REG, &id); 167803b262f2SGregor Boirie if (err) 167903b262f2SGregor Boirie goto sleep; 168003b262f2SGregor Boirie 168103b262f2SGregor Boirie if (id != hwid) { 168203b262f2SGregor Boirie dev_err(parent, "found device with unexpected id %02x", id); 168303b262f2SGregor Boirie err = -ENODEV; 168403b262f2SGregor Boirie goto sleep; 168503b262f2SGregor Boirie } 168603b262f2SGregor Boirie 168703b262f2SGregor Boirie err = zpa2326_config_oneshot(indio_dev, irq); 168803b262f2SGregor Boirie if (err) 168903b262f2SGregor Boirie goto sleep; 169003b262f2SGregor Boirie 169103b262f2SGregor Boirie /* Setup done : go sleeping. Device will be awaken upon user request. */ 169203b262f2SGregor Boirie err = zpa2326_sleep(indio_dev); 169303b262f2SGregor Boirie if (err) 169403b262f2SGregor Boirie goto poweroff; 169503b262f2SGregor Boirie 169603b262f2SGregor Boirie dev_set_drvdata(parent, indio_dev); 169703b262f2SGregor Boirie 169803b262f2SGregor Boirie zpa2326_init_runtime(parent); 169903b262f2SGregor Boirie 170003b262f2SGregor Boirie err = iio_device_register(indio_dev); 170103b262f2SGregor Boirie if (err) { 170203b262f2SGregor Boirie zpa2326_fini_runtime(parent); 170303b262f2SGregor Boirie goto poweroff; 170403b262f2SGregor Boirie } 170503b262f2SGregor Boirie 170603b262f2SGregor Boirie return 0; 170703b262f2SGregor Boirie 170803b262f2SGregor Boirie sleep: 170903b262f2SGregor Boirie /* Put to sleep just in case power regulators are "dummy" ones. */ 171003b262f2SGregor Boirie zpa2326_sleep(indio_dev); 171103b262f2SGregor Boirie poweroff: 171203b262f2SGregor Boirie zpa2326_power_off(indio_dev, priv); 171303b262f2SGregor Boirie 171403b262f2SGregor Boirie return err; 171503b262f2SGregor Boirie } 171603b262f2SGregor Boirie EXPORT_SYMBOL_GPL(zpa2326_probe); 171703b262f2SGregor Boirie 171803b262f2SGregor Boirie void zpa2326_remove(const struct device *parent) 171903b262f2SGregor Boirie { 172003b262f2SGregor Boirie struct iio_dev *indio_dev = dev_get_drvdata(parent); 172103b262f2SGregor Boirie 172203b262f2SGregor Boirie iio_device_unregister(indio_dev); 172303b262f2SGregor Boirie zpa2326_fini_runtime(indio_dev->dev.parent); 172403b262f2SGregor Boirie zpa2326_sleep(indio_dev); 172503b262f2SGregor Boirie zpa2326_power_off(indio_dev, iio_priv(indio_dev)); 172603b262f2SGregor Boirie } 172703b262f2SGregor Boirie EXPORT_SYMBOL_GPL(zpa2326_remove); 172803b262f2SGregor Boirie 172903b262f2SGregor Boirie MODULE_AUTHOR("Gregor Boirie <gregor.boirie@parrot.com>"); 173003b262f2SGregor Boirie MODULE_DESCRIPTION("Core driver for Murata ZPA2326 pressure sensor"); 173103b262f2SGregor Boirie MODULE_LICENSE("GPL v2"); 1732