drivers/iio/magnetometer/mag3110.c
Source file repositories/reference/linux-study-clean/drivers/iio/magnetometer/mag3110.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/magnetometer/mag3110.c- Extension
.c- Size
- 15460 bytes
- Lines
- 648
- 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/cleanup.hlinux/module.hlinux/i2c.hlinux/iio/iio.hlinux/iio/sysfs.hlinux/iio/trigger_consumer.hlinux/iio/buffer.hlinux/iio/triggered_buffer.hlinux/delay.hlinux/regulator/consumer.h
Detected Declarations
struct mag3110_datafunction mag3110_requestfunction mag3110_readfunction mag3110_show_int_plus_microsfunction mag3110_get_int_plus_micros_indexfunction mag3110_show_samp_freq_availfunction mag3110_get_samp_freq_indexfunction mag3110_calculate_sleepfunction mag3110_standbyfunction mag3110_wait_standbyfunction mag3110_activefunction mag3110_is_activefunction mag3110_change_configfunction __mag3110_read_info_rawfunction mag3110_read_rawfunction __mag3110_write_rawfunction mag3110_write_rawfunction mag3110_trigger_handlerfunction mag3110_probefunction mag3110_removefunction mag3110_suspendfunction mag3110_resume
Annotated Snippet
struct mag3110_data {
struct i2c_client *client;
struct mutex lock;
u8 ctrl_reg1;
int sleep_val;
struct regulator *vdd_reg;
struct regulator *vddio_reg;
/* Ensure natural alignment of timestamp */
struct {
__be16 channels[3];
u8 temperature;
aligned_s64 ts;
} scan;
};
static int mag3110_request(struct mag3110_data *data)
{
int ret, tries = 150;
if ((data->ctrl_reg1 & MAG3110_CTRL_AC) == 0) {
/* trigger measurement */
ret = i2c_smbus_write_byte_data(data->client, MAG3110_CTRL_REG1,
data->ctrl_reg1 | MAG3110_CTRL_TM);
if (ret < 0)
return ret;
}
while (tries-- > 0) {
ret = i2c_smbus_read_byte_data(data->client, MAG3110_STATUS);
if (ret < 0)
return ret;
/* wait for data ready */
if ((ret & MAG3110_STATUS_DRDY) == MAG3110_STATUS_DRDY)
break;
if (data->sleep_val <= 20)
usleep_range(data->sleep_val * 250, data->sleep_val * 500);
else
msleep(20);
}
if (tries < 0) {
dev_err(&data->client->dev, "data not ready\n");
return -EIO;
}
return 0;
}
static int mag3110_read(struct mag3110_data *data, __be16 buf[3])
{
int ret;
guard(mutex)(&data->lock);
ret = mag3110_request(data);
if (ret < 0)
return ret;
return i2c_smbus_read_i2c_block_data(data->client, MAG3110_OUT_X,
3 * sizeof(__be16), (u8 *) buf);
}
static ssize_t mag3110_show_int_plus_micros(char *buf,
const int (*vals)[2], int n)
{
size_t len = 0;
while (n-- > 0)
len += scnprintf(buf + len, PAGE_SIZE - len,
"%d.%06d ", vals[n][0], vals[n][1]);
/* replace trailing space by newline */
buf[len - 1] = '\n';
return len;
}
static int mag3110_get_int_plus_micros_index(const int (*vals)[2], int n,
int val, int val2)
{
while (n-- > 0)
if (val == vals[n][0] && val2 == vals[n][1])
return n;
return -EINVAL;
}
static const int mag3110_samp_freq[8][2] = {
{80, 0}, {40, 0}, {20, 0}, {10, 0}, {5, 0}, {2, 500000},
{1, 250000}, {0, 625000}
};
Annotation
- Immediate include surface: `linux/cleanup.h`, `linux/module.h`, `linux/i2c.h`, `linux/iio/iio.h`, `linux/iio/sysfs.h`, `linux/iio/trigger_consumer.h`, `linux/iio/buffer.h`, `linux/iio/triggered_buffer.h`.
- Detected declarations: `struct mag3110_data`, `function mag3110_request`, `function mag3110_read`, `function mag3110_show_int_plus_micros`, `function mag3110_get_int_plus_micros_index`, `function mag3110_show_samp_freq_avail`, `function mag3110_get_samp_freq_index`, `function mag3110_calculate_sleep`, `function mag3110_standby`, `function mag3110_wait_standby`.
- 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.