Lines Matching +full:adc +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Analog Devices AD9467 SPI ADC driver
5 * Copyright 2012-2020 Analog Devices Inc.
24 #include <linux/clk.h>
27 * ADI High-Speed ADC common spi interface registers
28 * See Application-Note AN-877:
29 * https://www.analog.com/media/en/technical-documentation/application-notes/AN-877.pdf
80 * Analog Devices AD9265 16-Bit, 125/105/80 MSPS ADC
88 * Analog Devices AD9434 12-Bit, 370/500 MSPS ADC
96 * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC
119 struct clk *clk; member
162 struct spi_device *spi = st->spi; in ad9467_reg_access()
166 guard(mutex)(&st->lock); in ad9467_reg_access()
201 const struct ad9467_chip_info *info = st->info; in __ad9467_get_scale()
202 const struct iio_chan_spec *chan = &info->channels[0]; in __ad9467_get_scale()
205 tmp = (info->scale_table[index][0] * 1000000ULL) >> in __ad9467_get_scale()
206 chan->scan_type.realbits; in __ad9467_get_scale()
273 const struct ad9467_chip_info *info = st->info; in ad9467_get_scale()
277 ret = ad9467_spi_read(st->spi, AN877_ADC_REG_VREF); in ad9467_get_scale()
281 vref_val = ret & info->vref_mask; in ad9467_get_scale()
283 for (i = 0; i < info->num_scales; i++) { in ad9467_get_scale()
284 if (vref_val == info->scale_table[i][1]) in ad9467_get_scale()
288 if (i == info->num_scales) in ad9467_get_scale()
289 return -ERANGE; in ad9467_get_scale()
298 const struct ad9467_chip_info *info = st->info; in ad9467_set_scale()
304 return -EINVAL; in ad9467_set_scale()
306 for (i = 0; i < info->num_scales; i++) { in ad9467_set_scale()
311 guard(mutex)(&st->lock); in ad9467_set_scale()
312 ret = ad9467_spi_write(st->spi, AN877_ADC_REG_VREF, in ad9467_set_scale()
313 info->scale_table[i][1]); in ad9467_set_scale()
317 return ad9467_spi_write(st->spi, AN877_ADC_REG_TRANSFER, in ad9467_set_scale()
321 return -EINVAL; in ad9467_set_scale()
334 *val = clk_get_rate(st->clk); in ad9467_read_raw()
338 return -EINVAL; in ad9467_read_raw()
347 const struct ad9467_chip_info *info = st->info; in ad9467_write_raw()
354 r_clk = clk_round_rate(st->clk, val); in ad9467_write_raw()
355 if (r_clk < 0 || r_clk > info->max_rate) { in ad9467_write_raw()
356 dev_warn(&st->spi->dev, in ad9467_write_raw()
357 "Error setting ADC sample rate %ld", r_clk); in ad9467_write_raw()
358 return -EINVAL; in ad9467_write_raw()
361 return clk_set_rate(st->clk, r_clk); in ad9467_write_raw()
363 return -EINVAL; in ad9467_write_raw()
373 const struct ad9467_chip_info *info = st->info; in ad9467_read_avail()
377 *vals = (const int *)st->scales; in ad9467_read_avail()
380 *length = info->num_scales * 2; in ad9467_read_avail()
383 return -EINVAL; in ad9467_read_avail()
394 for (c = 0; c < st->info->num_channels; c++) { in ad9467_update_scan_mode()
396 ret = iio_backend_chan_enable(st->back, c); in ad9467_update_scan_mode()
398 ret = iio_backend_chan_disable(st->back, c); in ad9467_update_scan_mode()
428 const struct ad9467_chip_info *info = st->info; in ad9467_scale_fill()
431 st->scales = devm_kmalloc_array(&st->spi->dev, info->num_scales, in ad9467_scale_fill()
432 sizeof(*st->scales), GFP_KERNEL); in ad9467_scale_fill()
433 if (!st->scales) in ad9467_scale_fill()
434 return -ENOMEM; in ad9467_scale_fill()
436 for (i = 0; i < info->num_scales; i++) { in ad9467_scale_fill()
438 st->scales[i][0] = val1; in ad9467_scale_fill()
439 st->scales[i][1] = val2; in ad9467_scale_fill()
454 mode = st->info->default_output_mode | AN877_ADC_OUTPUT_MODE_TWOS_COMPLEMENT; in ad9467_setup()
455 ret = ad9467_outputmode_set(st->spi, mode); in ad9467_setup()
459 for (c = 0; c < st->info->num_channels; c++) { in ad9467_setup()
460 ret = iio_backend_data_format_set(st->back, c, &data); in ad9467_setup()
485 struct device *dev = &st->spi->dev; in ad9467_iio_backend_get()
488 st->back = devm_iio_backend_get(dev, NULL); in ad9467_iio_backend_get()
489 if (!IS_ERR(st->back)) in ad9467_iio_backend_get()
492 if (PTR_ERR(st->back) != -ENOENT) in ad9467_iio_backend_get()
493 return PTR_ERR(st->back); in ad9467_iio_backend_get()
497 * 'adi,adc-dev' property. So we get all nodes with that property, and in ad9467_iio_backend_get()
500 * make io-backends mandatory which would break DT ABI. in ad9467_iio_backend_get()
502 for_each_node_with_property(__back, "adi,adc-dev") { in ad9467_iio_backend_get()
505 __me = of_parse_phandle(__back, "adi,adc-dev", 0); in ad9467_iio_backend_get()
515 st->back = __devm_iio_backend_get_from_fwnode_lookup(dev, in ad9467_iio_backend_get()
518 return PTR_ERR_OR_ZERO(st->back); in ad9467_iio_backend_get()
521 return -ENODEV; in ad9467_iio_backend_get()
531 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); in ad9467_probe()
533 return -ENOMEM; in ad9467_probe()
536 st->spi = spi; in ad9467_probe()
538 st->info = spi_get_device_match_data(spi); in ad9467_probe()
539 if (!st->info) in ad9467_probe()
540 return -ENODEV; in ad9467_probe()
542 st->clk = devm_clk_get_enabled(&spi->dev, "adc-clk"); in ad9467_probe()
543 if (IS_ERR(st->clk)) in ad9467_probe()
544 return PTR_ERR(st->clk); in ad9467_probe()
546 st->pwrdown_gpio = devm_gpiod_get_optional(&spi->dev, "powerdown", in ad9467_probe()
548 if (IS_ERR(st->pwrdown_gpio)) in ad9467_probe()
549 return PTR_ERR(st->pwrdown_gpio); in ad9467_probe()
551 ret = ad9467_reset(&spi->dev); in ad9467_probe()
560 if (id != st->info->id) { in ad9467_probe()
561 dev_err(&spi->dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n", in ad9467_probe()
562 id, st->info->id); in ad9467_probe()
563 return -ENODEV; in ad9467_probe()
566 indio_dev->name = st->info->name; in ad9467_probe()
567 indio_dev->channels = st->info->channels; in ad9467_probe()
568 indio_dev->num_channels = st->info->num_channels; in ad9467_probe()
569 indio_dev->info = &ad9467_info; in ad9467_probe()
575 ret = devm_iio_backend_request_buffer(&spi->dev, st->back, indio_dev); in ad9467_probe()
579 ret = devm_iio_backend_enable(&spi->dev, st->back); in ad9467_probe()
587 return devm_iio_device_register(&spi->dev, indio_dev); in ad9467_probe()
617 MODULE_DESCRIPTION("Analog Devices AD9467 ADC driver");