drivers/sbus/char/bbc_envctrl.c

Source file repositories/reference/linux-study-clean/drivers/sbus/char/bbc_envctrl.c

File Facts

System
Linux kernel
Corpus path
drivers/sbus/char/bbc_envctrl.c
Extension
.c
Size
16245 bytes
Lines
602
Domain
Driver Families
Bucket
drivers/sbus
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 temp_limits {
	s8 high_pwroff, high_shutdown, high_warn;
	s8 low_warn, low_shutdown, low_pwroff;
};

static struct temp_limits cpu_temp_limits[2] = {
	{ 100, 85, 80, 5, -5, -10 },
	{ 100, 85, 80, 5, -5, -10 },
};

static struct temp_limits amb_temp_limits[2] = {
	{ 65, 55, 40, 5, -5, -10 },
	{ 65, 55, 40, 5, -5, -10 },
};

static LIST_HEAD(all_temps);
static LIST_HEAD(all_fans);

#define CPU_FAN_REG	0xf0
#define SYS_FAN_REG	0xf2
#define PSUPPLY_FAN_REG	0xf4

#define FAN_SPEED_MIN	0x0c
#define FAN_SPEED_MAX	0x3f

#define PSUPPLY_FAN_ON	0x1f
#define PSUPPLY_FAN_OFF	0x00

static void set_fan_speeds(struct bbc_fan_control *fp)
{
	/* Put temperatures into range so we don't mis-program
	 * the hardware.
	 */
	if (fp->cpu_fan_speed < FAN_SPEED_MIN)
		fp->cpu_fan_speed = FAN_SPEED_MIN;
	if (fp->cpu_fan_speed > FAN_SPEED_MAX)
		fp->cpu_fan_speed = FAN_SPEED_MAX;
	if (fp->system_fan_speed < FAN_SPEED_MIN)
		fp->system_fan_speed = FAN_SPEED_MIN;
	if (fp->system_fan_speed > FAN_SPEED_MAX)
		fp->system_fan_speed = FAN_SPEED_MAX;
#ifdef ENVCTRL_TRACE
	printk("fan%d: Changed fan speed to cpu(%02x) sys(%02x)\n",
	       fp->index,
	       fp->cpu_fan_speed, fp->system_fan_speed);
#endif

	bbc_i2c_writeb(fp->client, fp->cpu_fan_speed, CPU_FAN_REG);
	bbc_i2c_writeb(fp->client, fp->system_fan_speed, SYS_FAN_REG);
	bbc_i2c_writeb(fp->client,
		       (fp->psupply_fan_on ?
			PSUPPLY_FAN_ON : PSUPPLY_FAN_OFF),
		       PSUPPLY_FAN_REG);
}

static void get_current_temps(struct bbc_cpu_temperature *tp)
{
	tp->prev_amb_temp = tp->curr_amb_temp;
	bbc_i2c_readb(tp->client,
		      (unsigned char *) &tp->curr_amb_temp,
		      MAX1617_AMB_TEMP);
	tp->prev_cpu_temp = tp->curr_cpu_temp;
	bbc_i2c_readb(tp->client,
		      (unsigned char *) &tp->curr_cpu_temp,
		      MAX1617_CPU_TEMP);
#ifdef ENVCTRL_TRACE
	printk("temp%d: cpu(%d C) amb(%d C)\n",
	       tp->index,
	       (int) tp->curr_cpu_temp, (int) tp->curr_amb_temp);
#endif
}


static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp)
{
	static int shutting_down = 0;
	char *type = "???";
	s8 val = -1;

	if (shutting_down != 0)
		return;

	if (tp->curr_amb_temp >= amb_temp_limits[tp->index].high_shutdown ||
	    tp->curr_amb_temp < amb_temp_limits[tp->index].low_shutdown) {
		type = "ambient";
		val = tp->curr_amb_temp;
	} else if (tp->curr_cpu_temp >= cpu_temp_limits[tp->index].high_shutdown ||
		   tp->curr_cpu_temp < cpu_temp_limits[tp->index].low_shutdown) {
		type = "CPU";
		val = tp->curr_cpu_temp;

Annotation

Implementation Notes