2 * Industrial I/O driver for Microchip digital potentiometers
3 * Copyright (c) 2015 Axentia Technologies AB
4 * Author: Peter Rosin <peda@axentia.se>
6 * Datasheet: http://www.microchip.com/downloads/en/DeviceDoc/22096b.pdf
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
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.
31 #include <linux/module.h>
32 #include <linux/i2c.h>
33 #include <linux/err.h>
35 #include <linux/of_device.h>
37 #include <linux/iio/iio.h>
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, },
115 #define MCP4531_WRITE (0 << 2)
116 #define MCP4531_INCR (1 << 2)
117 #define MCP4531_DECR (2 << 2)
118 #define MCP4531_READ (3 << 2)
120 #define MCP4531_WIPER_SHIFT (4)
122 struct mcp4531_data
{
123 struct i2c_client
*client
;
124 const struct mcp4531_cfg
*cfg
;
127 #define MCP4531_CHANNEL(ch) { \
128 .type = IIO_RESISTANCE, \
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), \
137 static const struct iio_chan_spec mcp4531_channels
[] = {
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
)
146 struct mcp4531_data
*data
= iio_priv(indio_dev
);
147 int address
= chan
->channel
<< MCP4531_WIPER_SHIFT
;
151 case IIO_CHAN_INFO_RAW
:
152 ret
= i2c_smbus_read_word_swapped(data
->client
,
153 MCP4531_READ
| address
);
158 case IIO_CHAN_INFO_SCALE
:
159 *val
= 1000 * data
->cfg
->kohms
;
160 *val2
= data
->cfg
->avail
[2];
161 return IIO_VAL_FRACTIONAL
;
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
,
172 struct mcp4531_data
*data
= iio_priv(indio_dev
);
175 case IIO_CHAN_INFO_RAW
:
176 *length
= ARRAY_SIZE(data
->cfg
->avail
);
177 *vals
= data
->cfg
->avail
;
179 return IIO_AVAIL_RANGE
;
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
)
189 struct mcp4531_data
*data
= iio_priv(indio_dev
);
190 int address
= chan
->channel
<< MCP4531_WIPER_SHIFT
;
193 case IIO_CHAN_INFO_RAW
:
194 if (val
> data
->cfg
->avail
[2] || val
< 0)
201 return i2c_smbus_write_byte_data(data
->client
,
202 MCP4531_WRITE
| address
| (val
>> 8),
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
,
215 #define MCP4531_COMPATIBLE(of_compatible, cfg) { \
216 .compatible = of_compatible, \
217 .data = &mcp4531_cfg[cfg], \
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
),
289 static int mcp4531_probe(struct i2c_client
*client
,
290 const struct i2c_device_id
*id
)
292 struct device
*dev
= &client
->dev
;
293 struct mcp4531_data
*data
;
294 struct iio_dev
*indio_dev
;
295 const struct of_device_id
*match
;
297 if (!i2c_check_functionality(client
->adapter
,
298 I2C_FUNC_SMBUS_WORD_DATA
)) {
299 dev_err(dev
, "SMBUS Word Data not supported\n");
303 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*data
));
306 data
= iio_priv(indio_dev
);
307 i2c_set_clientdata(client
, indio_dev
);
308 data
->client
= client
;
310 match
= of_match_device(of_match_ptr(mcp4531_of_match
), dev
);
312 data
->cfg
= of_device_get_match_data(dev
);
314 data
->cfg
= &mcp4531_cfg
[id
->driver_data
];
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
;
322 return devm_iio_device_register(dev
, indio_dev
);
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
},
392 MODULE_DEVICE_TABLE(i2c
, mcp4531_id
);
394 static struct i2c_driver mcp4531_driver
= {
397 .of_match_table
= of_match_ptr(mcp4531_of_match
),
399 .probe
= mcp4531_probe
,
400 .id_table
= mcp4531_id
,
403 module_i2c_driver(mcp4531_driver
);
405 MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
406 MODULE_DESCRIPTION("MCP4531 digital potentiometer");
407 MODULE_LICENSE("GPL");