drivers/thermal/airoha_thermal.c
Source file repositories/reference/linux-study-clean/drivers/thermal/airoha_thermal.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/thermal/airoha_thermal.c- Extension
.c- Size
- 16451 bytes
- Lines
- 490
- 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/module.hlinux/bitfield.hlinux/delay.hlinux/interrupt.hlinux/mfd/syscon.hlinux/of.hlinux/of_address.hlinux/platform_device.hlinux/regmap.hlinux/thermal.h
Detected Declarations
struct airoha_thermal_privfunction airoha_get_thermal_ADCfunction airoha_init_thermal_ADC_modefunction airoha_thermal_get_tempfunction airoha_thermal_set_tripsfunction airoha_thermal_irqfunction airoha_thermal_setup_adc_valfunction airoha_thermal_setup_monitorfunction airoha_thermal_probe
Annotated Snippet
struct airoha_thermal_priv {
void __iomem *base;
struct regmap *chip_scu;
struct resource scu_adc_res;
struct thermal_zone_device *tz;
int init_temp;
int default_slope;
int default_offset;
};
static int airoha_get_thermal_ADC(struct airoha_thermal_priv *priv)
{
u32 val;
regmap_read(priv->chip_scu, EN7581_DOUT_TADC, &val);
return FIELD_GET(EN7581_DOUT_TADC_MASK, val);
}
static void airoha_init_thermal_ADC_mode(struct airoha_thermal_priv *priv)
{
u32 adc_mux, pllrg;
/* Save PLLRG current value */
regmap_read(priv->chip_scu, EN7581_PLLRG_PROTECT, &pllrg);
/* Give access to thermal regs */
regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, EN7581_SCU_THERMAL_PROTECT_KEY);
adc_mux = FIELD_PREP(EN7581_MUX_TADC, EN7581_SCU_THERMAL_MUX_DIODE1);
regmap_write(priv->chip_scu, EN7581_PWD_TADC, adc_mux);
/* Restore PLLRG value on exit */
regmap_write(priv->chip_scu, EN7581_PLLRG_PROTECT, pllrg);
}
static int airoha_thermal_get_temp(struct thermal_zone_device *tz, int *temp)
{
struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
int min_value, max_value, avg_value, value;
int i;
avg_value = 0;
min_value = INT_MAX;
max_value = INT_MIN;
for (i = 0; i < AIROHA_MAX_SAMPLES; i++) {
value = airoha_get_thermal_ADC(priv);
min_value = min(value, min_value);
max_value = max(value, max_value);
avg_value += value;
}
/* Drop min and max and average for the remaining sample */
avg_value -= (min_value + max_value);
avg_value /= AIROHA_MAX_SAMPLES - 2;
*temp = RAW_TO_TEMP(priv, avg_value);
return 0;
}
static int airoha_thermal_set_trips(struct thermal_zone_device *tz, int low,
int high)
{
struct airoha_thermal_priv *priv = thermal_zone_device_priv(tz);
bool enable_monitor = false;
if (high != INT_MAX) {
/* Validate high and clamp it a supported value */
high = clamp_t(int, high, RAW_TO_TEMP(priv, 0),
RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
/* We offset the high temp of 1°C to trigger correct event */
writel(TEMP_TO_RAW(priv, high) >> 4,
priv->base + EN7581_TEMPOFFSETH);
enable_monitor = true;
}
if (low != -INT_MAX) {
/* Validate low and clamp it to a supported value */
low = clamp_t(int, high, RAW_TO_TEMP(priv, 0),
RAW_TO_TEMP(priv, FIELD_MAX(EN7581_DOUT_TADC_MASK)));
/* We offset the low temp of 1°C to trigger correct event */
writel(TEMP_TO_RAW(priv, low) >> 4,
priv->base + EN7581_TEMPOFFSETL);
enable_monitor = true;
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/bitfield.h`, `linux/delay.h`, `linux/interrupt.h`, `linux/mfd/syscon.h`, `linux/of.h`, `linux/of_address.h`, `linux/platform_device.h`.
- Detected declarations: `struct airoha_thermal_priv`, `function airoha_get_thermal_ADC`, `function airoha_init_thermal_ADC_mode`, `function airoha_thermal_get_temp`, `function airoha_thermal_set_trips`, `function airoha_thermal_irq`, `function airoha_thermal_setup_adc_val`, `function airoha_thermal_setup_monitor`, `function airoha_thermal_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.