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

Source file repositories/reference/linux-study-clean/drivers/iio/adc/xilinx-xadc-core.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/xilinx-xadc-core.c
Extension
.c
Size
39378 bytes
Lines
1461
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (xadc->trigger != NULL) {
			ret = -EBUSY;
			goto err_out;
		} else {
			xadc->trigger = trigger;
			if (trigger == xadc->convst_trigger)
				convst = XADC_CONF0_EC;
			else
				convst = 0;
		}
		ret = _xadc_update_adc_reg(xadc, XADC_REG_CONF1, XADC_CONF0_EC,
					convst);
		if (ret)
			goto err_out;
	} else {
		xadc->trigger = NULL;
	}

	spin_lock_irqsave(&xadc->lock, flags);
	xadc_read_reg(xadc, XADC_AXI_REG_IPIER, &val);
	xadc_write_reg(xadc, XADC_AXI_REG_IPISR, XADC_AXI_INT_EOS);
	if (state)
		val |= XADC_AXI_INT_EOS;
	else
		val &= ~XADC_AXI_INT_EOS;
	xadc_write_reg(xadc, XADC_AXI_REG_IPIER, val);
	spin_unlock_irqrestore(&xadc->lock, flags);

err_out:
	mutex_unlock(&xadc->mutex);

	return ret;
}

static const struct iio_trigger_ops xadc_trigger_ops = {
	.set_trigger_state = &xadc_trigger_set_state,
};

static struct iio_trigger *xadc_alloc_trigger(struct iio_dev *indio_dev,
	const char *name)
{
	struct device *dev = indio_dev->dev.parent;
	struct iio_trigger *trig;
	int ret;

	trig = devm_iio_trigger_alloc(dev, "%s%d-%s", indio_dev->name,
				      iio_device_id(indio_dev), name);
	if (trig == NULL)
		return ERR_PTR(-ENOMEM);

	trig->ops = &xadc_trigger_ops;
	iio_trigger_set_drvdata(trig, iio_priv(indio_dev));

	ret = devm_iio_trigger_register(dev, trig);
	if (ret)
		return ERR_PTR(ret);

	return trig;
}

static int xadc_power_adc_b(struct xadc *xadc, unsigned int seq_mode)
{
	uint16_t val;

	/*
	 * As per datasheet the power-down bits are don't care in the
	 * UltraScale, but as per reality setting the power-down bit for the
	 * non-existing ADC-B powers down the main ADC, so just return and don't
	 * do anything.
	 */
	if (xadc->ops->type == XADC_TYPE_US)
		return 0;

	/* Powerdown the ADC-B when it is not needed. */
	switch (seq_mode) {
	case XADC_CONF1_SEQ_SIMULTANEOUS:
	case XADC_CONF1_SEQ_INDEPENDENT:
		val = 0;
		break;
	default:
		val = XADC_CONF2_PD_ADC_B;
		break;
	}

	return xadc_update_adc_reg(xadc, XADC_REG_CONF2, XADC_CONF2_PD_MASK,
		val);
}

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

Annotation

Implementation Notes