18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Industrial I/O driver for Microchip digital potentiometers 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 2016 Slawomir Stepien 68c2ecf20Sopenharmony_ci * Based on: Peter Rosin's code from mcp4531.c 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/22060b.pdf 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * DEVID #Wipers #Positions Resistor Opts (kOhm) 118c2ecf20Sopenharmony_ci * mcp4131 1 129 5, 10, 50, 100 128c2ecf20Sopenharmony_ci * mcp4132 1 129 5, 10, 50, 100 138c2ecf20Sopenharmony_ci * mcp4141 1 129 5, 10, 50, 100 148c2ecf20Sopenharmony_ci * mcp4142 1 129 5, 10, 50, 100 158c2ecf20Sopenharmony_ci * mcp4151 1 257 5, 10, 50, 100 168c2ecf20Sopenharmony_ci * mcp4152 1 257 5, 10, 50, 100 178c2ecf20Sopenharmony_ci * mcp4161 1 257 5, 10, 50, 100 188c2ecf20Sopenharmony_ci * mcp4162 1 257 5, 10, 50, 100 198c2ecf20Sopenharmony_ci * mcp4231 2 129 5, 10, 50, 100 208c2ecf20Sopenharmony_ci * mcp4232 2 129 5, 10, 50, 100 218c2ecf20Sopenharmony_ci * mcp4241 2 129 5, 10, 50, 100 228c2ecf20Sopenharmony_ci * mcp4242 2 129 5, 10, 50, 100 238c2ecf20Sopenharmony_ci * mcp4251 2 257 5, 10, 50, 100 248c2ecf20Sopenharmony_ci * mcp4252 2 257 5, 10, 50, 100 258c2ecf20Sopenharmony_ci * mcp4261 2 257 5, 10, 50, 100 268c2ecf20Sopenharmony_ci * mcp4262 2 257 5, 10, 50, 100 278c2ecf20Sopenharmony_ci */ 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* 308c2ecf20Sopenharmony_ci * TODO: 318c2ecf20Sopenharmony_ci * 1. Write wiper setting to EEPROM for EEPROM capable models. 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#include <linux/cache.h> 358c2ecf20Sopenharmony_ci#include <linux/err.h> 368c2ecf20Sopenharmony_ci#include <linux/export.h> 378c2ecf20Sopenharmony_ci#include <linux/iio/iio.h> 388c2ecf20Sopenharmony_ci#include <linux/iio/types.h> 398c2ecf20Sopenharmony_ci#include <linux/module.h> 408c2ecf20Sopenharmony_ci#include <linux/mod_devicetable.h> 418c2ecf20Sopenharmony_ci#include <linux/mutex.h> 428c2ecf20Sopenharmony_ci#include <linux/property.h> 438c2ecf20Sopenharmony_ci#include <linux/spi/spi.h> 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define MCP4131_WRITE (0x00 << 2) 468c2ecf20Sopenharmony_ci#define MCP4131_READ (0x03 << 2) 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#define MCP4131_WIPER_SHIFT 4 498c2ecf20Sopenharmony_ci#define MCP4131_CMDERR(r) ((r[0]) & 0x02) 508c2ecf20Sopenharmony_ci#define MCP4131_RAW(r) ((r[0]) == 0xff ? 0x100 : (r[1])) 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_cistruct mcp4131_cfg { 538c2ecf20Sopenharmony_ci int wipers; 548c2ecf20Sopenharmony_ci int max_pos; 558c2ecf20Sopenharmony_ci int kohms; 568c2ecf20Sopenharmony_ci}; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cienum mcp4131_type { 598c2ecf20Sopenharmony_ci MCP413x_502 = 0, 608c2ecf20Sopenharmony_ci MCP413x_103, 618c2ecf20Sopenharmony_ci MCP413x_503, 628c2ecf20Sopenharmony_ci MCP413x_104, 638c2ecf20Sopenharmony_ci MCP414x_502, 648c2ecf20Sopenharmony_ci MCP414x_103, 658c2ecf20Sopenharmony_ci MCP414x_503, 668c2ecf20Sopenharmony_ci MCP414x_104, 678c2ecf20Sopenharmony_ci MCP415x_502, 688c2ecf20Sopenharmony_ci MCP415x_103, 698c2ecf20Sopenharmony_ci MCP415x_503, 708c2ecf20Sopenharmony_ci MCP415x_104, 718c2ecf20Sopenharmony_ci MCP416x_502, 728c2ecf20Sopenharmony_ci MCP416x_103, 738c2ecf20Sopenharmony_ci MCP416x_503, 748c2ecf20Sopenharmony_ci MCP416x_104, 758c2ecf20Sopenharmony_ci MCP423x_502, 768c2ecf20Sopenharmony_ci MCP423x_103, 778c2ecf20Sopenharmony_ci MCP423x_503, 788c2ecf20Sopenharmony_ci MCP423x_104, 798c2ecf20Sopenharmony_ci MCP424x_502, 808c2ecf20Sopenharmony_ci MCP424x_103, 818c2ecf20Sopenharmony_ci MCP424x_503, 828c2ecf20Sopenharmony_ci MCP424x_104, 838c2ecf20Sopenharmony_ci MCP425x_502, 848c2ecf20Sopenharmony_ci MCP425x_103, 858c2ecf20Sopenharmony_ci MCP425x_503, 868c2ecf20Sopenharmony_ci MCP425x_104, 878c2ecf20Sopenharmony_ci MCP426x_502, 888c2ecf20Sopenharmony_ci MCP426x_103, 898c2ecf20Sopenharmony_ci MCP426x_503, 908c2ecf20Sopenharmony_ci MCP426x_104, 918c2ecf20Sopenharmony_ci}; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic const struct mcp4131_cfg mcp4131_cfg[] = { 948c2ecf20Sopenharmony_ci [MCP413x_502] = { .wipers = 1, .max_pos = 128, .kohms = 5, }, 958c2ecf20Sopenharmony_ci [MCP413x_103] = { .wipers = 1, .max_pos = 128, .kohms = 10, }, 968c2ecf20Sopenharmony_ci [MCP413x_503] = { .wipers = 1, .max_pos = 128, .kohms = 50, }, 978c2ecf20Sopenharmony_ci [MCP413x_104] = { .wipers = 1, .max_pos = 128, .kohms = 100, }, 988c2ecf20Sopenharmony_ci [MCP414x_502] = { .wipers = 1, .max_pos = 128, .kohms = 5, }, 998c2ecf20Sopenharmony_ci [MCP414x_103] = { .wipers = 1, .max_pos = 128, .kohms = 10, }, 1008c2ecf20Sopenharmony_ci [MCP414x_503] = { .wipers = 1, .max_pos = 128, .kohms = 50, }, 1018c2ecf20Sopenharmony_ci [MCP414x_104] = { .wipers = 1, .max_pos = 128, .kohms = 100, }, 1028c2ecf20Sopenharmony_ci [MCP415x_502] = { .wipers = 1, .max_pos = 256, .kohms = 5, }, 1038c2ecf20Sopenharmony_ci [MCP415x_103] = { .wipers = 1, .max_pos = 256, .kohms = 10, }, 1048c2ecf20Sopenharmony_ci [MCP415x_503] = { .wipers = 1, .max_pos = 256, .kohms = 50, }, 1058c2ecf20Sopenharmony_ci [MCP415x_104] = { .wipers = 1, .max_pos = 256, .kohms = 100, }, 1068c2ecf20Sopenharmony_ci [MCP416x_502] = { .wipers = 1, .max_pos = 256, .kohms = 5, }, 1078c2ecf20Sopenharmony_ci [MCP416x_103] = { .wipers = 1, .max_pos = 256, .kohms = 10, }, 1088c2ecf20Sopenharmony_ci [MCP416x_503] = { .wipers = 1, .max_pos = 256, .kohms = 50, }, 1098c2ecf20Sopenharmony_ci [MCP416x_104] = { .wipers = 1, .max_pos = 256, .kohms = 100, }, 1108c2ecf20Sopenharmony_ci [MCP423x_502] = { .wipers = 2, .max_pos = 128, .kohms = 5, }, 1118c2ecf20Sopenharmony_ci [MCP423x_103] = { .wipers = 2, .max_pos = 128, .kohms = 10, }, 1128c2ecf20Sopenharmony_ci [MCP423x_503] = { .wipers = 2, .max_pos = 128, .kohms = 50, }, 1138c2ecf20Sopenharmony_ci [MCP423x_104] = { .wipers = 2, .max_pos = 128, .kohms = 100, }, 1148c2ecf20Sopenharmony_ci [MCP424x_502] = { .wipers = 2, .max_pos = 128, .kohms = 5, }, 1158c2ecf20Sopenharmony_ci [MCP424x_103] = { .wipers = 2, .max_pos = 128, .kohms = 10, }, 1168c2ecf20Sopenharmony_ci [MCP424x_503] = { .wipers = 2, .max_pos = 128, .kohms = 50, }, 1178c2ecf20Sopenharmony_ci [MCP424x_104] = { .wipers = 2, .max_pos = 128, .kohms = 100, }, 1188c2ecf20Sopenharmony_ci [MCP425x_502] = { .wipers = 2, .max_pos = 256, .kohms = 5, }, 1198c2ecf20Sopenharmony_ci [MCP425x_103] = { .wipers = 2, .max_pos = 256, .kohms = 10, }, 1208c2ecf20Sopenharmony_ci [MCP425x_503] = { .wipers = 2, .max_pos = 256, .kohms = 50, }, 1218c2ecf20Sopenharmony_ci [MCP425x_104] = { .wipers = 2, .max_pos = 256, .kohms = 100, }, 1228c2ecf20Sopenharmony_ci [MCP426x_502] = { .wipers = 2, .max_pos = 256, .kohms = 5, }, 1238c2ecf20Sopenharmony_ci [MCP426x_103] = { .wipers = 2, .max_pos = 256, .kohms = 10, }, 1248c2ecf20Sopenharmony_ci [MCP426x_503] = { .wipers = 2, .max_pos = 256, .kohms = 50, }, 1258c2ecf20Sopenharmony_ci [MCP426x_104] = { .wipers = 2, .max_pos = 256, .kohms = 100, }, 1268c2ecf20Sopenharmony_ci}; 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_cistruct mcp4131_data { 1298c2ecf20Sopenharmony_ci struct spi_device *spi; 1308c2ecf20Sopenharmony_ci const struct mcp4131_cfg *cfg; 1318c2ecf20Sopenharmony_ci struct mutex lock; 1328c2ecf20Sopenharmony_ci u8 buf[2] ____cacheline_aligned; 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci#define MCP4131_CHANNEL(ch) { \ 1368c2ecf20Sopenharmony_ci .type = IIO_RESISTANCE, \ 1378c2ecf20Sopenharmony_ci .indexed = 1, \ 1388c2ecf20Sopenharmony_ci .output = 1, \ 1398c2ecf20Sopenharmony_ci .channel = (ch), \ 1408c2ecf20Sopenharmony_ci .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 1418c2ecf20Sopenharmony_ci .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 1428c2ecf20Sopenharmony_ci} 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cistatic const struct iio_chan_spec mcp4131_channels[] = { 1458c2ecf20Sopenharmony_ci MCP4131_CHANNEL(0), 1468c2ecf20Sopenharmony_ci MCP4131_CHANNEL(1), 1478c2ecf20Sopenharmony_ci}; 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_cistatic int mcp4131_read(struct spi_device *spi, void *buf, size_t len) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci struct spi_transfer t = { 1528c2ecf20Sopenharmony_ci .tx_buf = buf, /* We need to send addr, cmd and 12 bits */ 1538c2ecf20Sopenharmony_ci .rx_buf = buf, 1548c2ecf20Sopenharmony_ci .len = len, 1558c2ecf20Sopenharmony_ci }; 1568c2ecf20Sopenharmony_ci struct spi_message m; 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci spi_message_init(&m); 1598c2ecf20Sopenharmony_ci spi_message_add_tail(&t, &m); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci return spi_sync(spi, &m); 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_cistatic int mcp4131_read_raw(struct iio_dev *indio_dev, 1658c2ecf20Sopenharmony_ci struct iio_chan_spec const *chan, 1668c2ecf20Sopenharmony_ci int *val, int *val2, long mask) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci int err; 1698c2ecf20Sopenharmony_ci struct mcp4131_data *data = iio_priv(indio_dev); 1708c2ecf20Sopenharmony_ci int address = chan->channel; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci switch (mask) { 1738c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_RAW: 1748c2ecf20Sopenharmony_ci mutex_lock(&data->lock); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci data->buf[0] = (address << MCP4131_WIPER_SHIFT) | MCP4131_READ; 1778c2ecf20Sopenharmony_ci data->buf[1] = 0; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci err = mcp4131_read(data->spi, data->buf, 2); 1808c2ecf20Sopenharmony_ci if (err) { 1818c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1828c2ecf20Sopenharmony_ci return err; 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci /* Error, bad address/command combination */ 1868c2ecf20Sopenharmony_ci if (!MCP4131_CMDERR(data->buf)) { 1878c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1888c2ecf20Sopenharmony_ci return -EIO; 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci *val = MCP4131_RAW(data->buf); 1928c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci return IIO_VAL_INT; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_SCALE: 1978c2ecf20Sopenharmony_ci *val = 1000 * data->cfg->kohms; 1988c2ecf20Sopenharmony_ci *val2 = data->cfg->max_pos; 1998c2ecf20Sopenharmony_ci return IIO_VAL_FRACTIONAL; 2008c2ecf20Sopenharmony_ci } 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci return -EINVAL; 2038c2ecf20Sopenharmony_ci} 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_cistatic int mcp4131_write_raw(struct iio_dev *indio_dev, 2068c2ecf20Sopenharmony_ci struct iio_chan_spec const *chan, 2078c2ecf20Sopenharmony_ci int val, int val2, long mask) 2088c2ecf20Sopenharmony_ci{ 2098c2ecf20Sopenharmony_ci int err; 2108c2ecf20Sopenharmony_ci struct mcp4131_data *data = iio_priv(indio_dev); 2118c2ecf20Sopenharmony_ci int address = chan->channel << MCP4131_WIPER_SHIFT; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci switch (mask) { 2148c2ecf20Sopenharmony_ci case IIO_CHAN_INFO_RAW: 2158c2ecf20Sopenharmony_ci if (val > data->cfg->max_pos || val < 0) 2168c2ecf20Sopenharmony_ci return -EINVAL; 2178c2ecf20Sopenharmony_ci break; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci default: 2208c2ecf20Sopenharmony_ci return -EINVAL; 2218c2ecf20Sopenharmony_ci } 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci mutex_lock(&data->lock); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci data->buf[0] = address << MCP4131_WIPER_SHIFT; 2268c2ecf20Sopenharmony_ci data->buf[0] |= MCP4131_WRITE | (val >> 8); 2278c2ecf20Sopenharmony_ci data->buf[1] = val & 0xFF; /* 8 bits here */ 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci err = spi_write(data->spi, data->buf, 2); 2308c2ecf20Sopenharmony_ci mutex_unlock(&data->lock); 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci return err; 2338c2ecf20Sopenharmony_ci} 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_cistatic const struct iio_info mcp4131_info = { 2368c2ecf20Sopenharmony_ci .read_raw = mcp4131_read_raw, 2378c2ecf20Sopenharmony_ci .write_raw = mcp4131_write_raw, 2388c2ecf20Sopenharmony_ci}; 2398c2ecf20Sopenharmony_ci 2408c2ecf20Sopenharmony_cistatic int mcp4131_probe(struct spi_device *spi) 2418c2ecf20Sopenharmony_ci{ 2428c2ecf20Sopenharmony_ci int err; 2438c2ecf20Sopenharmony_ci struct device *dev = &spi->dev; 2448c2ecf20Sopenharmony_ci unsigned long devid; 2458c2ecf20Sopenharmony_ci struct mcp4131_data *data; 2468c2ecf20Sopenharmony_ci struct iio_dev *indio_dev; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 2498c2ecf20Sopenharmony_ci if (!indio_dev) 2508c2ecf20Sopenharmony_ci return -ENOMEM; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci data = iio_priv(indio_dev); 2538c2ecf20Sopenharmony_ci spi_set_drvdata(spi, indio_dev); 2548c2ecf20Sopenharmony_ci data->spi = spi; 2558c2ecf20Sopenharmony_ci data->cfg = device_get_match_data(&spi->dev); 2568c2ecf20Sopenharmony_ci if (!data->cfg) { 2578c2ecf20Sopenharmony_ci devid = spi_get_device_id(spi)->driver_data; 2588c2ecf20Sopenharmony_ci data->cfg = &mcp4131_cfg[devid]; 2598c2ecf20Sopenharmony_ci } 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci mutex_init(&data->lock); 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci indio_dev->info = &mcp4131_info; 2648c2ecf20Sopenharmony_ci indio_dev->channels = mcp4131_channels; 2658c2ecf20Sopenharmony_ci indio_dev->num_channels = data->cfg->wipers; 2668c2ecf20Sopenharmony_ci indio_dev->name = spi_get_device_id(spi)->name; 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci err = devm_iio_device_register(dev, indio_dev); 2698c2ecf20Sopenharmony_ci if (err) { 2708c2ecf20Sopenharmony_ci dev_info(&spi->dev, "Unable to register %s\n", indio_dev->name); 2718c2ecf20Sopenharmony_ci return err; 2728c2ecf20Sopenharmony_ci } 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci return 0; 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_cistatic const struct of_device_id mcp4131_dt_ids[] = { 2788c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4131-502", 2798c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP413x_502] }, 2808c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4131-103", 2818c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP413x_103] }, 2828c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4131-503", 2838c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP413x_503] }, 2848c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4131-104", 2858c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP413x_104] }, 2868c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4132-502", 2878c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP413x_502] }, 2888c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4132-103", 2898c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP413x_103] }, 2908c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4132-503", 2918c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP413x_503] }, 2928c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4132-104", 2938c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP413x_104] }, 2948c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4141-502", 2958c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP414x_502] }, 2968c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4141-103", 2978c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP414x_103] }, 2988c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4141-503", 2998c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP414x_503] }, 3008c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4141-104", 3018c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP414x_104] }, 3028c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4142-502", 3038c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP414x_502] }, 3048c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4142-103", 3058c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP414x_103] }, 3068c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4142-503", 3078c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP414x_503] }, 3088c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4142-104", 3098c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP414x_104] }, 3108c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4151-502", 3118c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP415x_502] }, 3128c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4151-103", 3138c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP415x_103] }, 3148c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4151-503", 3158c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP415x_503] }, 3168c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4151-104", 3178c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP415x_104] }, 3188c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4152-502", 3198c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP415x_502] }, 3208c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4152-103", 3218c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP415x_103] }, 3228c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4152-503", 3238c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP415x_503] }, 3248c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4152-104", 3258c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP415x_104] }, 3268c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4161-502", 3278c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP416x_502] }, 3288c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4161-103", 3298c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP416x_103] }, 3308c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4161-503", 3318c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP416x_503] }, 3328c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4161-104", 3338c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP416x_104] }, 3348c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4162-502", 3358c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP416x_502] }, 3368c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4162-103", 3378c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP416x_103] }, 3388c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4162-503", 3398c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP416x_503] }, 3408c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4162-104", 3418c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP416x_104] }, 3428c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4231-502", 3438c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP423x_502] }, 3448c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4231-103", 3458c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP423x_103] }, 3468c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4231-503", 3478c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP423x_503] }, 3488c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4231-104", 3498c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP423x_104] }, 3508c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4232-502", 3518c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP423x_502] }, 3528c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4232-103", 3538c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP423x_103] }, 3548c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4232-503", 3558c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP423x_503] }, 3568c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4232-104", 3578c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP423x_104] }, 3588c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4241-502", 3598c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP424x_502] }, 3608c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4241-103", 3618c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP424x_103] }, 3628c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4241-503", 3638c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP424x_503] }, 3648c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4241-104", 3658c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP424x_104] }, 3668c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4242-502", 3678c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP424x_502] }, 3688c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4242-103", 3698c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP424x_103] }, 3708c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4242-503", 3718c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP424x_503] }, 3728c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4242-104", 3738c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP424x_104] }, 3748c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4251-502", 3758c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP425x_502] }, 3768c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4251-103", 3778c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP425x_103] }, 3788c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4251-503", 3798c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP425x_503] }, 3808c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4251-104", 3818c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP425x_104] }, 3828c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4252-502", 3838c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP425x_502] }, 3848c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4252-103", 3858c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP425x_103] }, 3868c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4252-503", 3878c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP425x_503] }, 3888c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4252-104", 3898c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP425x_104] }, 3908c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4261-502", 3918c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP426x_502] }, 3928c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4261-103", 3938c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP426x_103] }, 3948c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4261-503", 3958c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP426x_503] }, 3968c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4261-104", 3978c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP426x_104] }, 3988c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4262-502", 3998c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP426x_502] }, 4008c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4262-103", 4018c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP426x_103] }, 4028c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4262-503", 4038c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP426x_503] }, 4048c2ecf20Sopenharmony_ci { .compatible = "microchip,mcp4262-104", 4058c2ecf20Sopenharmony_ci .data = &mcp4131_cfg[MCP426x_104] }, 4068c2ecf20Sopenharmony_ci {} 4078c2ecf20Sopenharmony_ci}; 4088c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, mcp4131_dt_ids); 4098c2ecf20Sopenharmony_ci 4108c2ecf20Sopenharmony_cistatic const struct spi_device_id mcp4131_id[] = { 4118c2ecf20Sopenharmony_ci { "mcp4131-502", MCP413x_502 }, 4128c2ecf20Sopenharmony_ci { "mcp4131-103", MCP413x_103 }, 4138c2ecf20Sopenharmony_ci { "mcp4131-503", MCP413x_503 }, 4148c2ecf20Sopenharmony_ci { "mcp4131-104", MCP413x_104 }, 4158c2ecf20Sopenharmony_ci { "mcp4132-502", MCP413x_502 }, 4168c2ecf20Sopenharmony_ci { "mcp4132-103", MCP413x_103 }, 4178c2ecf20Sopenharmony_ci { "mcp4132-503", MCP413x_503 }, 4188c2ecf20Sopenharmony_ci { "mcp4132-104", MCP413x_104 }, 4198c2ecf20Sopenharmony_ci { "mcp4141-502", MCP414x_502 }, 4208c2ecf20Sopenharmony_ci { "mcp4141-103", MCP414x_103 }, 4218c2ecf20Sopenharmony_ci { "mcp4141-503", MCP414x_503 }, 4228c2ecf20Sopenharmony_ci { "mcp4141-104", MCP414x_104 }, 4238c2ecf20Sopenharmony_ci { "mcp4142-502", MCP414x_502 }, 4248c2ecf20Sopenharmony_ci { "mcp4142-103", MCP414x_103 }, 4258c2ecf20Sopenharmony_ci { "mcp4142-503", MCP414x_503 }, 4268c2ecf20Sopenharmony_ci { "mcp4142-104", MCP414x_104 }, 4278c2ecf20Sopenharmony_ci { "mcp4151-502", MCP415x_502 }, 4288c2ecf20Sopenharmony_ci { "mcp4151-103", MCP415x_103 }, 4298c2ecf20Sopenharmony_ci { "mcp4151-503", MCP415x_503 }, 4308c2ecf20Sopenharmony_ci { "mcp4151-104", MCP415x_104 }, 4318c2ecf20Sopenharmony_ci { "mcp4152-502", MCP415x_502 }, 4328c2ecf20Sopenharmony_ci { "mcp4152-103", MCP415x_103 }, 4338c2ecf20Sopenharmony_ci { "mcp4152-503", MCP415x_503 }, 4348c2ecf20Sopenharmony_ci { "mcp4152-104", MCP415x_104 }, 4358c2ecf20Sopenharmony_ci { "mcp4161-502", MCP416x_502 }, 4368c2ecf20Sopenharmony_ci { "mcp4161-103", MCP416x_103 }, 4378c2ecf20Sopenharmony_ci { "mcp4161-503", MCP416x_503 }, 4388c2ecf20Sopenharmony_ci { "mcp4161-104", MCP416x_104 }, 4398c2ecf20Sopenharmony_ci { "mcp4162-502", MCP416x_502 }, 4408c2ecf20Sopenharmony_ci { "mcp4162-103", MCP416x_103 }, 4418c2ecf20Sopenharmony_ci { "mcp4162-503", MCP416x_503 }, 4428c2ecf20Sopenharmony_ci { "mcp4162-104", MCP416x_104 }, 4438c2ecf20Sopenharmony_ci { "mcp4231-502", MCP423x_502 }, 4448c2ecf20Sopenharmony_ci { "mcp4231-103", MCP423x_103 }, 4458c2ecf20Sopenharmony_ci { "mcp4231-503", MCP423x_503 }, 4468c2ecf20Sopenharmony_ci { "mcp4231-104", MCP423x_104 }, 4478c2ecf20Sopenharmony_ci { "mcp4232-502", MCP423x_502 }, 4488c2ecf20Sopenharmony_ci { "mcp4232-103", MCP423x_103 }, 4498c2ecf20Sopenharmony_ci { "mcp4232-503", MCP423x_503 }, 4508c2ecf20Sopenharmony_ci { "mcp4232-104", MCP423x_104 }, 4518c2ecf20Sopenharmony_ci { "mcp4241-502", MCP424x_502 }, 4528c2ecf20Sopenharmony_ci { "mcp4241-103", MCP424x_103 }, 4538c2ecf20Sopenharmony_ci { "mcp4241-503", MCP424x_503 }, 4548c2ecf20Sopenharmony_ci { "mcp4241-104", MCP424x_104 }, 4558c2ecf20Sopenharmony_ci { "mcp4242-502", MCP424x_502 }, 4568c2ecf20Sopenharmony_ci { "mcp4242-103", MCP424x_103 }, 4578c2ecf20Sopenharmony_ci { "mcp4242-503", MCP424x_503 }, 4588c2ecf20Sopenharmony_ci { "mcp4242-104", MCP424x_104 }, 4598c2ecf20Sopenharmony_ci { "mcp4251-502", MCP425x_502 }, 4608c2ecf20Sopenharmony_ci { "mcp4251-103", MCP425x_103 }, 4618c2ecf20Sopenharmony_ci { "mcp4251-503", MCP425x_503 }, 4628c2ecf20Sopenharmony_ci { "mcp4251-104", MCP425x_104 }, 4638c2ecf20Sopenharmony_ci { "mcp4252-502", MCP425x_502 }, 4648c2ecf20Sopenharmony_ci { "mcp4252-103", MCP425x_103 }, 4658c2ecf20Sopenharmony_ci { "mcp4252-503", MCP425x_503 }, 4668c2ecf20Sopenharmony_ci { "mcp4252-104", MCP425x_104 }, 4678c2ecf20Sopenharmony_ci { "mcp4261-502", MCP426x_502 }, 4688c2ecf20Sopenharmony_ci { "mcp4261-103", MCP426x_103 }, 4698c2ecf20Sopenharmony_ci { "mcp4261-503", MCP426x_503 }, 4708c2ecf20Sopenharmony_ci { "mcp4261-104", MCP426x_104 }, 4718c2ecf20Sopenharmony_ci { "mcp4262-502", MCP426x_502 }, 4728c2ecf20Sopenharmony_ci { "mcp4262-103", MCP426x_103 }, 4738c2ecf20Sopenharmony_ci { "mcp4262-503", MCP426x_503 }, 4748c2ecf20Sopenharmony_ci { "mcp4262-104", MCP426x_104 }, 4758c2ecf20Sopenharmony_ci {} 4768c2ecf20Sopenharmony_ci}; 4778c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(spi, mcp4131_id); 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_cistatic struct spi_driver mcp4131_driver = { 4808c2ecf20Sopenharmony_ci .driver = { 4818c2ecf20Sopenharmony_ci .name = "mcp4131", 4828c2ecf20Sopenharmony_ci .of_match_table = mcp4131_dt_ids, 4838c2ecf20Sopenharmony_ci }, 4848c2ecf20Sopenharmony_ci .probe = mcp4131_probe, 4858c2ecf20Sopenharmony_ci .id_table = mcp4131_id, 4868c2ecf20Sopenharmony_ci}; 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_cimodule_spi_driver(mcp4131_driver); 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ciMODULE_AUTHOR("Slawomir Stepien <sst@poczta.fm>"); 4918c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("MCP4131 digital potentiometer"); 4928c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL v2"); 493