drivers/iio/magnetometer/tlv493d.c
Source file repositories/reference/linux-study-clean/drivers/iio/magnetometer/tlv493d.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/magnetometer/tlv493d.c- Extension
.c- Size
- 14633 bytes
- Lines
- 527
- 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/array_size.hlinux/bits.hlinux/bitfield.hlinux/cleanup.hlinux/delay.hlinux/dev_printk.hlinux/i2c.hlinux/iopoll.hlinux/module.hlinux/mod_devicetable.hlinux/pm.hlinux/pm_runtime.hlinux/regulator/consumer.hlinux/types.hlinux/units.hlinux/iio/buffer.hlinux/iio/iio.hlinux/iio/trigger_consumer.hlinux/iio/triggered_buffer.h
Detected Declarations
struct tlv493d_dataenum tlv493d_channelsenum tlv493d_op_modefunction tlv493d_write_all_regsfunction tlv493d_set_operating_modefunction tlv493d_get_channel_datafunction tlv493d_get_measurementsfunction tlv493d_initfunction tlv493d_read_rawfunction tlv493d_trigger_handlerfunction tlv493d_probefunction tlv493d_runtime_suspendfunction tlv493d_runtime_resume
Annotated Snippet
struct tlv493d_data {
struct i2c_client *client;
/* protects from simultaneous sensor access and register readings */
struct mutex lock;
enum tlv493d_op_mode mode;
u8 wr_regs[TLV493D_WR_REG_MAX];
};
/*
* Different mode has different measurement sampling time, this time is
* used in deriving the sleep and timeout while reading the data from
* sensor in polling.
* Power-down mode: No measurement.
* Fast mode: Freq:3.3 KHz. Measurement time:305 usec.
* Low-power mode: Freq:100 Hz. Measurement time:10 msec.
* Ultra low-power mode: Freq:10 Hz. Measurement time:100 msec.
* Master controlled mode: Freq:3.3 Khz. Measurement time:305 usec.
*/
static const u32 tlv493d_sample_rate_us[] = {
[TLV493D_OP_MODE_POWERDOWN] = 0,
[TLV493D_OP_MODE_FAST] = 305,
[TLV493D_OP_MODE_LOWPOWER] = 10 * USEC_PER_MSEC,
[TLV493D_OP_MODE_ULTRA_LOWPOWER] = 100 * USEC_PER_MSEC,
[TLV493D_OP_MODE_MASTERCONTROLLED] = 305,
};
static int tlv493d_write_all_regs(struct tlv493d_data *data)
{
int ret;
struct device *dev = &data->client->dev;
ret = i2c_master_send(data->client, data->wr_regs, ARRAY_SIZE(data->wr_regs));
if (ret < 0) {
dev_err(dev, "i2c write registers failed, error: %d\n", ret);
return ret;
}
return 0;
}
static int tlv493d_set_operating_mode(struct tlv493d_data *data, enum tlv493d_op_mode mode)
{
u8 *mode1_cfg = &data->wr_regs[TLV493D_WR_REG_MODE1];
u8 *mode2_cfg = &data->wr_regs[TLV493D_WR_REG_MODE2];
switch (mode) {
case TLV493D_OP_MODE_POWERDOWN:
FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 0);
FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 0);
break;
case TLV493D_OP_MODE_FAST:
FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 1);
FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 0);
break;
case TLV493D_OP_MODE_LOWPOWER:
FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 2);
FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 1);
break;
case TLV493D_OP_MODE_ULTRA_LOWPOWER:
FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 2);
FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 0);
break;
case TLV493D_OP_MODE_MASTERCONTROLLED:
FIELD_MODIFY(TLV493D_MODE1_MOD_LOWFAST, mode1_cfg, 3);
FIELD_MODIFY(TLV493D_MODE2_LP_PERIOD, mode2_cfg, 0);
break;
}
return tlv493d_write_all_regs(data);
}
static s16 tlv493d_get_channel_data(u8 *b, enum tlv493d_channels ch)
{
u16 val;
switch (ch) {
case TLV493D_AXIS_X:
val = FIELD_GET(TLV493D_BX_MAG_X_AXIS_MSB, b[TLV493D_RD_REG_BX]) << 4 |
FIELD_GET(TLV493D_BX2_MAG_X_AXIS_LSB, b[TLV493D_RD_REG_BX2]);
break;
case TLV493D_AXIS_Y:
val = FIELD_GET(TLV493D_BY_MAG_Y_AXIS_MSB, b[TLV493D_RD_REG_BY]) << 4 |
FIELD_GET(TLV493D_BX2_MAG_Y_AXIS_LSB, b[TLV493D_RD_REG_BX2]);
break;
case TLV493D_AXIS_Z:
val = FIELD_GET(TLV493D_BZ_MAG_Z_AXIS_MSB, b[TLV493D_RD_REG_BZ]) << 4 |
Annotation
- Immediate include surface: `linux/array_size.h`, `linux/bits.h`, `linux/bitfield.h`, `linux/cleanup.h`, `linux/delay.h`, `linux/dev_printk.h`, `linux/i2c.h`, `linux/iopoll.h`.
- Detected declarations: `struct tlv493d_data`, `enum tlv493d_channels`, `enum tlv493d_op_mode`, `function tlv493d_write_all_regs`, `function tlv493d_set_operating_mode`, `function tlv493d_get_channel_data`, `function tlv493d_get_measurements`, `function tlv493d_init`, `function tlv493d_read_raw`, `function tlv493d_trigger_handler`.
- 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.