drivers/hwmon/pmbus/isl68137.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/pmbus/isl68137.c
Extension
.c
Size
17407 bytes
Lines
530
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 isl68137_channel {
	u32 vout_voltage_divider[2];
};

struct isl68137_data {
	struct pmbus_driver_info info;
	struct isl68137_channel channel[MAX_CHANNELS];
};

#define to_isl68137_data(x)	container_of(x, struct isl68137_data, info)

static ssize_t isl68137_avs_enable_show_page(struct i2c_client *client,
					     int page,
					     char *buf)
{
	int val;

	val = pmbus_lock_interruptible(client);
	if (val)
		return val;

	val = pmbus_read_byte_data(client, page, PMBUS_OPERATION);

	pmbus_unlock(client);

	if (val < 0)
		return val;

	return sysfs_emit(buf, "%d\n",
			   (val & ISL68137_VOUT_AVS) == ISL68137_VOUT_AVS);
}

static ssize_t isl68137_avs_enable_store_page(struct i2c_client *client,
					      int page,
					      const char *buf, size_t count)
{
	int rc, op_val;
	bool result;

	rc = kstrtobool(buf, &result);
	if (rc)
		return rc;

	op_val = result ? ISL68137_VOUT_AVS : 0;

	rc = pmbus_lock_interruptible(client);
	if (rc)
		return rc;

	/*
	 * Writes to VOUT setpoint over AVSBus will persist after the VRM is
	 * switched to PMBus control. Switching back to AVSBus control
	 * restores this persisted setpoint rather than re-initializing to
	 * PMBus VOUT_COMMAND. Writing VOUT_COMMAND first over PMBus before
	 * enabling AVS control is the workaround.
	 */
	if (op_val == ISL68137_VOUT_AVS) {
		rc = pmbus_read_word_data(client, page, 0xff,
					  PMBUS_VOUT_COMMAND);
		if (rc < 0)
			goto unlock;

		rc = pmbus_write_word_data(client, page, PMBUS_VOUT_COMMAND,
					   rc);
		if (rc < 0)
			goto unlock;
	}

	rc = pmbus_update_byte_data(client, page, PMBUS_OPERATION,
				    ISL68137_VOUT_AVS, op_val);

unlock:
	pmbus_unlock(client);

	return (rc < 0) ? rc : count;
}

static ssize_t isl68137_avs_enable_show(struct device *dev,
					struct device_attribute *devattr,
					char *buf)
{
	struct i2c_client *client = to_i2c_client(dev->parent);
	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);

	return isl68137_avs_enable_show_page(client, attr->index, buf);
}

static ssize_t isl68137_avs_enable_store(struct device *dev,
				struct device_attribute *devattr,
				const char *buf, size_t count)

Annotation

Implementation Notes