drivers/thermal/k3_j72xx_bandgap.c

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

File Facts

System
Linux kernel
Corpus path
drivers/thermal/k3_j72xx_bandgap.c
Extension
.c
Size
15216 bytes
Lines
614
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 err_values {
	int refs[4];
	int errs[4];
};

static void create_table_segments(struct err_values *err_vals, int seg,
				  int *ref_table)
{
	int m = 0, c, num, den, i, err, idx1, idx2, err1, err2, ref1, ref2;

	if (seg == 0)
		idx1 = 0;
	else
		idx1 = err_vals->refs[seg];

	idx2 = err_vals->refs[seg + 1];
	err1 = err_vals->errs[seg];
	err2 = err_vals->errs[seg + 1];
	ref1 = err_vals->refs[seg];
	ref2 = err_vals->refs[seg + 1];

	/*
	 * Calculate the slope with adc values read from the register
	 * as the y-axis param and err in adc value as x-axis param
	 */
	num = ref2 - ref1;
	den = err2 - err1;
	if (den)
		m = num / den;
	c = ref2 - m * err2;

	/*
	 * Take care of divide by zero error if error values are same
	 * Or when the slope is 0
	 */
	if (den != 0 && m != 0) {
		for (i = idx1; i <= idx2; i++) {
			err = (i - c) / m;
			if (((i + err) < 0) || ((i + err) >= TABLE_SIZE))
				continue;
			derived_table[i] = ref_table[i + err];
		}
	} else { /* Constant error take care of divide by zero */
		for (i = idx1; i <= idx2; i++) {
			if (((i + err1) < 0) || ((i + err1) >= TABLE_SIZE))
				continue;
			derived_table[i] = ref_table[i + err1];
		}
	}
}

static int prep_lookup_table(struct err_values *err_vals, int *ref_table)
{
	int inc, i, seg;

	/*
	 * Fill up the lookup table under 3 segments
	 * region -40C to +30C
	 * region +30C to +125C
	 * region +125C to +150C
	 */
	for (seg = 0; seg < 3; seg++)
		create_table_segments(err_vals, seg, ref_table);

	/* Get to the first valid temperature */
	i = 0;
	while (!derived_table[i])
		i++;

	/*
	 * Get to the last zero index and back fill the temperature for
	 * sake of continuity
	 */
	if (i) {
		/* 300 milli celsius steps */
		while (i--)
			derived_table[i] = derived_table[i + 1] - 300;
	}

	/*
	 * Fill the last trailing 0s which are unfilled with increments of
	 * 100 milli celsius till 1023 code
	 */
	i = TABLE_SIZE - 1;
	while (!derived_table[i])
		i--;

	i++;
	inc = 1;
	while (i < TABLE_SIZE) {

Annotation

Implementation Notes