162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Xilinx XADC driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2013 Analog Devices Inc.
662306a36Sopenharmony_ci *  Author: Lars-Peter Clausen <lars@metafoo.de>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#ifndef __IIO_XILINX_XADC__
1062306a36Sopenharmony_ci#define __IIO_XILINX_XADC__
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <linux/interrupt.h>
1362306a36Sopenharmony_ci#include <linux/mutex.h>
1462306a36Sopenharmony_ci#include <linux/spinlock.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistruct iio_dev;
1762306a36Sopenharmony_cistruct clk;
1862306a36Sopenharmony_cistruct xadc_ops;
1962306a36Sopenharmony_cistruct platform_device;
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_civoid xadc_handle_events(struct iio_dev *indio_dev, unsigned long events);
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciint xadc_read_event_config(struct iio_dev *indio_dev,
2462306a36Sopenharmony_ci	const struct iio_chan_spec *chan, enum iio_event_type type,
2562306a36Sopenharmony_ci	enum iio_event_direction dir);
2662306a36Sopenharmony_ciint xadc_write_event_config(struct iio_dev *indio_dev,
2762306a36Sopenharmony_ci	const struct iio_chan_spec *chan, enum iio_event_type type,
2862306a36Sopenharmony_ci	enum iio_event_direction dir, int state);
2962306a36Sopenharmony_ciint xadc_read_event_value(struct iio_dev *indio_dev,
3062306a36Sopenharmony_ci	const struct iio_chan_spec *chan, enum iio_event_type type,
3162306a36Sopenharmony_ci	enum iio_event_direction dir, enum iio_event_info info,
3262306a36Sopenharmony_ci	int *val, int *val2);
3362306a36Sopenharmony_ciint xadc_write_event_value(struct iio_dev *indio_dev,
3462306a36Sopenharmony_ci	const struct iio_chan_spec *chan, enum iio_event_type type,
3562306a36Sopenharmony_ci	enum iio_event_direction dir, enum iio_event_info info,
3662306a36Sopenharmony_ci	int val, int val2);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cienum xadc_external_mux_mode {
3962306a36Sopenharmony_ci	XADC_EXTERNAL_MUX_NONE,
4062306a36Sopenharmony_ci	XADC_EXTERNAL_MUX_SINGLE,
4162306a36Sopenharmony_ci	XADC_EXTERNAL_MUX_DUAL,
4262306a36Sopenharmony_ci};
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistruct xadc {
4562306a36Sopenharmony_ci	void __iomem *base;
4662306a36Sopenharmony_ci	struct clk *clk;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	const struct xadc_ops *ops;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	uint16_t threshold[16];
5162306a36Sopenharmony_ci	uint16_t temp_hysteresis;
5262306a36Sopenharmony_ci	unsigned int alarm_mask;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	uint16_t *data;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	struct iio_trigger *trigger;
5762306a36Sopenharmony_ci	struct iio_trigger *convst_trigger;
5862306a36Sopenharmony_ci	struct iio_trigger *samplerate_trigger;
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	enum xadc_external_mux_mode external_mux_mode;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	unsigned int zynq_masked_alarm;
6362306a36Sopenharmony_ci	unsigned int zynq_intmask;
6462306a36Sopenharmony_ci	struct delayed_work zynq_unmask_work;
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	struct mutex mutex;
6762306a36Sopenharmony_ci	spinlock_t lock;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	struct completion completion;
7062306a36Sopenharmony_ci};
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_cienum xadc_type {
7362306a36Sopenharmony_ci	XADC_TYPE_S7, /* Series 7 */
7462306a36Sopenharmony_ci	XADC_TYPE_US, /* UltraScale and UltraScale+ */
7562306a36Sopenharmony_ci};
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistruct xadc_ops {
7862306a36Sopenharmony_ci	int (*read)(struct xadc *xadc, unsigned int reg, uint16_t *val);
7962306a36Sopenharmony_ci	int (*write)(struct xadc *xadc, unsigned int reg, uint16_t val);
8062306a36Sopenharmony_ci	int (*setup)(struct platform_device *pdev, struct iio_dev *indio_dev,
8162306a36Sopenharmony_ci			int irq);
8262306a36Sopenharmony_ci	void (*update_alarm)(struct xadc *xadc, unsigned int alarm);
8362306a36Sopenharmony_ci	unsigned long (*get_dclk_rate)(struct xadc *xadc);
8462306a36Sopenharmony_ci	irqreturn_t (*interrupt_handler)(int irq, void *devid);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	unsigned int flags;
8762306a36Sopenharmony_ci	enum xadc_type type;
8862306a36Sopenharmony_ci	int temp_scale;
8962306a36Sopenharmony_ci	int temp_offset;
9062306a36Sopenharmony_ci};
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_cistatic inline int _xadc_read_adc_reg(struct xadc *xadc, unsigned int reg,
9362306a36Sopenharmony_ci	uint16_t *val)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	lockdep_assert_held(&xadc->mutex);
9662306a36Sopenharmony_ci	return xadc->ops->read(xadc, reg, val);
9762306a36Sopenharmony_ci}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_cistatic inline int _xadc_write_adc_reg(struct xadc *xadc, unsigned int reg,
10062306a36Sopenharmony_ci	uint16_t val)
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	lockdep_assert_held(&xadc->mutex);
10362306a36Sopenharmony_ci	return xadc->ops->write(xadc, reg, val);
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cistatic inline int xadc_read_adc_reg(struct xadc *xadc, unsigned int reg,
10762306a36Sopenharmony_ci	uint16_t *val)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	int ret;
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	mutex_lock(&xadc->mutex);
11262306a36Sopenharmony_ci	ret = _xadc_read_adc_reg(xadc, reg, val);
11362306a36Sopenharmony_ci	mutex_unlock(&xadc->mutex);
11462306a36Sopenharmony_ci	return ret;
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic inline int xadc_write_adc_reg(struct xadc *xadc, unsigned int reg,
11862306a36Sopenharmony_ci	uint16_t val)
11962306a36Sopenharmony_ci{
12062306a36Sopenharmony_ci	int ret;
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	mutex_lock(&xadc->mutex);
12362306a36Sopenharmony_ci	ret = _xadc_write_adc_reg(xadc, reg, val);
12462306a36Sopenharmony_ci	mutex_unlock(&xadc->mutex);
12562306a36Sopenharmony_ci	return ret;
12662306a36Sopenharmony_ci}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci/* XADC hardmacro register definitions */
12962306a36Sopenharmony_ci#define XADC_REG_TEMP		0x00
13062306a36Sopenharmony_ci#define XADC_REG_VCCINT		0x01
13162306a36Sopenharmony_ci#define XADC_REG_VCCAUX		0x02
13262306a36Sopenharmony_ci#define XADC_REG_VPVN		0x03
13362306a36Sopenharmony_ci#define XADC_REG_VREFP		0x04
13462306a36Sopenharmony_ci#define XADC_REG_VREFN		0x05
13562306a36Sopenharmony_ci#define XADC_REG_VCCBRAM	0x06
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci#define XADC_REG_VCCPINT	0x0d
13862306a36Sopenharmony_ci#define XADC_REG_VCCPAUX	0x0e
13962306a36Sopenharmony_ci#define XADC_REG_VCCO_DDR	0x0f
14062306a36Sopenharmony_ci#define XADC_REG_VAUX(x)	(0x10 + (x))
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#define XADC_REG_MAX_TEMP	0x20
14362306a36Sopenharmony_ci#define XADC_REG_MAX_VCCINT	0x21
14462306a36Sopenharmony_ci#define XADC_REG_MAX_VCCAUX	0x22
14562306a36Sopenharmony_ci#define XADC_REG_MAX_VCCBRAM	0x23
14662306a36Sopenharmony_ci#define XADC_REG_MIN_TEMP	0x24
14762306a36Sopenharmony_ci#define XADC_REG_MIN_VCCINT	0x25
14862306a36Sopenharmony_ci#define XADC_REG_MIN_VCCAUX	0x26
14962306a36Sopenharmony_ci#define XADC_REG_MIN_VCCBRAM	0x27
15062306a36Sopenharmony_ci#define XADC_REG_MAX_VCCPINT	0x28
15162306a36Sopenharmony_ci#define XADC_REG_MAX_VCCPAUX	0x29
15262306a36Sopenharmony_ci#define XADC_REG_MAX_VCCO_DDR	0x2a
15362306a36Sopenharmony_ci#define XADC_REG_MIN_VCCPINT	0x2c
15462306a36Sopenharmony_ci#define XADC_REG_MIN_VCCPAUX	0x2d
15562306a36Sopenharmony_ci#define XADC_REG_MIN_VCCO_DDR	0x2e
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci#define XADC_REG_CONF0		0x40
15862306a36Sopenharmony_ci#define XADC_REG_CONF1		0x41
15962306a36Sopenharmony_ci#define XADC_REG_CONF2		0x42
16062306a36Sopenharmony_ci#define XADC_REG_SEQ(x)		(0x48 + (x))
16162306a36Sopenharmony_ci#define XADC_REG_INPUT_MODE(x)	(0x4c + (x))
16262306a36Sopenharmony_ci#define XADC_REG_THRESHOLD(x)	(0x50 + (x))
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci#define XADC_REG_FLAG		0x3f
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci#define XADC_CONF0_EC			BIT(9)
16762306a36Sopenharmony_ci#define XADC_CONF0_ACQ			BIT(8)
16862306a36Sopenharmony_ci#define XADC_CONF0_MUX			BIT(11)
16962306a36Sopenharmony_ci#define XADC_CONF0_CHAN(x)		(x)
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci#define XADC_CONF1_SEQ_MASK		(0xf << 12)
17262306a36Sopenharmony_ci#define XADC_CONF1_SEQ_DEFAULT		(0 << 12)
17362306a36Sopenharmony_ci#define XADC_CONF1_SEQ_SINGLE_PASS	(1 << 12)
17462306a36Sopenharmony_ci#define XADC_CONF1_SEQ_CONTINUOUS	(2 << 12)
17562306a36Sopenharmony_ci#define XADC_CONF1_SEQ_SINGLE_CHANNEL	(3 << 12)
17662306a36Sopenharmony_ci#define XADC_CONF1_SEQ_SIMULTANEOUS	(4 << 12)
17762306a36Sopenharmony_ci#define XADC_CONF1_SEQ_INDEPENDENT	(8 << 12)
17862306a36Sopenharmony_ci#define XADC_CONF1_ALARM_MASK		0x0f0f
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci#define XADC_CONF2_DIV_MASK	0xff00
18162306a36Sopenharmony_ci#define XADC_CONF2_DIV_OFFSET	8
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci#define XADC_CONF2_PD_MASK	(0x3 << 4)
18462306a36Sopenharmony_ci#define XADC_CONF2_PD_NONE	(0x0 << 4)
18562306a36Sopenharmony_ci#define XADC_CONF2_PD_ADC_B	(0x2 << 4)
18662306a36Sopenharmony_ci#define XADC_CONF2_PD_BOTH	(0x3 << 4)
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci#define XADC_ALARM_TEMP_MASK		BIT(0)
18962306a36Sopenharmony_ci#define XADC_ALARM_VCCINT_MASK		BIT(1)
19062306a36Sopenharmony_ci#define XADC_ALARM_VCCAUX_MASK		BIT(2)
19162306a36Sopenharmony_ci#define XADC_ALARM_OT_MASK		BIT(3)
19262306a36Sopenharmony_ci#define XADC_ALARM_VCCBRAM_MASK		BIT(4)
19362306a36Sopenharmony_ci#define XADC_ALARM_VCCPINT_MASK		BIT(5)
19462306a36Sopenharmony_ci#define XADC_ALARM_VCCPAUX_MASK		BIT(6)
19562306a36Sopenharmony_ci#define XADC_ALARM_VCCODDR_MASK		BIT(7)
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci#define XADC_THRESHOLD_TEMP_MAX		0x0
19862306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCINT_MAX	0x1
19962306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCAUX_MAX	0x2
20062306a36Sopenharmony_ci#define XADC_THRESHOLD_OT_MAX		0x3
20162306a36Sopenharmony_ci#define XADC_THRESHOLD_TEMP_MIN		0x4
20262306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCINT_MIN	0x5
20362306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCAUX_MIN	0x6
20462306a36Sopenharmony_ci#define XADC_THRESHOLD_OT_MIN		0x7
20562306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCBRAM_MAX	0x8
20662306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCPINT_MAX	0x9
20762306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCPAUX_MAX	0xa
20862306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCODDR_MAX	0xb
20962306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCBRAM_MIN	0xc
21062306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCPINT_MIN	0xd
21162306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCPAUX_MIN	0xe
21262306a36Sopenharmony_ci#define XADC_THRESHOLD_VCCODDR_MIN	0xf
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci#endif
215