1c924eee3SKuninori Morimoto // SPDX-License-Identifier: GPL-2.0
2a8e7e88dSJacopo Mondi /*
3a8e7e88dSJacopo Mondi * iio/adc/max11100.c
4a8e7e88dSJacopo Mondi * Maxim max11100 ADC Driver with IIO interface
5a8e7e88dSJacopo Mondi *
6a8e7e88dSJacopo Mondi * Copyright (C) 2016-17 Renesas Electronics Corporation
7a8e7e88dSJacopo Mondi * Copyright (C) 2016-17 Jacopo Mondi
8a8e7e88dSJacopo Mondi */
9a8e7e88dSJacopo Mondi #include <linux/delay.h>
10a8e7e88dSJacopo Mondi #include <linux/kernel.h>
117a3e190fSJonathan Cameron #include <linux/mod_devicetable.h>
12a8e7e88dSJacopo Mondi #include <linux/module.h>
13a8e7e88dSJacopo Mondi #include <linux/regulator/consumer.h>
14a8e7e88dSJacopo Mondi #include <linux/spi/spi.h>
15ff9111abSJonathan Cameron #include <asm/unaligned.h>
16a8e7e88dSJacopo Mondi
17a8e7e88dSJacopo Mondi #include <linux/iio/iio.h>
18a8e7e88dSJacopo Mondi #include <linux/iio/driver.h>
19a8e7e88dSJacopo Mondi
20a8e7e88dSJacopo Mondi /*
21a8e7e88dSJacopo Mondi * LSB is the ADC single digital step
22a8e7e88dSJacopo Mondi * 1 LSB = (vref_mv / 2 ^ 16)
23a8e7e88dSJacopo Mondi *
24a8e7e88dSJacopo Mondi * LSB is used to calculate analog voltage value
25a8e7e88dSJacopo Mondi * from the number of ADC steps count
26a8e7e88dSJacopo Mondi *
27a8e7e88dSJacopo Mondi * Ain = (count * LSB)
28a8e7e88dSJacopo Mondi */
29a8e7e88dSJacopo Mondi #define MAX11100_LSB_DIV (1 << 16)
30a8e7e88dSJacopo Mondi
31a8e7e88dSJacopo Mondi struct max11100_state {
32a8e7e88dSJacopo Mondi struct regulator *vref_reg;
33a8e7e88dSJacopo Mondi struct spi_device *spi;
34a8e7e88dSJacopo Mondi
35a8e7e88dSJacopo Mondi /*
36*51f30d63SJonathan Cameron * DMA (thus cache coherency maintenance) may require the
37a8e7e88dSJacopo Mondi * transfer buffers to live in their own cache lines.
38a8e7e88dSJacopo Mondi */
39*51f30d63SJonathan Cameron u8 buffer[3] __aligned(IIO_DMA_MINALIGN);
40a8e7e88dSJacopo Mondi };
41a8e7e88dSJacopo Mondi
42ce6c3736SRikard Falkeborn static const struct iio_chan_spec max11100_channels[] = {
43a8e7e88dSJacopo Mondi { /* [0] */
44a8e7e88dSJacopo Mondi .type = IIO_VOLTAGE,
45a8e7e88dSJacopo Mondi .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
46a8e7e88dSJacopo Mondi BIT(IIO_CHAN_INFO_SCALE),
47a8e7e88dSJacopo Mondi },
48a8e7e88dSJacopo Mondi };
49a8e7e88dSJacopo Mondi
max11100_read_single(struct iio_dev * indio_dev,int * val)50a8e7e88dSJacopo Mondi static int max11100_read_single(struct iio_dev *indio_dev, int *val)
51a8e7e88dSJacopo Mondi {
52a8e7e88dSJacopo Mondi int ret;
53a8e7e88dSJacopo Mondi struct max11100_state *state = iio_priv(indio_dev);
54a8e7e88dSJacopo Mondi
55a8e7e88dSJacopo Mondi ret = spi_read(state->spi, state->buffer, sizeof(state->buffer));
56a8e7e88dSJacopo Mondi if (ret) {
57a8e7e88dSJacopo Mondi dev_err(&indio_dev->dev, "SPI transfer failed\n");
58a8e7e88dSJacopo Mondi return ret;
59a8e7e88dSJacopo Mondi }
60a8e7e88dSJacopo Mondi
61a8e7e88dSJacopo Mondi /* the first 8 bits sent out from ADC must be 0s */
62a8e7e88dSJacopo Mondi if (state->buffer[0]) {
63a8e7e88dSJacopo Mondi dev_err(&indio_dev->dev, "Invalid value: buffer[0] != 0\n");
64a8e7e88dSJacopo Mondi return -EINVAL;
65a8e7e88dSJacopo Mondi }
66a8e7e88dSJacopo Mondi
67ff9111abSJonathan Cameron *val = get_unaligned_be16(&state->buffer[1]);
68a8e7e88dSJacopo Mondi
69a8e7e88dSJacopo Mondi return 0;
70a8e7e88dSJacopo Mondi }
71a8e7e88dSJacopo Mondi
max11100_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long info)72a8e7e88dSJacopo Mondi static int max11100_read_raw(struct iio_dev *indio_dev,
73a8e7e88dSJacopo Mondi struct iio_chan_spec const *chan,
74a8e7e88dSJacopo Mondi int *val, int *val2, long info)
75a8e7e88dSJacopo Mondi {
76a8e7e88dSJacopo Mondi int ret, vref_uv;
77a8e7e88dSJacopo Mondi struct max11100_state *state = iio_priv(indio_dev);
78a8e7e88dSJacopo Mondi
79a8e7e88dSJacopo Mondi switch (info) {
80a8e7e88dSJacopo Mondi case IIO_CHAN_INFO_RAW:
81a8e7e88dSJacopo Mondi ret = max11100_read_single(indio_dev, val);
82a8e7e88dSJacopo Mondi if (ret)
83a8e7e88dSJacopo Mondi return ret;
84a8e7e88dSJacopo Mondi
85a8e7e88dSJacopo Mondi return IIO_VAL_INT;
86a8e7e88dSJacopo Mondi
87a8e7e88dSJacopo Mondi case IIO_CHAN_INFO_SCALE:
88a8e7e88dSJacopo Mondi vref_uv = regulator_get_voltage(state->vref_reg);
89a8e7e88dSJacopo Mondi if (vref_uv < 0)
90a8e7e88dSJacopo Mondi /* dummy regulator "get_voltage" returns -EINVAL */
91a8e7e88dSJacopo Mondi return -EINVAL;
92a8e7e88dSJacopo Mondi
93a8e7e88dSJacopo Mondi *val = vref_uv / 1000;
94a8e7e88dSJacopo Mondi *val2 = MAX11100_LSB_DIV;
95a8e7e88dSJacopo Mondi return IIO_VAL_FRACTIONAL;
96a8e7e88dSJacopo Mondi }
97a8e7e88dSJacopo Mondi
98a8e7e88dSJacopo Mondi return -EINVAL;
99a8e7e88dSJacopo Mondi }
100a8e7e88dSJacopo Mondi
101a8e7e88dSJacopo Mondi static const struct iio_info max11100_info = {
102a8e7e88dSJacopo Mondi .read_raw = max11100_read_raw,
103a8e7e88dSJacopo Mondi };
104a8e7e88dSJacopo Mondi
max11100_regulator_disable(void * reg)1057169a78eSJonathan Cameron static void max11100_regulator_disable(void *reg)
1067169a78eSJonathan Cameron {
1077169a78eSJonathan Cameron regulator_disable(reg);
1087169a78eSJonathan Cameron }
1097169a78eSJonathan Cameron
max11100_probe(struct spi_device * spi)110a8e7e88dSJacopo Mondi static int max11100_probe(struct spi_device *spi)
111a8e7e88dSJacopo Mondi {
112a8e7e88dSJacopo Mondi int ret;
113a8e7e88dSJacopo Mondi struct iio_dev *indio_dev;
114a8e7e88dSJacopo Mondi struct max11100_state *state;
115a8e7e88dSJacopo Mondi
116a8e7e88dSJacopo Mondi indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
117a8e7e88dSJacopo Mondi if (!indio_dev)
118a8e7e88dSJacopo Mondi return -ENOMEM;
119a8e7e88dSJacopo Mondi
120a8e7e88dSJacopo Mondi state = iio_priv(indio_dev);
121a8e7e88dSJacopo Mondi state->spi = spi;
122a8e7e88dSJacopo Mondi
123a8e7e88dSJacopo Mondi indio_dev->name = "max11100";
124a8e7e88dSJacopo Mondi indio_dev->info = &max11100_info;
125a8e7e88dSJacopo Mondi indio_dev->modes = INDIO_DIRECT_MODE;
126bb4787f5SArushi Singhal indio_dev->channels = max11100_channels;
127bb4787f5SArushi Singhal indio_dev->num_channels = ARRAY_SIZE(max11100_channels);
128a8e7e88dSJacopo Mondi
129a8e7e88dSJacopo Mondi state->vref_reg = devm_regulator_get(&spi->dev, "vref");
130a8e7e88dSJacopo Mondi if (IS_ERR(state->vref_reg))
131a8e7e88dSJacopo Mondi return PTR_ERR(state->vref_reg);
132a8e7e88dSJacopo Mondi
133a8e7e88dSJacopo Mondi ret = regulator_enable(state->vref_reg);
134a8e7e88dSJacopo Mondi if (ret)
135a8e7e88dSJacopo Mondi return ret;
136a8e7e88dSJacopo Mondi
1377169a78eSJonathan Cameron ret = devm_add_action_or_reset(&spi->dev, max11100_regulator_disable,
1387169a78eSJonathan Cameron state->vref_reg);
139a8e7e88dSJacopo Mondi if (ret)
140a8e7e88dSJacopo Mondi return ret;
141a8e7e88dSJacopo Mondi
1427169a78eSJonathan Cameron return devm_iio_device_register(&spi->dev, indio_dev);
143a8e7e88dSJacopo Mondi }
144a8e7e88dSJacopo Mondi
145a8e7e88dSJacopo Mondi static const struct of_device_id max11100_ids[] = {
146a8e7e88dSJacopo Mondi {.compatible = "maxim,max11100"},
147a8e7e88dSJacopo Mondi { },
148a8e7e88dSJacopo Mondi };
149a8e7e88dSJacopo Mondi MODULE_DEVICE_TABLE(of, max11100_ids);
150a8e7e88dSJacopo Mondi
151a8e7e88dSJacopo Mondi static struct spi_driver max11100_driver = {
152a8e7e88dSJacopo Mondi .driver = {
153a8e7e88dSJacopo Mondi .name = "max11100",
1547a3e190fSJonathan Cameron .of_match_table = max11100_ids,
155a8e7e88dSJacopo Mondi },
156a8e7e88dSJacopo Mondi .probe = max11100_probe,
157a8e7e88dSJacopo Mondi };
158a8e7e88dSJacopo Mondi
159a8e7e88dSJacopo Mondi module_spi_driver(max11100_driver);
160a8e7e88dSJacopo Mondi
161a8e7e88dSJacopo Mondi MODULE_AUTHOR("Jacopo Mondi <jacopo@jmondi.org>");
162a8e7e88dSJacopo Mondi MODULE_DESCRIPTION("Maxim max11100 ADC Driver");
163a8e7e88dSJacopo Mondi MODULE_LICENSE("GPL v2");
164