Lines Matching +full:vref +full:- +full:internal
1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Microchip MCP3911, Two-channel Analog Front End
41 /* Internal voltage reference in mV */
52 struct regulator *vref; member
61 reg = MCP3911_REG_READ(reg, adc->dev_addr); in mcp3911_read()
62 ret = spi_write_then_read(adc->spi, ®, 1, val, len); in mcp3911_read()
67 *val >>= ((4 - len) * 8); in mcp3911_read()
68 dev_dbg(&adc->spi->dev, "reading 0x%x from register 0x%x\n", *val, in mcp3911_read()
75 dev_dbg(&adc->spi->dev, "writing 0x%x to register 0x%x\n", val, reg); in mcp3911_write()
77 val <<= (3 - len) * 8; in mcp3911_write()
79 val |= MCP3911_REG_WRITE(reg, adc->dev_addr); in mcp3911_write()
81 return spi_write(adc->spi, &val, len + 1); in mcp3911_write()
104 int ret = -EINVAL; in mcp3911_read_raw()
106 mutex_lock(&adc->lock); in mcp3911_read_raw()
110 MCP3911_CHANNEL(channel->channel), val, 3); in mcp3911_read_raw()
121 MCP3911_OFFCAL(channel->channel), val, 3); in mcp3911_read_raw()
129 if (adc->vref) { in mcp3911_read_raw()
130 ret = regulator_get_voltage(adc->vref); in mcp3911_read_raw()
132 dev_err(indio_dev->dev.parent, in mcp3911_read_raw()
133 "failed to get vref voltage: %d\n", in mcp3911_read_raw()
145 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5 in mcp3911_read_raw()
146 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5) in mcp3911_read_raw()
156 mutex_unlock(&adc->lock); in mcp3911_read_raw()
165 int ret = -EINVAL; in mcp3911_write_raw()
167 mutex_lock(&adc->lock); in mcp3911_write_raw()
171 ret = -EINVAL; in mcp3911_write_raw()
176 ret = mcp3911_write(adc, MCP3911_OFFCAL(channel->channel), val, in mcp3911_write_raw()
189 mutex_unlock(&adc->lock); in mcp3911_write_raw()
217 of_property_read_u32(of_node, "device-addr", &adc->dev_addr); in mcp3911_config()
218 if (adc->dev_addr > 3) { in mcp3911_config()
219 dev_err(&adc->spi->dev, in mcp3911_config()
220 "invalid device address (%i). Must be in range 0-3.\n", in mcp3911_config()
221 adc->dev_addr); in mcp3911_config()
222 return -EINVAL; in mcp3911_config()
224 dev_dbg(&adc->spi->dev, "use device address %i\n", adc->dev_addr); in mcp3911_config()
230 if (adc->vref) { in mcp3911_config()
231 dev_dbg(&adc->spi->dev, "use external voltage reference\n"); in mcp3911_config()
234 dev_dbg(&adc->spi->dev, in mcp3911_config()
235 "use internal voltage reference (1.2V)\n"); in mcp3911_config()
239 if (adc->clki) { in mcp3911_config()
240 dev_dbg(&adc->spi->dev, "use external clock as clocksource\n"); in mcp3911_config()
243 dev_dbg(&adc->spi->dev, in mcp3911_config()
257 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); in mcp3911_probe()
259 return -ENOMEM; in mcp3911_probe()
262 adc->spi = spi; in mcp3911_probe()
264 adc->vref = devm_regulator_get_optional(&adc->spi->dev, "vref"); in mcp3911_probe()
265 if (IS_ERR(adc->vref)) { in mcp3911_probe()
266 if (PTR_ERR(adc->vref) == -ENODEV) { in mcp3911_probe()
267 adc->vref = NULL; in mcp3911_probe()
269 dev_err(&adc->spi->dev, in mcp3911_probe()
271 PTR_ERR(adc->vref)); in mcp3911_probe()
272 return PTR_ERR(adc->vref); in mcp3911_probe()
276 ret = regulator_enable(adc->vref); in mcp3911_probe()
281 adc->clki = devm_clk_get(&adc->spi->dev, NULL); in mcp3911_probe()
282 if (IS_ERR(adc->clki)) { in mcp3911_probe()
283 if (PTR_ERR(adc->clki) == -ENOENT) { in mcp3911_probe()
284 adc->clki = NULL; in mcp3911_probe()
286 dev_err(&adc->spi->dev, in mcp3911_probe()
288 PTR_ERR(adc->clki)); in mcp3911_probe()
289 ret = PTR_ERR(adc->clki); in mcp3911_probe()
293 ret = clk_prepare_enable(adc->clki); in mcp3911_probe()
295 dev_err(&adc->spi->dev, in mcp3911_probe()
301 ret = mcp3911_config(adc, spi->dev.of_node); in mcp3911_probe()
305 indio_dev->name = spi_get_device_id(spi)->name; in mcp3911_probe()
306 indio_dev->modes = INDIO_DIRECT_MODE; in mcp3911_probe()
307 indio_dev->info = &mcp3911_info; in mcp3911_probe()
310 indio_dev->channels = mcp3911_channels; in mcp3911_probe()
311 indio_dev->num_channels = ARRAY_SIZE(mcp3911_channels); in mcp3911_probe()
313 mutex_init(&adc->lock); in mcp3911_probe()
322 clk_disable_unprepare(adc->clki); in mcp3911_probe()
324 if (adc->vref) in mcp3911_probe()
325 regulator_disable(adc->vref); in mcp3911_probe()
337 clk_disable_unprepare(adc->clki); in mcp3911_remove()
338 if (adc->vref) in mcp3911_remove()
339 regulator_disable(adc->vref); in mcp3911_remove()