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