drivers/hwmon/pmbus/mp2869.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/pmbus/mp2869.c
Extension
.c
Size
18193 bytes
Lines
667
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 mp2869_data {
	struct pmbus_driver_info info;
	bool mfr_thwn_flt_en;
	int vout_scale[MP2869_PAGE_NUM];
	int iout_scale[MP2869_PAGE_NUM];
};

static const int mp2869_vout_sacle[8] = {6400, 5120, 2560, 2048, 1024,
										 4, 2, 1};
static const int mp2869_iout_sacle[8] = {32, 1, 2, 4, 8, 16, 32, 64};

#define to_mp2869_data(x)	container_of(x, struct mp2869_data, info)

static u16 mp2869_reg2data_linear11(u16 word)
{
	s16 exponent;
	s32 mantissa;
	s64 val;

	exponent = ((s16)word) >> 11;
	mantissa = ((s16)((word & 0x7ff) << 5)) >> 5;
	val = mantissa;

	if (exponent >= 0)
		val <<= exponent;
	else
		val >>= -exponent;

	return val;
}

static int
mp2869_identify_thwn_flt(struct i2c_client *client, struct pmbus_driver_info *info,
			 int page)
{
	struct mp2869_data *data = to_mp2869_data(info);
	int ret;

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

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

	data->mfr_thwn_flt_en = FIELD_GET(GENMASK(13, 13), ret);

	return 0;
}

static int
mp2869_identify_vout_scale(struct i2c_client *client, struct pmbus_driver_info *info,
			   int page)
{
	struct mp2869_data *data = to_mp2869_data(info);
	int ret;

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

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

	/*
	 * The output voltage is equal to the READ_VOUT(0x8B) register value multiply
	 * by vout_scale.
	 * Obtain vout scale from the register PMBUS_VOUT_SCALE_LOOP, bits 12-10
	 * PMBUS_VOUT_SCALE_LOOP[12:10]:
	 * 000b - 6.25mV/LSB, 001b - 5mV/LSB, 010b - 2.5mV/LSB, 011b - 2mV/LSB
	 * 100b - 1mV/Lsb, 101b - (1/256)mV/LSB, 110b - (1/512)mV/LSB,
	 * 111b - (1/1024)mV/LSB
	 */
	data->vout_scale[page] = mp2869_vout_sacle[FIELD_GET(GENMASK(12, 10), ret)];

	return 0;
}

static int
mp2869_identify_iout_scale(struct i2c_client *client, struct pmbus_driver_info *info,
			   int page)
{
	struct mp2869_data *data = to_mp2869_data(info);
	int ret;

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

Annotation

Implementation Notes