drivers/hwmon/kfan.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/kfan.c
Extension
.c
Size
5087 bytes
Lines
247
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 kfan {
	void __iomem *base;
	bool tacho;
	bool regulable;

	/* hwmon API configuration */
	u32 fan_channel_config[2];
	struct hwmon_channel_info fan_info;
	u32 pwm_channel_config[2];
	struct hwmon_channel_info pwm_info;
	const struct hwmon_channel_info *info[3];
	struct hwmon_chip_info chip;
};

static bool kfan_get_fault(struct kfan *kfan)
{
	u8 status = ioread8(kfan->base + KFAN_STATUS_REG);

	if (!(status & KFAN_STATUS_PRESENT))
		return true;

	if (!kfan->tacho && (status & KFAN_STATUS_BLOCKED))
		return true;

	return false;
}

static unsigned int kfan_count_to_rpm(u16 count)
{
	if (count == 0 || count == 0xffff)
		return 0;

	return 5000000UL / (KFAN_DEFAULT_DIV * count);
}

static unsigned int kfan_get_rpm(struct kfan *kfan)
{
	unsigned int rpm;
	u16 count;

	count = ioread16(kfan->base + KFAN_TACHO_REG);
	rpm = kfan_count_to_rpm(count);

	return rpm;
}

static unsigned int kfan_get_pwm(struct kfan *kfan)
{
	return ioread8(kfan->base + KFAN_CONTROL_REG);
}

static int kfan_set_pwm(struct kfan *kfan, long val)
{
	if (val < 0 || val > 0xff)
		return -EINVAL;

	/* if none-regulable, then only 0 or 0xff can be written */
	if (!kfan->regulable && val > 0)
		val = 0xff;

	iowrite8(val, kfan->base + KFAN_CONTROL_REG);

	return 0;
}

static int kfan_write(struct device *dev, enum hwmon_sensor_types type,
		      u32 attr, int channel, long val)
{
	struct kfan *kfan = dev_get_drvdata(dev);

	switch (type) {
	case hwmon_pwm:
		switch (attr) {
		case hwmon_pwm_input:
			return kfan_set_pwm(kfan, val);
		default:
			break;
		}
		break;
	default:
		break;
	}

	return -EOPNOTSUPP;
}

static int kfan_read(struct device *dev, enum hwmon_sensor_types type,
		     u32 attr, int channel, long *val)
{
	struct kfan *kfan = dev_get_drvdata(dev);

Annotation

Implementation Notes