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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/err.hlinux/i2c.hlinux/module.hlinux/mod_devicetable.hlinux/delay.hlinux/sysfs.hlinux/unaligned.hlinux/iio/iio.hlinux/iio/sysfs.h
Detected Declarations
struct mcp3422function mcp3422_update_configfunction mcp3422_readfunction mcp3422_read_channelfunction mcp3422_read_rawfunction mcp3422_write_rawfunction mcp3422_write_raw_get_fmtfunction mcp3422_show_samp_freqsfunction mcp3422_show_scalesfunction mcp3422_probe
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
- Immediate include surface: `linux/err.h`, `linux/i2c.h`, `linux/module.h`, `linux/mod_devicetable.h`, `linux/delay.h`, `linux/sysfs.h`, `linux/unaligned.h`, `linux/iio/iio.h`.
- Detected declarations: `struct mcp3422`, `function mcp3422_update_config`, `function mcp3422_read`, `function mcp3422_read_channel`, `function mcp3422_read_raw`, `function mcp3422_write_raw`, `function mcp3422_write_raw_get_fmt`, `function mcp3422_show_samp_freqs`, `function mcp3422_show_scales`, `function mcp3422_probe`.
- Atlas domain: Driver Families / drivers/iio.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.