1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef DRIVERS_I2C_LM96000_CHIP_H
#define DRIVERS_I2C_LM96000_CHIP_H
#include <stdint.h>
#define LM96000_VIN_CNT 5
#define LM96000_TEMP_IN_CNT 3
#define LM96000_FAN_IN_CNT 4
#define LM96000_PWM_CTL_CNT 3
#define LM96000_TEMP_ZONE_CNT 3
enum lm96000_vin {
LM96000_2_5V = 0,
LM96000_VCCP = 1,
LM96000_3_3V = 2,
LM96000_5V = 3,
LM96000_12V = 4,
};
enum lm96000_fan_mode {
/* Bit 7 merely signifies that the mode is set, so we
can map the lower bits directly to register values. */
LM96000_FAN_IGNORE = 0x00,
LM96000_FAN_ZONE_1_AUTO = 0x80,
LM96000_FAN_ZONE_2_AUTO = 0x81,
LM96000_FAN_ZONE_3_AUTO = 0x82,
LM96000_FAN_ALWAYS_FULL = 0x83,
LM96000_FAN_DISABLED = 0x84,
LM96000_FAN_HOTTEST_23 = 0x85,
LM96000_FAN_HOTTEST_123 = 0x86,
LM96000_FAN_MANUAL = 0x87,
};
enum lm96000_pwm_freq {
LM96000_PWM_10HZ = 0,
LM96000_PWM_15HZ = 1,
LM96000_PWM_23HZ = 2,
LM96000_PWM_30HZ = 3,
LM96000_PWM_38HZ = 4,
LM96000_PWM_47HZ = 5,
LM96000_PWM_61HZ = 6,
LM96000_PWM_94HZ = 7,
LM96000_PWM_22_5KHZ = 8,
LM96000_PWM_24_0KHZ = 9,
LM96000_PWM_25_7KHZ = 10,
LM96000_PWM_27_7KHZ = 12,
LM96000_PWM_30_0KHZ = 14,
};
enum lm96000_tach_mode {
/* 0 will be used for kHz frequencies */
LM96000_TACH_MODE_1 = 1, /* use if TACHx isn't used with PWMx */
LM96000_TACH_MODE_2 = 2, /* use either 2 or 3 if TACHx matches PWMx */
LM96000_TACH_MODE_3 = 3,
};
enum lm96000_spinup_time {
LM96000_SPINUP_0MS = 0,
LM96000_SPINUP_100MS = 1,
LM96000_SPINUP_250MS = 2,
LM96000_SPINUP_400MS = 3,
LM96000_SPINUP_700MS = 4,
LM96000_SPINUP_1000MS = 5,
LM96000_SPINUP_2000MS = 6,
LM96000_SPINUP_4000MS = 7,
};
struct lm96000_fan_config {
enum lm96000_fan_mode mode;
int invert; /* invert PWM signal */
enum lm96000_spinup_time spinup;
enum lm96000_pwm_freq freq;
enum lm96000_tach_mode tach;
union {
u8 duty_cycle; /* duty cycle in manual mode */
u8 min_duty; /* minimum duty cycle */
};
};
struct lm96000_temp_zone {
u8 low_temp; /* temperature for min. duty cycle (in °C) */
u8 target_temp; /* temperature for 100% duty cycle (in °C) */
u8 panic_temp; /* temperature for 100% duty cycle on all fans */
/* This is tied to the zone in the implementation I tested
with. (Datasheet clearly states the opposite, that this
is tied to each PWM output so YMMV.) */
enum {
/* turn fan off below `low_temp - hysteresis` */
LM96000_LOW_TEMP_OFF = 0,
/* keep PWM at minimum duty cycle */
LM96000_LOW_TEMP_MIN = 1,
} min_off;
u8 hysteresis;
};
/* Implements only those parts currently used by coreboot mainboards. */
struct drivers_i2c_lm96000_config {
struct {
u16 low; /* in mV */
u16 high;
} vin[LM96000_VIN_CNT];
struct {
signed char low; /* in °C */
signed char high;
} temp_in[LM96000_TEMP_IN_CNT];
struct {
u16 low; /* in RPM */
} fan_in[LM96000_FAN_IN_CNT];
struct lm96000_fan_config fan[LM96000_PWM_CTL_CNT];
struct lm96000_temp_zone zone[LM96000_TEMP_ZONE_CNT];
};
#endif /* DRIVERS_I2C_LM96000_CHIP_H */
|