]>
Commit | Line | Data |
---|---|---|
c499d029 LPC |
1 | /* |
2 | * AD5755, AD5755-1, AD5757, AD5735, AD5737 Digital to analog converters driver | |
3 | * | |
4 | * Copyright 2012 Analog Devices Inc. | |
5 | * | |
6 | * Licensed under the GPL-2. | |
7 | */ | |
8 | ||
9 | #include <linux/device.h> | |
10 | #include <linux/err.h> | |
11 | #include <linux/module.h> | |
12 | #include <linux/kernel.h> | |
13 | #include <linux/spi/spi.h> | |
14 | #include <linux/slab.h> | |
15 | #include <linux/sysfs.h> | |
16 | #include <linux/delay.h> | |
17 | #include <linux/iio/iio.h> | |
18 | #include <linux/iio/sysfs.h> | |
19 | #include <linux/platform_data/ad5755.h> | |
20 | ||
21 | #define AD5755_NUM_CHANNELS 4 | |
22 | ||
23 | #define AD5755_ADDR(x) ((x) << 16) | |
24 | ||
25 | #define AD5755_WRITE_REG_DATA(chan) (chan) | |
26 | #define AD5755_WRITE_REG_GAIN(chan) (0x08 | (chan)) | |
27 | #define AD5755_WRITE_REG_OFFSET(chan) (0x10 | (chan)) | |
28 | #define AD5755_WRITE_REG_CTRL(chan) (0x1c | (chan)) | |
29 | ||
30 | #define AD5755_READ_REG_DATA(chan) (chan) | |
31 | #define AD5755_READ_REG_CTRL(chan) (0x4 | (chan)) | |
32 | #define AD5755_READ_REG_GAIN(chan) (0x8 | (chan)) | |
33 | #define AD5755_READ_REG_OFFSET(chan) (0xc | (chan)) | |
34 | #define AD5755_READ_REG_CLEAR(chan) (0x10 | (chan)) | |
35 | #define AD5755_READ_REG_SLEW(chan) (0x14 | (chan)) | |
36 | #define AD5755_READ_REG_STATUS 0x18 | |
37 | #define AD5755_READ_REG_MAIN 0x19 | |
38 | #define AD5755_READ_REG_DC_DC 0x1a | |
39 | ||
40 | #define AD5755_CTRL_REG_SLEW 0x0 | |
41 | #define AD5755_CTRL_REG_MAIN 0x1 | |
42 | #define AD5755_CTRL_REG_DAC 0x2 | |
43 | #define AD5755_CTRL_REG_DC_DC 0x3 | |
44 | #define AD5755_CTRL_REG_SW 0x4 | |
45 | ||
46 | #define AD5755_READ_FLAG 0x800000 | |
47 | ||
48 | #define AD5755_NOOP 0x1CE000 | |
49 | ||
50 | #define AD5755_DAC_INT_EN BIT(8) | |
51 | #define AD5755_DAC_CLR_EN BIT(7) | |
52 | #define AD5755_DAC_OUT_EN BIT(6) | |
53 | #define AD5755_DAC_INT_CURRENT_SENSE_RESISTOR BIT(5) | |
54 | #define AD5755_DAC_DC_DC_EN BIT(4) | |
55 | #define AD5755_DAC_VOLTAGE_OVERRANGE_EN BIT(3) | |
56 | ||
57 | #define AD5755_DC_DC_MAXV 0 | |
58 | #define AD5755_DC_DC_FREQ_SHIFT 2 | |
59 | #define AD5755_DC_DC_PHASE_SHIFT 4 | |
60 | #define AD5755_EXT_DC_DC_COMP_RES BIT(6) | |
61 | ||
62 | #define AD5755_SLEW_STEP_SIZE_SHIFT 0 | |
63 | #define AD5755_SLEW_RATE_SHIFT 3 | |
64 | #define AD5755_SLEW_ENABLE BIT(12) | |
65 | ||
66 | /** | |
67 | * struct ad5755_chip_info - chip specific information | |
68 | * @channel_template: channel specification | |
69 | * @calib_shift: shift for the calibration data registers | |
70 | * @has_voltage_out: whether the chip has voltage outputs | |
71 | */ | |
72 | struct ad5755_chip_info { | |
73 | const struct iio_chan_spec channel_template; | |
74 | unsigned int calib_shift; | |
75 | bool has_voltage_out; | |
76 | }; | |
77 | ||
78 | /** | |
79 | * struct ad5755_state - driver instance specific data | |
80 | * @spi: spi device the driver is attached to | |
81 | * @chip_info: chip model specific constants, available modes etc | |
82 | * @pwr_down: bitmask which contains hether a channel is powered down or not | |
83 | * @ctrl: software shadow of the channel ctrl registers | |
84 | * @channels: iio channel spec for the device | |
85 | * @data: spi transfer buffers | |
86 | */ | |
87 | struct ad5755_state { | |
88 | struct spi_device *spi; | |
89 | const struct ad5755_chip_info *chip_info; | |
90 | unsigned int pwr_down; | |
91 | unsigned int ctrl[AD5755_NUM_CHANNELS]; | |
92 | struct iio_chan_spec channels[AD5755_NUM_CHANNELS]; | |
93 | ||
94 | /* | |
95 | * DMA (thus cache coherency maintenance) requires the | |
96 | * transfer buffers to live in their own cache lines. | |
97 | */ | |
98 | ||
99 | union { | |
100 | u32 d32; | |
101 | u8 d8[4]; | |
102 | } data[2] ____cacheline_aligned; | |
103 | }; | |
104 | ||
105 | enum ad5755_type { | |
106 | ID_AD5755, | |
107 | ID_AD5757, | |
108 | ID_AD5735, | |
109 | ID_AD5737, | |
110 | }; | |
111 | ||
112 | static int ad5755_write_unlocked(struct iio_dev *indio_dev, | |
113 | unsigned int reg, unsigned int val) | |
114 | { | |
115 | struct ad5755_state *st = iio_priv(indio_dev); | |
116 | ||
117 | st->data[0].d32 = cpu_to_be32((reg << 16) | val); | |
118 | ||
119 | return spi_write(st->spi, &st->data[0].d8[1], 3); | |
120 | } | |
121 | ||
122 | static int ad5755_write_ctrl_unlocked(struct iio_dev *indio_dev, | |
123 | unsigned int channel, unsigned int reg, unsigned int val) | |
124 | { | |
125 | return ad5755_write_unlocked(indio_dev, | |
126 | AD5755_WRITE_REG_CTRL(channel), (reg << 13) | val); | |
127 | } | |
128 | ||
129 | static int ad5755_write(struct iio_dev *indio_dev, unsigned int reg, | |
130 | unsigned int val) | |
131 | { | |
132 | int ret; | |
133 | ||
134 | mutex_lock(&indio_dev->mlock); | |
135 | ret = ad5755_write_unlocked(indio_dev, reg, val); | |
136 | mutex_unlock(&indio_dev->mlock); | |
137 | ||
138 | return ret; | |
139 | } | |
140 | ||
141 | static int ad5755_write_ctrl(struct iio_dev *indio_dev, unsigned int channel, | |
142 | unsigned int reg, unsigned int val) | |
143 | { | |
144 | int ret; | |
145 | ||
146 | mutex_lock(&indio_dev->mlock); | |
147 | ret = ad5755_write_ctrl_unlocked(indio_dev, channel, reg, val); | |
148 | mutex_unlock(&indio_dev->mlock); | |
149 | ||
150 | return ret; | |
151 | } | |
152 | ||
153 | static int ad5755_read(struct iio_dev *indio_dev, unsigned int addr) | |
154 | { | |
155 | struct ad5755_state *st = iio_priv(indio_dev); | |
156 | struct spi_message m; | |
157 | int ret; | |
158 | struct spi_transfer t[] = { | |
159 | { | |
160 | .tx_buf = &st->data[0].d8[1], | |
161 | .len = 3, | |
162 | .cs_change = 1, | |
163 | }, { | |
164 | .tx_buf = &st->data[1].d8[1], | |
165 | .rx_buf = &st->data[1].d8[1], | |
166 | .len = 3, | |
167 | }, | |
168 | }; | |
169 | ||
170 | spi_message_init(&m); | |
171 | spi_message_add_tail(&t[0], &m); | |
172 | spi_message_add_tail(&t[1], &m); | |
173 | ||
174 | mutex_lock(&indio_dev->mlock); | |
175 | ||
176 | st->data[0].d32 = cpu_to_be32(AD5755_READ_FLAG | (addr << 16)); | |
177 | st->data[1].d32 = cpu_to_be32(AD5755_NOOP); | |
178 | ||
179 | ret = spi_sync(st->spi, &m); | |
180 | if (ret >= 0) | |
181 | ret = be32_to_cpu(st->data[1].d32) & 0xffff; | |
182 | ||
183 | mutex_unlock(&indio_dev->mlock); | |
184 | ||
185 | return ret; | |
186 | } | |
187 | ||
188 | static int ad5755_update_dac_ctrl(struct iio_dev *indio_dev, | |
189 | unsigned int channel, unsigned int set, unsigned int clr) | |
190 | { | |
191 | struct ad5755_state *st = iio_priv(indio_dev); | |
192 | int ret; | |
193 | ||
194 | st->ctrl[channel] |= set; | |
195 | st->ctrl[channel] &= ~clr; | |
196 | ||
197 | ret = ad5755_write_ctrl_unlocked(indio_dev, channel, | |
198 | AD5755_CTRL_REG_DAC, st->ctrl[channel]); | |
199 | ||
200 | return ret; | |
201 | } | |
202 | ||
203 | static int ad5755_set_channel_pwr_down(struct iio_dev *indio_dev, | |
204 | unsigned int channel, bool pwr_down) | |
205 | { | |
206 | struct ad5755_state *st = iio_priv(indio_dev); | |
207 | unsigned int mask = BIT(channel); | |
208 | ||
209 | mutex_lock(&indio_dev->mlock); | |
210 | ||
211 | if ((bool)(st->pwr_down & mask) == pwr_down) | |
212 | goto out_unlock; | |
213 | ||
214 | if (!pwr_down) { | |
215 | st->pwr_down &= ~mask; | |
216 | ad5755_update_dac_ctrl(indio_dev, channel, | |
217 | AD5755_DAC_INT_EN | AD5755_DAC_DC_DC_EN, 0); | |
218 | udelay(200); | |
219 | ad5755_update_dac_ctrl(indio_dev, channel, | |
220 | AD5755_DAC_OUT_EN, 0); | |
221 | } else { | |
222 | st->pwr_down |= mask; | |
223 | ad5755_update_dac_ctrl(indio_dev, channel, | |
224 | 0, AD5755_DAC_INT_EN | AD5755_DAC_OUT_EN | | |
225 | AD5755_DAC_DC_DC_EN); | |
226 | } | |
227 | ||
228 | out_unlock: | |
229 | mutex_unlock(&indio_dev->mlock); | |
230 | ||
231 | return 0; | |
232 | } | |
233 | ||
234 | static const int ad5755_min_max_table[][2] = { | |
235 | [AD5755_MODE_VOLTAGE_0V_5V] = { 0, 5000 }, | |
236 | [AD5755_MODE_VOLTAGE_0V_10V] = { 0, 10000 }, | |
237 | [AD5755_MODE_VOLTAGE_PLUSMINUS_5V] = { -5000, 5000 }, | |
238 | [AD5755_MODE_VOLTAGE_PLUSMINUS_10V] = { -10000, 10000 }, | |
239 | [AD5755_MODE_CURRENT_4mA_20mA] = { 4, 20 }, | |
240 | [AD5755_MODE_CURRENT_0mA_20mA] = { 0, 20 }, | |
241 | [AD5755_MODE_CURRENT_0mA_24mA] = { 0, 24 }, | |
242 | }; | |
243 | ||
244 | static void ad5755_get_min_max(struct ad5755_state *st, | |
245 | struct iio_chan_spec const *chan, int *min, int *max) | |
246 | { | |
247 | enum ad5755_mode mode = st->ctrl[chan->channel] & 7; | |
248 | *min = ad5755_min_max_table[mode][0]; | |
249 | *max = ad5755_min_max_table[mode][1]; | |
250 | } | |
251 | ||
252 | static inline int ad5755_get_offset(struct ad5755_state *st, | |
253 | struct iio_chan_spec const *chan) | |
254 | { | |
255 | int min, max; | |
256 | ||
257 | ad5755_get_min_max(st, chan, &min, &max); | |
258 | return (min * (1 << chan->scan_type.realbits)) / (max - min); | |
259 | } | |
260 | ||
261 | static inline int ad5755_get_scale(struct ad5755_state *st, | |
262 | struct iio_chan_spec const *chan) | |
263 | { | |
264 | int min, max; | |
265 | ||
266 | ad5755_get_min_max(st, chan, &min, &max); | |
267 | return ((max - min) * 1000000000ULL) >> chan->scan_type.realbits; | |
268 | } | |
269 | ||
270 | static int ad5755_chan_reg_info(struct ad5755_state *st, | |
271 | struct iio_chan_spec const *chan, long info, bool write, | |
272 | unsigned int *reg, unsigned int *shift, unsigned int *offset) | |
273 | { | |
274 | switch (info) { | |
275 | case IIO_CHAN_INFO_RAW: | |
276 | if (write) | |
277 | *reg = AD5755_WRITE_REG_DATA(chan->address); | |
278 | else | |
279 | *reg = AD5755_READ_REG_DATA(chan->address); | |
280 | *shift = chan->scan_type.shift; | |
281 | *offset = 0; | |
282 | break; | |
283 | case IIO_CHAN_INFO_CALIBBIAS: | |
284 | if (write) | |
285 | *reg = AD5755_WRITE_REG_OFFSET(chan->address); | |
286 | else | |
287 | *reg = AD5755_READ_REG_OFFSET(chan->address); | |
288 | *shift = st->chip_info->calib_shift; | |
289 | *offset = 32768; | |
290 | break; | |
291 | case IIO_CHAN_INFO_CALIBSCALE: | |
292 | if (write) | |
293 | *reg = AD5755_WRITE_REG_GAIN(chan->address); | |
294 | else | |
295 | *reg = AD5755_READ_REG_GAIN(chan->address); | |
296 | *shift = st->chip_info->calib_shift; | |
297 | *offset = 0; | |
298 | break; | |
299 | default: | |
300 | return -EINVAL; | |
301 | } | |
302 | ||
303 | return 0; | |
304 | } | |
305 | ||
306 | static int ad5755_read_raw(struct iio_dev *indio_dev, | |
307 | const struct iio_chan_spec *chan, int *val, int *val2, long info) | |
308 | { | |
309 | struct ad5755_state *st = iio_priv(indio_dev); | |
310 | unsigned int reg, shift, offset; | |
311 | int ret; | |
312 | ||
313 | switch (info) { | |
314 | case IIO_CHAN_INFO_SCALE: | |
315 | *val = 0; | |
316 | *val2 = ad5755_get_scale(st, chan); | |
317 | return IIO_VAL_INT_PLUS_NANO; | |
318 | case IIO_CHAN_INFO_OFFSET: | |
319 | *val = ad5755_get_offset(st, chan); | |
320 | return IIO_VAL_INT; | |
321 | default: | |
322 | ret = ad5755_chan_reg_info(st, chan, info, false, | |
323 | ®, &shift, &offset); | |
324 | if (ret) | |
325 | return ret; | |
326 | ||
327 | ret = ad5755_read(indio_dev, reg); | |
328 | if (ret < 0) | |
329 | return ret; | |
330 | ||
331 | *val = (ret - offset) >> shift; | |
332 | ||
333 | return IIO_VAL_INT; | |
334 | } | |
335 | ||
336 | return -EINVAL; | |
337 | } | |
338 | ||
339 | static int ad5755_write_raw(struct iio_dev *indio_dev, | |
340 | const struct iio_chan_spec *chan, int val, int val2, long info) | |
341 | { | |
342 | struct ad5755_state *st = iio_priv(indio_dev); | |
343 | unsigned int shift, reg, offset; | |
344 | int ret; | |
345 | ||
346 | ret = ad5755_chan_reg_info(st, chan, info, true, | |
347 | ®, &shift, &offset); | |
348 | if (ret) | |
349 | return ret; | |
350 | ||
351 | val <<= shift; | |
352 | val += offset; | |
353 | ||
354 | if (val < 0 || val > 0xffff) | |
355 | return -EINVAL; | |
356 | ||
357 | return ad5755_write(indio_dev, reg, val); | |
358 | } | |
359 | ||
360 | static ssize_t ad5755_read_powerdown(struct iio_dev *indio_dev, uintptr_t priv, | |
361 | const struct iio_chan_spec *chan, char *buf) | |
362 | { | |
363 | struct ad5755_state *st = iio_priv(indio_dev); | |
364 | ||
365 | return sprintf(buf, "%d\n", | |
366 | (bool)(st->pwr_down & (1 << chan->channel))); | |
367 | } | |
368 | ||
369 | static ssize_t ad5755_write_powerdown(struct iio_dev *indio_dev, uintptr_t priv, | |
370 | struct iio_chan_spec const *chan, const char *buf, size_t len) | |
371 | { | |
372 | bool pwr_down; | |
373 | int ret; | |
374 | ||
375 | ret = strtobool(buf, &pwr_down); | |
376 | if (ret) | |
377 | return ret; | |
378 | ||
379 | ret = ad5755_set_channel_pwr_down(indio_dev, chan->channel, pwr_down); | |
380 | return ret ? ret : len; | |
381 | } | |
382 | ||
383 | static const struct iio_info ad5755_info = { | |
384 | .read_raw = ad5755_read_raw, | |
385 | .write_raw = ad5755_write_raw, | |
386 | .driver_module = THIS_MODULE, | |
387 | }; | |
388 | ||
389 | static const struct iio_chan_spec_ext_info ad5755_ext_info[] = { | |
390 | { | |
391 | .name = "powerdown", | |
392 | .read = ad5755_read_powerdown, | |
393 | .write = ad5755_write_powerdown, | |
394 | }, | |
395 | { }, | |
396 | }; | |
397 | ||
398 | #define AD5755_CHANNEL(_bits) { \ | |
399 | .indexed = 1, \ | |
400 | .output = 1, \ | |
401 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | |
402 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | \ | |
403 | IIO_CHAN_INFO_OFFSET_SEPARATE_BIT | \ | |
404 | IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT | \ | |
405 | IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT, \ | |
406 | .scan_type = IIO_ST('u', (_bits), 16, 16 - (_bits)), \ | |
407 | .ext_info = ad5755_ext_info, \ | |
408 | } | |
409 | ||
410 | static const struct ad5755_chip_info ad5755_chip_info_tbl[] = { | |
411 | [ID_AD5735] = { | |
412 | .channel_template = AD5755_CHANNEL(14), | |
413 | .has_voltage_out = true, | |
414 | .calib_shift = 4, | |
415 | }, | |
416 | [ID_AD5737] = { | |
417 | .channel_template = AD5755_CHANNEL(14), | |
418 | .has_voltage_out = false, | |
419 | .calib_shift = 4, | |
420 | }, | |
421 | [ID_AD5755] = { | |
422 | .channel_template = AD5755_CHANNEL(16), | |
423 | .has_voltage_out = true, | |
424 | .calib_shift = 0, | |
425 | }, | |
426 | [ID_AD5757] = { | |
427 | .channel_template = AD5755_CHANNEL(16), | |
428 | .has_voltage_out = false, | |
429 | .calib_shift = 0, | |
430 | }, | |
431 | }; | |
432 | ||
433 | static bool ad5755_is_valid_mode(struct ad5755_state *st, enum ad5755_mode mode) | |
434 | { | |
435 | switch (mode) { | |
436 | case AD5755_MODE_VOLTAGE_0V_5V: | |
437 | case AD5755_MODE_VOLTAGE_0V_10V: | |
438 | case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: | |
439 | case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: | |
440 | return st->chip_info->has_voltage_out; | |
441 | case AD5755_MODE_CURRENT_4mA_20mA: | |
442 | case AD5755_MODE_CURRENT_0mA_20mA: | |
443 | case AD5755_MODE_CURRENT_0mA_24mA: | |
444 | return true; | |
445 | default: | |
446 | return false; | |
447 | } | |
448 | } | |
449 | ||
fc52692c GKH |
450 | static int ad5755_setup_pdata(struct iio_dev *indio_dev, |
451 | const struct ad5755_platform_data *pdata) | |
c499d029 LPC |
452 | { |
453 | struct ad5755_state *st = iio_priv(indio_dev); | |
c499d029 LPC |
454 | unsigned int val; |
455 | unsigned int i; | |
369d0e20 | 456 | int ret; |
c499d029 LPC |
457 | |
458 | if (pdata->dc_dc_phase > AD5755_DC_DC_PHASE_90_DEGREE || | |
459 | pdata->dc_dc_freq > AD5755_DC_DC_FREQ_650kHZ || | |
460 | pdata->dc_dc_maxv > AD5755_DC_DC_MAXV_29V5) | |
461 | return -EINVAL; | |
462 | ||
463 | val = pdata->dc_dc_maxv << AD5755_DC_DC_MAXV; | |
464 | val |= pdata->dc_dc_freq << AD5755_DC_DC_FREQ_SHIFT; | |
465 | val |= pdata->dc_dc_phase << AD5755_DC_DC_PHASE_SHIFT; | |
466 | if (pdata->ext_dc_dc_compenstation_resistor) | |
467 | val |= AD5755_EXT_DC_DC_COMP_RES; | |
468 | ||
469 | ret = ad5755_write_ctrl(indio_dev, 0, AD5755_CTRL_REG_DC_DC, val); | |
470 | if (ret < 0) | |
471 | return ret; | |
472 | ||
473 | for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) { | |
474 | val = pdata->dac[i].slew.step_size << | |
475 | AD5755_SLEW_STEP_SIZE_SHIFT; | |
476 | val |= pdata->dac[i].slew.rate << | |
477 | AD5755_SLEW_RATE_SHIFT; | |
478 | if (pdata->dac[i].slew.enable) | |
479 | val |= AD5755_SLEW_ENABLE; | |
480 | ||
481 | ret = ad5755_write_ctrl(indio_dev, i, | |
482 | AD5755_CTRL_REG_SLEW, val); | |
483 | if (ret < 0) | |
484 | return ret; | |
485 | } | |
486 | ||
487 | for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) { | |
488 | if (!ad5755_is_valid_mode(st, pdata->dac[i].mode)) | |
489 | return -EINVAL; | |
490 | ||
491 | val = 0; | |
492 | if (!pdata->dac[i].ext_current_sense_resistor) | |
493 | val |= AD5755_DAC_INT_CURRENT_SENSE_RESISTOR; | |
494 | if (pdata->dac[i].enable_voltage_overrange) | |
495 | val |= AD5755_DAC_VOLTAGE_OVERRANGE_EN; | |
496 | val |= pdata->dac[i].mode; | |
497 | ||
498 | ret = ad5755_update_dac_ctrl(indio_dev, i, val, 0); | |
499 | if (ret < 0) | |
500 | return ret; | |
501 | } | |
502 | ||
503 | return 0; | |
504 | } | |
505 | ||
fc52692c | 506 | static bool ad5755_is_voltage_mode(enum ad5755_mode mode) |
c499d029 LPC |
507 | { |
508 | switch (mode) { | |
509 | case AD5755_MODE_VOLTAGE_0V_5V: | |
510 | case AD5755_MODE_VOLTAGE_0V_10V: | |
511 | case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: | |
512 | case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: | |
513 | return true; | |
514 | default: | |
515 | return false; | |
516 | } | |
517 | } | |
518 | ||
fc52692c GKH |
519 | static int ad5755_init_channels(struct iio_dev *indio_dev, |
520 | const struct ad5755_platform_data *pdata) | |
c499d029 LPC |
521 | { |
522 | struct ad5755_state *st = iio_priv(indio_dev); | |
523 | struct iio_chan_spec *channels = st->channels; | |
524 | unsigned int i; | |
525 | ||
526 | for (i = 0; i < AD5755_NUM_CHANNELS; ++i) { | |
527 | channels[i] = st->chip_info->channel_template; | |
528 | channels[i].channel = i; | |
529 | channels[i].address = i; | |
530 | if (pdata && ad5755_is_voltage_mode(pdata->dac[i].mode)) | |
531 | channels[i].type = IIO_VOLTAGE; | |
532 | else | |
533 | channels[i].type = IIO_CURRENT; | |
534 | } | |
535 | ||
536 | indio_dev->channels = channels; | |
537 | ||
538 | return 0; | |
539 | } | |
540 | ||
541 | #define AD5755_DEFAULT_DAC_PDATA { \ | |
542 | .mode = AD5755_MODE_CURRENT_4mA_20mA, \ | |
543 | .ext_current_sense_resistor = true, \ | |
544 | .enable_voltage_overrange = false, \ | |
545 | .slew = { \ | |
546 | .enable = false, \ | |
547 | .rate = AD5755_SLEW_RATE_64k, \ | |
548 | .step_size = AD5755_SLEW_STEP_SIZE_1, \ | |
549 | }, \ | |
550 | } | |
551 | ||
552 | static const struct ad5755_platform_data ad5755_default_pdata = { | |
553 | .ext_dc_dc_compenstation_resistor = false, | |
554 | .dc_dc_phase = AD5755_DC_DC_PHASE_ALL_SAME_EDGE, | |
555 | .dc_dc_freq = AD5755_DC_DC_FREQ_410kHZ, | |
556 | .dc_dc_maxv = AD5755_DC_DC_MAXV_23V, | |
557 | .dac = { | |
558 | [0] = AD5755_DEFAULT_DAC_PDATA, | |
559 | [1] = AD5755_DEFAULT_DAC_PDATA, | |
560 | [2] = AD5755_DEFAULT_DAC_PDATA, | |
561 | [3] = AD5755_DEFAULT_DAC_PDATA, | |
562 | }, | |
563 | }; | |
564 | ||
fc52692c | 565 | static int ad5755_probe(struct spi_device *spi) |
c499d029 LPC |
566 | { |
567 | enum ad5755_type type = spi_get_device_id(spi)->driver_data; | |
568 | const struct ad5755_platform_data *pdata = dev_get_platdata(&spi->dev); | |
569 | struct iio_dev *indio_dev; | |
570 | struct ad5755_state *st; | |
571 | int ret; | |
572 | ||
573 | indio_dev = iio_device_alloc(sizeof(*st)); | |
574 | if (indio_dev == NULL) { | |
575 | dev_err(&spi->dev, "Failed to allocate iio device\n"); | |
576 | return -ENOMEM; | |
577 | } | |
578 | ||
579 | st = iio_priv(indio_dev); | |
580 | spi_set_drvdata(spi, indio_dev); | |
581 | ||
582 | st->chip_info = &ad5755_chip_info_tbl[type]; | |
583 | st->spi = spi; | |
584 | st->pwr_down = 0xf; | |
585 | ||
586 | indio_dev->dev.parent = &spi->dev; | |
587 | indio_dev->name = spi_get_device_id(spi)->name; | |
588 | indio_dev->info = &ad5755_info; | |
589 | indio_dev->modes = INDIO_DIRECT_MODE; | |
590 | indio_dev->num_channels = AD5755_NUM_CHANNELS; | |
591 | ||
592 | if (!pdata) | |
593 | pdata = &ad5755_default_pdata; | |
594 | ||
595 | ret = ad5755_init_channels(indio_dev, pdata); | |
596 | if (ret) | |
597 | goto error_free; | |
598 | ||
599 | ret = ad5755_setup_pdata(indio_dev, pdata); | |
600 | if (ret) | |
601 | goto error_free; | |
602 | ||
603 | ret = iio_device_register(indio_dev); | |
604 | if (ret) { | |
605 | dev_err(&spi->dev, "Failed to register iio device: %d\n", ret); | |
606 | goto error_free; | |
607 | } | |
608 | ||
609 | return 0; | |
610 | ||
611 | error_free: | |
612 | iio_device_free(indio_dev); | |
613 | ||
614 | return ret; | |
615 | } | |
616 | ||
fc52692c | 617 | static int ad5755_remove(struct spi_device *spi) |
c499d029 LPC |
618 | { |
619 | struct iio_dev *indio_dev = spi_get_drvdata(spi); | |
620 | ||
621 | iio_device_unregister(indio_dev); | |
622 | iio_device_free(indio_dev); | |
623 | ||
624 | return 0; | |
625 | } | |
626 | ||
627 | static const struct spi_device_id ad5755_id[] = { | |
628 | { "ad5755", ID_AD5755 }, | |
629 | { "ad5755-1", ID_AD5755 }, | |
630 | { "ad5757", ID_AD5757 }, | |
631 | { "ad5735", ID_AD5735 }, | |
632 | { "ad5737", ID_AD5737 }, | |
633 | {} | |
634 | }; | |
635 | MODULE_DEVICE_TABLE(spi, ad5755_id); | |
636 | ||
637 | static struct spi_driver ad5755_driver = { | |
638 | .driver = { | |
639 | .name = "ad5755", | |
640 | .owner = THIS_MODULE, | |
641 | }, | |
642 | .probe = ad5755_probe, | |
fc52692c | 643 | .remove = ad5755_remove, |
c499d029 LPC |
644 | .id_table = ad5755_id, |
645 | }; | |
646 | module_spi_driver(ad5755_driver); | |
647 | ||
648 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | |
649 | MODULE_DESCRIPTION("Analog Devices AD5755/55-1/57/35/37 DAC"); | |
650 | MODULE_LICENSE("GPL v2"); |