drivers/iio/potentiostat/lmp91000.c
Source file repositories/reference/linux-study-clean/drivers/iio/potentiostat/lmp91000.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/potentiostat/lmp91000.c- Extension
.c- Size
- 10569 bytes
- Lines
- 426
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/i2c.hlinux/delay.hlinux/mod_devicetable.hlinux/regmap.hlinux/iio/iio.hlinux/iio/buffer.hlinux/iio/consumer.hlinux/iio/trigger.hlinux/iio/trigger_consumer.hlinux/iio/triggered_buffer.h
Detected Declarations
struct lmp91000_datafunction lmp91000_readfunction lmp91000_buffer_handlerfunction lmp91000_read_rawfunction lmp91000_read_configfunction lmp91000_buffer_cbfunction lmp91000_buffer_postenablefunction lmp91000_buffer_predisablefunction lmp91000_probefunction lmp91000_remove
Annotated Snippet
struct lmp91000_data {
struct regmap *regmap;
struct device *dev;
struct iio_trigger *trig;
struct iio_cb_buffer *cb_buffer;
struct iio_channel *adc_chan;
struct completion completion;
u8 chan_select;
/* 64-bit data + 64-bit naturally aligned timestamp */
u32 buffer[4] __aligned(8);
};
static const struct iio_chan_spec lmp91000_channels[] = {
{ /* chemical channel mV */
.type = IIO_VOLTAGE,
.channel = 0,
.address = LMP91000_REG_MODECN_3LEAD,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE),
.scan_index = 0,
.scan_type = {
.sign = 's',
.realbits = 32,
.storagebits = 32,
},
},
IIO_CHAN_SOFT_TIMESTAMP(1),
{ /* temperature channel mV */
.type = IIO_TEMP,
.channel = 1,
.address = LMP91000_REG_MODECN_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
.scan_index = -1,
},
};
static int lmp91000_read(struct lmp91000_data *data, int channel, int *val)
{
int state, ret;
ret = regmap_read(data->regmap, LMP91000_REG_MODECN, &state);
if (ret)
return -EINVAL;
ret = regmap_write(data->regmap, LMP91000_REG_MODECN, channel);
if (ret)
return -EINVAL;
/* delay till first temperature reading is complete */
if (state != channel && channel == LMP91000_REG_MODECN_TEMP)
usleep_range(3000, 4000);
data->chan_select = channel != LMP91000_REG_MODECN_3LEAD;
iio_trigger_poll_nested(data->trig);
ret = wait_for_completion_timeout(&data->completion, HZ);
reinit_completion(&data->completion);
if (!ret)
return -ETIMEDOUT;
*val = data->buffer[data->chan_select];
return 0;
}
static irqreturn_t lmp91000_buffer_handler(int irq, void *private)
{
struct iio_poll_func *pf = private;
struct iio_dev *indio_dev = pf->indio_dev;
struct lmp91000_data *data = iio_priv(indio_dev);
int ret, val;
memset(data->buffer, 0, sizeof(data->buffer));
ret = lmp91000_read(data, LMP91000_REG_MODECN_3LEAD, &val);
if (!ret) {
data->buffer[0] = val;
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
iio_get_time_ns(indio_dev));
}
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/i2c.h`, `linux/delay.h`, `linux/mod_devicetable.h`, `linux/regmap.h`, `linux/iio/iio.h`, `linux/iio/buffer.h`, `linux/iio/consumer.h`.
- Detected declarations: `struct lmp91000_data`, `function lmp91000_read`, `function lmp91000_buffer_handler`, `function lmp91000_read_raw`, `function lmp91000_read_config`, `function lmp91000_buffer_cb`, `function lmp91000_buffer_postenable`, `function lmp91000_buffer_predisable`, `function lmp91000_probe`, `function lmp91000_remove`.
- Atlas domain: Driver Families / drivers/iio.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.