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