drivers/hwmon/w83792d.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/w83792d.c
Extension
.c
Size
55531 bytes
Lines
1645
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 w83792d_data {
	struct device *hwmon_dev;

	struct mutex update_lock;
	bool valid;		/* true if following fields are valid */
	unsigned long last_updated;	/* In jiffies */

	u8 in[9];		/* Register value */
	u8 in_max[9];		/* Register value */
	u8 in_min[9];		/* Register value */
	u16 low_bits;		/* Additional resolution to voltage in6-0 */
	u8 fan[7];		/* Register value */
	u8 fan_min[7];		/* Register value */
	u8 temp1[3];		/* current, over, thyst */
	u8 temp_add[2][6];	/* Register value */
	u8 fan_div[7];		/* Register encoding, shifted right */
	u8 pwm[7];		/* The 7 PWM outputs */
	u8 pwmenable[3];
	u32 alarms;		/* realtime status register encoding,combined */
	u8 chassis;		/* Chassis status */
	u8 thermal_cruise[3];	/* Smart FanI: Fan1,2,3 target value */
	u8 tolerance[3];	/* Fan1,2,3 tolerance(Smart Fan I/II) */
	u8 sf2_points[3][4];	/* Smart FanII: Fan1,2,3 temperature points */
	u8 sf2_levels[3][4];	/* Smart FanII: Fan1,2,3 duty cycle levels */
};

static int w83792d_probe(struct i2c_client *client);
static int w83792d_detect(struct i2c_client *client,
			  struct i2c_board_info *info);
static void w83792d_remove(struct i2c_client *client);
static struct w83792d_data *w83792d_update_device(struct device *dev);

#ifdef DEBUG
static void w83792d_print_debug(struct w83792d_data *data, struct device *dev);
#endif

static void w83792d_init_client(struct i2c_client *client);

static const struct i2c_device_id w83792d_id[] = {
	{ .name = "w83792d" },
	{ }
};
MODULE_DEVICE_TABLE(i2c, w83792d_id);

static struct i2c_driver w83792d_driver = {
	.class		= I2C_CLASS_HWMON,
	.driver = {
		.name = "w83792d",
	},
	.probe		= w83792d_probe,
	.remove		= w83792d_remove,
	.id_table	= w83792d_id,
	.detect		= w83792d_detect,
	.address_list	= normal_i2c,
};

static inline long in_count_from_reg(int nr, struct w83792d_data *data)
{
	/* in7 and in8 do not have low bits, but the formula still works */
	return (data->in[nr] << 2) | ((data->low_bits >> (2 * nr)) & 0x03);
}

/*
 * The SMBus locks itself. The Winbond W83792D chip has a bank register,
 * but the driver only accesses registers in bank 0, so we don't have
 * to switch banks and lock access between switches.
 */
static inline int w83792d_read_value(struct i2c_client *client, u8 reg)
{
	return i2c_smbus_read_byte_data(client, reg);
}

static inline int
w83792d_write_value(struct i2c_client *client, u8 reg, u8 value)
{
	return i2c_smbus_write_byte_data(client, reg, value);
}

/* following are the sysfs callback functions */
static ssize_t show_in(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
	int nr = sensor_attr->index;
	struct w83792d_data *data = w83792d_update_device(dev);
	return sprintf(buf, "%ld\n",
		       IN_FROM_REG(nr, in_count_from_reg(nr, data)));
}

#define show_in_reg(reg) \

Annotation

Implementation Notes