13c38fb934d50bd883ce0c3e0c543cda3384555e
[people/mcb30/edk2.git] / edk2 / MdePkg / Library / PeiSmbusLibSmbus2 / SmbusLib.c
1 /** @file\r
2 Implementation of SmBusLib class library for PEI phase.\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 \r
14 Module Name: SmbusLib.c\r
15 \r
16 **/\r
17 \r
18 #include <Ppi/Smbus2.h>\r
19 #include "InternalSmbusLib.h"\r
20 \r
21 /**\r
22   Executes an SMBUS quick read command.\r
23 \r
24   Executes an SMBUS quick read command on the SMBUS device specified by SmBusAddress.\r
25   Only the SMBUS slave address field of SmBusAddress is required.\r
26   If Status is not NULL, then the status of the executed command is returned in Status.\r
27   If PEC is set in SmBusAddress, then ASSERT().\r
28   If Command in SmBusAddress is not zero, then ASSERT().\r
29   If Length in SmBusAddress is not zero, then ASSERT().\r
30   If any reserved bits of SmBusAddress are set, then ASSERT().\r
31 \r
32   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
33                           SMBUS Command, SMBUS Data Length, and PEC.\r
34   @param  Status          Return status for the executed command.\r
35                           This is an optional parameter and may be NULL.\r
36 \r
37 **/\r
38 VOID\r
39 EFIAPI\r
40 SmBusQuickRead (\r
41   IN  UINTN                     SmBusAddress,\r
42   OUT RETURN_STATUS             *Status       OPTIONAL\r
43   )\r
44 {\r
45   ASSERT (!SMBUS_LIB_PEC (SmBusAddress));\r
46   ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);\r
47   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
48   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
49 \r
50   InternalSmBusExec (EfiSmbusQuickRead, SmBusAddress, 0, NULL, Status);\r
51 }\r
52 \r
53 /**\r
54   Executes an SMBUS quick write command.\r
55 \r
56   Executes an SMBUS quick write command on the SMBUS device specified by SmBusAddress.\r
57   Only the SMBUS slave address field of SmBusAddress is required.\r
58   If Status is not NULL, then the status of the executed command is returned in Status.\r
59   If PEC is set in SmBusAddress, then ASSERT().\r
60   If Command in SmBusAddress is not zero, then ASSERT().\r
61   If Length in SmBusAddress is not zero, then ASSERT().\r
62   If any reserved bits of SmBusAddress are set, then ASSERT().\r
63 \r
64   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
65                           SMBUS Command, SMBUS Data Length, and PEC.\r
66   @param  Status          Return status for the executed command.\r
67                           This is an optional parameter and may be NULL.\r
68 \r
69 **/\r
70 VOID\r
71 EFIAPI\r
72 SmBusQuickWrite (\r
73   IN  UINTN                     SmBusAddress,\r
74   OUT RETURN_STATUS             *Status       OPTIONAL\r
75   )\r
76 {\r
77   ASSERT (!SMBUS_LIB_PEC (SmBusAddress));\r
78   ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);\r
79   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
80   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
81 \r
82   InternalSmBusExec (EfiSmbusQuickWrite, SmBusAddress, 0, NULL, Status);\r
83 }\r
84 \r
85 /**\r
86   Executes an SMBUS receive byte command.\r
87 \r
88   Executes an SMBUS receive byte command on the SMBUS device specified by SmBusAddress.\r
89   Only the SMBUS slave address field of SmBusAddress is required.\r
90   The byte received from the SMBUS is returned.\r
91   If Status is not NULL, then the status of the executed command is returned in Status.\r
92   If Command in SmBusAddress is not zero, then ASSERT().\r
93   If Length in SmBusAddress is not zero, then ASSERT().\r
94   If any reserved bits of SmBusAddress are set, then ASSERT().\r
95 \r
96   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
97                           SMBUS Command, SMBUS Data Length, and PEC.\r
98   @param  Status          Return status for the executed command.\r
99                           This is an optional parameter and may be NULL.\r
100 \r
101   @return The byte received from the SMBUS.\r
102 \r
103 **/\r
104 UINT8\r
105 EFIAPI\r
106 SmBusReceiveByte (\r
107   IN  UINTN          SmBusAddress,\r
108   OUT RETURN_STATUS  *Status        OPTIONAL\r
109   )\r
110 {\r
111   UINT8   Byte;\r
112 \r
113   ASSERT (SMBUS_LIB_COMMAND (SmBusAddress) == 0);\r
114   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)  == 0);\r
115   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
116 \r
117   InternalSmBusExec (EfiSmbusReceiveByte, SmBusAddress, 1, &Byte, Status);\r
118 \r
119   return Byte;\r
120 }\r
121 \r
122 /**\r
123   Executes an SMBUS send byte command.\r
124 \r
125   Executes an SMBUS send byte command on the SMBUS device specified by SmBusAddress.\r
126   The byte specified by Value is sent.\r
127   Only the SMBUS slave address field of SmBusAddress is required.  Value is returned.\r
128   If Status is not NULL, then the status of the executed command is returned in Status.\r
129   If Command in SmBusAddress is not zero, then ASSERT().\r
130   If Length in SmBusAddress is not zero, then ASSERT().\r
131   If any reserved bits of SmBusAddress are set, then ASSERT().\r
132 \r
133   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
134                           SMBUS Command, SMBUS Data Length, and PEC.\r
135   @param  Value           The 8-bit value to send.\r
136   @param  Status          Return status for the executed command.\r
137                           This is an optional parameter and may be NULL.\r
138 \r
139   @return The parameter of Value.\r
140 \r
141 **/\r
142 UINT8\r
143 EFIAPI\r
144 SmBusSendByte (\r
145   IN  UINTN          SmBusAddress,\r
146   IN  UINT8          Value,\r
147   OUT RETURN_STATUS  *Status        OPTIONAL\r
148   )\r
149 {\r
150   UINT8   Byte;\r
151 \r
152   ASSERT (SMBUS_LIB_COMMAND (SmBusAddress)   == 0);\r
153   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
154   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
155 \r
156   Byte   = Value;\r
157   InternalSmBusExec (EfiSmbusSendByte, SmBusAddress, 1, &Byte, Status);\r
158 \r
159   return Value;\r
160 }\r
161 \r
162 /**\r
163   Executes an SMBUS read data byte command.\r
164 \r
165   Executes an SMBUS read data byte command on the SMBUS device specified by SmBusAddress.\r
166   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
167   The 8-bit value read from the SMBUS is returned.\r
168   If Status is not NULL, then the status of the executed command is returned in Status.\r
169   If Length in SmBusAddress is not zero, then ASSERT().\r
170   If any reserved bits of SmBusAddress are set, then ASSERT().\r
171 \r
172   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
173                           SMBUS Command, SMBUS Data Length, and PEC.\r
174   @param  Status          Return status for the executed command.\r
175                           This is an optional parameter and may be NULL.\r
176 \r
177   @return The byte read from the SMBUS.\r
178 \r
179 **/\r
180 UINT8\r
181 EFIAPI\r
182 SmBusReadDataByte (\r
183   IN  UINTN          SmBusAddress,\r
184   OUT RETURN_STATUS  *Status        OPTIONAL\r
185   )\r
186 {\r
187   UINT8   Byte;\r
188 \r
189   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
190   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
191 \r
192   InternalSmBusExec (EfiSmbusReadByte, SmBusAddress, 1, &Byte, Status);\r
193   \r
194   return Byte;\r
195 }\r
196 \r
197 /**\r
198   Executes an SMBUS write data byte command.\r
199 \r
200   Executes an SMBUS write data byte command on the SMBUS device specified by SmBusAddress.\r
201   The 8-bit value specified by Value is written.\r
202   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
203   Value is returned.\r
204   If Status is not NULL, then the status of the executed command is returned in Status.\r
205   If Length in SmBusAddress is not zero, then ASSERT().\r
206   If any reserved bits of SmBusAddress are set, then ASSERT().\r
207 \r
208   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
209                           SMBUS Command, SMBUS Data Length, and PEC.\r
210   @param  Value           The 8-bit value to write.\r
211   @param  Status          Return status for the executed command.\r
212                           This is an optional parameter and may be NULL.\r
213 \r
214   @return The parameter of Value.\r
215 \r
216 **/\r
217 UINT8\r
218 EFIAPI\r
219 SmBusWriteDataByte (\r
220   IN  UINTN          SmBusAddress,\r
221   IN  UINT8          Value,\r
222   OUT RETURN_STATUS  *Status        OPTIONAL\r
223   )\r
224 {\r
225   UINT8   Byte;\r
226 \r
227   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
228   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
229 \r
230   Byte = Value;\r
231   InternalSmBusExec (EfiSmbusWriteByte, SmBusAddress, 1, &Byte, Status);\r
232   \r
233   return Value;\r
234 }\r
235 \r
236 /**\r
237   Executes an SMBUS read data word command.\r
238 \r
239   Executes an SMBUS read data word command on the SMBUS device specified by SmBusAddress.\r
240   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
241   The 16-bit value read from the SMBUS is returned.\r
242   If Status is not NULL, then the status of the executed command is returned in Status.\r
243   If Length in SmBusAddress is not zero, then ASSERT().\r
244   If any reserved bits of SmBusAddress are set, then ASSERT().\r
245   \r
246   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
247                           SMBUS Command, SMBUS Data Length, and PEC.\r
248   @param  Status          Return status for the executed command.\r
249                           This is an optional parameter and may be NULL.\r
250 \r
251   @return The byte read from the SMBUS.\r
252 \r
253 **/\r
254 UINT16\r
255 EFIAPI\r
256 SmBusReadDataWord (\r
257   IN  UINTN          SmBusAddress,\r
258   OUT RETURN_STATUS  *Status        OPTIONAL\r
259   )\r
260 {\r
261   UINT16  Word;\r
262 \r
263   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
264   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
265 \r
266   InternalSmBusExec (EfiSmbusReadWord, SmBusAddress, 2, &Word, Status);\r
267   \r
268   return Word;\r
269 }\r
270 \r
271 /**\r
272   Executes an SMBUS write data word command.\r
273 \r
274   Executes an SMBUS write data word command on the SMBUS device specified by SmBusAddress.\r
275   The 16-bit value specified by Value is written.\r
276   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
277   Value is returned.\r
278   If Status is not NULL, then the status of the executed command is returned in Status.\r
279   If Length in SmBusAddress is not zero, then ASSERT().\r
280   If any reserved bits of SmBusAddress are set, then ASSERT().\r
281 \r
282   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
283                           SMBUS Command, SMBUS Data Length, and PEC.\r
284   @param  Value           The 16-bit value to write.\r
285   @param  Status          Return status for the executed command.\r
286                           This is an optional parameter and may be NULL.\r
287 \r
288   @return The parameter of Value.\r
289 \r
290 **/\r
291 UINT16\r
292 EFIAPI\r
293 SmBusWriteDataWord (\r
294   IN  UINTN          SmBusAddress,\r
295   IN  UINT16         Value,\r
296   OUT RETURN_STATUS  *Status        OPTIONAL\r
297   )\r
298 {\r
299   UINT16  Word;\r
300 \r
301   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
302   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
303 \r
304   Word = Value;\r
305   InternalSmBusExec (EfiSmbusWriteWord, SmBusAddress, 2, &Word, Status);\r
306 \r
307   return Value;\r
308 }\r
309 \r
310 /**\r
311   Executes an SMBUS process call command.\r
312 \r
313   Executes an SMBUS process call command on the SMBUS device specified by SmBusAddress.\r
314   The 16-bit value specified by Value is written.\r
315   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
316   The 16-bit value returned by the process call command is returned.\r
317   If Status is not NULL, then the status of the executed command is returned in Status.\r
318   If Length in SmBusAddress is not zero, then ASSERT().\r
319   If any reserved bits of SmBusAddress are set, then ASSERT().\r
320 \r
321   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
322                           SMBUS Command, SMBUS Data Length, and PEC.\r
323   @param  Value           The 16-bit value to write.\r
324   @param  Status          Return status for the executed command.\r
325                           This is an optional parameter and may be NULL.\r
326 \r
327   @return The 16-bit value returned by the process call command.\r
328 \r
329 **/\r
330 UINT16\r
331 EFIAPI\r
332 SmBusProcessCall (\r
333   IN  UINTN          SmBusAddress,\r
334   IN  UINT16         Value,\r
335   OUT RETURN_STATUS  *Status        OPTIONAL\r
336   )\r
337 {\r
338   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
339   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
340 \r
341   InternalSmBusExec (EfiSmbusProcessCall, SmBusAddress, 2, &Value, Status);\r
342   \r
343   return Value;\r
344 }\r
345 \r
346 /**\r
347   Executes an SMBUS read block command.\r
348 \r
349   Executes an SMBUS read block command on the SMBUS device specified by SmBusAddress.\r
350   Only the SMBUS slave address and SMBUS command fields of SmBusAddress are required.\r
351   Bytes are read from the SMBUS and stored in Buffer.\r
352   The number of bytes read is returned, and will never return a value larger than 32-bytes.\r
353   If Status is not NULL, then the status of the executed command is returned in Status.\r
354   It is the caller's responsibility to make sure Buffer is large enough for the total number of bytes read.\r
355   SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.\r
356   If Length in SmBusAddress is not zero, then ASSERT().\r
357   If Buffer is NULL, then ASSERT().\r
358   If any reserved bits of SmBusAddress are set, then ASSERT().\r
359 \r
360   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
361                           SMBUS Command, SMBUS Data Length, and PEC.\r
362   @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.\r
363   @param  Status          Return status for the executed command.\r
364                           This is an optional parameter and may be NULL.\r
365 \r
366   @return The number of bytes read.\r
367 \r
368 **/\r
369 UINTN\r
370 EFIAPI\r
371 SmBusReadBlock (\r
372   IN  UINTN          SmBusAddress,\r
373   OUT VOID           *Buffer,\r
374   OUT RETURN_STATUS  *Status        OPTIONAL\r
375   )\r
376 {\r
377   ASSERT (Buffer != NULL);\r
378   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress)    == 0);\r
379   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
380 \r
381   return InternalSmBusExec (EfiSmbusReadBlock, SmBusAddress, 0x20, Buffer, Status);\r
382 }\r
383 \r
384 /**\r
385   Executes an SMBUS write block command.\r
386 \r
387   Executes an SMBUS write block command on the SMBUS device specified by SmBusAddress.\r
388   The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.\r
389   Bytes are written to the SMBUS from Buffer.\r
390   The number of bytes written is returned, and will never return a value larger than 32-bytes.\r
391   If Status is not NULL, then the status of the executed command is returned in Status.  \r
392   If Length in SmBusAddress is zero or greater than 32, then ASSERT().\r
393   If Buffer is NULL, then ASSERT().\r
394   If any reserved bits of SmBusAddress are set, then ASSERT().\r
395 \r
396   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
397                           SMBUS Command, SMBUS Data Length, and PEC.\r
398   @param  Buffer          Pointer to the buffer to store the bytes read from the SMBUS.\r
399   @param  Status          Return status for the executed command.\r
400                           This is an optional parameter and may be NULL.\r
401 \r
402   @return The number of bytes written.\r
403 \r
404 **/\r
405 UINTN\r
406 EFIAPI\r
407 SmBusWriteBlock (\r
408   IN  UINTN          SmBusAddress,\r
409   OUT VOID           *Buffer,\r
410   OUT RETURN_STATUS  *Status        OPTIONAL\r
411   )\r
412 {\r
413   UINTN  Length;\r
414 \r
415   ASSERT (Buffer != NULL);\r
416   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);\r
417   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);\r
418   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
419 \r
420   Length = SMBUS_LIB_LENGTH (SmBusAddress);\r
421   return InternalSmBusExec (EfiSmbusWriteBlock, SmBusAddress, Length, Buffer, Status);\r
422 }\r
423 \r
424 /**\r
425   Executes an SMBUS block process call command.\r
426 \r
427   Executes an SMBUS block process call command on the SMBUS device specified by SmBusAddress.\r
428   The SMBUS slave address, SMBUS command, and SMBUS length fields of SmBusAddress are required.\r
429   Bytes are written to the SMBUS from WriteBuffer.  Bytes are then read from the SMBUS into ReadBuffer.\r
430   If Status is not NULL, then the status of the executed command is returned in Status.\r
431   It is the caller's responsibility to make sure ReadBuffer is large enough for the total number of bytes read.\r
432   SMBUS supports a maximum transfer size of 32 bytes, so Buffer does not need to be any larger than 32 bytes.\r
433   If Length in SmBusAddress is zero or greater than 32, then ASSERT().\r
434   If WriteBuffer is NULL, then ASSERT().\r
435   If ReadBuffer is NULL, then ASSERT().\r
436   If any reserved bits of SmBusAddress are set, then ASSERT().\r
437 \r
438   @param  SmBusAddress    Address that encodes the SMBUS Slave Address,\r
439                           SMBUS Command, SMBUS Data Length, and PEC.\r
440   @param  WriteBuffer     Pointer to the buffer of bytes to write to the SMBUS.\r
441   @param  ReadBuffer      Pointer to the buffer of bytes to read from the SMBUS.\r
442   @param  Status          Return status for the executed command.\r
443                           This is an optional parameter and may be NULL.\r
444 \r
445   @return The number of bytes written.\r
446 \r
447 **/\r
448 UINTN\r
449 EFIAPI\r
450 SmBusBlockProcessCall (\r
451   IN  UINTN          SmBusAddress,\r
452   IN  VOID           *WriteBuffer,\r
453   OUT VOID           *ReadBuffer,\r
454   OUT RETURN_STATUS  *Status        OPTIONAL\r
455   )\r
456 {\r
457   UINTN   Length;\r
458 \r
459   ASSERT (WriteBuffer != NULL);\r
460   ASSERT (ReadBuffer  != NULL);\r
461   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);\r
462   ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) <= 32);\r
463   ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);\r
464 \r
465   Length = SMBUS_LIB_LENGTH (SmBusAddress);\r
466   //\r
467   // Assuming that ReadBuffer is large enough to save another memory copy.\r
468   //\r
469   ReadBuffer = CopyMem (ReadBuffer, WriteBuffer, Length);\r
470   return InternalSmBusExec (EfiSmbusBWBRProcessCall, SmBusAddress, Length, ReadBuffer, Status);\r
471 }\r