linux/drivers/iio/adc/xilinx-xadc-core.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Xilinx XADC driver
 *
 * Copyright 2013-2014 Analog Devices Inc.
 *  Author: Lars-Peter Clausen <[email protected]>
 *
 * Documentation for the parts can be found at:
 *  - XADC hardmacro: Xilinx UG480
 *  - ZYNQ XADC interface: Xilinx UG585
 *  - AXI XADC interface: Xilinx PG019
 */

#include <linux/clk.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/overflow.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/sysfs.h>

#include <linux/iio/buffer.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>

#include "xilinx-xadc.h"

static const unsigned int XADC_ZYNQ_UNMASK_TIMEOUT =;

/* ZYNQ register definitions */
#define XADC_ZYNQ_REG_CFG
#define XADC_ZYNQ_REG_INTSTS
#define XADC_ZYNQ_REG_INTMSK
#define XADC_ZYNQ_REG_STATUS
#define XADC_ZYNQ_REG_CFIFO
#define XADC_ZYNQ_REG_DFIFO
#define XADC_ZYNQ_REG_CTL

#define XADC_ZYNQ_CFG_ENABLE
#define XADC_ZYNQ_CFG_CFIFOTH_MASK
#define XADC_ZYNQ_CFG_CFIFOTH_OFFSET
#define XADC_ZYNQ_CFG_DFIFOTH_MASK
#define XADC_ZYNQ_CFG_DFIFOTH_OFFSET
#define XADC_ZYNQ_CFG_WEDGE
#define XADC_ZYNQ_CFG_REDGE
#define XADC_ZYNQ_CFG_TCKRATE_MASK
#define XADC_ZYNQ_CFG_TCKRATE_DIV2
#define XADC_ZYNQ_CFG_TCKRATE_DIV4
#define XADC_ZYNQ_CFG_TCKRATE_DIV8
#define XADC_ZYNQ_CFG_TCKRATE_DIV16
#define XADC_ZYNQ_CFG_IGAP_MASK
#define XADC_ZYNQ_CFG_IGAP(x)

#define XADC_ZYNQ_INT_CFIFO_LTH
#define XADC_ZYNQ_INT_DFIFO_GTH
#define XADC_ZYNQ_INT_ALARM_MASK
#define XADC_ZYNQ_INT_ALARM_OFFSET

#define XADC_ZYNQ_STATUS_CFIFO_LVL_MASK
#define XADC_ZYNQ_STATUS_CFIFO_LVL_OFFSET
#define XADC_ZYNQ_STATUS_DFIFO_LVL_MASK
#define XADC_ZYNQ_STATUS_DFIFO_LVL_OFFSET
#define XADC_ZYNQ_STATUS_CFIFOF
#define XADC_ZYNQ_STATUS_CFIFOE
#define XADC_ZYNQ_STATUS_DFIFOF
#define XADC_ZYNQ_STATUS_DFIFOE
#define XADC_ZYNQ_STATUS_OT
#define XADC_ZYNQ_STATUS_ALM(x)

#define XADC_ZYNQ_CTL_RESET

#define XADC_ZYNQ_CMD_NOP
#define XADC_ZYNQ_CMD_READ
#define XADC_ZYNQ_CMD_WRITE

#define XADC_ZYNQ_CMD(cmd, addr, data)

/* AXI register definitions */
#define XADC_AXI_REG_RESET
#define XADC_AXI_REG_STATUS
#define XADC_AXI_REG_ALARM_STATUS
#define XADC_AXI_REG_CONVST
#define XADC_AXI_REG_XADC_RESET
#define XADC_AXI_REG_GIER
#define XADC_AXI_REG_IPISR
#define XADC_AXI_REG_IPIER

/* 7 Series */
#define XADC_7S_AXI_ADC_REG_OFFSET

/* UltraScale */
#define XADC_US_AXI_ADC_REG_OFFSET

#define XADC_AXI_RESET_MAGIC
#define XADC_AXI_GIER_ENABLE

#define XADC_AXI_INT_EOS
#define XADC_AXI_INT_ALARM_MASK

#define XADC_FLAGS_BUFFERED
#define XADC_FLAGS_IRQ_OPTIONAL

/*
 * The XADC hardware supports a samplerate of up to 1MSPS. Unfortunately it does
 * not have a hardware FIFO. Which means an interrupt is generated for each
 * conversion sequence. At 1MSPS sample rate the CPU in ZYNQ7000 is completely
 * overloaded by the interrupts that it soft-lockups. For this reason the driver
 * limits the maximum samplerate 150kSPS. At this rate the CPU is fairly busy,
 * but still responsive.
 */
#define XADC_MAX_SAMPLERATE

static void xadc_write_reg(struct xadc *xadc, unsigned int reg,
	uint32_t val)
{}

static void xadc_read_reg(struct xadc *xadc, unsigned int reg,
	uint32_t *val)
{}

/*
 * The ZYNQ interface uses two asynchronous FIFOs for communication with the
 * XADC. Reads and writes to the XADC register are performed by submitting a
 * request to the command FIFO (CFIFO), once the request has been completed the
 * result can be read from the data FIFO (DFIFO). The method currently used in
 * this driver is to submit the request for a read/write operation, then go to
 * sleep and wait for an interrupt that signals that a response is available in
 * the data FIFO.
 */

static void xadc_zynq_write_fifo(struct xadc *xadc, uint32_t *cmd,
	unsigned int n)
{}

static void xadc_zynq_drain_fifo(struct xadc *xadc)
{}

static void xadc_zynq_update_intmsk(struct xadc *xadc, unsigned int mask,
	unsigned int val)
{}

static int xadc_zynq_write_adc_reg(struct xadc *xadc, unsigned int reg,
	uint16_t val)
{}

static int xadc_zynq_read_adc_reg(struct xadc *xadc, unsigned int reg,
	uint16_t *val)
{}

static unsigned int xadc_zynq_transform_alarm(unsigned int alarm)
{}

/*
 * The ZYNQ threshold interrupts are level sensitive. Since we can't make the
 * threshold condition go way from within the interrupt handler, this means as
 * soon as a threshold condition is present we would enter the interrupt handler
 * again and again. To work around this we mask all active thresholds interrupts
 * in the interrupt handler and start a timer. In this timer we poll the
 * interrupt status and only if the interrupt is inactive we unmask it again.
 */
static void xadc_zynq_unmask_worker(struct work_struct *work)
{}

static irqreturn_t xadc_zynq_interrupt_handler(int irq, void *devid)
{}

#define XADC_ZYNQ_TCK_RATE_MAX
#define XADC_ZYNQ_IGAP_DEFAULT
#define XADC_ZYNQ_PCAP_RATE_MAX

static int xadc_zynq_setup(struct platform_device *pdev,
	struct iio_dev *indio_dev, int irq)
{}

static unsigned long xadc_zynq_get_dclk_rate(struct xadc *xadc)
{}

static void xadc_zynq_update_alarm(struct xadc *xadc, unsigned int alarm)
{}

static const struct xadc_ops xadc_zynq_ops =;

static const unsigned int xadc_axi_reg_offsets[] =;

static int xadc_axi_read_adc_reg(struct xadc *xadc, unsigned int reg,
	uint16_t *val)
{}

static int xadc_axi_write_adc_reg(struct xadc *xadc, unsigned int reg,
	uint16_t val)
{}

static int xadc_axi_setup(struct platform_device *pdev,
	struct iio_dev *indio_dev, int irq)
{}

static irqreturn_t xadc_axi_interrupt_handler(int irq, void *devid)
{}

static void xadc_axi_update_alarm(struct xadc *xadc, unsigned int alarm)
{}

static unsigned long xadc_axi_get_dclk(struct xadc *xadc)
{}

static const struct xadc_ops xadc_7s_axi_ops =;

static const struct xadc_ops xadc_us_axi_ops =;

static int _xadc_update_adc_reg(struct xadc *xadc, unsigned int reg,
	uint16_t mask, uint16_t val)
{}

static int xadc_update_adc_reg(struct xadc *xadc, unsigned int reg,
	uint16_t mask, uint16_t val)
{}

static unsigned long xadc_get_dclk_rate(struct xadc *xadc)
{}

static int xadc_update_scan_mode(struct iio_dev *indio_dev,
	const unsigned long *mask)
{}

static unsigned int xadc_scan_index_to_channel(unsigned int scan_index)
{}

static irqreturn_t xadc_trigger_handler(int irq, void *p)
{}

static int xadc_trigger_set_state(struct iio_trigger *trigger, bool state)
{}

static const struct iio_trigger_ops xadc_trigger_ops =;

static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev,
	const char *name)
{}

static int xadc_power_adc_b(struct xadc *xadc, unsigned int seq_mode)
{}

static int xadc_get_seq_mode(struct xadc *xadc, unsigned long scan_mode)
{}

static int xadc_postdisable(struct iio_dev *indio_dev)
{}

static int xadc_preenable(struct iio_dev *indio_dev)
{}

static const struct iio_buffer_setup_ops xadc_buffer_ops =;

static int xadc_read_samplerate(struct xadc *xadc)
{}

static int xadc_read_raw(struct iio_dev *indio_dev,
	struct iio_chan_spec const *chan, int *val, int *val2, long info)
{}

static int xadc_write_samplerate(struct xadc *xadc, int val)
{}

static int xadc_write_raw(struct iio_dev *indio_dev,
	struct iio_chan_spec const *chan, int val, int val2, long info)
{}

static const struct iio_event_spec xadc_temp_events[] =;

/* Separate values for upper and lower thresholds, but only a shared enabled */
static const struct iio_event_spec xadc_voltage_events[] =;

#define XADC_CHAN_TEMP(_chan, _scan_index, _addr, _bits)

#define XADC_CHAN_VOLTAGE(_chan, _scan_index, _addr, _bits, _ext, _alarm)

/* 7 Series */
#define XADC_7S_CHAN_TEMP(_chan, _scan_index, _addr)
#define XADC_7S_CHAN_VOLTAGE(_chan, _scan_index, _addr, _ext, _alarm)

static const struct iio_chan_spec xadc_7s_channels[] =;

/* UltraScale */
#define XADC_US_CHAN_TEMP(_chan, _scan_index, _addr)
#define XADC_US_CHAN_VOLTAGE(_chan, _scan_index, _addr, _ext, _alarm)

static const struct iio_chan_spec xadc_us_channels[] =;

static const struct iio_info xadc_info =;

static const struct of_device_id xadc_of_match_table[] =;
MODULE_DEVICE_TABLE(of, xadc_of_match_table);

static int xadc_parse_dt(struct iio_dev *indio_dev, unsigned int *conf, int irq)
{}

static const char * const xadc_type_names[] =;

static void xadc_cancel_delayed_work(void *data)
{}

static int xadc_probe(struct platform_device *pdev)
{}

static struct platform_driver xadc_driver =;
module_platform_driver();

MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();