drivers/hwmon/sch5627.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/sch5627.c
Extension
.c
Size
16315 bytes
Lines
663
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 sch5627_data {
	struct regmap *regmap;
	unsigned short addr;
	u8 control;

	struct mutex update_lock;
	unsigned long last_battery;	/* In jiffies */
	char temp_valid;		/* !=0 if following fields are valid */
	char fan_valid;
	char in_valid;
	unsigned long temp_last_updated;	/* In jiffies */
	unsigned long fan_last_updated;
	unsigned long in_last_updated;
	u16 temp[SCH5627_NO_TEMPS];
	u16 fan[SCH5627_NO_FANS];
	u16 in[SCH5627_NO_IN];
};

static const struct regmap_range sch5627_tunables_ranges[] = {
	regmap_reg_range(0x57, 0x57),
	regmap_reg_range(0x59, 0x59),
	regmap_reg_range(0x5B, 0x5B),
	regmap_reg_range(0x5D, 0x5D),
	regmap_reg_range(0x5F, 0x5F),
	regmap_reg_range(0x61, 0x69),
	regmap_reg_range(0x96, 0x9B),
	regmap_reg_range(0xA0, 0xA3),
	regmap_reg_range(0x184, 0x184),
	regmap_reg_range(0x186, 0x186),
	regmap_reg_range(0x1A8, 0x1A9),
};

static const struct regmap_access_table sch5627_tunables_table = {
	.yes_ranges = sch5627_tunables_ranges,
	.n_yes_ranges = ARRAY_SIZE(sch5627_tunables_ranges),
};

static const struct regmap_config sch5627_regmap_config = {
	.reg_bits = 16,
	.val_bits = 8,
	.wr_table = &sch5627_tunables_table,
	.rd_table = &sch5627_tunables_table,
	.cache_type = REGCACHE_MAPLE,
	.use_single_read = true,
	.use_single_write = true,
	.can_sleep = true,
};

static int sch5627_update_temp(struct sch5627_data *data)
{
	int ret = 0;
	int i, val;

	mutex_lock(&data->update_lock);

	/* Cache the values for 1 second */
	if (time_after(jiffies, data->temp_last_updated + HZ) || !data->temp_valid) {
		for (i = 0; i < SCH5627_NO_TEMPS; i++) {
			val = sch56xx_read_virtual_reg12(data->addr, SCH5627_REG_TEMP_MSB[i],
							 SCH5627_REG_TEMP_LSN[i],
							 SCH5627_REG_TEMP_HIGH_NIBBLE[i]);
			if (unlikely(val < 0)) {
				ret = val;
				goto abort;
			}
			data->temp[i] = val;
		}
		data->temp_last_updated = jiffies;
		data->temp_valid = 1;
	}
abort:
	mutex_unlock(&data->update_lock);
	return ret;
}

static int sch5627_update_fan(struct sch5627_data *data)
{
	int ret = 0;
	int i, val;

	mutex_lock(&data->update_lock);

	/* Cache the values for 1 second */
	if (time_after(jiffies, data->fan_last_updated + HZ) || !data->fan_valid) {
		for (i = 0; i < SCH5627_NO_FANS; i++) {
			val = sch56xx_read_virtual_reg16(data->addr, SCH5627_REG_FAN[i]);
			if (unlikely(val < 0)) {
				ret = val;
				goto abort;
			}

Annotation

Implementation Notes