drivers/hwmon/ltq-cputemp.c

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

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/ltq-cputemp.c
Extension
.c
Size
2941 bytes
Lines
135
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

// SPDX-License-Identifier: GPL-2.0-or-later
/* Lantiq cpu temperature sensor driver
 *
 * Copyright (C) 2017 Florian Eckert <fe@dev.tdt.de>
 */

#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/init.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include <lantiq_soc.h>

/* gphy1 configuration register contains cpu temperature */
#define CGU_GPHY1_CR   0x0040
#define CGU_TEMP_PD    BIT(19)

static void ltq_cputemp_enable(void)
{
	ltq_cgu_w32(ltq_cgu_r32(CGU_GPHY1_CR) | CGU_TEMP_PD, CGU_GPHY1_CR);
}

static void ltq_cputemp_disable(void *data)
{
	ltq_cgu_w32(ltq_cgu_r32(CGU_GPHY1_CR) & ~CGU_TEMP_PD, CGU_GPHY1_CR);
}

static int ltq_read(struct device *dev, enum hwmon_sensor_types type,
		    u32 attr, int channel, long *temp)
{
	int value;

	switch (attr) {
	case hwmon_temp_input:
		/* get the temperature including one decimal place */
		value = (ltq_cgu_r32(CGU_GPHY1_CR) >> 9) & 0x01FF;
		value = value * 5;
		/* range -38 to +154 °C, register value zero is -38.0 °C */
		value -= 380;
		/* scale temp to millidegree */
		value = value * 100;
		break;
	default:
		return -EOPNOTSUPP;
	}

	*temp = value;
	return 0;
}

static umode_t ltq_is_visible(const void *_data, enum hwmon_sensor_types type,
			      u32 attr, int channel)
{
	if (type != hwmon_temp)
		return 0;

	switch (attr) {
	case hwmon_temp_input:
		return 0444;
	default:
		return 0;
	}
}

static const struct hwmon_channel_info * const ltq_info[] = {
	HWMON_CHANNEL_INFO(chip,
			   HWMON_C_REGISTER_TZ),
	HWMON_CHANNEL_INFO(temp,
			   HWMON_T_INPUT),
	NULL
};

static const struct hwmon_ops ltq_hwmon_ops = {
	.is_visible = ltq_is_visible,
	.read = ltq_read,
};

static const struct hwmon_chip_info ltq_chip_info = {
	.ops = &ltq_hwmon_ops,
	.info = ltq_info,
};

static int ltq_cputemp_probe(struct platform_device *pdev)
{
	struct device *hwmon_dev;
	int err = 0;

Annotation

Implementation Notes