drivers/hwmon/w83791d.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/w83791d.c
Extension
.c
Size
50065 bytes
Lines
1663
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 w83791d_data {
	struct device *hwmon_dev;
	struct mutex update_lock;

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

	/* volts */
	u8 in[NUMBER_OF_VIN];		/* Register value */
	u8 in_max[NUMBER_OF_VIN];	/* Register value */
	u8 in_min[NUMBER_OF_VIN];	/* Register value */

	/* fans */
	u8 fan[NUMBER_OF_FANIN];	/* Register value */
	u8 fan_min[NUMBER_OF_FANIN];	/* Register value */
	u8 fan_div[NUMBER_OF_FANIN];	/* Register encoding, shifted right */

	/* Temperature sensors */

	s8 temp1[3];		/* current, over, thyst */
	s16 temp_add[2][3];	/* fixed point value. Top 8 bits are the
				 * integral part, bottom 8 bits are the
				 * fractional part. We only use the top
				 * 9 bits as the resolution is only
				 * to the 0.5 degree C...
				 * two sensors with three values
				 * (cur, over, hyst)
				 */

	/* PWMs */
	u8 pwm[5];		/* pwm duty cycle */
	u8 pwm_enable[3];	/* pwm enable status for fan 1-3
				 * (fan 4-5 only support manual mode)
				 */

	u8 temp_target[3];	/* pwm 1-3 target temperature */
	u8 temp_tolerance[3];	/* pwm 1-3 temperature tolerance */

	/* Misc */
	u32 alarms;		/* realtime status register encoding,combined */
	u8 beep_enable;		/* Global beep enable */
	u32 beep_mask;		/* Mask off specific beeps */
	u8 vid;			/* Register encoding, combined */
	u8 vrm;			/* hwmon-vid */
};

static int w83791d_probe(struct i2c_client *client);
static int w83791d_detect(struct i2c_client *client,
			  struct i2c_board_info *info);
static void w83791d_remove(struct i2c_client *client);

static int w83791d_read(struct i2c_client *client, u8 reg);
static int w83791d_write(struct i2c_client *client, u8 reg, u8 value);
static struct w83791d_data *w83791d_update_device(struct device *dev);

#ifdef DEBUG
static void w83791d_print_debug(struct w83791d_data *data, struct device *dev);
#endif

static void w83791d_init_client(struct i2c_client *client);

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

static struct i2c_driver w83791d_driver = {
	.class		= I2C_CLASS_HWMON,
	.driver = {
		.name = "w83791d",
	},
	.probe		= w83791d_probe,
	.remove		= w83791d_remove,
	.id_table	= w83791d_id,
	.detect		= w83791d_detect,
	.address_list	= normal_i2c,
};

/* following are the sysfs callback functions */
#define show_in_reg(reg) \
static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
			char *buf) \
{ \
	struct sensor_device_attribute *sensor_attr = \
						to_sensor_dev_attr(attr); \
	struct w83791d_data *data = w83791d_update_device(dev); \
	int nr = sensor_attr->index; \
	return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \
}

Annotation

Implementation Notes