]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseSmbusLib/SmbusLib.c
1. UINTN & INTN issue for EBC architecture:
[mirror_edk2.git] / MdePkg / Library / BaseSmbusLib / SmbusLib.c
CommitLineData
878ddf1f 1/** @file\r
2 Base SMBUS library implementation built upon I/O library.\r
3\r
4 Copyright (c) 2006, Intel Corporation<BR>\r
5 All rights reserved. This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
5f10fa01 13 Module Name: SmbusLib.c\r
878ddf1f 14\r
15**/\r
16\r
5f10fa01 17#include "SmbusLibRegisters.h"\r
878ddf1f 18\r
5f10fa01 19#define SMBUS_LIB_SLAVE_ADDRESS(SmBusAddress) (((SmBusAddress) >> 1) & 0x7f)\r
20#define SMBUS_LIB_COMMAND(SmBusAddress) (((SmBusAddress) >> 8) & 0xff)\r
4ba61e5e 21#define SMBUS_LIB_LENGTH(SmBusAddress) (((SmBusAddress) >> 16) & 0x3f)\r
5f10fa01 22#define SMBUS_LIB_PEC(SmBusAddress) ((BOOLEAN) (((SmBusAddress) & SMBUS_LIB_PEC_BIT) != 0))\r
4ba61e5e 23#define SMBUS_LIB_RESEARVED(SmBusAddress) ((SmBusAddress) & ~(((1 << 22) - 2) | SMBUS_LIB_PEC_BIT))\r
878ddf1f 24\r
25//\r
5f10fa01 26// Replaced by PCD\r
878ddf1f 27//\r
5f10fa01 28#define ICH_SMBUS_BASE_ADDRESS 0xEFA0\r
878ddf1f 29\r
5f10fa01 30/**\r
31 Reads an 8-bit SMBUS register on ICH.\r
878ddf1f 32\r
5f10fa01 33 This internal function reads an SMBUS register specified by Offset.\r
878ddf1f 34\r
5f10fa01 35 @param Offset The offset of SMBUS register.\r
878ddf1f 36\r
5f10fa01 37 @return The value read.\r
878ddf1f 38\r
5f10fa01 39**/\r
40UINT8\r
41InternalSmBusIoRead8 (\r
42 IN UINTN Offset\r
878ddf1f 43 )\r
44{\r
5f10fa01 45 return IoRead8 (ICH_SMBUS_BASE_ADDRESS + Offset);\r
878ddf1f 46}\r
47\r
5f10fa01 48/**\r
49 Writes an 8-bit SMBUS register on ICH.\r
878ddf1f 50\r
5f10fa01 51 This internal function writes an SMBUS register specified by Offset.\r
878ddf1f 52\r
5f10fa01 53 @param Offset The offset of SMBUS register.\r
54 @param Value The value to write to SMBUS register.\r
878ddf1f 55\r
5f10fa01 56 @return The value written the SMBUS register.\r
57\r
58**/\r
59UINT8\r
60InternalSmBusIoWrite8 (\r
61 IN UINTN Offset,\r
62 IN UINT8 Value\r
878ddf1f 63 )\r
64{\r
5f10fa01 65 return IoWrite8 (ICH_SMBUS_BASE_ADDRESS + Offset, Value);\r
878ddf1f 66}\r
67\r
5f10fa01 68/**\r
69 Acquires the ownership of SMBUS.\r
70\r
71 This internal function reads the host state register.\r
72 If the SMBUS is not available, RETURN_TIMEOUT is returned;\r
73 Otherwise, it performs some basic initializations and returns\r
74 RETURN_SUCCESS. \r
75\r
76 @retval RETURN_SUCCESS The SMBUS command was executed successfully.\r
77 @retval RETURN_TIMEOUT A timeout occurred while executing the SMBUS command.\r
78\r
79**/\r
80RETURN_STATUS\r
81InternalSmBusAcquire (\r
82 VOID \r
878ddf1f 83 )\r
84{\r
5f10fa01 85 UINT8 HostStatus;\r
878ddf1f 86\r
5f10fa01 87 HostStatus = InternalSmBusIoRead8 (SMBUS_R_HST_STS);\r
88 if ((HostStatus & SMBUS_B_INUSE_STS) != 0) {\r
89 return RETURN_TIMEOUT;\r
90 } else if ((HostStatus & SMBUS_B_HOST_BUSY) != 0) {\r
91 //\r
92 // Clear Status Register and exit\r
93 //\r
94 InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);\r
95 return RETURN_TIMEOUT;\r
96 }\r
97 //\r
98 // Clear byte pointer of 32-byte buffer.\r
99 //\r
100 InternalSmBusIoRead8 (SMBUS_R_HST_CTL);\r
101 //\r
102 // Clear BYTE_DONE status\r
103 //\r
104 InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_BYTE_DONE_STS);\r
105 \r
106 return RETURN_SUCCESS;\r
878ddf1f 107}\r
108\r
5f10fa01 109/**\r
110 Waits until the completion of SMBUS transaction.\r
111\r
112 This internal function waits until the transaction of SMBUS is over\r
113 by polling the INTR bit of Host status register.\r
114 If the SMBUS is not available, RETURN_TIMEOUT is returned;\r
115 Otherwise, it performs some basic initializations and returns\r
116 RETURN_SUCCESS. \r
117\r
118 @retval RETURN_SUCCESS The SMBUS command was executed successfully.\r
119 @retval RETURN_CRC_ERROR The checksum is not correct (PEC is incorrect).\r
120 @retval RETURN_DEVICE_ERROR The request was not completed because a failure reflected\r
121 in the Host Status Register bit. Device errors are\r
122 a result of a transaction collision, illegal command field,\r
123 unclaimed cycle (host initiated), or bus errors (collisions).\r
124\r
125**/\r
126RETURN_STATUS\r
127InternalSmBusWait (\r
128 VOID \r
878ddf1f 129 )\r
130{\r
5f10fa01 131 UINT8 HostStatus;\r
132 UINT8 AuxiliaryStatus;\r
133 BOOLEAN First;\r
134 First = TRUE;\r
135\r
136 do {\r
137 //\r
138 // Poll INTR bit of host status register.\r
139 //\r
140 HostStatus = InternalSmBusIoRead8 (SMBUS_R_HST_STS);\r
141 } while ((HostStatus & (SMBUS_B_INTR | SMBUS_B_ERROR | SMBUS_B_BYTE_DONE_STS)) == 0);\r
142 \r
143 if ((HostStatus & SMBUS_B_ERROR) == 0) {\r
144 return RETURN_SUCCESS;\r
145 }\r
146 //\r
147 // Clear error bits of host status register\r
148 //\r
149 InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_ERROR);\r
150 //\r
151 // Read auxiliary status register to judge CRC error.\r
152 //\r
153 AuxiliaryStatus = InternalSmBusIoRead8 (SMBUS_R_AUX_STS);\r
154 if ((AuxiliaryStatus & SMBUS_B_CRCE) != 0) {\r
155 return RETURN_CRC_ERROR;\r
156 }\r
157\r
158 return RETURN_DEVICE_ERROR;\r
878ddf1f 159}\r
160\r
5f10fa01 161/**\r
162 Executes an SMBUS quick read/write command.\r
163\r
164 This internal function executes an SMBUS quick read/write command\r
165 on the SMBUS device specified by SmBusAddress.\r
166 Only the SMBUS slave address field of SmBusAddress is required.\r
167 If Status is not NULL, then the status of the executed command is returned in Status.\r
168\r
169 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
170 SMBUS Command, SMBUS Data Length, and PEC.\r
171 @param Status Return status for the executed command.\r
172 This is an optional parameter and may be NULL.\r
173\r
174**/\r
175VOID\r
878ddf1f 176EFIAPI\r
5f10fa01 177InternalSmBusQuick (\r
178 IN UINTN SmBusAddress,\r
179 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 180 )\r
181{\r
5f10fa01 182 RETURN_STATUS ReturnStatus;\r
878ddf1f 183\r
5f10fa01 184 ReturnStatus = InternalSmBusAcquire ();\r
185 if (RETURN_ERROR (ReturnStatus)) {\r
186 goto Done;\r
878ddf1f 187 }\r
5f10fa01 188 \r
189 //\r
190 // Set Command register\r
191 //\r
192 InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, 0);\r
193 //\r
194 // Set Auxiliary Control register\r
195 //\r
196 InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, 0);\r
197 //\r
198 // Set SMBus slave address for the device to send/receive from\r
199 //\r
200 InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);\r
201 //\r
202 // Set Control Register (Initiate Operation, Interrupt disabled)\r
203 //\r
204 InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, SMBUS_V_SMB_CMD_QUICK + SMBUS_B_START);\r
878ddf1f 205\r
5f10fa01 206 //\r
207 // Wait for the end\r
208 //\r
209 ReturnStatus = InternalSmBusWait ();\r
878ddf1f 210\r
5f10fa01 211 //\r
212 // Clear status register and exit\r
213 //\r
214 InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);;\r
215\r
216Done:\r
217 if (Status != NULL) {\r
218 *Status = ReturnStatus;\r
219 }\r
878ddf1f 220}\r
221\r
5f10fa01 222/**\r
223 Executes an SMBUS quick read command.\r
224\r
225 Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.\r
226 Only the SMBUS slave address field of SmBusAddress is required.\r
227 If Status is not NULL, then the status of the executed command is returned in Status.\r
228 If PEC is set in SmBusAddress, then ASSERT().\r
229 If Command in SmBusAddress is not zero, then ASSERT().\r
230 If Length in SmBusAddress is not zero, then ASSERT().\r
231 If any reserved bits of SmBusAddress are set, then ASSERT().\r
232\r
233 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
234 SMBUS Command, SMBUS Data Length, and PEC.\r
235 @param Status Return status for the executed command.\r
236 This is an optional parameter and may be NULL.\r
237\r
238**/\r
878ddf1f 239VOID\r
240EFIAPI\r
241SmBusQuickRead (\r
5f10fa01 242 IN UINTN SmBusAddress,\r
243 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 244 )\r
245{\r
5f10fa01 246 ASSERT (!SMBUS_LIB_PEC (SmBusAddress));\r
247 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);\r
248 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
249 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
878ddf1f 250\r
5f10fa01 251 InternalSmBusQuick (SmBusAddress | SMBUS_B_READ, Status);\r
878ddf1f 252}\r
253\r
5f10fa01 254/**\r
255 Executes an SMBUS quick write command.\r
256\r
257 Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.\r
258 Only the SMBUS slave address field of SmBusAddress is required.\r
259 If Status is not NULL, then the status of the executed command is returned in Status.\r
260 If PEC is set in SmBusAddress, then ASSERT().\r
261 If Command in SmBusAddress is not zero, then ASSERT().\r
262 If Length in SmBusAddress is not zero, then ASSERT().\r
263 If any reserved bits of SmBusAddress are set, then ASSERT().\r
264\r
265 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
266 SMBUS Command, SMBUS Data Length, and PEC.\r
267 @param Status Return status for the executed command.\r
268 This is an optional parameter and may be NULL.\r
269\r
270**/\r
271VOID\r
878ddf1f 272EFIAPI\r
273SmBusQuickWrite (\r
5f10fa01 274 IN UINTN SmBusAddress,\r
275 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 276 )\r
277{\r
5f10fa01 278 ASSERT (!SMBUS_LIB_PEC (SmBusAddress));\r
279 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);\r
280 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
281 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
878ddf1f 282\r
5f10fa01 283 InternalSmBusQuick (SmBusAddress | SMBUS_B_WRITE, Status);\r
878ddf1f 284}\r
285\r
5f10fa01 286/**\r
287 Executes an SMBUS byte or word command.\r
288\r
289 This internal function executes an .\r
290 Only the SMBUS slave address field of SmBusAddress is required.\r
291 If Status is not NULL, then the status of the executed command is returned in Status.\r
292\r
293 @param HostControl The value of Host Control Register to set. \r
294 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
295 SMBUS Command, SMBUS Data Length, and PEC.\r
296 @param Value The byte/word write to the SMBUS.\r
297 @param Status Return status for the executed command.\r
298 This is an optional parameter and may be NULL.\r
299\r
300 @return The byte/word read from the SMBUS.\r
301\r
302**/\r
878ddf1f 303UINT16\r
5f10fa01 304InternalSmBusByteWord (\r
305 IN UINT8 HostControl,\r
306 IN UINTN SmBusAddress,\r
307 IN UINT16 Value,\r
308 OUT RETURN_STATUS *Status\r
878ddf1f 309 )\r
310{\r
5f10fa01 311 RETURN_STATUS ReturnStatus;\r
312 UINT8 AuxiliaryControl;\r
878ddf1f 313\r
5f10fa01 314 ReturnStatus = InternalSmBusAcquire ();\r
315 if (RETURN_ERROR (ReturnStatus)) {\r
316 goto Done;\r
878ddf1f 317 }\r
318\r
5f10fa01 319 AuxiliaryControl = 0;\r
320 if (SMBUS_LIB_PEC (SmBusAddress)) {\r
321 AuxiliaryControl |= SMBUS_B_AAC;\r
322 HostControl |= SMBUS_B_PEC_EN;\r
878ddf1f 323 }\r
5f10fa01 324 \r
325 //\r
326 // Set commond register\r
327 //\r
328 InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));\r
878ddf1f 329\r
5f10fa01 330 InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) Value);\r
331 InternalSmBusIoWrite8 (SMBUS_R_HST_D1, (UINT8) (Value >> 8));\r
332\r
333 //\r
334 // Set Auxiliary Control Regiester.\r
335 //\r
336 InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);\r
337 //\r
338 // Set SMBus slave address for the device to send/receive from.\r
339 //\r
340 InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);\r
341 //\r
342 // Set Control Register (Initiate Operation, Interrupt disabled)\r
343 //\r
344 InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, HostControl + SMBUS_B_START);\r
345\r
346 //\r
347 // Wait for the end\r
348 //\r
349 ReturnStatus = InternalSmBusWait ();\r
350 \r
351 Value = InternalSmBusIoRead8 (SMBUS_R_HST_D1) << 8;\r
352 Value |= InternalSmBusIoRead8 (SMBUS_R_HST_D0);\r
878ddf1f 353\r
5f10fa01 354 //\r
355 // Clear status register and exit\r
356 //\r
357 InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);;\r
878ddf1f 358\r
5f10fa01 359Done:\r
360 if (Status != NULL) {\r
361 *Status = ReturnStatus;\r
878ddf1f 362 }\r
363\r
878ddf1f 364 return Value;\r
365}\r
366\r
5f10fa01 367/**\r
368 Executes an SMBUS receive byte command.\r
369\r
370 Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.\r
371 Only the SMBUS slave address field of SmBusAddress is required.\r
372 The byte received from the SMBUS is returned.\r
373 If Status is not NULL, then the status of the executed command is returned in Status.\r
374 If Command in SmBusAddress is not zero, then ASSERT().\r
375 If Length in SmBusAddress is not zero, then ASSERT().\r
376 If any reserved bits of SmBusAddress are set, then ASSERT().\r
377\r
378 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
379 SMBUS Command, SMBUS Data Length, and PEC.\r
380 @param Status Return status for the executed command.\r
381 This is an optional parameter and may be NULL.\r
382\r
383 @return The byte received from the SMBUS.\r
384\r
385**/\r
878ddf1f 386UINT8\r
387EFIAPI\r
388SmBusReceiveByte (\r
5f10fa01 389 IN UINTN SmBusAddress,\r
390 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 391 )\r
392{\r
5f10fa01 393 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);\r
394 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
395 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
396\r
397 return (UINT8) InternalSmBusByteWord (\r
398 SMBUS_V_SMB_CMD_BYTE,\r
399 SmBusAddress | SMBUS_B_READ,\r
400 0,\r
401 Status\r
402 );\r
878ddf1f 403}\r
404\r
5f10fa01 405/**\r
406 Executes an SMBUS send byte command.\r
407\r
408 Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.\r
409 The byte specified by Value is sent.\r
410 Only the SMBUS slave address field of SmBusAddress is required. Value is returned.\r
411 If Status is not NULL, then the status of the executed command is returned in Status.\r
412 If Command in SmBusAddress is not zero, then ASSERT().\r
413 If Length in SmBusAddress is not zero, then ASSERT().\r
414 If any reserved bits of SmBusAddress are set, then ASSERT().\r
415\r
416 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
417 SMBUS Command, SMBUS Data Length, and PEC.\r
418 @param Value The 8-bit value to send.\r
419 @param Status Return status for the executed command.\r
420 This is an optional parameter and may be NULL.\r
421\r
422 @return The parameter of Value.\r
423\r
424**/\r
878ddf1f 425UINT8\r
426EFIAPI\r
427SmBusSendByte (\r
5f10fa01 428 IN UINTN SmBusAddress,\r
429 IN UINT8 Value,\r
430 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 431 )\r
432{\r
5f10fa01 433 ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);\r
434 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
435 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
436\r
437 return (UINT8) InternalSmBusByteWord (\r
438 SMBUS_V_SMB_CMD_BYTE,\r
439 SmBusAddress | SMBUS_B_WRITE,\r
440 Value,\r
441 Status\r
442 );\r
878ddf1f 443}\r
444\r
5f10fa01 445/**\r
446 Executes an SMBUS read data byte command.\r
447\r
448 Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.\r
449 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
450 The 8-bit value read from the SMBUS is returned.\r
451 If Status is not NULL, then the status of the executed command is returned in Status.\r
452 If Length in SmBusAddress is not zero, then ASSERT().\r
453 If any reserved bits of SmBusAddress are set, then ASSERT().\r
454\r
455 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
456 SMBUS Command, SMBUS Data Length, and PEC.\r
457 @param Status Return status for the executed command.\r
458 This is an optional parameter and may be NULL.\r
459\r
460 @return The byte read from the SMBUS.\r
461\r
462**/\r
878ddf1f 463UINT8\r
464EFIAPI\r
465SmBusReadDataByte (\r
5f10fa01 466 IN UINTN SmBusAddress,\r
467 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 468 )\r
469{\r
5f10fa01 470 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
471 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
472\r
473 return (UINT8) InternalSmBusByteWord (\r
474 SMBUS_V_SMB_CMD_BYTE_DATA,\r
475 SmBusAddress | SMBUS_B_READ,\r
476 0,\r
477 Status\r
478 );\r
878ddf1f 479}\r
480\r
5f10fa01 481/**\r
482 Executes an SMBUS write data byte command.\r
483\r
484 Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.\r
485 The 8-bit value specified by Value is written.\r
486 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
487 Value is returned.\r
488 If Status is not NULL, then the status of the executed command is returned in Status.\r
489 If Length in SmBusAddress is not zero, then ASSERT().\r
490 If any reserved bits of SmBusAddress are set, then ASSERT().\r
491\r
492 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
493 SMBUS Command, SMBUS Data Length, and PEC.\r
494 @param Value The 8-bit value to write.\r
495 @param Status Return status for the executed command.\r
496 This is an optional parameter and may be NULL.\r
497\r
498 @return The parameter of Value.\r
499\r
500**/\r
878ddf1f 501UINT8\r
502EFIAPI\r
503SmBusWriteDataByte (\r
5f10fa01 504 IN UINTN SmBusAddress,\r
505 IN UINT8 Value,\r
506 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 507 )\r
508{\r
5f10fa01 509 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
510 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
511\r
512 return (UINT8) InternalSmBusByteWord (\r
513 SMBUS_V_SMB_CMD_BYTE_DATA,\r
514 SmBusAddress | SMBUS_B_WRITE,\r
515 Value,\r
516 Status\r
517 );\r
878ddf1f 518}\r
519\r
5f10fa01 520/**\r
521 Executes an SMBUS read data word command.\r
522\r
523 Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.\r
524 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
525 The 16-bit value read from the SMBUS is returned.\r
526 If Status is not NULL, then the status of the executed command is returned in Status.\r
527 If Length in SmBusAddress is not zero, then ASSERT().\r
528 If any reserved bits of SmBusAddress are set, then ASSERT().\r
529 \r
530 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
531 SMBUS Command, SMBUS Data Length, and PEC.\r
532 @param Status Return status for the executed command.\r
533 This is an optional parameter and may be NULL.\r
534\r
535 @return The byte read from the SMBUS.\r
536\r
537**/\r
878ddf1f 538UINT16\r
539EFIAPI\r
540SmBusReadDataWord (\r
5f10fa01 541 IN UINTN SmBusAddress,\r
542 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 543 )\r
544{\r
5f10fa01 545 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
546 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
547\r
548 return InternalSmBusByteWord (\r
549 SMBUS_V_SMB_CMD_WORD_DATA,\r
550 SmBusAddress | SMBUS_B_READ,\r
878ddf1f 551 0,\r
878ddf1f 552 Status\r
553 );\r
554}\r
555\r
5f10fa01 556/**\r
557 Executes an SMBUS write data word command.\r
558\r
559 Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.\r
560 The 16-bit value specified by Value is written.\r
561 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
562 Value is returned.\r
563 If Status is not NULL, then the status of the executed command is returned in Status.\r
564 If Length in SmBusAddress is not zero, then ASSERT().\r
565 If any reserved bits of SmBusAddress are set, then ASSERT().\r
566\r
567 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
568 SMBUS Command, SMBUS Data Length, and PEC.\r
569 @param Value The 16-bit value to write.\r
570 @param Status Return status for the executed command.\r
571 This is an optional parameter and may be NULL.\r
572\r
573 @return The parameter of Value.\r
574\r
575**/\r
878ddf1f 576UINT16\r
577EFIAPI\r
578SmBusWriteDataWord (\r
5f10fa01 579 IN UINTN SmBusAddress,\r
580 IN UINT16 Value,\r
581 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 582 )\r
583{\r
5f10fa01 584 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
585 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
586\r
587 return InternalSmBusByteWord (\r
588 SMBUS_V_SMB_CMD_WORD_DATA,\r
589 SmBusAddress | SMBUS_B_WRITE,\r
878ddf1f 590 Value,\r
878ddf1f 591 Status\r
592 );\r
593}\r
594\r
5f10fa01 595/**\r
596 Executes an SMBUS process call command.\r
597\r
598 Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.\r
599 The 16-bit value specified by Value is written.\r
600 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
601 The 16-bit value returned by the process call command is returned.\r
602 If Status is not NULL, then the status of the executed command is returned in Status.\r
603 If Length in SmBusAddress is not zero, then ASSERT().\r
604 If any reserved bits of SmBusAddress are set, then ASSERT().\r
605\r
606 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
607 SMBUS Command, SMBUS Data Length, and PEC.\r
608 @param Value The 16-bit value to write.\r
609 @param Status Return status for the executed command.\r
610 This is an optional parameter and may be NULL.\r
611\r
612 @return The 16-bit value returned by the process call command.\r
613\r
614**/\r
878ddf1f 615UINT16\r
616EFIAPI\r
617SmBusProcessCall (\r
5f10fa01 618 IN UINTN SmBusAddress,\r
619 IN UINT16 Value,\r
620 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 621 )\r
622{\r
5f10fa01 623 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
624 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
625\r
626 return InternalSmBusByteWord (\r
627 SMBUS_V_SMB_CMD_PROCESS_CALL,\r
628 SmBusAddress | SMBUS_B_WRITE,\r
878ddf1f 629 Value,\r
878ddf1f 630 Status\r
631 );\r
632}\r
633\r
5f10fa01 634/**\r
635 Executes an SMBUS block command.\r
636\r
637 Executes an SMBUS block read, block write and block write-block read command\r
638 on the SMBUS device specified by SmBusAddress.\r
639 Bytes are read from the SMBUS and stored in Buffer.\r
640 The number of bytes read is returned, and will never return a value larger than 32-bytes.\r
641 If Status is not NULL, then the status of the executed command is returned in Status.\r
4ba61e5e 642 It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.\r
5f10fa01 643 SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.\r
644\r
645 @param HostControl The value of Host Control Register to set. \r
646 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
647 SMBUS Command, SMBUS Data Length, and PEC.\r
4ba61e5e 648 @param WriteBuffer Pointer to the buffer of bytes to write to the SMBUS.\r
649 @param ReadBuffer Pointer to the buffer of bytes to read from the SMBUS.\r
5f10fa01 650 @param Status Return status for the executed command.\r
651 This is an optional parameter and may be NULL.\r
652\r
653 @return The number of bytes read from the SMBUS.\r
654\r
655**/\r
878ddf1f 656UINTN\r
5f10fa01 657InternalSmBusBlock (\r
658 IN UINT8 HostControl,\r
659 IN UINTN SmBusAddress,\r
4ba61e5e 660 IN UINT8 *WriteBuffer,\r
661 OUT UINT8 *ReadBuffer,\r
5f10fa01 662 OUT RETURN_STATUS *Status\r
878ddf1f 663 )\r
664{\r
5f10fa01 665 RETURN_STATUS ReturnStatus;\r
666 UINTN Index;\r
667 UINTN BytesCount;\r
668 UINT8 AuxiliaryControl;\r
878ddf1f 669\r
4ba61e5e 670 BytesCount = SMBUS_LIB_LENGTH (SmBusAddress);\r
878ddf1f 671\r
5f10fa01 672 ReturnStatus = InternalSmBusAcquire ();\r
673 if (RETURN_ERROR (ReturnStatus)) {\r
674 goto Done;\r
878ddf1f 675 }\r
5f10fa01 676 \r
677 AuxiliaryControl = SMBUS_B_E32B;\r
678 if (SMBUS_LIB_PEC (SmBusAddress)) {\r
679 AuxiliaryControl |= SMBUS_B_AAC;\r
680 HostControl |= SMBUS_B_PEC_EN;\r
878ddf1f 681 }\r
682\r
5f10fa01 683 InternalSmBusIoWrite8 (SMBUS_R_HST_CMD, (UINT8) SMBUS_LIB_COMMAND (SmBusAddress));\r
684\r
685 InternalSmBusIoWrite8 (SMBUS_R_HST_D0, (UINT8) BytesCount);\r
686\r
4ba61e5e 687 if (WriteBuffer != NULL) {\r
5f10fa01 688 for (Index = 0; Index < BytesCount; Index++) {\r
4ba61e5e 689 InternalSmBusIoWrite8 (SMBUS_R_HOST_BLOCK_DB, WriteBuffer[Index]);\r
5f10fa01 690 }\r
878ddf1f 691 }\r
5f10fa01 692 //\r
693 // Set Auxiliary Control Regiester.\r
694 //\r
695 InternalSmBusIoWrite8 (SMBUS_R_AUX_CTL, AuxiliaryControl);\r
696 //\r
697 // Set SMBus slave address for the device to send/receive from\r
698 //\r
699 InternalSmBusIoWrite8 (SMBUS_R_XMIT_SLVA, (UINT8) SmBusAddress);\r
700 //\r
701 // Set Control Register (Initiate Operation, Interrupt disabled)\r
702 //\r
703 InternalSmBusIoWrite8 (SMBUS_R_HST_CTL, HostControl + SMBUS_B_START);\r
878ddf1f 704\r
705 //\r
5f10fa01 706 // Wait for the end\r
878ddf1f 707 //\r
5f10fa01 708 ReturnStatus = InternalSmBusWait ();\r
709 if (RETURN_ERROR (ReturnStatus)) {\r
710 goto Done;\r
878ddf1f 711 }\r
712\r
5f10fa01 713 BytesCount = InternalSmBusIoRead8 (SMBUS_R_HST_D0);\r
4ba61e5e 714 if (ReadBuffer != NULL) {\r
5f10fa01 715 for (Index = 0; Index < BytesCount; Index++) {\r
4ba61e5e 716 ReadBuffer[Index] = InternalSmBusIoRead8 (SMBUS_R_HOST_BLOCK_DB);\r
878ddf1f 717 }\r
718 }\r
719\r
5f10fa01 720 //\r
721 // Clear status register and exit\r
722 //\r
723 InternalSmBusIoWrite8 (SMBUS_R_HST_STS, SMBUS_B_HSTS_ALL);\r
724\r
725Done:\r
726 if (Status != NULL) {\r
727 *Status = ReturnStatus;\r
728 }\r
729\r
878ddf1f 730 return BytesCount;\r
731}\r
732\r
5f10fa01 733/**\r
734 Executes an SMBUS read block command.\r
735\r
736 Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.\r
737 Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
738 Bytes are read from the SMBUS and stored in Buffer.\r
739 The number of bytes read is returned, and will never return a value larger than 32-bytes.\r
740 If Status is not NULL, then the status of the executed command is returned in Status.\r
4ba61e5e 741 It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.\r
5f10fa01 742 SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.\r
743 If Length in SmBusAddress is not zero, then ASSERT().\r
744 If Buffer is NULL, then ASSERT().\r
745 If any reserved bits of SmBusAddress are set, then ASSERT().\r
746\r
747 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
748 SMBUS Command, SMBUS Data Length, and PEC.\r
749 @param Buffer Pointer to the buffer to store the bytes read from the SMBUS.\r
750 @param Status Return status for the executed command.\r
751 This is an optional parameter and may be NULL.\r
752\r
753 @return The number of bytes read.\r
754\r
755**/\r
878ddf1f 756UINTN\r
757EFIAPI\r
758SmBusReadBlock (\r
5f10fa01 759 IN UINTN SmBusAddress,\r
760 OUT VOID *Buffer,\r
761 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 762 )\r
763{\r
5f10fa01 764 ASSERT (Buffer != NULL);\r
765 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) == 0);\r
766 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
767\r
768 return InternalSmBusBlock (\r
769 SMBUS_V_SMB_CMD_BLOCK,\r
770 SmBusAddress | SMBUS_B_READ,\r
878ddf1f 771 NULL,\r
772 Buffer,\r
773 Status\r
774 );\r
775}\r
776\r
5f10fa01 777/**\r
778 Executes an SMBUS write block command.\r
779\r
780 Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.\r
781 The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.\r
782 Bytes are written to the SMBUS from Buffer.\r
783 The number of bytes written is returned, and will never return a value larger than 32-bytes.\r
784 If Status is not NULL, then the status of the executed command is returned in Status. \r
785 If Length in SmBusAddress is zero or greater than 32, then ASSERT().\r
786 If Buffer is NULL, then ASSERT().\r
787 If any reserved bits of SmBusAddress are set, then ASSERT().\r
788\r
789 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
790 SMBUS Command, SMBUS Data Length, and PEC.\r
791 @param Buffer Pointer to the buffer to store the bytes read from the SMBUS.\r
792 @param Status Return status for the executed command.\r
793 This is an optional parameter and may be NULL.\r
794\r
795 @return The number of bytes written.\r
796\r
797**/\r
878ddf1f 798UINTN\r
799EFIAPI\r
800SmBusWriteBlock (\r
5f10fa01 801 IN UINTN SmBusAddress,\r
802 OUT VOID *Buffer,\r
803 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 804 )\r
805{\r
5f10fa01 806 ASSERT (Buffer != NULL);\r
4ba61e5e 807 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);\r
808 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);\r
5f10fa01 809 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
810\r
811 return InternalSmBusBlock (\r
812 SMBUS_V_SMB_CMD_BLOCK,\r
813 SmBusAddress | SMBUS_B_WRITE,\r
878ddf1f 814 Buffer,\r
815 NULL,\r
816 Status\r
817 );\r
818}\r
819\r
5f10fa01 820/**\r
821 Executes an SMBUS block process call command.\r
822\r
823 Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.\r
824 The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.\r
4ba61e5e 825 Bytes are written to the SMBUS from WriteBuffer. Bytes are then read from the SMBUS into ReadBuffer.\r
5f10fa01 826 If Status is not NULL, then the status of the executed command is returned in Status.\r
4ba61e5e 827 It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.\r
5f10fa01 828 SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.\r
4ba61e5e 829 If Length in SmBusAddress is zero or greater than 32, then ASSERT().\r
830 If WriteBuffer is NULL, then ASSERT().\r
831 If ReadBuffer is NULL, then ASSERT().\r
5f10fa01 832 If any reserved bits of SmBusAddress are set, then ASSERT().\r
833\r
834 @param SmBusAddress Address that encodes the SMBUS Slave Address,\r
835 SMBUS Command, SMBUS Data Length, and PEC.\r
4ba61e5e 836 @param WriteBuffer Pointer to the buffer of bytes to write to the SMBUS.\r
837 @param ReadBuffer Pointer to the buffer of bytes to read from the SMBUS.\r
5f10fa01 838 @param Status Return status for the executed command.\r
839 This is an optional parameter and may be NULL.\r
840\r
841 @return The number of bytes written.\r
842\r
843**/\r
878ddf1f 844UINTN\r
845EFIAPI\r
846SmBusBlockProcessCall (\r
5f10fa01 847 IN UINTN SmBusAddress,\r
4ba61e5e 848 IN VOID *WriteBuffer,\r
849 OUT VOID *ReadBuffer,\r
5f10fa01 850 OUT RETURN_STATUS *Status OPTIONAL\r
878ddf1f 851 )\r
852{\r
4ba61e5e 853 ASSERT (WriteBuffer != NULL);\r
854 ASSERT (ReadBuffer != NULL);\r
855 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);\r
856 ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);\r
5f10fa01 857 ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
858\r
859 return InternalSmBusBlock (\r
860 SMBUS_V_SMB_CMD_BLOCK_PROCESS,\r
861 SmBusAddress | SMBUS_B_WRITE,\r
4ba61e5e 862 WriteBuffer,\r
863 ReadBuffer,\r
878ddf1f 864 Status\r
865 );\r
866}\r