1 /* $NetBSD: emcfaninfo.h,v 1.1 2025/03/11 13:56:46 brad Exp $ */ 2 3 /* 4 * Copyright (c) 2025 Brad Spencer <brad (at) anduin.eldar.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #ifndef _DEV_I2C_EMCFANINFO_H_ 20 #define _DEV_I2C_EMCFANINFO_H_ 21 22 #include <sys/gpio.h> 23 24 struct emcfan_chip_info { 25 const int family; /* The EMC chipset family, 210X or 230X */ 26 const uint8_t product_id; /* The product ID as read from the chip */ 27 const char *name; /* What we are calling this chip */ 28 const int num_tachs; /* The number of tachometers */ 29 const int num_fans; /* The number of fans. This may be different than the number of tachometers. */ 30 const uint8_t fan_drive_registers[5]; /* The registers used to drive the fans, one for each */ 31 const uint8_t fan_divider_registers[5]; /* The divider registers, one for each possible fan */ 32 const bool internal_temp_zone; /* Does the chip have an internal temperature zone */ 33 const int num_external_temp_zones; /* The number of external temperature zones except for ones that are VIN4 */ 34 const bool vin4_temp_zone; /* Does the chip have a VIN4 temperature zone */ 35 const int num_gpio_pins; /* The number of gpio pins that this chip has */ 36 const int gpio_pin_ability[6]; /* The abilities for each gpio pin */ 37 const char *gpio_names[6]; /* The default names of the gpio pins */ 38 const uint64_t register_void[4]; /* 4 64 bit values that specify if a particular register is valid */ 39 }; 40 41 static struct emcfan_chip_info emcfan_chip_infos[] = { 42 { 43 .family = EMCFAN_FAMILY_210X, 44 .product_id = EMCFAN_PRODUCT_2101, 45 .name = "EMC2101", 46 .num_tachs = 1, 47 .num_fans = 1, 48 .fan_drive_registers = { EMCFAN_2101_FAN_DRIVE }, 49 .fan_divider_registers = { EMCFAN_2101_FAN_DIVIDE }, 50 .internal_temp_zone = true, 51 .num_external_temp_zones = 1, 52 .vin4_temp_zone = false, 53 .num_gpio_pins = 0, 54 .register_void[0] = 0b0000000000000000000000000000001000000011110111111111111110111111, 55 .register_void[1] = 0b0000000000000000000000000000000011111111111111111111111111000000, 56 .register_void[2] = 0b1000000000000000000000000000000000000000000000000000000000000000, 57 .register_void[3] = 0b1110000000000000000000000000000000000000000000000000000000000000, 58 }, 59 { 60 .family = EMCFAN_FAMILY_210X, 61 .product_id = EMCFAN_PRODUCT_2101R, 62 .name = "EMC2101-R", 63 .num_tachs = 1, 64 .num_fans = 1, 65 .fan_drive_registers = { EMCFAN_2101_FAN_DRIVE }, 66 .fan_divider_registers = { EMCFAN_2101_FAN_DIVIDE }, 67 .internal_temp_zone = true, 68 .num_external_temp_zones = 1, 69 .vin4_temp_zone = false, 70 .num_gpio_pins = 0, 71 .register_void[0] = 0b0000000000000000000000000000001000000011110111111111111110111111, 72 .register_void[1] = 0b0000000000000000000000000000000011111111111111111111111111000000, 73 .register_void[2] = 0b1000000000000000000000000000000000000000000000000000000000000000, 74 .register_void[3] = 0b1110000000000000000000000000000000000000000000000000000000000000, 75 }, 76 { 77 .family = EMCFAN_FAMILY_210X, 78 .product_id = EMCFAN_PRODUCT_2103_1, 79 .name = "EMC2103-1", 80 .num_tachs = 1, 81 .num_fans = 1, 82 .fan_drive_registers = { EMCFAN_210_346_FAN_1_DRIVE }, 83 .fan_divider_registers = { EMCFAN_210_346_FAN_1_DIVIDE }, 84 .internal_temp_zone = true, 85 .num_external_temp_zones = 1, 86 .vin4_temp_zone = false, 87 .num_gpio_pins = 0, 88 .register_void[0] = 0b0001000100010001000011111111101110100010100100110011010000001111, 89 .register_void[1] = 0b0000001111111111111111111111111111111111111111111111111111101111, 90 .register_void[2] = 0b0000000000000000000000000000000000000000000000000000000000000000, 91 .register_void[3] = 0b1111000000000000100000000000000000000000000000000000000000000000, 92 }, 93 { 94 .family = EMCFAN_FAMILY_210X, 95 .product_id = EMCFAN_PRODUCT_2103_24, 96 .name = "EMC2103-2/4", 97 .num_tachs = 1, 98 .num_fans = 1, 99 .fan_drive_registers = { EMCFAN_210_346_FAN_1_DRIVE }, 100 .fan_divider_registers = { EMCFAN_210_346_FAN_1_DIVIDE }, 101 .internal_temp_zone = true, 102 .num_external_temp_zones = 3, 103 .vin4_temp_zone = false, 104 .num_gpio_pins = 2, 105 .gpio_pin_ability = { 106 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL, 107 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL 108 }, 109 .gpio_names = { "GPIO1", "GPIO2" }, 110 .register_void[0] = 0b0001011100010111000011111111101110101110101101110011010011111111, 111 .register_void[1] = 0b0000001111111111111111111111111111111111111111111111111111101111, 112 .register_void[2] = 0b0000000000000000000000000000000000000000000000000000000000000000, 113 .register_void[3] = 0b1111000000000000100000000111111000000000000000000000000000000000, 114 }, 115 { 116 .family = EMCFAN_FAMILY_210X, 117 .product_id = EMCFAN_PRODUCT_2104, 118 .name = "EMC2104", 119 .num_tachs = 2, 120 .num_fans = 2, 121 .fan_drive_registers = { EMCFAN_210_346_FAN_1_DRIVE, EMCFAN_210_346_FAN_2_DRIVE }, 122 .fan_divider_registers = { EMCFAN_210_346_FAN_1_DIVIDE, EMCFAN_210_346_FAN_1_DIVIDE }, 123 .internal_temp_zone = true, 124 .num_external_temp_zones = 4, 125 .vin4_temp_zone = true, 126 .num_gpio_pins = 3, 127 .gpio_pin_ability = { 128 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | GPIO_PIN_ALT0, 129 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | GPIO_PIN_ALT0, 130 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | GPIO_PIN_ALT0 131 }, 132 .gpio_names = { "CLK_IN / GPIO1", "TACH2 / GPIO2", "PWM2 / GPIO3" }, 133 .register_void[0] = 0b0011111100111111000011111111111110111111111100011111011111111111, 134 .register_void[1] = 0b0000001111111111111111111111111111111111111111111111111111101111, 135 .register_void[2] = 0b0000001111111111111111111111111111111111111111111111111111101111, 136 .register_void[3] = 0b1111000000000000100000000111111100000000000000000000000000000000, 137 }, 138 { 139 .family = EMCFAN_FAMILY_210X, 140 .product_id = EMCFAN_PRODUCT_2106, 141 .name = "EMC2106", 142 .num_tachs = 2, 143 .num_fans = 4, 144 .fan_drive_registers = { EMCFAN_210_346_FAN_1_DRIVE, EMCFAN_210_346_FAN_2_DRIVE, EMCFAN_2106_FAN_3_DRIVE, EMCFAN_2106_FAN_4_DRIVE }, 145 .fan_divider_registers = { EMCFAN_210_346_FAN_1_DIVIDE, EMCFAN_210_346_FAN_1_DIVIDE, EMCFAN_2106_FAN_3_DIVIDE, EMCFAN_2106_FAN_4_DIVIDE }, 146 .internal_temp_zone = true, 147 .num_external_temp_zones = 4, 148 .vin4_temp_zone = true, 149 .num_gpio_pins = 6, 150 .gpio_pin_ability = { 151 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | GPIO_PIN_ALT0, 152 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | GPIO_PIN_ALT0, 153 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | GPIO_PIN_ALT0, 154 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | GPIO_PIN_ALT0 | GPIO_PIN_ALT1, 155 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | GPIO_PIN_ALT0 | GPIO_PIN_ALT1, 156 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL 157 }, 158 .gpio_names = { "CLK_IN / GPIO1", "TACH2 / GPIO2", "PWM2 / GPIO3", "OVERT2 / GPIO4 / PWM3", "OVERT3 / GPIO5 / PWM4", "GPIO6" }, 159 .register_void[0] = 0b0011111100111111111111111111111110111111111100011111011111111111, 160 .register_void[1] = 0b0000001111111111111111111111111111111111111111111111111111101111, 161 .register_void[2] = 0b0000001111111111111111111111111111111111111111111111111111101111, 162 .register_void[3] = 0b1111000000000000100000000111111100000000000000000000000000000000, 163 }, 164 { 165 .family = EMCFAN_FAMILY_230X, 166 .product_id = EMCFAN_PRODUCT_2301, 167 .name = "EMC2301", 168 .num_tachs = 1, 169 .num_fans = 1, 170 .fan_drive_registers = { EMCFAN_230X_FAN_1_DRIVE }, 171 .fan_divider_registers = { EMCFAN_230X_FAN_1_DIVIDE }, 172 .internal_temp_zone = false, 173 .num_external_temp_zones = 0, 174 .vin4_temp_zone = false, 175 .num_gpio_pins = 0, 176 .register_void[0] = 0b1111111111101111001111101111000100000000000000000000000000000000, 177 .register_void[1] = 0b0000000000000000000000000000000000000000000000000000000000000000, 178 .register_void[2] = 0b0000000000000000000000000000000000000000000000000000000000000000, 179 .register_void[3] = 0b1110000000000000100000000000000000000000000000000000000000000000, 180 }, 181 { 182 .family = EMCFAN_FAMILY_230X, 183 .product_id = EMCFAN_PRODUCT_2302, 184 .name = "EMC2302", 185 .num_tachs = 2, 186 .num_fans = 2, 187 .fan_drive_registers = { EMCFAN_230X_FAN_1_DRIVE, EMCFAN_230X_FAN_2_DRIVE }, 188 .fan_divider_registers = { EMCFAN_230X_FAN_1_DIVIDE, EMCFAN_230X_FAN_2_DIVIDE }, 189 .internal_temp_zone = false, 190 .num_external_temp_zones = 0, 191 .vin4_temp_zone = false, 192 .num_gpio_pins = 0, 193 .register_void[0] = 0b1111111111101111001111101111000100000000000000000000000000000000, 194 .register_void[1] = 0b0000000000000000000000000000000000000000000000001111111111101111, 195 .register_void[2] = 0b0000000000000000000000000000000000000000000000000000000000000000, 196 .register_void[3] = 0b1110000000000000100000000000000000000000000000000000000000000000, 197 }, 198 { 199 .family = EMCFAN_FAMILY_230X, 200 .product_id = EMCFAN_PRODUCT_2303, 201 .name = "EMC2303", 202 .num_tachs = 3, 203 .num_fans = 3, 204 .fan_drive_registers = { EMCFAN_230X_FAN_1_DRIVE, EMCFAN_230X_FAN_2_DRIVE, EMCFAN_230X_FAN_3_DRIVE }, 205 .fan_divider_registers = { EMCFAN_230X_FAN_1_DIVIDE, EMCFAN_230X_FAN_2_DIVIDE, EMCFAN_230X_FAN_3_DIVIDE }, 206 .internal_temp_zone = false, 207 .num_external_temp_zones = 0, 208 .vin4_temp_zone = false, 209 .num_gpio_pins = 0, 210 .register_void[0] = 0b1111111111101111001111101111000100000000000000000000000000000000, 211 .register_void[1] = 0b0000000000000000000000000000000011111111111011111111111111101111, 212 .register_void[2] = 0b0000000000000000000000000000000000000000000000000000000000000000, 213 .register_void[3] = 0b1111000000000000100000000000000000000000000000000000000000000000, 214 }, 215 { 216 .family = EMCFAN_FAMILY_230X, 217 .product_id = EMCFAN_PRODUCT_2305, 218 .name = "EMC2305", 219 .num_tachs = 5, 220 .num_fans = 5, 221 .fan_drive_registers = { EMCFAN_230X_FAN_1_DRIVE, EMCFAN_230X_FAN_2_DRIVE, EMCFAN_230X_FAN_3_DRIVE, EMCFAN_230X_FAN_4_DRIVE, EMCFAN_230X_FAN_5_DRIVE }, 222 .fan_divider_registers = { EMCFAN_230X_FAN_1_DIVIDE, EMCFAN_230X_FAN_2_DIVIDE, EMCFAN_230X_FAN_3_DIVIDE, EMCFAN_230X_FAN_4_DIVIDE, EMCFAN_230X_FAN_5_DIVIDE }, 223 .internal_temp_zone = false, 224 .num_external_temp_zones = 0, 225 .vin4_temp_zone = false, 226 .num_gpio_pins = 0, 227 .register_void[0] = 0b1111111111101111001111101111000100000000000000000000000000000000, 228 .register_void[1] = 0b1111111111101111111111111110111111111111111011111111111111101111, 229 .register_void[2] = 0b0000000000000000000000000000000000000000000000000000000000000000, 230 .register_void[3] = 0b1111000000000000100000000000000000000000000000000000000000000000, 231 } 232 }; 233 234 #endif 235