cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ad7746.c (19192B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * AD7746 capacitive sensor driver supporting AD7745, AD7746 and AD7747
      4 *
      5 * Copyright 2011 Analog Devices Inc.
      6 */
      7
      8#include <linux/delay.h>
      9#include <linux/device.h>
     10#include <linux/i2c.h>
     11#include <linux/interrupt.h>
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/slab.h>
     15#include <linux/stat.h>
     16#include <linux/sysfs.h>
     17
     18#include <linux/iio/iio.h>
     19#include <linux/iio/sysfs.h>
     20
     21/*
     22 * AD7746 Register Definition
     23 */
     24
     25#define AD7746_REG_STATUS		0
     26#define AD7746_REG_CAP_DATA_HIGH	1
     27#define AD7746_REG_VT_DATA_HIGH		4
     28#define AD7746_REG_CAP_SETUP		7
     29#define AD7746_REG_VT_SETUP		8
     30#define AD7746_REG_EXC_SETUP		9
     31#define AD7746_REG_CFG			10
     32#define AD7746_REG_CAPDACA		11
     33#define AD7746_REG_CAPDACB		12
     34#define AD7746_REG_CAP_OFFH		13
     35#define AD7746_REG_CAP_GAINH		15
     36#define AD7746_REG_VOLT_GAINH		17
     37
     38/* Status Register Bit Designations (AD7746_REG_STATUS) */
     39#define AD7746_STATUS_EXCERR		BIT(3)
     40#define AD7746_STATUS_RDY		BIT(2)
     41#define AD7746_STATUS_RDYVT		BIT(1)
     42#define AD7746_STATUS_RDYCAP		BIT(0)
     43
     44/* Capacitive Channel Setup Register Bit Designations (AD7746_REG_CAP_SETUP) */
     45#define AD7746_CAPSETUP_CAPEN		BIT(7)
     46#define AD7746_CAPSETUP_CIN2		BIT(6) /* AD7746 only */
     47#define AD7746_CAPSETUP_CAPDIFF		BIT(5)
     48#define AD7746_CAPSETUP_CACHOP		BIT(0)
     49
     50/* Voltage/Temperature Setup Register Bit Designations (AD7746_REG_VT_SETUP) */
     51#define AD7746_VTSETUP_VTEN		(1 << 7)
     52#define AD7746_VTSETUP_VTMD_INT_TEMP	(0 << 5)
     53#define AD7746_VTSETUP_VTMD_EXT_TEMP	(1 << 5)
     54#define AD7746_VTSETUP_VTMD_VDD_MON	(2 << 5)
     55#define AD7746_VTSETUP_VTMD_EXT_VIN	(3 << 5)
     56#define AD7746_VTSETUP_EXTREF		BIT(4)
     57#define AD7746_VTSETUP_VTSHORT		BIT(1)
     58#define AD7746_VTSETUP_VTCHOP		BIT(0)
     59
     60/* Excitation Setup Register Bit Designations (AD7746_REG_EXC_SETUP) */
     61#define AD7746_EXCSETUP_CLKCTRL		BIT(7)
     62#define AD7746_EXCSETUP_EXCON		BIT(6)
     63#define AD7746_EXCSETUP_EXCB		BIT(5)
     64#define AD7746_EXCSETUP_NEXCB		BIT(4)
     65#define AD7746_EXCSETUP_EXCA		BIT(3)
     66#define AD7746_EXCSETUP_NEXCA		BIT(2)
     67#define AD7746_EXCSETUP_EXCLVL(x)	(((x) & 0x3) << 0)
     68
     69/* Config Register Bit Designations (AD7746_REG_CFG) */
     70#define AD7746_CONF_VTFS_SHIFT		6
     71#define AD7746_CONF_CAPFS_SHIFT		3
     72#define AD7746_CONF_VTFS_MASK		GENMASK(7, 6)
     73#define AD7746_CONF_CAPFS_MASK		GENMASK(5, 3)
     74#define AD7746_CONF_MODE_IDLE		(0 << 0)
     75#define AD7746_CONF_MODE_CONT_CONV	(1 << 0)
     76#define AD7746_CONF_MODE_SINGLE_CONV	(2 << 0)
     77#define AD7746_CONF_MODE_PWRDN		(3 << 0)
     78#define AD7746_CONF_MODE_OFFS_CAL	(5 << 0)
     79#define AD7746_CONF_MODE_GAIN_CAL	(6 << 0)
     80
     81/* CAPDAC Register Bit Designations (AD7746_REG_CAPDACx) */
     82#define AD7746_CAPDAC_DACEN		BIT(7)
     83#define AD7746_CAPDAC_DACP(x)		((x) & 0x7F)
     84
     85struct ad7746_chip_info {
     86	struct i2c_client *client;
     87	struct mutex lock; /* protect sensor state */
     88	/*
     89	 * Capacitive channel digital filter setup;
     90	 * conversion time/update rate setup per channel
     91	 */
     92	u8	config;
     93	u8	cap_setup;
     94	u8	vt_setup;
     95	u8	capdac[2][2];
     96	s8	capdac_set;
     97
     98	union {
     99		__be32 d32;
    100		u8 d8[4];
    101	} data ____cacheline_aligned;
    102};
    103
    104enum ad7746_chan {
    105	VIN,
    106	VIN_VDD,
    107	TEMP_INT,
    108	TEMP_EXT,
    109	CIN1,
    110	CIN1_DIFF,
    111	CIN2,
    112	CIN2_DIFF,
    113};
    114
    115static const struct iio_chan_spec ad7746_channels[] = {
    116	[VIN] = {
    117		.type = IIO_VOLTAGE,
    118		.indexed = 1,
    119		.channel = 0,
    120		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
    121		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
    122			BIT(IIO_CHAN_INFO_SAMP_FREQ),
    123		.address = AD7746_REG_VT_DATA_HIGH << 8 |
    124			AD7746_VTSETUP_VTMD_EXT_VIN,
    125	},
    126	[VIN_VDD] = {
    127		.type = IIO_VOLTAGE,
    128		.indexed = 1,
    129		.channel = 1,
    130		.extend_name = "supply",
    131		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
    132		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |
    133			BIT(IIO_CHAN_INFO_SAMP_FREQ),
    134		.address = AD7746_REG_VT_DATA_HIGH << 8 |
    135			AD7746_VTSETUP_VTMD_VDD_MON,
    136	},
    137	[TEMP_INT] = {
    138		.type = IIO_TEMP,
    139		.indexed = 1,
    140		.channel = 0,
    141		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
    142		.address = AD7746_REG_VT_DATA_HIGH << 8 |
    143			AD7746_VTSETUP_VTMD_INT_TEMP,
    144	},
    145	[TEMP_EXT] = {
    146		.type = IIO_TEMP,
    147		.indexed = 1,
    148		.channel = 1,
    149		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
    150		.address = AD7746_REG_VT_DATA_HIGH << 8 |
    151			AD7746_VTSETUP_VTMD_EXT_TEMP,
    152	},
    153	[CIN1] = {
    154		.type = IIO_CAPACITANCE,
    155		.indexed = 1,
    156		.channel = 0,
    157		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    158		BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
    159		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
    160		BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
    161		.address = AD7746_REG_CAP_DATA_HIGH << 8,
    162	},
    163	[CIN1_DIFF] = {
    164		.type = IIO_CAPACITANCE,
    165		.differential = 1,
    166		.indexed = 1,
    167		.channel = 0,
    168		.channel2 = 2,
    169		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    170		BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
    171		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
    172		BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
    173		.address = AD7746_REG_CAP_DATA_HIGH << 8 |
    174			AD7746_CAPSETUP_CAPDIFF
    175	},
    176	[CIN2] = {
    177		.type = IIO_CAPACITANCE,
    178		.indexed = 1,
    179		.channel = 1,
    180		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    181		BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
    182		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
    183		BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
    184		.address = AD7746_REG_CAP_DATA_HIGH << 8 |
    185			AD7746_CAPSETUP_CIN2,
    186	},
    187	[CIN2_DIFF] = {
    188		.type = IIO_CAPACITANCE,
    189		.differential = 1,
    190		.indexed = 1,
    191		.channel = 1,
    192		.channel2 = 3,
    193		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
    194		BIT(IIO_CHAN_INFO_CALIBSCALE) | BIT(IIO_CHAN_INFO_OFFSET),
    195		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBBIAS) |
    196		BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
    197		.address = AD7746_REG_CAP_DATA_HIGH << 8 |
    198			AD7746_CAPSETUP_CAPDIFF | AD7746_CAPSETUP_CIN2,
    199	}
    200};
    201
    202/* Values are Update Rate (Hz), Conversion Time (ms) + 1*/
    203static const unsigned char ad7746_vt_filter_rate_table[][2] = {
    204	{50, 20 + 1}, {31, 32 + 1}, {16, 62 + 1}, {8, 122 + 1},
    205};
    206
    207static const unsigned char ad7746_cap_filter_rate_table[][2] = {
    208	{91, 11 + 1}, {84, 12 + 1}, {50, 20 + 1}, {26, 38 + 1},
    209	{16, 62 + 1}, {13, 77 + 1}, {11, 92 + 1}, {9, 110 + 1},
    210};
    211
    212static int ad7746_set_capdac(struct ad7746_chip_info *chip, int channel)
    213{
    214	int ret = i2c_smbus_write_byte_data(chip->client,
    215					    AD7746_REG_CAPDACA,
    216					    chip->capdac[channel][0]);
    217	if (ret < 0)
    218		return ret;
    219
    220	return i2c_smbus_write_byte_data(chip->client,
    221					  AD7746_REG_CAPDACB,
    222					  chip->capdac[channel][1]);
    223}
    224
    225static int ad7746_select_channel(struct iio_dev *indio_dev,
    226				 struct iio_chan_spec const *chan)
    227{
    228	struct ad7746_chip_info *chip = iio_priv(indio_dev);
    229	u8 vt_setup, cap_setup;
    230	int ret, delay, idx;
    231
    232	switch (chan->type) {
    233	case IIO_CAPACITANCE:
    234		cap_setup = (chan->address & 0xFF) | AD7746_CAPSETUP_CAPEN;
    235		vt_setup = chip->vt_setup & ~AD7746_VTSETUP_VTEN;
    236		idx = (chip->config & AD7746_CONF_CAPFS_MASK) >>
    237			AD7746_CONF_CAPFS_SHIFT;
    238		delay = ad7746_cap_filter_rate_table[idx][1];
    239
    240		ret = ad7746_set_capdac(chip, chan->channel);
    241		if (ret < 0)
    242			return ret;
    243
    244		if (chip->capdac_set != chan->channel)
    245			chip->capdac_set = chan->channel;
    246		break;
    247	case IIO_VOLTAGE:
    248	case IIO_TEMP:
    249		vt_setup = (chan->address & 0xFF) | AD7746_VTSETUP_VTEN;
    250		cap_setup = chip->cap_setup & ~AD7746_CAPSETUP_CAPEN;
    251		idx = (chip->config & AD7746_CONF_VTFS_MASK) >>
    252			AD7746_CONF_VTFS_SHIFT;
    253		delay = ad7746_cap_filter_rate_table[idx][1];
    254		break;
    255	default:
    256		return -EINVAL;
    257	}
    258
    259	if (chip->cap_setup != cap_setup) {
    260		ret = i2c_smbus_write_byte_data(chip->client,
    261						AD7746_REG_CAP_SETUP,
    262						cap_setup);
    263		if (ret < 0)
    264			return ret;
    265
    266		chip->cap_setup = cap_setup;
    267	}
    268
    269	if (chip->vt_setup != vt_setup) {
    270		ret = i2c_smbus_write_byte_data(chip->client,
    271						AD7746_REG_VT_SETUP,
    272						vt_setup);
    273		if (ret < 0)
    274			return ret;
    275
    276		chip->vt_setup = vt_setup;
    277	}
    278
    279	return delay;
    280}
    281
    282static inline ssize_t ad7746_start_calib(struct device *dev,
    283					 struct device_attribute *attr,
    284					 const char *buf,
    285					 size_t len,
    286					 u8 regval)
    287{
    288	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
    289	struct ad7746_chip_info *chip = iio_priv(indio_dev);
    290	int ret, timeout = 10;
    291	bool doit;
    292
    293	ret = kstrtobool(buf, &doit);
    294	if (ret < 0)
    295		return ret;
    296
    297	if (!doit)
    298		return 0;
    299
    300	mutex_lock(&chip->lock);
    301	regval |= chip->config;
    302	ret = i2c_smbus_write_byte_data(chip->client, AD7746_REG_CFG, regval);
    303	if (ret < 0)
    304		goto unlock;
    305
    306	do {
    307		msleep(20);
    308		ret = i2c_smbus_read_byte_data(chip->client, AD7746_REG_CFG);
    309		if (ret < 0)
    310			goto unlock;
    311
    312	} while ((ret == regval) && timeout--);
    313
    314	mutex_unlock(&chip->lock);
    315
    316	return len;
    317
    318unlock:
    319	mutex_unlock(&chip->lock);
    320	return ret;
    321}
    322
    323static ssize_t ad7746_start_offset_calib(struct device *dev,
    324					 struct device_attribute *attr,
    325					 const char *buf,
    326					 size_t len)
    327{
    328	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
    329	int ret = ad7746_select_channel(indio_dev,
    330			      &ad7746_channels[to_iio_dev_attr(attr)->address]);
    331	if (ret < 0)
    332		return ret;
    333
    334	return ad7746_start_calib(dev, attr, buf, len,
    335				  AD7746_CONF_MODE_OFFS_CAL);
    336}
    337
    338static ssize_t ad7746_start_gain_calib(struct device *dev,
    339				       struct device_attribute *attr,
    340				       const char *buf,
    341				       size_t len)
    342{
    343	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
    344	int ret = ad7746_select_channel(indio_dev,
    345			      &ad7746_channels[to_iio_dev_attr(attr)->address]);
    346	if (ret < 0)
    347		return ret;
    348
    349	return ad7746_start_calib(dev, attr, buf, len,
    350				  AD7746_CONF_MODE_GAIN_CAL);
    351}
    352
    353static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration,
    354		       0200, NULL, ad7746_start_offset_calib, CIN1);
    355static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration,
    356		       0200, NULL, ad7746_start_offset_calib, CIN2);
    357static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
    358		       0200, NULL, ad7746_start_gain_calib, CIN1);
    359static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
    360		       0200, NULL, ad7746_start_gain_calib, CIN2);
    361static IIO_DEVICE_ATTR(in_voltage0_calibscale_calibration,
    362		       0200, NULL, ad7746_start_gain_calib, VIN);
    363
    364static int ad7746_store_cap_filter_rate_setup(struct ad7746_chip_info *chip,
    365					      int val)
    366{
    367	int i;
    368
    369	for (i = 0; i < ARRAY_SIZE(ad7746_cap_filter_rate_table); i++)
    370		if (val >= ad7746_cap_filter_rate_table[i][0])
    371			break;
    372
    373	if (i >= ARRAY_SIZE(ad7746_cap_filter_rate_table))
    374		i = ARRAY_SIZE(ad7746_cap_filter_rate_table) - 1;
    375
    376	chip->config &= ~AD7746_CONF_CAPFS_MASK;
    377	chip->config |= i << AD7746_CONF_CAPFS_SHIFT;
    378
    379	return 0;
    380}
    381
    382static int ad7746_store_vt_filter_rate_setup(struct ad7746_chip_info *chip,
    383					     int val)
    384{
    385	int i;
    386
    387	for (i = 0; i < ARRAY_SIZE(ad7746_vt_filter_rate_table); i++)
    388		if (val >= ad7746_vt_filter_rate_table[i][0])
    389			break;
    390
    391	if (i >= ARRAY_SIZE(ad7746_vt_filter_rate_table))
    392		i = ARRAY_SIZE(ad7746_vt_filter_rate_table) - 1;
    393
    394	chip->config &= ~AD7746_CONF_VTFS_MASK;
    395	chip->config |= i << AD7746_CONF_VTFS_SHIFT;
    396
    397	return 0;
    398}
    399
    400static IIO_CONST_ATTR(in_voltage_sampling_frequency_available, "50 31 16 8");
    401static IIO_CONST_ATTR(in_capacitance_sampling_frequency_available,
    402		       "91 84 50 26 16 13 11 9");
    403
    404static struct attribute *ad7746_attributes[] = {
    405	&iio_dev_attr_in_capacitance0_calibbias_calibration.dev_attr.attr,
    406	&iio_dev_attr_in_capacitance0_calibscale_calibration.dev_attr.attr,
    407	&iio_dev_attr_in_capacitance1_calibscale_calibration.dev_attr.attr,
    408	&iio_dev_attr_in_capacitance1_calibbias_calibration.dev_attr.attr,
    409	&iio_dev_attr_in_voltage0_calibscale_calibration.dev_attr.attr,
    410	&iio_const_attr_in_voltage_sampling_frequency_available.dev_attr.attr,
    411	&iio_const_attr_in_capacitance_sampling_frequency_available.dev_attr.attr,
    412	NULL,
    413};
    414
    415static const struct attribute_group ad7746_attribute_group = {
    416	.attrs = ad7746_attributes,
    417};
    418
    419static int ad7746_write_raw(struct iio_dev *indio_dev,
    420			    struct iio_chan_spec const *chan,
    421			    int val,
    422			    int val2,
    423			    long mask)
    424{
    425	struct ad7746_chip_info *chip = iio_priv(indio_dev);
    426	int ret, reg;
    427
    428	mutex_lock(&chip->lock);
    429
    430	switch (mask) {
    431	case IIO_CHAN_INFO_CALIBSCALE:
    432		if (val != 1) {
    433			ret = -EINVAL;
    434			goto out;
    435		}
    436
    437		val = (val2 * 1024) / 15625;
    438
    439		switch (chan->type) {
    440		case IIO_CAPACITANCE:
    441			reg = AD7746_REG_CAP_GAINH;
    442			break;
    443		case IIO_VOLTAGE:
    444			reg = AD7746_REG_VOLT_GAINH;
    445			break;
    446		default:
    447			ret = -EINVAL;
    448			goto out;
    449		}
    450
    451		ret = i2c_smbus_write_word_swapped(chip->client, reg, val);
    452		if (ret < 0)
    453			goto out;
    454
    455		ret = 0;
    456		break;
    457	case IIO_CHAN_INFO_CALIBBIAS:
    458		if (val < 0 || val > 0xFFFF) {
    459			ret = -EINVAL;
    460			goto out;
    461		}
    462		ret = i2c_smbus_write_word_swapped(chip->client,
    463						   AD7746_REG_CAP_OFFH, val);
    464		if (ret < 0)
    465			goto out;
    466
    467		ret = 0;
    468		break;
    469	case IIO_CHAN_INFO_OFFSET:
    470		if (val < 0 || val > 43008000) { /* 21pF */
    471			ret = -EINVAL;
    472			goto out;
    473		}
    474
    475		/*
    476		 * CAPDAC Scale = 21pF_typ / 127
    477		 * CIN Scale = 8.192pF / 2^24
    478		 * Offset Scale = CAPDAC Scale / CIN Scale = 338646
    479		 */
    480
    481		val /= 338646;
    482
    483		chip->capdac[chan->channel][chan->differential] = val > 0 ?
    484			AD7746_CAPDAC_DACP(val) | AD7746_CAPDAC_DACEN : 0;
    485
    486		ret = ad7746_set_capdac(chip, chan->channel);
    487		if (ret < 0)
    488			goto out;
    489
    490		chip->capdac_set = chan->channel;
    491
    492		ret = 0;
    493		break;
    494	case IIO_CHAN_INFO_SAMP_FREQ:
    495		if (val2) {
    496			ret = -EINVAL;
    497			goto out;
    498		}
    499
    500		switch (chan->type) {
    501		case IIO_CAPACITANCE:
    502			ret = ad7746_store_cap_filter_rate_setup(chip, val);
    503			break;
    504		case IIO_VOLTAGE:
    505			ret = ad7746_store_vt_filter_rate_setup(chip, val);
    506			break;
    507		default:
    508			ret = -EINVAL;
    509		}
    510		break;
    511	default:
    512		ret = -EINVAL;
    513	}
    514
    515out:
    516	mutex_unlock(&chip->lock);
    517	return ret;
    518}
    519
    520static int ad7746_read_raw(struct iio_dev *indio_dev,
    521			   struct iio_chan_spec const *chan,
    522			   int *val, int *val2,
    523			   long mask)
    524{
    525	struct ad7746_chip_info *chip = iio_priv(indio_dev);
    526	int ret, delay, idx;
    527	u8 regval, reg;
    528
    529	mutex_lock(&chip->lock);
    530
    531	switch (mask) {
    532	case IIO_CHAN_INFO_RAW:
    533	case IIO_CHAN_INFO_PROCESSED:
    534		ret = ad7746_select_channel(indio_dev, chan);
    535		if (ret < 0)
    536			goto out;
    537		delay = ret;
    538
    539		regval = chip->config | AD7746_CONF_MODE_SINGLE_CONV;
    540		ret = i2c_smbus_write_byte_data(chip->client, AD7746_REG_CFG,
    541						regval);
    542		if (ret < 0)
    543			goto out;
    544
    545		msleep(delay);
    546		/* Now read the actual register */
    547
    548		ret = i2c_smbus_read_i2c_block_data(chip->client,
    549						    chan->address >> 8, 3,
    550						    &chip->data.d8[1]);
    551
    552		if (ret < 0)
    553			goto out;
    554
    555		*val = (be32_to_cpu(chip->data.d32) & 0xFFFFFF) - 0x800000;
    556
    557		switch (chan->type) {
    558		case IIO_TEMP:
    559			/*
    560			 * temperature in milli degrees Celsius
    561			 * T = ((*val / 2048) - 4096) * 1000
    562			 */
    563			*val = (*val * 125) / 256;
    564			break;
    565		case IIO_VOLTAGE:
    566			if (chan->channel == 1) /* supply_raw*/
    567				*val = *val * 6;
    568			break;
    569		default:
    570			break;
    571		}
    572
    573		ret = IIO_VAL_INT;
    574		break;
    575	case IIO_CHAN_INFO_CALIBSCALE:
    576		switch (chan->type) {
    577		case IIO_CAPACITANCE:
    578			reg = AD7746_REG_CAP_GAINH;
    579			break;
    580		case IIO_VOLTAGE:
    581			reg = AD7746_REG_VOLT_GAINH;
    582			break;
    583		default:
    584			ret = -EINVAL;
    585			goto out;
    586		}
    587
    588		ret = i2c_smbus_read_word_swapped(chip->client, reg);
    589		if (ret < 0)
    590			goto out;
    591		/* 1 + gain_val / 2^16 */
    592		*val = 1;
    593		*val2 = (15625 * ret) / 1024;
    594
    595		ret = IIO_VAL_INT_PLUS_MICRO;
    596		break;
    597	case IIO_CHAN_INFO_CALIBBIAS:
    598		ret = i2c_smbus_read_word_swapped(chip->client,
    599						  AD7746_REG_CAP_OFFH);
    600		if (ret < 0)
    601			goto out;
    602		*val = ret;
    603
    604		ret = IIO_VAL_INT;
    605		break;
    606	case IIO_CHAN_INFO_OFFSET:
    607		*val = AD7746_CAPDAC_DACP(chip->capdac[chan->channel]
    608					  [chan->differential]) * 338646;
    609
    610		ret = IIO_VAL_INT;
    611		break;
    612	case IIO_CHAN_INFO_SCALE:
    613		switch (chan->type) {
    614		case IIO_CAPACITANCE:
    615			/* 8.192pf / 2^24 */
    616			*val =  0;
    617			*val2 = 488;
    618			ret = IIO_VAL_INT_PLUS_NANO;
    619			break;
    620		case IIO_VOLTAGE:
    621			/* 1170mV / 2^23 */
    622			*val = 1170;
    623			*val2 = 23;
    624			ret = IIO_VAL_FRACTIONAL_LOG2;
    625			break;
    626		default:
    627			ret = -EINVAL;
    628			break;
    629		}
    630
    631		break;
    632	case IIO_CHAN_INFO_SAMP_FREQ:
    633		switch (chan->type) {
    634		case IIO_CAPACITANCE:
    635			idx = (chip->config & AD7746_CONF_CAPFS_MASK) >>
    636				AD7746_CONF_CAPFS_SHIFT;
    637			*val = ad7746_cap_filter_rate_table[idx][0];
    638			ret = IIO_VAL_INT;
    639			break;
    640		case IIO_VOLTAGE:
    641			idx = (chip->config & AD7746_CONF_VTFS_MASK) >>
    642				AD7746_CONF_VTFS_SHIFT;
    643			*val = ad7746_vt_filter_rate_table[idx][0];
    644			ret = IIO_VAL_INT;
    645			break;
    646		default:
    647			ret = -EINVAL;
    648		}
    649		break;
    650	default:
    651		ret = -EINVAL;
    652	}
    653out:
    654	mutex_unlock(&chip->lock);
    655	return ret;
    656}
    657
    658static const struct iio_info ad7746_info = {
    659	.attrs = &ad7746_attribute_group,
    660	.read_raw = ad7746_read_raw,
    661	.write_raw = ad7746_write_raw,
    662};
    663
    664static int ad7746_probe(struct i2c_client *client,
    665			const struct i2c_device_id *id)
    666{
    667	struct device *dev = &client->dev;
    668	struct ad7746_chip_info *chip;
    669	struct iio_dev *indio_dev;
    670	unsigned char regval = 0;
    671	unsigned int vdd_permille;
    672	int ret;
    673
    674	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
    675	if (!indio_dev)
    676		return -ENOMEM;
    677	chip = iio_priv(indio_dev);
    678	mutex_init(&chip->lock);
    679	/* this is only used for device removal purposes */
    680	i2c_set_clientdata(client, indio_dev);
    681
    682	chip->client = client;
    683	chip->capdac_set = -1;
    684
    685	indio_dev->name = id->name;
    686	indio_dev->info = &ad7746_info;
    687	indio_dev->channels = ad7746_channels;
    688	if (id->driver_data == 7746)
    689		indio_dev->num_channels = ARRAY_SIZE(ad7746_channels);
    690	else
    691		indio_dev->num_channels =  ARRAY_SIZE(ad7746_channels) - 2;
    692	indio_dev->modes = INDIO_DIRECT_MODE;
    693
    694	if (device_property_read_bool(dev, "adi,exca-output-en")) {
    695		if (device_property_read_bool(dev, "adi,exca-output-invert"))
    696			regval |= AD7746_EXCSETUP_NEXCA;
    697		else
    698			regval |= AD7746_EXCSETUP_EXCA;
    699	}
    700
    701	if (device_property_read_bool(dev, "adi,excb-output-en")) {
    702		if (device_property_read_bool(dev, "adi,excb-output-invert"))
    703			regval |= AD7746_EXCSETUP_NEXCB;
    704		else
    705			regval |= AD7746_EXCSETUP_EXCB;
    706	}
    707
    708	ret = device_property_read_u32(dev, "adi,excitation-vdd-permille",
    709				       &vdd_permille);
    710	if (!ret) {
    711		switch (vdd_permille) {
    712		case 125:
    713			regval |= AD7746_EXCSETUP_EXCLVL(0);
    714			break;
    715		case 250:
    716			regval |= AD7746_EXCSETUP_EXCLVL(1);
    717			break;
    718		case 375:
    719			regval |= AD7746_EXCSETUP_EXCLVL(2);
    720			break;
    721		case 500:
    722			regval |= AD7746_EXCSETUP_EXCLVL(3);
    723			break;
    724		default:
    725			break;
    726		}
    727	}
    728
    729	ret = i2c_smbus_write_byte_data(chip->client,
    730					AD7746_REG_EXC_SETUP, regval);
    731	if (ret < 0)
    732		return ret;
    733
    734	return devm_iio_device_register(indio_dev->dev.parent, indio_dev);
    735}
    736
    737static const struct i2c_device_id ad7746_id[] = {
    738	{ "ad7745", 7745 },
    739	{ "ad7746", 7746 },
    740	{ "ad7747", 7747 },
    741	{}
    742};
    743
    744MODULE_DEVICE_TABLE(i2c, ad7746_id);
    745
    746static const struct of_device_id ad7746_of_match[] = {
    747	{ .compatible = "adi,ad7745" },
    748	{ .compatible = "adi,ad7746" },
    749	{ .compatible = "adi,ad7747" },
    750	{ },
    751};
    752
    753MODULE_DEVICE_TABLE(of, ad7746_of_match);
    754
    755static struct i2c_driver ad7746_driver = {
    756	.driver = {
    757		.name = KBUILD_MODNAME,
    758		.of_match_table = ad7746_of_match,
    759	},
    760	.probe = ad7746_probe,
    761	.id_table = ad7746_id,
    762};
    763module_i2c_driver(ad7746_driver);
    764
    765MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
    766MODULE_DESCRIPTION("Analog Devices AD7746/5/7 capacitive sensor driver");
    767MODULE_LICENSE("GPL v2");