162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * ADS1100 - Texas Instruments Analog-to-Digital Converter
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2023, Topic Embedded Products
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Datasheet: https://www.ti.com/lit/gpn/ads1100
862306a36Sopenharmony_ci * IIO driver for ADS1100 and ADS1000 ADC 16-bit I2C
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/bitfield.h>
1262306a36Sopenharmony_ci#include <linux/bits.h>
1362306a36Sopenharmony_ci#include <linux/delay.h>
1462306a36Sopenharmony_ci#include <linux/module.h>
1562306a36Sopenharmony_ci#include <linux/init.h>
1662306a36Sopenharmony_ci#include <linux/i2c.h>
1762306a36Sopenharmony_ci#include <linux/mutex.h>
1862306a36Sopenharmony_ci#include <linux/property.h>
1962306a36Sopenharmony_ci#include <linux/pm_runtime.h>
2062306a36Sopenharmony_ci#include <linux/regulator/consumer.h>
2162306a36Sopenharmony_ci#include <linux/units.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include <linux/iio/iio.h>
2462306a36Sopenharmony_ci#include <linux/iio/types.h>
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci/* The ADS1100 has a single byte config register */
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/* Conversion in progress bit */
2962306a36Sopenharmony_ci#define ADS1100_CFG_ST_BSY	BIT(7)
3062306a36Sopenharmony_ci/* Single conversion bit */
3162306a36Sopenharmony_ci#define ADS1100_CFG_SC		BIT(4)
3262306a36Sopenharmony_ci/* Data rate */
3362306a36Sopenharmony_ci#define ADS1100_DR_MASK		GENMASK(3, 2)
3462306a36Sopenharmony_ci/* Gain */
3562306a36Sopenharmony_ci#define ADS1100_PGA_MASK	GENMASK(1, 0)
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define ADS1100_CONTINUOUS	0
3862306a36Sopenharmony_ci#define	ADS1100_SINGLESHOT	ADS1100_CFG_SC
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#define ADS1100_SLEEP_DELAY_MS	2000
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic const int ads1100_data_rate[] = { 128, 32, 16, 8 };
4362306a36Sopenharmony_cistatic const int ads1100_data_rate_bits[] = { 12, 14, 15, 16 };
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistruct ads1100_data {
4662306a36Sopenharmony_ci	struct i2c_client *client;
4762306a36Sopenharmony_ci	struct regulator *reg_vdd;
4862306a36Sopenharmony_ci	struct mutex lock;
4962306a36Sopenharmony_ci	int scale_avail[2 * 4]; /* 4 gain settings */
5062306a36Sopenharmony_ci	u8 config;
5162306a36Sopenharmony_ci	bool supports_data_rate; /* Only the ADS1100 can select the rate */
5262306a36Sopenharmony_ci};
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistatic const struct iio_chan_spec ads1100_channel = {
5562306a36Sopenharmony_ci	.type = IIO_VOLTAGE,
5662306a36Sopenharmony_ci	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
5762306a36Sopenharmony_ci	.info_mask_shared_by_all =
5862306a36Sopenharmony_ci	    BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
5962306a36Sopenharmony_ci	.info_mask_shared_by_all_available =
6062306a36Sopenharmony_ci	    BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
6162306a36Sopenharmony_ci	.scan_type = {
6262306a36Sopenharmony_ci		      .sign = 's',
6362306a36Sopenharmony_ci		      .realbits = 16,
6462306a36Sopenharmony_ci		      .storagebits = 16,
6562306a36Sopenharmony_ci		      .endianness = IIO_CPU,
6662306a36Sopenharmony_ci		       },
6762306a36Sopenharmony_ci	.datasheet_name = "AIN",
6862306a36Sopenharmony_ci};
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_cistatic int ads1100_set_config_bits(struct ads1100_data *data, u8 mask, u8 value)
7162306a36Sopenharmony_ci{
7262306a36Sopenharmony_ci	int ret;
7362306a36Sopenharmony_ci	u8 config = (data->config & ~mask) | (value & mask);
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	if (data->config == config)
7662306a36Sopenharmony_ci		return 0;	/* Already done */
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	ret = i2c_master_send(data->client, &config, 1);
7962306a36Sopenharmony_ci	if (ret < 0)
8062306a36Sopenharmony_ci		return ret;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	data->config = config;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	return 0;
8562306a36Sopenharmony_ci};
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cistatic int ads1100_data_bits(struct ads1100_data *data)
8862306a36Sopenharmony_ci{
8962306a36Sopenharmony_ci	return ads1100_data_rate_bits[FIELD_GET(ADS1100_DR_MASK, data->config)];
9062306a36Sopenharmony_ci}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic int ads1100_get_adc_result(struct ads1100_data *data, int chan, int *val)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	int ret;
9562306a36Sopenharmony_ci	__be16 buffer;
9662306a36Sopenharmony_ci	s16 value;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	if (chan != 0)
9962306a36Sopenharmony_ci		return -EINVAL;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	ret = pm_runtime_resume_and_get(&data->client->dev);
10262306a36Sopenharmony_ci	if (ret < 0)
10362306a36Sopenharmony_ci		return ret;
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ci	ret = i2c_master_recv(data->client, (char *)&buffer, sizeof(buffer));
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	pm_runtime_mark_last_busy(&data->client->dev);
10862306a36Sopenharmony_ci	pm_runtime_put_autosuspend(&data->client->dev);
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	if (ret < 0) {
11162306a36Sopenharmony_ci		dev_err(&data->client->dev, "I2C read fail: %d\n", ret);
11262306a36Sopenharmony_ci		return ret;
11362306a36Sopenharmony_ci	}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	/* Value is always 16-bit 2's complement */
11662306a36Sopenharmony_ci	value = be16_to_cpu(buffer);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci	/* Shift result to compensate for bit resolution vs. sample rate */
11962306a36Sopenharmony_ci	value <<= 16 - ads1100_data_bits(data);
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	*val = sign_extend32(value, 15);
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	return 0;
12462306a36Sopenharmony_ci}
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_cistatic int ads1100_set_scale(struct ads1100_data *data, int val, int val2)
12762306a36Sopenharmony_ci{
12862306a36Sopenharmony_ci	int microvolts;
12962306a36Sopenharmony_ci	int gain;
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	/* With Vdd between 2.7 and 5V, the scale is always below 1 */
13262306a36Sopenharmony_ci	if (val)
13362306a36Sopenharmony_ci		return -EINVAL;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	if (!val2)
13662306a36Sopenharmony_ci		return -EINVAL;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	microvolts = regulator_get_voltage(data->reg_vdd);
13962306a36Sopenharmony_ci	/*
14062306a36Sopenharmony_ci	 * val2 is in 'micro' units, n = val2 / 1000000
14162306a36Sopenharmony_ci	 * result must be millivolts, d = microvolts / 1000
14262306a36Sopenharmony_ci	 * the full-scale value is d/n, corresponds to 2^15,
14362306a36Sopenharmony_ci	 * hence the gain = (d / n) >> 15, factoring out the 1000 and moving the
14462306a36Sopenharmony_ci	 * bitshift so everything fits in 32-bits yields this formula.
14562306a36Sopenharmony_ci	 */
14662306a36Sopenharmony_ci	gain = DIV_ROUND_CLOSEST(microvolts, BIT(15)) * MILLI / val2;
14762306a36Sopenharmony_ci	if (gain < BIT(0) || gain > BIT(3))
14862306a36Sopenharmony_ci		return -EINVAL;
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	ads1100_set_config_bits(data, ADS1100_PGA_MASK, ffs(gain) - 1);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	return 0;
15362306a36Sopenharmony_ci}
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistatic int ads1100_set_data_rate(struct ads1100_data *data, int chan, int rate)
15662306a36Sopenharmony_ci{
15762306a36Sopenharmony_ci	unsigned int i;
15862306a36Sopenharmony_ci	unsigned int size;
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci	size = data->supports_data_rate ? ARRAY_SIZE(ads1100_data_rate) : 1;
16162306a36Sopenharmony_ci	for (i = 0; i < size; i++) {
16262306a36Sopenharmony_ci		if (ads1100_data_rate[i] == rate)
16362306a36Sopenharmony_ci			return ads1100_set_config_bits(data, ADS1100_DR_MASK,
16462306a36Sopenharmony_ci						       FIELD_PREP(ADS1100_DR_MASK, i));
16562306a36Sopenharmony_ci	}
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	return -EINVAL;
16862306a36Sopenharmony_ci}
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_cistatic int ads1100_get_vdd_millivolts(struct ads1100_data *data)
17162306a36Sopenharmony_ci{
17262306a36Sopenharmony_ci	return regulator_get_voltage(data->reg_vdd) / (MICRO / MILLI);
17362306a36Sopenharmony_ci}
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_cistatic void ads1100_calc_scale_avail(struct ads1100_data *data)
17662306a36Sopenharmony_ci{
17762306a36Sopenharmony_ci	int millivolts = ads1100_get_vdd_millivolts(data);
17862306a36Sopenharmony_ci	unsigned int i;
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(data->scale_avail) / 2; i++) {
18162306a36Sopenharmony_ci		data->scale_avail[i * 2 + 0] = millivolts;
18262306a36Sopenharmony_ci		data->scale_avail[i * 2 + 1] = 15 + i;
18362306a36Sopenharmony_ci	}
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_cistatic int ads1100_read_avail(struct iio_dev *indio_dev,
18762306a36Sopenharmony_ci			      struct iio_chan_spec const *chan,
18862306a36Sopenharmony_ci			      const int **vals, int *type, int *length,
18962306a36Sopenharmony_ci			      long mask)
19062306a36Sopenharmony_ci{
19162306a36Sopenharmony_ci	struct ads1100_data *data = iio_priv(indio_dev);
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	if (chan->type != IIO_VOLTAGE)
19462306a36Sopenharmony_ci		return -EINVAL;
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	switch (mask) {
19762306a36Sopenharmony_ci	case IIO_CHAN_INFO_SAMP_FREQ:
19862306a36Sopenharmony_ci		*type = IIO_VAL_INT;
19962306a36Sopenharmony_ci		*vals = ads1100_data_rate;
20062306a36Sopenharmony_ci		if (data->supports_data_rate)
20162306a36Sopenharmony_ci			*length = ARRAY_SIZE(ads1100_data_rate);
20262306a36Sopenharmony_ci		else
20362306a36Sopenharmony_ci			*length = 1;
20462306a36Sopenharmony_ci		return IIO_AVAIL_LIST;
20562306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
20662306a36Sopenharmony_ci		*type = IIO_VAL_FRACTIONAL_LOG2;
20762306a36Sopenharmony_ci		*vals = data->scale_avail;
20862306a36Sopenharmony_ci		*length = ARRAY_SIZE(data->scale_avail);
20962306a36Sopenharmony_ci		return IIO_AVAIL_LIST;
21062306a36Sopenharmony_ci	default:
21162306a36Sopenharmony_ci		return -EINVAL;
21262306a36Sopenharmony_ci	}
21362306a36Sopenharmony_ci}
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_cistatic int ads1100_read_raw(struct iio_dev *indio_dev,
21662306a36Sopenharmony_ci			    struct iio_chan_spec const *chan, int *val,
21762306a36Sopenharmony_ci			    int *val2, long mask)
21862306a36Sopenharmony_ci{
21962306a36Sopenharmony_ci	int ret;
22062306a36Sopenharmony_ci	struct ads1100_data *data = iio_priv(indio_dev);
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_ci	mutex_lock(&data->lock);
22362306a36Sopenharmony_ci	switch (mask) {
22462306a36Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
22562306a36Sopenharmony_ci		ret = iio_device_claim_direct_mode(indio_dev);
22662306a36Sopenharmony_ci		if (ret)
22762306a36Sopenharmony_ci			break;
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci		ret = ads1100_get_adc_result(data, chan->address, val);
23062306a36Sopenharmony_ci		if (ret >= 0)
23162306a36Sopenharmony_ci			ret = IIO_VAL_INT;
23262306a36Sopenharmony_ci		iio_device_release_direct_mode(indio_dev);
23362306a36Sopenharmony_ci		break;
23462306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
23562306a36Sopenharmony_ci		/* full-scale is the supply voltage in millivolts */
23662306a36Sopenharmony_ci		*val = ads1100_get_vdd_millivolts(data);
23762306a36Sopenharmony_ci		*val2 = 15 + FIELD_GET(ADS1100_PGA_MASK, data->config);
23862306a36Sopenharmony_ci		ret = IIO_VAL_FRACTIONAL_LOG2;
23962306a36Sopenharmony_ci		break;
24062306a36Sopenharmony_ci	case IIO_CHAN_INFO_SAMP_FREQ:
24162306a36Sopenharmony_ci		*val = ads1100_data_rate[FIELD_GET(ADS1100_DR_MASK,
24262306a36Sopenharmony_ci						   data->config)];
24362306a36Sopenharmony_ci		ret = IIO_VAL_INT;
24462306a36Sopenharmony_ci		break;
24562306a36Sopenharmony_ci	default:
24662306a36Sopenharmony_ci		ret = -EINVAL;
24762306a36Sopenharmony_ci		break;
24862306a36Sopenharmony_ci	}
24962306a36Sopenharmony_ci	mutex_unlock(&data->lock);
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	return ret;
25262306a36Sopenharmony_ci}
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistatic int ads1100_write_raw(struct iio_dev *indio_dev,
25562306a36Sopenharmony_ci			     struct iio_chan_spec const *chan, int val,
25662306a36Sopenharmony_ci			     int val2, long mask)
25762306a36Sopenharmony_ci{
25862306a36Sopenharmony_ci	struct ads1100_data *data = iio_priv(indio_dev);
25962306a36Sopenharmony_ci	int ret;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	mutex_lock(&data->lock);
26262306a36Sopenharmony_ci	switch (mask) {
26362306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
26462306a36Sopenharmony_ci		ret = ads1100_set_scale(data, val, val2);
26562306a36Sopenharmony_ci		break;
26662306a36Sopenharmony_ci	case IIO_CHAN_INFO_SAMP_FREQ:
26762306a36Sopenharmony_ci		ret = ads1100_set_data_rate(data, chan->address, val);
26862306a36Sopenharmony_ci		break;
26962306a36Sopenharmony_ci	default:
27062306a36Sopenharmony_ci		ret = -EINVAL;
27162306a36Sopenharmony_ci		break;
27262306a36Sopenharmony_ci	}
27362306a36Sopenharmony_ci	mutex_unlock(&data->lock);
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	return ret;
27662306a36Sopenharmony_ci}
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_cistatic const struct iio_info ads1100_info = {
27962306a36Sopenharmony_ci	.read_avail = ads1100_read_avail,
28062306a36Sopenharmony_ci	.read_raw = ads1100_read_raw,
28162306a36Sopenharmony_ci	.write_raw = ads1100_write_raw,
28262306a36Sopenharmony_ci};
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_cistatic int ads1100_setup(struct ads1100_data *data)
28562306a36Sopenharmony_ci{
28662306a36Sopenharmony_ci	int ret;
28762306a36Sopenharmony_ci	u8 buffer[3];
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci	/* Setup continuous sampling mode at 8sps */
29062306a36Sopenharmony_ci	buffer[0] = ADS1100_DR_MASK | ADS1100_CONTINUOUS;
29162306a36Sopenharmony_ci	ret = i2c_master_send(data->client, buffer, 1);
29262306a36Sopenharmony_ci	if (ret < 0)
29362306a36Sopenharmony_ci		return ret;
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	ret = i2c_master_recv(data->client, buffer, sizeof(buffer));
29662306a36Sopenharmony_ci	if (ret < 0)
29762306a36Sopenharmony_ci		return ret;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	/* Config register returned in third byte, strip away the busy status */
30062306a36Sopenharmony_ci	data->config = buffer[2] & ~ADS1100_CFG_ST_BSY;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	/* Detect the sample rate capability by checking the DR bits */
30362306a36Sopenharmony_ci	data->supports_data_rate = FIELD_GET(ADS1100_DR_MASK, buffer[2]) != 0;
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	return 0;
30662306a36Sopenharmony_ci}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_cistatic void ads1100_reg_disable(void *reg)
30962306a36Sopenharmony_ci{
31062306a36Sopenharmony_ci	regulator_disable(reg);
31162306a36Sopenharmony_ci}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_cistatic void ads1100_disable_continuous(void *data)
31462306a36Sopenharmony_ci{
31562306a36Sopenharmony_ci	ads1100_set_config_bits(data, ADS1100_CFG_SC, ADS1100_SINGLESHOT);
31662306a36Sopenharmony_ci}
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_cistatic int ads1100_probe(struct i2c_client *client)
31962306a36Sopenharmony_ci{
32062306a36Sopenharmony_ci	struct iio_dev *indio_dev;
32162306a36Sopenharmony_ci	struct ads1100_data *data;
32262306a36Sopenharmony_ci	struct device *dev = &client->dev;
32362306a36Sopenharmony_ci	int ret;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
32662306a36Sopenharmony_ci	if (!indio_dev)
32762306a36Sopenharmony_ci		return -ENOMEM;
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	data = iio_priv(indio_dev);
33062306a36Sopenharmony_ci	dev_set_drvdata(dev, data);
33162306a36Sopenharmony_ci	data->client = client;
33262306a36Sopenharmony_ci	mutex_init(&data->lock);
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	indio_dev->name = "ads1100";
33562306a36Sopenharmony_ci	indio_dev->modes = INDIO_DIRECT_MODE;
33662306a36Sopenharmony_ci	indio_dev->channels = &ads1100_channel;
33762306a36Sopenharmony_ci	indio_dev->num_channels = 1;
33862306a36Sopenharmony_ci	indio_dev->info = &ads1100_info;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci	data->reg_vdd = devm_regulator_get(dev, "vdd");
34162306a36Sopenharmony_ci	if (IS_ERR(data->reg_vdd))
34262306a36Sopenharmony_ci		return dev_err_probe(dev, PTR_ERR(data->reg_vdd),
34362306a36Sopenharmony_ci				     "Failed to get vdd regulator\n");
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	ret = regulator_enable(data->reg_vdd);
34662306a36Sopenharmony_ci	if (ret < 0)
34762306a36Sopenharmony_ci		return dev_err_probe(dev, ret,
34862306a36Sopenharmony_ci				     "Failed to enable vdd regulator\n");
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	ret = devm_add_action_or_reset(dev, ads1100_reg_disable, data->reg_vdd);
35162306a36Sopenharmony_ci	if (ret)
35262306a36Sopenharmony_ci		return ret;
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	ret = ads1100_setup(data);
35562306a36Sopenharmony_ci	if (ret)
35662306a36Sopenharmony_ci		return dev_err_probe(dev, ret,
35762306a36Sopenharmony_ci				     "Failed to communicate with device\n");
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	ret = devm_add_action_or_reset(dev, ads1100_disable_continuous, data);
36062306a36Sopenharmony_ci	if (ret)
36162306a36Sopenharmony_ci		return ret;
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	ads1100_calc_scale_avail(data);
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	pm_runtime_set_autosuspend_delay(dev, ADS1100_SLEEP_DELAY_MS);
36662306a36Sopenharmony_ci	pm_runtime_use_autosuspend(dev);
36762306a36Sopenharmony_ci	pm_runtime_set_active(dev);
36862306a36Sopenharmony_ci	ret = devm_pm_runtime_enable(dev);
36962306a36Sopenharmony_ci	if (ret)
37062306a36Sopenharmony_ci		return dev_err_probe(dev, ret, "Failed to enable pm_runtime\n");
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	ret = devm_iio_device_register(dev, indio_dev);
37362306a36Sopenharmony_ci	if (ret)
37462306a36Sopenharmony_ci		return dev_err_probe(dev, ret,
37562306a36Sopenharmony_ci				     "Failed to register IIO device\n");
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	return 0;
37862306a36Sopenharmony_ci}
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_cistatic int ads1100_runtime_suspend(struct device *dev)
38162306a36Sopenharmony_ci{
38262306a36Sopenharmony_ci	struct ads1100_data *data = dev_get_drvdata(dev);
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	ads1100_set_config_bits(data, ADS1100_CFG_SC, ADS1100_SINGLESHOT);
38562306a36Sopenharmony_ci	regulator_disable(data->reg_vdd);
38662306a36Sopenharmony_ci
38762306a36Sopenharmony_ci	return 0;
38862306a36Sopenharmony_ci}
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_cistatic int ads1100_runtime_resume(struct device *dev)
39162306a36Sopenharmony_ci{
39262306a36Sopenharmony_ci	struct ads1100_data *data = dev_get_drvdata(dev);
39362306a36Sopenharmony_ci	int ret;
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	ret = regulator_enable(data->reg_vdd);
39662306a36Sopenharmony_ci	if (ret) {
39762306a36Sopenharmony_ci		dev_err(&data->client->dev, "Failed to enable Vdd\n");
39862306a36Sopenharmony_ci		return ret;
39962306a36Sopenharmony_ci	}
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	/*
40262306a36Sopenharmony_ci	 * We'll always change the mode bit in the config register, so there is
40362306a36Sopenharmony_ci	 * no need here to "force" a write to the config register. If the device
40462306a36Sopenharmony_ci	 * has been power-cycled, we'll re-write its config register now.
40562306a36Sopenharmony_ci	 */
40662306a36Sopenharmony_ci	return ads1100_set_config_bits(data, ADS1100_CFG_SC,
40762306a36Sopenharmony_ci				       ADS1100_CONTINUOUS);
40862306a36Sopenharmony_ci}
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_cistatic DEFINE_RUNTIME_DEV_PM_OPS(ads1100_pm_ops,
41162306a36Sopenharmony_ci				 ads1100_runtime_suspend,
41262306a36Sopenharmony_ci				 ads1100_runtime_resume,
41362306a36Sopenharmony_ci				 NULL);
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_cistatic const struct i2c_device_id ads1100_id[] = {
41662306a36Sopenharmony_ci	{ "ads1100" },
41762306a36Sopenharmony_ci	{ "ads1000" },
41862306a36Sopenharmony_ci	{ }
41962306a36Sopenharmony_ci};
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, ads1100_id);
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_cistatic const struct of_device_id ads1100_of_match[] = {
42462306a36Sopenharmony_ci	{.compatible = "ti,ads1100" },
42562306a36Sopenharmony_ci	{.compatible = "ti,ads1000" },
42662306a36Sopenharmony_ci	{ }
42762306a36Sopenharmony_ci};
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, ads1100_of_match);
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_cistatic struct i2c_driver ads1100_driver = {
43262306a36Sopenharmony_ci	.driver = {
43362306a36Sopenharmony_ci		   .name = "ads1100",
43462306a36Sopenharmony_ci		   .of_match_table = ads1100_of_match,
43562306a36Sopenharmony_ci		   .pm = pm_ptr(&ads1100_pm_ops),
43662306a36Sopenharmony_ci	},
43762306a36Sopenharmony_ci	.probe = ads1100_probe,
43862306a36Sopenharmony_ci	.id_table = ads1100_id,
43962306a36Sopenharmony_ci};
44062306a36Sopenharmony_ci
44162306a36Sopenharmony_cimodule_i2c_driver(ads1100_driver);
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ciMODULE_AUTHOR("Mike Looijmans <mike.looijmans@topic.nl>");
44462306a36Sopenharmony_ciMODULE_DESCRIPTION("Texas Instruments ADS1100 ADC driver");
44562306a36Sopenharmony_ciMODULE_LICENSE("GPL");
446