drivers/iio/adc/mcp3422.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/mcp3422.c
Extension
.c
Size
10347 bytes
Lines
428
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 mcp3422 {
	struct i2c_client *i2c;
	u8 id;
	u8 config;
	u8 pga[4];
	struct mutex lock;
};

static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig)
{
	int ret;

	ret = i2c_master_send(adc->i2c, &newconfig, 1);
	if (ret > 0) {
		adc->config = newconfig;
		ret = 0;
	}

	return ret;
}

static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config)
{
	int ret = 0;
	u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
	u8 buf[4] = {0, 0, 0, 0};
	u32 temp;

	if (sample_rate == MCP3422_SRATE_3) {
		ret = i2c_master_recv(adc->i2c, buf, 4);
		temp = get_unaligned_be24(&buf[0]);
		*config = buf[3];
	} else {
		ret = i2c_master_recv(adc->i2c, buf, 3);
		temp = get_unaligned_be16(&buf[0]);
		*config = buf[2];
	}

	*value = sign_extend32(temp, mcp3422_sign_extend[sample_rate]);

	return ret;
}

static int mcp3422_read_channel(struct mcp3422 *adc,
				struct iio_chan_spec const *channel, int *value)
{
	int ret;
	u8 config;
	u8 req_channel = channel->channel;

	mutex_lock(&adc->lock);

	if (req_channel != MCP3422_CHANNEL(adc->config)) {
		config = adc->config;
		config &= ~MCP3422_CHANNEL_MASK;
		config |= MCP3422_CHANNEL_VALUE(req_channel);
		config &= ~MCP3422_PGA_MASK;
		config |= MCP3422_PGA_VALUE(adc->pga[req_channel]);
		ret = mcp3422_update_config(adc, config);
		if (ret < 0) {
			mutex_unlock(&adc->lock);
			return ret;
		}
		msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]);
	}

	ret = mcp3422_read(adc, value, &config);

	mutex_unlock(&adc->lock);

	return ret;
}

static int mcp3422_read_raw(struct iio_dev *iio,
			struct iio_chan_spec const *channel, int *val1,
			int *val2, long mask)
{
	struct mcp3422 *adc = iio_priv(iio);
	int err;

	u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
	u8 pga		 = MCP3422_PGA(adc->config);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		err = mcp3422_read_channel(adc, channel, val1);
		if (err < 0)
			return -EINVAL;
		return IIO_VAL_INT;

Annotation

Implementation Notes