drivers/thermal/spacemit/k1_tsensor.c
Source file repositories/reference/linux-study-clean/drivers/thermal/spacemit/k1_tsensor.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/thermal/spacemit/k1_tsensor.c- Extension
.c- Size
- 7901 bytes
- Lines
- 281
- Domain
- Driver Families
- Bucket
- drivers/thermal
- 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.
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/clk.hlinux/err.hlinux/interrupt.hlinux/io.hlinux/kernel.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/reset.hlinux/slab.hlinux/thermal.h../thermal_hwmon.h
Detected Declarations
struct k1_tsensor_channelstruct k1_tsensorfunction k1_tsensor_initfunction k1_tsensor_enable_irqfunction Tfunction k1_tsensor_set_tripsfunction k1_tsensor_irq_threadfunction k1_tsensor_probe
Annotated Snippet
struct k1_tsensor_channel {
struct k1_tsensor *ts;
struct thermal_zone_device *tzd;
int id;
};
struct k1_tsensor {
void __iomem *base;
struct k1_tsensor_channel ch[MAX_SENSOR_NUMBER];
};
static void k1_tsensor_init(struct k1_tsensor *ts)
{
u32 val;
/* Disable all the interrupts */
writel(0xffffffff, ts->base + K1_TSENSOR_INT_EN_REG);
/* Configure ADC sampling time and filter period */
val = readl(ts->base + K1_TSENSOR_TIME_REG);
val &= ~K1_TSENSOR_TIME_MASK;
val |= K1_TSENSOR_TIME_FILTER_PERIOD |
K1_TSENSOR_TIME_ADC_CNT_RST |
K1_TSENSOR_TIME_WAIT_REF_CNT;
writel(val, ts->base + K1_TSENSOR_TIME_REG);
/*
* Enable all sensors' auto mode, enable dither control,
* consecutive mode, and power up sensor.
*/
val = readl(ts->base + K1_TSENSOR_PCTRL_REG);
val &= ~K1_TSENSOR_PCTRL_SW_CTRL;
val &= ~K1_TSENSOR_PCTRL_CTUNE;
val |= K1_TSENSOR_PCTRL_RAW_SEL |
K1_TSENSOR_PCTRL_TEMP_MODE |
K1_TSENSOR_PCTRL_HW_AUTO_MODE |
K1_TSENSOR_PCTRL_ENABLE;
writel(val, ts->base + K1_TSENSOR_PCTRL_REG);
/* Enable each sensor */
val = readl(ts->base + K1_TSENSOR_EN_REG);
val |= K1_TSENSOR_EN_ALL;
writel(val, ts->base + K1_TSENSOR_EN_REG);
}
static void k1_tsensor_enable_irq(struct k1_tsensor_channel *ch)
{
struct k1_tsensor *ts = ch->ts;
u32 val;
val = readl(ts->base + K1_TSENSOR_INT_CLR_REG);
val |= K1_TSENSOR_INT_MASK(ch->id);
writel(val, ts->base + K1_TSENSOR_INT_CLR_REG);
val = readl(ts->base + K1_TSENSOR_INT_EN_REG);
val &= ~K1_TSENSOR_INT_MASK(ch->id);
writel(val, ts->base + K1_TSENSOR_INT_EN_REG);
/* Enable thermal interrupt */
val = readl(ts->base + K1_TSENSOR_INT_EN_REG);
val |= K1_TSENSOR_INT_EN_MASK;
writel(val, ts->base + K1_TSENSOR_INT_EN_REG);
}
/*
* The conversion formula used is:
* T(m°C) = (((raw_value & mask) >> shift) - TEMPERATURE_OFFSET) * 1000
*/
static int k1_tsensor_get_temp(struct thermal_zone_device *tz, int *temp)
{
struct k1_tsensor_channel *ch = thermal_zone_device_priv(tz);
struct k1_tsensor *ts = ch->ts;
u32 val;
val = readl(ts->base + K1_TSENSOR_DATA_REG(ch->id));
if (ch->id % 2)
*temp = FIELD_GET(K1_TSENSOR_DATA_HIGH_MASK, val);
else
*temp = FIELD_GET(K1_TSENSOR_DATA_LOW_MASK, val);
*temp -= TEMPERATURE_OFFSET;
*temp *= 1000;
return 0;
}
/*
* For each sensor, the hardware threshold register is 32 bits:
* - Lower 16 bits [15:0] configure the low threshold temperature.
* - Upper 16 bits [31:16] configure the high threshold temperature.
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/err.h`, `linux/interrupt.h`, `linux/io.h`, `linux/kernel.h`, `linux/module.h`, `linux/of.h`.
- Detected declarations: `struct k1_tsensor_channel`, `struct k1_tsensor`, `function k1_tsensor_init`, `function k1_tsensor_enable_irq`, `function T`, `function k1_tsensor_set_trips`, `function k1_tsensor_irq_thread`, `function k1_tsensor_probe`.
- Atlas domain: Driver Families / drivers/thermal.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.