1/* SPDX-License-Identifier: GPL-2.0-only */ 2 3/* 4 * Include this file into a southbridge ASL block and it will 5 * expose the W83977TF/EF SuperIO and some of its functionality. 6 * 7 * Adapted from winbond/w83627dhg. 8 * 9 * It allows the change of IO ports, IRQs and DMA settings on logical 10 * devices, disabling and reenabling logical devices and controlling power 11 * saving mode on logical devices or the whole chip. 12 * 13 * Controllable through preprocessor defines: 14 * SUPERIO_PNP_BASE I/O address of the first PnP configuration register 15 * SUPERIO_SHOW_UARTA If defined, UARTA will be exposed. 16 * SUPERIO_SHOW_UARTB If defined, UARTB will be exposed. 17 * SUPERIO_SHOW_FDC If defined, floppy controller will be exposed. 18 * SUPERIO_SHOW_LPT If defined, parallel port will be exposed. 19 */ 20 21#define SUPERIO_CHIP_NAME W83977TF 22#include <superio/acpi/pnp.asl> 23#include <superio/winbond/w83977tf/w83977tf.h> 24 25/* Mutex for accesses to the configuration ports */ 26 27Mutex(CRMX, 1) 28 29/* SuperIO configuration ports */ 30OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 0x02) 31Field (CREG, ByteAcc, NoLock, Preserve) 32{ 33 PNP_ADDR_REG, 8, 34 PNP_DATA_REG, 8 35} 36IndexField (PNP_ADDR_REG, PNP_DATA_REG, ByteAcc, NoLock, Preserve) 37{ 38 Offset (0x07), 39 PNP_LOGICAL_DEVICE, 8, /* Logical device selector */ 40 Offset (0x20), 41 DID, 8, /* Device ID: TF=0x97, EF=0x52 */ 42 DREV, 8, /* Device revision */ 43 FDPW, 1, 44 , 2, 45 PRPW, 1, 46 UAPW, 1, /* UART A Power Down */ 47 UBPW, 1, /* UART B Power Down */ 48 Offset (0x23), 49 IPD, 1, /* Immediate Chip Power Down */ 50 Offset (0x30), 51 PNP_DEVICE_ACTIVE, 8, 52 Offset (0x60), 53 PNP_IO0_HIGH_BYTE, 8, 54 PNP_IO0_LOW_BYTE, 8, 55 PNP_IO1_HIGH_BYTE, 8, 56 PNP_IO1_LOW_BYTE, 8, 57 PNP_IO2_HIGH_BYTE, 8, 58 PNP_IO2_LOW_BYTE, 8, 59 Offset (0x70), 60 PNP_IRQ0, 8, 61 Offset (0x72), 62 PNP_IRQ1, 8, 63 Offset (0x74), 64 PNP_DMA0, 8, 65 /* MSWK and KBWK are for ACPI logical device, LDN 0xA */ 66 Offset (0xE0), 67 MSWK, 8, 68 Offset (0xE4), 69 KBWK, 8, 70 Offset (0xF0), 71 OPT1, 8, 72 OPT2, 8 73} 74 75#define PNP_ENTER_MAGIC_1ST 0x87 76#define PNP_ENTER_MAGIC_2ND 0x87 77#define PNP_EXIT_MAGIC_1ST 0xaa 78#include <superio/acpi/pnp_config.asl> 79 80/* PM: indicate IPD (Immediate Power Down) bit state as D0/D3 */ 81Method (_PSC) { 82 ENTER_CONFIG_MODE (PNP_NO_LDN_CHANGE) 83 Local0 = IPD 84 EXIT_CONFIG_MODE () 85 If (Local0) { Return (3) } 86 Else { Return (0) } 87} 88 89#ifdef SUPERIO_SHOW_FDC 90Device (FDC0) 91{ 92 Name (_HID, EisaId ("PNP0700")) 93 Method (_STA, 0, NotSerialized) 94 { 95 PNP_GENERIC_STA(W83977TF_FDC) 96 } 97 98 Method (_DIS, 0, NotSerialized) // _DIS: Disable Device 99 { 100 PNP_GENERIC_DIS(W83977TF_FDC) 101 } 102 103 Method (_CRS, 0) 104 { 105 Name (BUF0, ResourceTemplate () 106 { 107 IO (Decode16, 0x03F2, 0x03F2, 0x00, 0x04, IO0) 108 IO (Decode16, 0x03F7, 0x03F7, 0x00, 0x01, IO1) 109 IRQ (Edge, ActiveHigh, Exclusive, Y08) {6} 110 DMA (Compatibility, NotBusMaster, Transfer8, Y09) {2} 111 }) 112 CreateWordField (BUF0, IO1._MIN, IO1I) 113 CreateWordField (BUF0, IO1._MAX, IO1A) 114 115 ENTER_CONFIG_MODE(W83977TF_FDC) 116 /* OEM BIOS does not report actual programmed base port */ 117 /* xx0 is read from superio */ 118 PNP_READ_IO(PNP_IO0, BUF0, IO0) 119 /* Store xx7 range first so the value isn't overwritten 120 * for below */ 121 IO1I += 7 122 IO1A = IO1I 123 /* Store xx2 range */ 124 IO0I += 2 125 IO0A = IO0I 126 /* End OEM BIOS deficiency */ 127 PNP_READ_IRQ(PNP_IRQ0, BUF0, Y08) 128 PNP_READ_DMA(PNP_DMA0, BUF0, Y09) 129 130 EXIT_CONFIG_MODE() 131 Return (BUF0) 132 } 133 134 Name (_PRS, ResourceTemplate () 135 { 136 IO (Decode16, 0x03F2, 0x03F2, 0x00, 0x04, ) 137 IO (Decode16, 0x03F7, 0x03F7, 0x00, 0x01, ) 138 IRQ (Edge, ActiveHigh, Exclusive, ) {6} 139 DMA (Compatibility, NotBusMaster, Transfer8, ) {2} 140 }) 141 142 Method (_SRS, 1, NotSerialized) 143 { 144 CreateByteField (Arg0, 0x02, IOLO) 145 CreateByteField (Arg0, 0x03, IOHI) 146 CreateWordField (Arg0, 0x11, IRQW) 147 CreateByteField (Arg0, 0x15, DMAV) 148 ENTER_CONFIG_MODE(W83977TF_FDC) 149 /* FDC base port on 8-byte boundary. */ 150 PNP_IO0_LOW_BYTE = IOLO & 0xF8 151 PNP_IO0_HIGH_BYTE = IOHI 152 PNP_IRQ0 = FindSetLeftBit (IRQW) - 1 153 PNP_DMA0 = FindSetLeftBit (DMAV) - 1 154 PNP_DEVICE_ACTIVE = 1 155 EXIT_CONFIG_MODE() 156 } 157} 158#endif 159 160#ifdef SUPERIO_SHOW_LPT 161/* Standard LPT Parallel Port */ 162Device (LPT) 163{ 164 Name (_HID, EisaId ("PNP0400")) 165 Method (_STA, 0, NotSerialized) 166 { 167 ENTER_CONFIG_MODE(W83977TF_PP) 168 Local0 = OPT1 & 0x02 169 If (IO0H || IO0L) 170 { 171 /* Report device not present if ECP is enabled */ 172 If (Local0 == 0x02) 173 { 174 EXIT_CONFIG_MODE() 175 Return (0x00) 176 } 177 ElseIf (PNP_DEVICE_ACTIVE) 178 { 179 EXIT_CONFIG_MODE() 180 Return (0x0F) 181 } 182 Else 183 { 184 EXIT_CONFIG_MODE() 185 Return (0x0D) 186 } 187 } 188 189 EXIT_CONFIG_MODE() 190 Return (0) 191 } 192 193 Method (_DIS, 0, NotSerialized) 194 { 195 PNP_GENERIC_DIS(W83977TF_PP) 196 } 197 198 Method (_CRS, 0, NotSerialized) 199 { 200 Name (BUF5, ResourceTemplate () 201 { 202 IO (Decode16,0x0378,0x0378,0x00,0x04,Y0A) 203 IRQ (Edge, ActiveHigh, Exclusive, Y0B) 204 {7} 205 }) 206 ENTER_CONFIG_MODE(W83977TF_PP) 207 PNP_READ_IO(PNP_IO0,BUF5,Y0A) 208 PNP_READ_IRQ(PNP_IRQ0,BUF5,Y0B) 209 EXIT_CONFIG_MODE() 210 Return (BUF5) 211 } 212 213 Name (_PRS, ResourceTemplate () 214 { 215 StartDependentFn (0x01, 0x01) 216 { 217 IO (Decode16,0x0378,0x0378,0x00,0x08,) 218 IRQ (Edge, ActiveHigh, Exclusive, ) 219 {5,7} 220 } 221 StartDependentFn (0x01, 0x01) 222 { 223 IO (Decode16,0x0278,0x0278,0x00,0x08,) 224 IRQ (Edge, ActiveHigh, Exclusive, ) 225 {5,7} 226 } 227 StartDependentFn (0x01, 0x01) 228 { 229 IO (Decode16,0x03BC,0x03BC,0x00,0x04,) 230 IRQ (Edge, ActiveHigh, Exclusive, ) 231 {5,7} 232 } 233 EndDependentFn () 234 }) 235 236 Method (_SRS, 1, NotSerialized) 237 { 238 CreateByteField (Arg0, 0x02, IOLO) 239 CreateByteField (Arg0, 0x03, IOHI) 240 CreateWordField (Arg0, 0x09, IRQW) 241 ENTER_CONFIG_MODE(W83977TF_PP) 242 PNP_IO0_LOW_BYTE = IOLO 243 PNP_IO0_HIGH_BYTE = IOHI 244 PNP_IRQ0 = FindSetLeftBit (IRQW) - 1 245 PNP_DEVICE_ACTIVE = 1 246 EXIT_CONFIG_MODE() 247 } 248} 249 250/* ECP Parallel Port */ 251Device (ECP) 252{ 253 Name (_HID, EisaId ("PNP0401")) 254 Method (_STA, 0, NotSerialized) 255 { 256 ENTER_CONFIG_MODE(W83977TF_PP) 257 Local0 = OPT1 & 0x02 258 If (IO0H || IO0L) 259 { 260 If (Local0 == 0x02) 261 { 262 If (PNP_DEVICE_ACTIVE) 263 { 264 EXIT_CONFIG_MODE() 265 Return (0x0F) 266 } 267 Else 268 { 269 EXIT_CONFIG_MODE() 270 Return (0x05) 271 } 272 } 273 } 274 275 EXIT_CONFIG_MODE() 276 Return (0x00) 277 } 278 279 Method (_DIS, 0, NotSerialized) 280 { 281 PNP_GENERIC_DIS(W83977TF_PP) 282 } 283 284 Method (_CRS, 0, NotSerialized) 285 { 286 Name (BUF6, ResourceTemplate () 287 { 288 IO (Decode16,0x0378,0x0378,0,4,IO0) 289 IO (Decode16,0x0778,0x0778,0,4,IO1) 290 IRQ (Edge, ActiveHigh, Exclusive, IR1) {7} 291 DMA (Compatibility, NotBusMaster, Transfer8, Y0F) {1} 292 }) 293 ENTER_CONFIG_MODE(W83977TF_PP) 294 PNP_READ_IO(PNP_IO0, BUF6, IO0) 295 PNP_READ_IO(PNP_IO0, BUF6, IO1) 296 PNP_READ_IRQ(PNP_IRQ0, BUF6, IR1) 297 PNP_READ_DMA(PNP_DMA0, BUF6, Y0F) 298 299 /* Report a second port range that is 0x400 above base port. */ 300 CreateByteField (BUF6, 0x0B, I2HI) 301 CreateByteField (BUF6, 0x0D, I2RH) 302 I2RH = I2HI + 4 303 I2HI = I2HI + 4 304 EXIT_CONFIG_MODE() 305 Return (BUF6) 306 } 307 308 Name (_PRS, ResourceTemplate () // _PRS: Possible Resource Settings 309 { 310 StartDependentFn (0x01, 0x01) 311 { 312 IO (Decode16,0x0378,0x0378,0,4,) 313 IO (Decode16,0x0778,0x0778,0,4,) 314 IRQ (Edge, ActiveHigh, Exclusive, ) {5,7} 315 DMA (Compatibility, NotBusMaster, Transfer8, ) {0,1,3} 316 } 317 StartDependentFn (0x01, 0x01) 318 { 319 IO (Decode16,0x0278,0x0278,0,4,) 320 IO (Decode16,0x0678,0x0678,0,4,) 321 IRQ (Edge, ActiveHigh, Exclusive, ) {5,7} 322 DMA (Compatibility, NotBusMaster, Transfer8, ) {0,1,3} 323 } 324 StartDependentFn (0x01, 0x01) 325 { 326 IO (Decode16,0x03BC,0x03BC,0,4,) 327 IO (Decode16,0x07BC,0x07BC,0,4,) 328 IRQ (Edge, ActiveHigh, Exclusive, ) {5,7} 329 DMA (Compatibility, NotBusMaster, Transfer8, ) {0,1,3} 330 } 331 EndDependentFn () 332 }) 333 334 Method (_SRS, 1, NotSerialized) // _SRS: Set Resource Settings 335 { 336 CreateByteField (Arg0, 0x02, IOLO) 337 CreateByteField (Arg0, 0x03, IOHI) 338 CreateWordField (Arg0, 0x11, IRQW) 339 CreateByteField (Arg0, 0x15, DMAC) 340 341 ENTER_CONFIG_MODE(W83977TF_PP) 342 PNP_IO0_LOW_BYTE = IOLO 343 PNP_IO0_HIGH_BYTE = IOHI 344 PNP_IRQ0 = FindSetLeftBit (IRQW) - 1 345 PNP_DMA0 = FindSetLeftBit (DMAC) - 1 346 PNP_DEVICE_ACTIVE = 1 347 EXIT_CONFIG_MODE() 348 } 349} 350#endif 351 352#define SUPERIO_UART_PM_VAL 0 353#define SUPERIO_UART_PM_LDN PNP_NO_LDN_CHANGE 354 355#ifdef SUPERIO_SHOW_UARTA 356 #define SUPERIO_UART_LDN W83977TF_SP1 357 #define SUPERIO_UART_PM_REG UAPW 358 #include <superio/acpi/pnp_uart.asl> 359 #undef SUPERIO_UART_LDN 360 #undef SUPERIO_UART_PM_REG 361#endif 362 363#ifdef SUPERIO_SHOW_UARTB 364 #define SUPERIO_UART_LDN W83977TF_SP2 365 #define SUPERIO_UART_PM_REG UBPW 366 #include <superio/acpi/pnp_uart.asl> 367 #undef SUPERIO_UART_LDN 368 #undef SUPERIO_UART_PM_REG 369#endif 370 371/* 372 * TODO: IrDA device; 373 * EF=LDN 3 aka UARTB 374 * Some revisions of TF=LDN 6 375 */ 376 377#define SUPERIO_KBC_LDN W83977TF_KBC 378#define SUPERIO_KBC_PS2M /* Mouse shares same LDN */ 379#include <superio/acpi/pnp_kbc.asl> 380