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 .driver_module = THIS_MODULE, 211 }; 212 213 #ifdef CONFIG_OF 214 215 #define MCP4531_COMPATIBLE(of_compatible, cfg) { \ 216 .compatible = of_compatible, \ 217 .data = &mcp4531_cfg[cfg], \ 218 } 219 220 static const struct of_device_id mcp4531_of_match[] = { 221 MCP4531_COMPATIBLE("microchip,mcp4531-502", MCP453x_502), 222 MCP4531_COMPATIBLE("microchip,mcp4531-103", MCP453x_103), 223 MCP4531_COMPATIBLE("microchip,mcp4531-503", MCP453x_503), 224 MCP4531_COMPATIBLE("microchip,mcp4531-104", MCP453x_104), 225 MCP4531_COMPATIBLE("microchip,mcp4532-502", MCP453x_502), 226 MCP4531_COMPATIBLE("microchip,mcp4532-103", MCP453x_103), 227 MCP4531_COMPATIBLE("microchip,mcp4532-503", MCP453x_503), 228 MCP4531_COMPATIBLE("microchip,mcp4532-104", MCP453x_104), 229 MCP4531_COMPATIBLE("microchip,mcp4541-502", MCP454x_502), 230 MCP4531_COMPATIBLE("microchip,mcp4541-103", MCP454x_103), 231 MCP4531_COMPATIBLE("microchip,mcp4541-503", MCP454x_503), 232 MCP4531_COMPATIBLE("microchip,mcp4541-104", MCP454x_104), 233 MCP4531_COMPATIBLE("microchip,mcp4542-502", MCP454x_502), 234 MCP4531_COMPATIBLE("microchip,mcp4542-103", MCP454x_103), 235 MCP4531_COMPATIBLE("microchip,mcp4542-503", MCP454x_503), 236 MCP4531_COMPATIBLE("microchip,mcp4542-104", MCP454x_104), 237 MCP4531_COMPATIBLE("microchip,mcp4551-502", MCP455x_502), 238 MCP4531_COMPATIBLE("microchip,mcp4551-103", MCP455x_103), 239 MCP4531_COMPATIBLE("microchip,mcp4551-503", MCP455x_503), 240 MCP4531_COMPATIBLE("microchip,mcp4551-104", MCP455x_104), 241 MCP4531_COMPATIBLE("microchip,mcp4552-502", MCP455x_502), 242 MCP4531_COMPATIBLE("microchip,mcp4552-103", MCP455x_103), 243 MCP4531_COMPATIBLE("microchip,mcp4552-503", MCP455x_503), 244 MCP4531_COMPATIBLE("microchip,mcp4552-104", MCP455x_104), 245 MCP4531_COMPATIBLE("microchip,mcp4561-502", MCP456x_502), 246 MCP4531_COMPATIBLE("microchip,mcp4561-103", MCP456x_103), 247 MCP4531_COMPATIBLE("microchip,mcp4561-503", MCP456x_503), 248 MCP4531_COMPATIBLE("microchip,mcp4561-104", MCP456x_104), 249 MCP4531_COMPATIBLE("microchip,mcp4562-502", MCP456x_502), 250 MCP4531_COMPATIBLE("microchip,mcp4562-103", MCP456x_103), 251 MCP4531_COMPATIBLE("microchip,mcp4562-503", MCP456x_503), 252 MCP4531_COMPATIBLE("microchip,mcp4562-104", MCP456x_104), 253 MCP4531_COMPATIBLE("microchip,mcp4631-502", MCP463x_502), 254 MCP4531_COMPATIBLE("microchip,mcp4631-103", MCP463x_103), 255 MCP4531_COMPATIBLE("microchip,mcp4631-503", MCP463x_503), 256 MCP4531_COMPATIBLE("microchip,mcp4631-104", MCP463x_104), 257 MCP4531_COMPATIBLE("microchip,mcp4632-502", MCP463x_502), 258 MCP4531_COMPATIBLE("microchip,mcp4632-103", MCP463x_103), 259 MCP4531_COMPATIBLE("microchip,mcp4632-503", MCP463x_503), 260 MCP4531_COMPATIBLE("microchip,mcp4632-104", MCP463x_104), 261 MCP4531_COMPATIBLE("microchip,mcp4641-502", MCP464x_502), 262 MCP4531_COMPATIBLE("microchip,mcp4641-103", MCP464x_103), 263 MCP4531_COMPATIBLE("microchip,mcp4641-503", MCP464x_503), 264 MCP4531_COMPATIBLE("microchip,mcp4641-104", MCP464x_104), 265 MCP4531_COMPATIBLE("microchip,mcp4642-502", MCP464x_502), 266 MCP4531_COMPATIBLE("microchip,mcp4642-103", MCP464x_103), 267 MCP4531_COMPATIBLE("microchip,mcp4642-503", MCP464x_503), 268 MCP4531_COMPATIBLE("microchip,mcp4642-104", MCP464x_104), 269 MCP4531_COMPATIBLE("microchip,mcp4651-502", MCP465x_502), 270 MCP4531_COMPATIBLE("microchip,mcp4651-103", MCP465x_103), 271 MCP4531_COMPATIBLE("microchip,mcp4651-503", MCP465x_503), 272 MCP4531_COMPATIBLE("microchip,mcp4651-104", MCP465x_104), 273 MCP4531_COMPATIBLE("microchip,mcp4652-502", MCP465x_502), 274 MCP4531_COMPATIBLE("microchip,mcp4652-103", MCP465x_103), 275 MCP4531_COMPATIBLE("microchip,mcp4652-503", MCP465x_503), 276 MCP4531_COMPATIBLE("microchip,mcp4652-104", MCP465x_104), 277 MCP4531_COMPATIBLE("microchip,mcp4661-502", MCP466x_502), 278 MCP4531_COMPATIBLE("microchip,mcp4661-103", MCP466x_103), 279 MCP4531_COMPATIBLE("microchip,mcp4661-503", MCP466x_503), 280 MCP4531_COMPATIBLE("microchip,mcp4661-104", MCP466x_104), 281 MCP4531_COMPATIBLE("microchip,mcp4662-502", MCP466x_502), 282 MCP4531_COMPATIBLE("microchip,mcp4662-103", MCP466x_103), 283 MCP4531_COMPATIBLE("microchip,mcp4662-503", MCP466x_503), 284 MCP4531_COMPATIBLE("microchip,mcp4662-104", MCP466x_104), 285 { /* sentinel */ } 286 }; 287 #endif 288 289 static int mcp4531_probe(struct i2c_client *client, 290 const struct i2c_device_id *id) 291 { 292 struct device *dev = &client->dev; 293 struct mcp4531_data *data; 294 struct iio_dev *indio_dev; 295 const struct of_device_id *match; 296 297 if (!i2c_check_functionality(client->adapter, 298 I2C_FUNC_SMBUS_WORD_DATA)) { 299 dev_err(dev, "SMBUS Word Data not supported\n"); 300 return -EOPNOTSUPP; 301 } 302 303 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 304 if (!indio_dev) 305 return -ENOMEM; 306 data = iio_priv(indio_dev); 307 i2c_set_clientdata(client, indio_dev); 308 data->client = client; 309 310 match = of_match_device(of_match_ptr(mcp4531_of_match), dev); 311 if (match) 312 data->cfg = of_device_get_match_data(dev); 313 else 314 data->cfg = &mcp4531_cfg[id->driver_data]; 315 316 indio_dev->dev.parent = dev; 317 indio_dev->info = &mcp4531_info; 318 indio_dev->channels = mcp4531_channels; 319 indio_dev->num_channels = data->cfg->wipers; 320 indio_dev->name = client->name; 321 322 return devm_iio_device_register(dev, indio_dev); 323 } 324 325 static const struct i2c_device_id mcp4531_id[] = { 326 { "mcp4531-502", MCP453x_502 }, 327 { "mcp4531-103", MCP453x_103 }, 328 { "mcp4531-503", MCP453x_503 }, 329 { "mcp4531-104", MCP453x_104 }, 330 { "mcp4532-502", MCP453x_502 }, 331 { "mcp4532-103", MCP453x_103 }, 332 { "mcp4532-503", MCP453x_503 }, 333 { "mcp4532-104", MCP453x_104 }, 334 { "mcp4541-502", MCP454x_502 }, 335 { "mcp4541-103", MCP454x_103 }, 336 { "mcp4541-503", MCP454x_503 }, 337 { "mcp4541-104", MCP454x_104 }, 338 { "mcp4542-502", MCP454x_502 }, 339 { "mcp4542-103", MCP454x_103 }, 340 { "mcp4542-503", MCP454x_503 }, 341 { "mcp4542-104", MCP454x_104 }, 342 { "mcp4551-502", MCP455x_502 }, 343 { "mcp4551-103", MCP455x_103 }, 344 { "mcp4551-503", MCP455x_503 }, 345 { "mcp4551-104", MCP455x_104 }, 346 { "mcp4552-502", MCP455x_502 }, 347 { "mcp4552-103", MCP455x_103 }, 348 { "mcp4552-503", MCP455x_503 }, 349 { "mcp4552-104", MCP455x_104 }, 350 { "mcp4561-502", MCP456x_502 }, 351 { "mcp4561-103", MCP456x_103 }, 352 { "mcp4561-503", MCP456x_503 }, 353 { "mcp4561-104", MCP456x_104 }, 354 { "mcp4562-502", MCP456x_502 }, 355 { "mcp4562-103", MCP456x_103 }, 356 { "mcp4562-503", MCP456x_503 }, 357 { "mcp4562-104", MCP456x_104 }, 358 { "mcp4631-502", MCP463x_502 }, 359 { "mcp4631-103", MCP463x_103 }, 360 { "mcp4631-503", MCP463x_503 }, 361 { "mcp4631-104", MCP463x_104 }, 362 { "mcp4632-502", MCP463x_502 }, 363 { "mcp4632-103", MCP463x_103 }, 364 { "mcp4632-503", MCP463x_503 }, 365 { "mcp4632-104", MCP463x_104 }, 366 { "mcp4641-502", MCP464x_502 }, 367 { "mcp4641-103", MCP464x_103 }, 368 { "mcp4641-503", MCP464x_503 }, 369 { "mcp4641-104", MCP464x_104 }, 370 { "mcp4642-502", MCP464x_502 }, 371 { "mcp4642-103", MCP464x_103 }, 372 { "mcp4642-503", MCP464x_503 }, 373 { "mcp4642-104", MCP464x_104 }, 374 { "mcp4651-502", MCP465x_502 }, 375 { "mcp4651-103", MCP465x_103 }, 376 { "mcp4651-503", MCP465x_503 }, 377 { "mcp4651-104", MCP465x_104 }, 378 { "mcp4652-502", MCP465x_502 }, 379 { "mcp4652-103", MCP465x_103 }, 380 { "mcp4652-503", MCP465x_503 }, 381 { "mcp4652-104", MCP465x_104 }, 382 { "mcp4661-502", MCP466x_502 }, 383 { "mcp4661-103", MCP466x_103 }, 384 { "mcp4661-503", MCP466x_503 }, 385 { "mcp4661-104", MCP466x_104 }, 386 { "mcp4662-502", MCP466x_502 }, 387 { "mcp4662-103", MCP466x_103 }, 388 { "mcp4662-503", MCP466x_503 }, 389 { "mcp4662-104", MCP466x_104 }, 390 {} 391 }; 392 MODULE_DEVICE_TABLE(i2c, mcp4531_id); 393 394 static struct i2c_driver mcp4531_driver = { 395 .driver = { 396 .name = "mcp4531", 397 .of_match_table = of_match_ptr(mcp4531_of_match), 398 }, 399 .probe = mcp4531_probe, 400 .id_table = mcp4531_id, 401 }; 402 403 module_i2c_driver(mcp4531_driver); 404 405 MODULE_AUTHOR("Peter Rosin <peda@axentia.se>"); 406 MODULE_DESCRIPTION("MCP4531 digital potentiometer"); 407 MODULE_LICENSE("GPL"); 408