drivers/iio/magnetometer/ak8974.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/magnetometer/ak8974.c
Extension
.c
Size
27022 bytes
Lines
1051
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 ak8974 {
	struct i2c_client *i2c;
	struct iio_mount_matrix orientation;
	struct regmap *map;
	struct regulator_bulk_data regs[2];
	const char *name;
	u8 variant;
	struct mutex lock;
	bool drdy_irq;
	struct completion drdy_complete;
	bool drdy_active_low;
	/* Ensure timestamp is naturally aligned */
	struct {
		__le16 channels[3];
		aligned_s64 ts;
	} scan;
};

static const char ak8974_reg_avdd[] = "avdd";
static const char ak8974_reg_dvdd[] = "dvdd";

static int ak8974_get_u16_val(struct ak8974 *ak8974, u8 reg, u16 *val)
{
	int ret;
	__le16 bulk;

	ret = regmap_bulk_read(ak8974->map, reg, &bulk, 2);
	if (ret)
		return ret;
	*val = le16_to_cpu(bulk);

	return 0;
}

static int ak8974_set_u16_val(struct ak8974 *ak8974, u8 reg, u16 val)
{
	__le16 bulk = cpu_to_le16(val);

	return regmap_bulk_write(ak8974->map, reg, &bulk, 2);
}

static int ak8974_set_power(struct ak8974 *ak8974, bool mode)
{
	int ret;
	u8 val;

	val = mode ? AK8974_CTRL1_POWER : 0;
	val |= AK8974_CTRL1_FORCE_EN;
	ret = regmap_write(ak8974->map, AK8974_CTRL1, val);
	if (ret < 0)
		return ret;

	if (mode)
		msleep(AK8974_ACTIVATE_DELAY);

	return 0;
}

static int ak8974_reset(struct ak8974 *ak8974)
{
	int ret;

	/* Power on to get register access. Sets CTRL1 reg to reset state */
	ret = ak8974_set_power(ak8974, AK8974_PWR_ON);
	if (ret)
		return ret;
	ret = regmap_write(ak8974->map, AK8974_CTRL2, AK8974_CTRL2_RESDEF);
	if (ret)
		return ret;
	ret = regmap_write(ak8974->map, AK8974_CTRL3, AK8974_CTRL3_RESDEF);
	if (ret)
		return ret;
	if (ak8974->variant != AK8974_WHOAMI_VALUE_HSCDTD008A) {
		ret = regmap_write(ak8974->map, AK8974_INT_CTRL,
				   AK8974_INT_CTRL_RESDEF);
		if (ret)
			return ret;
	} else {
		ret = regmap_write(ak8974->map, HSCDTD008A_CTRL4,
				   HSCDTD008A_CTRL4_RESDEF);
		if (ret)
			return ret;
	}

	/* After reset, power off is default state */
	return ak8974_set_power(ak8974, AK8974_PWR_OFF);
}

static int ak8974_configure(struct ak8974 *ak8974)
{

Annotation

Implementation Notes