drivers/iio/magnetometer/mmc5633.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/magnetometer/mmc5633.c
Extension
.c
Size
14372 bytes
Lines
587
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct mmc5633_data {
	struct regmap *regmap;
	struct i3c_device *i3cdev;
	struct mutex mutex; /* protect to finish one whole measurement */
};

static int mmc5633_samp_freq[][2] = {
	{ 1, 200000 },
	{ 2, 0 },
	{ 3, 500000 },
	{ 6, 600000 },
};

#define MMC5633_CHANNEL(_axis) { \
	.type = IIO_MAGN, \
	.modified = 1, \
	.channel2 = IIO_MOD_ ## _axis, \
	.address = MMC5633_AXIS_ ## _axis, \
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
				    BIT(IIO_CHAN_INFO_SCALE), \
}

static const struct iio_chan_spec mmc5633_channels[] = {
	MMC5633_CHANNEL(X),
	MMC5633_CHANNEL(Y),
	MMC5633_CHANNEL(Z),
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_SCALE) |
				      BIT(IIO_CHAN_INFO_OFFSET),
		.address = MMC5633_TEMPERATURE,
	},
};

static int mmc5633_get_samp_freq_index(struct mmc5633_data *data,
				       int val, int val2)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(mmc5633_samp_freq); i++)
		if (mmc5633_samp_freq[i][0] == val &&
		    mmc5633_samp_freq[i][1] == val2)
			return i;
	return -EINVAL;
}

static int mmc5633_init(struct mmc5633_data *data)
{
	unsigned int reg_id;
	int ret;

	ret = regmap_read(data->regmap, MMC5633_REG_ID, &reg_id);
	if (ret)
		return dev_err_probe(regmap_get_device(data->regmap), ret,
				     "Error reading product id\n");

	/*
	 * Make sure we restore sensor characteristics, by doing
	 * a SET/RESET sequence, the axis polarity being naturally
	 * aligned after RESET.
	 */
	ret = regmap_write(data->regmap, MMC5633_REG_CTRL0, MMC5633_CTRL0_SET);
	if (ret)
		return ret;

	/*
	 * Minimum time interval between SET or RESET to other operations is
	 * 1ms according to Operating Timing Diagram in datasheet.
	 */
	fsleep(MMC5633_WAIT_SET_RESET_US);

	ret = regmap_write(data->regmap, MMC5633_REG_CTRL0, MMC5633_CTRL0_RESET);
	if (ret)
		return ret;

	/* set default sampling frequency */
	return regmap_update_bits(data->regmap, MMC5633_REG_CTRL1,
				  MMC5633_CTRL1_BW_MASK,
				  FIELD_PREP(MMC5633_CTRL1_BW_MASK, 0));
}

static int mmc5633_take_measurement(struct mmc5633_data *data, int address)
{
	unsigned int reg_status, val;
	int ret;

	val = (address == MMC5633_TEMPERATURE) ? MMC5633_CTRL0_MEAS_T : MMC5633_CTRL0_MEAS_M;
	ret = regmap_write(data->regmap, MMC5633_REG_CTRL0, val);

Annotation

Implementation Notes