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