drivers/thermal/renesas/rzg3e_thermal.c

Source file repositories/reference/linux-study-clean/drivers/thermal/renesas/rzg3e_thermal.c

File Facts

System
Linux kernel
Corpus path
drivers/thermal/renesas/rzg3e_thermal.c
Extension
.c
Size
15347 bytes
Lines
572
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct rzg3e_thermal_info {
	int (*get_trim)(struct rzg3e_thermal_priv *priv);
	int temp_d_mc;
	int temp_e_mc;
};

/**
 * struct rzg3e_thermal_priv - RZ/G3E TSU private data
 * @base: TSU register base
 * @dev: device pointer
 * @syscon: regmap for calibration values
 * @zone: thermal zone device
 * @rstc: reset control
 * @info: chip type specific information
 * @trmval0: calibration value 0 (b)
 * @trmval1: calibration value 1 (c)
 * @lock: protects hardware access during conversions
 */
struct rzg3e_thermal_priv {
	void __iomem *base;
	struct device *dev;
	struct thermal_zone_device *zone;
	struct reset_control *rstc;
	const struct rzg3e_thermal_info *info;
	u16 trmval0;
	u16 trmval1;
	struct mutex lock;
};

static int rzg3e_thermal_power_on(struct rzg3e_thermal_priv *priv)
{
	u32 val;
	int ret;

	/* Clear any pending interrupts */
	writel(TSU_SICR_ADCLR | TSU_SICR_CMPCLR, priv->base + TSU_SICR);

	/* Disable all interrupts during setup */
	writel(0, priv->base + TSU_SIER);

	/*
	 * Power-on sequence per datasheet 7.11.9.1:
	 * SOC_TS_EN must be set at same time or before EN_TS and ADC_PD_TS
	 */
	val = TSU_SSUSR_SOC_TS_EN | TSU_SSUSR_EN_TS;
	writel(val, priv->base + TSU_SSUSR);

	/* Wait for sensor stabilization per datasheet 7.11.7.1 */
	usleep_range(TSU_POWERUP_TIME_US, TSU_POWERUP_TIME_US + 10);

	/* Configure for average mode with 8 samples */
	val = TSU_SOSR1_OUTSEL | TSU_SOSR1_ADCT_8;
	writel(val, priv->base + TSU_SOSR1);

	/* Ensure we're in single scan mode (default) */
	val = readl(priv->base + TSU_SOSR1);
	if (val & TSU_SOSR1_ADCS) {
		dev_err(priv->dev, "Invalid scan mode setting\n");
		return -EINVAL;
	}

	/* Wait for any ongoing conversion to complete */
	ret = readl_poll_timeout(priv->base + TSU_SSR, val,
				 !(val & TSU_SSR_CONV),
				 TSU_POLL_DELAY_US,
				 USEC_PER_MSEC);
	if (ret) {
		dev_err(priv->dev, "Timeout waiting for conversion\n");
		return ret;
	}

	return 0;
}

static void rzg3e_thermal_power_off(struct rzg3e_thermal_priv *priv)
{
	/* Disable all interrupts */
	writel(0, priv->base + TSU_SIER);

	/* Clear pending interrupts */
	writel(TSU_SICR_ADCLR | TSU_SICR_CMPCLR, priv->base + TSU_SICR);

	/* Power down sequence per datasheet */
	writel(TSU_SSUSR_ADC_PD_TS, priv->base + TSU_SSUSR);
}

/*
 * Convert 12-bit sensor code to temperature in millicelsius
 * Formula from datasheet 7.11.7.8:
 * T(°C) = ((e - d) / (c - b)) * (a - b) + d

Annotation

Implementation Notes