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