linux/drivers/iio/adc/ti-ads1119.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Texas Instruments ADS1119 ADC driver.
 *
 * Copyright 2024 Toradex
 */

#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/dev_printk.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/iopoll.h>
#include <linux/i2c.h>
#include <linux/kernel.h>
#include <linux/math.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/units.h>

#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>

#define ADS1119_CMD_RESET		0x06
#define ADS1119_CMD_POWERDOWN		0x02
#define ADS1119_CMD_START_SYNC		0x08
#define ADS1119_CMD_RDATA		0x10
#define ADS1119_CMD_RREG_CONFIG		0x20
#define ADS1119_CMD_RREG_STATUS		0x24
#define ADS1119_CMD_WREG		0x40

#define ADS1119_CMD_RREG(reg)		(0x20 | (reg) << 2)

/* Config register */
#define ADS1119_REG_CONFIG	0x00
#define ADS1119_CONFIG_VREF_FIELD	BIT(0)
#define ADS1119_CONFIG_CM_FIELD		BIT(1)
#define ADS1119_CONFIG_DR_FIELD		GENMASK(3, 2)
#define ADS1119_CONFIG_GAIN_FIELD	BIT(4)
#define ADS1119_CONFIG_MUX_FIELD	GENMASK(7, 5)

#define ADS1119_VREF_INTERNAL	0
#define ADS1119_VREF_EXTERNAL	1
#define ADS1119_VREF_INTERNAL_VAL 2048000

#define ADS1119_CM_SINGLE	0
#define ADS1119_CM_CONTINUOUS	1

#define ADS1119_DR_20_SPS	0
#define ADS1119_DR_90_SPS	1
#define ADS1119_DR_330_SPS	2
#define ADS1119_DR_1000_SPS	3

#define ADS1119_GAIN_1	0
#define ADS1119_GAIN_4	1

#define ADS1119_MUX_AIN0_AIN1	0
#define ADS1119_MUX_AIN2_AIN3	1
#define ADS1119_MUX_AIN1_AIN2	2
#define ADS1119_MUX_AIN0	3
#define ADS1119_MUX_AIN1	4
#define ADS1119_MUX_AIN2	5
#define ADS1119_MUX_AIN3	6
#define ADS1119_MUX_SHORTED	7

/* Status register */
#define ADS1119_REG_STATUS	0x01
#define ADS1119_STATUS_DRDY_FIELD	BIT(7)

#define ADS1119_DEFAULT_GAIN		1
#define ADS1119_DEFAULT_DATARATE	20

#define ADS1119_SUSPEND_DELAY		2000

/* Timeout based on the minimum sample rate of 20 SPS (50000us) */
#define ADS1119_MAX_DRDY_TIMEOUT	85000

#define ADS1119_MAX_CHANNELS		7
#define ADS1119_MAX_SINGLE_CHANNELS	4

struct ads1119_channel_config {
	int gain;
	int datarate;
	int mux;
};

struct ads1119_state {
	struct completion completion;
	struct i2c_client *client;
	struct gpio_desc *reset_gpio;
	struct iio_trigger *trig;
	struct ads1119_channel_config *channels_cfg;
	unsigned int num_channels_cfg;
	unsigned int cached_config;
	int vref_uV;
};

static const char * const ads1119_power_supplies[] = {
	"avdd", "dvdd"
};

static const int ads1119_available_datarates[] = {
	20, 90, 330, 1000,
};

static const int ads1119_available_gains[] = {
	1, 1,
	1, 4,
};

static int ads1119_upd_cfg_reg(struct ads1119_state *st, unsigned int fields,
			       unsigned int val)
{
	unsigned int config = st->cached_config;
	int ret;

	config &= ~fields;
	config |= val;

	ret = i2c_smbus_write_byte_data(st->client, ADS1119_CMD_WREG, config);
	if (ret)
		return ret;

	st->cached_config = config;

	return 0;
}

static bool ads1119_data_ready(struct ads1119_state *st)
{
	int status;

	status = i2c_smbus_read_byte_data(st->client, ADS1119_CMD_RREG_STATUS);
	if (status < 0)
		return false;

	return FIELD_GET(ADS1119_STATUS_DRDY_FIELD, status);
}

static int ads1119_reset(struct ads1119_state *st)
{
	st->cached_config = 0;

	if (!st->reset_gpio)
		return i2c_smbus_write_byte(st->client, ADS1119_CMD_RESET);

	gpiod_set_value_cansleep(st->reset_gpio, 1);
	udelay(1);
	gpiod_set_value_cansleep(st->reset_gpio, 0);
	udelay(1);

	return 0;
}

static int ads1119_set_conv_mode(struct ads1119_state *st, bool continuous)
{
	unsigned int mode;

	if (continuous)
		mode = ADS1119_CM_CONTINUOUS;
	else
		mode = ADS1119_CM_SINGLE;

	return ads1119_upd_cfg_reg(st, ADS1119_CONFIG_CM_FIELD,
				   FIELD_PREP(ADS1119_CONFIG_CM_FIELD, mode));
}

static int ads1119_get_hw_gain(int gain)
{
	if (gain == 4)
		return ADS1119_GAIN_4;
	else
		return ADS1119_GAIN_1;
}

static int ads1119_get_hw_datarate(int datarate)
{
	switch (datarate) {
	case 90:
		return ADS1119_DR_90_SPS;
	case 330:
		return ADS1119_DR_330_SPS;
	case 1000:
		return ADS1119_DR_1000_SPS;
	case 20:
	default:
		return ADS1119_DR_20_SPS;
	}
}

static int ads1119_configure_channel(struct ads1119_state *st, int mux,
				     int gain, int datarate)
{
	int ret;

	ret = ads1119_upd_cfg_reg(st, ADS1119_CONFIG_MUX_FIELD,
				  FIELD_PREP(ADS1119_CONFIG_MUX_FIELD, mux));
	if (ret)
		return ret;

	ret = ads1119_upd_cfg_reg(st, ADS1119_CONFIG_GAIN_FIELD,
				  FIELD_PREP(ADS1119_CONFIG_GAIN_FIELD,
					     ads1119_get_hw_gain(gain)));
	if (ret)
		return ret;

	return ads1119_upd_cfg_reg(st, ADS1119_CONFIG_DR_FIELD,
				   FIELD_PREP(ADS1119_CONFIG_DR_FIELD,
					      ads1119_get_hw_datarate(datarate)));
}

static int ads1119_poll_data_ready(struct ads1119_state *st,
				   struct iio_chan_spec const *chan)
{
	unsigned int datarate = st->channels_cfg[chan->address].datarate;
	unsigned long wait_time;
	bool data_ready;

	/* Poll 5 times more than the data rate */
	wait_time = DIV_ROUND_CLOSEST(MICRO, 5 * datarate);

	return read_poll_timeout(ads1119_data_ready, data_ready,
				 data_ready, wait_time,
				 ADS1119_MAX_DRDY_TIMEOUT, false, st);
}

static int ads1119_read_data(struct ads1119_state *st,
			     struct iio_chan_spec const *chan,
			     unsigned int *val)
{
	unsigned int timeout;
	int ret = 0;

	timeout = msecs_to_jiffies(ADS1119_MAX_DRDY_TIMEOUT);

	if (!st->client->irq) {
		ret = ads1119_poll_data_ready(st, chan);
		if (ret)
			return ret;
	} else if (!wait_for_completion_timeout(&st->completion, timeout)) {
		return -ETIMEDOUT;
	}

	ret = i2c_smbus_read_word_swapped(st->client, ADS1119_CMD_RDATA);
	if (ret < 0)
		return ret;

	*val = ret;

	return 0;
}

static int ads1119_single_conversion(struct ads1119_state *st,
				     struct iio_chan_spec const *chan,
				     int *val,
				     bool calib_offset)
{
	struct device *dev = &st->client->dev;
	int mux = st->channels_cfg[chan->address].mux;
	int gain = st->channels_cfg[chan->address].gain;
	int datarate = st->channels_cfg[chan->address].datarate;
	unsigned int sample;
	int ret;

	if (calib_offset)
		mux = ADS1119_MUX_SHORTED;

	ret = pm_runtime_resume_and_get(dev);
	if (ret)
		goto pdown;

	ret = ads1119_configure_channel(st, mux, gain, datarate);
	if (ret)
		goto pdown;

	ret = i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC);
	if (ret)
		goto pdown;

	ret = ads1119_read_data(st, chan, &sample);
	if (ret)
		goto pdown;

	*val = sign_extend32(sample, chan->scan_type.realbits - 1);
	ret = IIO_VAL_INT;
pdown:
	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);
	return ret;
}

static int ads1119_validate_datarate(struct ads1119_state *st, int datarate)
{
	switch (datarate) {
	case 20:
	case 90:
	case 330:
	case 1000:
		return datarate;
	default:
		return -EINVAL;
	}
}

static int ads1119_read_avail(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan,
			      const int **vals, int *type, int *length,
			      long mask)
{
	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		*type = IIO_VAL_FRACTIONAL;
		*vals = ads1119_available_gains;
		*length = ARRAY_SIZE(ads1119_available_gains);
		return IIO_AVAIL_LIST;
	case IIO_CHAN_INFO_SAMP_FREQ:
		*type = IIO_VAL_INT;
		*vals = ads1119_available_datarates;
		*length = ARRAY_SIZE(ads1119_available_datarates);
		return IIO_AVAIL_LIST;
	default:
		return -EINVAL;
	}
}

static int ads1119_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int *val,
			    int *val2, long mask)
{
	struct ads1119_state *st = iio_priv(indio_dev);
	unsigned int index = chan->address;

	if (index >= st->num_channels_cfg)
		return -EINVAL;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		iio_device_claim_direct_scoped(return -EBUSY, indio_dev)
			return ads1119_single_conversion(st, chan, val, false);
		unreachable();
	case IIO_CHAN_INFO_OFFSET:
		iio_device_claim_direct_scoped(return -EBUSY, indio_dev)
			return ads1119_single_conversion(st, chan, val, true);
		unreachable();
	case IIO_CHAN_INFO_SCALE:
		*val = st->vref_uV / 1000;
		*val /= st->channels_cfg[index].gain;
		*val2 = chan->scan_type.realbits - 1;
		return IIO_VAL_FRACTIONAL_LOG2;
	case IIO_CHAN_INFO_SAMP_FREQ:
		*val = st->channels_cfg[index].datarate;
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int ads1119_write_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan, int val,
			     int val2, long mask)
{
	struct ads1119_state *st = iio_priv(indio_dev);
	unsigned int index = chan->address;
	int ret;

	if (index >= st->num_channels_cfg)
		return -EINVAL;

	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		ret = MICRO / ((val * MICRO) + val2);
		if (ret != 1 && ret != 4)
			return -EINVAL;

		st->channels_cfg[index].gain = ret;
		return 0;
	case IIO_CHAN_INFO_SAMP_FREQ:
		ret = ads1119_validate_datarate(st, val);
		if (ret < 0)
			return ret;

		st->channels_cfg[index].datarate = ret;
		return 0;
	default:
		return -EINVAL;
	}
}

static int ads1119_debugfs_reg_access(struct iio_dev *indio_dev,
				      unsigned int reg, unsigned int writeval,
				      unsigned int *readval)
{
	struct ads1119_state *st = iio_priv(indio_dev);
	int ret;

	if (reg > ADS1119_REG_STATUS)
		return -EINVAL;

	if (readval) {
		ret = i2c_smbus_read_byte_data(st->client,
					       ADS1119_CMD_RREG(reg));
		if (ret < 0)
			return ret;

		*readval = ret;
		return 0;
	}

	if (reg > ADS1119_REG_CONFIG)
		return -EINVAL;

	return i2c_smbus_write_byte_data(st->client, ADS1119_CMD_WREG,
					 writeval);
}

static const struct iio_info ads1119_info = {
	.read_avail = ads1119_read_avail,
	.read_raw = ads1119_read_raw,
	.write_raw = ads1119_write_raw,
	.debugfs_reg_access = ads1119_debugfs_reg_access,
};

static int ads1119_triggered_buffer_preenable(struct iio_dev *indio_dev)
{
	struct ads1119_state *st = iio_priv(indio_dev);
	struct device *dev = &st->client->dev;
	unsigned int index;
	int ret;

	index = find_first_bit(indio_dev->active_scan_mask,
			       iio_get_masklength(indio_dev));

	ret = ads1119_set_conv_mode(st, true);
	if (ret)
		return ret;

	ret = ads1119_configure_channel(st,
					st->channels_cfg[index].mux,
					st->channels_cfg[index].gain,
					st->channels_cfg[index].datarate);
	if (ret)
		return ret;

	ret = pm_runtime_resume_and_get(dev);
	if (ret)
		return ret;

	return i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC);
}

static int ads1119_triggered_buffer_postdisable(struct iio_dev *indio_dev)
{
	struct ads1119_state *st = iio_priv(indio_dev);
	struct device *dev = &st->client->dev;
	int ret;

	ret = ads1119_set_conv_mode(st, false);
	if (ret)
		return ret;

	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);

	return 0;
}

static const struct iio_buffer_setup_ops ads1119_buffer_setup_ops = {
	.preenable = ads1119_triggered_buffer_preenable,
	.postdisable = ads1119_triggered_buffer_postdisable,
	.validate_scan_mask = &iio_validate_scan_mask_onehot,
};

static const struct iio_trigger_ops ads1119_trigger_ops = {
	.validate_device = &iio_trigger_validate_own_device,
};

static irqreturn_t ads1119_irq_handler(int irq, void *dev_id)
{
	struct iio_dev *indio_dev = dev_id;
	struct ads1119_state *st = iio_priv(indio_dev);

	if (iio_buffer_enabled(indio_dev) && iio_trigger_using_own(indio_dev))
		iio_trigger_poll(indio_dev->trig);
	else
		complete(&st->completion);

	return IRQ_HANDLED;
}

static irqreturn_t ads1119_trigger_handler(int irq, void *private)
{
	struct iio_poll_func *pf = private;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct ads1119_state *st = iio_priv(indio_dev);
	struct {
		unsigned int sample;
		s64 timestamp __aligned(8);
	} scan;
	unsigned int index;
	int ret;

	if (!iio_trigger_using_own(indio_dev)) {
		index = find_first_bit(indio_dev->active_scan_mask,
				       iio_get_masklength(indio_dev));

		ret = ads1119_poll_data_ready(st, &indio_dev->channels[index]);
		if (ret) {
			dev_err(&st->client->dev,
				"Failed to poll data on trigger (%d)\n", ret);
			goto done;
		}
	}

	ret = i2c_smbus_read_word_swapped(st->client, ADS1119_CMD_RDATA);
	if (ret < 0) {
		dev_err(&st->client->dev,
			"Failed to read data on trigger (%d)\n", ret);
		goto done;
	}

	scan.sample = ret;

	iio_push_to_buffers_with_timestamp(indio_dev, &scan,
					   iio_get_time_ns(indio_dev));
done:
	iio_trigger_notify_done(indio_dev->trig);
	return IRQ_HANDLED;
}

static int ads1119_init(struct ads1119_state *st, bool vref_external)
{
	int ret;

	ret = ads1119_reset(st);
	if (ret)
		return ret;

	if (vref_external)
		return ads1119_upd_cfg_reg(st,
					   ADS1119_CONFIG_VREF_FIELD,
					   FIELD_PREP(ADS1119_CONFIG_VREF_FIELD,
						      ADS1119_VREF_EXTERNAL));
	return 0;
}

static int ads1119_map_analog_inputs_mux(int ain_pos, int ain_neg,
					 bool differential)
{
	if (ain_pos >= ADS1119_MAX_SINGLE_CHANNELS)
		return -EINVAL;

	if (!differential)
		return ADS1119_MUX_AIN0 + ain_pos;

	if (ain_pos == 0 && ain_neg == 1)
		return ADS1119_MUX_AIN0_AIN1;
	else if (ain_pos == 1 && ain_neg == 2)
		return ADS1119_MUX_AIN1_AIN2;
	else if (ain_pos == 2 && ain_neg == 3)
		return ADS1119_MUX_AIN2_AIN3;

	return -EINVAL;
}

static int ads1119_alloc_and_config_channels(struct iio_dev *indio_dev)
{
	const struct iio_chan_spec ads1119_channel =
		(const struct iio_chan_spec) {
		.type = IIO_VOLTAGE,
		.indexed = 1,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
		BIT(IIO_CHAN_INFO_SCALE) |
		BIT(IIO_CHAN_INFO_OFFSET) |
		BIT(IIO_CHAN_INFO_SAMP_FREQ),
		.info_mask_shared_by_all_available =
		BIT(IIO_CHAN_INFO_SCALE) |
		BIT(IIO_CHAN_INFO_SAMP_FREQ),
		.scan_type = {
			.sign = 's',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_CPU,
		},
	};
	const struct iio_chan_spec ads1119_ts = IIO_CHAN_SOFT_TIMESTAMP(0);
	struct ads1119_state *st = iio_priv(indio_dev);
	struct iio_chan_spec *iio_channels, *chan;
	struct device *dev = &st->client->dev;
	unsigned int num_channels, i;
	bool differential;
	u32 ain[2];
	int ret;

	st->num_channels_cfg = device_get_child_node_count(dev);
	if (st->num_channels_cfg > ADS1119_MAX_CHANNELS)
		return dev_err_probe(dev, -EINVAL,
				     "Too many channels %d, max is %d\n",
				     st->num_channels_cfg,
				     ADS1119_MAX_CHANNELS);

	st->channels_cfg = devm_kcalloc(dev, st->num_channels_cfg,
					sizeof(*st->channels_cfg), GFP_KERNEL);
	if (!st->channels_cfg)
		return -ENOMEM;

	/* Allocate one more iio channel for the timestamp */
	num_channels = st->num_channels_cfg + 1;
	iio_channels = devm_kcalloc(dev, num_channels, sizeof(*iio_channels),
				    GFP_KERNEL);
	if (!iio_channels)
		return -ENOMEM;

	i = 0;

	device_for_each_child_node_scoped(dev, child) {
		chan = &iio_channels[i];

		differential = fwnode_property_present(child, "diff-channels");
		if (differential)
			ret = fwnode_property_read_u32_array(child,
							     "diff-channels",
							     ain, 2);
		else
			ret = fwnode_property_read_u32(child, "single-channel",
						       &ain[0]);

		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to get channel property\n");

		ret = ads1119_map_analog_inputs_mux(ain[0], ain[1],
						    differential);
		if (ret < 0)
			return dev_err_probe(dev, ret,
					     "Invalid channel value\n");

		st->channels_cfg[i].mux = ret;
		st->channels_cfg[i].gain = ADS1119_DEFAULT_GAIN;
		st->channels_cfg[i].datarate = ADS1119_DEFAULT_DATARATE;

		*chan = ads1119_channel;
		chan->channel = ain[0];
		chan->address = i;
		chan->scan_index = i;

		if (differential) {
			chan->channel2 = ain[1];
			chan->differential = 1;
		}

		dev_dbg(dev, "channel: index %d, mux %d\n", i,
			st->channels_cfg[i].mux);

		i++;
	}

	iio_channels[i] = ads1119_ts;
	iio_channels[i].address = i;
	iio_channels[i].scan_index = i;

	indio_dev->channels = iio_channels;
	indio_dev->num_channels = num_channels;

	return 0;
}

static void ads1119_powerdown(void *data)
{
	struct ads1119_state *st = data;

	i2c_smbus_write_byte(st->client, ADS1119_CMD_POWERDOWN);
}

static int ads1119_probe(struct i2c_client *client)
{
	struct iio_dev *indio_dev;
	struct ads1119_state *st;
	struct device *dev = &client->dev;
	bool vref_external = true;
	int ret;

	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
	if (!indio_dev)
		return dev_err_probe(dev, -ENOMEM,
				     "Failed to allocate IIO device\n");

	st = iio_priv(indio_dev);
	st->client = client;

	indio_dev->name = "ads1119";
	indio_dev->info = &ads1119_info;
	indio_dev->modes = INDIO_DIRECT_MODE;

	i2c_set_clientdata(client, indio_dev);

	ret = devm_regulator_bulk_get_enable(dev,
					     ARRAY_SIZE(ads1119_power_supplies),
					     ads1119_power_supplies);
	if (ret)
		return dev_err_probe(dev, ret,
				     "Failed to get and enable supplies\n");

	st->vref_uV = devm_regulator_get_enable_read_voltage(dev, "vref");
	if (st->vref_uV == -ENODEV) {
		vref_external = false;
		st->vref_uV = ADS1119_VREF_INTERNAL_VAL;
	} else if (st->vref_uV < 0) {
		return dev_err_probe(dev, st->vref_uV, "Failed to get vref\n");
	}

	st->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(st->reset_gpio))
		return dev_err_probe(dev, PTR_ERR(st->reset_gpio),
				     "Failed to get reset gpio\n");

	ret = ads1119_alloc_and_config_channels(indio_dev);
	if (ret)
		return ret;

	init_completion(&st->completion);

	ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
					      ads1119_trigger_handler,
					      &ads1119_buffer_setup_ops);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to setup IIO buffer\n");

	if (client->irq > 0) {
		ret = devm_request_threaded_irq(dev, client->irq,
						ads1119_irq_handler,
						NULL, IRQF_ONESHOT,
						"ads1119", indio_dev);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to allocate irq\n");

		st->trig = devm_iio_trigger_alloc(dev, "%s-dev%d",
						  indio_dev->name,
						  iio_device_id(indio_dev));
		if (!st->trig)
			return dev_err_probe(dev, -ENOMEM,
					     "Failed to allocate IIO trigger\n");

		st->trig->ops = &ads1119_trigger_ops;
		iio_trigger_set_drvdata(st->trig, indio_dev);

		ret = devm_iio_trigger_register(dev, st->trig);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to register IIO trigger\n");
	}

	ret = ads1119_init(st, vref_external);
	if (ret)
		return dev_err_probe(dev, ret,
				     "Failed to initialize device\n");

	pm_runtime_set_autosuspend_delay(dev, ADS1119_SUSPEND_DELAY);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_mark_last_busy(dev);
	pm_runtime_set_active(dev);

	ret = devm_pm_runtime_enable(dev);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to enable pm runtime\n");

	ret = devm_add_action_or_reset(dev, ads1119_powerdown, st);
	if (ret)
		return dev_err_probe(dev, ret,
				     "Failed to add powerdown action\n");

	return devm_iio_device_register(dev, indio_dev);
}

static int ads1119_runtime_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
	struct ads1119_state *st = iio_priv(indio_dev);

	return i2c_smbus_write_byte(st->client, ADS1119_CMD_POWERDOWN);
}

/*
 * The ADS1119 does not require a resume function because it automatically
 * powers on after a reset.
 * After a power down command, the ADS1119 can still communicate but turns off
 * its analog parts. To resume from power down, the device will power up again
 * upon receiving a start/sync command.
 */
static DEFINE_RUNTIME_DEV_PM_OPS(ads1119_pm_ops, ads1119_runtime_suspend,
				 NULL, NULL);

static const struct of_device_id __maybe_unused ads1119_of_match[] = {
	{ .compatible = "ti,ads1119" },
	{ }
};
MODULE_DEVICE_TABLE(of, ads1119_of_match);

static const struct i2c_device_id ads1119_id[] = {
	{ "ads1119", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ads1119_id);

static struct i2c_driver ads1119_driver = {
	.driver = {
		.name = "ads1119",
		.of_match_table = ads1119_of_match,
		.pm = pm_ptr(&ads1119_pm_ops),
	},
	.probe = ads1119_probe,
	.id_table = ads1119_id,
};
module_i2c_driver(ads1119_driver);

MODULE_AUTHOR("João Paulo Gonçalves <[email protected]>");
MODULE_DESCRIPTION("Texas Instruments ADS1119 ADC Driver");
MODULE_LICENSE("GPL");