brintos

brintos / linux-shallow public Read only

0
0
Text · 11.3 KiB · edd0c3a Raw
443 lines · c
1// SPDX-License-Identifier: GPL-2.02/* ad7949.c - Analog Devices ADC driver 14/16 bits 4/8 channels3 *4 * Copyright (C) 2018 CMC NV5 *6 * https://www.analog.com/media/en/technical-documentation/data-sheets/AD7949.pdf7 */8 9#include <linux/delay.h>10#include <linux/iio/iio.h>11#include <linux/module.h>12#include <linux/regulator/consumer.h>13#include <linux/spi/spi.h>14#include <linux/bitfield.h>15 16#define AD7949_CFG_MASK_TOTAL		GENMASK(13, 0)17 18/* CFG: Configuration Update */19#define AD7949_CFG_MASK_OVERWRITE	BIT(13)20 21/* INCC: Input Channel Configuration */22#define AD7949_CFG_MASK_INCC		GENMASK(12, 10)23#define AD7949_CFG_VAL_INCC_UNIPOLAR_GND	724#define AD7949_CFG_VAL_INCC_UNIPOLAR_COMM	625#define AD7949_CFG_VAL_INCC_UNIPOLAR_DIFF	426#define AD7949_CFG_VAL_INCC_TEMP		327#define AD7949_CFG_VAL_INCC_BIPOLAR		228#define AD7949_CFG_VAL_INCC_BIPOLAR_DIFF	029 30/* INX: Input channel Selection in a binary fashion */31#define AD7949_CFG_MASK_INX		GENMASK(9, 7)32 33/* BW: select bandwidth for low-pass filter. Full or Quarter */34#define AD7949_CFG_MASK_BW_FULL		BIT(6)35 36/* REF: reference/buffer selection */37#define AD7949_CFG_MASK_REF		GENMASK(5, 3)38#define AD7949_CFG_VAL_REF_EXT_TEMP_BUF		339#define AD7949_CFG_VAL_REF_EXT_TEMP		240#define AD7949_CFG_VAL_REF_INT_4096		141#define AD7949_CFG_VAL_REF_INT_2500		042#define AD7949_CFG_VAL_REF_EXTERNAL		BIT(1)43 44/* SEQ: channel sequencer. Allows for scanning channels */45#define AD7949_CFG_MASK_SEQ		GENMASK(2, 1)46 47/* RB: Read back the CFG register */48#define AD7949_CFG_MASK_RBN		BIT(0)49 50enum {51	ID_AD7949 = 0,52	ID_AD7682,53	ID_AD7689,54};55 56struct ad7949_adc_spec {57	u8 num_channels;58	u8 resolution;59};60 61static const struct ad7949_adc_spec ad7949_adc_spec[] = {62	[ID_AD7949] = { .num_channels = 8, .resolution = 14 },63	[ID_AD7682] = { .num_channels = 4, .resolution = 16 },64	[ID_AD7689] = { .num_channels = 8, .resolution = 16 },65};66 67/**68 * struct ad7949_adc_chip - AD ADC chip69 * @lock: protects write sequences70 * @vref: regulator generating Vref71 * @indio_dev: reference to iio structure72 * @spi: reference to spi structure73 * @refsel: reference selection74 * @resolution: resolution of the chip75 * @cfg: copy of the configuration register76 * @current_channel: current channel in use77 * @buffer: buffer to send / receive data to / from device78 * @buf8b: be16 buffer to exchange data with the device in 8-bit transfers79 */80struct ad7949_adc_chip {81	struct mutex lock;82	struct regulator *vref;83	struct iio_dev *indio_dev;84	struct spi_device *spi;85	u32 refsel;86	u8 resolution;87	u16 cfg;88	unsigned int current_channel;89	u16 buffer __aligned(IIO_DMA_MINALIGN);90	__be16 buf8b;91};92 93static int ad7949_spi_write_cfg(struct ad7949_adc_chip *ad7949_adc, u16 val,94				u16 mask)95{96	int ret;97 98	ad7949_adc->cfg = (val & mask) | (ad7949_adc->cfg & ~mask);99 100	switch (ad7949_adc->spi->bits_per_word) {101	case 16:102		ad7949_adc->buffer = ad7949_adc->cfg << 2;103		ret = spi_write(ad7949_adc->spi, &ad7949_adc->buffer, 2);104		break;105	case 14:106		ad7949_adc->buffer = ad7949_adc->cfg;107		ret = spi_write(ad7949_adc->spi, &ad7949_adc->buffer, 2);108		break;109	case 8:110		/* Here, type is big endian as it must be sent in two transfers */111		ad7949_adc->buf8b = cpu_to_be16(ad7949_adc->cfg << 2);112		ret = spi_write(ad7949_adc->spi, &ad7949_adc->buf8b, 2);113		break;114	default:115		dev_err(&ad7949_adc->indio_dev->dev, "unsupported BPW\n");116		return -EINVAL;117	}118 119	/*120	 * This delay is to avoid a new request before the required time to121	 * send a new command to the device122	 */123	udelay(2);124	return ret;125}126 127static int ad7949_spi_read_channel(struct ad7949_adc_chip *ad7949_adc, int *val,128				   unsigned int channel)129{130	int ret;131	int i;132 133	/*134	 * 1: write CFG for sample N and read old data (sample N-2)135	 * 2: if CFG was not changed since sample N-1 then we'll get good data136	 *    at the next xfer, so we bail out now, otherwise we write something137	 *    and we read garbage (sample N-1 configuration).138	 */139	for (i = 0; i < 2; i++) {140		ret = ad7949_spi_write_cfg(ad7949_adc,141					   FIELD_PREP(AD7949_CFG_MASK_INX, channel),142					   AD7949_CFG_MASK_INX);143		if (ret)144			return ret;145		if (channel == ad7949_adc->current_channel)146			break;147	}148 149	/* 3: write something and read actual data */150	if (ad7949_adc->spi->bits_per_word == 8)151		ret = spi_read(ad7949_adc->spi, &ad7949_adc->buf8b, 2);152	else153		ret = spi_read(ad7949_adc->spi, &ad7949_adc->buffer, 2);154 155	if (ret)156		return ret;157 158	/*159	 * This delay is to avoid a new request before the required time to160	 * send a new command to the device161	 */162	udelay(2);163 164	ad7949_adc->current_channel = channel;165 166	switch (ad7949_adc->spi->bits_per_word) {167	case 16:168		*val = ad7949_adc->buffer;169		/* Shift-out padding bits */170		*val >>= 16 - ad7949_adc->resolution;171		break;172	case 14:173		*val = ad7949_adc->buffer & GENMASK(13, 0);174		break;175	case 8:176		/* Here, type is big endian as data was sent in two transfers */177		*val = be16_to_cpu(ad7949_adc->buf8b);178		/* Shift-out padding bits */179		*val >>= 16 - ad7949_adc->resolution;180		break;181	default:182		dev_err(&ad7949_adc->indio_dev->dev, "unsupported BPW\n");183		return -EINVAL;184	}185 186	return 0;187}188 189#define AD7949_ADC_CHANNEL(chan) {				\190	.type = IIO_VOLTAGE,					\191	.indexed = 1,						\192	.channel = (chan),					\193	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\194	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\195}196 197static const struct iio_chan_spec ad7949_adc_channels[] = {198	AD7949_ADC_CHANNEL(0),199	AD7949_ADC_CHANNEL(1),200	AD7949_ADC_CHANNEL(2),201	AD7949_ADC_CHANNEL(3),202	AD7949_ADC_CHANNEL(4),203	AD7949_ADC_CHANNEL(5),204	AD7949_ADC_CHANNEL(6),205	AD7949_ADC_CHANNEL(7),206};207 208static int ad7949_spi_read_raw(struct iio_dev *indio_dev,209			   struct iio_chan_spec const *chan,210			   int *val, int *val2, long mask)211{212	struct ad7949_adc_chip *ad7949_adc = iio_priv(indio_dev);213	int ret;214 215	if (!val)216		return -EINVAL;217 218	switch (mask) {219	case IIO_CHAN_INFO_RAW:220		mutex_lock(&ad7949_adc->lock);221		ret = ad7949_spi_read_channel(ad7949_adc, val, chan->channel);222		mutex_unlock(&ad7949_adc->lock);223 224		if (ret < 0)225			return ret;226 227		return IIO_VAL_INT;228 229	case IIO_CHAN_INFO_SCALE:230		switch (ad7949_adc->refsel) {231		case AD7949_CFG_VAL_REF_INT_2500:232			*val = 2500;233			break;234		case AD7949_CFG_VAL_REF_INT_4096:235			*val = 4096;236			break;237		case AD7949_CFG_VAL_REF_EXT_TEMP:238		case AD7949_CFG_VAL_REF_EXT_TEMP_BUF:239			ret = regulator_get_voltage(ad7949_adc->vref);240			if (ret < 0)241				return ret;242 243			/* convert value back to mV */244			*val = ret / 1000;245			break;246		}247 248		*val2 = (1 << ad7949_adc->resolution) - 1;249		return IIO_VAL_FRACTIONAL;250	}251 252	return -EINVAL;253}254 255static int ad7949_spi_reg_access(struct iio_dev *indio_dev,256			unsigned int reg, unsigned int writeval,257			unsigned int *readval)258{259	struct ad7949_adc_chip *ad7949_adc = iio_priv(indio_dev);260	int ret = 0;261 262	if (readval)263		*readval = ad7949_adc->cfg;264	else265		ret = ad7949_spi_write_cfg(ad7949_adc, writeval,266					   AD7949_CFG_MASK_TOTAL);267 268	return ret;269}270 271static const struct iio_info ad7949_spi_info = {272	.read_raw = ad7949_spi_read_raw,273	.debugfs_reg_access = ad7949_spi_reg_access,274};275 276static int ad7949_spi_init(struct ad7949_adc_chip *ad7949_adc)277{278	int ret;279	int val;280	u16 cfg;281 282	ad7949_adc->current_channel = 0;283 284	cfg = FIELD_PREP(AD7949_CFG_MASK_OVERWRITE, 1) |285		FIELD_PREP(AD7949_CFG_MASK_INCC, AD7949_CFG_VAL_INCC_UNIPOLAR_GND) |286		FIELD_PREP(AD7949_CFG_MASK_INX, ad7949_adc->current_channel) |287		FIELD_PREP(AD7949_CFG_MASK_BW_FULL, 1) |288		FIELD_PREP(AD7949_CFG_MASK_REF, ad7949_adc->refsel) |289		FIELD_PREP(AD7949_CFG_MASK_SEQ, 0x0) |290		FIELD_PREP(AD7949_CFG_MASK_RBN, 1);291 292	ret = ad7949_spi_write_cfg(ad7949_adc, cfg, AD7949_CFG_MASK_TOTAL);293 294	/*295	 * Do two dummy conversions to apply the first configuration setting.296	 * Required only after the start up of the device.297	 */298	ad7949_spi_read_channel(ad7949_adc, &val, ad7949_adc->current_channel);299	ad7949_spi_read_channel(ad7949_adc, &val, ad7949_adc->current_channel);300 301	return ret;302}303 304static void ad7949_disable_reg(void *reg)305{306	regulator_disable(reg);307}308 309static int ad7949_spi_probe(struct spi_device *spi)310{311	u32 spi_ctrl_mask = spi->controller->bits_per_word_mask;312	struct device *dev = &spi->dev;313	const struct ad7949_adc_spec *spec;314	struct ad7949_adc_chip *ad7949_adc;315	struct iio_dev *indio_dev;316	u32 tmp;317	int ret;318 319	indio_dev = devm_iio_device_alloc(dev, sizeof(*ad7949_adc));320	if (!indio_dev) {321		dev_err(dev, "can not allocate iio device\n");322		return -ENOMEM;323	}324 325	indio_dev->info = &ad7949_spi_info;326	indio_dev->name = spi_get_device_id(spi)->name;327	indio_dev->modes = INDIO_DIRECT_MODE;328	indio_dev->channels = ad7949_adc_channels;329	spi_set_drvdata(spi, indio_dev);330 331	ad7949_adc = iio_priv(indio_dev);332	ad7949_adc->indio_dev = indio_dev;333	ad7949_adc->spi = spi;334 335	spec = &ad7949_adc_spec[spi_get_device_id(spi)->driver_data];336	indio_dev->num_channels = spec->num_channels;337	ad7949_adc->resolution = spec->resolution;338 339	/* Set SPI bits per word */340	if (spi_ctrl_mask & SPI_BPW_MASK(ad7949_adc->resolution)) {341		spi->bits_per_word = ad7949_adc->resolution;342	} else if (spi_ctrl_mask == SPI_BPW_MASK(16)) {343		spi->bits_per_word = 16;344	} else if (spi_ctrl_mask == SPI_BPW_MASK(8)) {345		spi->bits_per_word = 8;346	} else {347		dev_err(dev, "unable to find common BPW with spi controller\n");348		return -EINVAL;349	}350 351	/* Setup internal voltage reference */352	tmp = 4096000;353	device_property_read_u32(dev, "adi,internal-ref-microvolt", &tmp);354 355	switch (tmp) {356	case 2500000:357		ad7949_adc->refsel = AD7949_CFG_VAL_REF_INT_2500;358		break;359	case 4096000:360		ad7949_adc->refsel = AD7949_CFG_VAL_REF_INT_4096;361		break;362	default:363		dev_err(dev, "unsupported internal voltage reference\n");364		return -EINVAL;365	}366 367	/* Setup external voltage reference, buffered? */368	ad7949_adc->vref = devm_regulator_get_optional(dev, "vrefin");369	if (IS_ERR(ad7949_adc->vref)) {370		ret = PTR_ERR(ad7949_adc->vref);371		if (ret != -ENODEV)372			return ret;373		/* unbuffered? */374		ad7949_adc->vref = devm_regulator_get_optional(dev, "vref");375		if (IS_ERR(ad7949_adc->vref)) {376			ret = PTR_ERR(ad7949_adc->vref);377			if (ret != -ENODEV)378				return ret;379		} else {380			ad7949_adc->refsel = AD7949_CFG_VAL_REF_EXT_TEMP;381		}382	} else {383		ad7949_adc->refsel = AD7949_CFG_VAL_REF_EXT_TEMP_BUF;384	}385 386	if (ad7949_adc->refsel & AD7949_CFG_VAL_REF_EXTERNAL) {387		ret = regulator_enable(ad7949_adc->vref);388		if (ret < 0) {389			dev_err(dev, "fail to enable regulator\n");390			return ret;391		}392 393		ret = devm_add_action_or_reset(dev, ad7949_disable_reg,394					       ad7949_adc->vref);395		if (ret)396			return ret;397	}398 399	mutex_init(&ad7949_adc->lock);400 401	ret = ad7949_spi_init(ad7949_adc);402	if (ret) {403		dev_err(dev, "fail to init this device: %d\n", ret);404		return ret;405	}406 407	ret = devm_iio_device_register(dev, indio_dev);408	if (ret)409		dev_err(dev, "fail to register iio device: %d\n", ret);410 411	return ret;412}413 414static const struct of_device_id ad7949_spi_of_id[] = {415	{ .compatible = "adi,ad7949" },416	{ .compatible = "adi,ad7682" },417	{ .compatible = "adi,ad7689" },418	{ }419};420MODULE_DEVICE_TABLE(of, ad7949_spi_of_id);421 422static const struct spi_device_id ad7949_spi_id[] = {423	{ "ad7949", ID_AD7949  },424	{ "ad7682", ID_AD7682 },425	{ "ad7689", ID_AD7689 },426	{ }427};428MODULE_DEVICE_TABLE(spi, ad7949_spi_id);429 430static struct spi_driver ad7949_spi_driver = {431	.driver = {432		.name		= "ad7949",433		.of_match_table	= ad7949_spi_of_id,434	},435	.probe	  = ad7949_spi_probe,436	.id_table = ad7949_spi_id,437};438module_spi_driver(ad7949_spi_driver);439 440MODULE_AUTHOR("Charles-Antoine Couret <charles-antoine.couret@essensium.com>");441MODULE_DESCRIPTION("Analog Devices 14/16-bit 8-channel ADC driver");442MODULE_LICENSE("GPL v2");443