/******************************************************************************** Copyright (C) 2016 Marvell International Ltd. Copyright (c) 2021-2022, Rockchip Limited. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent *******************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include CONST CHAR16 ShellI2cDemoFileName[] = L"I2cDemoTestShellCommand"; EFI_HANDLE ShellI2cDemoHiiHandle = NULL; STATIC CONST SHELL_PARAM_ITEM ParamList[] = { {L"read", TypeFlag}, {L"write", TypeFlag}, {L"list", TypeFlag}, {L"help", TypeFlag}, {NULL , TypeMax} }; /** Return the file name of the help text file if not using HII. @return The string pointer to the file name. **/ STATIC CONST CHAR16* EFIAPI ShellCommandGetManFileNameI2cDemo ( VOID ) { return ShellI2cDemoFileName; } STATIC VOID Usage ( VOID ) { Print (L"I2C DEMO TEST commands:\n" "i2cdemo [read] [write] [list] [][
] [] [] [] [] \n" "All modes except 'list' require Address, Length and Chip set.\n\n" "read - read from i2cdemo device\n" "write - write Data to i2cdemo device\\n" "list - list available i2cdemo devices\n\n" "Bus - I2C bus address\n" "Address - i2cdemo bus address\n" "Length - data byte length to read/write\\n" "RegAddress - address in i2cdemo to read/write\n" "RegAddressLength - address in i2cdemo length\n" "Data - data byte to be written\n" "Examples:\n" "List devices:\n" " i2cdemo list\n" "Read 2 bytes from address 0x10 in chip 0x51@bus2:\n" " i2cdemo read 2 0x51 2 0x10 1\n" "Fill 16 bytes with 0xab at address 0x0 in chip 0x57:\n" " i2cdemo write 2 0x51 1 0x10 1 0x00\n" ); } STATIC EFI_STATUS I2cDemoList ( ) { EFI_HANDLE *HandleBuffer; EFI_STATUS Status; UINTN ProtocolCount; ROCKCHIP_I2CDEMO_PROTOCOL *I2cDemoProtocol; UINTN i; Status = gBS->LocateHandleBuffer ( ByProtocol, &gRockchipI2cDemoProtocolGuid, NULL, &ProtocolCount, &HandleBuffer ); if (ProtocolCount == 0) { Print (L"0 devices found.\n"); } else { Print (L"%u devices found: ", ProtocolCount); } for (i = 0; i < ProtocolCount; i++) { Status = gBS->OpenProtocol ( HandleBuffer[i], &gRockchipI2cDemoProtocolGuid, (VOID **) &I2cDemoProtocol, gImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL ); Print (L"0x%x at bus %d\n", I2C_DEVICE_ADDRESS(I2cDemoProtocol->Identifier), I2C_DEVICE_BUS(I2cDemoProtocol->Identifier)); Status = gBS->CloseProtocol ( HandleBuffer[i], &gRockchipI2cDemoProtocolGuid, gImageHandle, NULL ); } Print (L"\n"); return Status; } STATIC EFI_STATUS I2cDemoLocateProtocol ( IN UINT32 Identifier, OUT EFI_HANDLE *FoundHandle, OUT ROCKCHIP_I2CDEMO_PROTOCOL **FoundI2cDemoProtocol ) { EFI_HANDLE *HandleBuffer; EFI_STATUS Status; UINTN ProtocolCount; ROCKCHIP_I2CDEMO_PROTOCOL *I2cDemoProtocol; UINTN i; Status = gBS->LocateHandleBuffer ( ByProtocol, &gRockchipI2cDemoProtocolGuid, NULL, &ProtocolCount, &HandleBuffer ); if (EFI_ERROR(Status)) { return Status; } for (i = 0; i < ProtocolCount; i++) { Status = gBS->OpenProtocol ( HandleBuffer[i], &gRockchipI2cDemoProtocolGuid, (VOID **) &I2cDemoProtocol, gImageHandle, NULL, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL ); if (I2cDemoProtocol->Identifier == Identifier) { *FoundI2cDemoProtocol = I2cDemoProtocol; *FoundHandle = HandleBuffer[i]; return EFI_SUCCESS; } Status = gBS->CloseProtocol ( HandleBuffer[i], &gRockchipI2cDemoProtocolGuid, gImageHandle, NULL ); } *FoundI2cDemoProtocol = NULL; return EFI_UNSUPPORTED; } SHELL_STATUS EFIAPI ShellCommandRunI2cDemo ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; LIST_ENTRY *CheckPackage; CHAR16 *ProblemParam; CONST CHAR16 *ValueStr; UINTN Bus, Address, XferLength, RegAddress, RegAddressLength, Source; UINT8 *Buffer; BOOLEAN ReadMode, WriteMode; EFI_HANDLE Handle, ProtHandle; ROCKCHIP_I2CDEMO_PROTOCOL *I2cDemoProtocol = NULL; UINTN HandleSize, i; UINTN TxData; Handle = NULL; Source = 0; HandleSize = 2 * sizeof (EFI_HANDLE); Status = gBS->LocateHandle (ByProtocol, &gRockchipI2cDemoProtocolGuid, NULL, &HandleSize, &ProtHandle); if (EFI_ERROR(Status)) { Print (L"No I2cDemo protocol, connect I2C stack\n"); Status = gBS->LocateHandle (ByProtocol, &gEfiI2cMasterProtocolGuid, NULL, &HandleSize, &ProtHandle); if (EFI_ERROR(Status)) { Print (L"Failed to locate I2cMaster protocol, abort!\n"); return SHELL_ABORTED; } Status = gBS->ConnectController (ProtHandle, NULL, NULL, TRUE); if (EFI_ERROR(Status)) { Print (L"Cannot connect I2C stack, abort!\n"); return SHELL_ABORTED; } } Status = ShellInitialize (); if (EFI_ERROR (Status)) { Print (L"Error - failed to initialize shell\n"); return SHELL_ABORTED; } Status = ShellCommandLineParse (ParamList, &CheckPackage, &ProblemParam, TRUE); if (EFI_ERROR (Status)) { Print (L"Error - failed to parse command line\n"); return SHELL_ABORTED; } if (ShellCommandLineGetFlag (CheckPackage, L"list")) { I2cDemoList(); return SHELL_SUCCESS; } if (ShellCommandLineGetFlag (CheckPackage, L"help")) { Usage(); return SHELL_SUCCESS; } ReadMode = ShellCommandLineGetFlag (CheckPackage, L"read"); WriteMode = ShellCommandLineGetFlag (CheckPackage, L"write"); if (!ReadMode && !WriteMode) { Print (L"Not support mode given.\n"); Usage(); return SHELL_ABORTED; } if (ShellCommandLineGetCount(CheckPackage) != 6 && ReadMode) { Print (L"Not enough arguments given.\n"); Usage(); return SHELL_ABORTED; } if (ShellCommandLineGetCount(CheckPackage) != 7 && WriteMode) { Print (L"Not enough arguments given.\n"); Usage(); return SHELL_ABORTED; } ValueStr = ShellCommandLineGetRawValue(CheckPackage, 1); Bus = ShellHexStrToUintn (ValueStr); ValueStr = ShellCommandLineGetRawValue(CheckPackage, 2); Address = ShellHexStrToUintn (ValueStr); ValueStr = ShellCommandLineGetRawValue(CheckPackage, 3); XferLength = ShellHexStrToUintn (ValueStr); ValueStr = ShellCommandLineGetRawValue(CheckPackage, 4); RegAddress = ShellHexStrToUintn (ValueStr); ValueStr = ShellCommandLineGetRawValue(CheckPackage, 5); RegAddressLength = ShellHexStrToUintn (ValueStr); if (WriteMode) { ValueStr = ShellCommandLineGetRawValue(CheckPackage, 6); TxData = ShellHexStrToUintn (ValueStr); } I2cDemoLocateProtocol (I2C_DEVICE_INDEX(Bus, Address), &Handle, &I2cDemoProtocol); if (I2cDemoProtocol == NULL) { Print (L"Failed to locate I2CDEMO protocol.\n"); return SHELL_INVALID_PARAMETER; } Buffer = AllocateZeroPool (XferLength); if (Buffer == NULL) { Status = SHELL_OUT_OF_RESOURCES; Print (L"Error - out of resources.\n"); goto out_close; } if (ReadMode) { Status = I2cDemoProtocol->Read(I2cDemoProtocol, (UINT8 *)&RegAddress, RegAddressLength, Buffer, XferLength); if (!EFI_ERROR(Status)) { Print (L"Read data[0 ~ %d]:", XferLength - 1); for (i = 0; i Write(I2cDemoProtocol, (UINT8 *)&RegAddress, RegAddressLength, (UINT8 *)&TxData, XferLength); } if (EFI_ERROR(Status)) { Print (L"I2c Operation failed %d.\n", Status); } else { Print (L"I2c Operation successfully.\n"); } Status = SHELL_SUCCESS; FreePool(Buffer); out_close: gBS->CloseProtocol ( Handle, &gRockchipI2cDemoProtocolGuid, gImageHandle, NULL ); return Status; } EFI_STATUS EFIAPI ShellI2cDemoTestLibConstructor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { Print (L"~Filed to add Hii package\n"); ShellI2cDemoHiiHandle = NULL; ShellI2cDemoHiiHandle = HiiAddPackages ( &gShellI2cDemoHiiGuid, gImageHandle, UefiShellI2cDemoLibStrings, NULL ); if (ShellI2cDemoHiiHandle == NULL) { Print (L"Filed to add Hii package\n"); return EFI_DEVICE_ERROR; } ShellCommandRegisterCommandName ( L"i2cdemo", ShellCommandRunI2cDemo, ShellCommandGetManFileNameI2cDemo, 0, L"i2cdemo", TRUE , ShellI2cDemoHiiHandle, STRING_TOKEN (STR_GET_HELP_I2CDEMO) ); return EFI_SUCCESS; } EFI_STATUS EFIAPI ShellI2cDemoTestLibDestructor ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { if (ShellI2cDemoHiiHandle != NULL) { HiiRemovePackages (ShellI2cDemoHiiHandle); } return EFI_SUCCESS; }