drivers/hwmon/asb100.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/asb100.c
Extension
.c
Size
27797 bytes
Lines
1009
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 asb100_data {
	struct device *hwmon_dev;
	struct mutex lock;

	struct mutex update_lock;
	unsigned long last_updated;	/* In jiffies */

	/* array of 2 pointers to subclients */
	struct i2c_client *lm75[2];

	bool valid;		/* true if following fields are valid */
	u8 in[7];		/* Register value */
	u8 in_max[7];		/* Register value */
	u8 in_min[7];		/* Register value */
	u8 fan[3];		/* Register value */
	u8 fan_min[3];		/* Register value */
	u16 temp[4];		/* Register value (0 and 3 are u8 only) */
	u16 temp_max[4];	/* Register value (0 and 3 are u8 only) */
	u16 temp_hyst[4];	/* Register value (0 and 3 are u8 only) */
	u8 fan_div[3];		/* Register encoding, right justified */
	u8 pwm;			/* Register encoding */
	u8 vid;			/* Register encoding, combined */
	u32 alarms;		/* Register encoding, combined */
	u8 vrm;
};

static int asb100_read_value(struct i2c_client *client, u16 reg);
static void asb100_write_value(struct i2c_client *client, u16 reg, u16 val);

static int asb100_probe(struct i2c_client *client);
static int asb100_detect(struct i2c_client *client,
			 struct i2c_board_info *info);
static void asb100_remove(struct i2c_client *client);
static struct asb100_data *asb100_update_device(struct device *dev);
static void asb100_init_client(struct i2c_client *client);

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

static struct i2c_driver asb100_driver = {
	.class		= I2C_CLASS_HWMON,
	.driver = {
		.name	= "asb100",
	},
	.probe		= asb100_probe,
	.remove		= asb100_remove,
	.id_table	= asb100_id,
	.detect		= asb100_detect,
	.address_list	= normal_i2c,
};

/* 7 Voltages */
#define show_in_reg(reg) \
static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \
		char *buf) \
{ \
	int nr = to_sensor_dev_attr(attr)->index; \
	struct asb100_data *data = asb100_update_device(dev); \
	return sprintf(buf, "%d\n", IN_FROM_REG(data->reg[nr])); \
}

show_in_reg(in)
show_in_reg(in_min)
show_in_reg(in_max)

#define set_in_reg(REG, reg) \
static ssize_t set_in_##reg(struct device *dev, struct device_attribute *attr, \
		const char *buf, size_t count) \
{ \
	int nr = to_sensor_dev_attr(attr)->index; \
	struct i2c_client *client = to_i2c_client(dev); \
	struct asb100_data *data = i2c_get_clientdata(client); \
	unsigned long val; \
	int err = kstrtoul(buf, 10, &val); \
	if (err) \
		return err; \
	mutex_lock(&data->update_lock); \
	data->in_##reg[nr] = IN_TO_REG(val); \
	asb100_write_value(client, ASB100_REG_IN_##REG(nr), \
		data->in_##reg[nr]); \
	mutex_unlock(&data->update_lock); \
	return count; \
}

set_in_reg(MIN, min)
set_in_reg(MAX, max)

Annotation

Implementation Notes