drivers/iio/health/max30102.c
Source file repositories/reference/linux-study-clean/drivers/iio/health/max30102.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/health/max30102.c- Extension
.c- Size
- 15989 bytes
- Lines
- 628
- 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.
- 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/init.hlinux/interrupt.hlinux/delay.hlinux/err.hlinux/irq.hlinux/i2c.hlinux/mutex.hlinux/mod_devicetable.hlinux/regmap.hlinux/iio/iio.hlinux/iio/buffer.hlinux/iio/kfifo_buf.h
Detected Declarations
struct max30102_dataenum max30102_chip_idenum max3012_led_idxfunction max30102_set_powerfunction max30102_set_powermodefunction max30102_buffer_postenablefunction max30102_buffer_predisablefunction max30102_fifo_countfunction max30102_read_measurementfunction max30102_interrupt_handlerfunction max30102_get_current_idxfunction max30102_led_initfunction max30102_chip_initfunction max30102_read_tempfunction max30102_get_tempfunction max30102_read_rawfunction max30102_probefunction max30102_remove
Annotated Snippet
struct max30102_data {
struct i2c_client *client;
struct iio_dev *indio_dev;
struct mutex lock;
struct regmap *regmap;
enum max30102_chip_id chip_id;
u8 buffer[12];
__be32 processed_buffer[3]; /* 3 x 18-bit (padded to 32-bits) */
};
static const struct regmap_config max30102_regmap_config = {
.name = "max30102_regmap",
.reg_bits = 8,
.val_bits = 8,
};
static const unsigned long max30102_scan_masks[] = {
BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR),
0
};
static const unsigned long max30105_scan_masks[] = {
BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR),
BIT(MAX30102_LED_RED) | BIT(MAX30102_LED_IR) |
BIT(MAX30105_LED_GREEN),
0
};
#define MAX30102_INTENSITY_CHANNEL(_si, _mod) { \
.type = IIO_INTENSITY, \
.channel2 = _mod, \
.modified = 1, \
.scan_index = _si, \
.scan_type = { \
.sign = 'u', \
.shift = 8, \
.realbits = 18, \
.storagebits = 32, \
.endianness = IIO_BE, \
}, \
}
static const struct iio_chan_spec max30102_channels[] = {
MAX30102_INTENSITY_CHANNEL(MAX30102_LED_RED, IIO_MOD_LIGHT_RED),
MAX30102_INTENSITY_CHANNEL(MAX30102_LED_IR, IIO_MOD_LIGHT_IR),
{
.type = IIO_TEMP,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.scan_index = -1,
},
};
static const struct iio_chan_spec max30105_channels[] = {
MAX30102_INTENSITY_CHANNEL(MAX30102_LED_RED, IIO_MOD_LIGHT_RED),
MAX30102_INTENSITY_CHANNEL(MAX30102_LED_IR, IIO_MOD_LIGHT_IR),
MAX30102_INTENSITY_CHANNEL(MAX30105_LED_GREEN, IIO_MOD_LIGHT_GREEN),
{
.type = IIO_TEMP,
.info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
.scan_index = -1,
},
};
static int max30102_set_power(struct max30102_data *data, bool en)
{
return regmap_update_bits(data->regmap, MAX30102_REG_MODE_CONFIG,
MAX30102_REG_MODE_CONFIG_PWR,
en ? 0 : MAX30102_REG_MODE_CONFIG_PWR);
}
static int max30102_set_powermode(struct max30102_data *data, u8 mode, bool en)
{
u8 reg = mode;
if (!en)
reg |= MAX30102_REG_MODE_CONFIG_PWR;
return regmap_update_bits(data->regmap, MAX30102_REG_MODE_CONFIG,
MAX30102_REG_MODE_CONFIG_PWR |
MAX30102_REG_MODE_CONFIG_MODE_MASK, reg);
}
#define MAX30102_MODE_CONTROL_LED_SLOTS(slot2, slot1) \
((slot2 << MAX30102_REG_MODE_CONTROL_SLOT_SHIFT) | slot1)
static int max30102_buffer_postenable(struct iio_dev *indio_dev)
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/interrupt.h`, `linux/delay.h`, `linux/err.h`, `linux/irq.h`, `linux/i2c.h`, `linux/mutex.h`.
- Detected declarations: `struct max30102_data`, `enum max30102_chip_id`, `enum max3012_led_idx`, `function max30102_set_power`, `function max30102_set_powermode`, `function max30102_buffer_postenable`, `function max30102_buffer_predisable`, `function max30102_fifo_count`, `function max30102_read_measurement`, `function max30102_interrupt_handler`.
- 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.
- 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.