xref: /openbmc/linux/drivers/iio/adc/nau7802.c (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
1c51cb3f5SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
28b20be87SAlexandre Belloni /*
38b20be87SAlexandre Belloni  * Driver for the Nuvoton NAU7802 ADC
48b20be87SAlexandre Belloni  *
58b20be87SAlexandre Belloni  * Copyright 2013 Free Electrons
68b20be87SAlexandre Belloni  */
78b20be87SAlexandre Belloni 
88b20be87SAlexandre Belloni #include <linux/delay.h>
98b20be87SAlexandre Belloni #include <linux/i2c.h>
108b20be87SAlexandre Belloni #include <linux/interrupt.h>
11d34a1dafSAndy Shevchenko #include <linux/mod_devicetable.h>
128b20be87SAlexandre Belloni #include <linux/module.h>
13d34a1dafSAndy Shevchenko #include <linux/property.h>
148b20be87SAlexandre Belloni #include <linux/wait.h>
158b20be87SAlexandre Belloni #include <linux/log2.h>
168b20be87SAlexandre Belloni 
178b20be87SAlexandre Belloni #include <linux/iio/iio.h>
188b20be87SAlexandre Belloni #include <linux/iio/sysfs.h>
198b20be87SAlexandre Belloni 
208b20be87SAlexandre Belloni #define NAU7802_REG_PUCTRL	0x00
218b20be87SAlexandre Belloni #define NAU7802_PUCTRL_RR(x)		(x << 0)
228b20be87SAlexandre Belloni #define NAU7802_PUCTRL_RR_BIT		NAU7802_PUCTRL_RR(1)
238b20be87SAlexandre Belloni #define NAU7802_PUCTRL_PUD(x)		(x << 1)
248b20be87SAlexandre Belloni #define NAU7802_PUCTRL_PUD_BIT		NAU7802_PUCTRL_PUD(1)
258b20be87SAlexandre Belloni #define NAU7802_PUCTRL_PUA(x)		(x << 2)
268b20be87SAlexandre Belloni #define NAU7802_PUCTRL_PUA_BIT		NAU7802_PUCTRL_PUA(1)
278b20be87SAlexandre Belloni #define NAU7802_PUCTRL_PUR(x)		(x << 3)
288b20be87SAlexandre Belloni #define NAU7802_PUCTRL_PUR_BIT		NAU7802_PUCTRL_PUR(1)
298b20be87SAlexandre Belloni #define NAU7802_PUCTRL_CS(x)		(x << 4)
308b20be87SAlexandre Belloni #define NAU7802_PUCTRL_CS_BIT		NAU7802_PUCTRL_CS(1)
318b20be87SAlexandre Belloni #define NAU7802_PUCTRL_CR(x)		(x << 5)
328b20be87SAlexandre Belloni #define NAU7802_PUCTRL_CR_BIT		NAU7802_PUCTRL_CR(1)
338b20be87SAlexandre Belloni #define NAU7802_PUCTRL_AVDDS(x)		(x << 7)
348b20be87SAlexandre Belloni #define NAU7802_PUCTRL_AVDDS_BIT	NAU7802_PUCTRL_AVDDS(1)
358b20be87SAlexandre Belloni #define NAU7802_REG_CTRL1	0x01
368b20be87SAlexandre Belloni #define NAU7802_CTRL1_VLDO(x)		(x << 3)
378b20be87SAlexandre Belloni #define NAU7802_CTRL1_GAINS(x)		(x)
388b20be87SAlexandre Belloni #define NAU7802_CTRL1_GAINS_BITS	0x07
398b20be87SAlexandre Belloni #define NAU7802_REG_CTRL2	0x02
408b20be87SAlexandre Belloni #define NAU7802_CTRL2_CHS(x)		(x << 7)
418b20be87SAlexandre Belloni #define NAU7802_CTRL2_CRS(x)		(x << 4)
428b20be87SAlexandre Belloni #define NAU7802_SAMP_FREQ_320	0x07
438b20be87SAlexandre Belloni #define NAU7802_CTRL2_CHS_BIT		NAU7802_CTRL2_CHS(1)
448b20be87SAlexandre Belloni #define NAU7802_REG_ADC_B2	0x12
458b20be87SAlexandre Belloni #define NAU7802_REG_ADC_B1	0x13
468b20be87SAlexandre Belloni #define NAU7802_REG_ADC_B0	0x14
478b20be87SAlexandre Belloni #define NAU7802_REG_ADC_CTRL	0x15
488b20be87SAlexandre Belloni 
498b20be87SAlexandre Belloni #define NAU7802_MIN_CONVERSIONS 6
508b20be87SAlexandre Belloni 
518b20be87SAlexandre Belloni struct nau7802_state {
528b20be87SAlexandre Belloni 	struct i2c_client	*client;
538b20be87SAlexandre Belloni 	s32			last_value;
548b20be87SAlexandre Belloni 	struct mutex		lock;
558b20be87SAlexandre Belloni 	struct mutex		data_lock;
568b20be87SAlexandre Belloni 	u32			vref_mv;
578b20be87SAlexandre Belloni 	u32			conversion_count;
588b20be87SAlexandre Belloni 	u32			min_conversions;
598b20be87SAlexandre Belloni 	u8			sample_rate;
608b20be87SAlexandre Belloni 	u32			scale_avail[8];
618b20be87SAlexandre Belloni 	struct completion	value_ok;
628b20be87SAlexandre Belloni };
638b20be87SAlexandre Belloni 
648b20be87SAlexandre Belloni #define NAU7802_CHANNEL(chan) {					\
658b20be87SAlexandre Belloni 	.type = IIO_VOLTAGE,					\
668b20be87SAlexandre Belloni 	.indexed = 1,						\
678b20be87SAlexandre Belloni 	.channel = (chan),					\
688b20be87SAlexandre Belloni 	.scan_index = (chan),					\
698b20be87SAlexandre Belloni 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
708b20be87SAlexandre Belloni 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
718b20be87SAlexandre Belloni 				BIT(IIO_CHAN_INFO_SAMP_FREQ)	\
728b20be87SAlexandre Belloni }
738b20be87SAlexandre Belloni 
748b20be87SAlexandre Belloni static const struct iio_chan_spec nau7802_chan_array[] = {
758b20be87SAlexandre Belloni 	NAU7802_CHANNEL(0),
768b20be87SAlexandre Belloni 	NAU7802_CHANNEL(1),
778b20be87SAlexandre Belloni };
788b20be87SAlexandre Belloni 
798b20be87SAlexandre Belloni static const u16 nau7802_sample_freq_avail[] = {10, 20, 40, 80,
808b20be87SAlexandre Belloni 						10, 10, 10, 320};
818b20be87SAlexandre Belloni 
nau7802_show_scales(struct device * dev,struct device_attribute * attr,char * buf)8244072b2cSQuentin Schulz static ssize_t nau7802_show_scales(struct device *dev,
8344072b2cSQuentin Schulz 				   struct device_attribute *attr, char *buf)
8444072b2cSQuentin Schulz {
8544072b2cSQuentin Schulz 	struct nau7802_state *st = iio_priv(dev_to_iio_dev(dev));
8644072b2cSQuentin Schulz 	int i, len = 0;
8744072b2cSQuentin Schulz 
8844072b2cSQuentin Schulz 	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
8944072b2cSQuentin Schulz 		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09d ",
9044072b2cSQuentin Schulz 				 st->scale_avail[i]);
9144072b2cSQuentin Schulz 
9244072b2cSQuentin Schulz 	buf[len-1] = '\n';
9344072b2cSQuentin Schulz 
9444072b2cSQuentin Schulz 	return len;
9544072b2cSQuentin Schulz }
9644072b2cSQuentin Schulz 
978b20be87SAlexandre Belloni static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("10 40 80 320");
988b20be87SAlexandre Belloni 
9944072b2cSQuentin Schulz static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO, nau7802_show_scales,
10044072b2cSQuentin Schulz 		       NULL, 0);
10144072b2cSQuentin Schulz 
1028b20be87SAlexandre Belloni static struct attribute *nau7802_attributes[] = {
1038b20be87SAlexandre Belloni 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
10444072b2cSQuentin Schulz 	&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
1058b20be87SAlexandre Belloni 	NULL
1068b20be87SAlexandre Belloni };
1078b20be87SAlexandre Belloni 
1088b20be87SAlexandre Belloni static const struct attribute_group nau7802_attribute_group = {
1098b20be87SAlexandre Belloni 	.attrs = nau7802_attributes,
1108b20be87SAlexandre Belloni };
1118b20be87SAlexandre Belloni 
nau7802_set_gain(struct nau7802_state * st,int gain)1128b20be87SAlexandre Belloni static int nau7802_set_gain(struct nau7802_state *st, int gain)
1138b20be87SAlexandre Belloni {
1148b20be87SAlexandre Belloni 	int ret;
1158b20be87SAlexandre Belloni 
1168b20be87SAlexandre Belloni 	mutex_lock(&st->lock);
1178b20be87SAlexandre Belloni 	st->conversion_count = 0;
1188b20be87SAlexandre Belloni 
1198b20be87SAlexandre Belloni 	ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
1208b20be87SAlexandre Belloni 	if (ret < 0)
1218b20be87SAlexandre Belloni 		goto nau7802_sysfs_set_gain_out;
1228b20be87SAlexandre Belloni 	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
1238b20be87SAlexandre Belloni 					(ret & (~NAU7802_CTRL1_GAINS_BITS)) |
1248b20be87SAlexandre Belloni 					gain);
1258b20be87SAlexandre Belloni 
1268b20be87SAlexandre Belloni nau7802_sysfs_set_gain_out:
1278b20be87SAlexandre Belloni 	mutex_unlock(&st->lock);
1288b20be87SAlexandre Belloni 
1298b20be87SAlexandre Belloni 	return ret;
1308b20be87SAlexandre Belloni }
1318b20be87SAlexandre Belloni 
nau7802_read_conversion(struct nau7802_state * st)1328b20be87SAlexandre Belloni static int nau7802_read_conversion(struct nau7802_state *st)
1338b20be87SAlexandre Belloni {
1348b20be87SAlexandre Belloni 	int data;
1358b20be87SAlexandre Belloni 
1368b20be87SAlexandre Belloni 	mutex_lock(&st->data_lock);
1378b20be87SAlexandre Belloni 	data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B2);
1388b20be87SAlexandre Belloni 	if (data < 0)
1398b20be87SAlexandre Belloni 		goto nau7802_read_conversion_out;
1408b20be87SAlexandre Belloni 	st->last_value = data << 16;
1418b20be87SAlexandre Belloni 
1428b20be87SAlexandre Belloni 	data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B1);
1438b20be87SAlexandre Belloni 	if (data < 0)
1448b20be87SAlexandre Belloni 		goto nau7802_read_conversion_out;
1458b20be87SAlexandre Belloni 	st->last_value |= data << 8;
1468b20be87SAlexandre Belloni 
1478b20be87SAlexandre Belloni 	data = i2c_smbus_read_byte_data(st->client, NAU7802_REG_ADC_B0);
1488b20be87SAlexandre Belloni 	if (data < 0)
1498b20be87SAlexandre Belloni 		goto nau7802_read_conversion_out;
1508b20be87SAlexandre Belloni 	st->last_value |= data;
1518b20be87SAlexandre Belloni 
1528b20be87SAlexandre Belloni 	st->last_value = sign_extend32(st->last_value, 23);
1538b20be87SAlexandre Belloni 
1548b20be87SAlexandre Belloni nau7802_read_conversion_out:
1558b20be87SAlexandre Belloni 	mutex_unlock(&st->data_lock);
1568b20be87SAlexandre Belloni 
1578b20be87SAlexandre Belloni 	return data;
1588b20be87SAlexandre Belloni }
1598b20be87SAlexandre Belloni 
1608b20be87SAlexandre Belloni /*
1618b20be87SAlexandre Belloni  * Conversions are synchronised on the rising edge of NAU7802_PUCTRL_CS_BIT
1628b20be87SAlexandre Belloni  */
nau7802_sync(struct nau7802_state * st)1638b20be87SAlexandre Belloni static int nau7802_sync(struct nau7802_state *st)
1648b20be87SAlexandre Belloni {
1658b20be87SAlexandre Belloni 	int ret;
1668b20be87SAlexandre Belloni 
1678b20be87SAlexandre Belloni 	ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
1688b20be87SAlexandre Belloni 	if (ret < 0)
1698b20be87SAlexandre Belloni 		return ret;
1708b20be87SAlexandre Belloni 	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
1718b20be87SAlexandre Belloni 				ret | NAU7802_PUCTRL_CS_BIT);
1728b20be87SAlexandre Belloni 
1738b20be87SAlexandre Belloni 	return ret;
1748b20be87SAlexandre Belloni }
1758b20be87SAlexandre Belloni 
nau7802_eoc_trigger(int irq,void * private)1768b20be87SAlexandre Belloni static irqreturn_t nau7802_eoc_trigger(int irq, void *private)
1778b20be87SAlexandre Belloni {
1788b20be87SAlexandre Belloni 	struct iio_dev *indio_dev = private;
1798b20be87SAlexandre Belloni 	struct nau7802_state *st = iio_priv(indio_dev);
1808b20be87SAlexandre Belloni 	int status;
1818b20be87SAlexandre Belloni 
1828b20be87SAlexandre Belloni 	status = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
1838b20be87SAlexandre Belloni 	if (status < 0)
1848b20be87SAlexandre Belloni 		return IRQ_HANDLED;
1858b20be87SAlexandre Belloni 
1868b20be87SAlexandre Belloni 	if (!(status & NAU7802_PUCTRL_CR_BIT))
1878b20be87SAlexandre Belloni 		return IRQ_NONE;
1888b20be87SAlexandre Belloni 
1898b20be87SAlexandre Belloni 	if (nau7802_read_conversion(st) < 0)
1908b20be87SAlexandre Belloni 		return IRQ_HANDLED;
1918b20be87SAlexandre Belloni 
1928b20be87SAlexandre Belloni 	/*
1938b20be87SAlexandre Belloni 	 * Because there is actually only one ADC for both channels, we have to
1948b20be87SAlexandre Belloni 	 * wait for enough conversions to happen before getting a significant
1958b20be87SAlexandre Belloni 	 * value when changing channels and the values are far apart.
1968b20be87SAlexandre Belloni 	 */
1978b20be87SAlexandre Belloni 	if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
1988b20be87SAlexandre Belloni 		st->conversion_count++;
1998b20be87SAlexandre Belloni 	if (st->conversion_count >= NAU7802_MIN_CONVERSIONS)
200cba4985eSDaniel Wagner 		complete(&st->value_ok);
2018b20be87SAlexandre Belloni 
2028b20be87SAlexandre Belloni 	return IRQ_HANDLED;
2038b20be87SAlexandre Belloni }
2048b20be87SAlexandre Belloni 
nau7802_read_irq(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val)2058b20be87SAlexandre Belloni static int nau7802_read_irq(struct iio_dev *indio_dev,
2068b20be87SAlexandre Belloni 			struct iio_chan_spec const *chan,
2078b20be87SAlexandre Belloni 			int *val)
2088b20be87SAlexandre Belloni {
2098b20be87SAlexandre Belloni 	struct nau7802_state *st = iio_priv(indio_dev);
2108b20be87SAlexandre Belloni 	int ret;
2118b20be87SAlexandre Belloni 
21216735d02SWolfram Sang 	reinit_completion(&st->value_ok);
2138b20be87SAlexandre Belloni 	enable_irq(st->client->irq);
2148b20be87SAlexandre Belloni 
2158b20be87SAlexandre Belloni 	nau7802_sync(st);
2168b20be87SAlexandre Belloni 
2178b20be87SAlexandre Belloni 	/* read registers to ensure we flush everything */
2188b20be87SAlexandre Belloni 	ret = nau7802_read_conversion(st);
2198b20be87SAlexandre Belloni 	if (ret < 0)
2208b20be87SAlexandre Belloni 		goto read_chan_info_failure;
2218b20be87SAlexandre Belloni 
2228b20be87SAlexandre Belloni 	/* Wait for a conversion to finish */
2238b20be87SAlexandre Belloni 	ret = wait_for_completion_interruptible_timeout(&st->value_ok,
2248b20be87SAlexandre Belloni 			msecs_to_jiffies(1000));
2258b20be87SAlexandre Belloni 	if (ret == 0)
2268b20be87SAlexandre Belloni 		ret = -ETIMEDOUT;
2278b20be87SAlexandre Belloni 
2288b20be87SAlexandre Belloni 	if (ret < 0)
2298b20be87SAlexandre Belloni 		goto read_chan_info_failure;
2308b20be87SAlexandre Belloni 
2318b20be87SAlexandre Belloni 	disable_irq(st->client->irq);
2328b20be87SAlexandre Belloni 
2338b20be87SAlexandre Belloni 	*val = st->last_value;
2348b20be87SAlexandre Belloni 
2358b20be87SAlexandre Belloni 	return IIO_VAL_INT;
2368b20be87SAlexandre Belloni 
2378b20be87SAlexandre Belloni read_chan_info_failure:
2388b20be87SAlexandre Belloni 	disable_irq(st->client->irq);
2398b20be87SAlexandre Belloni 
2408b20be87SAlexandre Belloni 	return ret;
2418b20be87SAlexandre Belloni }
2428b20be87SAlexandre Belloni 
nau7802_read_poll(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val)2438b20be87SAlexandre Belloni static int nau7802_read_poll(struct iio_dev *indio_dev,
2448b20be87SAlexandre Belloni 			struct iio_chan_spec const *chan,
2458b20be87SAlexandre Belloni 			int *val)
2468b20be87SAlexandre Belloni {
2478b20be87SAlexandre Belloni 	struct nau7802_state *st = iio_priv(indio_dev);
2488b20be87SAlexandre Belloni 	int ret;
2498b20be87SAlexandre Belloni 
2508b20be87SAlexandre Belloni 	nau7802_sync(st);
2518b20be87SAlexandre Belloni 
2528b20be87SAlexandre Belloni 	/* read registers to ensure we flush everything */
2538b20be87SAlexandre Belloni 	ret = nau7802_read_conversion(st);
2548b20be87SAlexandre Belloni 	if (ret < 0)
2558b20be87SAlexandre Belloni 		return ret;
2568b20be87SAlexandre Belloni 
2578b20be87SAlexandre Belloni 	/*
2588b20be87SAlexandre Belloni 	 * Because there is actually only one ADC for both channels, we have to
2598b20be87SAlexandre Belloni 	 * wait for enough conversions to happen before getting a significant
2608b20be87SAlexandre Belloni 	 * value when changing channels and the values are far appart.
2618b20be87SAlexandre Belloni 	 */
2628b20be87SAlexandre Belloni 	do {
2638b20be87SAlexandre Belloni 		ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
2648b20be87SAlexandre Belloni 		if (ret < 0)
2658b20be87SAlexandre Belloni 			return ret;
2668b20be87SAlexandre Belloni 
2678b20be87SAlexandre Belloni 		while (!(ret & NAU7802_PUCTRL_CR_BIT)) {
2688b20be87SAlexandre Belloni 			if (st->sample_rate != NAU7802_SAMP_FREQ_320)
2698b20be87SAlexandre Belloni 				msleep(20);
2708b20be87SAlexandre Belloni 			else
2718b20be87SAlexandre Belloni 				mdelay(4);
2728b20be87SAlexandre Belloni 			ret = i2c_smbus_read_byte_data(st->client,
2738b20be87SAlexandre Belloni 							NAU7802_REG_PUCTRL);
2748b20be87SAlexandre Belloni 			if (ret < 0)
2758b20be87SAlexandre Belloni 				return ret;
2768b20be87SAlexandre Belloni 		}
2778b20be87SAlexandre Belloni 
2788b20be87SAlexandre Belloni 		ret = nau7802_read_conversion(st);
2798b20be87SAlexandre Belloni 		if (ret < 0)
2808b20be87SAlexandre Belloni 			return ret;
2818b20be87SAlexandre Belloni 		if (st->conversion_count < NAU7802_MIN_CONVERSIONS)
2828b20be87SAlexandre Belloni 			st->conversion_count++;
2838b20be87SAlexandre Belloni 	} while (st->conversion_count < NAU7802_MIN_CONVERSIONS);
2848b20be87SAlexandre Belloni 
2858b20be87SAlexandre Belloni 	*val = st->last_value;
2868b20be87SAlexandre Belloni 
2878b20be87SAlexandre Belloni 	return IIO_VAL_INT;
2888b20be87SAlexandre Belloni }
2898b20be87SAlexandre Belloni 
nau7802_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)2908b20be87SAlexandre Belloni static int nau7802_read_raw(struct iio_dev *indio_dev,
2918b20be87SAlexandre Belloni 			    struct iio_chan_spec const *chan,
2928b20be87SAlexandre Belloni 			    int *val, int *val2, long mask)
2938b20be87SAlexandre Belloni {
2948b20be87SAlexandre Belloni 	struct nau7802_state *st = iio_priv(indio_dev);
2958b20be87SAlexandre Belloni 	int ret;
2968b20be87SAlexandre Belloni 
2978b20be87SAlexandre Belloni 	switch (mask) {
2988b20be87SAlexandre Belloni 	case IIO_CHAN_INFO_RAW:
2998b20be87SAlexandre Belloni 		mutex_lock(&st->lock);
3008b20be87SAlexandre Belloni 		/*
3018b20be87SAlexandre Belloni 		 * Select the channel to use
3028b20be87SAlexandre Belloni 		 *   - Channel 1 is value 0 in the CHS register
3038b20be87SAlexandre Belloni 		 *   - Channel 2 is value 1 in the CHS register
3048b20be87SAlexandre Belloni 		 */
3058b20be87SAlexandre Belloni 		ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL2);
3068b20be87SAlexandre Belloni 		if (ret < 0) {
3078b20be87SAlexandre Belloni 			mutex_unlock(&st->lock);
3088b20be87SAlexandre Belloni 			return ret;
3098b20be87SAlexandre Belloni 		}
3108b20be87SAlexandre Belloni 
3118b20be87SAlexandre Belloni 		if (((ret & NAU7802_CTRL2_CHS_BIT) && !chan->channel) ||
3128b20be87SAlexandre Belloni 				(!(ret & NAU7802_CTRL2_CHS_BIT) &&
3138b20be87SAlexandre Belloni 				 chan->channel)) {
3148b20be87SAlexandre Belloni 			st->conversion_count = 0;
3158b20be87SAlexandre Belloni 			ret = i2c_smbus_write_byte_data(st->client,
3168b20be87SAlexandre Belloni 					NAU7802_REG_CTRL2,
3178b20be87SAlexandre Belloni 					NAU7802_CTRL2_CHS(chan->channel) |
3188b20be87SAlexandre Belloni 					NAU7802_CTRL2_CRS(st->sample_rate));
3198b20be87SAlexandre Belloni 
3208b20be87SAlexandre Belloni 			if (ret < 0) {
3218b20be87SAlexandre Belloni 				mutex_unlock(&st->lock);
3228b20be87SAlexandre Belloni 				return ret;
3238b20be87SAlexandre Belloni 			}
3248b20be87SAlexandre Belloni 		}
3258b20be87SAlexandre Belloni 
3268b20be87SAlexandre Belloni 		if (st->client->irq)
3278b20be87SAlexandre Belloni 			ret = nau7802_read_irq(indio_dev, chan, val);
3288b20be87SAlexandre Belloni 		else
3298b20be87SAlexandre Belloni 			ret = nau7802_read_poll(indio_dev, chan, val);
3308b20be87SAlexandre Belloni 
3318b20be87SAlexandre Belloni 		mutex_unlock(&st->lock);
3328b20be87SAlexandre Belloni 		return ret;
3338b20be87SAlexandre Belloni 
3348b20be87SAlexandre Belloni 	case IIO_CHAN_INFO_SCALE:
3358b20be87SAlexandre Belloni 		ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_CTRL1);
3368b20be87SAlexandre Belloni 		if (ret < 0)
3378b20be87SAlexandre Belloni 			return ret;
3388b20be87SAlexandre Belloni 
3398b20be87SAlexandre Belloni 		/*
3408b20be87SAlexandre Belloni 		 * We have 24 bits of signed data, that means 23 bits of data
3418b20be87SAlexandre Belloni 		 * plus the sign bit
3428b20be87SAlexandre Belloni 		 */
3438b20be87SAlexandre Belloni 		*val = st->vref_mv;
3448b20be87SAlexandre Belloni 		*val2 = 23 + (ret & NAU7802_CTRL1_GAINS_BITS);
3458b20be87SAlexandre Belloni 
3468b20be87SAlexandre Belloni 		return IIO_VAL_FRACTIONAL_LOG2;
3478b20be87SAlexandre Belloni 
3488b20be87SAlexandre Belloni 	case IIO_CHAN_INFO_SAMP_FREQ:
3498b20be87SAlexandre Belloni 		*val =  nau7802_sample_freq_avail[st->sample_rate];
3508b20be87SAlexandre Belloni 		*val2 = 0;
3518b20be87SAlexandre Belloni 		return IIO_VAL_INT;
3528b20be87SAlexandre Belloni 
3538b20be87SAlexandre Belloni 	default:
3548b20be87SAlexandre Belloni 		break;
3558b20be87SAlexandre Belloni 	}
3568b20be87SAlexandre Belloni 
3578b20be87SAlexandre Belloni 	return -EINVAL;
3588b20be87SAlexandre Belloni }
3598b20be87SAlexandre Belloni 
nau7802_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)3608b20be87SAlexandre Belloni static int nau7802_write_raw(struct iio_dev *indio_dev,
3618b20be87SAlexandre Belloni 			     struct iio_chan_spec const *chan,
3628b20be87SAlexandre Belloni 			     int val, int val2, long mask)
3638b20be87SAlexandre Belloni {
3648b20be87SAlexandre Belloni 	struct nau7802_state *st = iio_priv(indio_dev);
3658b20be87SAlexandre Belloni 	int i, ret;
3668b20be87SAlexandre Belloni 
3678b20be87SAlexandre Belloni 	switch (mask) {
3688b20be87SAlexandre Belloni 	case IIO_CHAN_INFO_SCALE:
3698b20be87SAlexandre Belloni 		for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
3708b20be87SAlexandre Belloni 			if (val2 == st->scale_avail[i])
3718b20be87SAlexandre Belloni 				return nau7802_set_gain(st, i);
3728b20be87SAlexandre Belloni 
3738b20be87SAlexandre Belloni 		break;
3748b20be87SAlexandre Belloni 
3758b20be87SAlexandre Belloni 	case IIO_CHAN_INFO_SAMP_FREQ:
3768b20be87SAlexandre Belloni 		for (i = 0; i < ARRAY_SIZE(nau7802_sample_freq_avail); i++)
3778b20be87SAlexandre Belloni 			if (val == nau7802_sample_freq_avail[i]) {
3788b20be87SAlexandre Belloni 				mutex_lock(&st->lock);
3798b20be87SAlexandre Belloni 				st->sample_rate = i;
3808b20be87SAlexandre Belloni 				st->conversion_count = 0;
3818b20be87SAlexandre Belloni 				ret = i2c_smbus_write_byte_data(st->client,
3828b20be87SAlexandre Belloni 					NAU7802_REG_CTRL2,
3838b20be87SAlexandre Belloni 					NAU7802_CTRL2_CRS(st->sample_rate));
3848b20be87SAlexandre Belloni 				mutex_unlock(&st->lock);
3858b20be87SAlexandre Belloni 				return ret;
3868b20be87SAlexandre Belloni 			}
3878b20be87SAlexandre Belloni 
3888b20be87SAlexandre Belloni 		break;
3898b20be87SAlexandre Belloni 
3908b20be87SAlexandre Belloni 	default:
3918b20be87SAlexandre Belloni 		break;
3928b20be87SAlexandre Belloni 	}
3938b20be87SAlexandre Belloni 
3948b20be87SAlexandre Belloni 	return -EINVAL;
3958b20be87SAlexandre Belloni }
3968b20be87SAlexandre Belloni 
nau7802_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,long mask)3978b20be87SAlexandre Belloni static int nau7802_write_raw_get_fmt(struct iio_dev *indio_dev,
3988b20be87SAlexandre Belloni 				     struct iio_chan_spec const *chan,
3998b20be87SAlexandre Belloni 				     long mask)
4008b20be87SAlexandre Belloni {
4018b20be87SAlexandre Belloni 	return IIO_VAL_INT_PLUS_NANO;
4028b20be87SAlexandre Belloni }
4038b20be87SAlexandre Belloni 
4048b20be87SAlexandre Belloni static const struct iio_info nau7802_info = {
4058b20be87SAlexandre Belloni 	.read_raw = &nau7802_read_raw,
4068b20be87SAlexandre Belloni 	.write_raw = &nau7802_write_raw,
4078b20be87SAlexandre Belloni 	.write_raw_get_fmt = nau7802_write_raw_get_fmt,
4088b20be87SAlexandre Belloni 	.attrs = &nau7802_attribute_group,
4098b20be87SAlexandre Belloni };
4108b20be87SAlexandre Belloni 
nau7802_probe(struct i2c_client * client)411d8600a18SAndy Shevchenko static int nau7802_probe(struct i2c_client *client)
4128b20be87SAlexandre Belloni {
4138b20be87SAlexandre Belloni 	struct iio_dev *indio_dev;
4148b20be87SAlexandre Belloni 	struct nau7802_state *st;
4158b20be87SAlexandre Belloni 	int i, ret;
4168b20be87SAlexandre Belloni 	u8 data;
4178b20be87SAlexandre Belloni 	u32 tmp = 0;
4188b20be87SAlexandre Belloni 
419ed6886c1SSachin Kamat 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
4208b20be87SAlexandre Belloni 	if (indio_dev == NULL)
4218b20be87SAlexandre Belloni 		return -ENOMEM;
4228b20be87SAlexandre Belloni 
4238b20be87SAlexandre Belloni 	st = iio_priv(indio_dev);
4248b20be87SAlexandre Belloni 
4258b20be87SAlexandre Belloni 	indio_dev->name = dev_name(&client->dev);
4268b20be87SAlexandre Belloni 	indio_dev->modes = INDIO_DIRECT_MODE;
4278b20be87SAlexandre Belloni 	indio_dev->info = &nau7802_info;
4288b20be87SAlexandre Belloni 
4298b20be87SAlexandre Belloni 	st->client = client;
4308b20be87SAlexandre Belloni 
4318b20be87SAlexandre Belloni 	/* Reset the device */
4328b20be87SAlexandre Belloni 	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
4338b20be87SAlexandre Belloni 				  NAU7802_PUCTRL_RR_BIT);
4348b20be87SAlexandre Belloni 	if (ret < 0)
435ed6886c1SSachin Kamat 		return ret;
4368b20be87SAlexandre Belloni 
4378b20be87SAlexandre Belloni 	/* Enter normal operation mode */
4388b20be87SAlexandre Belloni 	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL,
4398b20be87SAlexandre Belloni 				  NAU7802_PUCTRL_PUD_BIT);
4408b20be87SAlexandre Belloni 	if (ret < 0)
441ed6886c1SSachin Kamat 		return ret;
4428b20be87SAlexandre Belloni 
4438b20be87SAlexandre Belloni 	/*
4448b20be87SAlexandre Belloni 	 * After about 200 usecs, the device should be ready and then
4458b20be87SAlexandre Belloni 	 * the Power Up bit will be set to 1. If not, wait for it.
4468b20be87SAlexandre Belloni 	 */
4478b20be87SAlexandre Belloni 	udelay(210);
4488b20be87SAlexandre Belloni 	ret = i2c_smbus_read_byte_data(st->client, NAU7802_REG_PUCTRL);
4498b20be87SAlexandre Belloni 	if (ret < 0)
450ed6886c1SSachin Kamat 		return ret;
4518b20be87SAlexandre Belloni 	if (!(ret & NAU7802_PUCTRL_PUR_BIT))
452ed6886c1SSachin Kamat 		return ret;
4538b20be87SAlexandre Belloni 
454d34a1dafSAndy Shevchenko 	device_property_read_u32(&client->dev, "nuvoton,vldo", &tmp);
4558b20be87SAlexandre Belloni 	st->vref_mv = tmp;
4568b20be87SAlexandre Belloni 
4578b20be87SAlexandre Belloni 	data = NAU7802_PUCTRL_PUD_BIT | NAU7802_PUCTRL_PUA_BIT |
4588b20be87SAlexandre Belloni 		NAU7802_PUCTRL_CS_BIT;
4598b20be87SAlexandre Belloni 	if (tmp >= 2400)
4608b20be87SAlexandre Belloni 		data |= NAU7802_PUCTRL_AVDDS_BIT;
4618b20be87SAlexandre Belloni 
4628b20be87SAlexandre Belloni 	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_PUCTRL, data);
4638b20be87SAlexandre Belloni 	if (ret < 0)
464ed6886c1SSachin Kamat 		return ret;
4658b20be87SAlexandre Belloni 	ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_ADC_CTRL, 0x30);
4668b20be87SAlexandre Belloni 	if (ret < 0)
467ed6886c1SSachin Kamat 		return ret;
4688b20be87SAlexandre Belloni 
4698b20be87SAlexandre Belloni 	if (tmp >= 2400) {
4708b20be87SAlexandre Belloni 		data = NAU7802_CTRL1_VLDO((4500 - tmp) / 300);
4718b20be87SAlexandre Belloni 		ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL1,
4728b20be87SAlexandre Belloni 						data);
4738b20be87SAlexandre Belloni 		if (ret < 0)
474ed6886c1SSachin Kamat 			return ret;
4758b20be87SAlexandre Belloni 	}
4768b20be87SAlexandre Belloni 
4778b20be87SAlexandre Belloni 	/* Populate available ADC input ranges */
4788b20be87SAlexandre Belloni 	for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++)
4798b20be87SAlexandre Belloni 		st->scale_avail[i] = (((u64)st->vref_mv) * 1000000000ULL)
4808b20be87SAlexandre Belloni 					   >> (23 + i);
4818b20be87SAlexandre Belloni 
4828b20be87SAlexandre Belloni 	init_completion(&st->value_ok);
4838b20be87SAlexandre Belloni 
4848b20be87SAlexandre Belloni 	/*
4858b20be87SAlexandre Belloni 	 * The ADC fires continuously and we can't do anything about
4868b20be87SAlexandre Belloni 	 * it. So we need to have the IRQ disabled by default, and we
4878b20be87SAlexandre Belloni 	 * will enable them back when we will need them..
4888b20be87SAlexandre Belloni 	 */
4898b20be87SAlexandre Belloni 	if (client->irq) {
49044153810SAlexandru Ardelean 		ret = devm_request_threaded_irq(&client->dev, client->irq,
4918b20be87SAlexandre Belloni 						NULL,
4928b20be87SAlexandre Belloni 						nau7802_eoc_trigger,
493aef3ef16SJonathan Cameron 						IRQF_TRIGGER_HIGH | IRQF_ONESHOT |
494aef3ef16SJonathan Cameron 						IRQF_NO_AUTOEN,
4958b20be87SAlexandre Belloni 						client->dev.driver->name,
4968b20be87SAlexandre Belloni 						indio_dev);
4978b20be87SAlexandre Belloni 		if (ret) {
4988b20be87SAlexandre Belloni 			/*
4998b20be87SAlexandre Belloni 			 * What may happen here is that our IRQ controller is
5008b20be87SAlexandre Belloni 			 * not able to get level interrupt but this is required
5018b20be87SAlexandre Belloni 			 * by this ADC as when going over 40 sample per second,
5028b20be87SAlexandre Belloni 			 * the interrupt line may stay high between conversions.
5038b20be87SAlexandre Belloni 			 * So, we continue no matter what but we switch to
5048b20be87SAlexandre Belloni 			 * polling mode.
5058b20be87SAlexandre Belloni 			 */
5068b20be87SAlexandre Belloni 			dev_info(&client->dev,
5078b20be87SAlexandre Belloni 				"Failed to allocate IRQ, using polling mode\n");
5088b20be87SAlexandre Belloni 			client->irq = 0;
509aef3ef16SJonathan Cameron 		}
5108b20be87SAlexandre Belloni 	}
5118b20be87SAlexandre Belloni 
5128b20be87SAlexandre Belloni 	if (!client->irq) {
5138b20be87SAlexandre Belloni 		/*
5148b20be87SAlexandre Belloni 		 * We are polling, use the fastest sample rate by
5158b20be87SAlexandre Belloni 		 * default
5168b20be87SAlexandre Belloni 		 */
5178b20be87SAlexandre Belloni 		st->sample_rate = NAU7802_SAMP_FREQ_320;
5188b20be87SAlexandre Belloni 		ret = i2c_smbus_write_byte_data(st->client, NAU7802_REG_CTRL2,
5198b20be87SAlexandre Belloni 					  NAU7802_CTRL2_CRS(st->sample_rate));
5208b20be87SAlexandre Belloni 		if (ret)
52144153810SAlexandru Ardelean 			return ret;
5228b20be87SAlexandre Belloni 	}
5238b20be87SAlexandre Belloni 
5248b20be87SAlexandre Belloni 	/* Setup the ADC channels available on the board */
5258b20be87SAlexandre Belloni 	indio_dev->num_channels = ARRAY_SIZE(nau7802_chan_array);
5268b20be87SAlexandre Belloni 	indio_dev->channels = nau7802_chan_array;
5278b20be87SAlexandre Belloni 
5288b20be87SAlexandre Belloni 	mutex_init(&st->lock);
5298b20be87SAlexandre Belloni 	mutex_init(&st->data_lock);
5308b20be87SAlexandre Belloni 
53144153810SAlexandru Ardelean 	return devm_iio_device_register(&client->dev, indio_dev);
5328b20be87SAlexandre Belloni }
5338b20be87SAlexandre Belloni 
5348b20be87SAlexandre Belloni static const struct i2c_device_id nau7802_i2c_id[] = {
5358b20be87SAlexandre Belloni 	{ "nau7802", 0 },
5368b20be87SAlexandre Belloni 	{ }
5378b20be87SAlexandre Belloni };
5388b20be87SAlexandre Belloni MODULE_DEVICE_TABLE(i2c, nau7802_i2c_id);
5398b20be87SAlexandre Belloni 
5408b20be87SAlexandre Belloni static const struct of_device_id nau7802_dt_ids[] = {
5418b20be87SAlexandre Belloni 	{ .compatible = "nuvoton,nau7802" },
5428b20be87SAlexandre Belloni 	{},
5438b20be87SAlexandre Belloni };
5448b20be87SAlexandre Belloni MODULE_DEVICE_TABLE(of, nau7802_dt_ids);
5458b20be87SAlexandre Belloni 
5468b20be87SAlexandre Belloni static struct i2c_driver nau7802_driver = {
547*7cf15f42SUwe Kleine-König 	.probe = nau7802_probe,
5488b20be87SAlexandre Belloni 	.id_table = nau7802_i2c_id,
5498b20be87SAlexandre Belloni 	.driver = {
5508b20be87SAlexandre Belloni 		   .name = "nau7802",
551d453a4abSSachin Kamat 		   .of_match_table = nau7802_dt_ids,
5528b20be87SAlexandre Belloni 	},
5538b20be87SAlexandre Belloni };
5548b20be87SAlexandre Belloni 
5558b20be87SAlexandre Belloni module_i2c_driver(nau7802_driver);
5568b20be87SAlexandre Belloni 
5578b20be87SAlexandre Belloni MODULE_LICENSE("GPL");
5588b20be87SAlexandre Belloni MODULE_DESCRIPTION("Nuvoton NAU7802 ADC Driver");
5598b20be87SAlexandre Belloni MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
5608b20be87SAlexandre Belloni MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
561