xref: /linux/drivers/iio/dac/mcp4821.c (revision 3a2c4d55e32ad65efebdb6de44eef3bfa08bb49d)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2023 Anshul Dalal <anshulusr@gmail.com>
4  *
5  * Driver for Microchip MCP4801, MCP4802, MCP4811, MCP4812, MCP4821 and MCP4822
6  *
7  * Based on the work of:
8  *	Michael Welling (MCP4922 Driver)
9  *
10  * Datasheet:
11  *	MCP48x1: https://ww1.microchip.com/downloads/en/DeviceDoc/22244B.pdf
12  *	MCP48x2: https://ww1.microchip.com/downloads/en/DeviceDoc/20002249B.pdf
13  *
14  * TODO:
15  *	- Regulator control
16  */
17 
18 #include <linux/module.h>
19 #include <linux/spi/spi.h>
20 #include <linux/units.h>
21 
22 #include <linux/iio/iio.h>
23 #include <linux/iio/types.h>
24 
25 #include <linux/unaligned.h>
26 
27 #define MCP4821_ACTIVE_MODE BIT(12)
28 #define MCP4821_GAIN_ENABLE BIT(13)
29 #define MCP4802_SECOND_CHAN BIT(15)
30 
31 /* DAC uses an internal Voltage reference of 2.048V */
32 #define MCP4821_VREF_MV 2048
33 
34 /*
35  * MCP48xx DAC output:
36  *
37  * Vout = (Vref * D / 2^N) * G
38  *
39  * where:
40  *  - Vref = 2.048V (internal reference)
41  *  - N = DAC resolution (12 bits for MCP4821)
42  *  - G = gain selection:
43  *        1x when GA bit = 1
44  *        2x when GA bit = 0 (default)
45  *
46  * Therefore full-scale voltage is:
47  *  - 1x gain: 2.048V
48  *  - 2x gain: 4.096V
49  *
50  * Scale = Vfull-scale / 2^N
51  */
52 
53 enum mcp4821_supported_device_ids {
54 	ID_MCP4801,
55 	ID_MCP4802,
56 	ID_MCP4811,
57 	ID_MCP4812,
58 	ID_MCP4821,
59 	ID_MCP4822,
60 };
61 
62 struct mcp4821_state {
63 	struct spi_device *spi;
64 	u16 dac_value[2];
65 	int gain;
66 	int scale_avail[4];
67 };
68 
69 struct mcp4821_chip_info {
70 	const char *name;
71 	int num_channels;
72 	const struct iio_chan_spec channels[2];
73 };
74 
75 #define MCP4821_CHAN(channel_id, resolution)                          \
76 	{                                                             \
77 		.type = IIO_VOLTAGE, .output = 1, .indexed = 1,       \
78 		.channel = (channel_id),                              \
79 		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),         \
80 		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
81 		.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \
82 		.scan_type = {                                        \
83 			.realbits = (resolution),                     \
84 			.shift = 12 - (resolution),                   \
85 		},                                                    \
86 	}
87 
88 static const struct mcp4821_chip_info mcp4821_chip_info_table[6] = {
89 	[ID_MCP4801] = {
90 			.name = "mcp4801",
91 			.num_channels = 1,
92 			.channels = {
93 				MCP4821_CHAN(0, 8),
94 			},
95 	},
96 	[ID_MCP4802] = {
97 			.name = "mcp4802",
98 			.num_channels = 2,
99 			.channels = {
100 				MCP4821_CHAN(0, 8),
101 				MCP4821_CHAN(1, 8),
102 			},
103 	},
104 	[ID_MCP4811] = {
105 			.name = "mcp4811",
106 			.num_channels = 1,
107 			.channels = {
108 				MCP4821_CHAN(0, 10),
109 			},
110 	},
111 	[ID_MCP4812] = {
112 			.name = "mcp4812",
113 			.num_channels = 2,
114 			.channels = {
115 				MCP4821_CHAN(0, 10),
116 				MCP4821_CHAN(1, 10),
117 			},
118 	},
119 	[ID_MCP4821] = {
120 			.name = "mcp4821",
121 			.num_channels = 1,
122 			.channels = {
123 				MCP4821_CHAN(0, 12),
124 			},
125 	},
126 	[ID_MCP4822] = {
127 			.name = "mcp4822",
128 			.num_channels = 2,
129 			.channels = {
130 				MCP4821_CHAN(0, 12),
131 				MCP4821_CHAN(1, 12),
132 			},
133 	},
134 };
135 
136 static int mcp4821_read_raw(struct iio_dev *indio_dev,
137 			    struct iio_chan_spec const *chan, int *val,
138 			    int *val2, long mask)
139 {
140 	struct mcp4821_state *state = iio_priv(indio_dev);
141 
142 	switch (mask) {
143 	case IIO_CHAN_INFO_RAW:
144 		*val = state->dac_value[chan->channel];
145 		return IIO_VAL_INT;
146 
147 	case IIO_CHAN_INFO_SCALE:
148 		*val = MCP4821_VREF_MV * state->gain;
149 		*val2 = chan->scan_type.realbits;
150 		return IIO_VAL_FRACTIONAL_LOG2;
151 	default:
152 		return -EINVAL;
153 	}
154 }
155 
156 static void mcp4821_calc_scale(int vref_mv, int resolution,
157 				int *val, int *val2)
158 {
159 	s64 tmp;
160 	int micro;
161 
162 	tmp = (s64)vref_mv * MICRO >> resolution;
163 	*val = div_s64_rem(tmp, MICRO, &micro);
164 	*val2 = micro;
165 }
166 
167 static int mcp4821_write_raw(struct iio_dev *indio_dev,
168 			     struct iio_chan_spec const *chan, int val,
169 			     int val2, long mask)
170 {
171 	struct mcp4821_state *state = iio_priv(indio_dev);
172 	u16 write_val;
173 	__be16 write_buffer;
174 	int ret;
175 	int v, v2;
176 
177 	switch (mask) {
178 	case IIO_CHAN_INFO_RAW:
179 
180 		if (val2 != 0)
181 			return -EINVAL;
182 
183 		if (val < 0 || val >= BIT(chan->scan_type.realbits))
184 			return -EINVAL;
185 
186 		write_val = MCP4821_ACTIVE_MODE | val << chan->scan_type.shift;
187 		if (chan->channel)
188 			write_val |= MCP4802_SECOND_CHAN;
189 
190 		/* GA bit = 1 -> 1x gain */
191 		if (state->gain == 1)
192 			write_val |= MCP4821_GAIN_ENABLE;
193 
194 		write_buffer = cpu_to_be16(write_val);
195 		ret = spi_write(state->spi, &write_buffer, sizeof(write_buffer));
196 		if (ret) {
197 			dev_err(&state->spi->dev, "Failed to write to device: %d", ret);
198 			return ret;
199 		}
200 
201 		state->dac_value[chan->channel] = val;
202 		return 0;
203 
204 	case IIO_CHAN_INFO_SCALE:
205 		mcp4821_calc_scale(MCP4821_VREF_MV, chan->scan_type.realbits, &v, &v2);
206 		if (val == v && val2 == v2) {
207 			state->gain = 1;
208 			return 0;
209 		}
210 
211 		mcp4821_calc_scale(MCP4821_VREF_MV * 2,
212 				chan->scan_type.realbits, &v, &v2);
213 		if (val == v && val2 == v2) {
214 			state->gain = 2;
215 			return 0;
216 		}
217 		return -EINVAL;
218 	default:
219 		return -EINVAL;
220 	}
221 }
222 
223 static inline void mcp4821_init_avail_gain(struct mcp4821_state *state,
224 				int resolution)
225 {
226 	state->scale_avail[0] = MCP4821_VREF_MV;
227 	state->scale_avail[1] = resolution;
228 	state->scale_avail[2] = MCP4821_VREF_MV * 2;
229 	state->scale_avail[3] = resolution;
230 }
231 
232 static int mcp4821_read_avail(struct iio_dev *indio_dev,
233 			     struct iio_chan_spec const *chan,
234 			     const int **vals, int *type, int *length,
235 			     long info)
236 {
237 	struct mcp4821_state *state = iio_priv(indio_dev);
238 
239 	switch (info) {
240 	case IIO_CHAN_INFO_SCALE:
241 		*vals = state->scale_avail;
242 		*type = IIO_VAL_FRACTIONAL_LOG2;
243 		*length = ARRAY_SIZE(state->scale_avail);
244 		return IIO_AVAIL_LIST;
245 	default:
246 		return -EINVAL;
247 	}
248 }
249 
250 static const struct iio_info mcp4821_info = {
251 	.read_raw = &mcp4821_read_raw,
252 	.write_raw = &mcp4821_write_raw,
253 	.read_avail = &mcp4821_read_avail,
254 };
255 
256 static int mcp4821_probe(struct spi_device *spi)
257 {
258 	struct iio_dev *indio_dev;
259 	struct mcp4821_state *state;
260 	const struct mcp4821_chip_info *info;
261 
262 	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
263 	if (indio_dev == NULL)
264 		return -ENOMEM;
265 
266 	state = iio_priv(indio_dev);
267 	state->spi = spi;
268 
269 	/* default gain is 2x */
270 	state->gain = 2;
271 	info = spi_get_device_match_data(spi);
272 	indio_dev->name = info->name;
273 	indio_dev->info = &mcp4821_info;
274 	indio_dev->modes = INDIO_DIRECT_MODE;
275 	indio_dev->channels = info->channels;
276 	indio_dev->num_channels = info->num_channels;
277 	mcp4821_init_avail_gain(state, info->channels[0].scan_type.realbits);
278 
279 	return devm_iio_device_register(&spi->dev, indio_dev);
280 }
281 
282 #define MCP4821_COMPATIBLE(of_compatible, id)        \
283 	{                                            \
284 		.compatible = of_compatible,         \
285 		.data = &mcp4821_chip_info_table[id] \
286 	}
287 
288 static const struct of_device_id mcp4821_of_table[] = {
289 	MCP4821_COMPATIBLE("microchip,mcp4801", ID_MCP4801),
290 	MCP4821_COMPATIBLE("microchip,mcp4802", ID_MCP4802),
291 	MCP4821_COMPATIBLE("microchip,mcp4811", ID_MCP4811),
292 	MCP4821_COMPATIBLE("microchip,mcp4812", ID_MCP4812),
293 	MCP4821_COMPATIBLE("microchip,mcp4821", ID_MCP4821),
294 	MCP4821_COMPATIBLE("microchip,mcp4822", ID_MCP4822),
295 	{ }
296 };
297 MODULE_DEVICE_TABLE(of, mcp4821_of_table);
298 
299 static const struct spi_device_id mcp4821_id_table[] = {
300 	{ .name = "mcp4801", .driver_data = (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4801] },
301 	{ .name = "mcp4802", .driver_data = (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4802] },
302 	{ .name = "mcp4811", .driver_data = (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4811] },
303 	{ .name = "mcp4812", .driver_data = (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4812] },
304 	{ .name = "mcp4821", .driver_data = (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4821] },
305 	{ .name = "mcp4822", .driver_data = (kernel_ulong_t)&mcp4821_chip_info_table[ID_MCP4822] },
306 	{ }
307 };
308 MODULE_DEVICE_TABLE(spi, mcp4821_id_table);
309 
310 static struct spi_driver mcp4821_driver = {
311 	.driver = {
312 		.name = "mcp4821",
313 		.of_match_table = mcp4821_of_table,
314 	},
315 	.probe = mcp4821_probe,
316 	.id_table = mcp4821_id_table,
317 };
318 module_spi_driver(mcp4821_driver);
319 
320 MODULE_AUTHOR("Anshul Dalal <anshulusr@gmail.com>");
321 MODULE_DESCRIPTION("Microchip MCP4821 DAC Driver");
322 MODULE_LICENSE("GPL");
323