drivers/hwmon/max127.c

Source file repositories/reference/linux-study-clean/drivers/hwmon/max127.c

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/max127.c
Extension
.c
Size
7449 bytes
Lines
334
Domain
Driver Families
Bucket
drivers/hwmon
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 max127_data {
	struct i2c_client *client;
	u8 ctrl_byte[MAX127_NUM_CHANNELS];
};

static int max127_select_channel(struct i2c_client *client, u8 ctrl_byte)
{
	int status;
	struct i2c_msg msg = {
		.addr = client->addr,
		.flags = 0,
		.len = sizeof(ctrl_byte),
		.buf = &ctrl_byte,
	};

	status = i2c_transfer(client->adapter, &msg, 1);
	if (status < 0)
		return status;
	if (status != 1)
		return -EIO;

	return 0;
}

static int max127_read_channel(struct i2c_client *client, long *val)
{
	int status;
	u8 i2c_data[MAX127_DATA_LEN];
	struct i2c_msg msg = {
		.addr = client->addr,
		.flags = I2C_M_RD,
		.len = sizeof(i2c_data),
		.buf = i2c_data,
	};

	status = i2c_transfer(client->adapter, &msg, 1);
	if (status < 0)
		return status;
	if (status != 1)
		return -EIO;

	*val = (i2c_data[1] >> MAX127_DATA_SHIFT) |
		((u16)i2c_data[0] << MAX127_DATA_SHIFT);
	return 0;
}

static long max127_process_raw(u8 ctrl_byte, long raw)
{
	long scale, weight;

	/*
	 * MAX127's data coding is binary in unipolar mode with 1 LSB =
	 * (Full-Scale/4096) and two’s complement binary in bipolar mode
	 * with 1 LSB = [(2 x |FS|)/4096].
	 * Refer to MAX127 datasheet, "Transfer Function" section for
	 * details.
	 */
	scale = (ctrl_byte & MAX127_CTRL_RNG) ? MAX127_FULL_RANGE :
						MAX127_HALF_RANGE;
	if (ctrl_byte & MAX127_CTRL_BIP) {
		weight = (raw & MAX127_SIGN_BIT);
		raw &= ~MAX127_SIGN_BIT;
		raw -= weight;
		raw *= 2;
	}

	return raw * scale / 4096;
}

static int max127_read_input(struct max127_data *data, int channel, long *val)
{
	long raw;
	int status;
	struct i2c_client *client = data->client;
	u8 ctrl_byte = data->ctrl_byte[channel];

	status = max127_select_channel(client, ctrl_byte);
	if (status)
		return status;

	status = max127_read_channel(client, &raw);
	if (status)
		return status;

	*val = max127_process_raw(ctrl_byte, raw);
	return 0;
}

static int max127_read_min(struct max127_data *data, int channel, long *val)
{

Annotation

Implementation Notes