1/**@file 2 Provide the SMBUS ASL methods for BIOS usage. 3 Note the code requested here illegally consumes PCI IO resources and 4 collides with some runtime SMBUS driver. 5 The only valid solution is to retire this code and provide native SMBUS 6 driver with SMBUS operation region support implemented for ACPI usage. 7 8Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> 9SPDX-License-Identifier: BSD-2-Clause-Patent 10 11**/ 12 13// 14// Define various SMBus PCI Configuration Space Registers. 15// 16OperationRegion(SMBP, PCI_Config, 0x0, 0xC0) 17Field(SMBP,DWordAcc,NoLock,Preserve) 18{ 19 Offset(0x20), // SMBus Base Address 20 , 5, 21 SBAR, 11, 22 Offset(0x40), // Host Configuration 23 , 2, 24 I2CE, 1, // I2C_EN 25} 26 27// 28// Define various SMBus IO Mapped Registers. 29// 30OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10) 31Field(SMBI,ByteAcc,NoLock,Preserve) 32{ 33 HSTS, 8, // 0 - Host Status Register 34 Offset(0x02), 35 HCON, 8, // 2 - Host Control 36 HCOM, 8, // 3 - Host Command 37 TXSA, 8, // 4 - Transmit Slave Address 38 DAT0, 8, // 5 - Host Data 0 39 DAT1, 8, // 6 - Host Data 1 40 HBDR, 8, // 7 - Host Block Data 41 PECR, 8, // 8 - Packer Error Check 42 RXSA, 8, // 9 - Receive Slave Address 43 SDAT, 16, // A - Slave Data 44} 45 46// SMBus Send Byte - This function will write a single byte of 47// data to a specific Slave Device per SMBus Send Byte Protocol. 48// Arg0 = Address 49// Arg1 = Data 50// Return: Success = 1 51// Failure = 0 52Method(SSXB,2,Serialized) 53{ 54 // Step 1: Confirm the ICHx SMBus is ready to perform 55 // communication. 56 57 If(STRT()) 58 { 59 Return(0) 60 } 61 62 // Step 2: Initiate a Send Byte. 63 Store(0,I2CE) // Ensure SMbus Mode. 64 Store(0xBF,HSTS) // Clear all but INUSE_STS. 65 Store(Arg0,TXSA) // Write Address in TXSA. 66 Store(Arg1,HCOM) // Data in HCOM. 67 68 // Set the SMBus Host control register to 0x48. 69 // Bit 7: = 0 = reserved 70 // Bit 6: = 1 = start 71 // Bit 5: = 0 = disregard, I2C related bit 72 // Bits 4:2: = 001 = Byte Protocol 73 // Bit 1: = 0 = Normal Function 74 // Bit 0: = 0 = Disable interrupt generation 75 Store(0x48,HCON) 76 77 // Step 3: Exit the Method correctly. 78 If(COMP) 79 { 80 Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others.. 81 Return(1) // Return Success. 82 } 83 84 Return(0) 85} 86 87// SMBus Receive Byte - This function will write a single byte 88// of data to a specific Slave Device per SMBus Receive Byte 89// Protocol. 90// Arg0 = Address 91// Return: Success = Byte-Size Value 92// Failure = Word-Size Value = FFFFh. 93Method(SRXB,1,Serialized) 94{ 95 // Step 1: Confirm the ICHx SMBus is ready to perform 96 // communication. 97 If(STRT()) 98 { 99 Return(0xFFFF) 100 } 101 102 // Step 2: Initiate a Receive Byte. 103 Store(0,I2CE) // Ensure SMbus Mode. 104 Store(0xBF,HSTS) // Clear all but INUSE_STS. 105 Store(Or(Arg0,1),TXSA) // Read Address in TXSA. 106 107 // Set the SMBus Host control register to 0x48. 108 // Bit 7: = 0 = reserved 109 // Bit 6: = 1 = start 110 // Bit 5: = 0 = disregard, I2C related bit 111 // Bits 4:2: = 001 = Byte Protocol 112 // Bit 1: = 0 = Normal Function 113 // Bit 0: = 0 = Disable interrupt generation 114 Store(0x44,HCON) 115 116 // Step 3: Exit the Method correctly. 117 If(COMP) 118 { 119 Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others 120 Return(DAT0) // Return Success. 121 } 122 123 Return(0xFFFF) // Return Failure. 124} 125 126// SMBus Write Byte - This function will write a single byte 127// of data to a specific Slave Device per SMBus Write Byte 128// Protocol. 129// Arg0 = Address 130// Arg1 = Command 131// Arg2 = Data 132// Return: Success = 1 133// Failure = 0 134Method(SWRB,3,Serialized) 135{ 136 // Step 1: Confirm the ICHx SMBus is ready to perform communication. 137 If(STRT()) 138 { 139 Return(0) 140 } 141 142 // Step 2: Initiate a Write Byte. 143 Store(0,I2CE) // Ensure SMbus Mode. 144 Store(0xBF,HSTS) // Clear all but INUSE_STS. 145 Store(Arg0,TXSA) // Write Address in TXSA. 146 Store(Arg1,HCOM) // Command in HCOM. 147 Store(Arg2,DAT0) // Data in DAT0. 148 149 // Set the SMBus Host control register to 0x48. 150 // Bit 7: = 0 = reserved 151 // Bit 6: = 1 = start 152 // Bit 5: = 0 = disregard, I2C related bit 153 // Bits 4:2: = 010 = Byte Data Protocol 154 // Bit 1: = 0 = Normal Function 155 // Bit 0: = 0 = Disable interrupt generation 156 Store(0x48,HCON) 157 158 // Step 3: Exit the Method correctly. 159 If(COMP) 160 { 161 Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others.. 162 Return(1) // Return Success. 163 } 164 165 Return(0) // Return Failure. 166} 167 168// SMBus Read Byte - This function will read a single byte of data 169// from a specific slave device per SMBus Read Byte Protocol. 170// Arg0 = Address 171// Arg1 = Command 172// Return: Success = Byte-Size Value 173// Failure = Word-Size Value 174Method(SRDB,2,Serialized) 175{ 176 // Step 1: Confirm the ICHx SMBus is ready to perform communication. 177 If(STRT()) 178 { 179 Return(0xFFFF) 180 } 181 182 // Step 2: Initiate a Read Byte. 183 Store(0,I2CE) // Ensure SMbus Mode. 184 Store(0xBF,HSTS) // Clear all but INUSE_STS. 185 Store(Or(Arg0,1),TXSA) // Read Address in TXSA. 186 Store(Arg1,HCOM) // Command in HCOM. 187 188 // Set the SMBus Host control register to 0x48. 189 // Bit 7: = 0 = reserved 190 // Bit 6: = 1 = start 191 // Bit 5: = 0 = disregard, I2C related bit 192 // Bits 4:2: = 010 = Byte Data Protocol 193 // Bit 1: = 0 = Normal Function 194 // Bit 0: = 0 = Disable interrupt generation 195 Store(0x48,HCON) 196 197 // Step 3: Exit the Method correctly. 198 If(COMP) 199 { 200 Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others.. 201 Return(DAT0) // Return Success. 202 } 203 204 Return(0xFFFF) // Return Failure. 205} 206 207// SMBus Write Word - This function will write a single word 208// of data to a specific Slave Device per SMBus Write Word 209// Protocol. 210// Arg0 = Address 211// Arg1 = Command 212// Arg2 = Data (16 bits in size) 213// Return: Success = 1 214// Failure = 0 215Method(SWRW,3,Serialized) 216{ 217 // Step 1: Confirm the ICHx SMBus is ready to perform communication. 218 If(STRT()) 219 { 220 Return(0) 221 } 222 223 // Step 2: Initiate a Write Word. 224 Store(0,I2CE) // Ensure SMbus Mode. 225 Store(0xBF,HSTS) // Clear all but INUSE_STS. 226 Store(Arg0,TXSA) // Write Address in TXSA. 227 Store(Arg1,HCOM) // Command in HCOM. 228 And(Arg2,0xFF,DAT1) // Low byte Data in DAT1. 229 And(ShiftRight(Arg2,8),0xFF,DAT0) // High byte Data in DAT0. 230 231 // Set the SMBus Host control register to 0x4C. 232 // Bit 7: = 0 = reserved 233 // Bit 6: = 1 = start 234 // Bit 5: = 0 = disregard, I2C related bit 235 // Bits 4:2: = 011 = Word Data Protocol 236 // Bit 1: = 0 = Normal Function 237 // Bit 0: = 0 = Disable interrupt generation 238 Store(0x4C,HCON) 239 240 // Step 3: Exit the Method correctly. 241 If(COMP()) 242 { 243 Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others. 244 Return(1) // Return Success. 245 } 246 247 Return(0) // Return Failure. 248} 249 250// SMBus Read Word - This function will read a single byte of data 251// from a specific slave device per SMBus Read Word Protocol. 252// Arg0 = Address 253// Arg1 = Command 254// Return: Success = Word-Size Value 255// Failure = Dword-Size Value 256Method(SRDW,2,Serialized) 257{ 258 // Step 1: Confirm the ICHx SMBus is ready to perform communication. 259 If(STRT()) 260 { 261 Return(0xFFFF) 262 } 263 264 // Step 2: Initiate a Read Word. 265 Store(0,I2CE) // Ensure SMbus Mode. 266 Store(0xBF,HSTS) // Clear all but INUSE_STS. 267 Store(Or(Arg0,1),TXSA) // Read Address in TXSA. 268 Store(Arg1,HCOM) // Command in HCOM. 269 270 // Set the SMBus Host control register to 0x4C. 271 // Bit 7: = 0 = reserved 272 // Bit 6: = 1 = start 273 // Bit 5: = 0 = disregard, I2C related bit 274 // Bits 4:2: = 011 = Word Data Protocol 275 // Bit 1: = 0 = Normal Function 276 // Bit 0: = 0 = Disable interrupt generation 277 Store(0x4C,HCON) 278 279 // Step 3: Exit the Method correctly. 280 If(COMP()) 281 { 282 Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others. 283 Return(Or(ShiftLeft(DAT0,8),DAT1)) // Return Success. 284 } 285 286 Return(0xFFFFFFFF) // Return Failure. 287} 288 289// SMBus Block Write - This function will write an entire block of data 290// to a specific slave device per SMBus Block Write Protocol. 291// Arg0 = Address 292// Arg1 = Command 293// Arg2 = Buffer of Data to Write 294// Arg3 = 1 = I2C Block Write, 0 = SMBus Block Write 295// Return: Success = 1 296// Failure = 0 297Method(SBLW,4,Serialized) 298{ 299 // Step 1: Confirm the ICHx SMBus is ready to perform communication. 300 If(STRT()) 301 { 302 Return(0) 303 } 304 305 // Step 2: Initiate a Block Write. 306 Store(Arg3,I2CE) // Select the proper protocol. 307 Store(0xBF,HSTS) // Clear all but INUSE_STS. 308 Store(Arg0,TXSA) // Write Address in TXSA. 309 Store(Arg1,HCOM) // Command in HCOM. 310 Store(Sizeof(Arg2),DAT0) // Count in DAT0. 311 Store(0,Local1) // Init Pointer to Buffer. 312 Store(DerefOf(Index(Arg2,0)),HBDR) // First Byte in HBD Register. 313 314 // Set the SMBus Host control register to 0x48. 315 // Bit 7: = 0 = reserved 316 // Bit 6: = 1 = start 317 // Bit 5: = 0 = disregard, I2C related bit 318 // Bits 4:2: = 101 = Block Protocol 319 // Bit 1: = 0 = Normal Function 320 // Bit 0: = 0 = Disable interrupt generation 321 Store(0x54,HCON) 322 323 // Step 3: Send the entire Block of Data. 324 While(LGreater(Sizeof(Arg2),Local1)) 325 { 326 // Wait up to 200ms for Host Status to get set. 327 Store(4000,Local0) // 4000 * 50us = 200ms. 328 329 While(LAnd(LNot(And(HSTS,0x80)),Local0)) 330 { 331 Decrement(Local0) // Decrement Count. 332 Stall(50) // Delay = 50us. 333 } 334 335 If(LNot(Local0)) // Timeout? 336 { 337 KILL() // Yes. Kill Communication. 338 Return(0) // Return failure. 339 } 340 341 Store(0x80,HSTS) // Clear Host Status. 342 Increment(Local1) // Point to Next Byte. 343 344 // Place next byte in HBDR if last byte has not been sent. 345 If(LGreater(Sizeof(Arg2),Local1)) 346 { 347 Store(DerefOf(Index(Arg2,Local1)),HBDR) 348 } 349 } 350 351 // Step 4: Exit the Method correctly. 352 If(COMP()) 353 { 354 Or(HSTS,0xFF,HSTS) // Clear all status bits. 355 Return(1) // Return Success. 356 } 357 358 Return(0) // Return Failure. 359} 360 361// SMBus Block Read - This function will read a block of data from 362// a specific slave device per SMBus Block Read Protocol. 363// Arg0 = Address 364// Arg1 = Command 365// Arg2 = 1 = I2C Block Write, 0 = SMBus Block Write 366// Return: Success = Data Buffer (First Byte = length) 367// Failure = 0 368Method(SBLR,3,Serialized) 369{ 370 Name(TBUF, Buffer(256) {}) 371 372 // Step 1: Confirm the ICHx SMBus is ready to perform communication. 373 If(STRT()) 374 { 375 Return(0) 376 } 377 378 // Step 2: Initiate a Block Read. 379 Store(Arg2,I2CE) // Select the proper protocol. 380 Store(0xBF,HSTS) // Clear all but INUSE_STS. 381 Store(Or(Arg0,1),TXSA) // Read Address in TXSA. 382 Store(Arg1,HCOM) // Command in HCOM. 383 384 // Set the SMBus Host control register to 0x48. 385 // Bit 7: = 0 = reserved 386 // Bit 6: = 1 = start 387 // Bit 5: = 0 = disregard, I2C related bit 388 // Bits 4:2: = 101 = Block Protocol 389 // Bit 1: = 0 = Normal Function 390 // Bit 0: = 0 = Disable interrupt generation 391 Store(0x54,HCON) 392 393 // Step 3: Wait up to 200ms to get the Data Count. 394 Store(4000,Local0) // 4000 * 50us = 200ms. 395 396 While(LAnd(LNot(And(HSTS,0x80)),Local0)) 397 { 398 Decrement(Local0) // Decrement Count. 399 Stall(50) // Delay = 50us. 400 } 401 402 If(LNot(Local0)) // Timeout? 403 { 404 KILL() // Yes. Kill Communication. 405 Return(0) // Return failure. 406 } 407 408 Store(DAT0,Index(TBUF,0)) // Get the Data Count. 409 Store(0x80,HSTS) // Clear Host Status. 410 Store(1,Local1) // Local1 = Buffer Pointer. 411 412 // Step 4: Get the Block Data and store it. 413 While(LLess(Local1,DerefOf(Index(TBUF,0)))) 414 { 415 // Wait up to 200ms for Host Status to get set. 416 Store(4000,Local0) // 4000 * 50us = 200ms. 417 418 While(LAnd(LNot(And(HSTS,0x80)),Local0)) 419 { 420 Decrement(Local0) // Decrement Count. 421 Stall(50) // Delay = 50us. 422 } 423 424 If(LNot(Local0)) // Timeout? 425 { 426 KILL() // Yes. Kill Communication. 427 Return(0) // Return failure. 428 } 429 430 Store(HBDR,Index(TBUF,Local1)) // Place into Buffer. 431 Store(0x80,HSTS) // Clear Host Status. 432 Increment(Local1) 433 } 434 435 // Step 5: Exit the Method correctly. 436 If(COMP()) 437 { 438 Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others. 439 Return(TBUF) // Return Success. 440 } 441 442 Return(0) // Return Failure. 443} 444 445 446// SMBus Start Check 447// Return: Success = 0 448// Failure = 1 449Method(STRT,0,Serialized) 450{ 451 // Wait up to 200ms to confirm the SMBus Semaphore has been 452 // released (In Use Status = 0). Note that the Sleep time may take 453 // longer as the This function will yield the Processor such that it 454 // may perform different tasks during the delay. 455 Store(200,Local0) // 200 * 1ms = 200ms. 456 457 While(Local0) 458 { 459 If(And(HSTS,0x40)) // In Use Set? 460 { 461 Decrement(Local0) // Yes. Decrement Count. 462 Sleep(1) // Delay = 1ms. 463 If(LEqual(Local0,0)) // Count = 0? 464 { 465 Return(1) // Return failure. 466 } 467 } 468 Else 469 { 470 Store(0,Local0) // In Use Clear. Continue. 471 } 472 } 473 474 // In Use Status = 0 during last read, which will make subsequent 475 // reads return In Use Status = 1 until software clears it. All 476 // software using ICHx SMBus should check this bit before initiating 477 // any SMBus communication. 478 479 // Wait up to 200ms to confirm the Host Interface is 480 // not processing a command. 481 Store(4000,Local0) // 4000 * 50us = 200ms. 482 483 While(Local0) 484 { 485 If(And(HSTS,0x01)) // Host Busy Set? 486 { 487 Decrement(Local0) // Decrement Count. 488 Stall(50) // Delay = 50us. 489 If(LEqual(Local0,0)) // Count = 0? 490 { 491 KILL() // Yes. Kill Communication. 492 } 493 } 494 Else 495 { 496 Return(0) 497 } 498 } 499 500 Return(1) // Timeout. Return failure. 501} 502 503// SMBus Completion Check 504// Return: Success = 1 505// Failure = 0 506Method(COMP,0,Serialized) 507{ 508 // Wait for up to 200ms for the Completion Command 509 // Status to get set. 510 Store(4000,Local0) // 4000 * 50us = 200ms. 511 512 While(Local0) 513 { 514 If(And(HSTS,0x02)) // Completion Status Set? 515 { 516 Return(1) // Yes. We are done. 517 } 518 Else 519 { 520 Decrement(Local0) // Decrement Count. 521 Stall(50) // Delay 50us. 522 If(LEqual(Local0,0)) // Count = 0? 523 { 524 KILL() // Yes. Kill Communication. 525 } 526 } 527 } 528 529 Return(0) // Timeout. Return Failure. 530} 531 532// SMBus Kill Command 533Method(KILL,0,Serialized) 534{ 535 Or(HCON,0x02,HCON) // Yes. Send Kill command. 536 Or(HSTS,0xFF,HSTS) // Clear all status. 537} 538