162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Industrial I/O driver for Microchip digital potentiometers
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2016 Slawomir Stepien
662306a36Sopenharmony_ci * Based on: Peter Rosin's code from mcp4531.c
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/22060b.pdf
962306a36Sopenharmony_ci *
1062306a36Sopenharmony_ci * DEVID	#Wipers	#Positions	Resistor Opts (kOhm)
1162306a36Sopenharmony_ci * mcp4131	1	129		5, 10, 50, 100
1262306a36Sopenharmony_ci * mcp4132	1	129		5, 10, 50, 100
1362306a36Sopenharmony_ci * mcp4141	1	129		5, 10, 50, 100
1462306a36Sopenharmony_ci * mcp4142	1	129		5, 10, 50, 100
1562306a36Sopenharmony_ci * mcp4151	1	257		5, 10, 50, 100
1662306a36Sopenharmony_ci * mcp4152	1	257		5, 10, 50, 100
1762306a36Sopenharmony_ci * mcp4161	1	257		5, 10, 50, 100
1862306a36Sopenharmony_ci * mcp4162	1	257		5, 10, 50, 100
1962306a36Sopenharmony_ci * mcp4231	2	129		5, 10, 50, 100
2062306a36Sopenharmony_ci * mcp4232	2	129		5, 10, 50, 100
2162306a36Sopenharmony_ci * mcp4241	2	129		5, 10, 50, 100
2262306a36Sopenharmony_ci * mcp4242	2	129		5, 10, 50, 100
2362306a36Sopenharmony_ci * mcp4251	2	257		5, 10, 50, 100
2462306a36Sopenharmony_ci * mcp4252	2	257		5, 10, 50, 100
2562306a36Sopenharmony_ci * mcp4261	2	257		5, 10, 50, 100
2662306a36Sopenharmony_ci * mcp4262	2	257		5, 10, 50, 100
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci/*
3062306a36Sopenharmony_ci * TODO:
3162306a36Sopenharmony_ci * 1. Write wiper setting to EEPROM for EEPROM capable models.
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci#include <linux/cache.h>
3562306a36Sopenharmony_ci#include <linux/err.h>
3662306a36Sopenharmony_ci#include <linux/export.h>
3762306a36Sopenharmony_ci#include <linux/iio/iio.h>
3862306a36Sopenharmony_ci#include <linux/iio/types.h>
3962306a36Sopenharmony_ci#include <linux/module.h>
4062306a36Sopenharmony_ci#include <linux/mod_devicetable.h>
4162306a36Sopenharmony_ci#include <linux/mutex.h>
4262306a36Sopenharmony_ci#include <linux/property.h>
4362306a36Sopenharmony_ci#include <linux/spi/spi.h>
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#define MCP4131_WRITE		(0x00 << 2)
4662306a36Sopenharmony_ci#define MCP4131_READ		(0x03 << 2)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci#define MCP4131_WIPER_SHIFT	4
4962306a36Sopenharmony_ci#define MCP4131_CMDERR(r)	((r[0]) & 0x02)
5062306a36Sopenharmony_ci#define MCP4131_RAW(r)		((r[0]) == 0xff ? 0x100 : (r[1]))
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cistruct mcp4131_cfg {
5362306a36Sopenharmony_ci	int wipers;
5462306a36Sopenharmony_ci	int max_pos;
5562306a36Sopenharmony_ci	int kohms;
5662306a36Sopenharmony_ci};
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cienum mcp4131_type {
5962306a36Sopenharmony_ci	MCP413x_502 = 0,
6062306a36Sopenharmony_ci	MCP413x_103,
6162306a36Sopenharmony_ci	MCP413x_503,
6262306a36Sopenharmony_ci	MCP413x_104,
6362306a36Sopenharmony_ci	MCP414x_502,
6462306a36Sopenharmony_ci	MCP414x_103,
6562306a36Sopenharmony_ci	MCP414x_503,
6662306a36Sopenharmony_ci	MCP414x_104,
6762306a36Sopenharmony_ci	MCP415x_502,
6862306a36Sopenharmony_ci	MCP415x_103,
6962306a36Sopenharmony_ci	MCP415x_503,
7062306a36Sopenharmony_ci	MCP415x_104,
7162306a36Sopenharmony_ci	MCP416x_502,
7262306a36Sopenharmony_ci	MCP416x_103,
7362306a36Sopenharmony_ci	MCP416x_503,
7462306a36Sopenharmony_ci	MCP416x_104,
7562306a36Sopenharmony_ci	MCP423x_502,
7662306a36Sopenharmony_ci	MCP423x_103,
7762306a36Sopenharmony_ci	MCP423x_503,
7862306a36Sopenharmony_ci	MCP423x_104,
7962306a36Sopenharmony_ci	MCP424x_502,
8062306a36Sopenharmony_ci	MCP424x_103,
8162306a36Sopenharmony_ci	MCP424x_503,
8262306a36Sopenharmony_ci	MCP424x_104,
8362306a36Sopenharmony_ci	MCP425x_502,
8462306a36Sopenharmony_ci	MCP425x_103,
8562306a36Sopenharmony_ci	MCP425x_503,
8662306a36Sopenharmony_ci	MCP425x_104,
8762306a36Sopenharmony_ci	MCP426x_502,
8862306a36Sopenharmony_ci	MCP426x_103,
8962306a36Sopenharmony_ci	MCP426x_503,
9062306a36Sopenharmony_ci	MCP426x_104,
9162306a36Sopenharmony_ci};
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic const struct mcp4131_cfg mcp4131_cfg[] = {
9462306a36Sopenharmony_ci	[MCP413x_502] = { .wipers = 1, .max_pos = 128, .kohms =   5, },
9562306a36Sopenharmony_ci	[MCP413x_103] = { .wipers = 1, .max_pos = 128, .kohms =  10, },
9662306a36Sopenharmony_ci	[MCP413x_503] = { .wipers = 1, .max_pos = 128, .kohms =  50, },
9762306a36Sopenharmony_ci	[MCP413x_104] = { .wipers = 1, .max_pos = 128, .kohms = 100, },
9862306a36Sopenharmony_ci	[MCP414x_502] = { .wipers = 1, .max_pos = 128, .kohms =   5, },
9962306a36Sopenharmony_ci	[MCP414x_103] = { .wipers = 1, .max_pos = 128, .kohms =  10, },
10062306a36Sopenharmony_ci	[MCP414x_503] = { .wipers = 1, .max_pos = 128, .kohms =  50, },
10162306a36Sopenharmony_ci	[MCP414x_104] = { .wipers = 1, .max_pos = 128, .kohms = 100, },
10262306a36Sopenharmony_ci	[MCP415x_502] = { .wipers = 1, .max_pos = 256, .kohms =   5, },
10362306a36Sopenharmony_ci	[MCP415x_103] = { .wipers = 1, .max_pos = 256, .kohms =  10, },
10462306a36Sopenharmony_ci	[MCP415x_503] = { .wipers = 1, .max_pos = 256, .kohms =  50, },
10562306a36Sopenharmony_ci	[MCP415x_104] = { .wipers = 1, .max_pos = 256, .kohms = 100, },
10662306a36Sopenharmony_ci	[MCP416x_502] = { .wipers = 1, .max_pos = 256, .kohms =   5, },
10762306a36Sopenharmony_ci	[MCP416x_103] = { .wipers = 1, .max_pos = 256, .kohms =  10, },
10862306a36Sopenharmony_ci	[MCP416x_503] = { .wipers = 1, .max_pos = 256, .kohms =  50, },
10962306a36Sopenharmony_ci	[MCP416x_104] = { .wipers = 1, .max_pos = 256, .kohms = 100, },
11062306a36Sopenharmony_ci	[MCP423x_502] = { .wipers = 2, .max_pos = 128, .kohms =   5, },
11162306a36Sopenharmony_ci	[MCP423x_103] = { .wipers = 2, .max_pos = 128, .kohms =  10, },
11262306a36Sopenharmony_ci	[MCP423x_503] = { .wipers = 2, .max_pos = 128, .kohms =  50, },
11362306a36Sopenharmony_ci	[MCP423x_104] = { .wipers = 2, .max_pos = 128, .kohms = 100, },
11462306a36Sopenharmony_ci	[MCP424x_502] = { .wipers = 2, .max_pos = 128, .kohms =   5, },
11562306a36Sopenharmony_ci	[MCP424x_103] = { .wipers = 2, .max_pos = 128, .kohms =  10, },
11662306a36Sopenharmony_ci	[MCP424x_503] = { .wipers = 2, .max_pos = 128, .kohms =  50, },
11762306a36Sopenharmony_ci	[MCP424x_104] = { .wipers = 2, .max_pos = 128, .kohms = 100, },
11862306a36Sopenharmony_ci	[MCP425x_502] = { .wipers = 2, .max_pos = 256, .kohms =   5, },
11962306a36Sopenharmony_ci	[MCP425x_103] = { .wipers = 2, .max_pos = 256, .kohms =  10, },
12062306a36Sopenharmony_ci	[MCP425x_503] = { .wipers = 2, .max_pos = 256, .kohms =  50, },
12162306a36Sopenharmony_ci	[MCP425x_104] = { .wipers = 2, .max_pos = 256, .kohms = 100, },
12262306a36Sopenharmony_ci	[MCP426x_502] = { .wipers = 2, .max_pos = 256, .kohms =   5, },
12362306a36Sopenharmony_ci	[MCP426x_103] = { .wipers = 2, .max_pos = 256, .kohms =  10, },
12462306a36Sopenharmony_ci	[MCP426x_503] = { .wipers = 2, .max_pos = 256, .kohms =  50, },
12562306a36Sopenharmony_ci	[MCP426x_104] = { .wipers = 2, .max_pos = 256, .kohms = 100, },
12662306a36Sopenharmony_ci};
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cistruct mcp4131_data {
12962306a36Sopenharmony_ci	struct spi_device *spi;
13062306a36Sopenharmony_ci	const struct mcp4131_cfg *cfg;
13162306a36Sopenharmony_ci	struct mutex lock;
13262306a36Sopenharmony_ci	u8 buf[2] __aligned(IIO_DMA_MINALIGN);
13362306a36Sopenharmony_ci};
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci#define MCP4131_CHANNEL(ch) {					\
13662306a36Sopenharmony_ci	.type = IIO_RESISTANCE,					\
13762306a36Sopenharmony_ci	.indexed = 1,						\
13862306a36Sopenharmony_ci	.output = 1,						\
13962306a36Sopenharmony_ci	.channel = (ch),					\
14062306a36Sopenharmony_ci	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
14162306a36Sopenharmony_ci	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_cistatic const struct iio_chan_spec mcp4131_channels[] = {
14562306a36Sopenharmony_ci	MCP4131_CHANNEL(0),
14662306a36Sopenharmony_ci	MCP4131_CHANNEL(1),
14762306a36Sopenharmony_ci};
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistatic int mcp4131_read(struct spi_device *spi, void *buf, size_t len)
15062306a36Sopenharmony_ci{
15162306a36Sopenharmony_ci	struct spi_transfer t = {
15262306a36Sopenharmony_ci		.tx_buf = buf, /* We need to send addr, cmd and 12 bits */
15362306a36Sopenharmony_ci		.rx_buf	= buf,
15462306a36Sopenharmony_ci		.len = len,
15562306a36Sopenharmony_ci	};
15662306a36Sopenharmony_ci	struct spi_message m;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	spi_message_init(&m);
15962306a36Sopenharmony_ci	spi_message_add_tail(&t, &m);
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci	return spi_sync(spi, &m);
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistatic int mcp4131_read_raw(struct iio_dev *indio_dev,
16562306a36Sopenharmony_ci			    struct iio_chan_spec const *chan,
16662306a36Sopenharmony_ci			    int *val, int *val2, long mask)
16762306a36Sopenharmony_ci{
16862306a36Sopenharmony_ci	int err;
16962306a36Sopenharmony_ci	struct mcp4131_data *data = iio_priv(indio_dev);
17062306a36Sopenharmony_ci	int address = chan->channel;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	switch (mask) {
17362306a36Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
17462306a36Sopenharmony_ci		mutex_lock(&data->lock);
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci		data->buf[0] = (address << MCP4131_WIPER_SHIFT) | MCP4131_READ;
17762306a36Sopenharmony_ci		data->buf[1] = 0;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci		err = mcp4131_read(data->spi, data->buf, 2);
18062306a36Sopenharmony_ci		if (err) {
18162306a36Sopenharmony_ci			mutex_unlock(&data->lock);
18262306a36Sopenharmony_ci			return err;
18362306a36Sopenharmony_ci		}
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci		/* Error, bad address/command combination */
18662306a36Sopenharmony_ci		if (!MCP4131_CMDERR(data->buf)) {
18762306a36Sopenharmony_ci			mutex_unlock(&data->lock);
18862306a36Sopenharmony_ci			return -EIO;
18962306a36Sopenharmony_ci		}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci		*val = MCP4131_RAW(data->buf);
19262306a36Sopenharmony_ci		mutex_unlock(&data->lock);
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci		return IIO_VAL_INT;
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	case IIO_CHAN_INFO_SCALE:
19762306a36Sopenharmony_ci		*val = 1000 * data->cfg->kohms;
19862306a36Sopenharmony_ci		*val2 = data->cfg->max_pos;
19962306a36Sopenharmony_ci		return IIO_VAL_FRACTIONAL;
20062306a36Sopenharmony_ci	}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	return -EINVAL;
20362306a36Sopenharmony_ci}
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_cistatic int mcp4131_write_raw(struct iio_dev *indio_dev,
20662306a36Sopenharmony_ci			     struct iio_chan_spec const *chan,
20762306a36Sopenharmony_ci			     int val, int val2, long mask)
20862306a36Sopenharmony_ci{
20962306a36Sopenharmony_ci	int err;
21062306a36Sopenharmony_ci	struct mcp4131_data *data = iio_priv(indio_dev);
21162306a36Sopenharmony_ci	int address = chan->channel << MCP4131_WIPER_SHIFT;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	switch (mask) {
21462306a36Sopenharmony_ci	case IIO_CHAN_INFO_RAW:
21562306a36Sopenharmony_ci		if (val > data->cfg->max_pos || val < 0)
21662306a36Sopenharmony_ci			return -EINVAL;
21762306a36Sopenharmony_ci		break;
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	default:
22062306a36Sopenharmony_ci		return -EINVAL;
22162306a36Sopenharmony_ci	}
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	mutex_lock(&data->lock);
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	data->buf[0] = address << MCP4131_WIPER_SHIFT;
22662306a36Sopenharmony_ci	data->buf[0] |= MCP4131_WRITE | (val >> 8);
22762306a36Sopenharmony_ci	data->buf[1] = val & 0xFF; /* 8 bits here */
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci	err = spi_write(data->spi, data->buf, 2);
23062306a36Sopenharmony_ci	mutex_unlock(&data->lock);
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	return err;
23362306a36Sopenharmony_ci}
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_cistatic const struct iio_info mcp4131_info = {
23662306a36Sopenharmony_ci	.read_raw = mcp4131_read_raw,
23762306a36Sopenharmony_ci	.write_raw = mcp4131_write_raw,
23862306a36Sopenharmony_ci};
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_cistatic int mcp4131_probe(struct spi_device *spi)
24162306a36Sopenharmony_ci{
24262306a36Sopenharmony_ci	int err;
24362306a36Sopenharmony_ci	struct device *dev = &spi->dev;
24462306a36Sopenharmony_ci	unsigned long devid;
24562306a36Sopenharmony_ci	struct mcp4131_data *data;
24662306a36Sopenharmony_ci	struct iio_dev *indio_dev;
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
24962306a36Sopenharmony_ci	if (!indio_dev)
25062306a36Sopenharmony_ci		return -ENOMEM;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	data = iio_priv(indio_dev);
25362306a36Sopenharmony_ci	spi_set_drvdata(spi, indio_dev);
25462306a36Sopenharmony_ci	data->spi = spi;
25562306a36Sopenharmony_ci	data->cfg = device_get_match_data(&spi->dev);
25662306a36Sopenharmony_ci	if (!data->cfg) {
25762306a36Sopenharmony_ci		devid = spi_get_device_id(spi)->driver_data;
25862306a36Sopenharmony_ci		data->cfg = &mcp4131_cfg[devid];
25962306a36Sopenharmony_ci	}
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	mutex_init(&data->lock);
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	indio_dev->info = &mcp4131_info;
26462306a36Sopenharmony_ci	indio_dev->channels = mcp4131_channels;
26562306a36Sopenharmony_ci	indio_dev->num_channels = data->cfg->wipers;
26662306a36Sopenharmony_ci	indio_dev->name = spi_get_device_id(spi)->name;
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	err = devm_iio_device_register(dev, indio_dev);
26962306a36Sopenharmony_ci	if (err) {
27062306a36Sopenharmony_ci		dev_info(&spi->dev, "Unable to register %s\n", indio_dev->name);
27162306a36Sopenharmony_ci		return err;
27262306a36Sopenharmony_ci	}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	return 0;
27562306a36Sopenharmony_ci}
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_cistatic const struct of_device_id mcp4131_dt_ids[] = {
27862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4131-502",
27962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP413x_502] },
28062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4131-103",
28162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP413x_103] },
28262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4131-503",
28362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP413x_503] },
28462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4131-104",
28562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP413x_104] },
28662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4132-502",
28762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP413x_502] },
28862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4132-103",
28962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP413x_103] },
29062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4132-503",
29162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP413x_503] },
29262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4132-104",
29362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP413x_104] },
29462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4141-502",
29562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP414x_502] },
29662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4141-103",
29762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP414x_103] },
29862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4141-503",
29962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP414x_503] },
30062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4141-104",
30162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP414x_104] },
30262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4142-502",
30362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP414x_502] },
30462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4142-103",
30562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP414x_103] },
30662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4142-503",
30762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP414x_503] },
30862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4142-104",
30962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP414x_104] },
31062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4151-502",
31162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP415x_502] },
31262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4151-103",
31362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP415x_103] },
31462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4151-503",
31562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP415x_503] },
31662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4151-104",
31762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP415x_104] },
31862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4152-502",
31962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP415x_502] },
32062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4152-103",
32162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP415x_103] },
32262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4152-503",
32362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP415x_503] },
32462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4152-104",
32562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP415x_104] },
32662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4161-502",
32762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP416x_502] },
32862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4161-103",
32962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP416x_103] },
33062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4161-503",
33162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP416x_503] },
33262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4161-104",
33362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP416x_104] },
33462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4162-502",
33562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP416x_502] },
33662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4162-103",
33762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP416x_103] },
33862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4162-503",
33962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP416x_503] },
34062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4162-104",
34162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP416x_104] },
34262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4231-502",
34362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP423x_502] },
34462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4231-103",
34562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP423x_103] },
34662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4231-503",
34762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP423x_503] },
34862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4231-104",
34962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP423x_104] },
35062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4232-502",
35162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP423x_502] },
35262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4232-103",
35362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP423x_103] },
35462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4232-503",
35562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP423x_503] },
35662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4232-104",
35762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP423x_104] },
35862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4241-502",
35962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP424x_502] },
36062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4241-103",
36162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP424x_103] },
36262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4241-503",
36362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP424x_503] },
36462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4241-104",
36562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP424x_104] },
36662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4242-502",
36762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP424x_502] },
36862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4242-103",
36962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP424x_103] },
37062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4242-503",
37162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP424x_503] },
37262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4242-104",
37362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP424x_104] },
37462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4251-502",
37562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP425x_502] },
37662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4251-103",
37762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP425x_103] },
37862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4251-503",
37962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP425x_503] },
38062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4251-104",
38162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP425x_104] },
38262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4252-502",
38362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP425x_502] },
38462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4252-103",
38562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP425x_103] },
38662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4252-503",
38762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP425x_503] },
38862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4252-104",
38962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP425x_104] },
39062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4261-502",
39162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP426x_502] },
39262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4261-103",
39362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP426x_103] },
39462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4261-503",
39562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP426x_503] },
39662306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4261-104",
39762306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP426x_104] },
39862306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4262-502",
39962306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP426x_502] },
40062306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4262-103",
40162306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP426x_103] },
40262306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4262-503",
40362306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP426x_503] },
40462306a36Sopenharmony_ci	{ .compatible = "microchip,mcp4262-104",
40562306a36Sopenharmony_ci		.data = &mcp4131_cfg[MCP426x_104] },
40662306a36Sopenharmony_ci	{}
40762306a36Sopenharmony_ci};
40862306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, mcp4131_dt_ids);
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_cistatic const struct spi_device_id mcp4131_id[] = {
41162306a36Sopenharmony_ci	{ "mcp4131-502", MCP413x_502 },
41262306a36Sopenharmony_ci	{ "mcp4131-103", MCP413x_103 },
41362306a36Sopenharmony_ci	{ "mcp4131-503", MCP413x_503 },
41462306a36Sopenharmony_ci	{ "mcp4131-104", MCP413x_104 },
41562306a36Sopenharmony_ci	{ "mcp4132-502", MCP413x_502 },
41662306a36Sopenharmony_ci	{ "mcp4132-103", MCP413x_103 },
41762306a36Sopenharmony_ci	{ "mcp4132-503", MCP413x_503 },
41862306a36Sopenharmony_ci	{ "mcp4132-104", MCP413x_104 },
41962306a36Sopenharmony_ci	{ "mcp4141-502", MCP414x_502 },
42062306a36Sopenharmony_ci	{ "mcp4141-103", MCP414x_103 },
42162306a36Sopenharmony_ci	{ "mcp4141-503", MCP414x_503 },
42262306a36Sopenharmony_ci	{ "mcp4141-104", MCP414x_104 },
42362306a36Sopenharmony_ci	{ "mcp4142-502", MCP414x_502 },
42462306a36Sopenharmony_ci	{ "mcp4142-103", MCP414x_103 },
42562306a36Sopenharmony_ci	{ "mcp4142-503", MCP414x_503 },
42662306a36Sopenharmony_ci	{ "mcp4142-104", MCP414x_104 },
42762306a36Sopenharmony_ci	{ "mcp4151-502", MCP415x_502 },
42862306a36Sopenharmony_ci	{ "mcp4151-103", MCP415x_103 },
42962306a36Sopenharmony_ci	{ "mcp4151-503", MCP415x_503 },
43062306a36Sopenharmony_ci	{ "mcp4151-104", MCP415x_104 },
43162306a36Sopenharmony_ci	{ "mcp4152-502", MCP415x_502 },
43262306a36Sopenharmony_ci	{ "mcp4152-103", MCP415x_103 },
43362306a36Sopenharmony_ci	{ "mcp4152-503", MCP415x_503 },
43462306a36Sopenharmony_ci	{ "mcp4152-104", MCP415x_104 },
43562306a36Sopenharmony_ci	{ "mcp4161-502", MCP416x_502 },
43662306a36Sopenharmony_ci	{ "mcp4161-103", MCP416x_103 },
43762306a36Sopenharmony_ci	{ "mcp4161-503", MCP416x_503 },
43862306a36Sopenharmony_ci	{ "mcp4161-104", MCP416x_104 },
43962306a36Sopenharmony_ci	{ "mcp4162-502", MCP416x_502 },
44062306a36Sopenharmony_ci	{ "mcp4162-103", MCP416x_103 },
44162306a36Sopenharmony_ci	{ "mcp4162-503", MCP416x_503 },
44262306a36Sopenharmony_ci	{ "mcp4162-104", MCP416x_104 },
44362306a36Sopenharmony_ci	{ "mcp4231-502", MCP423x_502 },
44462306a36Sopenharmony_ci	{ "mcp4231-103", MCP423x_103 },
44562306a36Sopenharmony_ci	{ "mcp4231-503", MCP423x_503 },
44662306a36Sopenharmony_ci	{ "mcp4231-104", MCP423x_104 },
44762306a36Sopenharmony_ci	{ "mcp4232-502", MCP423x_502 },
44862306a36Sopenharmony_ci	{ "mcp4232-103", MCP423x_103 },
44962306a36Sopenharmony_ci	{ "mcp4232-503", MCP423x_503 },
45062306a36Sopenharmony_ci	{ "mcp4232-104", MCP423x_104 },
45162306a36Sopenharmony_ci	{ "mcp4241-502", MCP424x_502 },
45262306a36Sopenharmony_ci	{ "mcp4241-103", MCP424x_103 },
45362306a36Sopenharmony_ci	{ "mcp4241-503", MCP424x_503 },
45462306a36Sopenharmony_ci	{ "mcp4241-104", MCP424x_104 },
45562306a36Sopenharmony_ci	{ "mcp4242-502", MCP424x_502 },
45662306a36Sopenharmony_ci	{ "mcp4242-103", MCP424x_103 },
45762306a36Sopenharmony_ci	{ "mcp4242-503", MCP424x_503 },
45862306a36Sopenharmony_ci	{ "mcp4242-104", MCP424x_104 },
45962306a36Sopenharmony_ci	{ "mcp4251-502", MCP425x_502 },
46062306a36Sopenharmony_ci	{ "mcp4251-103", MCP425x_103 },
46162306a36Sopenharmony_ci	{ "mcp4251-503", MCP425x_503 },
46262306a36Sopenharmony_ci	{ "mcp4251-104", MCP425x_104 },
46362306a36Sopenharmony_ci	{ "mcp4252-502", MCP425x_502 },
46462306a36Sopenharmony_ci	{ "mcp4252-103", MCP425x_103 },
46562306a36Sopenharmony_ci	{ "mcp4252-503", MCP425x_503 },
46662306a36Sopenharmony_ci	{ "mcp4252-104", MCP425x_104 },
46762306a36Sopenharmony_ci	{ "mcp4261-502", MCP426x_502 },
46862306a36Sopenharmony_ci	{ "mcp4261-103", MCP426x_103 },
46962306a36Sopenharmony_ci	{ "mcp4261-503", MCP426x_503 },
47062306a36Sopenharmony_ci	{ "mcp4261-104", MCP426x_104 },
47162306a36Sopenharmony_ci	{ "mcp4262-502", MCP426x_502 },
47262306a36Sopenharmony_ci	{ "mcp4262-103", MCP426x_103 },
47362306a36Sopenharmony_ci	{ "mcp4262-503", MCP426x_503 },
47462306a36Sopenharmony_ci	{ "mcp4262-104", MCP426x_104 },
47562306a36Sopenharmony_ci	{}
47662306a36Sopenharmony_ci};
47762306a36Sopenharmony_ciMODULE_DEVICE_TABLE(spi, mcp4131_id);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_cistatic struct spi_driver mcp4131_driver = {
48062306a36Sopenharmony_ci	.driver = {
48162306a36Sopenharmony_ci		.name	= "mcp4131",
48262306a36Sopenharmony_ci		.of_match_table = mcp4131_dt_ids,
48362306a36Sopenharmony_ci	},
48462306a36Sopenharmony_ci	.probe		= mcp4131_probe,
48562306a36Sopenharmony_ci	.id_table	= mcp4131_id,
48662306a36Sopenharmony_ci};
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_cimodule_spi_driver(mcp4131_driver);
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ciMODULE_AUTHOR("Slawomir Stepien <sst@poczta.fm>");
49162306a36Sopenharmony_ciMODULE_DESCRIPTION("MCP4131 digital potentiometer");
49262306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
493