drivers/hwmon/pmbus/max16601.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/pmbus/max16601.c
Extension
.c
Size
10298 bytes
Lines
370
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 max16601_data {
	enum chips id;
	struct pmbus_driver_info info;
	struct i2c_client *vsa;
	int iout_avg_pkg;
};

#define to_max16601_data(x) container_of(x, struct max16601_data, info)

static int max16601_read_byte(struct i2c_client *client, int page, int reg)
{
	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
	struct max16601_data *data = to_max16601_data(info);

	if (page > 0) {
		if (page == 2)	/* VSA */
			return i2c_smbus_read_byte_data(data->vsa, reg);
		return -EOPNOTSUPP;
	}
	return -ENODATA;
}

static int max16601_read_word(struct i2c_client *client, int page, int phase,
			      int reg)
{
	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
	struct max16601_data *data = to_max16601_data(info);
	u8 buf[I2C_SMBUS_BLOCK_MAX + 1];
	int ret;

	switch (page) {
	case 0:		/* VCORE */
		if (phase == 0xff)
			return -ENODATA;
		switch (reg) {
		case PMBUS_READ_IIN:
		case PMBUS_READ_IOUT:
		case PMBUS_READ_TEMPERATURE_1:
			ret = i2c_smbus_write_byte_data(client, REG_PHASE_ID,
							phase);
			if (ret)
				return ret;
			ret = i2c_smbus_read_block_data(client,
							REG_PHASE_REPORTING,
							buf);
			if (ret < 0)
				return ret;
			if (ret < 6)
				return -EIO;
			switch (reg) {
			case PMBUS_READ_TEMPERATURE_1:
				return buf[1] << 8 | buf[0];
			case PMBUS_READ_IOUT:
				return buf[3] << 8 | buf[2];
			case PMBUS_READ_IIN:
				return buf[5] << 8 | buf[4];
			default:
				break;
			}
		}
		return -EOPNOTSUPP;
	case 1:		/* VCORE, read IIN/PIN from sensor element */
		switch (reg) {
		case PMBUS_READ_IIN:
			return i2c_smbus_read_word_data(client, REG_IIN_SENSOR);
		case PMBUS_READ_PIN:
			return i2c_smbus_read_word_data(client,
							REG_TOTAL_INPUT_POWER);
		default:
			break;
		}
		return -EOPNOTSUPP;
	case 2:		/* VSA */
		switch (reg) {
		case PMBUS_VIRT_READ_IOUT_MAX:
			ret = i2c_smbus_read_word_data(data->vsa,
						       REG_IOUT_AVG_PK);
			if (ret < 0)
				return ret;
			if (sign_extend32(ret, 10) >
			    sign_extend32(data->iout_avg_pkg, 10))
				data->iout_avg_pkg = ret;
			return data->iout_avg_pkg;
		case PMBUS_VIRT_RESET_IOUT_HISTORY:
			return 0;
		case PMBUS_IOUT_OC_FAULT_LIMIT:
		case PMBUS_IOUT_OC_WARN_LIMIT:
		case PMBUS_OT_FAULT_LIMIT:
		case PMBUS_OT_WARN_LIMIT:
		case PMBUS_READ_IIN:

Annotation

Implementation Notes