1 // SPDX-License-Identifier: GPL-2.0
3 * Industrial I/O driver for Microchip digital potentiometers
4 * Copyright (c) 2018 Axentia Technologies AB
5 * Author: Peter Rosin <peda@axentia.se>
7 * Datasheet: http://www.microchip.com/downloads/en/DeviceDoc/22147a.pdf
9 * DEVID #Wipers #Positions Resistor Opts (kOhm)
10 * mcp4017 1 128 5, 10, 50, 100
11 * mcp4018 1 128 5, 10, 50, 100
12 * mcp4019 1 128 5, 10, 50, 100
15 #include <linux/err.h>
16 #include <linux/i2c.h>
17 #include <linux/iio/iio.h>
18 #include <linux/module.h>
19 #include <linux/mod_devicetable.h>
20 #include <linux/property.h>
22 #define MCP4018_WIPER_MAX 127
35 static const struct mcp4018_cfg mcp4018_cfg
[] = {
36 [MCP4018_502
] = { .kohms
= 5, },
37 [MCP4018_103
] = { .kohms
= 10, },
38 [MCP4018_503
] = { .kohms
= 50, },
39 [MCP4018_104
] = { .kohms
= 100, },
43 struct i2c_client
*client
;
44 const struct mcp4018_cfg
*cfg
;
47 static const struct iio_chan_spec mcp4018_channel
= {
48 .type
= IIO_RESISTANCE
,
52 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
53 .info_mask_shared_by_type
= BIT(IIO_CHAN_INFO_SCALE
),
56 static int mcp4018_read_raw(struct iio_dev
*indio_dev
,
57 struct iio_chan_spec
const *chan
,
58 int *val
, int *val2
, long mask
)
60 struct mcp4018_data
*data
= iio_priv(indio_dev
);
64 case IIO_CHAN_INFO_RAW
:
65 ret
= i2c_smbus_read_byte(data
->client
);
70 case IIO_CHAN_INFO_SCALE
:
71 *val
= 1000 * data
->cfg
->kohms
;
72 *val2
= MCP4018_WIPER_MAX
;
73 return IIO_VAL_FRACTIONAL
;
79 static int mcp4018_write_raw(struct iio_dev
*indio_dev
,
80 struct iio_chan_spec
const *chan
,
81 int val
, int val2
, long mask
)
83 struct mcp4018_data
*data
= iio_priv(indio_dev
);
86 case IIO_CHAN_INFO_RAW
:
87 if (val
> MCP4018_WIPER_MAX
|| val
< 0)
94 return i2c_smbus_write_byte(data
->client
, val
);
97 static const struct iio_info mcp4018_info
= {
98 .read_raw
= mcp4018_read_raw
,
99 .write_raw
= mcp4018_write_raw
,
102 #define MCP4018_ID_TABLE(_name, cfg) { \
104 .driver_data = (kernel_ulong_t)&mcp4018_cfg[cfg], \
107 static const struct i2c_device_id mcp4018_id
[] = {
108 MCP4018_ID_TABLE("mcp4017-502", MCP4018_502
),
109 MCP4018_ID_TABLE("mcp4017-103", MCP4018_103
),
110 MCP4018_ID_TABLE("mcp4017-503", MCP4018_503
),
111 MCP4018_ID_TABLE("mcp4017-104", MCP4018_104
),
112 MCP4018_ID_TABLE("mcp4018-502", MCP4018_502
),
113 MCP4018_ID_TABLE("mcp4018-103", MCP4018_103
),
114 MCP4018_ID_TABLE("mcp4018-503", MCP4018_503
),
115 MCP4018_ID_TABLE("mcp4018-104", MCP4018_104
),
116 MCP4018_ID_TABLE("mcp4019-502", MCP4018_502
),
117 MCP4018_ID_TABLE("mcp4019-103", MCP4018_103
),
118 MCP4018_ID_TABLE("mcp4019-503", MCP4018_503
),
119 MCP4018_ID_TABLE("mcp4019-104", MCP4018_104
),
122 MODULE_DEVICE_TABLE(i2c
, mcp4018_id
);
124 #define MCP4018_COMPATIBLE(of_compatible, cfg) { \
125 .compatible = of_compatible, \
126 .data = &mcp4018_cfg[cfg], \
129 static const struct of_device_id mcp4018_of_match
[] = {
130 MCP4018_COMPATIBLE("microchip,mcp4017-502", MCP4018_502
),
131 MCP4018_COMPATIBLE("microchip,mcp4017-103", MCP4018_103
),
132 MCP4018_COMPATIBLE("microchip,mcp4017-503", MCP4018_503
),
133 MCP4018_COMPATIBLE("microchip,mcp4017-104", MCP4018_104
),
134 MCP4018_COMPATIBLE("microchip,mcp4018-502", MCP4018_502
),
135 MCP4018_COMPATIBLE("microchip,mcp4018-103", MCP4018_103
),
136 MCP4018_COMPATIBLE("microchip,mcp4018-503", MCP4018_503
),
137 MCP4018_COMPATIBLE("microchip,mcp4018-104", MCP4018_104
),
138 MCP4018_COMPATIBLE("microchip,mcp4019-502", MCP4018_502
),
139 MCP4018_COMPATIBLE("microchip,mcp4019-103", MCP4018_103
),
140 MCP4018_COMPATIBLE("microchip,mcp4019-503", MCP4018_503
),
141 MCP4018_COMPATIBLE("microchip,mcp4019-104", MCP4018_104
),
144 MODULE_DEVICE_TABLE(of
, mcp4018_of_match
);
146 static int mcp4018_probe(struct i2c_client
*client
)
148 struct device
*dev
= &client
->dev
;
149 struct mcp4018_data
*data
;
150 struct iio_dev
*indio_dev
;
152 if (!i2c_check_functionality(client
->adapter
,
153 I2C_FUNC_SMBUS_BYTE
)) {
154 dev_err(dev
, "SMBUS Byte transfers not supported\n");
158 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*data
));
161 data
= iio_priv(indio_dev
);
162 i2c_set_clientdata(client
, indio_dev
);
163 data
->client
= client
;
165 data
->cfg
= i2c_get_match_data(client
);
167 indio_dev
->info
= &mcp4018_info
;
168 indio_dev
->channels
= &mcp4018_channel
;
169 indio_dev
->num_channels
= 1;
170 indio_dev
->name
= client
->name
;
172 return devm_iio_device_register(dev
, indio_dev
);
175 static struct i2c_driver mcp4018_driver
= {
178 .of_match_table
= mcp4018_of_match
,
180 .probe
= mcp4018_probe
,
181 .id_table
= mcp4018_id
,
184 module_i2c_driver(mcp4018_driver
);
186 MODULE_AUTHOR("Peter Rosin <peda@axentia.se>");
187 MODULE_DESCRIPTION("MCP4018 digital potentiometer");
188 MODULE_LICENSE("GPL v2");