drivers/hwmon/pmbus/zl6100.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/pmbus/zl6100.c
Extension
.c
Size
10672 bytes
Lines
424
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 zl6100_data {
	int id;
	struct pmbus_driver_info info;
};

#define to_zl6100_data(x)  container_of(x, struct zl6100_data, info)

#define ZL6100_MFR_CONFIG		0xd0
#define ZL6100_DEVICE_ID		0xe4

#define ZL6100_MFR_XTEMP_ENABLE		BIT(7)

#define ZL8802_MFR_USER_GLOBAL_CONFIG	0xe9
#define ZL8802_MFR_TMON_ENABLE		BIT(12)
#define ZL8802_MFR_USER_CONFIG		0xd1
#define ZL8802_MFR_XTEMP_ENABLE_2	BIT(1)
#define ZL8802_MFR_DDC_CONFIG		0xd3
#define ZL8802_MFR_PHASES_MASK		0x0007

#define MFR_VMON_OV_FAULT_LIMIT		0xf5
#define MFR_VMON_UV_FAULT_LIMIT		0xf6
#define MFR_READ_VMON			0xf7

#define VMON_UV_WARNING			BIT(5)
#define VMON_OV_WARNING			BIT(4)
#define VMON_UV_FAULT			BIT(1)
#define VMON_OV_FAULT			BIT(0)

#define ZL6100_WAIT_TIME		1000	/* uS	*/

static ushort delay = ZL6100_WAIT_TIME;
module_param(delay, ushort, 0644);
MODULE_PARM_DESC(delay, "Delay between chip accesses in uS");

/* Convert linear sensor value to milli-units */
static long zl6100_l2d(s16 l)
{
	s16 exponent;
	s32 mantissa;
	long val;

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

	val = mantissa;

	/* scale result to milli-units */
	val = val * 1000L;

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

	return val;
}

#define MAX_MANTISSA	(1023 * 1000)
#define MIN_MANTISSA	(511 * 1000)

static u16 zl6100_d2l(long val)
{
	s16 exponent = 0, mantissa;
	bool negative = false;

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

	if (val < 0) {
		negative = true;
		val = -val;
	}

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

	/* Convert mantissa from milli-units to units */
	mantissa = DIV_ROUND_CLOSEST(val, 1000);

	/* Ensure that resulting number is within range */
	if (mantissa > 0x3ff)

Annotation

Implementation Notes