drivers/iio/imu/smi240.c
Source file repositories/reference/linux-study-clean/drivers/iio/imu/smi240.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/imu/smi240.c- Extension
.c- Size
- 15577 bytes
- Lines
- 621
- 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/bitfield.hlinux/bits.hlinux/delay.hlinux/device.hlinux/module.hlinux/regmap.hlinux/spi/spi.hlinux/unaligned.hlinux/units.hlinux/iio/buffer.hlinux/iio/iio.hlinux/iio/trigger.hlinux/iio/trigger_consumer.hlinux/iio/triggered_buffer.h
Detected Declarations
struct smi240_dataenum capture_modefunction Copyrightfunction smi240_crc3function smi240_sensor_data_is_validfunction smi240_regmap_spi_readfunction smi240_regmap_spi_writefunction smi240_soft_resetfunction smi240_soft_configfunction smi240_get_low_pass_filter_freqfunction smi240_get_datafunction smi240_trigger_handlerfunction iio_for_each_active_channelfunction smi240_read_availfunction smi240_read_rawfunction smi240_write_rawfunction smi240_write_raw_get_fmtfunction smi240_initfunction smi240_probe
Annotated Snippet
struct smi240_data {
struct regmap *regmap;
u16 accel_filter_freq;
u16 anglvel_filter_freq;
u8 built_in_self_test_count;
enum capture_mode capture;
/*
* Ensure natural alignment for timestamp if present.
* Channel size: 2 bytes.
* Max length needed: 2 * 3 channels + temp channel + 2 bytes padding + 8 byte ts.
* If fewer channels are enabled, less space may be needed, as
* long as the timestamp is still aligned to 8 bytes.
*/
s16 buf[12] __aligned(8);
__be32 spi_buf __aligned(IIO_DMA_MINALIGN);
};
enum {
SMI240_TEMP_OBJECT,
SMI240_SCAN_ACCEL_X,
SMI240_SCAN_ACCEL_Y,
SMI240_SCAN_ACCEL_Z,
SMI240_SCAN_GYRO_X,
SMI240_SCAN_GYRO_Y,
SMI240_SCAN_GYRO_Z,
SMI240_SCAN_TIMESTAMP,
};
static const struct iio_chan_spec smi240_channels[] = {
SMI240_TEMP_CHANNEL(SMI240_TEMP_OBJECT),
SMI240_DATA_CHANNEL(IIO_ACCEL, X, SMI240_SCAN_ACCEL_X),
SMI240_DATA_CHANNEL(IIO_ACCEL, Y, SMI240_SCAN_ACCEL_Y),
SMI240_DATA_CHANNEL(IIO_ACCEL, Z, SMI240_SCAN_ACCEL_Z),
SMI240_DATA_CHANNEL(IIO_ANGL_VEL, X, SMI240_SCAN_GYRO_X),
SMI240_DATA_CHANNEL(IIO_ANGL_VEL, Y, SMI240_SCAN_GYRO_Y),
SMI240_DATA_CHANNEL(IIO_ANGL_VEL, Z, SMI240_SCAN_GYRO_Z),
IIO_CHAN_SOFT_TIMESTAMP(SMI240_SCAN_TIMESTAMP),
};
static const int smi240_low_pass_freqs[] = { SMI240_LOW_BANDWIDTH_HZ,
SMI240_HIGH_BANDWIDTH_HZ };
static u8 smi240_crc3(u32 data, u8 init, u8 poly)
{
u8 crc = init;
u8 do_xor;
s8 i = 31;
do {
do_xor = crc & 0x04;
crc <<= 1;
crc |= 0x01 & (data >> i);
if (do_xor)
crc ^= poly;
crc &= SMI240_CRC_MASK;
} while (--i >= 0);
return crc;
}
static bool smi240_sensor_data_is_valid(u32 data)
{
if (smi240_crc3(data, SMI240_CRC_INIT, SMI240_CRC_POLY) != 0)
return false;
if (FIELD_GET(SMI240_READ_SD_BIT_MASK, data) &
FIELD_GET(SMI240_READ_CS_BIT_MASK, data))
return false;
return true;
}
static int smi240_regmap_spi_read(void *context, const void *reg_buf,
size_t reg_size, void *val_buf,
size_t val_size)
{
int ret;
u32 request, response;
u16 *val = val_buf;
struct spi_device *spi = context;
struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
struct smi240_data *iio_priv_data = iio_priv(indio_dev);
if (reg_size != 1 || val_size != 2)
return -EINVAL;
request = FIELD_PREP(SMI240_WRITE_BUS_ID_MASK, SMI240_BUS_ID);
request |= FIELD_PREP(SMI240_WRITE_CAP_BIT_MASK, iio_priv_data->capture);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/bits.h`, `linux/delay.h`, `linux/device.h`, `linux/module.h`, `linux/regmap.h`, `linux/spi/spi.h`, `linux/unaligned.h`.
- Detected declarations: `struct smi240_data`, `enum capture_mode`, `function Copyright`, `function smi240_crc3`, `function smi240_sensor_data_is_valid`, `function smi240_regmap_spi_read`, `function smi240_regmap_spi_write`, `function smi240_soft_reset`, `function smi240_soft_config`, `function smi240_get_low_pass_filter_freq`.
- 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.