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