cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ad5791.c (11328B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * AD5760, AD5780, AD5781, AD5790, AD5791 Voltage Output Digital to Analog
      4 * Converter
      5 *
      6 * Copyright 2011 Analog Devices Inc.
      7 */
      8
      9#include <linux/interrupt.h>
     10#include <linux/fs.h>
     11#include <linux/device.h>
     12#include <linux/kernel.h>
     13#include <linux/spi/spi.h>
     14#include <linux/slab.h>
     15#include <linux/sysfs.h>
     16#include <linux/regulator/consumer.h>
     17#include <linux/module.h>
     18#include <linux/bitops.h>
     19
     20#include <linux/iio/iio.h>
     21#include <linux/iio/sysfs.h>
     22#include <linux/iio/dac/ad5791.h>
     23
     24#define AD5791_DAC_MASK			GENMASK(19, 0)
     25
     26#define AD5791_CMD_READ			BIT(23)
     27#define AD5791_CMD_WRITE		0
     28#define AD5791_ADDR(addr)		((addr) << 20)
     29
     30/* Registers */
     31#define AD5791_ADDR_NOOP		0
     32#define AD5791_ADDR_DAC0		1
     33#define AD5791_ADDR_CTRL		2
     34#define AD5791_ADDR_CLRCODE		3
     35#define AD5791_ADDR_SW_CTRL		4
     36
     37/* Control Register */
     38#define AD5791_CTRL_RBUF		BIT(1)
     39#define AD5791_CTRL_OPGND		BIT(2)
     40#define AD5791_CTRL_DACTRI		BIT(3)
     41#define AD5791_CTRL_BIN2SC		BIT(4)
     42#define AD5791_CTRL_SDODIS		BIT(5)
     43#define AD5761_CTRL_LINCOMP(x)		((x) << 6)
     44
     45#define AD5791_LINCOMP_0_10		0
     46#define AD5791_LINCOMP_10_12		1
     47#define AD5791_LINCOMP_12_16		2
     48#define AD5791_LINCOMP_16_19		3
     49#define AD5791_LINCOMP_19_20		12
     50
     51#define AD5780_LINCOMP_0_10		0
     52#define AD5780_LINCOMP_10_20		12
     53
     54/* Software Control Register */
     55#define AD5791_SWCTRL_LDAC		BIT(0)
     56#define AD5791_SWCTRL_CLR		BIT(1)
     57#define AD5791_SWCTRL_RESET		BIT(2)
     58
     59#define AD5791_DAC_PWRDN_6K		0
     60#define AD5791_DAC_PWRDN_3STATE		1
     61
     62/**
     63 * struct ad5791_chip_info - chip specific information
     64 * @get_lin_comp:	function pointer to the device specific function
     65 */
     66
     67struct ad5791_chip_info {
     68	int (*get_lin_comp)	(unsigned int span);
     69};
     70
     71/**
     72 * struct ad5791_state - driver instance specific data
     73 * @spi:			spi_device
     74 * @reg_vdd:		positive supply regulator
     75 * @reg_vss:		negative supply regulator
     76 * @chip_info:		chip model specific constants
     77 * @vref_mv:		actual reference voltage used
     78 * @vref_neg_mv:	voltage of the negative supply
     79 * @ctrl:		control register cache
     80 * @pwr_down_mode:	current power down mode
     81 * @pwr_down:		true if device is powered down
     82 * @data:		spi transfer buffers
     83 */
     84struct ad5791_state {
     85	struct spi_device		*spi;
     86	struct regulator		*reg_vdd;
     87	struct regulator		*reg_vss;
     88	const struct ad5791_chip_info	*chip_info;
     89	unsigned short			vref_mv;
     90	unsigned int			vref_neg_mv;
     91	unsigned			ctrl;
     92	unsigned			pwr_down_mode;
     93	bool				pwr_down;
     94
     95	union {
     96		__be32 d32;
     97		u8 d8[4];
     98	} data[3] ____cacheline_aligned;
     99};
    100
    101enum ad5791_supported_device_ids {
    102	ID_AD5760,
    103	ID_AD5780,
    104	ID_AD5781,
    105	ID_AD5791,
    106};
    107
    108static int ad5791_spi_write(struct ad5791_state *st, u8 addr, u32 val)
    109{
    110	st->data[0].d32 = cpu_to_be32(AD5791_CMD_WRITE |
    111			      AD5791_ADDR(addr) |
    112			      (val & AD5791_DAC_MASK));
    113
    114	return spi_write(st->spi, &st->data[0].d8[1], 3);
    115}
    116
    117static int ad5791_spi_read(struct ad5791_state *st, u8 addr, u32 *val)
    118{
    119	int ret;
    120	struct spi_transfer xfers[] = {
    121		{
    122			.tx_buf = &st->data[0].d8[1],
    123			.bits_per_word = 8,
    124			.len = 3,
    125			.cs_change = 1,
    126		}, {
    127			.tx_buf = &st->data[1].d8[1],
    128			.rx_buf = &st->data[2].d8[1],
    129			.bits_per_word = 8,
    130			.len = 3,
    131		},
    132	};
    133
    134	st->data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
    135			      AD5791_ADDR(addr));
    136	st->data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
    137
    138	ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
    139
    140	*val = be32_to_cpu(st->data[2].d32);
    141
    142	return ret;
    143}
    144
    145static const char * const ad5791_powerdown_modes[] = {
    146	"6kohm_to_gnd",
    147	"three_state",
    148};
    149
    150static int ad5791_get_powerdown_mode(struct iio_dev *indio_dev,
    151	const struct iio_chan_spec *chan)
    152{
    153	struct ad5791_state *st = iio_priv(indio_dev);
    154
    155	return st->pwr_down_mode;
    156}
    157
    158static int ad5791_set_powerdown_mode(struct iio_dev *indio_dev,
    159	const struct iio_chan_spec *chan, unsigned int mode)
    160{
    161	struct ad5791_state *st = iio_priv(indio_dev);
    162
    163	st->pwr_down_mode = mode;
    164
    165	return 0;
    166}
    167
    168static const struct iio_enum ad5791_powerdown_mode_enum = {
    169	.items = ad5791_powerdown_modes,
    170	.num_items = ARRAY_SIZE(ad5791_powerdown_modes),
    171	.get = ad5791_get_powerdown_mode,
    172	.set = ad5791_set_powerdown_mode,
    173};
    174
    175static ssize_t ad5791_read_dac_powerdown(struct iio_dev *indio_dev,
    176	uintptr_t private, const struct iio_chan_spec *chan, char *buf)
    177{
    178	struct ad5791_state *st = iio_priv(indio_dev);
    179
    180	return sysfs_emit(buf, "%d\n", st->pwr_down);
    181}
    182
    183static ssize_t ad5791_write_dac_powerdown(struct iio_dev *indio_dev,
    184	 uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
    185	 size_t len)
    186{
    187	bool pwr_down;
    188	int ret;
    189	struct ad5791_state *st = iio_priv(indio_dev);
    190
    191	ret = kstrtobool(buf, &pwr_down);
    192	if (ret)
    193		return ret;
    194
    195	if (!pwr_down) {
    196		st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
    197	} else {
    198		if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
    199			st->ctrl |= AD5791_CTRL_OPGND;
    200		else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
    201			st->ctrl |= AD5791_CTRL_DACTRI;
    202	}
    203	st->pwr_down = pwr_down;
    204
    205	ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl);
    206
    207	return ret ? ret : len;
    208}
    209
    210static int ad5791_get_lin_comp(unsigned int span)
    211{
    212	if (span <= 10000)
    213		return AD5791_LINCOMP_0_10;
    214	else if (span <= 12000)
    215		return AD5791_LINCOMP_10_12;
    216	else if (span <= 16000)
    217		return AD5791_LINCOMP_12_16;
    218	else if (span <= 19000)
    219		return AD5791_LINCOMP_16_19;
    220	else
    221		return AD5791_LINCOMP_19_20;
    222}
    223
    224static int ad5780_get_lin_comp(unsigned int span)
    225{
    226	if (span <= 10000)
    227		return AD5780_LINCOMP_0_10;
    228	else
    229		return AD5780_LINCOMP_10_20;
    230}
    231static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
    232	[ID_AD5760] = {
    233		.get_lin_comp = ad5780_get_lin_comp,
    234	},
    235	[ID_AD5780] = {
    236		.get_lin_comp = ad5780_get_lin_comp,
    237	},
    238	[ID_AD5781] = {
    239		.get_lin_comp = ad5791_get_lin_comp,
    240	},
    241	[ID_AD5791] = {
    242		.get_lin_comp = ad5791_get_lin_comp,
    243	},
    244};
    245
    246static int ad5791_read_raw(struct iio_dev *indio_dev,
    247			   struct iio_chan_spec const *chan,
    248			   int *val,
    249			   int *val2,
    250			   long m)
    251{
    252	struct ad5791_state *st = iio_priv(indio_dev);
    253	u64 val64;
    254	int ret;
    255
    256	switch (m) {
    257	case IIO_CHAN_INFO_RAW:
    258		ret = ad5791_spi_read(st, chan->address, val);
    259		if (ret)
    260			return ret;
    261		*val &= AD5791_DAC_MASK;
    262		*val >>= chan->scan_type.shift;
    263		return IIO_VAL_INT;
    264	case IIO_CHAN_INFO_SCALE:
    265		*val = st->vref_mv;
    266		*val2 = (1 << chan->scan_type.realbits) - 1;
    267		return IIO_VAL_FRACTIONAL;
    268	case IIO_CHAN_INFO_OFFSET:
    269		val64 = (((u64)st->vref_neg_mv) << chan->scan_type.realbits);
    270		do_div(val64, st->vref_mv);
    271		*val = -val64;
    272		return IIO_VAL_INT;
    273	default:
    274		return -EINVAL;
    275	}
    276
    277};
    278
    279static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
    280	{
    281		.name = "powerdown",
    282		.shared = IIO_SHARED_BY_TYPE,
    283		.read = ad5791_read_dac_powerdown,
    284		.write = ad5791_write_dac_powerdown,
    285	},
    286	IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
    287		 &ad5791_powerdown_mode_enum),
    288	IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &ad5791_powerdown_mode_enum),
    289	{ },
    290};
    291
    292#define AD5791_CHAN(bits, _shift) {			\
    293	.type = IIO_VOLTAGE,				\
    294	.output = 1,					\
    295	.indexed = 1,					\
    296	.address = AD5791_ADDR_DAC0,			\
    297	.channel = 0,					\
    298	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
    299	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
    300		BIT(IIO_CHAN_INFO_OFFSET),		\
    301	.scan_type = {					\
    302		.sign = 'u',				\
    303		.realbits = (bits),			\
    304		.storagebits = 24,			\
    305		.shift = (_shift),			\
    306	},						\
    307	.ext_info = ad5791_ext_info,			\
    308}
    309
    310static const struct iio_chan_spec ad5791_channels[] = {
    311	[ID_AD5760] = AD5791_CHAN(16, 4),
    312	[ID_AD5780] = AD5791_CHAN(18, 2),
    313	[ID_AD5781] = AD5791_CHAN(18, 2),
    314	[ID_AD5791] = AD5791_CHAN(20, 0)
    315};
    316
    317static int ad5791_write_raw(struct iio_dev *indio_dev,
    318			    struct iio_chan_spec const *chan,
    319			    int val,
    320			    int val2,
    321			    long mask)
    322{
    323	struct ad5791_state *st = iio_priv(indio_dev);
    324
    325	switch (mask) {
    326	case IIO_CHAN_INFO_RAW:
    327		val &= GENMASK(chan->scan_type.realbits - 1, 0);
    328		val <<= chan->scan_type.shift;
    329
    330		return ad5791_spi_write(st, chan->address, val);
    331
    332	default:
    333		return -EINVAL;
    334	}
    335}
    336
    337static const struct iio_info ad5791_info = {
    338	.read_raw = &ad5791_read_raw,
    339	.write_raw = &ad5791_write_raw,
    340};
    341
    342static int ad5791_probe(struct spi_device *spi)
    343{
    344	struct ad5791_platform_data *pdata = spi->dev.platform_data;
    345	struct iio_dev *indio_dev;
    346	struct ad5791_state *st;
    347	int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
    348
    349	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
    350	if (!indio_dev)
    351		return -ENOMEM;
    352	st = iio_priv(indio_dev);
    353	st->reg_vdd = devm_regulator_get(&spi->dev, "vdd");
    354	if (!IS_ERR(st->reg_vdd)) {
    355		ret = regulator_enable(st->reg_vdd);
    356		if (ret)
    357			return ret;
    358
    359		ret = regulator_get_voltage(st->reg_vdd);
    360		if (ret < 0)
    361			goto error_disable_reg_pos;
    362
    363		pos_voltage_uv = ret;
    364	}
    365
    366	st->reg_vss = devm_regulator_get(&spi->dev, "vss");
    367	if (!IS_ERR(st->reg_vss)) {
    368		ret = regulator_enable(st->reg_vss);
    369		if (ret)
    370			goto error_disable_reg_pos;
    371
    372		ret = regulator_get_voltage(st->reg_vss);
    373		if (ret < 0)
    374			goto error_disable_reg_neg;
    375
    376		neg_voltage_uv = ret;
    377	}
    378
    379	st->pwr_down = true;
    380	st->spi = spi;
    381
    382	if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd)) {
    383		st->vref_mv = (pos_voltage_uv + neg_voltage_uv) / 1000;
    384		st->vref_neg_mv = neg_voltage_uv / 1000;
    385	} else if (pdata) {
    386		st->vref_mv = pdata->vref_pos_mv + pdata->vref_neg_mv;
    387		st->vref_neg_mv = pdata->vref_neg_mv;
    388	} else {
    389		dev_warn(&spi->dev, "reference voltage unspecified\n");
    390	}
    391
    392	ret = ad5791_spi_write(st, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
    393	if (ret)
    394		goto error_disable_reg_neg;
    395
    396	st->chip_info =	&ad5791_chip_info_tbl[spi_get_device_id(spi)
    397					      ->driver_data];
    398
    399
    400	st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
    401		  | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
    402		  AD5791_CTRL_BIN2SC;
    403
    404	ret = ad5791_spi_write(st, AD5791_ADDR_CTRL, st->ctrl |
    405		AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
    406	if (ret)
    407		goto error_disable_reg_neg;
    408
    409	spi_set_drvdata(spi, indio_dev);
    410	indio_dev->info = &ad5791_info;
    411	indio_dev->modes = INDIO_DIRECT_MODE;
    412	indio_dev->channels
    413		= &ad5791_channels[spi_get_device_id(spi)->driver_data];
    414	indio_dev->num_channels = 1;
    415	indio_dev->name = spi_get_device_id(st->spi)->name;
    416	ret = iio_device_register(indio_dev);
    417	if (ret)
    418		goto error_disable_reg_neg;
    419
    420	return 0;
    421
    422error_disable_reg_neg:
    423	if (!IS_ERR(st->reg_vss))
    424		regulator_disable(st->reg_vss);
    425error_disable_reg_pos:
    426	if (!IS_ERR(st->reg_vdd))
    427		regulator_disable(st->reg_vdd);
    428	return ret;
    429}
    430
    431static void ad5791_remove(struct spi_device *spi)
    432{
    433	struct iio_dev *indio_dev = spi_get_drvdata(spi);
    434	struct ad5791_state *st = iio_priv(indio_dev);
    435
    436	iio_device_unregister(indio_dev);
    437	if (!IS_ERR(st->reg_vdd))
    438		regulator_disable(st->reg_vdd);
    439
    440	if (!IS_ERR(st->reg_vss))
    441		regulator_disable(st->reg_vss);
    442}
    443
    444static const struct spi_device_id ad5791_id[] = {
    445	{"ad5760", ID_AD5760},
    446	{"ad5780", ID_AD5780},
    447	{"ad5781", ID_AD5781},
    448	{"ad5790", ID_AD5791},
    449	{"ad5791", ID_AD5791},
    450	{}
    451};
    452MODULE_DEVICE_TABLE(spi, ad5791_id);
    453
    454static struct spi_driver ad5791_driver = {
    455	.driver = {
    456		   .name = "ad5791",
    457		   },
    458	.probe = ad5791_probe,
    459	.remove = ad5791_remove,
    460	.id_table = ad5791_id,
    461};
    462module_spi_driver(ad5791_driver);
    463
    464MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
    465MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5790/AD5791 DAC");
    466MODULE_LICENSE("GPL v2");