brintos

brintos / linux-shallow public Read only

0
0
Text · 12.0 KiB · 7949b07 Raw
478 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * AD7266/65 SPI ADC driver4 *5 * Copyright 2012 Analog Devices Inc.6 */7 8#include <linux/device.h>9#include <linux/kernel.h>10#include <linux/slab.h>11#include <linux/spi/spi.h>12#include <linux/regulator/consumer.h>13#include <linux/err.h>14#include <linux/gpio/consumer.h>15#include <linux/module.h>16 17#include <linux/interrupt.h>18 19#include <linux/iio/iio.h>20#include <linux/iio/buffer.h>21#include <linux/iio/trigger_consumer.h>22#include <linux/iio/triggered_buffer.h>23 24#include <linux/platform_data/ad7266.h>25 26#define AD7266_INTERNAL_REF_MV	250027 28struct ad7266_state {29	struct spi_device	*spi;30	unsigned long		vref_mv;31 32	struct spi_transfer	single_xfer[3];33	struct spi_message	single_msg;34 35	enum ad7266_range	range;36	enum ad7266_mode	mode;37	bool			fixed_addr;38	struct gpio_desc	*gpios[3];39 40	/*41	 * DMA (thus cache coherency maintenance) may require the42	 * transfer buffers to live in their own cache lines.43	 * The buffer needs to be large enough to hold two samples (4 bytes) and44	 * the naturally aligned timestamp (8 bytes).45	 */46	struct {47		__be16 sample[2];48		s64 timestamp;49	} data __aligned(IIO_DMA_MINALIGN);50};51 52static int ad7266_wakeup(struct ad7266_state *st)53{54	/* Any read with >= 2 bytes will wake the device */55	return spi_read(st->spi, &st->data.sample[0], 2);56}57 58static int ad7266_powerdown(struct ad7266_state *st)59{60	/* Any read with < 2 bytes will powerdown the device */61	return spi_read(st->spi, &st->data.sample[0], 1);62}63 64static int ad7266_preenable(struct iio_dev *indio_dev)65{66	struct ad7266_state *st = iio_priv(indio_dev);67	return ad7266_wakeup(st);68}69 70static int ad7266_postdisable(struct iio_dev *indio_dev)71{72	struct ad7266_state *st = iio_priv(indio_dev);73	return ad7266_powerdown(st);74}75 76static const struct iio_buffer_setup_ops iio_triggered_buffer_setup_ops = {77	.preenable = &ad7266_preenable,78	.postdisable = &ad7266_postdisable,79};80 81static irqreturn_t ad7266_trigger_handler(int irq, void *p)82{83	struct iio_poll_func *pf = p;84	struct iio_dev *indio_dev = pf->indio_dev;85	struct ad7266_state *st = iio_priv(indio_dev);86	int ret;87 88	ret = spi_read(st->spi, st->data.sample, 4);89	if (ret == 0) {90		iio_push_to_buffers_with_timestamp(indio_dev, &st->data,91			    pf->timestamp);92	}93 94	iio_trigger_notify_done(indio_dev->trig);95 96	return IRQ_HANDLED;97}98 99static void ad7266_select_input(struct ad7266_state *st, unsigned int nr)100{101	unsigned int i;102 103	if (st->fixed_addr)104		return;105 106	switch (st->mode) {107	case AD7266_MODE_SINGLE_ENDED:108		nr >>= 1;109		break;110	case AD7266_MODE_PSEUDO_DIFF:111		nr |= 1;112		break;113	case AD7266_MODE_DIFF:114		nr &= ~1;115		break;116	}117 118	for (i = 0; i < 3; ++i)119		gpiod_set_value(st->gpios[i], (bool)(nr & BIT(i)));120}121 122static int ad7266_update_scan_mode(struct iio_dev *indio_dev,123	const unsigned long *scan_mask)124{125	struct ad7266_state *st = iio_priv(indio_dev);126	unsigned int nr = find_first_bit(scan_mask,127					 iio_get_masklength(indio_dev));128 129	ad7266_select_input(st, nr);130 131	return 0;132}133 134static int ad7266_read_single(struct ad7266_state *st, int *val,135	unsigned int address)136{137	int ret;138 139	ad7266_select_input(st, address);140 141	ret = spi_sync(st->spi, &st->single_msg);142	*val = be16_to_cpu(st->data.sample[address % 2]);143 144	return ret;145}146 147static int ad7266_read_raw(struct iio_dev *indio_dev,148	struct iio_chan_spec const *chan, int *val, int *val2, long m)149{150	struct ad7266_state *st = iio_priv(indio_dev);151	unsigned long scale_mv;152	int ret;153 154	switch (m) {155	case IIO_CHAN_INFO_RAW:156		ret = iio_device_claim_direct_mode(indio_dev);157		if (ret)158			return ret;159		ret = ad7266_read_single(st, val, chan->address);160		iio_device_release_direct_mode(indio_dev);161 162		if (ret < 0)163			return ret;164		*val = (*val >> 2) & 0xfff;165		if (chan->scan_type.sign == 's')166			*val = sign_extend32(*val,167					     chan->scan_type.realbits - 1);168 169		return IIO_VAL_INT;170	case IIO_CHAN_INFO_SCALE:171		scale_mv = st->vref_mv;172		if (st->mode == AD7266_MODE_DIFF)173			scale_mv *= 2;174		if (st->range == AD7266_RANGE_2VREF)175			scale_mv *= 2;176 177		*val = scale_mv;178		*val2 = chan->scan_type.realbits;179		return IIO_VAL_FRACTIONAL_LOG2;180	case IIO_CHAN_INFO_OFFSET:181		if (st->range == AD7266_RANGE_2VREF &&182			st->mode != AD7266_MODE_DIFF)183			*val = 2048;184		else185			*val = 0;186		return IIO_VAL_INT;187	}188	return -EINVAL;189}190 191#define AD7266_CHAN(_chan, _sign) {			\192	.type = IIO_VOLTAGE,				\193	.indexed = 1,					\194	.channel = (_chan),				\195	.address = (_chan),				\196	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\197	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) \198		| BIT(IIO_CHAN_INFO_OFFSET),			\199	.scan_index = (_chan),				\200	.scan_type = {					\201		.sign = (_sign),			\202		.realbits = 12,				\203		.storagebits = 16,			\204		.shift = 2,				\205		.endianness = IIO_BE,			\206	},						\207}208 209#define AD7266_DECLARE_SINGLE_ENDED_CHANNELS(_name, _sign) \210const struct iio_chan_spec ad7266_channels_##_name[] = { \211	AD7266_CHAN(0, (_sign)), \212	AD7266_CHAN(1, (_sign)), \213	AD7266_CHAN(2, (_sign)), \214	AD7266_CHAN(3, (_sign)), \215	AD7266_CHAN(4, (_sign)), \216	AD7266_CHAN(5, (_sign)), \217	AD7266_CHAN(6, (_sign)), \218	AD7266_CHAN(7, (_sign)), \219	AD7266_CHAN(8, (_sign)), \220	AD7266_CHAN(9, (_sign)), \221	AD7266_CHAN(10, (_sign)), \222	AD7266_CHAN(11, (_sign)), \223	IIO_CHAN_SOFT_TIMESTAMP(13), \224}225 226#define AD7266_DECLARE_SINGLE_ENDED_CHANNELS_FIXED(_name, _sign) \227const struct iio_chan_spec ad7266_channels_##_name##_fixed[] = { \228	AD7266_CHAN(0, (_sign)), \229	AD7266_CHAN(1, (_sign)), \230	IIO_CHAN_SOFT_TIMESTAMP(2), \231}232 233static AD7266_DECLARE_SINGLE_ENDED_CHANNELS(u, 'u');234static AD7266_DECLARE_SINGLE_ENDED_CHANNELS(s, 's');235static AD7266_DECLARE_SINGLE_ENDED_CHANNELS_FIXED(u, 'u');236static AD7266_DECLARE_SINGLE_ENDED_CHANNELS_FIXED(s, 's');237 238#define AD7266_CHAN_DIFF(_chan, _sign) {			\239	.type = IIO_VOLTAGE,				\240	.indexed = 1,					\241	.channel = (_chan) * 2,				\242	.channel2 = (_chan) * 2 + 1,			\243	.address = (_chan),				\244	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\245	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE)	\246		| BIT(IIO_CHAN_INFO_OFFSET),			\247	.scan_index = (_chan),				\248	.scan_type = {					\249		.sign = _sign,			\250		.realbits = 12,				\251		.storagebits = 16,			\252		.shift = 2,				\253		.endianness = IIO_BE,			\254	},						\255	.differential = 1,				\256}257 258#define AD7266_DECLARE_DIFF_CHANNELS(_name, _sign) \259const struct iio_chan_spec ad7266_channels_diff_##_name[] = { \260	AD7266_CHAN_DIFF(0, (_sign)), \261	AD7266_CHAN_DIFF(1, (_sign)), \262	AD7266_CHAN_DIFF(2, (_sign)), \263	AD7266_CHAN_DIFF(3, (_sign)), \264	AD7266_CHAN_DIFF(4, (_sign)), \265	AD7266_CHAN_DIFF(5, (_sign)), \266	IIO_CHAN_SOFT_TIMESTAMP(6), \267}268 269static AD7266_DECLARE_DIFF_CHANNELS(s, 's');270static AD7266_DECLARE_DIFF_CHANNELS(u, 'u');271 272#define AD7266_DECLARE_DIFF_CHANNELS_FIXED(_name, _sign) \273const struct iio_chan_spec ad7266_channels_diff_fixed_##_name[] = { \274	AD7266_CHAN_DIFF(0, (_sign)), \275	AD7266_CHAN_DIFF(1, (_sign)), \276	IIO_CHAN_SOFT_TIMESTAMP(2), \277}278 279static AD7266_DECLARE_DIFF_CHANNELS_FIXED(s, 's');280static AD7266_DECLARE_DIFF_CHANNELS_FIXED(u, 'u');281 282static const struct iio_info ad7266_info = {283	.read_raw = &ad7266_read_raw,284	.update_scan_mode = &ad7266_update_scan_mode,285};286 287static const unsigned long ad7266_available_scan_masks[] = {288	0x003,289	0x00c,290	0x030,291	0x0c0,292	0x300,293	0xc00,294	0x000,295};296 297static const unsigned long ad7266_available_scan_masks_diff[] = {298	0x003,299	0x00c,300	0x030,301	0x000,302};303 304static const unsigned long ad7266_available_scan_masks_fixed[] = {305	0x003,306	0x000,307};308 309struct ad7266_chan_info {310	const struct iio_chan_spec *channels;311	unsigned int num_channels;312	const unsigned long *scan_masks;313};314 315#define AD7266_CHAN_INFO_INDEX(_differential, _signed, _fixed) \316	(((_differential) << 2) | ((_signed) << 1) | ((_fixed) << 0))317 318static const struct ad7266_chan_info ad7266_chan_infos[] = {319	[AD7266_CHAN_INFO_INDEX(0, 0, 0)] = {320		.channels = ad7266_channels_u,321		.num_channels = ARRAY_SIZE(ad7266_channels_u),322		.scan_masks = ad7266_available_scan_masks,323	},324	[AD7266_CHAN_INFO_INDEX(0, 0, 1)] = {325		.channels = ad7266_channels_u_fixed,326		.num_channels = ARRAY_SIZE(ad7266_channels_u_fixed),327		.scan_masks = ad7266_available_scan_masks_fixed,328	},329	[AD7266_CHAN_INFO_INDEX(0, 1, 0)] = {330		.channels = ad7266_channels_s,331		.num_channels = ARRAY_SIZE(ad7266_channels_s),332		.scan_masks = ad7266_available_scan_masks,333	},334	[AD7266_CHAN_INFO_INDEX(0, 1, 1)] = {335		.channels = ad7266_channels_s_fixed,336		.num_channels = ARRAY_SIZE(ad7266_channels_s_fixed),337		.scan_masks = ad7266_available_scan_masks_fixed,338	},339	[AD7266_CHAN_INFO_INDEX(1, 0, 0)] = {340		.channels = ad7266_channels_diff_u,341		.num_channels = ARRAY_SIZE(ad7266_channels_diff_u),342		.scan_masks = ad7266_available_scan_masks_diff,343	},344	[AD7266_CHAN_INFO_INDEX(1, 0, 1)] = {345		.channels = ad7266_channels_diff_fixed_u,346		.num_channels = ARRAY_SIZE(ad7266_channels_diff_fixed_u),347		.scan_masks = ad7266_available_scan_masks_fixed,348	},349	[AD7266_CHAN_INFO_INDEX(1, 1, 0)] = {350		.channels = ad7266_channels_diff_s,351		.num_channels = ARRAY_SIZE(ad7266_channels_diff_s),352		.scan_masks = ad7266_available_scan_masks_diff,353	},354	[AD7266_CHAN_INFO_INDEX(1, 1, 1)] = {355		.channels = ad7266_channels_diff_fixed_s,356		.num_channels = ARRAY_SIZE(ad7266_channels_diff_fixed_s),357		.scan_masks = ad7266_available_scan_masks_fixed,358	},359};360 361static void ad7266_init_channels(struct iio_dev *indio_dev)362{363	struct ad7266_state *st = iio_priv(indio_dev);364	bool is_differential, is_signed;365	const struct ad7266_chan_info *chan_info;366	int i;367 368	is_differential = st->mode != AD7266_MODE_SINGLE_ENDED;369	is_signed = (st->range == AD7266_RANGE_2VREF) |370		    (st->mode == AD7266_MODE_DIFF);371 372	i = AD7266_CHAN_INFO_INDEX(is_differential, is_signed, st->fixed_addr);373	chan_info = &ad7266_chan_infos[i];374 375	indio_dev->channels = chan_info->channels;376	indio_dev->num_channels = chan_info->num_channels;377	indio_dev->available_scan_masks = chan_info->scan_masks;378}379 380static const char * const ad7266_gpio_labels[] = {381	"ad0", "ad1", "ad2",382};383 384static int ad7266_probe(struct spi_device *spi)385{386	struct ad7266_platform_data *pdata = spi->dev.platform_data;387	struct iio_dev *indio_dev;388	struct ad7266_state *st;389	unsigned int i;390	int ret;391 392	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));393	if (indio_dev == NULL)394		return -ENOMEM;395 396	st = iio_priv(indio_dev);397 398	ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vref");399	if (ret < 0 && ret != -ENODEV)400		return ret;401 402	st->vref_mv = ret == -ENODEV ? AD7266_INTERNAL_REF_MV : ret / 1000;403 404	if (pdata) {405		st->fixed_addr = pdata->fixed_addr;406		st->mode = pdata->mode;407		st->range = pdata->range;408 409		if (!st->fixed_addr) {410			for (i = 0; i < ARRAY_SIZE(st->gpios); ++i) {411				st->gpios[i] = devm_gpiod_get(&spi->dev,412						      ad7266_gpio_labels[i],413						      GPIOD_OUT_LOW);414				if (IS_ERR(st->gpios[i])) {415					ret = PTR_ERR(st->gpios[i]);416					return ret;417				}418			}419		}420	} else {421		st->fixed_addr = true;422		st->range = AD7266_RANGE_VREF;423		st->mode = AD7266_MODE_DIFF;424	}425 426	st->spi = spi;427 428	indio_dev->name = spi_get_device_id(spi)->name;429	indio_dev->modes = INDIO_DIRECT_MODE;430	indio_dev->info = &ad7266_info;431 432	ad7266_init_channels(indio_dev);433 434	/* wakeup */435	st->single_xfer[0].rx_buf = &st->data.sample[0];436	st->single_xfer[0].len = 2;437	st->single_xfer[0].cs_change = 1;438	/* conversion */439	st->single_xfer[1].rx_buf = st->data.sample;440	st->single_xfer[1].len = 4;441	st->single_xfer[1].cs_change = 1;442	/* powerdown */443	st->single_xfer[2].tx_buf = &st->data.sample[0];444	st->single_xfer[2].len = 1;445 446	spi_message_init(&st->single_msg);447	spi_message_add_tail(&st->single_xfer[0], &st->single_msg);448	spi_message_add_tail(&st->single_xfer[1], &st->single_msg);449	spi_message_add_tail(&st->single_xfer[2], &st->single_msg);450 451	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, &iio_pollfunc_store_time,452		&ad7266_trigger_handler, &iio_triggered_buffer_setup_ops);453	if (ret)454		return ret;455 456	return devm_iio_device_register(&spi->dev, indio_dev);457}458 459static const struct spi_device_id ad7266_id[] = {460	{ "ad7265", 0 },461	{ "ad7266", 0 },462	{ }463};464MODULE_DEVICE_TABLE(spi, ad7266_id);465 466static struct spi_driver ad7266_driver = {467	.driver = {468		.name	= "ad7266",469	},470	.probe		= ad7266_probe,471	.id_table	= ad7266_id,472};473module_spi_driver(ad7266_driver);474 475MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");476MODULE_DESCRIPTION("Analog Devices AD7266/65 ADC");477MODULE_LICENSE("GPL v2");478