drivers/hwmon/pmbus/mp2975.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/pmbus/mp2975.c
Extension
.c
Size
29420 bytes
Lines
1107
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 mp2975_driver_info {
	const struct pmbus_driver_info *info;
	enum chips chip_id;
};

struct mp2975_data {
	struct pmbus_driver_info info;
	enum chips chip_id;
	int vout_scale;
	int max_phases[MP2975_PAGE_NUM];
	int vid_step[MP2975_PAGE_NUM];
	int vref[MP2975_PAGE_NUM];
	int vref_off[MP2975_PAGE_NUM];
	int vout_max[MP2975_PAGE_NUM];
	int vout_ov_fixed[MP2975_PAGE_NUM];
	int curr_sense_gain[MP2975_PAGE_NUM];
};

static const struct regulator_desc __maybe_unused mp2975_reg_desc[] = {
	PMBUS_REGULATOR("vout", 0),
	PMBUS_REGULATOR("vout", 1),
};

#define to_mp2975_data(x)  container_of(x, struct mp2975_data, info)

static int mp2975_read_byte_data(struct i2c_client *client, int page, int reg)
{
	switch (reg) {
	case PMBUS_VOUT_MODE:
		/*
		 * Report direct format as configured by MFR_DC_LOOP_CTRL.
		 * Unlike on MP2971/MP2973 the reported VOUT_MODE isn't automatically
		 * internally updated, but always reads as PB_VOUT_MODE_VID.
		 */
		return PB_VOUT_MODE_DIRECT;
	default:
		return -ENODATA;
	}
}

static int
mp2975_read_word_helper(struct i2c_client *client, int page, int phase, u8 reg,
			u16 mask)
{
	int ret = pmbus_read_word_data(client, page, phase, reg);

	return (ret > 0) ? ret & mask : ret;
}

static int
mp2975_vid2direct(int vrf, int val)
{
	switch (vrf) {
	case vr12:
		if (val >= 0x01)
			return 250 + (val - 1) * 5;
		break;
	case vr13:
		if (val >= 0x01)
			return 500 + (val - 1) * 10;
		break;
	case imvp9:
		if (val >= 0x01)
			return 200 + (val - 1) * 10;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}

#define MAX_LIN_MANTISSA	(1023 * 1000)
#define MIN_LIN_MANTISSA	(511 * 1000)

/* Converts a milli-unit DIRECT value to LINEAR11 format */
static u16 mp2975_data2reg_linear11(s64 val)
{
	s16 exponent = 0, mantissa;
	bool negative = false;

	/* simple case */
	if (val == 0)
		return 0;

	/* Reduce large mantissa until it fits into 10 bit */
	while (val >= MAX_LIN_MANTISSA && exponent < 15) {
		exponent++;
		val >>= 1;
	}
	/* Increase small mantissa to improve precision */

Annotation

Implementation Notes