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