drivers/iio/adc/mcp320x.c
Source file repositories/reference/linux-study-clean/drivers/iio/adc/mcp320x.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/adc/mcp320x.c- Extension
.c- Size
- 13375 bytes
- Lines
- 510
- 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/delay.hlinux/spi/spi.hlinux/module.hlinux/mod_devicetable.hlinux/iio/iio.hlinux/regulator/consumer.h
Detected Declarations
struct mcp320x_chip_infostruct mcp320xfunction mcp320x_channel_to_tx_datafunction mcp320x_adc_conversionfunction mcp320x_read_rawfunction mcp320x_regulator_disablefunction mcp320x_probe
Annotated Snippet
struct mcp320x_chip_info {
const struct iio_chan_spec *channels;
unsigned int num_channels;
unsigned int resolution;
unsigned int conv_time; /* usec */
};
/**
* struct mcp320x - Microchip SPI ADC instance
* @spi: SPI slave (parent of the IIO device)
* @msg: SPI message to select a channel and receive a value from the ADC
* @transfer: SPI transfers used by @msg
* @start_conv_msg: SPI message to start a conversion by briefly asserting CS
* @start_conv_transfer: SPI transfer used by @start_conv_msg
* @reg: regulator generating Vref
* @lock: protects read sequences
* @chip_info: ADC properties
* @tx_buf: buffer for @transfer[0] (not used on single-channel converters)
* @rx_buf: buffer for @transfer[1]
*/
struct mcp320x {
struct spi_device *spi;
struct spi_message msg;
struct spi_transfer transfer[2];
struct spi_message start_conv_msg;
struct spi_transfer start_conv_transfer;
struct regulator *reg;
struct mutex lock;
const struct mcp320x_chip_info *chip_info;
u8 tx_buf __aligned(IIO_DMA_MINALIGN);
u8 rx_buf[4];
};
static int mcp320x_channel_to_tx_data(int device_index,
const unsigned int channel, bool differential)
{
int start_bit = 1;
switch (device_index) {
case mcp3002:
case mcp3202:
return ((start_bit << 4) | (!differential << 3) |
(channel << 2));
case mcp3004:
case mcp3204:
case mcp3008:
case mcp3208:
return ((start_bit << 6) | (!differential << 5) |
(channel << 2));
default:
return -EINVAL;
}
}
static int mcp320x_adc_conversion(struct mcp320x *adc, u8 channel,
bool differential, int device_index, int *val)
{
int ret;
if (adc->chip_info->conv_time) {
ret = spi_sync(adc->spi, &adc->start_conv_msg);
if (ret < 0)
return ret;
usleep_range(adc->chip_info->conv_time,
adc->chip_info->conv_time + 100);
}
memset(&adc->rx_buf, 0, sizeof(adc->rx_buf));
if (adc->chip_info->num_channels > 1)
adc->tx_buf = mcp320x_channel_to_tx_data(device_index, channel,
differential);
ret = spi_sync(adc->spi, &adc->msg);
if (ret < 0)
return ret;
switch (device_index) {
case mcp3001:
*val = (adc->rx_buf[0] << 5 | adc->rx_buf[1] >> 3);
return 0;
case mcp3002:
case mcp3004:
case mcp3008:
*val = (adc->rx_buf[0] << 2 | adc->rx_buf[1] >> 6);
return 0;
case mcp3201:
*val = (adc->rx_buf[0] << 7 | adc->rx_buf[1] >> 1);
Annotation
- Immediate include surface: `linux/err.h`, `linux/delay.h`, `linux/spi/spi.h`, `linux/module.h`, `linux/mod_devicetable.h`, `linux/iio/iio.h`, `linux/regulator/consumer.h`.
- Detected declarations: `struct mcp320x_chip_info`, `struct mcp320x`, `function mcp320x_channel_to_tx_data`, `function mcp320x_adc_conversion`, `function mcp320x_read_raw`, `function mcp320x_regulator_disable`, `function mcp320x_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.