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