1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Microchip MCP3911, Two-channel Analog Front End
5 * Copyright (C) 2018 Marcus Folkesson <marcus.folkesson@gmail.com>
6 * Copyright (C) 2018 Kent Gustavsson <kent@minoris.se>
9 #include <linux/delay.h>
10 #include <linux/err.h>
11 #include <linux/iio/iio.h>
12 #include <linux/module.h>
13 #include <linux/regulator/consumer.h>
14 #include <linux/spi/spi.h>
16 #define MCP3911_REG_CHANNEL0 0x00
17 #define MCP3911_REG_CHANNEL1 0x03
18 #define MCP3911_REG_MOD 0x06
19 #define MCP3911_REG_PHASE 0x07
20 #define MCP3911_REG_GAIN 0x09
22 #define MCP3911_REG_STATUSCOM 0x0a
23 #define MCP3911_STATUSCOM_CH1_24WIDTH BIT(4)
24 #define MCP3911_STATUSCOM_CH0_24WIDTH BIT(3)
25 #define MCP3911_STATUSCOM_EN_OFFCAL BIT(2)
26 #define MCP3911_STATUSCOM_EN_GAINCAL BIT(1)
28 #define MCP3911_REG_CONFIG 0x0c
29 #define MCP3911_CONFIG_CLKEXT BIT(1)
30 #define MCP3911_CONFIG_VREFEXT BIT(2)
32 #define MCP3911_REG_OFFCAL_CH0 0x0e
33 #define MCP3911_REG_GAINCAL_CH0 0x11
34 #define MCP3911_REG_OFFCAL_CH1 0x14
35 #define MCP3911_REG_GAINCAL_CH1 0x17
36 #define MCP3911_REG_VREFCAL 0x1a
38 #define MCP3911_CHANNEL(x) (MCP3911_REG_CHANNEL0 + x * 3)
39 #define MCP3911_OFFCAL(x) (MCP3911_REG_OFFCAL_CH0 + x * 6)
41 /* Internal voltage reference in uV */
42 #define MCP3911_INT_VREF_UV 1200000
44 #define MCP3911_REG_READ(reg, id) ((((reg) << 1) | ((id) << 5) | (1 << 0)) & 0xff)
45 #define MCP3911_REG_WRITE(reg, id) ((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff)
47 #define MCP3911_NUM_CHANNELS 2
50 struct spi_device
*spi
;
52 struct regulator
*vref
;
57 static int mcp3911_read(struct mcp3911
*adc
, u8 reg
, u32
*val
, u8 len
)
61 reg
= MCP3911_REG_READ(reg
, adc
->dev_addr
);
62 ret
= spi_write_then_read(adc
->spi
, ®
, 1, val
, len
);
67 *val
>>= ((4 - len
) * 8);
68 dev_dbg(&adc
->spi
->dev
, "reading 0x%x from register 0x%x\n", *val
,
73 static int mcp3911_write(struct mcp3911
*adc
, u8 reg
, u32 val
, u8 len
)
75 dev_dbg(&adc
->spi
->dev
, "writing 0x%x to register 0x%x\n", val
, reg
);
77 val
<<= (3 - len
) * 8;
79 val
|= MCP3911_REG_WRITE(reg
, adc
->dev_addr
);
81 return spi_write(adc
->spi
, &val
, len
+ 1);
84 static int mcp3911_update(struct mcp3911
*adc
, u8 reg
, u32 mask
,
90 ret
= mcp3911_read(adc
, reg
, &tmp
, len
);
96 return mcp3911_write(adc
, reg
, val
, len
);
99 static int mcp3911_read_raw(struct iio_dev
*indio_dev
,
100 struct iio_chan_spec
const *channel
, int *val
,
101 int *val2
, long mask
)
103 struct mcp3911
*adc
= iio_priv(indio_dev
);
106 mutex_lock(&adc
->lock
);
108 case IIO_CHAN_INFO_RAW
:
109 ret
= mcp3911_read(adc
,
110 MCP3911_CHANNEL(channel
->channel
), val
, 3);
117 case IIO_CHAN_INFO_OFFSET
:
118 ret
= mcp3911_read(adc
,
119 MCP3911_OFFCAL(channel
->channel
), val
, 3);
126 case IIO_CHAN_INFO_SCALE
:
128 ret
= regulator_get_voltage(adc
->vref
);
130 dev_err(indio_dev
->dev
.parent
,
131 "failed to get vref voltage: %d\n",
138 *val
= MCP3911_INT_VREF_UV
;
142 ret
= IIO_VAL_FRACTIONAL_LOG2
;
147 mutex_unlock(&adc
->lock
);
151 static int mcp3911_write_raw(struct iio_dev
*indio_dev
,
152 struct iio_chan_spec
const *channel
, int val
,
155 struct mcp3911
*adc
= iio_priv(indio_dev
);
158 mutex_lock(&adc
->lock
);
160 case IIO_CHAN_INFO_OFFSET
:
167 ret
= mcp3911_write(adc
, MCP3911_OFFCAL(channel
->channel
), val
,
173 ret
= mcp3911_update(adc
, MCP3911_REG_STATUSCOM
,
174 MCP3911_STATUSCOM_EN_OFFCAL
,
175 MCP3911_STATUSCOM_EN_OFFCAL
, 2);
180 mutex_unlock(&adc
->lock
);
184 #define MCP3911_CHAN(idx) { \
185 .type = IIO_VOLTAGE, \
188 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
189 BIT(IIO_CHAN_INFO_OFFSET) | \
190 BIT(IIO_CHAN_INFO_SCALE), \
193 static const struct iio_chan_spec mcp3911_channels
[] = {
198 static const struct iio_info mcp3911_info
= {
199 .read_raw
= mcp3911_read_raw
,
200 .write_raw
= mcp3911_write_raw
,
203 static int mcp3911_config(struct mcp3911
*adc
, struct device_node
*of_node
)
208 of_property_read_u32(of_node
, "device-addr", &adc
->dev_addr
);
209 if (adc
->dev_addr
> 3) {
210 dev_err(&adc
->spi
->dev
,
211 "invalid device address (%i). Must be in range 0-3.\n",
215 dev_dbg(&adc
->spi
->dev
, "use device address %i\n", adc
->dev_addr
);
217 ret
= mcp3911_read(adc
, MCP3911_REG_CONFIG
, &configreg
, 2);
222 dev_dbg(&adc
->spi
->dev
, "use external voltage reference\n");
223 configreg
|= MCP3911_CONFIG_VREFEXT
;
225 dev_dbg(&adc
->spi
->dev
,
226 "use internal voltage reference (1.2V)\n");
227 configreg
&= ~MCP3911_CONFIG_VREFEXT
;
231 dev_dbg(&adc
->spi
->dev
, "use external clock as clocksource\n");
232 configreg
|= MCP3911_CONFIG_CLKEXT
;
234 dev_dbg(&adc
->spi
->dev
,
235 "use crystal oscillator as clocksource\n");
236 configreg
&= ~MCP3911_CONFIG_CLKEXT
;
239 return mcp3911_write(adc
, MCP3911_REG_CONFIG
, configreg
, 2);
242 static int mcp3911_probe(struct spi_device
*spi
)
244 struct iio_dev
*indio_dev
;
248 indio_dev
= devm_iio_device_alloc(&spi
->dev
, sizeof(*adc
));
252 adc
= iio_priv(indio_dev
);
255 adc
->vref
= devm_regulator_get_optional(&adc
->spi
->dev
, "vref");
256 if (IS_ERR(adc
->vref
)) {
257 if (PTR_ERR(adc
->vref
) == -ENODEV
) {
260 dev_err(&adc
->spi
->dev
,
261 "failed to get regulator (%ld)\n",
263 return PTR_ERR(adc
->vref
);
267 ret
= regulator_enable(adc
->vref
);
272 adc
->clki
= devm_clk_get(&adc
->spi
->dev
, NULL
);
273 if (IS_ERR(adc
->clki
)) {
274 if (PTR_ERR(adc
->clki
) == -ENOENT
) {
277 dev_err(&adc
->spi
->dev
,
278 "failed to get adc clk (%ld)\n",
280 ret
= PTR_ERR(adc
->clki
);
284 ret
= clk_prepare_enable(adc
->clki
);
286 dev_err(&adc
->spi
->dev
,
287 "Failed to enable clki: %d\n", ret
);
292 ret
= mcp3911_config(adc
, spi
->dev
.of_node
);
296 indio_dev
->name
= spi_get_device_id(spi
)->name
;
297 indio_dev
->modes
= INDIO_DIRECT_MODE
;
298 indio_dev
->info
= &mcp3911_info
;
299 spi_set_drvdata(spi
, indio_dev
);
301 indio_dev
->channels
= mcp3911_channels
;
302 indio_dev
->num_channels
= ARRAY_SIZE(mcp3911_channels
);
304 mutex_init(&adc
->lock
);
306 ret
= iio_device_register(indio_dev
);
313 clk_disable_unprepare(adc
->clki
);
316 regulator_disable(adc
->vref
);
321 static int mcp3911_remove(struct spi_device
*spi
)
323 struct iio_dev
*indio_dev
= spi_get_drvdata(spi
);
324 struct mcp3911
*adc
= iio_priv(indio_dev
);
326 iio_device_unregister(indio_dev
);
328 clk_disable_unprepare(adc
->clki
);
330 regulator_disable(adc
->vref
);
335 static const struct of_device_id mcp3911_dt_ids
[] = {
336 { .compatible
= "microchip,mcp3911" },
339 MODULE_DEVICE_TABLE(of
, mcp3911_dt_ids
);
341 static const struct spi_device_id mcp3911_id
[] = {
345 MODULE_DEVICE_TABLE(spi
, mcp3911_id
);
347 static struct spi_driver mcp3911_driver
= {
350 .of_match_table
= mcp3911_dt_ids
,
352 .probe
= mcp3911_probe
,
353 .remove
= mcp3911_remove
,
354 .id_table
= mcp3911_id
,
356 module_spi_driver(mcp3911_driver
);
358 MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>");
359 MODULE_AUTHOR("Kent Gustavsson <kent@minoris.se>");
360 MODULE_DESCRIPTION("Microchip Technology MCP3911");
361 MODULE_LICENSE("GPL v2");