xref: /linux/drivers/iio/potentiostat/lmp91000.c (revision 353b7a55dcaf5fb8758e09ebe2ddf5f3adbac7c5)
1d6ad8058SMatt Ranostay // SPDX-License-Identifier: GPL-2.0+
267e17300SMatt Ranostay /*
367e17300SMatt Ranostay  * lmp91000.c - Support for Texas Instruments digital potentiostats
467e17300SMatt Ranostay  *
5d6ad8058SMatt Ranostay  * Copyright (C) 2016, 2018
6d6ad8058SMatt Ranostay  * Author: Matt Ranostay <matt.ranostay@konsulko.com>
767e17300SMatt Ranostay  *
867e17300SMatt Ranostay  * TODO: bias voltage + polarity control, and multiple chip support
967e17300SMatt Ranostay  */
1067e17300SMatt Ranostay 
1167e17300SMatt Ranostay #include <linux/module.h>
1267e17300SMatt Ranostay #include <linux/i2c.h>
1367e17300SMatt Ranostay #include <linux/delay.h>
144c55fb8cSJonathan Cameron #include <linux/mod_devicetable.h>
1567e17300SMatt Ranostay #include <linux/regmap.h>
1667e17300SMatt Ranostay #include <linux/iio/iio.h>
1767e17300SMatt Ranostay #include <linux/iio/buffer.h>
1867e17300SMatt Ranostay #include <linux/iio/consumer.h>
1967e17300SMatt Ranostay #include <linux/iio/trigger.h>
2067e17300SMatt Ranostay #include <linux/iio/trigger_consumer.h>
2167e17300SMatt Ranostay #include <linux/iio/triggered_buffer.h>
2267e17300SMatt Ranostay 
2367e17300SMatt Ranostay #define LMP91000_REG_LOCK		0x01
2467e17300SMatt Ranostay #define LMP91000_REG_TIACN		0x10
2567e17300SMatt Ranostay #define LMP91000_REG_TIACN_GAIN_SHIFT	2
2667e17300SMatt Ranostay 
2767e17300SMatt Ranostay #define LMP91000_REG_REFCN		0x11
2867e17300SMatt Ranostay #define LMP91000_REG_REFCN_EXT_REF	0x20
2967e17300SMatt Ranostay #define LMP91000_REG_REFCN_50_ZERO	0x80
3067e17300SMatt Ranostay 
3167e17300SMatt Ranostay #define LMP91000_REG_MODECN		0x12
3267e17300SMatt Ranostay #define LMP91000_REG_MODECN_3LEAD	0x03
3367e17300SMatt Ranostay #define LMP91000_REG_MODECN_TEMP	0x07
3467e17300SMatt Ranostay 
3567e17300SMatt Ranostay #define LMP91000_DRV_NAME	"lmp91000"
3667e17300SMatt Ranostay 
3767e17300SMatt Ranostay static const int lmp91000_tia_gain[] = { 0, 2750, 3500, 7000, 14000, 35000,
3867e17300SMatt Ranostay 					 120000, 350000 };
3967e17300SMatt Ranostay 
4067e17300SMatt Ranostay static const int lmp91000_rload[] = { 10, 33, 50, 100 };
4167e17300SMatt Ranostay 
4267e17300SMatt Ranostay #define LMP91000_TEMP_BASE	-40
4367e17300SMatt Ranostay 
4467e17300SMatt Ranostay static const u16 lmp91000_temp_lut[] = {
4567e17300SMatt Ranostay 	1875, 1867, 1860, 1852, 1844, 1836, 1828, 1821, 1813, 1805,
4667e17300SMatt Ranostay 	1797, 1789, 1782, 1774, 1766, 1758, 1750, 1742, 1734, 1727,
4767e17300SMatt Ranostay 	1719, 1711, 1703, 1695, 1687, 1679, 1671, 1663, 1656, 1648,
4867e17300SMatt Ranostay 	1640, 1632, 1624, 1616, 1608, 1600, 1592, 1584, 1576, 1568,
4967e17300SMatt Ranostay 	1560, 1552, 1544, 1536, 1528, 1520, 1512, 1504, 1496, 1488,
5067e17300SMatt Ranostay 	1480, 1472, 1464, 1456, 1448, 1440, 1432, 1424, 1415, 1407,
5167e17300SMatt Ranostay 	1399, 1391, 1383, 1375, 1367, 1359, 1351, 1342, 1334, 1326,
5267e17300SMatt Ranostay 	1318, 1310, 1302, 1293, 1285, 1277, 1269, 1261, 1253, 1244,
5367e17300SMatt Ranostay 	1236, 1228, 1220, 1212, 1203, 1195, 1187, 1179, 1170, 1162,
5467e17300SMatt Ranostay 	1154, 1146, 1137, 1129, 1121, 1112, 1104, 1096, 1087, 1079,
5567e17300SMatt Ranostay 	1071, 1063, 1054, 1046, 1038, 1029, 1021, 1012, 1004,  996,
5667e17300SMatt Ranostay 	 987,  979,  971,  962,  954,  945,  937,  929,  920,  912,
5767e17300SMatt Ranostay 	 903,  895,  886,  878,  870,  861 };
5867e17300SMatt Ranostay 
5967e17300SMatt Ranostay static const struct regmap_config lmp91000_regmap_config = {
6067e17300SMatt Ranostay 	.reg_bits = 8,
6167e17300SMatt Ranostay 	.val_bits = 8,
6267e17300SMatt Ranostay };
6367e17300SMatt Ranostay 
6467e17300SMatt Ranostay struct lmp91000_data {
6567e17300SMatt Ranostay 	struct regmap *regmap;
6667e17300SMatt Ranostay 	struct device *dev;
6767e17300SMatt Ranostay 
6867e17300SMatt Ranostay 	struct iio_trigger *trig;
6967e17300SMatt Ranostay 	struct iio_cb_buffer *cb_buffer;
7067e17300SMatt Ranostay 	struct iio_channel *adc_chan;
7167e17300SMatt Ranostay 
7267e17300SMatt Ranostay 	struct completion completion;
7367e17300SMatt Ranostay 	u8 chan_select;
74*8979b67eSJonathan Cameron 	/* 64-bit data + 64-bit naturally aligned timestamp */
75*8979b67eSJonathan Cameron 	u32 buffer[4] __aligned(8);
7667e17300SMatt Ranostay };
7767e17300SMatt Ranostay 
7867e17300SMatt Ranostay static const struct iio_chan_spec lmp91000_channels[] = {
7967e17300SMatt Ranostay 	{ /* chemical channel mV */
8067e17300SMatt Ranostay 		.type = IIO_VOLTAGE,
8167e17300SMatt Ranostay 		.channel = 0,
8267e17300SMatt Ranostay 		.address = LMP91000_REG_MODECN_3LEAD,
8367e17300SMatt Ranostay 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
8467e17300SMatt Ranostay 				      BIT(IIO_CHAN_INFO_OFFSET) |
8567e17300SMatt Ranostay 				      BIT(IIO_CHAN_INFO_SCALE),
8667e17300SMatt Ranostay 		.scan_index = 0,
8767e17300SMatt Ranostay 		.scan_type = {
8867e17300SMatt Ranostay 			.sign = 's',
8967e17300SMatt Ranostay 			.realbits = 32,
9067e17300SMatt Ranostay 			.storagebits = 32,
9167e17300SMatt Ranostay 		},
9267e17300SMatt Ranostay 	},
9367e17300SMatt Ranostay 	IIO_CHAN_SOFT_TIMESTAMP(1),
9467e17300SMatt Ranostay 	{ /* temperature channel mV */
9567e17300SMatt Ranostay 		.type = IIO_TEMP,
9667e17300SMatt Ranostay 		.channel = 1,
9767e17300SMatt Ranostay 		.address = LMP91000_REG_MODECN_TEMP,
9867e17300SMatt Ranostay 		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
9967e17300SMatt Ranostay 		.scan_index = -1,
10067e17300SMatt Ranostay 	},
10167e17300SMatt Ranostay };
10267e17300SMatt Ranostay 
10367e17300SMatt Ranostay static int lmp91000_read(struct lmp91000_data *data, int channel, int *val)
10467e17300SMatt Ranostay {
10567e17300SMatt Ranostay 	int state, ret;
10667e17300SMatt Ranostay 
10767e17300SMatt Ranostay 	ret = regmap_read(data->regmap, LMP91000_REG_MODECN, &state);
10867e17300SMatt Ranostay 	if (ret)
10967e17300SMatt Ranostay 		return -EINVAL;
11067e17300SMatt Ranostay 
11167e17300SMatt Ranostay 	ret = regmap_write(data->regmap, LMP91000_REG_MODECN, channel);
11267e17300SMatt Ranostay 	if (ret)
11367e17300SMatt Ranostay 		return -EINVAL;
11467e17300SMatt Ranostay 
11567e17300SMatt Ranostay 	/* delay till first temperature reading is complete */
116681ca447SLucas Oshiro 	if (state != channel && channel == LMP91000_REG_MODECN_TEMP)
11767e17300SMatt Ranostay 		usleep_range(3000, 4000);
11867e17300SMatt Ranostay 
11967e17300SMatt Ranostay 	data->chan_select = channel != LMP91000_REG_MODECN_3LEAD;
12067e17300SMatt Ranostay 
12167e17300SMatt Ranostay 	iio_trigger_poll_chained(data->trig);
12267e17300SMatt Ranostay 
12367e17300SMatt Ranostay 	ret = wait_for_completion_timeout(&data->completion, HZ);
12467e17300SMatt Ranostay 	reinit_completion(&data->completion);
12567e17300SMatt Ranostay 
12667e17300SMatt Ranostay 	if (!ret)
12767e17300SMatt Ranostay 		return -ETIMEDOUT;
12867e17300SMatt Ranostay 
12967e17300SMatt Ranostay 	*val = data->buffer[data->chan_select];
13067e17300SMatt Ranostay 
13167e17300SMatt Ranostay 	return 0;
13267e17300SMatt Ranostay }
13367e17300SMatt Ranostay 
13467e17300SMatt Ranostay static irqreturn_t lmp91000_buffer_handler(int irq, void *private)
13567e17300SMatt Ranostay {
13667e17300SMatt Ranostay 	struct iio_poll_func *pf = private;
13767e17300SMatt Ranostay 	struct iio_dev *indio_dev = pf->indio_dev;
13867e17300SMatt Ranostay 	struct lmp91000_data *data = iio_priv(indio_dev);
13967e17300SMatt Ranostay 	int ret, val;
14067e17300SMatt Ranostay 
14167e17300SMatt Ranostay 	memset(data->buffer, 0, sizeof(data->buffer));
14267e17300SMatt Ranostay 
14367e17300SMatt Ranostay 	ret = lmp91000_read(data, LMP91000_REG_MODECN_3LEAD, &val);
14467e17300SMatt Ranostay 	if (!ret) {
14567e17300SMatt Ranostay 		data->buffer[0] = val;
14667e17300SMatt Ranostay 		iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
14767e17300SMatt Ranostay 						   iio_get_time_ns(indio_dev));
14867e17300SMatt Ranostay 	}
14967e17300SMatt Ranostay 
15067e17300SMatt Ranostay 	iio_trigger_notify_done(indio_dev->trig);
15167e17300SMatt Ranostay 
15267e17300SMatt Ranostay 	return IRQ_HANDLED;
15367e17300SMatt Ranostay }
15467e17300SMatt Ranostay 
15567e17300SMatt Ranostay static int lmp91000_read_raw(struct iio_dev *indio_dev,
15667e17300SMatt Ranostay 			     struct iio_chan_spec const *chan,
15767e17300SMatt Ranostay 			     int *val, int *val2, long mask)
15867e17300SMatt Ranostay {
15967e17300SMatt Ranostay 	struct lmp91000_data *data = iio_priv(indio_dev);
16067e17300SMatt Ranostay 
16167e17300SMatt Ranostay 	switch (mask) {
16267e17300SMatt Ranostay 	case IIO_CHAN_INFO_RAW:
16367e17300SMatt Ranostay 	case IIO_CHAN_INFO_PROCESSED: {
16467e17300SMatt Ranostay 		int ret = iio_channel_start_all_cb(data->cb_buffer);
16567e17300SMatt Ranostay 
16667e17300SMatt Ranostay 		if (ret)
16767e17300SMatt Ranostay 			return ret;
16867e17300SMatt Ranostay 
16967e17300SMatt Ranostay 		ret = lmp91000_read(data, chan->address, val);
17067e17300SMatt Ranostay 
17167e17300SMatt Ranostay 		iio_channel_stop_all_cb(data->cb_buffer);
17267e17300SMatt Ranostay 
17367e17300SMatt Ranostay 		if (ret)
17467e17300SMatt Ranostay 			return ret;
17567e17300SMatt Ranostay 
17667e17300SMatt Ranostay 		if (mask == IIO_CHAN_INFO_PROCESSED) {
17767e17300SMatt Ranostay 			int tmp, i;
17867e17300SMatt Ranostay 
17967e17300SMatt Ranostay 			ret = iio_convert_raw_to_processed(data->adc_chan,
18067e17300SMatt Ranostay 							   *val, &tmp, 1);
18167e17300SMatt Ranostay 			if (ret)
18267e17300SMatt Ranostay 				return ret;
18367e17300SMatt Ranostay 
18467e17300SMatt Ranostay 			for (i = 0; i < ARRAY_SIZE(lmp91000_temp_lut); i++)
18567e17300SMatt Ranostay 				if (lmp91000_temp_lut[i] < tmp)
18667e17300SMatt Ranostay 					break;
18767e17300SMatt Ranostay 
18867e17300SMatt Ranostay 			*val = (LMP91000_TEMP_BASE + i) * 1000;
18967e17300SMatt Ranostay 		}
19067e17300SMatt Ranostay 		return IIO_VAL_INT;
19167e17300SMatt Ranostay 	}
19267e17300SMatt Ranostay 	case IIO_CHAN_INFO_OFFSET:
19367e17300SMatt Ranostay 		return iio_read_channel_offset(data->adc_chan, val, val2);
19467e17300SMatt Ranostay 	case IIO_CHAN_INFO_SCALE:
19567e17300SMatt Ranostay 		return iio_read_channel_scale(data->adc_chan, val, val2);
19667e17300SMatt Ranostay 	}
19767e17300SMatt Ranostay 
19867e17300SMatt Ranostay 	return -EINVAL;
19967e17300SMatt Ranostay }
20067e17300SMatt Ranostay 
20167e17300SMatt Ranostay static const struct iio_info lmp91000_info = {
20267e17300SMatt Ranostay 	.read_raw = lmp91000_read_raw,
20367e17300SMatt Ranostay };
20467e17300SMatt Ranostay 
20567e17300SMatt Ranostay static int lmp91000_read_config(struct lmp91000_data *data)
20667e17300SMatt Ranostay {
20767e17300SMatt Ranostay 	struct device *dev = data->dev;
20867e17300SMatt Ranostay 	unsigned int reg, val;
20967e17300SMatt Ranostay 	int i, ret;
21067e17300SMatt Ranostay 
2114c55fb8cSJonathan Cameron 	ret = device_property_read_u32(dev, "ti,tia-gain-ohm", &val);
21267e17300SMatt Ranostay 	if (ret) {
2134c55fb8cSJonathan Cameron 		if (!device_property_read_bool(dev, "ti,external-tia-resistor")) {
21471a7766bSAnderson Reis 			dev_err(dev, "no ti,tia-gain-ohm defined and external resistor not specified\n");
21567e17300SMatt Ranostay 			return ret;
21667e17300SMatt Ranostay 		}
217b11a89d5SAnderson Reis 		val = 0;
21867e17300SMatt Ranostay 	}
21967e17300SMatt Ranostay 
22067e17300SMatt Ranostay 	ret = -EINVAL;
22167e17300SMatt Ranostay 	for (i = 0; i < ARRAY_SIZE(lmp91000_tia_gain); i++) {
22267e17300SMatt Ranostay 		if (lmp91000_tia_gain[i] == val) {
22367e17300SMatt Ranostay 			reg = i << LMP91000_REG_TIACN_GAIN_SHIFT;
22467e17300SMatt Ranostay 			ret = 0;
22567e17300SMatt Ranostay 			break;
22667e17300SMatt Ranostay 		}
22767e17300SMatt Ranostay 	}
22867e17300SMatt Ranostay 
22967e17300SMatt Ranostay 	if (ret) {
23067e17300SMatt Ranostay 		dev_err(dev, "invalid ti,tia-gain-ohm %d\n", val);
23167e17300SMatt Ranostay 		return ret;
23267e17300SMatt Ranostay 	}
23367e17300SMatt Ranostay 
2344c55fb8cSJonathan Cameron 	ret = device_property_read_u32(dev, "ti,rload-ohm", &val);
23567e17300SMatt Ranostay 	if (ret) {
23667e17300SMatt Ranostay 		val = 100;
23767e17300SMatt Ranostay 		dev_info(dev, "no ti,rload-ohm defined, default to %d\n", val);
23867e17300SMatt Ranostay 	}
23967e17300SMatt Ranostay 
24067e17300SMatt Ranostay 	ret = -EINVAL;
24167e17300SMatt Ranostay 	for (i = 0; i < ARRAY_SIZE(lmp91000_rload); i++) {
24267e17300SMatt Ranostay 		if (lmp91000_rload[i] == val) {
24367e17300SMatt Ranostay 			reg |= i;
24467e17300SMatt Ranostay 			ret = 0;
24567e17300SMatt Ranostay 			break;
24667e17300SMatt Ranostay 		}
24767e17300SMatt Ranostay 	}
24867e17300SMatt Ranostay 
24967e17300SMatt Ranostay 	if (ret) {
25067e17300SMatt Ranostay 		dev_err(dev, "invalid ti,rload-ohm %d\n", val);
25167e17300SMatt Ranostay 		return ret;
25267e17300SMatt Ranostay 	}
25367e17300SMatt Ranostay 
25467e17300SMatt Ranostay 	regmap_write(data->regmap, LMP91000_REG_LOCK, 0);
25567e17300SMatt Ranostay 	regmap_write(data->regmap, LMP91000_REG_TIACN, reg);
256cd4779f1SAnderson Reis 	regmap_write(data->regmap, LMP91000_REG_REFCN,
257cd4779f1SAnderson Reis 		     LMP91000_REG_REFCN_EXT_REF | LMP91000_REG_REFCN_50_ZERO);
25867e17300SMatt Ranostay 	regmap_write(data->regmap, LMP91000_REG_LOCK, 1);
25967e17300SMatt Ranostay 
26067e17300SMatt Ranostay 	return 0;
26167e17300SMatt Ranostay }
26267e17300SMatt Ranostay 
26367e17300SMatt Ranostay static int lmp91000_buffer_cb(const void *val, void *private)
26467e17300SMatt Ranostay {
26567e17300SMatt Ranostay 	struct iio_dev *indio_dev = private;
26667e17300SMatt Ranostay 	struct lmp91000_data *data = iio_priv(indio_dev);
26767e17300SMatt Ranostay 
26867e17300SMatt Ranostay 	data->buffer[data->chan_select] = *((int *)val);
26967e17300SMatt Ranostay 	complete_all(&data->completion);
27067e17300SMatt Ranostay 
27167e17300SMatt Ranostay 	return 0;
27267e17300SMatt Ranostay }
27367e17300SMatt Ranostay 
27467e17300SMatt Ranostay static const struct iio_trigger_ops lmp91000_trigger_ops = {
27567e17300SMatt Ranostay };
27667e17300SMatt Ranostay 
277d7cf5f60SAlexandru Ardelean static int lmp91000_buffer_postenable(struct iio_dev *indio_dev)
27867e17300SMatt Ranostay {
27967e17300SMatt Ranostay 	struct lmp91000_data *data = iio_priv(indio_dev);
28067e17300SMatt Ranostay 
281f11d59d8SLars-Peter Clausen 	return iio_channel_start_all_cb(data->cb_buffer);
28267e17300SMatt Ranostay }
28367e17300SMatt Ranostay 
28467e17300SMatt Ranostay static int lmp91000_buffer_predisable(struct iio_dev *indio_dev)
28567e17300SMatt Ranostay {
28667e17300SMatt Ranostay 	struct lmp91000_data *data = iio_priv(indio_dev);
28767e17300SMatt Ranostay 
28867e17300SMatt Ranostay 	iio_channel_stop_all_cb(data->cb_buffer);
28967e17300SMatt Ranostay 
290f11d59d8SLars-Peter Clausen 	return 0;
29167e17300SMatt Ranostay }
29267e17300SMatt Ranostay 
29367e17300SMatt Ranostay static const struct iio_buffer_setup_ops lmp91000_buffer_setup_ops = {
294d7cf5f60SAlexandru Ardelean 	.postenable = lmp91000_buffer_postenable,
29567e17300SMatt Ranostay 	.predisable = lmp91000_buffer_predisable,
29667e17300SMatt Ranostay };
29767e17300SMatt Ranostay 
29867e17300SMatt Ranostay static int lmp91000_probe(struct i2c_client *client,
29967e17300SMatt Ranostay 			  const struct i2c_device_id *id)
30067e17300SMatt Ranostay {
30167e17300SMatt Ranostay 	struct device *dev = &client->dev;
30267e17300SMatt Ranostay 	struct lmp91000_data *data;
30367e17300SMatt Ranostay 	struct iio_dev *indio_dev;
30467e17300SMatt Ranostay 	int ret;
30567e17300SMatt Ranostay 
30667e17300SMatt Ranostay 	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
30767e17300SMatt Ranostay 	if (!indio_dev)
30867e17300SMatt Ranostay 		return -ENOMEM;
30967e17300SMatt Ranostay 
31067e17300SMatt Ranostay 	indio_dev->info = &lmp91000_info;
31167e17300SMatt Ranostay 	indio_dev->channels = lmp91000_channels;
31267e17300SMatt Ranostay 	indio_dev->num_channels = ARRAY_SIZE(lmp91000_channels);
31367e17300SMatt Ranostay 	indio_dev->name = LMP91000_DRV_NAME;
31467e17300SMatt Ranostay 	indio_dev->modes = INDIO_DIRECT_MODE;
31567e17300SMatt Ranostay 	i2c_set_clientdata(client, indio_dev);
31667e17300SMatt Ranostay 
31767e17300SMatt Ranostay 	data = iio_priv(indio_dev);
31867e17300SMatt Ranostay 	data->dev = dev;
31967e17300SMatt Ranostay 	data->regmap = devm_regmap_init_i2c(client, &lmp91000_regmap_config);
32067e17300SMatt Ranostay 	if (IS_ERR(data->regmap)) {
32167e17300SMatt Ranostay 		dev_err(dev, "regmap initialization failed.\n");
32267e17300SMatt Ranostay 		return PTR_ERR(data->regmap);
32367e17300SMatt Ranostay 	}
32467e17300SMatt Ranostay 
3254d031666SGwendal Grignou 	data->trig = devm_iio_trigger_alloc(dev, "%s-mux%d",
32615ea2878SJonathan Cameron 					    indio_dev->name,
32715ea2878SJonathan Cameron 					    iio_device_id(indio_dev));
32867e17300SMatt Ranostay 	if (!data->trig) {
32967e17300SMatt Ranostay 		dev_err(dev, "cannot allocate iio trigger.\n");
33067e17300SMatt Ranostay 		return -ENOMEM;
33167e17300SMatt Ranostay 	}
33267e17300SMatt Ranostay 
33367e17300SMatt Ranostay 	data->trig->ops = &lmp91000_trigger_ops;
33467e17300SMatt Ranostay 	init_completion(&data->completion);
33567e17300SMatt Ranostay 
33667e17300SMatt Ranostay 	ret = lmp91000_read_config(data);
33767e17300SMatt Ranostay 	if (ret)
33867e17300SMatt Ranostay 		return ret;
33967e17300SMatt Ranostay 
34067e17300SMatt Ranostay 	ret = iio_trigger_set_immutable(iio_channel_cb_get_iio_dev(data->cb_buffer),
34167e17300SMatt Ranostay 					data->trig);
34267e17300SMatt Ranostay 	if (ret) {
34367e17300SMatt Ranostay 		dev_err(dev, "cannot set immutable trigger.\n");
34467e17300SMatt Ranostay 		return ret;
34567e17300SMatt Ranostay 	}
34667e17300SMatt Ranostay 
34767e17300SMatt Ranostay 	ret = iio_trigger_register(data->trig);
34867e17300SMatt Ranostay 	if (ret) {
34967e17300SMatt Ranostay 		dev_err(dev, "cannot register iio trigger.\n");
35067e17300SMatt Ranostay 		return ret;
35167e17300SMatt Ranostay 	}
35267e17300SMatt Ranostay 
35367e17300SMatt Ranostay 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
35467e17300SMatt Ranostay 					 &lmp91000_buffer_handler,
35567e17300SMatt Ranostay 					 &lmp91000_buffer_setup_ops);
35667e17300SMatt Ranostay 	if (ret)
35767e17300SMatt Ranostay 		goto error_unreg_trigger;
35867e17300SMatt Ranostay 
35967e17300SMatt Ranostay 	data->cb_buffer = iio_channel_get_all_cb(dev, &lmp91000_buffer_cb,
36067e17300SMatt Ranostay 						 indio_dev);
36167e17300SMatt Ranostay 
36267e17300SMatt Ranostay 	if (IS_ERR(data->cb_buffer)) {
36367e17300SMatt Ranostay 		if (PTR_ERR(data->cb_buffer) == -ENODEV)
36467e17300SMatt Ranostay 			ret = -EPROBE_DEFER;
36567e17300SMatt Ranostay 		else
36667e17300SMatt Ranostay 			ret = PTR_ERR(data->cb_buffer);
36767e17300SMatt Ranostay 
36867e17300SMatt Ranostay 		goto error_unreg_buffer;
36967e17300SMatt Ranostay 	}
37067e17300SMatt Ranostay 
37167e17300SMatt Ranostay 	data->adc_chan = iio_channel_cb_get_channels(data->cb_buffer);
37267e17300SMatt Ranostay 
37367e17300SMatt Ranostay 	ret = iio_device_register(indio_dev);
37467e17300SMatt Ranostay 	if (ret)
37567e17300SMatt Ranostay 		goto error_unreg_cb_buffer;
37667e17300SMatt Ranostay 
37767e17300SMatt Ranostay 	return 0;
37867e17300SMatt Ranostay 
37967e17300SMatt Ranostay error_unreg_cb_buffer:
38067e17300SMatt Ranostay 	iio_channel_release_all_cb(data->cb_buffer);
38167e17300SMatt Ranostay 
38267e17300SMatt Ranostay error_unreg_buffer:
38367e17300SMatt Ranostay 	iio_triggered_buffer_cleanup(indio_dev);
38467e17300SMatt Ranostay 
38567e17300SMatt Ranostay error_unreg_trigger:
38667e17300SMatt Ranostay 	iio_trigger_unregister(data->trig);
38767e17300SMatt Ranostay 
38867e17300SMatt Ranostay 	return ret;
38967e17300SMatt Ranostay }
39067e17300SMatt Ranostay 
39167e17300SMatt Ranostay static int lmp91000_remove(struct i2c_client *client)
39267e17300SMatt Ranostay {
39367e17300SMatt Ranostay 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
39467e17300SMatt Ranostay 	struct lmp91000_data *data = iio_priv(indio_dev);
39567e17300SMatt Ranostay 
39667e17300SMatt Ranostay 	iio_device_unregister(indio_dev);
39767e17300SMatt Ranostay 
39867e17300SMatt Ranostay 	iio_channel_stop_all_cb(data->cb_buffer);
39967e17300SMatt Ranostay 	iio_channel_release_all_cb(data->cb_buffer);
40067e17300SMatt Ranostay 
40167e17300SMatt Ranostay 	iio_triggered_buffer_cleanup(indio_dev);
40267e17300SMatt Ranostay 	iio_trigger_unregister(data->trig);
40367e17300SMatt Ranostay 
40467e17300SMatt Ranostay 	return 0;
40567e17300SMatt Ranostay }
40667e17300SMatt Ranostay 
40767e17300SMatt Ranostay static const struct of_device_id lmp91000_of_match[] = {
40867e17300SMatt Ranostay 	{ .compatible = "ti,lmp91000", },
4090cb2aab8SMatt Ranostay 	{ .compatible = "ti,lmp91002", },
41067e17300SMatt Ranostay 	{ },
41167e17300SMatt Ranostay };
41267e17300SMatt Ranostay MODULE_DEVICE_TABLE(of, lmp91000_of_match);
41367e17300SMatt Ranostay 
41467e17300SMatt Ranostay static const struct i2c_device_id lmp91000_id[] = {
41567e17300SMatt Ranostay 	{ "lmp91000", 0 },
4160cb2aab8SMatt Ranostay 	{ "lmp91002", 0 },
41767e17300SMatt Ranostay 	{}
41867e17300SMatt Ranostay };
41967e17300SMatt Ranostay MODULE_DEVICE_TABLE(i2c, lmp91000_id);
42067e17300SMatt Ranostay 
42167e17300SMatt Ranostay static struct i2c_driver lmp91000_driver = {
42267e17300SMatt Ranostay 	.driver = {
42367e17300SMatt Ranostay 		.name = LMP91000_DRV_NAME,
4244c55fb8cSJonathan Cameron 		.of_match_table = lmp91000_of_match,
42567e17300SMatt Ranostay 	},
42667e17300SMatt Ranostay 	.probe = lmp91000_probe,
42767e17300SMatt Ranostay 	.remove = lmp91000_remove,
42867e17300SMatt Ranostay 	.id_table = lmp91000_id,
42967e17300SMatt Ranostay };
43067e17300SMatt Ranostay module_i2c_driver(lmp91000_driver);
43167e17300SMatt Ranostay 
432d6ad8058SMatt Ranostay MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
43367e17300SMatt Ranostay MODULE_DESCRIPTION("LMP91000 digital potentiostat");
43467e17300SMatt Ranostay MODULE_LICENSE("GPL");
435