1d03a74bfSMugilraj Dhavachelvan // SPDX-License-Identifier: GPL-2.0+ 2d03a74bfSMugilraj Dhavachelvan /* 3d03a74bfSMugilraj Dhavachelvan * Analog Devices AD5110 digital potentiometer driver 4d03a74bfSMugilraj Dhavachelvan * 5d03a74bfSMugilraj Dhavachelvan * Copyright (C) 2021 Mugilraj Dhavachelvan <dmugil2000@gmail.com> 6d03a74bfSMugilraj Dhavachelvan * 7d03a74bfSMugilraj Dhavachelvan * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/AD5110_5112_5114.pdf 8d03a74bfSMugilraj Dhavachelvan */ 9d03a74bfSMugilraj Dhavachelvan 10d03a74bfSMugilraj Dhavachelvan #include <linux/bitfield.h> 11d03a74bfSMugilraj Dhavachelvan #include <linux/delay.h> 12d03a74bfSMugilraj Dhavachelvan #include <linux/device.h> 13d03a74bfSMugilraj Dhavachelvan #include <linux/i2c.h> 14d03a74bfSMugilraj Dhavachelvan #include <linux/module.h> 15d03a74bfSMugilraj Dhavachelvan 16d03a74bfSMugilraj Dhavachelvan #include <linux/iio/iio.h> 17d03a74bfSMugilraj Dhavachelvan #include <linux/iio/sysfs.h> 18d03a74bfSMugilraj Dhavachelvan 19d03a74bfSMugilraj Dhavachelvan /* AD5110 commands */ 20d03a74bfSMugilraj Dhavachelvan #define AD5110_EEPROM_WR 1 21d03a74bfSMugilraj Dhavachelvan #define AD5110_RDAC_WR 2 22d03a74bfSMugilraj Dhavachelvan #define AD5110_SHUTDOWN 3 23d03a74bfSMugilraj Dhavachelvan #define AD5110_RESET 4 24d03a74bfSMugilraj Dhavachelvan #define AD5110_RDAC_RD 5 25d03a74bfSMugilraj Dhavachelvan #define AD5110_EEPROM_RD 6 26d03a74bfSMugilraj Dhavachelvan 27d03a74bfSMugilraj Dhavachelvan /* AD5110_EEPROM_RD data */ 28d03a74bfSMugilraj Dhavachelvan #define AD5110_WIPER_POS 0 29d03a74bfSMugilraj Dhavachelvan #define AD5110_RESISTOR_TOL 1 30d03a74bfSMugilraj Dhavachelvan 31d03a74bfSMugilraj Dhavachelvan #define AD5110_WIPER_RESISTANCE 70 32d03a74bfSMugilraj Dhavachelvan 33d03a74bfSMugilraj Dhavachelvan struct ad5110_cfg { 34d03a74bfSMugilraj Dhavachelvan int max_pos; 35d03a74bfSMugilraj Dhavachelvan int kohms; 36d03a74bfSMugilraj Dhavachelvan int shift; 37d03a74bfSMugilraj Dhavachelvan }; 38d03a74bfSMugilraj Dhavachelvan 39d03a74bfSMugilraj Dhavachelvan enum ad5110_type { 40d03a74bfSMugilraj Dhavachelvan AD5110_10, 41d03a74bfSMugilraj Dhavachelvan AD5110_80, 42d03a74bfSMugilraj Dhavachelvan AD5112_05, 43d03a74bfSMugilraj Dhavachelvan AD5112_10, 44d03a74bfSMugilraj Dhavachelvan AD5112_80, 45d03a74bfSMugilraj Dhavachelvan AD5114_10, 46d03a74bfSMugilraj Dhavachelvan AD5114_80, 47d03a74bfSMugilraj Dhavachelvan }; 48d03a74bfSMugilraj Dhavachelvan 49d03a74bfSMugilraj Dhavachelvan static const struct ad5110_cfg ad5110_cfg[] = { 50d03a74bfSMugilraj Dhavachelvan [AD5110_10] = { .max_pos = 128, .kohms = 10 }, 51d03a74bfSMugilraj Dhavachelvan [AD5110_80] = { .max_pos = 128, .kohms = 80 }, 52d03a74bfSMugilraj Dhavachelvan [AD5112_05] = { .max_pos = 64, .kohms = 5, .shift = 1 }, 53d03a74bfSMugilraj Dhavachelvan [AD5112_10] = { .max_pos = 64, .kohms = 10, .shift = 1 }, 54d03a74bfSMugilraj Dhavachelvan [AD5112_80] = { .max_pos = 64, .kohms = 80, .shift = 1 }, 55d03a74bfSMugilraj Dhavachelvan [AD5114_10] = { .max_pos = 32, .kohms = 10, .shift = 2 }, 56d03a74bfSMugilraj Dhavachelvan [AD5114_80] = { .max_pos = 32, .kohms = 80, .shift = 2 }, 57d03a74bfSMugilraj Dhavachelvan }; 58d03a74bfSMugilraj Dhavachelvan 59d03a74bfSMugilraj Dhavachelvan struct ad5110_data { 60d03a74bfSMugilraj Dhavachelvan struct i2c_client *client; 61d03a74bfSMugilraj Dhavachelvan s16 tol; /* resistor tolerance */ 62d03a74bfSMugilraj Dhavachelvan bool enable; 63d03a74bfSMugilraj Dhavachelvan struct mutex lock; 64d03a74bfSMugilraj Dhavachelvan const struct ad5110_cfg *cfg; 65d03a74bfSMugilraj Dhavachelvan /* 66*b5841c38SJonathan Cameron * DMA (thus cache coherency maintenance) may require the 67d03a74bfSMugilraj Dhavachelvan * transfer buffers to live in their own cache lines. 68d03a74bfSMugilraj Dhavachelvan */ 69*b5841c38SJonathan Cameron u8 buf[2] __aligned(IIO_DMA_MINALIGN); 70d03a74bfSMugilraj Dhavachelvan }; 71d03a74bfSMugilraj Dhavachelvan 72d03a74bfSMugilraj Dhavachelvan static const struct iio_chan_spec ad5110_channels[] = { 73d03a74bfSMugilraj Dhavachelvan { 74d03a74bfSMugilraj Dhavachelvan .type = IIO_RESISTANCE, 75d03a74bfSMugilraj Dhavachelvan .output = 1, 76d03a74bfSMugilraj Dhavachelvan .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_OFFSET) | 77d03a74bfSMugilraj Dhavachelvan BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_ENABLE), 78d03a74bfSMugilraj Dhavachelvan }, 79d03a74bfSMugilraj Dhavachelvan }; 80d03a74bfSMugilraj Dhavachelvan 81d03a74bfSMugilraj Dhavachelvan static int ad5110_read(struct ad5110_data *data, u8 cmd, int *val) 82d03a74bfSMugilraj Dhavachelvan { 83d03a74bfSMugilraj Dhavachelvan int ret; 84d03a74bfSMugilraj Dhavachelvan 85d03a74bfSMugilraj Dhavachelvan mutex_lock(&data->lock); 86d03a74bfSMugilraj Dhavachelvan data->buf[0] = cmd; 87d03a74bfSMugilraj Dhavachelvan data->buf[1] = *val; 88d03a74bfSMugilraj Dhavachelvan 89d03a74bfSMugilraj Dhavachelvan ret = i2c_master_send_dmasafe(data->client, data->buf, sizeof(data->buf)); 90d03a74bfSMugilraj Dhavachelvan if (ret < 0) { 91d03a74bfSMugilraj Dhavachelvan goto error; 92d03a74bfSMugilraj Dhavachelvan } else if (ret != sizeof(data->buf)) { 93d03a74bfSMugilraj Dhavachelvan ret = -EIO; 94d03a74bfSMugilraj Dhavachelvan goto error; 95d03a74bfSMugilraj Dhavachelvan } 96d03a74bfSMugilraj Dhavachelvan 97d03a74bfSMugilraj Dhavachelvan ret = i2c_master_recv_dmasafe(data->client, data->buf, 1); 98d03a74bfSMugilraj Dhavachelvan if (ret < 0) { 99d03a74bfSMugilraj Dhavachelvan goto error; 100d03a74bfSMugilraj Dhavachelvan } else if (ret != 1) { 101d03a74bfSMugilraj Dhavachelvan ret = -EIO; 102d03a74bfSMugilraj Dhavachelvan goto error; 103d03a74bfSMugilraj Dhavachelvan } 104d03a74bfSMugilraj Dhavachelvan 105d03a74bfSMugilraj Dhavachelvan *val = data->buf[0]; 106d03a74bfSMugilraj Dhavachelvan ret = 0; 107d03a74bfSMugilraj Dhavachelvan 108d03a74bfSMugilraj Dhavachelvan error: 109d03a74bfSMugilraj Dhavachelvan mutex_unlock(&data->lock); 110d03a74bfSMugilraj Dhavachelvan return ret; 111d03a74bfSMugilraj Dhavachelvan } 112d03a74bfSMugilraj Dhavachelvan 113d03a74bfSMugilraj Dhavachelvan static int ad5110_write(struct ad5110_data *data, u8 cmd, u8 val) 114d03a74bfSMugilraj Dhavachelvan { 115d03a74bfSMugilraj Dhavachelvan int ret; 116d03a74bfSMugilraj Dhavachelvan 117d03a74bfSMugilraj Dhavachelvan mutex_lock(&data->lock); 118d03a74bfSMugilraj Dhavachelvan data->buf[0] = cmd; 119d03a74bfSMugilraj Dhavachelvan data->buf[1] = val; 120d03a74bfSMugilraj Dhavachelvan 121d03a74bfSMugilraj Dhavachelvan ret = i2c_master_send_dmasafe(data->client, data->buf, sizeof(data->buf)); 122d03a74bfSMugilraj Dhavachelvan if (ret < 0) { 123d03a74bfSMugilraj Dhavachelvan goto error; 124d03a74bfSMugilraj Dhavachelvan } else if (ret != sizeof(data->buf)) { 125d03a74bfSMugilraj Dhavachelvan ret = -EIO; 126d03a74bfSMugilraj Dhavachelvan goto error; 127d03a74bfSMugilraj Dhavachelvan } 128d03a74bfSMugilraj Dhavachelvan 129d03a74bfSMugilraj Dhavachelvan ret = 0; 130d03a74bfSMugilraj Dhavachelvan 131d03a74bfSMugilraj Dhavachelvan error: 132d03a74bfSMugilraj Dhavachelvan mutex_unlock(&data->lock); 133d03a74bfSMugilraj Dhavachelvan return ret; 134d03a74bfSMugilraj Dhavachelvan } 135d03a74bfSMugilraj Dhavachelvan 136d03a74bfSMugilraj Dhavachelvan static int ad5110_resistor_tol(struct ad5110_data *data, u8 cmd, int val) 137d03a74bfSMugilraj Dhavachelvan { 138d03a74bfSMugilraj Dhavachelvan int ret; 139d03a74bfSMugilraj Dhavachelvan 140d03a74bfSMugilraj Dhavachelvan ret = ad5110_read(data, cmd, &val); 141d03a74bfSMugilraj Dhavachelvan if (ret) 142d03a74bfSMugilraj Dhavachelvan return ret; 143d03a74bfSMugilraj Dhavachelvan 144d03a74bfSMugilraj Dhavachelvan data->tol = data->cfg->kohms * (val & GENMASK(6, 0)) * 10 / 8; 145d03a74bfSMugilraj Dhavachelvan if (!(val & BIT(7))) 146d03a74bfSMugilraj Dhavachelvan data->tol *= -1; 147d03a74bfSMugilraj Dhavachelvan 148d03a74bfSMugilraj Dhavachelvan return 0; 149d03a74bfSMugilraj Dhavachelvan } 150d03a74bfSMugilraj Dhavachelvan 151d03a74bfSMugilraj Dhavachelvan static ssize_t store_eeprom_show(struct device *dev, 152d03a74bfSMugilraj Dhavachelvan struct device_attribute *attr, 153d03a74bfSMugilraj Dhavachelvan char *buf) 154d03a74bfSMugilraj Dhavachelvan { 155d03a74bfSMugilraj Dhavachelvan struct iio_dev *indio_dev = dev_to_iio_dev(dev); 156d03a74bfSMugilraj Dhavachelvan struct ad5110_data *data = iio_priv(indio_dev); 157d03a74bfSMugilraj Dhavachelvan int val = AD5110_WIPER_POS; 158d03a74bfSMugilraj Dhavachelvan int ret; 159d03a74bfSMugilraj Dhavachelvan 160d03a74bfSMugilraj Dhavachelvan ret = ad5110_read(data, AD5110_EEPROM_RD, &val); 161d03a74bfSMugilraj Dhavachelvan if (ret) 162d03a74bfSMugilraj Dhavachelvan return ret; 163d03a74bfSMugilraj Dhavachelvan 164d03a74bfSMugilraj Dhavachelvan val = val >> data->cfg->shift; 165d03a74bfSMugilraj Dhavachelvan return iio_format_value(buf, IIO_VAL_INT, 1, &val); 166d03a74bfSMugilraj Dhavachelvan } 167d03a74bfSMugilraj Dhavachelvan 168d03a74bfSMugilraj Dhavachelvan static ssize_t store_eeprom_store(struct device *dev, 169d03a74bfSMugilraj Dhavachelvan struct device_attribute *attr, 170d03a74bfSMugilraj Dhavachelvan const char *buf, size_t len) 171d03a74bfSMugilraj Dhavachelvan { 172d03a74bfSMugilraj Dhavachelvan struct iio_dev *indio_dev = dev_to_iio_dev(dev); 173d03a74bfSMugilraj Dhavachelvan struct ad5110_data *data = iio_priv(indio_dev); 174d03a74bfSMugilraj Dhavachelvan int ret; 175d03a74bfSMugilraj Dhavachelvan 176d03a74bfSMugilraj Dhavachelvan ret = ad5110_write(data, AD5110_EEPROM_WR, 0); 177d03a74bfSMugilraj Dhavachelvan if (ret) { 178d03a74bfSMugilraj Dhavachelvan dev_err(&data->client->dev, "RDAC to EEPROM write failed\n"); 179d03a74bfSMugilraj Dhavachelvan return ret; 180d03a74bfSMugilraj Dhavachelvan } 181d03a74bfSMugilraj Dhavachelvan 182d03a74bfSMugilraj Dhavachelvan /* The storing of EEPROM data takes approximately 18 ms. */ 183d03a74bfSMugilraj Dhavachelvan msleep(20); 184d03a74bfSMugilraj Dhavachelvan 185d03a74bfSMugilraj Dhavachelvan return len; 186d03a74bfSMugilraj Dhavachelvan } 187d03a74bfSMugilraj Dhavachelvan 188d03a74bfSMugilraj Dhavachelvan static IIO_DEVICE_ATTR_RW(store_eeprom, 0); 189d03a74bfSMugilraj Dhavachelvan 190d03a74bfSMugilraj Dhavachelvan static struct attribute *ad5110_attributes[] = { 191d03a74bfSMugilraj Dhavachelvan &iio_dev_attr_store_eeprom.dev_attr.attr, 192d03a74bfSMugilraj Dhavachelvan NULL 193d03a74bfSMugilraj Dhavachelvan }; 194d03a74bfSMugilraj Dhavachelvan 195d03a74bfSMugilraj Dhavachelvan static const struct attribute_group ad5110_attribute_group = { 196d03a74bfSMugilraj Dhavachelvan .attrs = ad5110_attributes, 197d03a74bfSMugilraj Dhavachelvan }; 198d03a74bfSMugilraj Dhavachelvan 199d03a74bfSMugilraj Dhavachelvan static int ad5110_read_raw(struct iio_dev *indio_dev, 200d03a74bfSMugilraj Dhavachelvan struct iio_chan_spec const *chan, 201d03a74bfSMugilraj Dhavachelvan int *val, int *val2, long mask) 202d03a74bfSMugilraj Dhavachelvan { 203d03a74bfSMugilraj Dhavachelvan struct ad5110_data *data = iio_priv(indio_dev); 204d03a74bfSMugilraj Dhavachelvan int ret; 205d03a74bfSMugilraj Dhavachelvan 206d03a74bfSMugilraj Dhavachelvan switch (mask) { 207d03a74bfSMugilraj Dhavachelvan case IIO_CHAN_INFO_RAW: 208d03a74bfSMugilraj Dhavachelvan ret = ad5110_read(data, AD5110_RDAC_RD, val); 209d03a74bfSMugilraj Dhavachelvan if (ret) 210d03a74bfSMugilraj Dhavachelvan return ret; 211d03a74bfSMugilraj Dhavachelvan 212d03a74bfSMugilraj Dhavachelvan *val = *val >> data->cfg->shift; 213d03a74bfSMugilraj Dhavachelvan return IIO_VAL_INT; 214d03a74bfSMugilraj Dhavachelvan case IIO_CHAN_INFO_OFFSET: 215d03a74bfSMugilraj Dhavachelvan *val = AD5110_WIPER_RESISTANCE * data->cfg->max_pos; 216d03a74bfSMugilraj Dhavachelvan *val2 = 1000 * data->cfg->kohms + data->tol; 217d03a74bfSMugilraj Dhavachelvan return IIO_VAL_FRACTIONAL; 218d03a74bfSMugilraj Dhavachelvan case IIO_CHAN_INFO_SCALE: 219d03a74bfSMugilraj Dhavachelvan *val = 1000 * data->cfg->kohms + data->tol; 220d03a74bfSMugilraj Dhavachelvan *val2 = data->cfg->max_pos; 221d03a74bfSMugilraj Dhavachelvan return IIO_VAL_FRACTIONAL; 222d03a74bfSMugilraj Dhavachelvan case IIO_CHAN_INFO_ENABLE: 223d03a74bfSMugilraj Dhavachelvan *val = data->enable; 224d03a74bfSMugilraj Dhavachelvan return IIO_VAL_INT; 225d03a74bfSMugilraj Dhavachelvan default: 226d03a74bfSMugilraj Dhavachelvan return -EINVAL; 227d03a74bfSMugilraj Dhavachelvan } 228d03a74bfSMugilraj Dhavachelvan } 229d03a74bfSMugilraj Dhavachelvan 230d03a74bfSMugilraj Dhavachelvan static int ad5110_write_raw(struct iio_dev *indio_dev, 231d03a74bfSMugilraj Dhavachelvan struct iio_chan_spec const *chan, 232d03a74bfSMugilraj Dhavachelvan int val, int val2, long mask) 233d03a74bfSMugilraj Dhavachelvan { 234d03a74bfSMugilraj Dhavachelvan struct ad5110_data *data = iio_priv(indio_dev); 235d03a74bfSMugilraj Dhavachelvan int ret; 236d03a74bfSMugilraj Dhavachelvan 237d03a74bfSMugilraj Dhavachelvan switch (mask) { 238d03a74bfSMugilraj Dhavachelvan case IIO_CHAN_INFO_RAW: 239d03a74bfSMugilraj Dhavachelvan if (val > data->cfg->max_pos || val < 0) 240d03a74bfSMugilraj Dhavachelvan return -EINVAL; 241d03a74bfSMugilraj Dhavachelvan 242d03a74bfSMugilraj Dhavachelvan return ad5110_write(data, AD5110_RDAC_WR, val << data->cfg->shift); 243d03a74bfSMugilraj Dhavachelvan case IIO_CHAN_INFO_ENABLE: 244d03a74bfSMugilraj Dhavachelvan if (val < 0 || val > 1) 245d03a74bfSMugilraj Dhavachelvan return -EINVAL; 246d03a74bfSMugilraj Dhavachelvan if (data->enable == val) 247d03a74bfSMugilraj Dhavachelvan return 0; 248d03a74bfSMugilraj Dhavachelvan ret = ad5110_write(data, AD5110_SHUTDOWN, val ? 0 : 1); 249d03a74bfSMugilraj Dhavachelvan if (ret) 250d03a74bfSMugilraj Dhavachelvan return ret; 251d03a74bfSMugilraj Dhavachelvan data->enable = val; 252d03a74bfSMugilraj Dhavachelvan return 0; 253d03a74bfSMugilraj Dhavachelvan default: 254d03a74bfSMugilraj Dhavachelvan return -EINVAL; 255d03a74bfSMugilraj Dhavachelvan } 256d03a74bfSMugilraj Dhavachelvan } 257d03a74bfSMugilraj Dhavachelvan 258d03a74bfSMugilraj Dhavachelvan static const struct iio_info ad5110_info = { 259d03a74bfSMugilraj Dhavachelvan .read_raw = ad5110_read_raw, 260d03a74bfSMugilraj Dhavachelvan .write_raw = ad5110_write_raw, 261d03a74bfSMugilraj Dhavachelvan .attrs = &ad5110_attribute_group, 262d03a74bfSMugilraj Dhavachelvan }; 263d03a74bfSMugilraj Dhavachelvan 264d03a74bfSMugilraj Dhavachelvan #define AD5110_COMPATIBLE(of_compatible, cfg) { \ 265d03a74bfSMugilraj Dhavachelvan .compatible = of_compatible, \ 266d03a74bfSMugilraj Dhavachelvan .data = &ad5110_cfg[cfg], \ 267d03a74bfSMugilraj Dhavachelvan } 268d03a74bfSMugilraj Dhavachelvan 269d03a74bfSMugilraj Dhavachelvan static const struct of_device_id ad5110_of_match[] = { 270d03a74bfSMugilraj Dhavachelvan AD5110_COMPATIBLE("adi,ad5110-10", AD5110_10), 271d03a74bfSMugilraj Dhavachelvan AD5110_COMPATIBLE("adi,ad5110-80", AD5110_80), 272d03a74bfSMugilraj Dhavachelvan AD5110_COMPATIBLE("adi,ad5112-05", AD5112_05), 273d03a74bfSMugilraj Dhavachelvan AD5110_COMPATIBLE("adi,ad5112-10", AD5112_10), 274d03a74bfSMugilraj Dhavachelvan AD5110_COMPATIBLE("adi,ad5112-80", AD5112_80), 275d03a74bfSMugilraj Dhavachelvan AD5110_COMPATIBLE("adi,ad5114-10", AD5114_10), 276d03a74bfSMugilraj Dhavachelvan AD5110_COMPATIBLE("adi,ad5114-80", AD5114_80), 277d03a74bfSMugilraj Dhavachelvan { } 278d03a74bfSMugilraj Dhavachelvan }; 279d03a74bfSMugilraj Dhavachelvan MODULE_DEVICE_TABLE(of, ad5110_of_match); 280d03a74bfSMugilraj Dhavachelvan 281d03a74bfSMugilraj Dhavachelvan static const struct i2c_device_id ad5110_id[] = { 282d03a74bfSMugilraj Dhavachelvan { "ad5110-10", AD5110_10 }, 283d03a74bfSMugilraj Dhavachelvan { "ad5110-80", AD5110_80 }, 284d03a74bfSMugilraj Dhavachelvan { "ad5112-05", AD5112_05 }, 285d03a74bfSMugilraj Dhavachelvan { "ad5112-10", AD5112_10 }, 286d03a74bfSMugilraj Dhavachelvan { "ad5112-80", AD5112_80 }, 287d03a74bfSMugilraj Dhavachelvan { "ad5114-10", AD5114_10 }, 288d03a74bfSMugilraj Dhavachelvan { "ad5114-80", AD5114_80 }, 289d03a74bfSMugilraj Dhavachelvan { } 290d03a74bfSMugilraj Dhavachelvan }; 291d03a74bfSMugilraj Dhavachelvan MODULE_DEVICE_TABLE(i2c, ad5110_id); 292d03a74bfSMugilraj Dhavachelvan 293d03a74bfSMugilraj Dhavachelvan static int ad5110_probe(struct i2c_client *client) 294d03a74bfSMugilraj Dhavachelvan { 295d03a74bfSMugilraj Dhavachelvan struct device *dev = &client->dev; 296d03a74bfSMugilraj Dhavachelvan struct iio_dev *indio_dev; 297d03a74bfSMugilraj Dhavachelvan struct ad5110_data *data; 298d03a74bfSMugilraj Dhavachelvan int ret; 299d03a74bfSMugilraj Dhavachelvan 300d03a74bfSMugilraj Dhavachelvan indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 301d03a74bfSMugilraj Dhavachelvan if (!indio_dev) 302d03a74bfSMugilraj Dhavachelvan return -ENOMEM; 303d03a74bfSMugilraj Dhavachelvan 304d03a74bfSMugilraj Dhavachelvan data = iio_priv(indio_dev); 305d03a74bfSMugilraj Dhavachelvan data->client = client; 306d03a74bfSMugilraj Dhavachelvan mutex_init(&data->lock); 307d03a74bfSMugilraj Dhavachelvan data->enable = 1; 308d03a74bfSMugilraj Dhavachelvan data->cfg = device_get_match_data(dev); 309d03a74bfSMugilraj Dhavachelvan 310d03a74bfSMugilraj Dhavachelvan /* refresh RDAC register with EEPROM */ 311d03a74bfSMugilraj Dhavachelvan ret = ad5110_write(data, AD5110_RESET, 0); 312d03a74bfSMugilraj Dhavachelvan if (ret) { 313d03a74bfSMugilraj Dhavachelvan dev_err(dev, "Refresh RDAC with EEPROM failed\n"); 314d03a74bfSMugilraj Dhavachelvan return ret; 315d03a74bfSMugilraj Dhavachelvan } 316d03a74bfSMugilraj Dhavachelvan 317d03a74bfSMugilraj Dhavachelvan ret = ad5110_resistor_tol(data, AD5110_EEPROM_RD, AD5110_RESISTOR_TOL); 318d03a74bfSMugilraj Dhavachelvan if (ret) { 319d03a74bfSMugilraj Dhavachelvan dev_err(dev, "Read resistor tolerance failed\n"); 320d03a74bfSMugilraj Dhavachelvan return ret; 321d03a74bfSMugilraj Dhavachelvan } 322d03a74bfSMugilraj Dhavachelvan 323d03a74bfSMugilraj Dhavachelvan indio_dev->modes = INDIO_DIRECT_MODE; 324d03a74bfSMugilraj Dhavachelvan indio_dev->info = &ad5110_info; 325d03a74bfSMugilraj Dhavachelvan indio_dev->channels = ad5110_channels; 326d03a74bfSMugilraj Dhavachelvan indio_dev->num_channels = ARRAY_SIZE(ad5110_channels); 327d03a74bfSMugilraj Dhavachelvan indio_dev->name = client->name; 328d03a74bfSMugilraj Dhavachelvan 329d03a74bfSMugilraj Dhavachelvan return devm_iio_device_register(dev, indio_dev); 330d03a74bfSMugilraj Dhavachelvan } 331d03a74bfSMugilraj Dhavachelvan 332d03a74bfSMugilraj Dhavachelvan static struct i2c_driver ad5110_driver = { 333d03a74bfSMugilraj Dhavachelvan .driver = { 334d03a74bfSMugilraj Dhavachelvan .name = "ad5110", 335d03a74bfSMugilraj Dhavachelvan .of_match_table = ad5110_of_match, 336d03a74bfSMugilraj Dhavachelvan }, 337d03a74bfSMugilraj Dhavachelvan .probe_new = ad5110_probe, 338d03a74bfSMugilraj Dhavachelvan .id_table = ad5110_id, 339d03a74bfSMugilraj Dhavachelvan }; 340d03a74bfSMugilraj Dhavachelvan module_i2c_driver(ad5110_driver); 341d03a74bfSMugilraj Dhavachelvan 342d03a74bfSMugilraj Dhavachelvan MODULE_AUTHOR("Mugilraj Dhavachelvan <dmugil2000@gmail.com>"); 343d03a74bfSMugilraj Dhavachelvan MODULE_DESCRIPTION("AD5110 digital potentiometer"); 344d03a74bfSMugilraj Dhavachelvan MODULE_LICENSE("GPL v2"); 345