drivers/hwmon/pmbus/mp9941.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/pmbus/mp9941.c
Extension
.c
Size
7735 bytes
Lines
320
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 mp9941_data {
	struct pmbus_driver_info info;
	int vid_resolution;
};

#define to_mp9941_data(x) container_of(x, struct mp9941_data, info)

static int mp9941_set_vout_format(struct i2c_client *client)
{
	int ret;

	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
	if (ret < 0)
		return ret;

	ret = i2c_smbus_read_word_data(client, MFR_RESO_SET);
	if (ret < 0)
		return ret;

	/*
	 * page = 0, MFR_RESO_SET[7:6] defines the vout format
	 * 2'b11 set the vout format as direct
	 */
	ret = (ret & ~GENMASK(7, 6)) | FIELD_PREP(GENMASK(7, 6), 3);

	return i2c_smbus_write_word_data(client, MFR_RESO_SET, ret);
}

static int
mp9941_identify_vid_resolution(struct i2c_client *client, struct pmbus_driver_info *info)
{
	struct mp9941_data *data = to_mp9941_data(info);
	int ret;

	/*
	 * page = 2, MFR_VR_MULTI_CONFIG_R1[4:4] defines rail1 vid step value
	 * 1'b0 represents the vid step value is 10mV
	 * 1'b1 represents the vid step value is 5mV
	 */
	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 2);
	if (ret < 0)
		return ret;

	ret = i2c_smbus_read_word_data(client, MFR_VR_MULTI_CONFIG_R1);
	if (ret < 0)
		return ret;

	if (FIELD_GET(GENMASK(4, 4), ret))
		data->vid_resolution = 5;
	else
		data->vid_resolution = 10;

	return 0;
}

static int mp9941_identify_iin_scale(struct i2c_client *client)
{
	int ret;

	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
	if (ret < 0)
		return ret;

	ret = i2c_smbus_read_word_data(client, MFR_RESO_SET);
	if (ret < 0)
		return ret;

	ret = (ret & ~GENMASK(3, 2)) | FIELD_PREP(GENMASK(3, 2), 0);

	ret = i2c_smbus_write_word_data(client, MFR_RESO_SET, ret);
	if (ret < 0)
		return ret;

	/*
	 * page = 2, MFR_ICC_MAX[15:13] defines the iin scale
	 * 3'b000 set the iout scale as 0.5A/Lsb
	 */
	ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, 2);
	if (ret < 0)
		return ret;

	ret = i2c_smbus_read_word_data(client, MFR_ICC_MAX);
	if (ret < 0)
		return ret;

	ret = (ret & ~GENMASK(15, 13)) | FIELD_PREP(GENMASK(15, 13), 0);

	return i2c_smbus_write_word_data(client, MFR_ICC_MAX, ret);
}

Annotation

Implementation Notes