1 /* 2 * Industrial I/O driver for Microchip digital potentiometers 3 * Copyright (c) 2015 Axentia Technologies AB 4 * Author: Peter Rosin <peda@axentia.se> 5 * 6 * Datasheet: http://www.microchip.com/downloads/en/DeviceDoc/22096b.pdf 7 * 8 * DEVID #Wipers #Positions Resistor Opts (kOhm) i2c address 9 * mcp4531 1 129 5, 10, 50, 100 010111x 10 * mcp4532 1 129 5, 10, 50, 100 01011xx 11 * mcp4541 1 129 5, 10, 50, 100 010111x 12 * mcp4542 1 129 5, 10, 50, 100 01011xx 13 * mcp4551 1 257 5, 10, 50, 100 010111x 14 * mcp4552 1 257 5, 10, 50, 100 01011xx 15 * mcp4561 1 257 5, 10, 50, 100 010111x 16 * mcp4562 1 257 5, 10, 50, 100 01011xx 17 * mcp4631 2 129 5, 10, 50, 100 0101xxx 18 * mcp4632 2 129 5, 10, 50, 100 01011xx 19 * mcp4641 2 129 5, 10, 50, 100 0101xxx 20 * mcp4642 2 129 5, 10, 50, 100 01011xx 21 * mcp4651 2 257 5, 10, 50, 100 0101xxx 22 * mcp4652 2 257 5, 10, 50, 100 01011xx 23 * mcp4661 2 257 5, 10, 50, 100 0101xxx 24 * mcp4662 2 257 5, 10, 50, 100 01011xx 25 * 26 * This program is free software; you can redistribute it and/or modify it 27 * under the terms of the GNU General Public License version 2 as published by 28 * the Free Software Foundation. 29 */ 30 31 #include <linux/module.h> 32 #include <linux/i2c.h> 33 #include <linux/err.h> 34 #include <linux/of.h> 35 #include <linux/of_device.h> 36 37 #include <linux/iio/iio.h> 38 39 struct mcp4531_cfg { 40 int wipers; 41 int avail[3]; 42 int kohms; 43 }; 44 45 enum mcp4531_type { 46 MCP453x_502, 47 MCP453x_103, 48 MCP453x_503, 49 MCP453x_104, 50 MCP454x_502, 51 MCP454x_103, 52 MCP454x_503, 53 MCP454x_104, 54 MCP455x_502, 55 MCP455x_103, 56 MCP455x_503, 57 MCP455x_104, 58 MCP456x_502, 59 MCP456x_103, 60 MCP456x_503, 61 MCP456x_104, 62 MCP463x_502, 63 MCP463x_103, 64 MCP463x_503, 65 MCP463x_104, 66 MCP464x_502, 67 MCP464x_103, 68 MCP464x_503, 69 MCP464x_104, 70 MCP465x_502, 71 MCP465x_103, 72 MCP465x_503, 73 MCP465x_104, 74 MCP466x_502, 75 MCP466x_103, 76 MCP466x_503, 77 MCP466x_104, 78 }; 79 80 static const struct mcp4531_cfg mcp4531_cfg[] = { 81 [MCP453x_502] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 5, }, 82 [MCP453x_103] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 10, }, 83 [MCP453x_503] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 50, }, 84 [MCP453x_104] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 100, }, 85 [MCP454x_502] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 5, }, 86 [MCP454x_103] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 10, }, 87 [MCP454x_503] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 50, }, 88 [MCP454x_104] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 100, }, 89 [MCP455x_502] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 5, }, 90 [MCP455x_103] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 10, }, 91 [MCP455x_503] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 50, }, 92 [MCP455x_104] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 100, }, 93 [MCP456x_502] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 5, }, 94 [MCP456x_103] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 10, }, 95 [MCP456x_503] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 50, }, 96 [MCP456x_104] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 100, }, 97 [MCP463x_502] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 5, }, 98 [MCP463x_103] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 10, }, 99 [MCP463x_503] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 50, }, 100 [MCP463x_104] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 100, }, 101 [MCP464x_502] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 5, }, 102 [MCP464x_103] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 10, }, 103 [MCP464x_503] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 50, }, 104 [MCP464x_104] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 100, }, 105 [MCP465x_502] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 5, }, 106 [MCP465x_103] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 10, }, 107 [MCP465x_503] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 50, }, 108 [MCP465x_104] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 100, }, 109 [MCP466x_502] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 5, }, 110 [MCP466x_103] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 10, }, 111 [MCP466x_503] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 50, }, 112 [MCP466x_104] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 100, }, 113 }; 114 115 #define MCP4531_WRITE (0 << 2) 116 #define MCP4531_INCR (1 << 2) 117 #define MCP4531_DECR (2 << 2) 118 #define MCP4531_READ (3 << 2) 119 120 #define MCP4531_WIPER_SHIFT (4) 121 122 struct mcp4531_data { 123 struct i2c_client *client; 124 const struct mcp4531_cfg *cfg; 125 }; 126 127 #define MCP4531_CHANNEL(ch) { \ 128 .type = IIO_RESISTANCE, \ 129 .indexed = 1, \ 130 .output = 1, \ 131 .channel = (ch), \ 132 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 133 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 134 .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_RAW), \ 135 } 136 137 static const struct iio_chan_spec mcp4531_channels[] = { 138 MCP4531_CHANNEL(0), 139 MCP4531_CHANNEL(1), 140 }; 141 142 static int mcp4531_read_raw(struct iio_dev *indio_dev, 143 struct iio_chan_spec const *chan, 144 int *val, int *val2, long mask) 145 { 146 struct mcp4531_data *data = iio_priv(indio_dev); 147 int address = chan->channel << MCP4531_WIPER_SHIFT; 148 s32 ret; 149 150 switch (mask) { 151 case IIO_CHAN_INFO_RAW: 152 ret = i2c_smbus_read_word_swapped(data->client, 153 MCP4531_READ | address); 154 if (ret < 0) 155 return ret; 156 *val = ret; 157 return IIO_VAL_INT; 158 case IIO_CHAN_INFO_SCALE: 159 *val = 1000 * data->cfg->kohms; 160 *val2 = data->cfg->avail[2]; 161 return IIO_VAL_FRACTIONAL; 162 } 163 164 return -EINVAL; 165 } 166 167 static int mcp4531_read_avail(struct iio_dev *indio_dev, 168 struct iio_chan_spec const *chan, 169 const int **vals, int *type, int *length, 170 long mask) 171 { 172 struct mcp4531_data *data = iio_priv(indio_dev); 173 174 switch (mask) { 175 case IIO_CHAN_INFO_RAW: 176 *length = ARRAY_SIZE(data->cfg->avail); 177 *vals = data->cfg->avail; 178 *type = IIO_VAL_INT; 179 return IIO_AVAIL_RANGE; 180 } 181 182 return -EINVAL; 183 } 184 185 static int mcp4531_write_raw(struct iio_dev *indio_dev, 186 struct iio_chan_spec const *chan, 187 int val, int val2, long mask) 188 { 189 struct mcp4531_data *data = iio_priv(indio_dev); 190 int address = chan->channel << MCP4531_WIPER_SHIFT; 191 192 switch (mask) { 193 case IIO_CHAN_INFO_RAW: 194 if (val > data->cfg->avail[2] || val < 0) 195 return -EINVAL; 196 break; 197 default: 198 return -EINVAL; 199 } 200 201 return i2c_smbus_write_byte_data(data->client, 202 MCP4531_WRITE | address | (val >> 8), 203 val & 0xff); 204 } 205 206 static const struct iio_info mcp4531_info = { 207 .read_raw = mcp4531_read_raw, 208 .read_avail = mcp4531_read_avail, 209 .write_raw = mcp4531_write_raw, 210 }; 211 212 static const struct i2c_device_id mcp4531_id[] = { 213 { "mcp4531-502", MCP453x_502 }, 214 { "mcp4531-103", MCP453x_103 }, 215 { "mcp4531-503", MCP453x_503 }, 216 { "mcp4531-104", MCP453x_104 }, 217 { "mcp4532-502", MCP453x_502 }, 218 { "mcp4532-103", MCP453x_103 }, 219 { "mcp4532-503", MCP453x_503 }, 220 { "mcp4532-104", MCP453x_104 }, 221 { "mcp4541-502", MCP454x_502 }, 222 { "mcp4541-103", MCP454x_103 }, 223 { "mcp4541-503", MCP454x_503 }, 224 { "mcp4541-104", MCP454x_104 }, 225 { "mcp4542-502", MCP454x_502 }, 226 { "mcp4542-103", MCP454x_103 }, 227 { "mcp4542-503", MCP454x_503 }, 228 { "mcp4542-104", MCP454x_104 }, 229 { "mcp4551-502", MCP455x_502 }, 230 { "mcp4551-103", MCP455x_103 }, 231 { "mcp4551-503", MCP455x_503 }, 232 { "mcp4551-104", MCP455x_104 }, 233 { "mcp4552-502", MCP455x_502 }, 234 { "mcp4552-103", MCP455x_103 }, 235 { "mcp4552-503", MCP455x_503 }, 236 { "mcp4552-104", MCP455x_104 }, 237 { "mcp4561-502", MCP456x_502 }, 238 { "mcp4561-103", MCP456x_103 }, 239 { "mcp4561-503", MCP456x_503 }, 240 { "mcp4561-104", MCP456x_104 }, 241 { "mcp4562-502", MCP456x_502 }, 242 { "mcp4562-103", MCP456x_103 }, 243 { "mcp4562-503", MCP456x_503 }, 244 { "mcp4562-104", MCP456x_104 }, 245 { "mcp4631-502", MCP463x_502 }, 246 { "mcp4631-103", MCP463x_103 }, 247 { "mcp4631-503", MCP463x_503 }, 248 { "mcp4631-104", MCP463x_104 }, 249 { "mcp4632-502", MCP463x_502 }, 250 { "mcp4632-103", MCP463x_103 }, 251 { "mcp4632-503", MCP463x_503 }, 252 { "mcp4632-104", MCP463x_104 }, 253 { "mcp4641-502", MCP464x_502 }, 254 { "mcp4641-103", MCP464x_103 }, 255 { "mcp4641-503", MCP464x_503 }, 256 { "mcp4641-104", MCP464x_104 }, 257 { "mcp4642-502", MCP464x_502 }, 258 { "mcp4642-103", MCP464x_103 }, 259 { "mcp4642-503", MCP464x_503 }, 260 { "mcp4642-104", MCP464x_104 }, 261 { "mcp4651-502", MCP465x_502 }, 262 { "mcp4651-103", MCP465x_103 }, 263 { "mcp4651-503", MCP465x_503 }, 264 { "mcp4651-104", MCP465x_104 }, 265 { "mcp4652-502", MCP465x_502 }, 266 { "mcp4652-103", MCP465x_103 }, 267 { "mcp4652-503", MCP465x_503 }, 268 { "mcp4652-104", MCP465x_104 }, 269 { "mcp4661-502", MCP466x_502 }, 270 { "mcp4661-103", MCP466x_103 }, 271 { "mcp4661-503", MCP466x_503 }, 272 { "mcp4661-104", MCP466x_104 }, 273 { "mcp4662-502", MCP466x_502 }, 274 { "mcp4662-103", MCP466x_103 }, 275 { "mcp4662-503", MCP466x_503 }, 276 { "mcp4662-104", MCP466x_104 }, 277 {} 278 }; 279 MODULE_DEVICE_TABLE(i2c, mcp4531_id); 280 281 #ifdef CONFIG_OF 282 283 #define MCP4531_COMPATIBLE(of_compatible, cfg) { \ 284 .compatible = of_compatible, \ 285 .data = &mcp4531_cfg[cfg], \ 286 } 287 288 static const struct of_device_id mcp4531_of_match[] = { 289 MCP4531_COMPATIBLE("microchip,mcp4531-502", MCP453x_502), 290 MCP4531_COMPATIBLE("microchip,mcp4531-103", MCP453x_103), 291 MCP4531_COMPATIBLE("microchip,mcp4531-503", MCP453x_503), 292 MCP4531_COMPATIBLE("microchip,mcp4531-104", MCP453x_104), 293 MCP4531_COMPATIBLE("microchip,mcp4532-502", MCP453x_502), 294 MCP4531_COMPATIBLE("microchip,mcp4532-103", MCP453x_103), 295 MCP4531_COMPATIBLE("microchip,mcp4532-503", MCP453x_503), 296 MCP4531_COMPATIBLE("microchip,mcp4532-104", MCP453x_104), 297 MCP4531_COMPATIBLE("microchip,mcp4541-502", MCP454x_502), 298 MCP4531_COMPATIBLE("microchip,mcp4541-103", MCP454x_103), 299 MCP4531_COMPATIBLE("microchip,mcp4541-503", MCP454x_503), 300 MCP4531_COMPATIBLE("microchip,mcp4541-104", MCP454x_104), 301 MCP4531_COMPATIBLE("microchip,mcp4542-502", MCP454x_502), 302 MCP4531_COMPATIBLE("microchip,mcp4542-103", MCP454x_103), 303 MCP4531_COMPATIBLE("microchip,mcp4542-503", MCP454x_503), 304 MCP4531_COMPATIBLE("microchip,mcp4542-104", MCP454x_104), 305 MCP4531_COMPATIBLE("microchip,mcp4551-502", MCP455x_502), 306 MCP4531_COMPATIBLE("microchip,mcp4551-103", MCP455x_103), 307 MCP4531_COMPATIBLE("microchip,mcp4551-503", MCP455x_503), 308 MCP4531_COMPATIBLE("microchip,mcp4551-104", MCP455x_104), 309 MCP4531_COMPATIBLE("microchip,mcp4552-502", MCP455x_502), 310 MCP4531_COMPATIBLE("microchip,mcp4552-103", MCP455x_103), 311 MCP4531_COMPATIBLE("microchip,mcp4552-503", MCP455x_503), 312 MCP4531_COMPATIBLE("microchip,mcp4552-104", MCP455x_104), 313 MCP4531_COMPATIBLE("microchip,mcp4561-502", MCP456x_502), 314 MCP4531_COMPATIBLE("microchip,mcp4561-103", MCP456x_103), 315 MCP4531_COMPATIBLE("microchip,mcp4561-503", MCP456x_503), 316 MCP4531_COMPATIBLE("microchip,mcp4561-104", MCP456x_104), 317 MCP4531_COMPATIBLE("microchip,mcp4562-502", MCP456x_502), 318 MCP4531_COMPATIBLE("microchip,mcp4562-103", MCP456x_103), 319 MCP4531_COMPATIBLE("microchip,mcp4562-503", MCP456x_503), 320 MCP4531_COMPATIBLE("microchip,mcp4562-104", MCP456x_104), 321 MCP4531_COMPATIBLE("microchip,mcp4631-502", MCP463x_502), 322 MCP4531_COMPATIBLE("microchip,mcp4631-103", MCP463x_103), 323 MCP4531_COMPATIBLE("microchip,mcp4631-503", MCP463x_503), 324 MCP4531_COMPATIBLE("microchip,mcp4631-104", MCP463x_104), 325 MCP4531_COMPATIBLE("microchip,mcp4632-502", MCP463x_502), 326 MCP4531_COMPATIBLE("microchip,mcp4632-103", MCP463x_103), 327 MCP4531_COMPATIBLE("microchip,mcp4632-503", MCP463x_503), 328 MCP4531_COMPATIBLE("microchip,mcp4632-104", MCP463x_104), 329 MCP4531_COMPATIBLE("microchip,mcp4641-502", MCP464x_502), 330 MCP4531_COMPATIBLE("microchip,mcp4641-103", MCP464x_103), 331 MCP4531_COMPATIBLE("microchip,mcp4641-503", MCP464x_503), 332 MCP4531_COMPATIBLE("microchip,mcp4641-104", MCP464x_104), 333 MCP4531_COMPATIBLE("microchip,mcp4642-502", MCP464x_502), 334 MCP4531_COMPATIBLE("microchip,mcp4642-103", MCP464x_103), 335 MCP4531_COMPATIBLE("microchip,mcp4642-503", MCP464x_503), 336 MCP4531_COMPATIBLE("microchip,mcp4642-104", MCP464x_104), 337 MCP4531_COMPATIBLE("microchip,mcp4651-502", MCP465x_502), 338 MCP4531_COMPATIBLE("microchip,mcp4651-103", MCP465x_103), 339 MCP4531_COMPATIBLE("microchip,mcp4651-503", MCP465x_503), 340 MCP4531_COMPATIBLE("microchip,mcp4651-104", MCP465x_104), 341 MCP4531_COMPATIBLE("microchip,mcp4652-502", MCP465x_502), 342 MCP4531_COMPATIBLE("microchip,mcp4652-103", MCP465x_103), 343 MCP4531_COMPATIBLE("microchip,mcp4652-503", MCP465x_503), 344 MCP4531_COMPATIBLE("microchip,mcp4652-104", MCP465x_104), 345 MCP4531_COMPATIBLE("microchip,mcp4661-502", MCP466x_502), 346 MCP4531_COMPATIBLE("microchip,mcp4661-103", MCP466x_103), 347 MCP4531_COMPATIBLE("microchip,mcp4661-503", MCP466x_503), 348 MCP4531_COMPATIBLE("microchip,mcp4661-104", MCP466x_104), 349 MCP4531_COMPATIBLE("microchip,mcp4662-502", MCP466x_502), 350 MCP4531_COMPATIBLE("microchip,mcp4662-103", MCP466x_103), 351 MCP4531_COMPATIBLE("microchip,mcp4662-503", MCP466x_503), 352 MCP4531_COMPATIBLE("microchip,mcp4662-104", MCP466x_104), 353 { /* sentinel */ } 354 }; 355 MODULE_DEVICE_TABLE(of, mcp4531_of_match); 356 #endif 357 358 static int mcp4531_probe(struct i2c_client *client) 359 { 360 struct device *dev = &client->dev; 361 struct mcp4531_data *data; 362 struct iio_dev *indio_dev; 363 const struct of_device_id *match; 364 365 if (!i2c_check_functionality(client->adapter, 366 I2C_FUNC_SMBUS_WORD_DATA)) { 367 dev_err(dev, "SMBUS Word Data not supported\n"); 368 return -EOPNOTSUPP; 369 } 370 371 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 372 if (!indio_dev) 373 return -ENOMEM; 374 data = iio_priv(indio_dev); 375 i2c_set_clientdata(client, indio_dev); 376 data->client = client; 377 378 match = of_match_device(of_match_ptr(mcp4531_of_match), dev); 379 if (match) 380 data->cfg = of_device_get_match_data(dev); 381 else 382 data->cfg = &mcp4531_cfg[i2c_match_id(mcp4531_id, client)->driver_data]; 383 384 indio_dev->dev.parent = dev; 385 indio_dev->info = &mcp4531_info; 386 indio_dev->channels = mcp4531_channels; 387 indio_dev->num_channels = data->cfg->wipers; 388 indio_dev->name = client->name; 389 390 return devm_iio_device_register(dev, indio_dev); 391 } 392 393 static struct i2c_driver mcp4531_driver = { 394 .driver = { 395 .name = "mcp4531", 396 .of_match_table = of_match_ptr(mcp4531_of_match), 397 }, 398 .probe_new = mcp4531_probe, 399 .id_table = mcp4531_id, 400 }; 401 402 module_i2c_driver(mcp4531_driver); 403 404 MODULE_AUTHOR("Peter Rosin <peda@axentia.se>"); 405 MODULE_DESCRIPTION("MCP4531 digital potentiometer"); 406 MODULE_LICENSE("GPL"); 407