]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c
QuarkSocPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkSocPkg / QuarkSouthCluster / Library / I2cLib / I2cLib.c
1 /** @file
2 I2C Library for Quark I2C Controller.
3 Follows I2C Controller setup instructions as detailed in
4 Quark DataSheet (doc id: 329676) Section 19.1/19.1.3.
5
6
7 Copyright (c) 2013-2015 Intel Corporation.
8
9 SPDX-License-Identifier: BSD-2-Clause-Patent
10
11 **/
12
13 #include "CommonHeader.h"
14
15 /**
16 The Called to Common Service Entry.
17
18 @return None.
19
20 **/
21
22 VOID
23 I2cCommonServiceEntry (
24 OUT UINT16 *SaveCmdPtr,
25 OUT UINT32 *SaveBar0Ptr
26 )
27 {
28 *SaveBar0Ptr = IohMmPci32 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0);
29 if (((*SaveBar0Ptr) & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0) {
30
31 IohMmPci32(0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0) =
32 FixedPcdGet32 (PcdIohI2cMmioBase) & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK;
33
34 //
35 // also Save Cmd Register, Setup by InitializeInternal later during xfers.
36 //
37 *SaveCmdPtr = IohMmPci16 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_CMD);
38 }
39 }
40
41 /**
42 The Called on Common Service Exit.
43
44 @return None.
45
46 **/
47 VOID
48 I2cCommonServiceExit (
49 IN CONST UINT16 SaveCmd,
50 IN CONST UINT32 SaveBar0
51
52 )
53 {
54 if ((SaveBar0 & B_IOH_I2C_GPIO_MEMBAR_ADDR_MASK) == 0) {
55 IohMmPci16 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_CMD) = SaveCmd;
56 IohMmPci32 (0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0) = SaveBar0;
57 }
58 }
59
60
61 /**
62 The GetI2CIoPortBaseAddress() function gets IO port base address of I2C Controller.
63
64 Always reads PCI configuration space to get MMIO base address of I2C Controller.
65
66 @return The IO port base address of I2C controller.
67
68 **/
69 UINTN
70 GetI2CIoPortBaseAddress (
71 VOID
72 )
73 {
74 UINTN I2CIoPortBaseAddress;
75
76 //
77 // Get I2C Memory Mapped registers base address.
78 //
79 I2CIoPortBaseAddress = IohMmPci32(0, I2C_Bus, I2C_Device, I2C_Func, PCI_BAR0);
80
81 //
82 // Make sure that the IO port base address has been properly set.
83 //
84 ASSERT (I2CIoPortBaseAddress != 0);
85 ASSERT (I2CIoPortBaseAddress != 0xFF);
86
87 return I2CIoPortBaseAddress;
88 }
89
90
91 /**
92 The EnableI2CMmioSpace() function enables access to I2C MMIO space.
93
94 **/
95 VOID
96 EnableI2CMmioSpace (
97 VOID
98 )
99 {
100 UINT8 PciCmd;
101
102 //
103 // Read PCICMD. Bus=0, Dev=0, Func=0, Reg=0x4
104 //
105 PciCmd = IohMmPci8(0, I2C_Bus, I2C_Device, I2C_Func, PCI_REG_PCICMD);
106
107 //
108 // Enable Bus Master(Bit2), MMIO Space(Bit1) & I/O Space(Bit0)
109 //
110 PciCmd |= 0x7;
111 IohMmPci8(0, I2C_Bus, I2C_Device, I2C_Func, PCI_REG_PCICMD) = PciCmd;
112
113 }
114
115 /**
116 The DisableI2CController() functions disables I2C Controller.
117
118 **/
119 VOID
120 DisableI2CController (
121 VOID
122 )
123 {
124 UINTN I2CIoPortBaseAddress;
125 UINT32 Addr;
126 UINT32 Data;
127 UINT8 PollCount;
128
129 PollCount = 0;
130
131 //
132 // Get I2C Memory Mapped registers base address.
133 //
134 I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
135
136 //
137 // Disable the I2C Controller by setting IC_ENABLE.ENABLE to zero
138 //
139 Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE;
140 Data = *((volatile UINT32 *) (UINTN)(Addr));
141 Data &= ~B_I2C_REG_ENABLE;
142 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
143
144 //
145 // Read the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled
146 //
147 Data = 0xFF;
148 Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE_STATUS;
149 Data = *((volatile UINT32 *) (UINTN)(Addr)) & I2C_REG_ENABLE_STATUS;
150 while (Data != 0) {
151 //
152 // Poll the IC_ENABLE_STATUS.IC_EN Bit to check if Controller is disabled, until timeout (TI2C_POLL*MAX_T_POLL_COUNT).
153 //
154 PollCount++;
155 if (PollCount >= MAX_T_POLL_COUNT) {
156 break;
157 }
158 MicroSecondDelay(TI2C_POLL);
159 Data = *((volatile UINT32 *) (UINTN)(Addr));
160 Data &= I2C_REG_ENABLE_STATUS;
161 }
162
163 //
164 // Asset if controller does not enter Disabled state.
165 //
166 ASSERT (PollCount < MAX_T_POLL_COUNT);
167
168 //
169 // Read IC_CLR_INTR register to automatically clear the combined interrupt,
170 // all individual interrupts and the IC_TX_ABRT_SOURCE register.
171 //
172 Addr = I2CIoPortBaseAddress + I2C_REG_CLR_INT;
173 Data = *((volatile UINT32 *) (UINTN)(Addr));
174
175 }
176
177 /**
178 The EnableI2CController() function enables the I2C Controller.
179
180 **/
181 VOID
182 EnableI2CController (
183 VOID
184 )
185 {
186 UINTN I2CIoPortBaseAddress;
187 UINT32 Addr;
188 UINT32 Data;
189
190 //
191 // Get I2C Memory Mapped registers base address.
192 //
193 I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
194
195 //
196 // Enable the I2C Controller by setting IC_ENABLE.ENABLE to 1
197 //
198 Addr = I2CIoPortBaseAddress + I2C_REG_ENABLE;
199 Data = *((volatile UINT32 *) (UINTN)(Addr));
200 Data |= B_I2C_REG_ENABLE;
201 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
202
203 //
204 // Clear overflow and abort error status bits before transactions.
205 //
206 Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_OVER;
207 Data = *((volatile UINT32 *) (UINTN)(Addr));
208 Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_OVER;
209 Data = *((volatile UINT32 *) (UINTN)(Addr));
210 Addr = I2CIoPortBaseAddress + I2C_REG_CLR_TX_ABRT;
211 Data = *((volatile UINT32 *) (UINTN)(Addr));
212
213 }
214
215 /**
216 The WaitForStopDet() function waits until I2C STOP Condition occurs,
217 indicating transfer completion.
218
219 @retval EFI_SUCCESS Stop detected.
220 @retval EFI_TIMEOUT Timeout while waiting for stop condition.
221 @retval EFI_ABORTED Tx abort signaled in HW status register.
222 @retval EFI_DEVICE_ERROR Tx or Rx overflow detected.
223
224 **/
225 EFI_STATUS
226 WaitForStopDet (
227 VOID
228 )
229 {
230 UINTN I2CIoPortBaseAddress;
231 UINT32 Addr;
232 UINT32 Data;
233 UINT32 PollCount;
234 EFI_STATUS Status;
235
236 Status = EFI_SUCCESS;
237
238 PollCount = 0;
239
240 //
241 // Get I2C Memory Mapped registers base address.
242 //
243 I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
244
245 //
246 // Wait for STOP Detect.
247 //
248 Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
249
250 do {
251 Data = *((volatile UINT32 *) (UINTN)(Addr));
252 if ((Data & I2C_REG_RAW_INTR_STAT_TX_ABRT) != 0) {
253 Status = EFI_ABORTED;
254 break;
255 }
256 if ((Data & I2C_REG_RAW_INTR_STAT_TX_OVER) != 0) {
257 Status = EFI_DEVICE_ERROR;
258 break;
259 }
260 if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0) {
261 Status = EFI_DEVICE_ERROR;
262 break;
263 }
264 if ((Data & I2C_REG_RAW_INTR_STAT_STOP_DET) != 0) {
265 Status = EFI_SUCCESS;
266 break;
267 }
268 MicroSecondDelay(TI2C_POLL);
269 PollCount++;
270 if (PollCount >= MAX_STOP_DET_POLL_COUNT) {
271 Status = EFI_TIMEOUT;
272 break;
273 }
274
275 } while (TRUE);
276
277 return Status;
278 }
279
280 /**
281
282 The InitializeInternal() function initialises internal I2C Controller
283 register values that are commonly required for I2C Write and Read transfers.
284
285 @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
286
287 @retval EFI_SUCCESS I2C Operation completed successfully.
288
289 **/
290 EFI_STATUS
291 InitializeInternal (
292 IN EFI_I2C_ADDR_MODE AddrMode
293 )
294 {
295 UINTN I2CIoPortBaseAddress;
296 UINTN Addr;
297 UINT32 Data;
298 EFI_STATUS Status;
299
300 Status = EFI_SUCCESS;
301
302 //
303 // Enable access to I2C Controller MMIO space.
304 //
305 EnableI2CMmioSpace ();
306
307 //
308 // Disable I2C Controller initially
309 //
310 DisableI2CController ();
311
312 //
313 // Get I2C Memory Mapped registers base address.
314 //
315 I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
316
317 //
318 // Clear START_DET
319 //
320 Addr = I2CIoPortBaseAddress + I2C_REG_CLR_START_DET;
321 Data = *((volatile UINT32 *) (UINTN)(Addr));
322 Data &= ~B_I2C_REG_CLR_START_DET;
323 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
324
325 //
326 // Clear STOP_DET
327 //
328 Addr = I2CIoPortBaseAddress + I2C_REG_CLR_STOP_DET;
329 Data = *((volatile UINT32 *) (UINTN)(Addr));
330 Data &= ~B_I2C_REG_CLR_STOP_DET;
331 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
332
333 //
334 // Set addressing mode to user defined (7 or 10 bit) and
335 // speed mode to that defined by PCD (standard mode default).
336 //
337 Addr = I2CIoPortBaseAddress + I2C_REG_CON;
338 Data = *((volatile UINT32 *) (UINTN)(Addr));
339 // Set Addressing Mode
340 if (AddrMode == EfiI2CSevenBitAddrMode) {
341 Data &= ~B_I2C_REG_CON_10BITADD_MASTER;
342 } else {
343 Data |= B_I2C_REG_CON_10BITADD_MASTER;
344 }
345 // Set Speed Mode
346 Data &= ~B_I2C_REG_CON_SPEED;
347 if (FeaturePcdGet (PcdI2CFastModeEnabled)) {
348 Data |= BIT2;
349 } else {
350 Data |= BIT1;
351 }
352 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
353
354 Data = *((volatile UINT32 *) (UINTN)(Addr));
355
356 return Status;
357
358 }
359
360 /**
361
362 The WriteByte() function provides a standard way to execute a
363 standard single byte write to an IC2 device (without accessing
364 sub-addresses), as defined in the I2C Specification.
365
366 @param I2CAddress I2C Slave device address
367 @param Value The 8-bit value to write.
368
369 @retval EFI_SUCCESS Transfer success.
370 @retval EFI_UNSUPPORTED Unsupported input param.
371 @retval EFI_TIMEOUT Timeout while waiting xfer.
372 @retval EFI_ABORTED Controller aborted xfer.
373 @retval EFI_DEVICE_ERROR Device error detected by controller.
374
375 **/
376 EFI_STATUS
377 EFIAPI
378 WriteByte (
379 IN UINTN I2CAddress,
380 IN UINT8 Value
381 )
382 {
383 UINTN I2CIoPortBaseAddress;
384 UINTN Addr;
385 UINT32 Data;
386 EFI_STATUS Status;
387
388 //
389 // Get I2C Memory Mapped registers base address
390 //
391 I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
392
393 //
394 // Write to the IC_TAR register the address of the slave device to be addressed
395 //
396 Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
397 Data = *((volatile UINT32 *) (UINTN)(Addr));
398 Data &= ~B_I2C_REG_TAR;
399 Data |= I2CAddress;
400 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
401
402 //
403 // Enable the I2C Controller
404 //
405 EnableI2CController ();
406
407 //
408 // Write the data and transfer direction to the IC_DATA_CMD register.
409 // Also specify that transfer should be terminated by STOP condition.
410 //
411 Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
412 Data = *((volatile UINT32 *) (UINTN)(Addr));
413 Data &= 0xFFFFFF00;
414 Data |= (UINT8)Value;
415 Data &= ~B_I2C_REG_DATA_CMD_RW;
416 Data |= B_I2C_REG_DATA_CMD_STOP;
417 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
418
419 //
420 // Wait for transfer completion.
421 //
422 Status = WaitForStopDet ();
423
424 //
425 // Ensure I2C Controller disabled.
426 //
427 DisableI2CController();
428
429 return Status;
430 }
431
432 /**
433
434 The ReadByte() function provides a standard way to execute a
435 standard single byte read to an IC2 device (without accessing
436 sub-addresses), as defined in the I2C Specification.
437
438 @param I2CAddress I2C Slave device address
439 @param ReturnDataPtr Pointer to location to receive read byte.
440
441 @retval EFI_SUCCESS Transfer success.
442 @retval EFI_UNSUPPORTED Unsupported input param.
443 @retval EFI_TIMEOUT Timeout while waiting xfer.
444 @retval EFI_ABORTED Controller aborted xfer.
445 @retval EFI_DEVICE_ERROR Device error detected by controller.
446
447 **/
448 EFI_STATUS
449 EFIAPI
450 ReadByte (
451 IN UINTN I2CAddress,
452 OUT UINT8 *ReturnDataPtr
453 )
454 {
455 UINTN I2CIoPortBaseAddress;
456 UINTN Addr;
457 UINT32 Data;
458 EFI_STATUS Status;
459
460 //
461 // Get I2C Memory Mapped registers base address.
462 //
463 I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
464
465 //
466 // Write to the IC_TAR register the address of the slave device to be addressed
467 //
468 Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
469 Data = *((volatile UINT32 *) (UINTN)(Addr));
470 Data &= ~B_I2C_REG_TAR;
471 Data |= I2CAddress;
472 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
473
474 //
475 // Enable the I2C Controller
476 //
477 EnableI2CController ();
478
479 //
480 // Write transfer direction to the IC_DATA_CMD register and
481 // specify that transfer should be terminated by STOP condition.
482 //
483 Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
484 Data = *((volatile UINT32 *) (UINTN)(Addr));
485 Data &= 0xFFFFFF00;
486 Data |= B_I2C_REG_DATA_CMD_RW;
487 Data |= B_I2C_REG_DATA_CMD_STOP;
488 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
489
490 //
491 // Wait for transfer completion
492 //
493 Status = WaitForStopDet ();
494 if (!EFI_ERROR(Status)) {
495
496 //
497 // Clear RX underflow before reading IC_DATA_CMD.
498 //
499 Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_UNDER;
500 Data = *((volatile UINT32 *) (UINTN)(Addr));
501
502 //
503 // Obtain and return read data byte from RX buffer (IC_DATA_CMD[7:0]).
504 //
505 Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
506 Data = *((volatile UINT32 *) (UINTN)(Addr));
507 Data &= 0x000000FF;
508 *ReturnDataPtr = (UINT8) Data;
509
510 Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
511 Data = *((volatile UINT32 *) (UINTN)(Addr));
512 Data &= I2C_REG_RAW_INTR_STAT_RX_UNDER;
513 if (Data != 0) {
514 Status = EFI_DEVICE_ERROR;
515 }
516 }
517
518 //
519 // Ensure I2C Controller disabled.
520 //
521 DisableI2CController ();
522
523 return Status;
524 }
525
526 /**
527
528 The WriteMultipleByte() function provides a standard way to execute
529 multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
530 when writing block of data), as defined in the I2C Specification.
531
532 @param I2CAddress The I2C slave address of the device
533 with which to communicate.
534
535 @param WriteBuffer Contains the value of byte to be written to the
536 I2C slave device.
537
538 @param Length No. of bytes to be written.
539
540 @retval EFI_SUCCESS Transfer success.
541 @retval EFI_UNSUPPORTED Unsupported input param.
542 @retval EFI_TIMEOUT Timeout while waiting xfer.
543 @retval EFI_ABORTED Tx abort signaled in HW status register.
544 @retval EFI_DEVICE_ERROR Tx overflow detected.
545
546 **/
547 EFI_STATUS
548 EFIAPI
549 WriteMultipleByte (
550 IN UINTN I2CAddress,
551 IN UINT8 *WriteBuffer,
552 IN UINTN Length
553 )
554 {
555 UINTN I2CIoPortBaseAddress;
556 UINTN Index;
557 UINTN Addr;
558 UINT32 Data;
559 EFI_STATUS Status;
560
561 if (Length > I2C_FIFO_SIZE) {
562 return EFI_UNSUPPORTED; // Routine does not handle xfers > fifo size.
563 }
564
565 I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
566
567 //
568 // Write to the IC_TAR register the address of the slave device to be addressed
569 //
570 Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
571 Data = *((volatile UINT32 *) (UINTN)(Addr));
572 Data &= ~B_I2C_REG_TAR;
573 Data |= I2CAddress;
574 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
575
576 //
577 // Enable the I2C Controller
578 //
579 EnableI2CController ();
580
581 //
582 // Write the data and transfer direction to the IC_DATA_CMD register.
583 // Also specify that transfer should be terminated by STOP condition.
584 //
585 Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
586 for (Index = 0; Index < Length; Index++) {
587 Data = *((volatile UINT32 *) (UINTN)(Addr));
588 Data &= 0xFFFFFF00;
589 Data |= (UINT8)WriteBuffer[Index];
590 Data &= ~B_I2C_REG_DATA_CMD_RW;
591 if (Index == (Length-1)) {
592 Data |= B_I2C_REG_DATA_CMD_STOP;
593 }
594 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
595 }
596
597 //
598 // Wait for transfer completion
599 //
600 Status = WaitForStopDet ();
601
602 //
603 // Ensure I2C Controller disabled.
604 //
605 DisableI2CController ();
606 return Status;
607 }
608
609 /**
610
611 The ReadMultipleByte() function provides a standard way to execute
612 multiple byte writes to an IC2 device (e.g. when accessing sub-addresses or
613 when reading block of data), as defined in the I2C Specification (I2C combined
614 write/read protocol).
615
616 @param I2CAddress The I2C slave address of the device
617 with which to communicate.
618
619 @param Buffer Contains the value of byte data written or read from the
620 I2C slave device.
621
622 @param WriteLength No. of bytes to be written. In this case data
623 written typically contains sub-address or sub-addresses
624 in Hi-Lo format, that need to be read (I2C combined
625 write/read protocol).
626
627 @param ReadLength No. of bytes to be read from I2C slave device.
628
629 @retval EFI_SUCCESS Transfer success.
630 @retval EFI_UNSUPPORTED Unsupported input param.
631 @retval EFI_TIMEOUT Timeout while waiting xfer.
632 @retval EFI_ABORTED Tx abort signaled in HW status register.
633 @retval EFI_DEVICE_ERROR Rx underflow or Rx/Tx overflow detected.
634
635 **/
636 EFI_STATUS
637 EFIAPI
638 ReadMultipleByte (
639 IN UINTN I2CAddress,
640 IN OUT UINT8 *Buffer,
641 IN UINTN WriteLength,
642 IN UINTN ReadLength
643 )
644 {
645 UINTN I2CIoPortBaseAddress;
646 UINTN Index;
647 UINTN Addr;
648 UINT32 Data;
649 UINT8 PollCount;
650 EFI_STATUS Status;
651
652 if (WriteLength > I2C_FIFO_SIZE || ReadLength > I2C_FIFO_SIZE) {
653 return EFI_UNSUPPORTED; // Routine does not handle xfers > fifo size.
654 }
655
656 I2CIoPortBaseAddress = GetI2CIoPortBaseAddress ();
657
658 //
659 // Write to the IC_TAR register the address of the slave device to be addressed
660 //
661 Addr = I2CIoPortBaseAddress + I2C_REG_TAR;
662 Data = *((volatile UINT32 *) (UINTN)(Addr));
663 Data &= ~B_I2C_REG_TAR;
664 Data |= I2CAddress;
665 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
666
667 //
668 // Enable the I2C Controller
669 //
670 EnableI2CController ();
671
672 //
673 // Write the data (sub-addresses) to the IC_DATA_CMD register.
674 //
675 Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
676 for (Index = 0; Index < WriteLength; Index++) {
677 Data = *((volatile UINT32 *) (UINTN)(Addr));
678 Data &= 0xFFFFFF00;
679 Data |= (UINT8)Buffer[Index];
680 Data &= ~B_I2C_REG_DATA_CMD_RW;
681 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
682 }
683
684 //
685 // Issue Read Transfers for each byte (Restart issued when write/read bit changed).
686 //
687 for (Index = 0; Index < ReadLength; Index++) {
688 Data = *((volatile UINT32 *) (UINTN)(Addr));
689 Data |= B_I2C_REG_DATA_CMD_RW;
690 // Issue a STOP for last read transfer.
691 if (Index == (ReadLength-1)) {
692 Data |= B_I2C_REG_DATA_CMD_STOP;
693 }
694 *((volatile UINT32 *) (UINTN)(Addr)) = Data;
695 }
696
697 //
698 // Wait for STOP condition.
699 //
700 Status = WaitForStopDet ();
701 if (!EFI_ERROR(Status)) {
702
703 //
704 // Poll Receive FIFO Buffer Level register until valid (upto MAX_T_POLL_COUNT times).
705 //
706 Data = 0;
707 PollCount = 0;
708 Addr = I2CIoPortBaseAddress + I2C_REG_RXFLR;
709 Data = *((volatile UINT32 *) (UINTN)(Addr));
710 while ((Data != ReadLength) && (PollCount < MAX_T_POLL_COUNT)) {
711 MicroSecondDelay(TI2C_POLL);
712 PollCount++;
713 Data = *((volatile UINT32 *) (UINTN)(Addr));
714 }
715
716 Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
717 Data = *((volatile UINT32 *) (UINTN)(Addr));
718
719 //
720 // If no timeout or device error then read rx data.
721 //
722 if (PollCount == MAX_T_POLL_COUNT) {
723 Status = EFI_TIMEOUT;
724 } else if ((Data & I2C_REG_RAW_INTR_STAT_RX_OVER) != 0) {
725 Status = EFI_DEVICE_ERROR;
726 } else {
727
728 //
729 // Clear RX underflow before reading IC_DATA_CMD.
730 //
731 Addr = I2CIoPortBaseAddress + I2C_REG_CLR_RX_UNDER;
732 Data = *((volatile UINT32 *) (UINTN)(Addr));
733
734 //
735 // Read data.
736 //
737 Addr = I2CIoPortBaseAddress + I2C_REG_DATA_CMD;
738 for (Index = 0; Index < ReadLength; Index++) {
739 Data = *((volatile UINT32 *) (UINTN)(Addr));
740 Data &= 0x000000FF;
741 *(Buffer+Index) = (UINT8)Data;
742 }
743 Addr = I2CIoPortBaseAddress + I2C_REG_RAW_INTR_STAT;
744 Data = *((volatile UINT32 *) (UINTN)(Addr));
745 Data &= I2C_REG_RAW_INTR_STAT_RX_UNDER;
746 if (Data != 0) {
747 Status = EFI_DEVICE_ERROR;
748 } else {
749 Status = EFI_SUCCESS;
750 }
751 }
752 }
753
754 //
755 // Ensure I2C Controller disabled.
756 //
757 DisableI2CController ();
758
759 return Status;
760 }
761
762 /**
763
764 The I2cWriteByte() function is a wrapper function for the WriteByte function.
765 Provides a standard way to execute a standard single byte write to an IC2 device
766 (without accessing sub-addresses), as defined in the I2C Specification.
767
768 @param SlaveAddress The I2C slave address of the device
769 with which to communicate.
770
771 @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
772
773 @param Buffer Contains the value of byte data to execute to the
774 I2C slave device.
775
776
777 @retval EFI_SUCCESS Transfer success.
778 @retval EFI_INVALID_PARAMETER This or Buffer pointers are invalid.
779 @retval EFI_UNSUPPORTED Unsupported input param.
780 @retval EFI_TIMEOUT Timeout while waiting xfer.
781 @retval EFI_ABORTED Controller aborted xfer.
782 @retval EFI_DEVICE_ERROR Device error detected by controller.
783
784 **/
785 EFI_STATUS
786 EFIAPI
787 I2cWriteByte (
788 IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,
789 IN EFI_I2C_ADDR_MODE AddrMode,
790 IN OUT VOID *Buffer
791 )
792 {
793 EFI_STATUS Status;
794 UINTN I2CAddress;
795 UINT16 SaveCmd;
796 UINT32 SaveBar0;
797
798 if (Buffer == NULL) {
799 return EFI_INVALID_PARAMETER;
800 }
801 SaveCmd = 0;
802 SaveBar0 = 0;
803
804 I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
805
806 Status = EFI_SUCCESS;
807
808 I2CAddress = SlaveAddress.I2CDeviceAddress;
809 Status = InitializeInternal (AddrMode);
810 if (!EFI_ERROR(Status)) {
811 Status = WriteByte (I2CAddress, *(UINT8 *) Buffer);
812 }
813
814 I2cCommonServiceExit (SaveCmd, SaveBar0);
815 return Status;
816 }
817
818 /**
819
820 The I2cReadByte() function is a wrapper function for the ReadByte function.
821 Provides a standard way to execute a standard single byte read to an I2C device
822 (without accessing sub-addresses), as defined in the I2C Specification.
823
824 @param SlaveAddress The I2C slave address of the device
825 with which to communicate.
826
827 @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
828
829 @param Buffer Contains the value of byte data read from the
830 I2C slave device.
831
832
833 @retval EFI_SUCCESS Transfer success.
834 @retval EFI_INVALID_PARAMETER This or Buffer pointers are invalid.
835 @retval EFI_TIMEOUT Timeout while waiting xfer.
836 @retval EFI_ABORTED Controller aborted xfer.
837 @retval EFI_DEVICE_ERROR Device error detected by controller.
838
839
840 **/
841 EFI_STATUS
842 EFIAPI
843 I2cReadByte (
844 IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,
845 IN EFI_I2C_ADDR_MODE AddrMode,
846 IN OUT VOID *Buffer
847 )
848 {
849 EFI_STATUS Status;
850 UINTN I2CAddress;
851 UINT16 SaveCmd;
852 UINT32 SaveBar0;
853
854 if (Buffer == NULL) {
855 return EFI_INVALID_PARAMETER;
856 }
857 SaveCmd = 0;
858 SaveBar0 =0;
859
860 I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
861
862 Status = EFI_SUCCESS;
863
864 I2CAddress = SlaveAddress.I2CDeviceAddress;
865
866 Status = InitializeInternal (AddrMode);
867 if (!EFI_ERROR(Status)) {
868 Status = ReadByte (I2CAddress, (UINT8 *) Buffer);
869 }
870 I2cCommonServiceExit (SaveCmd, SaveBar0);
871 return Status;
872 }
873
874 /**
875
876 The I2cWriteMultipleByte() function is a wrapper function for the
877 WriteMultipleByte() function. Provides a standard way to execute multiple
878 byte writes to an I2C device (e.g. when accessing sub-addresses or writing
879 block of data), as defined in the I2C Specification.
880
881 @param SlaveAddress The I2C slave address of the device
882 with which to communicate.
883
884 @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
885
886 @param Length No. of bytes to be written.
887
888 @param Buffer Contains the value of byte to be written to the
889 I2C slave device.
890
891 @retval EFI_SUCCESS Transfer success.
892 @retval EFI_INVALID_PARAMETER This, Length or Buffer pointers are invalid.
893 @retval EFI_UNSUPPORTED Unsupported input param.
894 @retval EFI_TIMEOUT Timeout while waiting xfer.
895 @retval EFI_ABORTED Controller aborted xfer.
896 @retval EFI_DEVICE_ERROR Device error detected by controller.
897
898 **/
899 EFI_STATUS
900 EFIAPI
901 I2cWriteMultipleByte (
902 IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,
903 IN EFI_I2C_ADDR_MODE AddrMode,
904 IN UINTN *Length,
905 IN OUT VOID *Buffer
906 )
907 {
908 EFI_STATUS Status;
909 UINTN I2CAddress;
910 UINT16 SaveCmd;
911 UINT32 SaveBar0;
912
913 if (Buffer == NULL || Length == NULL) {
914 return EFI_INVALID_PARAMETER;
915 }
916 SaveCmd = 0;
917 SaveBar0 =0;
918
919 I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
920 Status = EFI_SUCCESS;
921
922 I2CAddress = SlaveAddress.I2CDeviceAddress;
923
924 Status = InitializeInternal (AddrMode);
925 if (!EFI_ERROR(Status)) {
926 Status = WriteMultipleByte (I2CAddress, Buffer, (*Length));
927 }
928
929 I2cCommonServiceExit (SaveCmd, SaveBar0);
930 return Status;
931 }
932
933 /**
934
935 The I2cReadMultipleByte() function is a wrapper function for the ReadMultipleByte() function.
936 Provides a standard way to execute multiple byte writes to an I2C device
937 (e.g. when accessing sub-addresses or when reading block of data), as defined
938 in the I2C Specification (I2C combined write/read protocol).
939
940 @param SlaveAddress The I2C slave address of the device
941 with which to communicate.
942
943 @param AddrMode I2C Addressing Mode: 7-bit or 10-bit address.
944
945 @param WriteLength No. of bytes to be written. In this case data
946 written typically contains sub-address or sub-addresses
947 in Hi-Lo format, that need to be read (I2C combined
948 write/read protocol).
949
950 @param ReadLength No. of bytes to be read from I2C slave device.
951
952 @param Buffer Contains the value of byte data read from the
953 I2C slave device.
954
955 @retval EFI_SUCCESS Transfer success.
956 @retval EFI_INVALID_PARAMETER This, WriteLength, ReadLength or Buffer
957 pointers are invalid.
958 @retval EFI_UNSUPPORTED Unsupported input param.
959 @retval EFI_TIMEOUT Timeout while waiting xfer.
960 @retval EFI_ABORTED Controller aborted xfer.
961 @retval EFI_DEVICE_ERROR Device error detected by controller.
962
963 **/
964 EFI_STATUS
965 EFIAPI
966 I2cReadMultipleByte (
967 IN EFI_I2C_DEVICE_ADDRESS SlaveAddress,
968 IN EFI_I2C_ADDR_MODE AddrMode,
969 IN UINTN *WriteLength,
970 IN UINTN *ReadLength,
971 IN OUT VOID *Buffer
972 )
973 {
974 EFI_STATUS Status;
975 UINTN I2CAddress;
976 UINT16 SaveCmd;
977 UINT32 SaveBar0;
978
979 if (Buffer == NULL || WriteLength == NULL || ReadLength == NULL) {
980 return EFI_INVALID_PARAMETER;
981 }
982 SaveCmd = 0;
983 SaveBar0 =0;
984
985 I2cCommonServiceEntry (&SaveCmd, &SaveBar0);
986
987 Status = EFI_SUCCESS;
988
989 I2CAddress = SlaveAddress.I2CDeviceAddress;
990 Status = InitializeInternal (AddrMode);
991 if (!EFI_ERROR(Status)) {
992 Status = ReadMultipleByte (I2CAddress, Buffer, (*WriteLength), (*ReadLength));
993 }
994 I2cCommonServiceExit (SaveCmd, SaveBar0);
995 return Status;
996 }
997
998