2 * Copyright (C) 2015 Prevas A/S
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
9 #include <linux/device.h>
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/sysfs.h>
13 #include <linux/spi/spi.h>
14 #include <linux/regulator/consumer.h>
15 #include <linux/err.h>
16 #include <linux/module.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
22 #define ADS8688_CMD_REG(x) (x << 8)
23 #define ADS8688_CMD_REG_NOOP 0x00
24 #define ADS8688_CMD_REG_RST 0x85
25 #define ADS8688_CMD_REG_MAN_CH(chan) (0xC0 | (4 * chan))
26 #define ADS8688_CMD_DONT_CARE_BITS 16
28 #define ADS8688_PROG_REG(x) (x << 9)
29 #define ADS8688_PROG_REG_RANGE_CH(chan) (0x05 + chan)
30 #define ADS8688_PROG_WR_BIT BIT(8)
31 #define ADS8688_PROG_DONT_CARE_BITS 8
33 #define ADS8688_REG_PLUSMINUS25VREF 0
34 #define ADS8688_REG_PLUSMINUS125VREF 1
35 #define ADS8688_REG_PLUSMINUS0625VREF 2
36 #define ADS8688_REG_PLUS25VREF 5
37 #define ADS8688_REG_PLUS125VREF 6
39 #define ADS8688_VREF_MV 4096
40 #define ADS8688_REALBITS 16
43 * enum ads8688_range - ADS8688 reference voltage range
44 * @ADS8688_PLUSMINUS25VREF: Device is configured for input range ±2.5 * VREF
45 * @ADS8688_PLUSMINUS125VREF: Device is configured for input range ±1.25 * VREF
46 * @ADS8688_PLUSMINUS0625VREF: Device is configured for input range ±0.625 * VREF
47 * @ADS8688_PLUS25VREF: Device is configured for input range 0 - 2.5 * VREF
48 * @ADS8688_PLUS125VREF: Device is configured for input range 0 - 1.25 * VREF
51 ADS8688_PLUSMINUS25VREF
,
52 ADS8688_PLUSMINUS125VREF
,
53 ADS8688_PLUSMINUS0625VREF
,
58 struct ads8688_chip_info
{
59 const struct iio_chan_spec
*channels
;
60 unsigned int num_channels
;
63 struct ads8688_state
{
65 const struct ads8688_chip_info
*chip_info
;
66 struct spi_device
*spi
;
67 struct regulator
*reg
;
69 enum ads8688_range range
[8];
73 } data
[2] ____cacheline_aligned
;
81 struct ads8688_ranges
{
82 enum ads8688_range range
;
88 static const struct ads8688_ranges ads8688_range_def
[5] = {
90 .range
= ADS8688_PLUSMINUS25VREF
,
92 .offset
= -(1 << (ADS8688_REALBITS
- 1)),
93 .reg
= ADS8688_REG_PLUSMINUS25VREF
,
95 .range
= ADS8688_PLUSMINUS125VREF
,
97 .offset
= -(1 << (ADS8688_REALBITS
- 1)),
98 .reg
= ADS8688_REG_PLUSMINUS125VREF
,
100 .range
= ADS8688_PLUSMINUS0625VREF
,
102 .offset
= -(1 << (ADS8688_REALBITS
- 1)),
103 .reg
= ADS8688_REG_PLUSMINUS0625VREF
,
105 .range
= ADS8688_PLUS25VREF
,
108 .reg
= ADS8688_REG_PLUS25VREF
,
110 .range
= ADS8688_PLUS125VREF
,
113 .reg
= ADS8688_REG_PLUS125VREF
,
117 static ssize_t
ads8688_show_scales(struct device
*dev
,
118 struct device_attribute
*attr
, char *buf
)
120 struct ads8688_state
*st
= iio_priv(dev_to_iio_dev(dev
));
122 return sprintf(buf
, "0.%09u 0.%09u 0.%09u\n",
123 ads8688_range_def
[0].scale
* st
->vref_mv
,
124 ads8688_range_def
[1].scale
* st
->vref_mv
,
125 ads8688_range_def
[2].scale
* st
->vref_mv
);
128 static ssize_t
ads8688_show_offsets(struct device
*dev
,
129 struct device_attribute
*attr
, char *buf
)
131 return sprintf(buf
, "%d %d\n", ads8688_range_def
[0].offset
,
132 ads8688_range_def
[3].offset
);
135 static IIO_DEVICE_ATTR(in_voltage_scale_available
, S_IRUGO
,
136 ads8688_show_scales
, NULL
, 0);
137 static IIO_DEVICE_ATTR(in_voltage_offset_available
, S_IRUGO
,
138 ads8688_show_offsets
, NULL
, 0);
140 static struct attribute
*ads8688_attributes
[] = {
141 &iio_dev_attr_in_voltage_scale_available
.dev_attr
.attr
,
142 &iio_dev_attr_in_voltage_offset_available
.dev_attr
.attr
,
146 static const struct attribute_group ads8688_attribute_group
= {
147 .attrs
= ads8688_attributes
,
150 #define ADS8688_CHAN(index) \
152 .type = IIO_VOLTAGE, \
155 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \
156 | BIT(IIO_CHAN_INFO_SCALE) \
157 | BIT(IIO_CHAN_INFO_OFFSET), \
160 static const struct iio_chan_spec ads8684_channels
[] = {
167 static const struct iio_chan_spec ads8688_channels
[] = {
178 static int ads8688_prog_write(struct iio_dev
*indio_dev
, unsigned int addr
,
181 struct ads8688_state
*st
= iio_priv(indio_dev
);
184 tmp
= ADS8688_PROG_REG(addr
) | ADS8688_PROG_WR_BIT
| val
;
185 tmp
<<= ADS8688_PROG_DONT_CARE_BITS
;
186 st
->data
[0].d32
= cpu_to_be32(tmp
);
188 return spi_write(st
->spi
, &st
->data
[0].d8
[1], 3);
191 static int ads8688_reset(struct iio_dev
*indio_dev
)
193 struct ads8688_state
*st
= iio_priv(indio_dev
);
196 tmp
= ADS8688_CMD_REG(ADS8688_CMD_REG_RST
);
197 tmp
<<= ADS8688_CMD_DONT_CARE_BITS
;
198 st
->data
[0].d32
= cpu_to_be32(tmp
);
200 return spi_write(st
->spi
, &st
->data
[0].d8
[0], 4);
203 static int ads8688_read(struct iio_dev
*indio_dev
, unsigned int chan
)
205 struct ads8688_state
*st
= iio_priv(indio_dev
);
208 struct spi_transfer t
[] = {
210 .tx_buf
= &st
->data
[0].d8
[0],
214 .tx_buf
= &st
->data
[1].d8
[0],
215 .rx_buf
= &st
->data
[1].d8
[0],
220 tmp
= ADS8688_CMD_REG(ADS8688_CMD_REG_MAN_CH(chan
));
221 tmp
<<= ADS8688_CMD_DONT_CARE_BITS
;
222 st
->data
[0].d32
= cpu_to_be32(tmp
);
224 tmp
= ADS8688_CMD_REG(ADS8688_CMD_REG_NOOP
);
225 tmp
<<= ADS8688_CMD_DONT_CARE_BITS
;
226 st
->data
[1].d32
= cpu_to_be32(tmp
);
228 ret
= spi_sync_transfer(st
->spi
, t
, ARRAY_SIZE(t
));
232 return be32_to_cpu(st
->data
[1].d32
) & 0xffff;
235 static int ads8688_read_raw(struct iio_dev
*indio_dev
,
236 struct iio_chan_spec
const *chan
,
237 int *val
, int *val2
, long m
)
240 unsigned long scale_mv
;
242 struct ads8688_state
*st
= iio_priv(indio_dev
);
244 mutex_lock(&st
->lock
);
246 case IIO_CHAN_INFO_RAW
:
247 ret
= ads8688_read(indio_dev
, chan
->channel
);
248 mutex_unlock(&st
->lock
);
253 case IIO_CHAN_INFO_SCALE
:
254 scale_mv
= st
->vref_mv
;
255 scale_mv
*= ads8688_range_def
[st
->range
[chan
->channel
]].scale
;
258 mutex_unlock(&st
->lock
);
259 return IIO_VAL_INT_PLUS_NANO
;
260 case IIO_CHAN_INFO_OFFSET
:
261 offset
= ads8688_range_def
[st
->range
[chan
->channel
]].offset
;
263 mutex_unlock(&st
->lock
);
266 mutex_unlock(&st
->lock
);
271 static int ads8688_write_reg_range(struct iio_dev
*indio_dev
,
272 struct iio_chan_spec
const *chan
,
273 enum ads8688_range range
)
278 tmp
= ADS8688_PROG_REG_RANGE_CH(chan
->channel
);
279 ret
= ads8688_prog_write(indio_dev
, tmp
, range
);
284 static int ads8688_write_raw(struct iio_dev
*indio_dev
,
285 struct iio_chan_spec
const *chan
,
286 int val
, int val2
, long mask
)
288 struct ads8688_state
*st
= iio_priv(indio_dev
);
289 unsigned int scale
= 0;
290 int ret
= -EINVAL
, i
, offset
= 0;
292 mutex_lock(&st
->lock
);
294 case IIO_CHAN_INFO_SCALE
:
295 /* If the offset is 0 the ±2.5 * VREF mode is not available */
296 offset
= ads8688_range_def
[st
->range
[chan
->channel
]].offset
;
297 if (offset
== 0 && val2
== ads8688_range_def
[0].scale
* st
->vref_mv
) {
298 mutex_unlock(&st
->lock
);
302 /* Lookup new mode */
303 for (i
= 0; i
< ARRAY_SIZE(ads8688_range_def
); i
++)
304 if (val2
== ads8688_range_def
[i
].scale
* st
->vref_mv
&&
305 offset
== ads8688_range_def
[i
].offset
) {
306 ret
= ads8688_write_reg_range(indio_dev
, chan
,
307 ads8688_range_def
[i
].reg
);
311 case IIO_CHAN_INFO_OFFSET
:
313 * There are only two available offsets:
314 * 0 and -(1 << (ADS8688_REALBITS - 1))
316 if (!(ads8688_range_def
[0].offset
== val
||
317 ads8688_range_def
[3].offset
== val
)) {
318 mutex_unlock(&st
->lock
);
323 * If the device are in ±2.5 * VREF mode, it's not allowed to
324 * switch to a mode where the offset is 0
327 st
->range
[chan
->channel
] == ADS8688_PLUSMINUS25VREF
) {
328 mutex_unlock(&st
->lock
);
332 scale
= ads8688_range_def
[st
->range
[chan
->channel
]].scale
;
334 /* Lookup new mode */
335 for (i
= 0; i
< ARRAY_SIZE(ads8688_range_def
); i
++)
336 if (val
== ads8688_range_def
[i
].offset
&&
337 scale
== ads8688_range_def
[i
].scale
) {
338 ret
= ads8688_write_reg_range(indio_dev
, chan
,
339 ads8688_range_def
[i
].reg
);
346 st
->range
[chan
->channel
] = ads8688_range_def
[i
].range
;
348 mutex_unlock(&st
->lock
);
353 static int ads8688_write_raw_get_fmt(struct iio_dev
*indio_dev
,
354 struct iio_chan_spec
const *chan
,
358 case IIO_CHAN_INFO_SCALE
:
359 return IIO_VAL_INT_PLUS_NANO
;
360 case IIO_CHAN_INFO_OFFSET
:
367 static const struct iio_info ads8688_info
= {
368 .read_raw
= &ads8688_read_raw
,
369 .write_raw
= &ads8688_write_raw
,
370 .write_raw_get_fmt
= &ads8688_write_raw_get_fmt
,
371 .attrs
= &ads8688_attribute_group
,
372 .driver_module
= THIS_MODULE
,
375 static const struct ads8688_chip_info ads8688_chip_info_tbl
[] = {
377 .channels
= ads8684_channels
,
378 .num_channels
= ARRAY_SIZE(ads8684_channels
),
381 .channels
= ads8688_channels
,
382 .num_channels
= ARRAY_SIZE(ads8688_channels
),
386 static int ads8688_probe(struct spi_device
*spi
)
388 struct ads8688_state
*st
;
389 struct iio_dev
*indio_dev
;
392 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*st
));
393 if (indio_dev
== NULL
)
396 st
= iio_priv(indio_dev
);
398 st
->reg
= devm_regulator_get_optional(&spi
->dev
, "vref");
399 if (!IS_ERR(st
->reg
)) {
400 ret
= regulator_enable(st
->reg
);
404 ret
= regulator_get_voltage(st
->reg
);
408 st
->vref_mv
= ret
/ 1000;
410 /* Use internal reference */
411 st
->vref_mv
= ADS8688_VREF_MV
;
414 st
->chip_info
= &ads8688_chip_info_tbl
[spi_get_device_id(spi
)->driver_data
];
416 spi
->mode
= SPI_MODE_1
;
418 spi_set_drvdata(spi
, indio_dev
);
422 indio_dev
->name
= spi_get_device_id(spi
)->name
;
423 indio_dev
->dev
.parent
= &spi
->dev
;
424 indio_dev
->modes
= INDIO_DIRECT_MODE
;
425 indio_dev
->channels
= st
->chip_info
->channels
;
426 indio_dev
->num_channels
= st
->chip_info
->num_channels
;
427 indio_dev
->info
= &ads8688_info
;
429 ads8688_reset(indio_dev
);
431 mutex_init(&st
->lock
);
433 ret
= iio_device_register(indio_dev
);
440 if (!IS_ERR_OR_NULL(st
->reg
))
441 regulator_disable(st
->reg
);
446 static int ads8688_remove(struct spi_device
*spi
)
448 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
449 struct ads8688_state
*st
= iio_priv(indio_dev
);
451 iio_device_unregister(indio_dev
);
453 if (!IS_ERR_OR_NULL(st
->reg
))
454 regulator_disable(st
->reg
);
459 static const struct spi_device_id ads8688_id
[] = {
460 {"ads8684", ID_ADS8684
},
461 {"ads8688", ID_ADS8688
},
464 MODULE_DEVICE_TABLE(spi
, ads8688_id
);
466 static const struct of_device_id ads8688_of_match
[] = {
467 { .compatible
= "ti,ads8684" },
468 { .compatible
= "ti,ads8688" },
471 MODULE_DEVICE_TABLE(of
, ads8688_of_match
);
473 static struct spi_driver ads8688_driver
= {
476 .owner
= THIS_MODULE
,
478 .probe
= ads8688_probe
,
479 .remove
= ads8688_remove
,
480 .id_table
= ads8688_id
,
482 module_spi_driver(ads8688_driver
);
484 MODULE_AUTHOR("Sean Nyekjaer <sean.nyekjaer@prevas.dk>");
485 MODULE_DESCRIPTION("Texas Instruments ADS8688 driver");
486 MODULE_LICENSE("GPL v2");