drivers/hwmon/pmbus/tda38640.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/pmbus/tda38640.c
Extension
.c
Size
5781 bytes
Lines
225
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 tda38640_data {
	struct pmbus_driver_info info;
	u32 en_pin_lvl;
};

#define to_tda38640_data(x)  container_of(x, struct tda38640_data, info)

/*
 * Map PB_ON_OFF_CONFIG_POLARITY_HIGH to PB_OPERATION_CONTROL_ON.
 */
static int tda38640_read_byte_data(struct i2c_client *client, int page, int reg)
{
	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
	struct tda38640_data *data = to_tda38640_data(info);
	int ret, on_off_config, enabled;

	if (reg != PMBUS_OPERATION)
		return -ENODATA;

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

	on_off_config = pmbus_read_byte_data(client, page,
					     PMBUS_ON_OFF_CONFIG);
	if (on_off_config < 0)
		return on_off_config;

	enabled = !!(on_off_config & PB_ON_OFF_CONFIG_POLARITY_HIGH);

	enabled ^= data->en_pin_lvl;
	if (enabled)
		ret &= ~PB_OPERATION_CONTROL_ON;
	else
		ret |= PB_OPERATION_CONTROL_ON;

	return ret;
}

/*
 * Map PB_OPERATION_CONTROL_ON to PB_ON_OFF_CONFIG_POLARITY_HIGH.
 */
static int tda38640_write_byte_data(struct i2c_client *client, int page,
				    int reg, u8 byte)
{
	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
	struct tda38640_data *data = to_tda38640_data(info);
	int enable, ret;

	if (reg != PMBUS_OPERATION)
		return -ENODATA;

	enable = !!(byte & PB_OPERATION_CONTROL_ON);

	byte &= ~PB_OPERATION_CONTROL_ON;
	ret = pmbus_write_byte_data(client, page, reg, byte);
	if (ret < 0)
		return ret;

	enable ^= data->en_pin_lvl;

	return pmbus_update_byte_data(client, page, PMBUS_ON_OFF_CONFIG,
				      PB_ON_OFF_CONFIG_POLARITY_HIGH,
				      enable ? 0 : PB_ON_OFF_CONFIG_POLARITY_HIGH);
}

static int svid_mode(struct i2c_client *client, struct tda38640_data *data)
{
	/* PMBUS_MFR_READ(0xD0) + MTP Address offset */
	u8 write_buf[] = {0xd0, 0x44, 0x00};
	u8 read_buf[2];
	int ret, svid;
	bool off, reg_en_pin_pol;

	struct i2c_msg msgs[2] = {
		{
			.addr = client->addr,
			.flags = 0,
			.buf = write_buf,
			.len = sizeof(write_buf),
		},
		{
			.addr = client->addr,
			.flags = I2C_M_RD,
			.buf = read_buf,
			.len = sizeof(read_buf),
		}
	};

	ret = i2c_transfer(client->adapter, msgs, 2);

Annotation

Implementation Notes