drivers/hwmon/pmbus/mp2888.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/pmbus/mp2888.c
Extension
.c
Size
11682 bytes
Lines
408
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 mp2888_data {
	struct pmbus_driver_info info;
	int total_curr_resolution;
	int phase_curr_resolution;
	int curr_sense_gain;
};

#define to_mp2888_data(x)	container_of(x, struct mp2888_data, info)

static int mp2888_read_byte_data(struct i2c_client *client, int page, int reg)
{
	switch (reg) {
	case PMBUS_VOUT_MODE:
		/* Enforce VOUT direct format. */
		return PB_VOUT_MODE_DIRECT;
	default:
		return -ENODATA;
	}
}

static int
mp2888_current_sense_gain_and_resolution_get(struct i2c_client *client, struct mp2888_data *data)
{
	int ret;

	/*
	 * Obtain DrMOS current sense gain of power stage from the register
	 * , bits 0-2. The value is selected as below:
	 * 00b - 5µA/A, 01b - 8.5µA/A, 10b - 9.7µA/A, 11b - 10µA/A. Other
	 * values are reserved.
	 */
	ret = i2c_smbus_read_word_data(client, MP2888_MFR_SYS_CONFIG);
	if (ret < 0)
		return ret;

	switch (ret & MP2888_DRMOS_KCS) {
	case 0:
		data->curr_sense_gain = 85;
		break;
	case 1:
		data->curr_sense_gain = 97;
		break;
	case 2:
		data->curr_sense_gain = 100;
		break;
	case 3:
		data->curr_sense_gain = 50;
		break;
	default:
		return -EINVAL;
	}

	/*
	 * Obtain resolution selector for total and phase current report and protection.
	 * 0: original resolution; 1: half resolution (in such case phase current value should
	 * be doubled.
	 */
	data->total_curr_resolution = (ret & MP2888_TOTAL_CURRENT_RESOLUTION) >> 3;
	data->phase_curr_resolution = (ret & MP2888_PHASE_CURRENT_RESOLUTION) >> 4;

	return 0;
}

static int
mp2888_read_phase(struct i2c_client *client, struct mp2888_data *data, int page, int phase, u8 reg)
{
	int ret;

	ret = pmbus_read_word_data(client, page, phase, reg);
	if (ret < 0)
		return ret;

	if (!((phase + 1) % 2))
		ret >>= 8;
	ret &= 0xff;

	/*
	 * Output value is calculated as: (READ_CSx / 80 – 1.23) / (Kcs * Rcs)
	 * where:
	 * - Kcs is the DrMOS current sense gain of power stage, which is obtained from the
	 *   register MP2888_MFR_VR_CONFIG1, bits 13-12 with the following selection of DrMOS
	 *   (data->curr_sense_gain):
	 *   00b - 8.5µA/A, 01b - 9.7µA/A, 1b - 10µA/A, 11b - 5µA/A.
	 * - Rcs is the internal phase current sense resistor. This parameter depends on hardware
	 *   assembly. By default it is set to 1kΩ. In case of different assembly, user should
	 *   scale this parameter by dividing it by Rcs.
	 * If phase current resolution bit is set to 1, READ_CSx value should be doubled.
	 * Note, that current phase sensing, providing by the device is not accurate. This is
	 * because sampling of current occurrence of bit weight has a big deviation, especially for
	 * light load.

Annotation

Implementation Notes