1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * Industrial I/O driver for Microchip digital potentiometers |
4 | * Copyright (c) 2015 Axentia Technologies AB |
5 | * Author: Peter Rosin <peda@axentia.se> |
6 | * |
7 | * Datasheet: http://www.microchip.com/downloads/en/DeviceDoc/22096b.pdf |
8 | * |
9 | * DEVID #Wipers #Positions Resistor Opts (kOhm) i2c address |
10 | * mcp4531 1 129 5, 10, 50, 100 010111x |
11 | * mcp4532 1 129 5, 10, 50, 100 01011xx |
12 | * mcp4541 1 129 5, 10, 50, 100 010111x |
13 | * mcp4542 1 129 5, 10, 50, 100 01011xx |
14 | * mcp4551 1 257 5, 10, 50, 100 010111x |
15 | * mcp4552 1 257 5, 10, 50, 100 01011xx |
16 | * mcp4561 1 257 5, 10, 50, 100 010111x |
17 | * mcp4562 1 257 5, 10, 50, 100 01011xx |
18 | * mcp4631 2 129 5, 10, 50, 100 0101xxx |
19 | * mcp4632 2 129 5, 10, 50, 100 01011xx |
20 | * mcp4641 2 129 5, 10, 50, 100 0101xxx |
21 | * mcp4642 2 129 5, 10, 50, 100 01011xx |
22 | * mcp4651 2 257 5, 10, 50, 100 0101xxx |
23 | * mcp4652 2 257 5, 10, 50, 100 01011xx |
24 | * mcp4661 2 257 5, 10, 50, 100 0101xxx |
25 | * mcp4662 2 257 5, 10, 50, 100 01011xx |
26 | */ |
27 | |
28 | #include <linux/module.h> |
29 | #include <linux/i2c.h> |
30 | #include <linux/err.h> |
31 | #include <linux/mod_devicetable.h> |
32 | #include <linux/property.h> |
33 | |
34 | #include <linux/iio/iio.h> |
35 | |
36 | struct mcp4531_cfg { |
37 | int wipers; |
38 | int avail[3]; |
39 | int kohms; |
40 | }; |
41 | |
42 | enum mcp4531_type { |
43 | MCP453x_502, |
44 | MCP453x_103, |
45 | MCP453x_503, |
46 | MCP453x_104, |
47 | MCP454x_502, |
48 | MCP454x_103, |
49 | MCP454x_503, |
50 | MCP454x_104, |
51 | MCP455x_502, |
52 | MCP455x_103, |
53 | MCP455x_503, |
54 | MCP455x_104, |
55 | MCP456x_502, |
56 | MCP456x_103, |
57 | MCP456x_503, |
58 | MCP456x_104, |
59 | MCP463x_502, |
60 | MCP463x_103, |
61 | MCP463x_503, |
62 | MCP463x_104, |
63 | MCP464x_502, |
64 | MCP464x_103, |
65 | MCP464x_503, |
66 | MCP464x_104, |
67 | MCP465x_502, |
68 | MCP465x_103, |
69 | MCP465x_503, |
70 | MCP465x_104, |
71 | MCP466x_502, |
72 | MCP466x_103, |
73 | MCP466x_503, |
74 | MCP466x_104, |
75 | }; |
76 | |
77 | static const struct mcp4531_cfg mcp4531_cfg[] = { |
78 | [MCP453x_502] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 5, }, |
79 | [MCP453x_103] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 10, }, |
80 | [MCP453x_503] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 50, }, |
81 | [MCP453x_104] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 100, }, |
82 | [MCP454x_502] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 5, }, |
83 | [MCP454x_103] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 10, }, |
84 | [MCP454x_503] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 50, }, |
85 | [MCP454x_104] = { .wipers = 1, .avail = { 0, 1, 128 }, .kohms = 100, }, |
86 | [MCP455x_502] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 5, }, |
87 | [MCP455x_103] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 10, }, |
88 | [MCP455x_503] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 50, }, |
89 | [MCP455x_104] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 100, }, |
90 | [MCP456x_502] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 5, }, |
91 | [MCP456x_103] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 10, }, |
92 | [MCP456x_503] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 50, }, |
93 | [MCP456x_104] = { .wipers = 1, .avail = { 0, 1, 256 }, .kohms = 100, }, |
94 | [MCP463x_502] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 5, }, |
95 | [MCP463x_103] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 10, }, |
96 | [MCP463x_503] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 50, }, |
97 | [MCP463x_104] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 100, }, |
98 | [MCP464x_502] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 5, }, |
99 | [MCP464x_103] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 10, }, |
100 | [MCP464x_503] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 50, }, |
101 | [MCP464x_104] = { .wipers = 2, .avail = { 0, 1, 128 }, .kohms = 100, }, |
102 | [MCP465x_502] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 5, }, |
103 | [MCP465x_103] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 10, }, |
104 | [MCP465x_503] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 50, }, |
105 | [MCP465x_104] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 100, }, |
106 | [MCP466x_502] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 5, }, |
107 | [MCP466x_103] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 10, }, |
108 | [MCP466x_503] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 50, }, |
109 | [MCP466x_104] = { .wipers = 2, .avail = { 0, 1, 256 }, .kohms = 100, }, |
110 | }; |
111 | |
112 | #define MCP4531_WRITE (0 << 2) |
113 | #define MCP4531_INCR (1 << 2) |
114 | #define MCP4531_DECR (2 << 2) |
115 | #define MCP4531_READ (3 << 2) |
116 | |
117 | #define MCP4531_WIPER_SHIFT (4) |
118 | |
119 | struct mcp4531_data { |
120 | struct i2c_client *client; |
121 | const struct mcp4531_cfg *cfg; |
122 | }; |
123 | |
124 | #define MCP4531_CHANNEL(ch) { \ |
125 | .type = IIO_RESISTANCE, \ |
126 | .indexed = 1, \ |
127 | .output = 1, \ |
128 | .channel = (ch), \ |
129 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
130 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
131 | .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_RAW), \ |
132 | } |
133 | |
134 | static const struct iio_chan_spec mcp4531_channels[] = { |
135 | MCP4531_CHANNEL(0), |
136 | MCP4531_CHANNEL(1), |
137 | }; |
138 | |
139 | static int mcp4531_read_raw(struct iio_dev *indio_dev, |
140 | struct iio_chan_spec const *chan, |
141 | int *val, int *val2, long mask) |
142 | { |
143 | struct mcp4531_data *data = iio_priv(indio_dev); |
144 | int address = chan->channel << MCP4531_WIPER_SHIFT; |
145 | s32 ret; |
146 | |
147 | switch (mask) { |
148 | case IIO_CHAN_INFO_RAW: |
149 | ret = i2c_smbus_read_word_swapped(client: data->client, |
150 | MCP4531_READ | address); |
151 | if (ret < 0) |
152 | return ret; |
153 | *val = ret; |
154 | return IIO_VAL_INT; |
155 | case IIO_CHAN_INFO_SCALE: |
156 | *val = 1000 * data->cfg->kohms; |
157 | *val2 = data->cfg->avail[2]; |
158 | return IIO_VAL_FRACTIONAL; |
159 | } |
160 | |
161 | return -EINVAL; |
162 | } |
163 | |
164 | static int mcp4531_read_avail(struct iio_dev *indio_dev, |
165 | struct iio_chan_spec const *chan, |
166 | const int **vals, int *type, int *length, |
167 | long mask) |
168 | { |
169 | struct mcp4531_data *data = iio_priv(indio_dev); |
170 | |
171 | switch (mask) { |
172 | case IIO_CHAN_INFO_RAW: |
173 | *length = ARRAY_SIZE(data->cfg->avail); |
174 | *vals = data->cfg->avail; |
175 | *type = IIO_VAL_INT; |
176 | return IIO_AVAIL_RANGE; |
177 | } |
178 | |
179 | return -EINVAL; |
180 | } |
181 | |
182 | static int mcp4531_write_raw(struct iio_dev *indio_dev, |
183 | struct iio_chan_spec const *chan, |
184 | int val, int val2, long mask) |
185 | { |
186 | struct mcp4531_data *data = iio_priv(indio_dev); |
187 | int address = chan->channel << MCP4531_WIPER_SHIFT; |
188 | |
189 | switch (mask) { |
190 | case IIO_CHAN_INFO_RAW: |
191 | if (val > data->cfg->avail[2] || val < 0) |
192 | return -EINVAL; |
193 | break; |
194 | default: |
195 | return -EINVAL; |
196 | } |
197 | |
198 | return i2c_smbus_write_byte_data(client: data->client, |
199 | MCP4531_WRITE | address | (val >> 8), |
200 | value: val & 0xff); |
201 | } |
202 | |
203 | static const struct iio_info mcp4531_info = { |
204 | .read_raw = mcp4531_read_raw, |
205 | .read_avail = mcp4531_read_avail, |
206 | .write_raw = mcp4531_write_raw, |
207 | }; |
208 | |
209 | #define MCP4531_ID_TABLE(_name, cfg) { \ |
210 | .name = _name, \ |
211 | .driver_data = (kernel_ulong_t)&mcp4531_cfg[cfg], \ |
212 | } |
213 | |
214 | static const struct i2c_device_id mcp4531_id[] = { |
215 | MCP4531_ID_TABLE("mcp4531-502" , MCP453x_502), |
216 | MCP4531_ID_TABLE("mcp4531-103" , MCP453x_103), |
217 | MCP4531_ID_TABLE("mcp4531-503" , MCP453x_503), |
218 | MCP4531_ID_TABLE("mcp4531-104" , MCP453x_104), |
219 | MCP4531_ID_TABLE("mcp4532-502" , MCP453x_502), |
220 | MCP4531_ID_TABLE("mcp4532-103" , MCP453x_103), |
221 | MCP4531_ID_TABLE("mcp4532-503" , MCP453x_503), |
222 | MCP4531_ID_TABLE("mcp4532-104" , MCP453x_104), |
223 | MCP4531_ID_TABLE("mcp4541-502" , MCP454x_502), |
224 | MCP4531_ID_TABLE("mcp4541-103" , MCP454x_103), |
225 | MCP4531_ID_TABLE("mcp4541-503" , MCP454x_503), |
226 | MCP4531_ID_TABLE("mcp4541-104" , MCP454x_104), |
227 | MCP4531_ID_TABLE("mcp4542-502" , MCP454x_502), |
228 | MCP4531_ID_TABLE("mcp4542-103" , MCP454x_103), |
229 | MCP4531_ID_TABLE("mcp4542-503" , MCP454x_503), |
230 | MCP4531_ID_TABLE("mcp4542-104" , MCP454x_104), |
231 | MCP4531_ID_TABLE("mcp4551-502" , MCP455x_502), |
232 | MCP4531_ID_TABLE("mcp4551-103" , MCP455x_103), |
233 | MCP4531_ID_TABLE("mcp4551-503" , MCP455x_503), |
234 | MCP4531_ID_TABLE("mcp4551-104" , MCP455x_104), |
235 | MCP4531_ID_TABLE("mcp4552-502" , MCP455x_502), |
236 | MCP4531_ID_TABLE("mcp4552-103" , MCP455x_103), |
237 | MCP4531_ID_TABLE("mcp4552-503" , MCP455x_503), |
238 | MCP4531_ID_TABLE("mcp4552-104" , MCP455x_104), |
239 | MCP4531_ID_TABLE("mcp4561-502" , MCP456x_502), |
240 | MCP4531_ID_TABLE("mcp4561-103" , MCP456x_103), |
241 | MCP4531_ID_TABLE("mcp4561-503" , MCP456x_503), |
242 | MCP4531_ID_TABLE("mcp4561-104" , MCP456x_104), |
243 | MCP4531_ID_TABLE("mcp4562-502" , MCP456x_502), |
244 | MCP4531_ID_TABLE("mcp4562-103" , MCP456x_103), |
245 | MCP4531_ID_TABLE("mcp4562-503" , MCP456x_503), |
246 | MCP4531_ID_TABLE("mcp4562-104" , MCP456x_104), |
247 | MCP4531_ID_TABLE("mcp4631-502" , MCP463x_502), |
248 | MCP4531_ID_TABLE("mcp4631-103" , MCP463x_103), |
249 | MCP4531_ID_TABLE("mcp4631-503" , MCP463x_503), |
250 | MCP4531_ID_TABLE("mcp4631-104" , MCP463x_104), |
251 | MCP4531_ID_TABLE("mcp4632-502" , MCP463x_502), |
252 | MCP4531_ID_TABLE("mcp4632-103" , MCP463x_103), |
253 | MCP4531_ID_TABLE("mcp4632-503" , MCP463x_503), |
254 | MCP4531_ID_TABLE("mcp4632-104" , MCP463x_104), |
255 | MCP4531_ID_TABLE("mcp4641-502" , MCP464x_502), |
256 | MCP4531_ID_TABLE("mcp4641-103" , MCP464x_103), |
257 | MCP4531_ID_TABLE("mcp4641-503" , MCP464x_503), |
258 | MCP4531_ID_TABLE("mcp4641-104" , MCP464x_104), |
259 | MCP4531_ID_TABLE("mcp4642-502" , MCP464x_502), |
260 | MCP4531_ID_TABLE("mcp4642-103" , MCP464x_103), |
261 | MCP4531_ID_TABLE("mcp4642-503" , MCP464x_503), |
262 | MCP4531_ID_TABLE("mcp4642-104" , MCP464x_104), |
263 | MCP4531_ID_TABLE("mcp4651-502" , MCP465x_502), |
264 | MCP4531_ID_TABLE("mcp4651-103" , MCP465x_103), |
265 | MCP4531_ID_TABLE("mcp4651-503" , MCP465x_503), |
266 | MCP4531_ID_TABLE("mcp4651-104" , MCP465x_104), |
267 | MCP4531_ID_TABLE("mcp4652-502" , MCP465x_502), |
268 | MCP4531_ID_TABLE("mcp4652-103" , MCP465x_103), |
269 | MCP4531_ID_TABLE("mcp4652-503" , MCP465x_503), |
270 | MCP4531_ID_TABLE("mcp4652-104" , MCP465x_104), |
271 | MCP4531_ID_TABLE("mcp4661-502" , MCP466x_502), |
272 | MCP4531_ID_TABLE("mcp4661-103" , MCP466x_103), |
273 | MCP4531_ID_TABLE("mcp4661-503" , MCP466x_503), |
274 | MCP4531_ID_TABLE("mcp4661-104" , MCP466x_104), |
275 | MCP4531_ID_TABLE("mcp4662-502" , MCP466x_502), |
276 | MCP4531_ID_TABLE("mcp4662-103" , MCP466x_103), |
277 | MCP4531_ID_TABLE("mcp4662-503" , MCP466x_503), |
278 | MCP4531_ID_TABLE("mcp4662-104" , MCP466x_104), |
279 | { /* sentinel */ } |
280 | }; |
281 | MODULE_DEVICE_TABLE(i2c, mcp4531_id); |
282 | |
283 | #define MCP4531_COMPATIBLE(of_compatible, cfg) { \ |
284 | .compatible = of_compatible, \ |
285 | .data = &mcp4531_cfg[cfg], \ |
286 | } |
287 | |
288 | static const struct of_device_id mcp4531_of_match[] = { |
289 | MCP4531_COMPATIBLE("microchip,mcp4531-502" , MCP453x_502), |
290 | MCP4531_COMPATIBLE("microchip,mcp4531-103" , MCP453x_103), |
291 | MCP4531_COMPATIBLE("microchip,mcp4531-503" , MCP453x_503), |
292 | MCP4531_COMPATIBLE("microchip,mcp4531-104" , MCP453x_104), |
293 | MCP4531_COMPATIBLE("microchip,mcp4532-502" , MCP453x_502), |
294 | MCP4531_COMPATIBLE("microchip,mcp4532-103" , MCP453x_103), |
295 | MCP4531_COMPATIBLE("microchip,mcp4532-503" , MCP453x_503), |
296 | MCP4531_COMPATIBLE("microchip,mcp4532-104" , MCP453x_104), |
297 | MCP4531_COMPATIBLE("microchip,mcp4541-502" , MCP454x_502), |
298 | MCP4531_COMPATIBLE("microchip,mcp4541-103" , MCP454x_103), |
299 | MCP4531_COMPATIBLE("microchip,mcp4541-503" , MCP454x_503), |
300 | MCP4531_COMPATIBLE("microchip,mcp4541-104" , MCP454x_104), |
301 | MCP4531_COMPATIBLE("microchip,mcp4542-502" , MCP454x_502), |
302 | MCP4531_COMPATIBLE("microchip,mcp4542-103" , MCP454x_103), |
303 | MCP4531_COMPATIBLE("microchip,mcp4542-503" , MCP454x_503), |
304 | MCP4531_COMPATIBLE("microchip,mcp4542-104" , MCP454x_104), |
305 | MCP4531_COMPATIBLE("microchip,mcp4551-502" , MCP455x_502), |
306 | MCP4531_COMPATIBLE("microchip,mcp4551-103" , MCP455x_103), |
307 | MCP4531_COMPATIBLE("microchip,mcp4551-503" , MCP455x_503), |
308 | MCP4531_COMPATIBLE("microchip,mcp4551-104" , MCP455x_104), |
309 | MCP4531_COMPATIBLE("microchip,mcp4552-502" , MCP455x_502), |
310 | MCP4531_COMPATIBLE("microchip,mcp4552-103" , MCP455x_103), |
311 | MCP4531_COMPATIBLE("microchip,mcp4552-503" , MCP455x_503), |
312 | MCP4531_COMPATIBLE("microchip,mcp4552-104" , MCP455x_104), |
313 | MCP4531_COMPATIBLE("microchip,mcp4561-502" , MCP456x_502), |
314 | MCP4531_COMPATIBLE("microchip,mcp4561-103" , MCP456x_103), |
315 | MCP4531_COMPATIBLE("microchip,mcp4561-503" , MCP456x_503), |
316 | MCP4531_COMPATIBLE("microchip,mcp4561-104" , MCP456x_104), |
317 | MCP4531_COMPATIBLE("microchip,mcp4562-502" , MCP456x_502), |
318 | MCP4531_COMPATIBLE("microchip,mcp4562-103" , MCP456x_103), |
319 | MCP4531_COMPATIBLE("microchip,mcp4562-503" , MCP456x_503), |
320 | MCP4531_COMPATIBLE("microchip,mcp4562-104" , MCP456x_104), |
321 | MCP4531_COMPATIBLE("microchip,mcp4631-502" , MCP463x_502), |
322 | MCP4531_COMPATIBLE("microchip,mcp4631-103" , MCP463x_103), |
323 | MCP4531_COMPATIBLE("microchip,mcp4631-503" , MCP463x_503), |
324 | MCP4531_COMPATIBLE("microchip,mcp4631-104" , MCP463x_104), |
325 | MCP4531_COMPATIBLE("microchip,mcp4632-502" , MCP463x_502), |
326 | MCP4531_COMPATIBLE("microchip,mcp4632-103" , MCP463x_103), |
327 | MCP4531_COMPATIBLE("microchip,mcp4632-503" , MCP463x_503), |
328 | MCP4531_COMPATIBLE("microchip,mcp4632-104" , MCP463x_104), |
329 | MCP4531_COMPATIBLE("microchip,mcp4641-502" , MCP464x_502), |
330 | MCP4531_COMPATIBLE("microchip,mcp4641-103" , MCP464x_103), |
331 | MCP4531_COMPATIBLE("microchip,mcp4641-503" , MCP464x_503), |
332 | MCP4531_COMPATIBLE("microchip,mcp4641-104" , MCP464x_104), |
333 | MCP4531_COMPATIBLE("microchip,mcp4642-502" , MCP464x_502), |
334 | MCP4531_COMPATIBLE("microchip,mcp4642-103" , MCP464x_103), |
335 | MCP4531_COMPATIBLE("microchip,mcp4642-503" , MCP464x_503), |
336 | MCP4531_COMPATIBLE("microchip,mcp4642-104" , MCP464x_104), |
337 | MCP4531_COMPATIBLE("microchip,mcp4651-502" , MCP465x_502), |
338 | MCP4531_COMPATIBLE("microchip,mcp4651-103" , MCP465x_103), |
339 | MCP4531_COMPATIBLE("microchip,mcp4651-503" , MCP465x_503), |
340 | MCP4531_COMPATIBLE("microchip,mcp4651-104" , MCP465x_104), |
341 | MCP4531_COMPATIBLE("microchip,mcp4652-502" , MCP465x_502), |
342 | MCP4531_COMPATIBLE("microchip,mcp4652-103" , MCP465x_103), |
343 | MCP4531_COMPATIBLE("microchip,mcp4652-503" , MCP465x_503), |
344 | MCP4531_COMPATIBLE("microchip,mcp4652-104" , MCP465x_104), |
345 | MCP4531_COMPATIBLE("microchip,mcp4661-502" , MCP466x_502), |
346 | MCP4531_COMPATIBLE("microchip,mcp4661-103" , MCP466x_103), |
347 | MCP4531_COMPATIBLE("microchip,mcp4661-503" , MCP466x_503), |
348 | MCP4531_COMPATIBLE("microchip,mcp4661-104" , MCP466x_104), |
349 | MCP4531_COMPATIBLE("microchip,mcp4662-502" , MCP466x_502), |
350 | MCP4531_COMPATIBLE("microchip,mcp4662-103" , MCP466x_103), |
351 | MCP4531_COMPATIBLE("microchip,mcp4662-503" , MCP466x_503), |
352 | MCP4531_COMPATIBLE("microchip,mcp4662-104" , MCP466x_104), |
353 | { /* sentinel */ } |
354 | }; |
355 | MODULE_DEVICE_TABLE(of, mcp4531_of_match); |
356 | |
357 | static int mcp4531_probe(struct i2c_client *client) |
358 | { |
359 | struct device *dev = &client->dev; |
360 | struct mcp4531_data *data; |
361 | struct iio_dev *indio_dev; |
362 | |
363 | if (!i2c_check_functionality(adap: client->adapter, |
364 | I2C_FUNC_SMBUS_WORD_DATA)) { |
365 | dev_err(dev, "SMBUS Word Data not supported\n" ); |
366 | return -EOPNOTSUPP; |
367 | } |
368 | |
369 | indio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*data)); |
370 | if (!indio_dev) |
371 | return -ENOMEM; |
372 | data = iio_priv(indio_dev); |
373 | i2c_set_clientdata(client, data: indio_dev); |
374 | data->client = client; |
375 | |
376 | data->cfg = i2c_get_match_data(client); |
377 | |
378 | indio_dev->info = &mcp4531_info; |
379 | indio_dev->channels = mcp4531_channels; |
380 | indio_dev->num_channels = data->cfg->wipers; |
381 | indio_dev->name = client->name; |
382 | |
383 | return devm_iio_device_register(dev, indio_dev); |
384 | } |
385 | |
386 | static struct i2c_driver mcp4531_driver = { |
387 | .driver = { |
388 | .name = "mcp4531" , |
389 | .of_match_table = mcp4531_of_match, |
390 | }, |
391 | .probe = mcp4531_probe, |
392 | .id_table = mcp4531_id, |
393 | }; |
394 | |
395 | module_i2c_driver(mcp4531_driver); |
396 | |
397 | MODULE_AUTHOR("Peter Rosin <peda@axentia.se>" ); |
398 | MODULE_DESCRIPTION("MCP4531 digital potentiometer" ); |
399 | MODULE_LICENSE("GPL v2" ); |
400 | |