drivers/iio/adc/men_z188_adc.c

Source file repositories/reference/linux-study-clean/drivers/iio/adc/men_z188_adc.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/men_z188_adc.c
Extension
.c
Size
3680 bytes
Lines
175
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

struct z188_adc {
	struct resource *mem;
	void __iomem *base;
};

#define Z188_ADC_CHANNEL(idx) {					\
		.type = IIO_VOLTAGE,				\
		.indexed = 1,					\
		.channel = (idx),				\
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
}

static const struct iio_chan_spec z188_adc_iio_channels[] = {
	Z188_ADC_CHANNEL(0),
	Z188_ADC_CHANNEL(1),
	Z188_ADC_CHANNEL(2),
	Z188_ADC_CHANNEL(3),
	Z188_ADC_CHANNEL(4),
	Z188_ADC_CHANNEL(5),
	Z188_ADC_CHANNEL(6),
	Z188_ADC_CHANNEL(7),
};

static int z188_iio_read_raw(struct iio_dev *iio_dev,
			struct iio_chan_spec const *chan,
			int *val,
			int *val2,
			long info)
{
	struct z188_adc *adc = iio_priv(iio_dev);
	int ret;
	u16 tmp;

	switch (info) {
	case IIO_CHAN_INFO_RAW:
		tmp = readw(adc->base + chan->channel * 4);

		if (ADC_OVR(tmp)) {
			dev_info(&iio_dev->dev,
				"Oversampling error on ADC channel %d\n",
				chan->channel);
			return -EIO;
		}
		*val = ADC_DATA(tmp);
		ret = IIO_VAL_INT;
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

static const struct iio_info z188_adc_info = {
	.read_raw = &z188_iio_read_raw,
};

static void men_z188_config_channels(void __iomem *addr)
{
	int i;
	u32 cfg;
	u32 ctl;

	ctl = readl(addr + Z188_CTRL_REG);
	ctl |= Z188_CFG_AUTO;
	writel(ctl, addr + Z188_CTRL_REG);

	for (i = 0; i < Z188_ADC_MAX_CHAN; i++) {
		cfg = readl(addr + i);
		cfg &= ~Z188_ADC_GAIN;
		cfg |= Z188_MODE_VOLTAGE;
		writel(cfg, addr + i);
	}
}

static int men_z188_probe(struct mcb_device *dev,
			const struct mcb_device_id *id)
{
	struct z188_adc *adc;
	struct iio_dev *indio_dev;
	struct resource *mem;
	int ret;

	indio_dev = devm_iio_device_alloc(&dev->dev, sizeof(struct z188_adc));
	if (!indio_dev)
		return -ENOMEM;

	adc = iio_priv(indio_dev);
	indio_dev->name = "z188-adc";

Annotation

Implementation Notes