1
0

feat(MP/kernel): add temperature API

- init and exit fonction for the module
- read_temp(), to get the temperature
This commit is contained in:
2026-06-05 11:46:39 +02:00
committed by Fastium
parent 66dd0c5192
commit ce3b308d6d
4 changed files with 152 additions and 5 deletions

View File

@@ -11,7 +11,15 @@ SOURCE := main
ifneq ($(KERNELRELEASE),)
obj-m += $(MODULE).o ## name of the generated module
$(MODULE)-objs := $(SOURCE).o ## list of objects needed for that module
# add folder sources
SOURCES_C := $(wildcard $(src)/*.c)
# add temperature sources
SOURCES_C += $(wildcard $(src)/temperature/*.c)
$(MODULE)-objs := $(patsubst $(src)/%.c, %.o, $(SOURCES_C))
# $(MODULE)-objs := $(SOURCE).o ## list of objects needed for that module
CFLAGS_$(SOURCE).o := -DDEBUG
# Part executed when called from standard make in module source directory:
@@ -28,7 +36,6 @@ clean:
install:
$(MAKE) -C $(KDIR) M=$(PWD) INSTALL_MOD_PATH=$(MODPATH) modules_install
install -D -m 0644 $(MODULE).conf $(MODPATH)/etc/modprobe.d/$(MODULE).conf
# install -D -m 0644 $(MODULE).conf $(MODPATH)/etc/modprobe.d/$(MODULE).conf
endif

View File

@@ -2,13 +2,41 @@
#include <linux/module.h> // needed by all modules
#include <linux/init.h> // needed for macros
#include <linux/kernel.h> // needed for debugging
#include <linux/kthread.h>
#include <linux/delay.h>
#include <linux/err.h>
#include "linux/printk.h"
#include "temperature/temp.h"
static struct task_struct *temp_thread = NULL;
/* Thread function that runs in the background */
static int temp_thread_fn(void *data) {
pr_info("temp_regulator: Background thread started\n");
while (!kthread_should_stop()) {
read_temp();
/* Wait 1 second (1000 milliseconds) */
msleep(1000);
}
pr_info("temp_regulator: Background thread stopping\n");
return 0;
}
static int __init temp_regulator_init(void) {
pr_info("Linux module temp_regulator loading...\n");
int ret;
/* Initialize temperature sensor API */
ret = temp_init();
if (ret != 0) {
pr_err("temp_regulator: Initialization failed with error %d\n", ret);
return ret;
}
pr_info("Linux module temp_regulator loaded\n");
return 0;
@@ -18,7 +46,9 @@ static void __exit temp_regulator_exit(void) {
pr_info("Linux module temp_regulator unloading...\n");
/* Release sensor resources */
temp_exit();
pr_info("Linux module temp_regulator unloaded\n");
}

View File

@@ -0,0 +1,83 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/errno.h>
#include "temp.h"
#define TEMPERATURE_SENSOR_BASE_ADDR 0x01C25000
#define TEMPERATURE_SENSOR_REG_SIZE 0x1000
#define TEMPERATURE_REG_OFFSET 0x80
static struct resource *temp_res = NULL;
static void __iomem *temp_reg = NULL;
int temp_init(void) {
/* Request physical memory region */
temp_res = request_mem_region(TEMPERATURE_SENSOR_BASE_ADDR,
TEMPERATURE_SENSOR_REG_SIZE,
"nanopi - temperature sensor");
if (temp_res == NULL) {
pr_warn("temp_regulator: Failed to reserve physical memory region\n");
}
/* Map the physical memory to virtual kernel memory */
temp_reg = ioremap(TEMPERATURE_SENSOR_BASE_ADDR, TEMPERATURE_SENSOR_REG_SIZE);
if (temp_reg == NULL) {
pr_err("temp_regulator: Failed to ioremap registers\n");
/* Clean up previously requested region */
release_mem_region(TEMPERATURE_SENSOR_BASE_ADDR, TEMPERATURE_SENSOR_REG_SIZE);
temp_res = NULL;
return -ENOMEM;
}
pr_info("temp_regulator: Temperature sensor memory successfully mapped\n");
return 0;
}
uint32_t read_temp(void) {
uint32_t temperature = 0;
uint32_t raw_val = 0;
if (temp_reg == NULL) {
pr_warn("temp_regulator: Cannot read temperature, sensor not initialized\n");
return 0;
}
/* Read the raw register value from THS0_DATA (offset 0x80) */
raw_val = ioread32(temp_reg + TEMPERATURE_REG_OFFSET);
/* Choose the correct formula according to the datasheet */
if (raw_val > 0x500) {
/* Temperature is lower than 70°C */
temperature = -1191 * (int32_t)raw_val / 10 + 223000;
} else {
/* Temperature is higher than or equal to 70°C */
temperature = -1452 * (int32_t)raw_val / 10 + 259000;
}
pr_info("temp_regulator: Temperature=%u.%03u C (register raw value: %u)\n",
temperature / 1000,
temperature % 1000,
raw_val);
return temperature;
}
void temp_exit(void) {
/* Unmap virtual address space */
if (temp_reg != NULL) {
iounmap(temp_reg);
temp_reg = NULL;
}
/* Release physical memory region */
if (temp_res != NULL) {
release_mem_region(TEMPERATURE_SENSOR_BASE_ADDR, TEMPERATURE_SENSOR_REG_SIZE);
temp_res = NULL;
}
pr_info("temp_regulator: Temperature sensor resources released\n");
}

View File

@@ -0,0 +1,27 @@
#ifndef TEMP_H
#define TEMP_H
#include <linux/types.h>
/**
* temp_init() - Request physical memory and map it into kernel virtual memory.
*
* Return: 0 on success, or a negative error code on failure.
*/
int temp_init(void);
/**
* read_temp() - Read the current CPU temperature from the mapped registers.
* To convert it in degrees Celsius, divide by 1000.0
*
* Return: The calculated temperature value.
*/
uint32_t read_temp(void);
/**
* temp_exit() - Unmap the virtual memory and release the requested physical memory region.
*/
void temp_exit(void);
#endif /* TEMP_H */