drivers/hwmon/adt7470.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/adt7470.c
Extension
.c
Size
34869 bytes
Lines
1321
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 adt7470_data {
	struct regmap		*regmap;
	struct mutex		lock;
	char			sensors_valid;
	char			limits_valid;
	unsigned long		sensors_last_updated;	/* In jiffies */
	unsigned long		limits_last_updated;	/* In jiffies */

	int			num_temp_sensors;	/* -1 = probe */
	int			temperatures_probed;

	s8			temp[ADT7470_TEMP_COUNT];
	s8			temp_min[ADT7470_TEMP_COUNT];
	s8			temp_max[ADT7470_TEMP_COUNT];
	u16			fan[ADT7470_FAN_COUNT];
	u16			fan_min[ADT7470_FAN_COUNT];
	u16			fan_max[ADT7470_FAN_COUNT];
	u16			alarm;
	u16			alarms_mask;
	u8			force_pwm_max;
	u8			pwm[ADT7470_PWM_COUNT];
	u8			pwm_max[ADT7470_PWM_COUNT];
	u8			pwm_automatic[ADT7470_PWM_COUNT];
	u8			pwm_min[ADT7470_PWM_COUNT];
	s8			pwm_tmin[ADT7470_PWM_COUNT];
	u8			pwm_auto_temp[ADT7470_PWM_COUNT];

	struct task_struct	*auto_update;
	unsigned int		auto_update_interval;
};

/*
 * 16-bit registers on the ADT7470 are low-byte first.  The data sheet says
 * that the low byte must be read before the high byte.
 */
static inline int adt7470_read_word_data(struct adt7470_data *data, unsigned int reg,
					 unsigned int *val)
{
	u8 regval[2];
	int err;

	err = regmap_bulk_read(data->regmap, reg, &regval, 2);
	if (err < 0)
		return err;

	*val = regval[0] | (regval[1] << 8);

	return 0;
}

static inline int adt7470_write_word_data(struct adt7470_data *data, unsigned int reg,
					  unsigned int val)
{
	u8 regval[2];

	regval[0] = val & 0xFF;
	regval[1] = val >> 8;

	return regmap_bulk_write(data->regmap, reg, &regval, 2);
}

/* Probe for temperature sensors.  Assumes lock is held */
static int adt7470_read_temperatures(struct adt7470_data *data)
{
	unsigned long res;
	unsigned int pwm_cfg[2];
	int err;
	int i;
	u8 pwm[ADT7470_FAN_COUNT];

	/* save pwm[1-4] config register */
	err = regmap_read(data->regmap, ADT7470_REG_PWM_CFG(0), &pwm_cfg[0]);
	if (err < 0)
		return err;
	err = regmap_read(data->regmap, ADT7470_REG_PWM_CFG(2), &pwm_cfg[1]);
	if (err < 0)
		return err;

	/* set manual pwm to whatever it is set to now */
	err = regmap_bulk_read(data->regmap, ADT7470_REG_PWM(0), &pwm[0],
			       ADT7470_PWM_COUNT);
	if (err < 0)
		return err;

	/* put pwm in manual mode */
	err = regmap_update_bits(data->regmap, ADT7470_REG_PWM_CFG(0),
				 ADT7470_PWM_AUTO_MASK, 0);
	if (err < 0)
		return err;
	err = regmap_update_bits(data->regmap, ADT7470_REG_PWM_CFG(2),

Annotation

Implementation Notes