drivers/hwmon/f75375s.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/f75375s.c
Extension
.c
Size
25835 bytes
Lines
903
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 f75375_data {
	unsigned short addr;
	struct device *hwmon_dev;

	const char *name;
	int kind;
	struct mutex update_lock; /* protect register access */
	bool valid;
	unsigned long last_updated;	/* In jiffies */
	unsigned long last_limits;	/* In jiffies */

	/* Register values */
	u8 in[4];
	u8 in_max[4];
	u8 in_min[4];
	u16 fan[2];
	u16 fan_min[2];
	u16 fan_max[2];
	u16 fan_target[2];
	u8 fan_timer;
	u8 pwm[2];
	u8 pwm_mode[2];
	u8 pwm_enable[2];
	/*
	 * f75387: For remote temperature reading, it uses signed 11-bit
	 * values with LSB = 0.125 degree Celsius, left-justified in 16-bit
	 * registers. For original 8-bit temp readings, the LSB just is 0.
	 */
	s16 temp11[2];
	s8 temp_high[2];
	s8 temp_max_hyst[2];
};

static inline int f75375_read8(struct i2c_client *client, u8 reg)
{
	return i2c_smbus_read_byte_data(client, reg);
}

/* in most cases, should be called while holding update_lock */
static inline u16 f75375_read16(struct i2c_client *client, u8 reg)
{
	return (i2c_smbus_read_byte_data(client, reg) << 8)
		| i2c_smbus_read_byte_data(client, reg + 1);
}

static inline void f75375_write8(struct i2c_client *client, u8 reg,
		u8 value)
{
	i2c_smbus_write_byte_data(client, reg, value);
}

static inline void f75375_write16(struct i2c_client *client, u8 reg,
		u16 value)
{
	int err = i2c_smbus_write_byte_data(client, reg, (value >> 8));
	if (err)
		return;
	i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF));
}

static void f75375_write_pwm(struct i2c_client *client, int nr)
{
	struct f75375_data *data = i2c_get_clientdata(client);
	if (data->kind == f75387)
		f75375_write16(client, F75375_REG_FAN_EXP(nr), data->pwm[nr]);
	else
		f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
			      data->pwm[nr]);
}

static struct f75375_data *f75375_update_device(struct device *dev)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct f75375_data *data = i2c_get_clientdata(client);
	int nr;

	mutex_lock(&data->update_lock);

	/* Limit registers cache is refreshed after 60 seconds */
	if (time_after(jiffies, data->last_limits + 60 * HZ)
		|| !data->valid) {
		for (nr = 0; nr < 2; nr++) {
			data->temp_high[nr] =
				f75375_read8(client, F75375_REG_TEMP_HIGH(nr));
			data->temp_max_hyst[nr] =
				f75375_read8(client, F75375_REG_TEMP_HYST(nr));
			data->fan_max[nr] =
				f75375_read16(client, F75375_REG_FAN_FULL(nr));
			data->fan_min[nr] =
				f75375_read16(client, F75375_REG_FAN_MIN(nr));

Annotation

Implementation Notes