File Index
Files and directories
Sign in
FILE

ltc2496.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/adc/ltc2496.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * ltc2496.c - Driver for Analog Devices/Linear Technology LTC2496 ADC
  4 *
  5 * Based on ltc2497.c which has
  6 * Copyright (C) 2017 Analog Devices Inc.
  7 *
  8 * Licensed under the GPL-2.
  9 *
 10 * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/2496fc.pdf
 11 */
 12
 13#include <linux/spi/spi.h>
 14#include <linux/iio/iio.h>
 15#include <linux/iio/driver.h>
 16#include <linux/module.h>
 17#include <linux/mod_devicetable.h>
 18#include <linux/property.h>
 19
 20#include "ltc2497.h"
 21
 22struct ltc2496_driverdata {
 23	/* this must be the first member */
 24	struct ltc2497core_driverdata common_ddata;
 25	struct spi_device *spi;
 26
 27	/*
 28	 * DMA (thus cache coherency maintenance) may require the
 29	 * transfer buffers to live in their own cache lines.
 30	 */
 31	unsigned char rxbuf[3] __aligned(IIO_DMA_MINALIGN);
 32	unsigned char txbuf[3];
 33};
 34
 35static int ltc2496_result_and_measure(struct ltc2497core_driverdata *ddata,
 36				      u8 address, int *val)
 37{
 38	struct ltc2496_driverdata *st =
 39		container_of(ddata, struct ltc2496_driverdata, common_ddata);
 40	struct spi_transfer t = {
 41		.tx_buf = st->txbuf,
 42		.rx_buf = st->rxbuf,
 43		.len = sizeof(st->txbuf),
 44	};
 45	int ret;
 46
 47	st->txbuf[0] = LTC2497_ENABLE | address;
 48
 49	ret = spi_sync_transfer(st->spi, &t, 1);
 50	if (ret < 0)  {
 51		dev_err(&st->spi->dev, "spi_sync_transfer failed: %pe\n",
 52			ERR_PTR(ret));
 53		return ret;
 54	}
 55
 56	if (val)
 57		*val = ((st->rxbuf[0] & 0x3f) << 12 |
 58			st->rxbuf[1] << 4 | st->rxbuf[2] >> 4) -
 59			(1 << 17);
 60
 61	return 0;
 62}
 63
 64static int ltc2496_probe(struct spi_device *spi)
 65{
 66	struct iio_dev *indio_dev;
 67	struct ltc2496_driverdata *st;
 68	struct device *dev = &spi->dev;
 69
 70	indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
 71	if (!indio_dev)
 72		return -ENOMEM;
 73
 74	st = iio_priv(indio_dev);
 75	spi_set_drvdata(spi, indio_dev);
 76	st->spi = spi;
 77	st->common_ddata.result_and_measure = ltc2496_result_and_measure;
 78	st->common_ddata.chip_info = device_get_match_data(dev);
 79
 80	return ltc2497core_probe(dev, indio_dev);
 81}
 82
 83static void ltc2496_remove(struct spi_device *spi)
 84{
 85	struct iio_dev *indio_dev = spi_get_drvdata(spi);
 86
 87	ltc2497core_remove(indio_dev);
 88}
 89
 90static const struct ltc2497_chip_info ltc2496_info = {
 91	.resolution = 16,
 92	.name = NULL,
 93};
 94
 95static const struct of_device_id ltc2496_of_match[] = {
 96	{ .compatible = "lltc,ltc2496", .data = &ltc2496_info, },
 97	{ }
 98};
 99MODULE_DEVICE_TABLE(of, ltc2496_of_match);
100
101static struct spi_driver ltc2496_driver = {
102	.driver = {
103		.name = "ltc2496",
104		.of_match_table = ltc2496_of_match,
105	},
106	.probe = ltc2496_probe,
107	.remove = ltc2496_remove,
108};
109module_spi_driver(ltc2496_driver);
110
111MODULE_AUTHOR("Uwe Kleine-König <u.kleine-könig@pengutronix.de>");
112MODULE_DESCRIPTION("Linear Technology LTC2496 ADC driver");
113MODULE_LICENSE("GPL v2");
~/ Read-only file preview.