180503b23SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
23b1cae7cSLars-Peter Clausen /*
33b1cae7cSLars-Peter Clausen * AD7291 8-Channel, I2C, 12-Bit SAR ADC with Temperature Sensor
43b1cae7cSLars-Peter Clausen *
53b1cae7cSLars-Peter Clausen * Copyright 2010-2011 Analog Devices Inc.
63b1cae7cSLars-Peter Clausen */
73b1cae7cSLars-Peter Clausen
83b1cae7cSLars-Peter Clausen #include <linux/device.h>
93b1cae7cSLars-Peter Clausen #include <linux/err.h>
103b1cae7cSLars-Peter Clausen #include <linux/i2c.h>
113b1cae7cSLars-Peter Clausen #include <linux/interrupt.h>
123b1cae7cSLars-Peter Clausen #include <linux/kernel.h>
133b1cae7cSLars-Peter Clausen #include <linux/module.h>
143b1cae7cSLars-Peter Clausen #include <linux/mutex.h>
153b1cae7cSLars-Peter Clausen #include <linux/regulator/consumer.h>
163b1cae7cSLars-Peter Clausen #include <linux/slab.h>
173b1cae7cSLars-Peter Clausen #include <linux/sysfs.h>
183b1cae7cSLars-Peter Clausen
193b1cae7cSLars-Peter Clausen #include <linux/iio/iio.h>
203b1cae7cSLars-Peter Clausen #include <linux/iio/sysfs.h>
213b1cae7cSLars-Peter Clausen #include <linux/iio/events.h>
223b1cae7cSLars-Peter Clausen
233b1cae7cSLars-Peter Clausen /*
243b1cae7cSLars-Peter Clausen * Simplified handling
253b1cae7cSLars-Peter Clausen *
263b1cae7cSLars-Peter Clausen * If no events enabled - single polled channel read
273b1cae7cSLars-Peter Clausen * If event enabled direct reads disable unless channel
283b1cae7cSLars-Peter Clausen * is in the read mask.
293b1cae7cSLars-Peter Clausen *
303b1cae7cSLars-Peter Clausen * The noise-delayed bit as per datasheet suggestion is always enabled.
313b1cae7cSLars-Peter Clausen */
323b1cae7cSLars-Peter Clausen
333b1cae7cSLars-Peter Clausen /*
343b1cae7cSLars-Peter Clausen * AD7291 registers definition
353b1cae7cSLars-Peter Clausen */
363b1cae7cSLars-Peter Clausen #define AD7291_COMMAND 0x00
373b1cae7cSLars-Peter Clausen #define AD7291_VOLTAGE 0x01
383b1cae7cSLars-Peter Clausen #define AD7291_T_SENSE 0x02
393b1cae7cSLars-Peter Clausen #define AD7291_T_AVERAGE 0x03
403b1cae7cSLars-Peter Clausen #define AD7291_DATA_HIGH(x) ((x) * 3 + 0x4)
413b1cae7cSLars-Peter Clausen #define AD7291_DATA_LOW(x) ((x) * 3 + 0x5)
423b1cae7cSLars-Peter Clausen #define AD7291_HYST(x) ((x) * 3 + 0x6)
433b1cae7cSLars-Peter Clausen #define AD7291_VOLTAGE_ALERT_STATUS 0x1F
443b1cae7cSLars-Peter Clausen #define AD7291_T_ALERT_STATUS 0x20
453b1cae7cSLars-Peter Clausen
463b1cae7cSLars-Peter Clausen #define AD7291_BITS 12
473b1cae7cSLars-Peter Clausen #define AD7291_VOLTAGE_LIMIT_COUNT 8
483b1cae7cSLars-Peter Clausen
493b1cae7cSLars-Peter Clausen
503b1cae7cSLars-Peter Clausen /*
513b1cae7cSLars-Peter Clausen * AD7291 command
523b1cae7cSLars-Peter Clausen */
533b1cae7cSLars-Peter Clausen #define AD7291_AUTOCYCLE BIT(0)
543b1cae7cSLars-Peter Clausen #define AD7291_RESET BIT(1)
553b1cae7cSLars-Peter Clausen #define AD7291_ALERT_CLEAR BIT(2)
563b1cae7cSLars-Peter Clausen #define AD7291_ALERT_POLARITY BIT(3)
573b1cae7cSLars-Peter Clausen #define AD7291_EXT_REF BIT(4)
583b1cae7cSLars-Peter Clausen #define AD7291_NOISE_DELAY BIT(5)
593b1cae7cSLars-Peter Clausen #define AD7291_T_SENSE_MASK BIT(7)
603b1cae7cSLars-Peter Clausen #define AD7291_VOLTAGE_MASK GENMASK(15, 8)
613b1cae7cSLars-Peter Clausen #define AD7291_VOLTAGE_OFFSET 8
623b1cae7cSLars-Peter Clausen
633b1cae7cSLars-Peter Clausen /*
643b1cae7cSLars-Peter Clausen * AD7291 value masks
653b1cae7cSLars-Peter Clausen */
663b1cae7cSLars-Peter Clausen #define AD7291_VALUE_MASK GENMASK(11, 0)
673b1cae7cSLars-Peter Clausen
683b1cae7cSLars-Peter Clausen /*
693b1cae7cSLars-Peter Clausen * AD7291 alert register bits
703b1cae7cSLars-Peter Clausen */
713b1cae7cSLars-Peter Clausen #define AD7291_T_LOW BIT(0)
723b1cae7cSLars-Peter Clausen #define AD7291_T_HIGH BIT(1)
733b1cae7cSLars-Peter Clausen #define AD7291_T_AVG_LOW BIT(2)
743b1cae7cSLars-Peter Clausen #define AD7291_T_AVG_HIGH BIT(3)
753b1cae7cSLars-Peter Clausen #define AD7291_V_LOW(x) BIT((x) * 2)
763b1cae7cSLars-Peter Clausen #define AD7291_V_HIGH(x) BIT((x) * 2 + 1)
773b1cae7cSLars-Peter Clausen
783b1cae7cSLars-Peter Clausen
793b1cae7cSLars-Peter Clausen struct ad7291_chip_info {
803b1cae7cSLars-Peter Clausen struct i2c_client *client;
813b1cae7cSLars-Peter Clausen struct regulator *reg;
823b1cae7cSLars-Peter Clausen u16 command;
833b1cae7cSLars-Peter Clausen u16 c_mask; /* Active voltage channels for events */
843b1cae7cSLars-Peter Clausen struct mutex state_lock;
853b1cae7cSLars-Peter Clausen };
863b1cae7cSLars-Peter Clausen
ad7291_i2c_read(struct ad7291_chip_info * chip,u8 reg,u16 * data)873b1cae7cSLars-Peter Clausen static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data)
883b1cae7cSLars-Peter Clausen {
893b1cae7cSLars-Peter Clausen struct i2c_client *client = chip->client;
903b1cae7cSLars-Peter Clausen int ret = 0;
913b1cae7cSLars-Peter Clausen
923b1cae7cSLars-Peter Clausen ret = i2c_smbus_read_word_swapped(client, reg);
933b1cae7cSLars-Peter Clausen if (ret < 0) {
943b1cae7cSLars-Peter Clausen dev_err(&client->dev, "I2C read error\n");
953b1cae7cSLars-Peter Clausen return ret;
963b1cae7cSLars-Peter Clausen }
973b1cae7cSLars-Peter Clausen
983b1cae7cSLars-Peter Clausen *data = ret;
993b1cae7cSLars-Peter Clausen
1003b1cae7cSLars-Peter Clausen return 0;
1013b1cae7cSLars-Peter Clausen }
1023b1cae7cSLars-Peter Clausen
ad7291_i2c_write(struct ad7291_chip_info * chip,u8 reg,u16 data)1033b1cae7cSLars-Peter Clausen static int ad7291_i2c_write(struct ad7291_chip_info *chip, u8 reg, u16 data)
1043b1cae7cSLars-Peter Clausen {
1053b1cae7cSLars-Peter Clausen return i2c_smbus_write_word_swapped(chip->client, reg, data);
1063b1cae7cSLars-Peter Clausen }
1073b1cae7cSLars-Peter Clausen
ad7291_event_handler(int irq,void * private)1083b1cae7cSLars-Peter Clausen static irqreturn_t ad7291_event_handler(int irq, void *private)
1093b1cae7cSLars-Peter Clausen {
1103b1cae7cSLars-Peter Clausen struct iio_dev *indio_dev = private;
1113b1cae7cSLars-Peter Clausen struct ad7291_chip_info *chip = iio_priv(private);
1123b1cae7cSLars-Peter Clausen u16 t_status, v_status;
1133b1cae7cSLars-Peter Clausen u16 command;
1143b1cae7cSLars-Peter Clausen int i;
115bc2b7dabSGregor Boirie s64 timestamp = iio_get_time_ns(indio_dev);
1163b1cae7cSLars-Peter Clausen
1173b1cae7cSLars-Peter Clausen if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status))
1183b1cae7cSLars-Peter Clausen return IRQ_HANDLED;
1193b1cae7cSLars-Peter Clausen
1203b1cae7cSLars-Peter Clausen if (ad7291_i2c_read(chip, AD7291_VOLTAGE_ALERT_STATUS, &v_status))
1213b1cae7cSLars-Peter Clausen return IRQ_HANDLED;
1223b1cae7cSLars-Peter Clausen
1233b1cae7cSLars-Peter Clausen if (!(t_status || v_status))
1243b1cae7cSLars-Peter Clausen return IRQ_HANDLED;
1253b1cae7cSLars-Peter Clausen
1263b1cae7cSLars-Peter Clausen command = chip->command | AD7291_ALERT_CLEAR;
1273b1cae7cSLars-Peter Clausen ad7291_i2c_write(chip, AD7291_COMMAND, command);
1283b1cae7cSLars-Peter Clausen
1293b1cae7cSLars-Peter Clausen command = chip->command & ~AD7291_ALERT_CLEAR;
1303b1cae7cSLars-Peter Clausen ad7291_i2c_write(chip, AD7291_COMMAND, command);
1313b1cae7cSLars-Peter Clausen
1323b1cae7cSLars-Peter Clausen /* For now treat t_sense and t_sense_average the same */
1333b1cae7cSLars-Peter Clausen if ((t_status & AD7291_T_LOW) || (t_status & AD7291_T_AVG_LOW))
1343b1cae7cSLars-Peter Clausen iio_push_event(indio_dev,
1353b1cae7cSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_TEMP,
1363b1cae7cSLars-Peter Clausen 0,
1373b1cae7cSLars-Peter Clausen IIO_EV_TYPE_THRESH,
1383b1cae7cSLars-Peter Clausen IIO_EV_DIR_FALLING),
1393b1cae7cSLars-Peter Clausen timestamp);
1403b1cae7cSLars-Peter Clausen if ((t_status & AD7291_T_HIGH) || (t_status & AD7291_T_AVG_HIGH))
1413b1cae7cSLars-Peter Clausen iio_push_event(indio_dev,
1423b1cae7cSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_TEMP,
1433b1cae7cSLars-Peter Clausen 0,
1443b1cae7cSLars-Peter Clausen IIO_EV_TYPE_THRESH,
1453b1cae7cSLars-Peter Clausen IIO_EV_DIR_RISING),
1463b1cae7cSLars-Peter Clausen timestamp);
1473b1cae7cSLars-Peter Clausen
1483b1cae7cSLars-Peter Clausen for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT; i++) {
1493b1cae7cSLars-Peter Clausen if (v_status & AD7291_V_LOW(i))
1503b1cae7cSLars-Peter Clausen iio_push_event(indio_dev,
1513b1cae7cSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
1523b1cae7cSLars-Peter Clausen i,
1533b1cae7cSLars-Peter Clausen IIO_EV_TYPE_THRESH,
1543b1cae7cSLars-Peter Clausen IIO_EV_DIR_FALLING),
1553b1cae7cSLars-Peter Clausen timestamp);
1563b1cae7cSLars-Peter Clausen if (v_status & AD7291_V_HIGH(i))
1573b1cae7cSLars-Peter Clausen iio_push_event(indio_dev,
1583b1cae7cSLars-Peter Clausen IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE,
1593b1cae7cSLars-Peter Clausen i,
1603b1cae7cSLars-Peter Clausen IIO_EV_TYPE_THRESH,
1613b1cae7cSLars-Peter Clausen IIO_EV_DIR_RISING),
1623b1cae7cSLars-Peter Clausen timestamp);
1633b1cae7cSLars-Peter Clausen }
1643b1cae7cSLars-Peter Clausen
1653b1cae7cSLars-Peter Clausen return IRQ_HANDLED;
1663b1cae7cSLars-Peter Clausen }
1673b1cae7cSLars-Peter Clausen
ad7291_threshold_reg(const struct iio_chan_spec * chan,enum iio_event_direction dir,enum iio_event_info info)1683b1cae7cSLars-Peter Clausen static unsigned int ad7291_threshold_reg(const struct iio_chan_spec *chan,
1693b1cae7cSLars-Peter Clausen enum iio_event_direction dir,
1703b1cae7cSLars-Peter Clausen enum iio_event_info info)
1713b1cae7cSLars-Peter Clausen {
1723b1cae7cSLars-Peter Clausen unsigned int offset;
1733b1cae7cSLars-Peter Clausen
1743b1cae7cSLars-Peter Clausen switch (chan->type) {
1753b1cae7cSLars-Peter Clausen case IIO_VOLTAGE:
1763b1cae7cSLars-Peter Clausen offset = chan->channel;
1773b1cae7cSLars-Peter Clausen break;
1783b1cae7cSLars-Peter Clausen case IIO_TEMP:
1793b1cae7cSLars-Peter Clausen offset = AD7291_VOLTAGE_OFFSET;
1803b1cae7cSLars-Peter Clausen break;
1813b1cae7cSLars-Peter Clausen default:
1823b1cae7cSLars-Peter Clausen return 0;
1833b1cae7cSLars-Peter Clausen }
1843b1cae7cSLars-Peter Clausen
1853b1cae7cSLars-Peter Clausen switch (info) {
1863b1cae7cSLars-Peter Clausen case IIO_EV_INFO_VALUE:
1873b1cae7cSLars-Peter Clausen if (dir == IIO_EV_DIR_FALLING)
1883b1cae7cSLars-Peter Clausen return AD7291_DATA_HIGH(offset);
1893b1cae7cSLars-Peter Clausen else
1903b1cae7cSLars-Peter Clausen return AD7291_DATA_LOW(offset);
1913b1cae7cSLars-Peter Clausen case IIO_EV_INFO_HYSTERESIS:
1923b1cae7cSLars-Peter Clausen return AD7291_HYST(offset);
1933b1cae7cSLars-Peter Clausen default:
1943b1cae7cSLars-Peter Clausen break;
1953b1cae7cSLars-Peter Clausen }
1963b1cae7cSLars-Peter Clausen return 0;
1973b1cae7cSLars-Peter Clausen }
1983b1cae7cSLars-Peter Clausen
ad7291_read_event_value(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int * val,int * val2)1993b1cae7cSLars-Peter Clausen static int ad7291_read_event_value(struct iio_dev *indio_dev,
2003b1cae7cSLars-Peter Clausen const struct iio_chan_spec *chan,
2013b1cae7cSLars-Peter Clausen enum iio_event_type type,
2023b1cae7cSLars-Peter Clausen enum iio_event_direction dir,
2033b1cae7cSLars-Peter Clausen enum iio_event_info info,
2043b1cae7cSLars-Peter Clausen int *val, int *val2)
2053b1cae7cSLars-Peter Clausen {
2063b1cae7cSLars-Peter Clausen struct ad7291_chip_info *chip = iio_priv(indio_dev);
2073b1cae7cSLars-Peter Clausen int ret;
2083b1cae7cSLars-Peter Clausen u16 uval;
2093b1cae7cSLars-Peter Clausen
2103b1cae7cSLars-Peter Clausen ret = ad7291_i2c_read(chip, ad7291_threshold_reg(chan, dir, info),
2113b1cae7cSLars-Peter Clausen &uval);
2123b1cae7cSLars-Peter Clausen if (ret < 0)
2133b1cae7cSLars-Peter Clausen return ret;
2143b1cae7cSLars-Peter Clausen
2153b1cae7cSLars-Peter Clausen if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE)
2163b1cae7cSLars-Peter Clausen *val = uval & AD7291_VALUE_MASK;
2173b1cae7cSLars-Peter Clausen
2183b1cae7cSLars-Peter Clausen else
2193b1cae7cSLars-Peter Clausen *val = sign_extend32(uval, 11);
2203b1cae7cSLars-Peter Clausen
2213b1cae7cSLars-Peter Clausen return IIO_VAL_INT;
2223b1cae7cSLars-Peter Clausen }
2233b1cae7cSLars-Peter Clausen
ad7291_write_event_value(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int val,int val2)2243b1cae7cSLars-Peter Clausen static int ad7291_write_event_value(struct iio_dev *indio_dev,
2253b1cae7cSLars-Peter Clausen const struct iio_chan_spec *chan,
2263b1cae7cSLars-Peter Clausen enum iio_event_type type,
2273b1cae7cSLars-Peter Clausen enum iio_event_direction dir,
2283b1cae7cSLars-Peter Clausen enum iio_event_info info,
2293b1cae7cSLars-Peter Clausen int val, int val2)
2303b1cae7cSLars-Peter Clausen {
2313b1cae7cSLars-Peter Clausen struct ad7291_chip_info *chip = iio_priv(indio_dev);
2323b1cae7cSLars-Peter Clausen
2333b1cae7cSLars-Peter Clausen if (info == IIO_EV_INFO_HYSTERESIS || chan->type == IIO_VOLTAGE) {
2343b1cae7cSLars-Peter Clausen if (val > AD7291_VALUE_MASK || val < 0)
2353b1cae7cSLars-Peter Clausen return -EINVAL;
2363b1cae7cSLars-Peter Clausen } else {
2373b1cae7cSLars-Peter Clausen if (val > 2047 || val < -2048)
2383b1cae7cSLars-Peter Clausen return -EINVAL;
2393b1cae7cSLars-Peter Clausen }
2403b1cae7cSLars-Peter Clausen
2413b1cae7cSLars-Peter Clausen return ad7291_i2c_write(chip, ad7291_threshold_reg(chan, dir, info),
2423b1cae7cSLars-Peter Clausen val);
2433b1cae7cSLars-Peter Clausen }
2443b1cae7cSLars-Peter Clausen
ad7291_read_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir)2453b1cae7cSLars-Peter Clausen static int ad7291_read_event_config(struct iio_dev *indio_dev,
2463b1cae7cSLars-Peter Clausen const struct iio_chan_spec *chan,
2473b1cae7cSLars-Peter Clausen enum iio_event_type type,
2483b1cae7cSLars-Peter Clausen enum iio_event_direction dir)
2493b1cae7cSLars-Peter Clausen {
2503b1cae7cSLars-Peter Clausen struct ad7291_chip_info *chip = iio_priv(indio_dev);
2513b1cae7cSLars-Peter Clausen /*
2523b1cae7cSLars-Peter Clausen * To be enabled the channel must simply be on. If any are enabled
2533b1cae7cSLars-Peter Clausen * we are in continuous sampling mode
2543b1cae7cSLars-Peter Clausen */
2553b1cae7cSLars-Peter Clausen
2563b1cae7cSLars-Peter Clausen switch (chan->type) {
2573b1cae7cSLars-Peter Clausen case IIO_VOLTAGE:
2583b1cae7cSLars-Peter Clausen return !!(chip->c_mask & BIT(15 - chan->channel));
2593b1cae7cSLars-Peter Clausen case IIO_TEMP:
2603b1cae7cSLars-Peter Clausen /* always on */
2613b1cae7cSLars-Peter Clausen return 1;
2623b1cae7cSLars-Peter Clausen default:
2633b1cae7cSLars-Peter Clausen return -EINVAL;
2643b1cae7cSLars-Peter Clausen }
2653b1cae7cSLars-Peter Clausen
2663b1cae7cSLars-Peter Clausen }
2673b1cae7cSLars-Peter Clausen
ad7291_write_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,int state)2683b1cae7cSLars-Peter Clausen static int ad7291_write_event_config(struct iio_dev *indio_dev,
2693b1cae7cSLars-Peter Clausen const struct iio_chan_spec *chan,
2703b1cae7cSLars-Peter Clausen enum iio_event_type type,
2713b1cae7cSLars-Peter Clausen enum iio_event_direction dir,
2723b1cae7cSLars-Peter Clausen int state)
2733b1cae7cSLars-Peter Clausen {
2743b1cae7cSLars-Peter Clausen int ret = 0;
2753b1cae7cSLars-Peter Clausen struct ad7291_chip_info *chip = iio_priv(indio_dev);
2763b1cae7cSLars-Peter Clausen unsigned int mask;
2773b1cae7cSLars-Peter Clausen u16 regval;
2783b1cae7cSLars-Peter Clausen
2793b1cae7cSLars-Peter Clausen mutex_lock(&chip->state_lock);
2803b1cae7cSLars-Peter Clausen regval = chip->command;
2813b1cae7cSLars-Peter Clausen /*
2823b1cae7cSLars-Peter Clausen * To be enabled the channel must simply be on. If any are enabled
2833b1cae7cSLars-Peter Clausen * use continuous sampling mode.
2843b1cae7cSLars-Peter Clausen * Possible to disable temp as well but that makes single read tricky.
2853b1cae7cSLars-Peter Clausen */
2863b1cae7cSLars-Peter Clausen
2873b1cae7cSLars-Peter Clausen mask = BIT(15 - chan->channel);
2883b1cae7cSLars-Peter Clausen
2893b1cae7cSLars-Peter Clausen switch (chan->type) {
2903b1cae7cSLars-Peter Clausen case IIO_VOLTAGE:
2913b1cae7cSLars-Peter Clausen if ((!state) && (chip->c_mask & mask))
2923b1cae7cSLars-Peter Clausen chip->c_mask &= ~mask;
2933b1cae7cSLars-Peter Clausen else if (state && (!(chip->c_mask & mask)))
2943b1cae7cSLars-Peter Clausen chip->c_mask |= mask;
2953b1cae7cSLars-Peter Clausen else
2963b1cae7cSLars-Peter Clausen break;
2973b1cae7cSLars-Peter Clausen
2983b1cae7cSLars-Peter Clausen regval &= ~AD7291_AUTOCYCLE;
2993b1cae7cSLars-Peter Clausen regval |= chip->c_mask;
3003b1cae7cSLars-Peter Clausen if (chip->c_mask) /* Enable autocycle? */
3013b1cae7cSLars-Peter Clausen regval |= AD7291_AUTOCYCLE;
3023b1cae7cSLars-Peter Clausen
3033b1cae7cSLars-Peter Clausen ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
3043b1cae7cSLars-Peter Clausen if (ret < 0)
3053b1cae7cSLars-Peter Clausen goto error_ret;
3063b1cae7cSLars-Peter Clausen
3073b1cae7cSLars-Peter Clausen chip->command = regval;
3083b1cae7cSLars-Peter Clausen break;
3093b1cae7cSLars-Peter Clausen default:
3103b1cae7cSLars-Peter Clausen ret = -EINVAL;
3113b1cae7cSLars-Peter Clausen }
3123b1cae7cSLars-Peter Clausen
3133b1cae7cSLars-Peter Clausen error_ret:
3143b1cae7cSLars-Peter Clausen mutex_unlock(&chip->state_lock);
3153b1cae7cSLars-Peter Clausen return ret;
3163b1cae7cSLars-Peter Clausen }
3173b1cae7cSLars-Peter Clausen
ad7291_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)3183b1cae7cSLars-Peter Clausen static int ad7291_read_raw(struct iio_dev *indio_dev,
3193b1cae7cSLars-Peter Clausen struct iio_chan_spec const *chan,
3203b1cae7cSLars-Peter Clausen int *val,
3213b1cae7cSLars-Peter Clausen int *val2,
3223b1cae7cSLars-Peter Clausen long mask)
3233b1cae7cSLars-Peter Clausen {
3243b1cae7cSLars-Peter Clausen int ret;
3253b1cae7cSLars-Peter Clausen struct ad7291_chip_info *chip = iio_priv(indio_dev);
3263b1cae7cSLars-Peter Clausen u16 regval;
3273b1cae7cSLars-Peter Clausen
3283b1cae7cSLars-Peter Clausen switch (mask) {
3293b1cae7cSLars-Peter Clausen case IIO_CHAN_INFO_RAW:
3303b1cae7cSLars-Peter Clausen switch (chan->type) {
3313b1cae7cSLars-Peter Clausen case IIO_VOLTAGE:
3323b1cae7cSLars-Peter Clausen mutex_lock(&chip->state_lock);
3333b1cae7cSLars-Peter Clausen /* If in autocycle mode drop through */
3343b1cae7cSLars-Peter Clausen if (chip->command & AD7291_AUTOCYCLE) {
3353b1cae7cSLars-Peter Clausen mutex_unlock(&chip->state_lock);
3363b1cae7cSLars-Peter Clausen return -EBUSY;
3373b1cae7cSLars-Peter Clausen }
3383b1cae7cSLars-Peter Clausen /* Enable this channel alone */
3393b1cae7cSLars-Peter Clausen regval = chip->command & (~AD7291_VOLTAGE_MASK);
3403b1cae7cSLars-Peter Clausen regval |= BIT(15 - chan->channel);
3413b1cae7cSLars-Peter Clausen ret = ad7291_i2c_write(chip, AD7291_COMMAND, regval);
3423b1cae7cSLars-Peter Clausen if (ret < 0) {
3433b1cae7cSLars-Peter Clausen mutex_unlock(&chip->state_lock);
3443b1cae7cSLars-Peter Clausen return ret;
3453b1cae7cSLars-Peter Clausen }
3463b1cae7cSLars-Peter Clausen /* Read voltage */
3473b1cae7cSLars-Peter Clausen ret = i2c_smbus_read_word_swapped(chip->client,
3483b1cae7cSLars-Peter Clausen AD7291_VOLTAGE);
3493b1cae7cSLars-Peter Clausen if (ret < 0) {
3503b1cae7cSLars-Peter Clausen mutex_unlock(&chip->state_lock);
3513b1cae7cSLars-Peter Clausen return ret;
3523b1cae7cSLars-Peter Clausen }
3533b1cae7cSLars-Peter Clausen *val = ret & AD7291_VALUE_MASK;
3543b1cae7cSLars-Peter Clausen mutex_unlock(&chip->state_lock);
3553b1cae7cSLars-Peter Clausen return IIO_VAL_INT;
3563b1cae7cSLars-Peter Clausen case IIO_TEMP:
3573b1cae7cSLars-Peter Clausen /* Assumes tsense bit of command register always set */
3583b1cae7cSLars-Peter Clausen ret = i2c_smbus_read_word_swapped(chip->client,
3593b1cae7cSLars-Peter Clausen AD7291_T_SENSE);
3603b1cae7cSLars-Peter Clausen if (ret < 0)
3613b1cae7cSLars-Peter Clausen return ret;
3623b1cae7cSLars-Peter Clausen *val = sign_extend32(ret, 11);
3633b1cae7cSLars-Peter Clausen return IIO_VAL_INT;
3643b1cae7cSLars-Peter Clausen default:
3653b1cae7cSLars-Peter Clausen return -EINVAL;
3663b1cae7cSLars-Peter Clausen }
3673b1cae7cSLars-Peter Clausen case IIO_CHAN_INFO_AVERAGE_RAW:
3683b1cae7cSLars-Peter Clausen ret = i2c_smbus_read_word_swapped(chip->client,
3693b1cae7cSLars-Peter Clausen AD7291_T_AVERAGE);
3703b1cae7cSLars-Peter Clausen if (ret < 0)
3713b1cae7cSLars-Peter Clausen return ret;
3723b1cae7cSLars-Peter Clausen *val = sign_extend32(ret, 11);
3733b1cae7cSLars-Peter Clausen return IIO_VAL_INT;
3743b1cae7cSLars-Peter Clausen case IIO_CHAN_INFO_SCALE:
3753b1cae7cSLars-Peter Clausen switch (chan->type) {
3763b1cae7cSLars-Peter Clausen case IIO_VOLTAGE:
3773b1cae7cSLars-Peter Clausen if (chip->reg) {
3783b1cae7cSLars-Peter Clausen int vref;
3793b1cae7cSLars-Peter Clausen
3803b1cae7cSLars-Peter Clausen vref = regulator_get_voltage(chip->reg);
3813b1cae7cSLars-Peter Clausen if (vref < 0)
3823b1cae7cSLars-Peter Clausen return vref;
3833b1cae7cSLars-Peter Clausen *val = vref / 1000;
3843b1cae7cSLars-Peter Clausen } else {
3853b1cae7cSLars-Peter Clausen *val = 2500;
3863b1cae7cSLars-Peter Clausen }
3873b1cae7cSLars-Peter Clausen *val2 = AD7291_BITS;
3883b1cae7cSLars-Peter Clausen return IIO_VAL_FRACTIONAL_LOG2;
3893b1cae7cSLars-Peter Clausen case IIO_TEMP:
3903b1cae7cSLars-Peter Clausen /*
3913b1cae7cSLars-Peter Clausen * One LSB of the ADC corresponds to 0.25 deg C.
3923b1cae7cSLars-Peter Clausen * The temperature reading is in 12-bit twos
3933b1cae7cSLars-Peter Clausen * complement format
3943b1cae7cSLars-Peter Clausen */
3953b1cae7cSLars-Peter Clausen *val = 250;
3963b1cae7cSLars-Peter Clausen return IIO_VAL_INT;
3973b1cae7cSLars-Peter Clausen default:
3983b1cae7cSLars-Peter Clausen return -EINVAL;
3993b1cae7cSLars-Peter Clausen }
4003b1cae7cSLars-Peter Clausen default:
4013b1cae7cSLars-Peter Clausen return -EINVAL;
4023b1cae7cSLars-Peter Clausen }
4033b1cae7cSLars-Peter Clausen }
4043b1cae7cSLars-Peter Clausen
4053b1cae7cSLars-Peter Clausen static const struct iio_event_spec ad7291_events[] = {
4063b1cae7cSLars-Peter Clausen {
4073b1cae7cSLars-Peter Clausen .type = IIO_EV_TYPE_THRESH,
4083b1cae7cSLars-Peter Clausen .dir = IIO_EV_DIR_RISING,
4093b1cae7cSLars-Peter Clausen .mask_separate = BIT(IIO_EV_INFO_VALUE) |
4103b1cae7cSLars-Peter Clausen BIT(IIO_EV_INFO_ENABLE),
4113b1cae7cSLars-Peter Clausen }, {
4123b1cae7cSLars-Peter Clausen .type = IIO_EV_TYPE_THRESH,
4133b1cae7cSLars-Peter Clausen .dir = IIO_EV_DIR_FALLING,
4143b1cae7cSLars-Peter Clausen .mask_separate = BIT(IIO_EV_INFO_VALUE) |
4153b1cae7cSLars-Peter Clausen BIT(IIO_EV_INFO_ENABLE),
4163b1cae7cSLars-Peter Clausen }, {
4173b1cae7cSLars-Peter Clausen .type = IIO_EV_TYPE_THRESH,
4183b1cae7cSLars-Peter Clausen .dir = IIO_EV_DIR_EITHER,
4193b1cae7cSLars-Peter Clausen .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS),
4203b1cae7cSLars-Peter Clausen },
4213b1cae7cSLars-Peter Clausen };
4223b1cae7cSLars-Peter Clausen
4233b1cae7cSLars-Peter Clausen #define AD7291_VOLTAGE_CHAN(_chan) \
4243b1cae7cSLars-Peter Clausen { \
4253b1cae7cSLars-Peter Clausen .type = IIO_VOLTAGE, \
4263b1cae7cSLars-Peter Clausen .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
4273b1cae7cSLars-Peter Clausen .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
4283b1cae7cSLars-Peter Clausen .indexed = 1, \
4293b1cae7cSLars-Peter Clausen .channel = _chan, \
4303b1cae7cSLars-Peter Clausen .event_spec = ad7291_events, \
4313b1cae7cSLars-Peter Clausen .num_event_specs = ARRAY_SIZE(ad7291_events), \
4323b1cae7cSLars-Peter Clausen }
4333b1cae7cSLars-Peter Clausen
4343b1cae7cSLars-Peter Clausen static const struct iio_chan_spec ad7291_channels[] = {
4353b1cae7cSLars-Peter Clausen AD7291_VOLTAGE_CHAN(0),
4363b1cae7cSLars-Peter Clausen AD7291_VOLTAGE_CHAN(1),
4373b1cae7cSLars-Peter Clausen AD7291_VOLTAGE_CHAN(2),
4383b1cae7cSLars-Peter Clausen AD7291_VOLTAGE_CHAN(3),
4393b1cae7cSLars-Peter Clausen AD7291_VOLTAGE_CHAN(4),
4403b1cae7cSLars-Peter Clausen AD7291_VOLTAGE_CHAN(5),
4413b1cae7cSLars-Peter Clausen AD7291_VOLTAGE_CHAN(6),
4423b1cae7cSLars-Peter Clausen AD7291_VOLTAGE_CHAN(7),
4433b1cae7cSLars-Peter Clausen {
4443b1cae7cSLars-Peter Clausen .type = IIO_TEMP,
4453b1cae7cSLars-Peter Clausen .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
4463b1cae7cSLars-Peter Clausen BIT(IIO_CHAN_INFO_AVERAGE_RAW) |
4473b1cae7cSLars-Peter Clausen BIT(IIO_CHAN_INFO_SCALE),
4483b1cae7cSLars-Peter Clausen .indexed = 1,
4493b1cae7cSLars-Peter Clausen .channel = 0,
4503b1cae7cSLars-Peter Clausen .event_spec = ad7291_events,
4513b1cae7cSLars-Peter Clausen .num_event_specs = ARRAY_SIZE(ad7291_events),
4523b1cae7cSLars-Peter Clausen }
4533b1cae7cSLars-Peter Clausen };
4543b1cae7cSLars-Peter Clausen
4553b1cae7cSLars-Peter Clausen static const struct iio_info ad7291_info = {
4563b1cae7cSLars-Peter Clausen .read_raw = &ad7291_read_raw,
4573b1cae7cSLars-Peter Clausen .read_event_config = &ad7291_read_event_config,
4583b1cae7cSLars-Peter Clausen .write_event_config = &ad7291_write_event_config,
4593b1cae7cSLars-Peter Clausen .read_event_value = &ad7291_read_event_value,
4603b1cae7cSLars-Peter Clausen .write_event_value = &ad7291_write_event_value,
4613b1cae7cSLars-Peter Clausen };
4623b1cae7cSLars-Peter Clausen
ad7291_reg_disable(void * reg)4633cc2fd27SAlexandru Ardelean static void ad7291_reg_disable(void *reg)
4643cc2fd27SAlexandru Ardelean {
4653cc2fd27SAlexandru Ardelean regulator_disable(reg);
4663cc2fd27SAlexandru Ardelean }
4673cc2fd27SAlexandru Ardelean
ad7291_probe(struct i2c_client * client)4683ff5dd78SUwe Kleine-König static int ad7291_probe(struct i2c_client *client)
4693b1cae7cSLars-Peter Clausen {
4703ff5dd78SUwe Kleine-König const struct i2c_device_id *id = i2c_client_get_device_id(client);
4713b1cae7cSLars-Peter Clausen struct ad7291_chip_info *chip;
4723b1cae7cSLars-Peter Clausen struct iio_dev *indio_dev;
473db7c17ecSGreg Kroah-Hartman int ret;
4743b1cae7cSLars-Peter Clausen
4753b1cae7cSLars-Peter Clausen indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
4763b1cae7cSLars-Peter Clausen if (!indio_dev)
4773b1cae7cSLars-Peter Clausen return -ENOMEM;
4783b1cae7cSLars-Peter Clausen chip = iio_priv(indio_dev);
4793b1cae7cSLars-Peter Clausen
4803b1cae7cSLars-Peter Clausen mutex_init(&chip->state_lock);
4813b1cae7cSLars-Peter Clausen
4823b1cae7cSLars-Peter Clausen chip->client = client;
4833b1cae7cSLars-Peter Clausen
4843b1cae7cSLars-Peter Clausen chip->command = AD7291_NOISE_DELAY |
4853b1cae7cSLars-Peter Clausen AD7291_T_SENSE_MASK | /* Tsense always enabled */
4863b1cae7cSLars-Peter Clausen AD7291_ALERT_POLARITY; /* set irq polarity low level */
4873b1cae7cSLars-Peter Clausen
48848404cf5SMichael Auchter chip->reg = devm_regulator_get_optional(&client->dev, "vref");
48948404cf5SMichael Auchter if (IS_ERR(chip->reg)) {
49048404cf5SMichael Auchter if (PTR_ERR(chip->reg) != -ENODEV)
49148404cf5SMichael Auchter return PTR_ERR(chip->reg);
49248404cf5SMichael Auchter
49348404cf5SMichael Auchter chip->reg = NULL;
49448404cf5SMichael Auchter }
49548404cf5SMichael Auchter
49648404cf5SMichael Auchter if (chip->reg) {
49748404cf5SMichael Auchter ret = regulator_enable(chip->reg);
49848404cf5SMichael Auchter if (ret)
49948404cf5SMichael Auchter return ret;
50048404cf5SMichael Auchter
5013cc2fd27SAlexandru Ardelean ret = devm_add_action_or_reset(&client->dev, ad7291_reg_disable,
5023cc2fd27SAlexandru Ardelean chip->reg);
5033cc2fd27SAlexandru Ardelean if (ret)
5043cc2fd27SAlexandru Ardelean return ret;
5053cc2fd27SAlexandru Ardelean
5063b1cae7cSLars-Peter Clausen chip->command |= AD7291_EXT_REF;
50748404cf5SMichael Auchter }
5083b1cae7cSLars-Peter Clausen
5093b1cae7cSLars-Peter Clausen indio_dev->name = id->name;
5103b1cae7cSLars-Peter Clausen indio_dev->channels = ad7291_channels;
5113b1cae7cSLars-Peter Clausen indio_dev->num_channels = ARRAY_SIZE(ad7291_channels);
5123b1cae7cSLars-Peter Clausen
5133b1cae7cSLars-Peter Clausen indio_dev->info = &ad7291_info;
5143b1cae7cSLars-Peter Clausen indio_dev->modes = INDIO_DIRECT_MODE;
5153b1cae7cSLars-Peter Clausen
5163b1cae7cSLars-Peter Clausen ret = ad7291_i2c_write(chip, AD7291_COMMAND, AD7291_RESET);
5173cc2fd27SAlexandru Ardelean if (ret)
5183cc2fd27SAlexandru Ardelean return -EIO;
5193b1cae7cSLars-Peter Clausen
5203b1cae7cSLars-Peter Clausen ret = ad7291_i2c_write(chip, AD7291_COMMAND, chip->command);
5213cc2fd27SAlexandru Ardelean if (ret)
5223cc2fd27SAlexandru Ardelean return -EIO;
5233b1cae7cSLars-Peter Clausen
5243b1cae7cSLars-Peter Clausen if (client->irq > 0) {
5253cc2fd27SAlexandru Ardelean ret = devm_request_threaded_irq(&client->dev, client->irq,
5263b1cae7cSLars-Peter Clausen NULL,
5273b1cae7cSLars-Peter Clausen &ad7291_event_handler,
5283b1cae7cSLars-Peter Clausen IRQF_TRIGGER_LOW | IRQF_ONESHOT,
5293b1cae7cSLars-Peter Clausen id->name,
5303b1cae7cSLars-Peter Clausen indio_dev);
5313b1cae7cSLars-Peter Clausen if (ret)
5323b1cae7cSLars-Peter Clausen return ret;
5333b1cae7cSLars-Peter Clausen }
5343b1cae7cSLars-Peter Clausen
5353cc2fd27SAlexandru Ardelean return devm_iio_device_register(&client->dev, indio_dev);
5363b1cae7cSLars-Peter Clausen }
5373b1cae7cSLars-Peter Clausen
5383b1cae7cSLars-Peter Clausen static const struct i2c_device_id ad7291_id[] = {
5393b1cae7cSLars-Peter Clausen { "ad7291", 0 },
5403b1cae7cSLars-Peter Clausen {}
5413b1cae7cSLars-Peter Clausen };
5423b1cae7cSLars-Peter Clausen
5433b1cae7cSLars-Peter Clausen MODULE_DEVICE_TABLE(i2c, ad7291_id);
5443b1cae7cSLars-Peter Clausen
54548404cf5SMichael Auchter static const struct of_device_id ad7291_of_match[] = {
54648404cf5SMichael Auchter { .compatible = "adi,ad7291" },
54748404cf5SMichael Auchter {}
54848404cf5SMichael Auchter };
54948404cf5SMichael Auchter MODULE_DEVICE_TABLE(of, ad7291_of_match);
55048404cf5SMichael Auchter
5513b1cae7cSLars-Peter Clausen static struct i2c_driver ad7291_driver = {
5523b1cae7cSLars-Peter Clausen .driver = {
5533b1cae7cSLars-Peter Clausen .name = KBUILD_MODNAME,
55448404cf5SMichael Auchter .of_match_table = ad7291_of_match,
5553b1cae7cSLars-Peter Clausen },
556*7cf15f42SUwe Kleine-König .probe = ad7291_probe,
5573b1cae7cSLars-Peter Clausen .id_table = ad7291_id,
5583b1cae7cSLars-Peter Clausen };
5593b1cae7cSLars-Peter Clausen module_i2c_driver(ad7291_driver);
5603b1cae7cSLars-Peter Clausen
5613b1cae7cSLars-Peter Clausen MODULE_AUTHOR("Sonic Zhang <sonic.zhang@analog.com>");
5623b1cae7cSLars-Peter Clausen MODULE_DESCRIPTION("Analog Devices AD7291 ADC driver");
5633b1cae7cSLars-Peter Clausen MODULE_LICENSE("GPL v2");
564