drivers/hwmon/max1668.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/max1668.c
Extension
.c
Size
7985 bytes
Lines
320
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 max1668_data {
	struct regmap *regmap;
	int channels;
};

static int max1668_read(struct device *dev, enum hwmon_sensor_types type,
			u32 attr, int channel, long *val)
{
	struct max1668_data *data = dev_get_drvdata(dev);
	struct regmap *regmap = data->regmap;
	u32 regs[2] = { MAX1668_REG_STAT1, MAX1668_REG_TEMP(channel) };
	u8 regvals[2];
	u32 regval;
	int ret;

	switch (attr) {
	case hwmon_temp_input:
		ret = regmap_read(regmap, MAX1668_REG_TEMP(channel), &regval);
		if (ret)
			return ret;
		*val = sign_extend32(regval, 7) * 1000;
		break;
	case hwmon_temp_min:
		ret = regmap_read(regmap, MAX1668_REG_LIML(channel), &regval);
		if (ret)
			return ret;
		*val = sign_extend32(regval, 7) * 1000;
		break;
	case hwmon_temp_max:
		ret = regmap_read(regmap, MAX1668_REG_LIMH(channel), &regval);
		if (ret)
			return ret;
		*val = sign_extend32(regval, 7) * 1000;
		break;
	case hwmon_temp_min_alarm:
		ret = regmap_read(regmap,
				  channel ? MAX1668_REG_STAT2 : MAX1668_REG_STAT1,
				  &regval);
		if (ret)
			return ret;
		if (channel)
			*val = !!(regval & BIT(9 - channel * 2));
		else
			*val = !!(regval & BIT(5));
		break;
	case hwmon_temp_max_alarm:
		ret = regmap_read(regmap,
				  channel ? MAX1668_REG_STAT2 : MAX1668_REG_STAT1,
				  &regval);
		if (ret)
			return ret;
		if (channel)
			*val = !!(regval & BIT(8 - channel * 2));
		else
			*val = !!(regval & BIT(6));
		break;
	case hwmon_temp_fault:
		ret = regmap_multi_reg_read(regmap, regs, regvals, 2);
		if (ret)
			return ret;
		*val = !!((regvals[0] & BIT(4)) && regvals[1] == 127);
		break;
	default:
		return -EOPNOTSUPP;
	}
	return 0;
}

static int max1668_write(struct device *dev, enum hwmon_sensor_types type,
			 u32 attr, int channel, long val)
{
	struct max1668_data *data = dev_get_drvdata(dev);
	struct regmap *regmap = data->regmap;

	val = clamp_val(val / 1000, -128, 127);

	switch (attr) {
	case hwmon_temp_min:
		return regmap_write(regmap, MAX1668_REG_LIML(channel), val);
	case hwmon_temp_max:
		return regmap_write(regmap, MAX1668_REG_LIMH(channel), val);
	default:
		return -EOPNOTSUPP;
	}
}

static umode_t max1668_is_visible(const void *_data, enum hwmon_sensor_types type,
				  u32 attr, int channel)
{
	const struct max1668_data *data = _data;

Annotation

Implementation Notes