drivers/hwmon/pmbus/mp5990.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/pmbus/mp5990.c
Extension
.c
Size
6034 bytes
Lines
231
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 mp5990_data {
	struct pmbus_driver_info info;
	u8 vout_mode;
	u8 vout_linear_exponent;
};

#define to_mp5990_data(x)  container_of(x, struct mp5990_data, info)

static int mp5990_read_byte_data(struct i2c_client *client, int page, int reg)
{
	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
	struct mp5990_data *data = to_mp5990_data(info);

	switch (reg) {
	case PMBUS_VOUT_MODE:
		if (data->vout_mode == linear) {
			/*
			 * The VOUT format used by the chip is linear11,
			 * not linear16. Report that VOUT is in linear mode
			 * and return exponent value extracted while probing
			 * the chip.
			 */
			return data->vout_linear_exponent;
		}

		/*
		 * The datasheet does not support the VOUT command,
		 * but the device responds with a default value of 0x17.
		 * In the standard, 0x17 represents linear mode.
		 * Therefore, we should report that VOUT is in direct
		 * format when the chip is configured for it.
		 */
		return PB_VOUT_MODE_DIRECT;

	default:
		return -ENODATA;
	}
}

static int mp5990_read_word_data(struct i2c_client *client, int page,
				 int phase, int reg)
{
	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
	struct mp5990_data *data = to_mp5990_data(info);
	int ret;
	s32 mantissa;

	switch (reg) {
	case PMBUS_READ_VOUT:
		ret = pmbus_read_word_data(client, page, phase, reg);
		if (ret < 0)
			return ret;
		/*
		 * Because the VOUT format used by the chip is linear11 and not
		 * linear16, we disregard bits[15:11]. The exponent is reported
		 * as part of the VOUT_MODE command.
		 */
		if (data->vout_mode == linear) {
			mantissa = ((s16)((ret & 0x7ff) << 5)) >> 5;
			ret = mantissa;
		}
		break;
	default:
		return -ENODATA;
	}

	return ret;
}

static struct pmbus_driver_info mp5990_info = {
	.pages = 1,
	.format[PSC_VOLTAGE_IN] = direct,
	.format[PSC_VOLTAGE_OUT] = direct,
	.format[PSC_CURRENT_OUT] = direct,
	.format[PSC_POWER] = direct,
	.format[PSC_TEMPERATURE] = direct,
	.m[PSC_VOLTAGE_IN] = 32,
	.b[PSC_VOLTAGE_IN] = 0,
	.R[PSC_VOLTAGE_IN] = 0,
	.m[PSC_VOLTAGE_OUT] = 32,
	.b[PSC_VOLTAGE_OUT] = 0,
	.R[PSC_VOLTAGE_OUT] = 0,
	.m[PSC_CURRENT_OUT] = 16,
	.b[PSC_CURRENT_OUT] = 0,
	.R[PSC_CURRENT_OUT] = 0,
	.m[PSC_POWER] = 1,
	.b[PSC_POWER] = 0,
	.R[PSC_POWER] = 0,
	.m[PSC_TEMPERATURE] = 1,
	.b[PSC_TEMPERATURE] = 0,

Annotation

Implementation Notes