Lines Matching +full:adc +full:- +full:vref

1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for Microchip MCP3911, Two-channel Analog Front End
73 struct regulator *vref; member
87 static int mcp3911_read(struct mcp3911 *adc, u8 reg, u32 *val, u8 len) in mcp3911_read() argument
91 reg = MCP3911_REG_READ(reg, adc->dev_addr); in mcp3911_read()
92 ret = spi_write_then_read(adc->spi, &reg, 1, val, len); in mcp3911_read()
97 *val >>= ((4 - len) * 8); in mcp3911_read()
98 dev_dbg(&adc->spi->dev, "reading 0x%x from register 0x%lx\n", *val, in mcp3911_read()
103 static int mcp3911_write(struct mcp3911 *adc, u8 reg, u32 val, u8 len) in mcp3911_write() argument
105 dev_dbg(&adc->spi->dev, "writing 0x%x to register 0x%x\n", val, reg); in mcp3911_write()
107 val <<= (3 - len) * 8; in mcp3911_write()
109 val |= MCP3911_REG_WRITE(reg, adc->dev_addr); in mcp3911_write()
111 return spi_write(adc->spi, &val, len + 1); in mcp3911_write()
114 static int mcp3911_update(struct mcp3911 *adc, u8 reg, u32 mask, in mcp3911_update() argument
120 ret = mcp3911_read(adc, reg, &tmp, len); in mcp3911_update()
126 return mcp3911_write(adc, reg, val, len); in mcp3911_update()
160 return -EINVAL; in mcp3911_read_avail()
168 struct mcp3911 *adc = iio_priv(indio_dev); in mcp3911_read_raw() local
169 int ret = -EINVAL; in mcp3911_read_raw()
171 mutex_lock(&adc->lock); in mcp3911_read_raw()
174 ret = mcp3911_read(adc, in mcp3911_read_raw()
175 MCP3911_CHANNEL(channel->channel), val, 3); in mcp3911_read_raw()
185 ret = mcp3911_read(adc, in mcp3911_read_raw()
186 MCP3911_OFFCAL(channel->channel), val, 3); in mcp3911_read_raw()
193 ret = mcp3911_read(adc, MCP3911_REG_CONFIG, val, 2); in mcp3911_read_raw()
203 *val = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][0]; in mcp3911_read_raw()
204 *val2 = mcp3911_scale_table[ilog2(adc->gain[channel->channel])][1]; in mcp3911_read_raw()
210 mutex_unlock(&adc->lock); in mcp3911_read_raw()
218 struct mcp3911 *adc = iio_priv(indio_dev); in mcp3911_write_raw() local
219 int ret = -EINVAL; in mcp3911_write_raw()
221 mutex_lock(&adc->lock); in mcp3911_write_raw()
228 adc->gain[channel->channel] = BIT(i); in mcp3911_write_raw()
229 ret = mcp3911_update(adc, MCP3911_REG_GAIN, in mcp3911_write_raw()
230 MCP3911_GAIN_MASK(channel->channel), in mcp3911_write_raw()
231 MCP3911_GAIN_VAL(channel->channel, i), 1); in mcp3911_write_raw()
237 ret = -EINVAL; in mcp3911_write_raw()
242 ret = mcp3911_write(adc, MCP3911_OFFCAL(channel->channel), val, in mcp3911_write_raw()
248 ret = mcp3911_update(adc, MCP3911_REG_STATUSCOM, in mcp3911_write_raw()
257 ret = mcp3911_update(adc, MCP3911_REG_CONFIG, MCP3911_CONFIG_OSR, in mcp3911_write_raw()
266 mutex_unlock(&adc->lock); in mcp3911_write_raw()
270 static int mcp3911_calc_scale_table(struct mcp3911 *adc) in mcp3911_calc_scale_table() argument
277 if (adc->vref) { in mcp3911_calc_scale_table()
278 ret = regulator_get_voltage(adc->vref); in mcp3911_calc_scale_table()
280 dev_err(&adc->spi->dev, in mcp3911_calc_scale_table()
281 "failed to get vref voltage: %d\n", in mcp3911_calc_scale_table()
290 * For 24-bit Conversion in mcp3911_calc_scale_table()
291 * Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5 in mcp3911_calc_scale_table()
292 * Voltage = Raw * (Vref)/(2^23 * Gain * 1.5) in mcp3911_calc_scale_table()
338 struct iio_dev *indio_dev = pf->indio_dev; in mcp3911_trigger_handler()
339 struct mcp3911 *adc = iio_priv(indio_dev); in mcp3911_trigger_handler() local
342 .tx_buf = &adc->tx_buf, in mcp3911_trigger_handler()
345 .rx_buf = adc->rx_buf, in mcp3911_trigger_handler()
346 .len = sizeof(adc->rx_buf), in mcp3911_trigger_handler()
353 mutex_lock(&adc->lock); in mcp3911_trigger_handler()
354 adc->tx_buf = MCP3911_REG_READ(MCP3911_CHANNEL(0), adc->dev_addr); in mcp3911_trigger_handler()
355 ret = spi_sync_transfer(adc->spi, xfer, ARRAY_SIZE(xfer)); in mcp3911_trigger_handler()
357 dev_warn(&adc->spi->dev, in mcp3911_trigger_handler()
362 for_each_set_bit(scan_index, indio_dev->active_scan_mask, indio_dev->masklength) { in mcp3911_trigger_handler()
363 const struct iio_chan_spec *scan_chan = &indio_dev->channels[scan_index]; in mcp3911_trigger_handler()
365 adc->scan.channels[i] = get_unaligned_be24(&adc->rx_buf[scan_chan->channel * 3]); in mcp3911_trigger_handler()
368 iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan, in mcp3911_trigger_handler()
371 mutex_unlock(&adc->lock); in mcp3911_trigger_handler()
372 iio_trigger_notify_done(indio_dev->trig); in mcp3911_trigger_handler()
384 static int mcp3911_config(struct mcp3911 *adc) in mcp3911_config() argument
386 struct device *dev = &adc->spi->dev; in mcp3911_config()
390 ret = device_property_read_u32(dev, "microchip,device-addr", &adc->dev_addr); in mcp3911_config()
393 * Fallback to "device-addr" due to historical mismatch between in mcp3911_config()
394 * dt-bindings and implementation in mcp3911_config()
397 device_property_read_u32(dev, "device-addr", &adc->dev_addr); in mcp3911_config()
398 if (adc->dev_addr > 3) { in mcp3911_config()
399 dev_err(&adc->spi->dev, in mcp3911_config()
400 "invalid device address (%i). Must be in range 0-3.\n", in mcp3911_config()
401 adc->dev_addr); in mcp3911_config()
402 return -EINVAL; in mcp3911_config()
404 dev_dbg(&adc->spi->dev, "use device address %i\n", adc->dev_addr); in mcp3911_config()
406 ret = mcp3911_read(adc, MCP3911_REG_CONFIG, &regval, 2); in mcp3911_config()
411 if (adc->vref) { in mcp3911_config()
412 dev_dbg(&adc->spi->dev, "use external voltage reference\n"); in mcp3911_config()
415 dev_dbg(&adc->spi->dev, in mcp3911_config()
421 if (adc->clki) { in mcp3911_config()
422 dev_dbg(&adc->spi->dev, "use external clock as clocksource\n"); in mcp3911_config()
425 dev_dbg(&adc->spi->dev, in mcp3911_config()
430 ret = mcp3911_write(adc, MCP3911_REG_CONFIG, regval, 2); in mcp3911_config()
434 ret = mcp3911_read(adc, MCP3911_REG_STATUSCOM, &regval, 2); in mcp3911_config()
442 return mcp3911_write(adc, MCP3911_REG_STATUSCOM, regval, 2); in mcp3911_config()
445 static void mcp3911_cleanup_regulator(void *vref) in mcp3911_cleanup_regulator() argument
447 regulator_disable(vref); in mcp3911_cleanup_regulator()
452 struct mcp3911 *adc = iio_trigger_get_drvdata(trig); in mcp3911_set_trigger_state() local
455 enable_irq(adc->spi->irq); in mcp3911_set_trigger_state()
457 disable_irq(adc->spi->irq); in mcp3911_set_trigger_state()
470 struct mcp3911 *adc; in mcp3911_probe() local
473 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc)); in mcp3911_probe()
475 return -ENOMEM; in mcp3911_probe()
477 adc = iio_priv(indio_dev); in mcp3911_probe()
478 adc->spi = spi; in mcp3911_probe()
480 adc->vref = devm_regulator_get_optional(&adc->spi->dev, "vref"); in mcp3911_probe()
481 if (IS_ERR(adc->vref)) { in mcp3911_probe()
482 if (PTR_ERR(adc->vref) == -ENODEV) { in mcp3911_probe()
483 adc->vref = NULL; in mcp3911_probe()
485 dev_err(&adc->spi->dev, in mcp3911_probe()
487 PTR_ERR(adc->vref)); in mcp3911_probe()
488 return PTR_ERR(adc->vref); in mcp3911_probe()
492 ret = regulator_enable(adc->vref); in mcp3911_probe()
496 ret = devm_add_action_or_reset(&spi->dev, in mcp3911_probe()
497 mcp3911_cleanup_regulator, adc->vref); in mcp3911_probe()
502 adc->clki = devm_clk_get_enabled(&adc->spi->dev, NULL); in mcp3911_probe()
503 if (IS_ERR(adc->clki)) { in mcp3911_probe()
504 if (PTR_ERR(adc->clki) == -ENOENT) { in mcp3911_probe()
505 adc->clki = NULL; in mcp3911_probe()
507 dev_err(&adc->spi->dev, in mcp3911_probe()
508 "failed to get adc clk (%ld)\n", in mcp3911_probe()
509 PTR_ERR(adc->clki)); in mcp3911_probe()
510 return PTR_ERR(adc->clki); in mcp3911_probe()
514 ret = mcp3911_config(adc); in mcp3911_probe()
518 if (device_property_read_bool(&adc->spi->dev, "microchip,data-ready-hiz")) in mcp3911_probe()
519 ret = mcp3911_update(adc, MCP3911_REG_STATUSCOM, MCP3911_STATUSCOM_DRHIZ, in mcp3911_probe()
522 ret = mcp3911_update(adc, MCP3911_REG_STATUSCOM, MCP3911_STATUSCOM_DRHIZ, in mcp3911_probe()
527 ret = mcp3911_calc_scale_table(adc); in mcp3911_probe()
533 adc->gain[i] = 1; in mcp3911_probe()
534 ret = mcp3911_update(adc, MCP3911_REG_GAIN, in mcp3911_probe()
541 indio_dev->name = spi_get_device_id(spi)->name; in mcp3911_probe()
542 indio_dev->modes = INDIO_DIRECT_MODE; in mcp3911_probe()
543 indio_dev->info = &mcp3911_info; in mcp3911_probe()
546 indio_dev->channels = mcp3911_channels; in mcp3911_probe()
547 indio_dev->num_channels = ARRAY_SIZE(mcp3911_channels); in mcp3911_probe()
549 mutex_init(&adc->lock); in mcp3911_probe()
551 if (spi->irq > 0) { in mcp3911_probe()
552 adc->trig = devm_iio_trigger_alloc(&spi->dev, "%s-dev%d", in mcp3911_probe()
553 indio_dev->name, in mcp3911_probe()
555 if (!adc->trig) in mcp3911_probe()
556 return -ENOMEM; in mcp3911_probe()
558 adc->trig->ops = &mcp3911_trigger_ops; in mcp3911_probe()
559 iio_trigger_set_drvdata(adc->trig, adc); in mcp3911_probe()
560 ret = devm_iio_trigger_register(&spi->dev, adc->trig); in mcp3911_probe()
569 ret = devm_request_irq(&spi->dev, spi->irq, in mcp3911_probe()
571 indio_dev->name, adc->trig); in mcp3911_probe()
576 ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, in mcp3911_probe()
582 return devm_iio_device_register(&adc->spi->dev, indio_dev); in mcp3911_probe()