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