18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Industrial I/O driver for Microchip digital potentiometers 48c2ecf20Sopenharmony_ci * Copyright (c) 2015 Axentia Technologies AB 58c2ecf20Sopenharmony_ci * Author: Peter Rosin <peda@axentia.se> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Datasheet: http://www.microchip.com/downloads/en/DeviceDoc/22096b.pdf 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * DEVID #Wipers #Positions Resistor Opts (kOhm) i2c address 108c2ecf20Sopenharmony_ci * mcp4531 1 129 5, 10, 50, 100 010111x 118c2ecf20Sopenharmony_ci * mcp4532 1 129 5, 10, 50, 100 01011xx 128c2ecf20Sopenharmony_ci * mcp4541 1 129 5, 10, 50, 100 010111x 138c2ecf20Sopenharmony_ci * mcp4542 1 129 5, 10, 50, 100 01011xx 148c2ecf20Sopenharmony_ci * mcp4551 1 257 5, 10, 50, 100 010111x 158c2ecf20Sopenharmony_ci * mcp4552 1 257 5, 10, 50, 100 01011xx 168c2ecf20Sopenharmony_ci * mcp4561 1 257 5, 10, 50, 100 010111x 178c2ecf20Sopenharmony_ci * mcp4562 1 257 5, 10, 50, 100 01011xx 188c2ecf20Sopenharmony_ci * mcp4631 2 129 5, 10, 50, 100 0101xxx 198c2ecf20Sopenharmony_ci * mcp4632 2 129 5, 10, 50, 100 01011xx 208c2ecf20Sopenharmony_ci * mcp4641 2 129 5, 10, 50, 100 0101xxx 218c2ecf20Sopenharmony_ci * mcp4642 2 129 5, 10, 50, 100 01011xx 228c2ecf20Sopenharmony_ci * mcp4651 2 257 5, 10, 50, 100 0101xxx 238c2ecf20Sopenharmony_ci * mcp4652 2 257 5, 10, 50, 100 01011xx 248c2ecf20Sopenharmony_ci * mcp4661 2 257 5, 10, 50, 100 0101xxx 258c2ecf20Sopenharmony_ci * mcp4662 2 257 5, 10, 50, 100 01011xx 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#include <linux/module.h> 298c2ecf20Sopenharmony_ci#include <linux/i2c.h> 308c2ecf20Sopenharmony_ci#include <linux/err.h> 318c2ecf20Sopenharmony_ci#include <linux/mod_devicetable.h> 328c2ecf20Sopenharmony_ci#include <linux/property.h> 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#include <linux/iio/iio.h> 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistruct mcp4531_cfg { 378c2ecf20Sopenharmony_ci int wipers; 388c2ecf20Sopenharmony_ci int avail[3]; 398c2ecf20Sopenharmony_ci int kohms; 408c2ecf20Sopenharmony_ci}; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cienum mcp4531_type { 438c2ecf20Sopenharmony_ci MCP453x_502, 448c2ecf20Sopenharmony_ci MCP453x_103, 458c2ecf20Sopenharmony_ci MCP453x_503, 468c2ecf20Sopenharmony_ci MCP453x_104, 478c2ecf20Sopenharmony_ci MCP454x_502, 488c2ecf20Sopenharmony_ci MCP454x_103, 498c2ecf20Sopenharmony_ci MCP454x_503, 508c2ecf20Sopenharmony_ci MCP454x_104, 518c2ecf20Sopenharmony_ci MCP455x_502, 528c2ecf20Sopenharmony_ci MCP455x_103, 538c2ecf20Sopenharmony_ci MCP455x_503, 548c2ecf20Sopenharmony_ci MCP455x_104, 558c2ecf20Sopenharmony_ci MCP456x_502, 568c2ecf20Sopenharmony_ci MCP456x_103, 578c2ecf20Sopenharmony_ci MCP456x_503, 588c2ecf20Sopenharmony_ci MCP456x_104, 598c2ecf20Sopenharmony_ci MCP463x_502, 608c2ecf20Sopenharmony_ci MCP463x_103, 618c2ecf20Sopenharmony_ci MCP463x_503, 628c2ecf20Sopenharmony_ci MCP463x_104, 638c2ecf20Sopenharmony_ci MCP464x_502, 648c2ecf20Sopenharmony_ci MCP464x_103, 658c2ecf20Sopenharmony_ci MCP464x_503, 668c2ecf20Sopenharmony_ci MCP464x_104, 678c2ecf20Sopenharmony_ci MCP465x_502, 688c2ecf20Sopenharmony_ci MCP465x_103, 698c2ecf20Sopenharmony_ci MCP465x_503, 708c2ecf20Sopenharmony_ci MCP465x_104, 718c2ecf20Sopenharmony_ci MCP466x_502, 728c2ecf20Sopenharmony_ci MCP466x_103, 738c2ecf20Sopenharmony_ci MCP466x_503, 748c2ecf20Sopenharmony_ci MCP466x_104, 758c2ecf20Sopenharmony_ci}; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic const struct mcp4531_cfg mcp4531_cfg[] = { 788c2ecf20Sopenharmony_ci [MCP453x_502] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 5, }, 798c2ecf20Sopenharmony_ci [MCP453x_103] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 10, }, 808c2ecf20Sopenharmony_ci [MCP453x_503] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 50, }, 818c2ecf20Sopenharmony_ci [MCP453x_104] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 100, }, 828c2ecf20Sopenharmony_ci [MCP454x_502] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 5, }, 838c2ecf20Sopenharmony_ci [MCP454x_103] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 10, }, 848c2ecf20Sopenharmony_ci [MCP454x_503] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 50, }, 858c2ecf20Sopenharmony_ci [MCP454x_104] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 100, }, 868c2ecf20Sopenharmony_ci [MCP455x_502] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 5, }, 878c2ecf20Sopenharmony_ci [MCP455x_103] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 10, }, 888c2ecf20Sopenharmony_ci [MCP455x_503] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 50, }, 898c2ecf20Sopenharmony_ci [MCP455x_104] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 100, }, 908c2ecf20Sopenharmony_ci [MCP456x_502] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 5, }, 918c2ecf20Sopenharmony_ci [MCP456x_103] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 10, }, 928c2ecf20Sopenharmony_ci [MCP456x_503] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 50, }, 938c2ecf20Sopenharmony_ci [MCP456x_104] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 100, }, 948c2ecf20Sopenharmony_ci [MCP463x_502] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 5, }, 958c2ecf20Sopenharmony_ci [MCP463x_103] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 10, }, 968c2ecf20Sopenharmony_ci [MCP463x_503] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 50, }, 978c2ecf20Sopenharmony_ci [MCP463x_104] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 100, }, 988c2ecf20Sopenharmony_ci [MCP464x_502] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 5, }, 998c2ecf20Sopenharmony_ci [MCP464x_103] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 10, }, 1008c2ecf20Sopenharmony_ci [MCP464x_503] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 50, }, 1018c2ecf20Sopenharmony_ci [MCP464x_104] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 100, }, 1028c2ecf20Sopenharmony_ci [MCP465x_502] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 5, }, 1038c2ecf20Sopenharmony_ci [MCP465x_103] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 10, }, 1048c2ecf20Sopenharmony_ci [MCP465x_503] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 50, }, 1058c2ecf20Sopenharmony_ci [MCP465x_104] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 100, }, 1068c2ecf20Sopenharmony_ci [MCP466x_502] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 5, }, 1078c2ecf20Sopenharmony_ci [MCP466x_103] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 10, }, 1088c2ecf20Sopenharmony_ci [MCP466x_503] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 50, }, 1098c2ecf20Sopenharmony_ci [MCP466x_104] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 100, }, 1108c2ecf20Sopenharmony_ci}; 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci#define MCP4531_WRITE (0 << 2) 1138c2ecf20Sopenharmony_ci#define MCP4531_INCR (1 << 2) 1148c2ecf20Sopenharmony_ci#define MCP4531_DECR (2 << 2) 1158c2ecf20Sopenharmony_ci#define MCP4531_READ (3 << 2) 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci#define MCP4531_WIPER_SHIFT (4) 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistruct mcp4531_data { 1208c2ecf20Sopenharmony_ci struct i2c_client *client; 1218c2ecf20Sopenharmony_ci const struct mcp4531_cfg *cfg; 1228c2ecf20Sopenharmony_ci}; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci#define MCP4531_CHANNEL(ch) { \ 1258c2ecf20Sopenharmony_ci .type = IIO_RESISTANCE, \ 1268c2ecf20Sopenharmony_ci .indexed = 1, \ 1278c2ecf20Sopenharmony_ci .output = 1, \ 1288c2ecf20Sopenharmony_ci .channel = (ch), \ 1298c2ecf20Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 1308c2ecf20Sopenharmony_ci .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 1318c2ecf20Sopenharmony_ci .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_RAW), \ 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic const struct iio_chan_spec mcp4531_channels[] = { 1358c2ecf20Sopenharmony_ci MCP4531_CHANNEL(0), 1368c2ecf20Sopenharmony_ci MCP4531_CHANNEL(1), 1378c2ecf20Sopenharmony_ci}; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistatic int mcp4531_read_raw(struct iio_dev *indio_dev, 1408c2ecf20Sopenharmony_ci struct iio_chan_spec const *chan, 1418c2ecf20Sopenharmony_ci int *val, int *val2, long mask) 1428c2ecf20Sopenharmony_ci{ 1438c2ecf20Sopenharmony_ci struct mcp4531_data *data = iio_priv(indio_dev); 1448c2ecf20Sopenharmony_ci int address = chan->channel << MCP4531_WIPER_SHIFT; 1458c2ecf20Sopenharmony_ci s32 ret; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci switch (mask) { 1488c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_RAW: 1498c2ecf20Sopenharmony_ci ret = i2c_smbus_read_word_swapped(data->client, 1508c2ecf20Sopenharmony_ci MCP4531_READ | address); 1518c2ecf20Sopenharmony_ci if (ret < 0) 1528c2ecf20Sopenharmony_ci return ret; 1538c2ecf20Sopenharmony_ci *val = ret; 1548c2ecf20Sopenharmony_ci return IIO_VAL_INT; 1558c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_SCALE: 1568c2ecf20Sopenharmony_ci *val = 1000 * data->cfg->kohms; 1578c2ecf20Sopenharmony_ci *val2 = data->cfg->avail[2]; 1588c2ecf20Sopenharmony_ci return IIO_VAL_FRACTIONAL; 1598c2ecf20Sopenharmony_ci } 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci return -EINVAL; 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic int mcp4531_read_avail(struct iio_dev *indio_dev, 1658c2ecf20Sopenharmony_ci struct iio_chan_spec const *chan, 1668c2ecf20Sopenharmony_ci const int **vals, int *type, int *length, 1678c2ecf20Sopenharmony_ci long mask) 1688c2ecf20Sopenharmony_ci{ 1698c2ecf20Sopenharmony_ci struct mcp4531_data *data = iio_priv(indio_dev); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci switch (mask) { 1728c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_RAW: 1738c2ecf20Sopenharmony_ci *length = ARRAY_SIZE(data->cfg->avail); 1748c2ecf20Sopenharmony_ci *vals = data->cfg->avail; 1758c2ecf20Sopenharmony_ci *type = IIO_VAL_INT; 1768c2ecf20Sopenharmony_ci return IIO_AVAIL_RANGE; 1778c2ecf20Sopenharmony_ci } 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci return -EINVAL; 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic int mcp4531_write_raw(struct iio_dev *indio_dev, 1838c2ecf20Sopenharmony_ci struct iio_chan_spec const *chan, 1848c2ecf20Sopenharmony_ci int val, int val2, long mask) 1858c2ecf20Sopenharmony_ci{ 1868c2ecf20Sopenharmony_ci struct mcp4531_data *data = iio_priv(indio_dev); 1878c2ecf20Sopenharmony_ci int address = chan->channel << MCP4531_WIPER_SHIFT; 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci switch (mask) { 1908c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_RAW: 1918c2ecf20Sopenharmony_ci if (val > data->cfg->avail[2] || val < 0) 1928c2ecf20Sopenharmony_ci return -EINVAL; 1938c2ecf20Sopenharmony_ci break; 1948c2ecf20Sopenharmony_ci default: 1958c2ecf20Sopenharmony_ci return -EINVAL; 1968c2ecf20Sopenharmony_ci } 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci return i2c_smbus_write_byte_data(data->client, 1998c2ecf20Sopenharmony_ci MCP4531_WRITE | address | (val >> 8), 2008c2ecf20Sopenharmony_ci val & 0xff); 2018c2ecf20Sopenharmony_ci} 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cistatic const struct iio_info mcp4531_info = { 2048c2ecf20Sopenharmony_ci .read_raw = mcp4531_read_raw, 2058c2ecf20Sopenharmony_ci .read_avail = mcp4531_read_avail, 2068c2ecf20Sopenharmony_ci .write_raw = mcp4531_write_raw, 2078c2ecf20Sopenharmony_ci}; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_cistatic const struct i2c_device_id mcp4531_id[] = { 2108c2ecf20Sopenharmony_ci { "mcp4531-502", MCP453x_502 }, 2118c2ecf20Sopenharmony_ci { "mcp4531-103", MCP453x_103 }, 2128c2ecf20Sopenharmony_ci { "mcp4531-503", MCP453x_503 }, 2138c2ecf20Sopenharmony_ci { "mcp4531-104", MCP453x_104 }, 2148c2ecf20Sopenharmony_ci { "mcp4532-502", MCP453x_502 }, 2158c2ecf20Sopenharmony_ci { "mcp4532-103", MCP453x_103 }, 2168c2ecf20Sopenharmony_ci { "mcp4532-503", MCP453x_503 }, 2178c2ecf20Sopenharmony_ci { "mcp4532-104", MCP453x_104 }, 2188c2ecf20Sopenharmony_ci { "mcp4541-502", MCP454x_502 }, 2198c2ecf20Sopenharmony_ci { "mcp4541-103", MCP454x_103 }, 2208c2ecf20Sopenharmony_ci { "mcp4541-503", MCP454x_503 }, 2218c2ecf20Sopenharmony_ci { "mcp4541-104", MCP454x_104 }, 2228c2ecf20Sopenharmony_ci { "mcp4542-502", MCP454x_502 }, 2238c2ecf20Sopenharmony_ci { "mcp4542-103", MCP454x_103 }, 2248c2ecf20Sopenharmony_ci { "mcp4542-503", MCP454x_503 }, 2258c2ecf20Sopenharmony_ci { "mcp4542-104", MCP454x_104 }, 2268c2ecf20Sopenharmony_ci { "mcp4551-502", MCP455x_502 }, 2278c2ecf20Sopenharmony_ci { "mcp4551-103", MCP455x_103 }, 2288c2ecf20Sopenharmony_ci { "mcp4551-503", MCP455x_503 }, 2298c2ecf20Sopenharmony_ci { "mcp4551-104", MCP455x_104 }, 2308c2ecf20Sopenharmony_ci { "mcp4552-502", MCP455x_502 }, 2318c2ecf20Sopenharmony_ci { "mcp4552-103", MCP455x_103 }, 2328c2ecf20Sopenharmony_ci { "mcp4552-503", MCP455x_503 }, 2338c2ecf20Sopenharmony_ci { "mcp4552-104", MCP455x_104 }, 2348c2ecf20Sopenharmony_ci { "mcp4561-502", MCP456x_502 }, 2358c2ecf20Sopenharmony_ci { "mcp4561-103", MCP456x_103 }, 2368c2ecf20Sopenharmony_ci { "mcp4561-503", MCP456x_503 }, 2378c2ecf20Sopenharmony_ci { "mcp4561-104", MCP456x_104 }, 2388c2ecf20Sopenharmony_ci { "mcp4562-502", MCP456x_502 }, 2398c2ecf20Sopenharmony_ci { "mcp4562-103", MCP456x_103 }, 2408c2ecf20Sopenharmony_ci { "mcp4562-503", MCP456x_503 }, 2418c2ecf20Sopenharmony_ci { "mcp4562-104", MCP456x_104 }, 2428c2ecf20Sopenharmony_ci { "mcp4631-502", MCP463x_502 }, 2438c2ecf20Sopenharmony_ci { "mcp4631-103", MCP463x_103 }, 2448c2ecf20Sopenharmony_ci { "mcp4631-503", MCP463x_503 }, 2458c2ecf20Sopenharmony_ci { "mcp4631-104", MCP463x_104 }, 2468c2ecf20Sopenharmony_ci { "mcp4632-502", MCP463x_502 }, 2478c2ecf20Sopenharmony_ci { "mcp4632-103", MCP463x_103 }, 2488c2ecf20Sopenharmony_ci { "mcp4632-503", MCP463x_503 }, 2498c2ecf20Sopenharmony_ci { "mcp4632-104", MCP463x_104 }, 2508c2ecf20Sopenharmony_ci { "mcp4641-502", MCP464x_502 }, 2518c2ecf20Sopenharmony_ci { "mcp4641-103", MCP464x_103 }, 2528c2ecf20Sopenharmony_ci { "mcp4641-503", MCP464x_503 }, 2538c2ecf20Sopenharmony_ci { "mcp4641-104", MCP464x_104 }, 2548c2ecf20Sopenharmony_ci { "mcp4642-502", MCP464x_502 }, 2558c2ecf20Sopenharmony_ci { "mcp4642-103", MCP464x_103 }, 2568c2ecf20Sopenharmony_ci { "mcp4642-503", MCP464x_503 }, 2578c2ecf20Sopenharmony_ci { "mcp4642-104", MCP464x_104 }, 2588c2ecf20Sopenharmony_ci { "mcp4651-502", MCP465x_502 }, 2598c2ecf20Sopenharmony_ci { "mcp4651-103", MCP465x_103 }, 2608c2ecf20Sopenharmony_ci { "mcp4651-503", MCP465x_503 }, 2618c2ecf20Sopenharmony_ci { "mcp4651-104", MCP465x_104 }, 2628c2ecf20Sopenharmony_ci { "mcp4652-502", MCP465x_502 }, 2638c2ecf20Sopenharmony_ci { "mcp4652-103", MCP465x_103 }, 2648c2ecf20Sopenharmony_ci { "mcp4652-503", MCP465x_503 }, 2658c2ecf20Sopenharmony_ci { "mcp4652-104", MCP465x_104 }, 2668c2ecf20Sopenharmony_ci { "mcp4661-502", MCP466x_502 }, 2678c2ecf20Sopenharmony_ci { "mcp4661-103", MCP466x_103 }, 2688c2ecf20Sopenharmony_ci { "mcp4661-503", MCP466x_503 }, 2698c2ecf20Sopenharmony_ci { "mcp4661-104", MCP466x_104 }, 2708c2ecf20Sopenharmony_ci { "mcp4662-502", MCP466x_502 }, 2718c2ecf20Sopenharmony_ci { "mcp4662-103", MCP466x_103 }, 2728c2ecf20Sopenharmony_ci { "mcp4662-503", MCP466x_503 }, 2738c2ecf20Sopenharmony_ci { "mcp4662-104", MCP466x_104 }, 2748c2ecf20Sopenharmony_ci {} 2758c2ecf20Sopenharmony_ci}; 2768c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, mcp4531_id); 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci#define MCP4531_COMPATIBLE(of_compatible, cfg) { \ 2798c2ecf20Sopenharmony_ci .compatible = of_compatible, \ 2808c2ecf20Sopenharmony_ci .data = &mcp4531_cfg[cfg], \ 2818c2ecf20Sopenharmony_ci} 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic const struct of_device_id mcp4531_of_match[] = { 2848c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4531-502", MCP453x_502), 2858c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4531-103", MCP453x_103), 2868c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4531-503", MCP453x_503), 2878c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4531-104", MCP453x_104), 2888c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4532-502", MCP453x_502), 2898c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4532-103", MCP453x_103), 2908c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4532-503", MCP453x_503), 2918c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4532-104", MCP453x_104), 2928c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4541-502", MCP454x_502), 2938c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4541-103", MCP454x_103), 2948c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4541-503", MCP454x_503), 2958c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4541-104", MCP454x_104), 2968c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4542-502", MCP454x_502), 2978c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4542-103", MCP454x_103), 2988c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4542-503", MCP454x_503), 2998c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4542-104", MCP454x_104), 3008c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4551-502", MCP455x_502), 3018c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4551-103", MCP455x_103), 3028c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4551-503", MCP455x_503), 3038c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4551-104", MCP455x_104), 3048c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4552-502", MCP455x_502), 3058c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4552-103", MCP455x_103), 3068c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4552-503", MCP455x_503), 3078c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4552-104", MCP455x_104), 3088c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4561-502", MCP456x_502), 3098c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4561-103", MCP456x_103), 3108c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4561-503", MCP456x_503), 3118c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4561-104", MCP456x_104), 3128c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4562-502", MCP456x_502), 3138c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4562-103", MCP456x_103), 3148c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4562-503", MCP456x_503), 3158c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4562-104", MCP456x_104), 3168c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4631-502", MCP463x_502), 3178c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4631-103", MCP463x_103), 3188c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4631-503", MCP463x_503), 3198c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4631-104", MCP463x_104), 3208c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4632-502", MCP463x_502), 3218c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4632-103", MCP463x_103), 3228c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4632-503", MCP463x_503), 3238c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4632-104", MCP463x_104), 3248c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4641-502", MCP464x_502), 3258c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4641-103", MCP464x_103), 3268c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4641-503", MCP464x_503), 3278c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4641-104", MCP464x_104), 3288c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4642-502", MCP464x_502), 3298c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4642-103", MCP464x_103), 3308c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4642-503", MCP464x_503), 3318c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4642-104", MCP464x_104), 3328c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4651-502", MCP465x_502), 3338c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4651-103", MCP465x_103), 3348c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4651-503", MCP465x_503), 3358c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4651-104", MCP465x_104), 3368c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4652-502", MCP465x_502), 3378c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4652-103", MCP465x_103), 3388c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4652-503", MCP465x_503), 3398c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4652-104", MCP465x_104), 3408c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4661-502", MCP466x_502), 3418c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4661-103", MCP466x_103), 3428c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4661-503", MCP466x_503), 3438c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4661-104", MCP466x_104), 3448c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4662-502", MCP466x_502), 3458c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4662-103", MCP466x_103), 3468c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4662-503", MCP466x_503), 3478c2ecf20Sopenharmony_ci MCP4531_COMPATIBLE("microchip,mcp4662-104", MCP466x_104), 3488c2ecf20Sopenharmony_ci { /* sentinel */ } 3498c2ecf20Sopenharmony_ci}; 3508c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, mcp4531_of_match); 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_cistatic int mcp4531_probe(struct i2c_client *client) 3538c2ecf20Sopenharmony_ci{ 3548c2ecf20Sopenharmony_ci struct device *dev = &client->dev; 3558c2ecf20Sopenharmony_ci struct mcp4531_data *data; 3568c2ecf20Sopenharmony_ci struct iio_dev *indio_dev; 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci if (!i2c_check_functionality(client->adapter, 3598c2ecf20Sopenharmony_ci I2C_FUNC_SMBUS_WORD_DATA)) { 3608c2ecf20Sopenharmony_ci dev_err(dev, "SMBUS Word Data not supported\n"); 3618c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 3628c2ecf20Sopenharmony_ci } 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 3658c2ecf20Sopenharmony_ci if (!indio_dev) 3668c2ecf20Sopenharmony_ci return -ENOMEM; 3678c2ecf20Sopenharmony_ci data = iio_priv(indio_dev); 3688c2ecf20Sopenharmony_ci i2c_set_clientdata(client, indio_dev); 3698c2ecf20Sopenharmony_ci data->client = client; 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_ci data->cfg = device_get_match_data(dev); 3728c2ecf20Sopenharmony_ci if (!data->cfg) 3738c2ecf20Sopenharmony_ci data->cfg = &mcp4531_cfg[i2c_match_id(mcp4531_id, client)->driver_data]; 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_ci indio_dev->info = &mcp4531_info; 3768c2ecf20Sopenharmony_ci indio_dev->channels = mcp4531_channels; 3778c2ecf20Sopenharmony_ci indio_dev->num_channels = data->cfg->wipers; 3788c2ecf20Sopenharmony_ci indio_dev->name = client->name; 3798c2ecf20Sopenharmony_ci 3808c2ecf20Sopenharmony_ci return devm_iio_device_register(dev, indio_dev); 3818c2ecf20Sopenharmony_ci} 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_cistatic struct i2c_driver mcp4531_driver = { 3848c2ecf20Sopenharmony_ci .driver = { 3858c2ecf20Sopenharmony_ci .name = "mcp4531", 3868c2ecf20Sopenharmony_ci .of_match_table = mcp4531_of_match, 3878c2ecf20Sopenharmony_ci }, 3888c2ecf20Sopenharmony_ci .probe_new = mcp4531_probe, 3898c2ecf20Sopenharmony_ci .id_table = mcp4531_id, 3908c2ecf20Sopenharmony_ci}; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_cimodule_i2c_driver(mcp4531_driver); 3938c2ecf20Sopenharmony_ci 3948c2ecf20Sopenharmony_ciMODULE_AUTHOR("Peter Rosin <peda@axentia.se>"); 3958c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("MCP4531 digital potentiometer"); 3968c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 397