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