drivers/iio/magnetometer/rm3100-core.c

Source file repositories/reference/linux-study-clean/drivers/iio/magnetometer/rm3100-core.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/magnetometer/rm3100-core.c
Extension
.c
Size
15853 bytes
Lines
611
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rm3100_data {
	struct regmap *regmap;
	struct completion measuring_done;
	bool use_interrupt;
	int conversion_time;
	int scale;
	/* Ensure naturally aligned timestamp */
	u8 buffer[RM3100_SCAN_BYTES] __aligned(8);
	struct iio_trigger *drdy_trig;

	/*
	 * This lock is for protecting the consistency of series of i2c
	 * operations, that is, to make sure a measurement process will
	 * not be interrupted by a set frequency operation, which should
	 * be taken where a series of i2c operation starts, released where
	 * the operation ends.
	 */
	struct mutex lock;
};

static const struct regmap_range rm3100_readable_ranges[] = {
	regmap_reg_range(RM3100_R_REG_START, RM3100_R_REG_END),
};

const struct regmap_access_table rm3100_readable_table = {
	.yes_ranges = rm3100_readable_ranges,
	.n_yes_ranges = ARRAY_SIZE(rm3100_readable_ranges),
};
EXPORT_SYMBOL_NS_GPL(rm3100_readable_table, "IIO_RM3100");

static const struct regmap_range rm3100_writable_ranges[] = {
	regmap_reg_range(RM3100_W_REG_START, RM3100_W_REG_END),
};

const struct regmap_access_table rm3100_writable_table = {
	.yes_ranges = rm3100_writable_ranges,
	.n_yes_ranges = ARRAY_SIZE(rm3100_writable_ranges),
};
EXPORT_SYMBOL_NS_GPL(rm3100_writable_table, "IIO_RM3100");

static const struct regmap_range rm3100_volatile_ranges[] = {
	regmap_reg_range(RM3100_V_REG_START, RM3100_V_REG_END),
};

const struct regmap_access_table rm3100_volatile_table = {
	.yes_ranges = rm3100_volatile_ranges,
	.n_yes_ranges = ARRAY_SIZE(rm3100_volatile_ranges),
};
EXPORT_SYMBOL_NS_GPL(rm3100_volatile_table, "IIO_RM3100");

static irqreturn_t rm3100_thread_fn(int irq, void *d)
{
	struct iio_dev *indio_dev = d;
	struct rm3100_data *data = iio_priv(indio_dev);

	/*
	 * Write operation to any register or read operation
	 * to first byte of results will clear the interrupt.
	 */
	regmap_write(data->regmap, RM3100_REG_POLL, 0);

	return IRQ_HANDLED;
}

static irqreturn_t rm3100_irq_handler(int irq, void *d)
{
	struct iio_dev *indio_dev = d;
	struct rm3100_data *data = iio_priv(indio_dev);

	if (!iio_buffer_enabled(indio_dev))
		complete(&data->measuring_done);
	else
		iio_trigger_poll(data->drdy_trig);

	return IRQ_WAKE_THREAD;
}

static int rm3100_wait_measurement(struct rm3100_data *data)
{
	struct regmap *regmap = data->regmap;
	unsigned int val;
	int tries = 20;
	int ret;

	/*
	 * A read cycle of 400kbits i2c bus is about 20us, plus the time
	 * used for scheduling, a read cycle of fast mode of this device
	 * can reach 1.7ms, it may be possible for data to arrive just
	 * after we check the RM3100_REG_STATUS. In this case, irq_handler is
	 * called before measuring_done is reinitialized, it will wait

Annotation

Implementation Notes