aaaaaaaaaaaaaaaaaaaaaaaa

This commit is contained in:
Leandro Friedrich 2022-12-10 20:18:36 +01:00
parent 77f7c07180
commit 5d995b114c
30 changed files with 8 additions and 4194 deletions

View File

@ -1,30 +0,0 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BamDxe
FILE_GUID = 6914BF99-1BAB-4042-A266-B206374E0239
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = BamDxeInitialize
[Sources.common]
Driver.c
bam.c
[BuildOptions.AARCH64]
GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
UefiDriverEntryPoint
IoLib
[Protocols]
gQcomBamProtocolGuid
[Depex]
TRUE

View File

@ -1,40 +0,0 @@
#include <PiDxe.h>
#include <Library/LKEnvLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Protocol/QcomBam.h>
#include "bam_p.h"
STATIC QCOM_BAM_PROTOCOL mBam = {
bam_init,
bam_sys_pipe_init,
bam_pipe_fifo_init,
bam_add_cmd_element,
bam_add_desc,
bam_add_one_desc,
bam_sys_gen_event,
bam_wait_for_interrupt,
bam_read_offset_update,
};
EFI_STATUS
EFIAPI
BamDxeInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_HANDLE Handle = NULL;
EFI_STATUS Status;
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle,
&gQcomBamProtocolGuid,
&mBam,
NULL
);
ASSERT_EFI_ERROR(Status);
return Status;
}

View File

@ -1,2 +0,0 @@
URL: https://source.codeaurora.org/quic/la/kernel/lk
BRANCH: LA.AF.1.1-02810-8064.0

View File

@ -1,471 +0,0 @@
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Library/LKEnvLib.h>
#include <Library/Pow2Lib.h>
#include <Protocol/QcomBam.h>
#include "bam_p.h"
#define HLOS_EE_INDEX 0
/* Reset BAM registers and pipes */
static void bam_reset(struct bam_instance *bam)
{
/* Initiate SW reset */
writel(BAM_SW_RST_BIT_MASK, BAM_CTRL_REG(bam->base));
/* No delay required */
/* Disable SW reset */
writel(~BAM_SW_RST_BIT_MASK, BAM_CTRL_REG(bam->base));
}
/* Resets pipe registers and state machines */
static void bam_pipe_reset(struct bam_instance *bam,
uint8_t pipe_num)
{
/* Start sw reset of the pipe to be allocated */
writel(1, BAM_P_RSTn(bam->pipe[pipe_num].pipe_num, bam->base));
/* No delay required */
/* Stop sw reset of the pipe to be allocated */
writel(0, BAM_P_RSTn(bam->pipe[pipe_num].pipe_num, bam->base));
}
/* A blocking function that waits till an interrupt is signalled.
* bam : BAM instance for the descriptors to be queued.
* pipe_num : pipe number for the descriptors to be queued.
* interrupt: interrupt to wait for.
*/
int bam_wait_for_interrupt(struct bam_instance *bam,
uint8_t pipe_num,
enum p_int_type interrupt)
{
uint32_t val;
while (1)
{
/* Wait for a interrupt on the right pipe */
do{
/* Determine the pipe causing the interrupt */
val = readl(BAM_IRQ_SRCS(bam->base));
/* Flush out the right most global interrupt bit */
} while (!((val & 0x7FFF) & (1 << bam->pipe[pipe_num].pipe_num)));
/* Check the reason for this BAM interrupt */
if (readl(BAM_IRQ_STTS(bam->base)))
goto bam_wait_int_error;
/* Check the interrupt type */
/* Read interrupt status register */
val = readl(BAM_P_IRQ_STTSn(bam->pipe[pipe_num].pipe_num, bam->base));
/* Check for error */
if (val & P_ERR_EN_MASK)
goto bam_wait_int_error;
if (val & interrupt)
{
/* Correct interrupt was fired. */
/* Clear the other interrupts */
val = P_OUT_OF_DESC_EN_MASK | P_PRCSD_DESC_EN_MASK | P_TRNSFR_END_EN_MASK;
writel (val, BAM_P_IRQ_CLRn(bam->pipe[pipe_num].pipe_num, bam->base));
return BAM_RESULT_SUCCESS;
}
else if (val & P_TRNSFR_END_EN_MASK)
{
dprintf(CRITICAL,
"Trasfer end signalled before the last descc was processed\n");
goto bam_wait_int_error;
}
}
bam_wait_int_error:
dprintf(CRITICAL, "Unexpected interrupt\n");
return BAM_RESULT_FAILURE;
}
/* Enable BAM and pipe level interrupts */
void bam_enable_interrupts(struct bam_instance *bam, uint8_t pipe_num)
{
uint32_t int_mask = P_ERR_EN_MASK | P_OUT_OF_DESC_EN_MASK |
P_PRCSD_DESC_EN_MASK | P_TRNSFR_END_EN_MASK;
uint32_t val;
/* Enable BAM error interrupts */
writel(BAM_ERROR_EN_MASK, BAM_IRQ_EN_REG(bam->base));
/* Enable the interrupts for the pipe by enabling the relevant bits
* in the BAM_PIPE_INTERRUPT_ENABLE register.
*/
writel(int_mask,
BAM_P_IRQ_ENn(bam->pipe[pipe_num].pipe_num, bam->base));
/* Enable pipe interrups */
/* Do read-modify-write */
val = readl(BAM_IRQ_SRCS_MSK(bam->base));
writel((1 << bam->pipe[pipe_num].pipe_num) | val,
BAM_IRQ_SRCS_MSK(bam->base));
}
/* Reset and initialize the bam module */
void bam_init(struct bam_instance *bam)
{
uint32_t val = 0;
bam_reset(bam);
/* Check for only one pipe's direction.
* The other is assumed to be the opposite system
* transaction.
*/
if (bam->pipe[0].trans_type == SYS2BAM ||
bam->pipe[0].trans_type == BAM2SYS)
{
/* Program the threshold count */
writel(bam->threshold, BAM_DESC_CNT_TRSHLD_REG(bam->base));
}
/* Program config register for H/W bug fixes */
val = 0xffffffff & ~(1 << 11);
writel(val, BAM_CNFG_BITS(bam->base));
/* Write the EE index to control the mapping of interrupts to EE */
val = HLOS_EE_INDEX & BAM_EE_MASK;
writel(val, BAM_TRUST_REG(bam->base));
/* Enable the BAM */
writel(BAM_ENABLE_BIT_MASK, BAM_CTRL_REG(bam->base));
}
/* Funtion to setup a simple fifo structure.
* Note: Addr should be 8 byte aligned.
* bam : BAM instance for the descriptors to be queued.
* pipe_num : pipe number for the descriptors to be queued.
*/
int bam_pipe_fifo_init(struct bam_instance *bam,
uint8_t pipe_num)
{
if (bam->pipe[pipe_num].fifo.size > 0x7FFF)
{
dprintf(CRITICAL,
"Size exceeds max size for a descriptor(0x7FFF)\n");
return BAM_RESULT_FAILURE;
}
/* Check if fifo start is 8-byte alligned */
ASSERT(!((uint32_t)bam->pipe[pipe_num].fifo.head & 0x7));
/* Check if fifo size is a power of 2.
* The circular fifo logic in lk expects this.
*/
ASSERT(ispow2(bam->pipe[pipe_num].fifo.size));
bam->pipe[pipe_num].fifo.current = bam->pipe[pipe_num].fifo.head;
/* Set the descriptor buffer size. Must be a multiple of 8 */
writel(bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE,
BAM_P_FIFO_SIZESn(bam->pipe[pipe_num].pipe_num, bam->base));
/* Write descriptors FIFO base addr must be 8-byte aligned */
/* Needs a physical address conversion as we are setting up
* the base of the FIFO for the BAM state machine.
*/
writel((uint32_t)bam->pipe[pipe_num].fifo.head,
BAM_P_DESC_FIFO_ADDRn(bam->pipe[pipe_num].pipe_num, bam->base));
/* Initialize FIFO offset for the first read */
bam->pipe[pipe_num].fifo.offset = BAM_DESC_SIZE;
/* Everything is set.
* Flag pipe init done.
*/
bam->pipe[pipe_num].initialized = 1;
return BAM_RESULT_SUCCESS;
}
void bam_sys_pipe_init(struct bam_instance *bam,
uint8_t pipe_num)
{
uint32_t val = 0;
/* Reset the pipe to be allocated */
bam_pipe_reset(bam, pipe_num);
/* Enable minimal interrupts */
bam_enable_interrupts(bam, pipe_num);
/* Pipe event threshold register is not relevant in sys modes */
/* Enable pipe in system mode and set the direction */
writel(P_SYS_MODE_MASK | P_ENABLE |
(bam->pipe[pipe_num].trans_type << P_DIRECTION_SHIFT),
BAM_P_CTRLn(bam->pipe[pipe_num].pipe_num, bam->base));
/* Write the EE index to control the mapping of pipe interrupts to EE */
val = HLOS_EE_INDEX & BAM_EE_MASK;
writel(val, BAM_P_TRUST_REGn(bam->pipe[pipe_num].pipe_num, bam->base));
/* Mark the pipe FIFO as uninitialized. */
bam->pipe[pipe_num].initialized = 0;
}
/* Function to notify written descriptors to BAM.
* bam : BAM instance for the descriptors to be queued.
* pipe_num : pipe number for the descriptors to be queued.
* num_desc : number of the descriptors.
* fifo : Circular FIFO used for the descriptors.
*/
void bam_sys_gen_event(struct bam_instance *bam,
uint8_t pipe_num,
unsigned int num_desc)
{
uint32_t val = 0;
if (num_desc >= bam->pipe[pipe_num].fifo.size) {
dprintf(CRITICAL,
"Max allowed desc is one less than the fifo length\n");
return;
}
/* Update the fifo peer offset */
val = (num_desc - 1) * BAM_DESC_SIZE;
val += bam->pipe[pipe_num].fifo.offset;
val &= (bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE - 1);
writel(val, BAM_P_EVNT_REGn(bam->pipe[pipe_num].pipe_num, bam->base));
}
/* Function to read the updates for FIFO offsets.
* bam : BAM that uses the FIFO.
* pipe : BAM pipe that uses the FIFO.
* return : FIFO offset where the next descriptor should be written.
* Note : S/W maintains the circular properties of the FIFO and updates
* the offsets accordingly.
*/
void bam_read_offset_update(struct bam_instance *bam, unsigned int pipe_num)
{
uint32_t offset;
offset = readl(BAM_P_SW_OFSTSn(bam->pipe[pipe_num].pipe_num, bam->base));
offset &= 0xFFFF;
dprintf(INFO, "Offset value is %d \n", offset);
/* Save the next offset to be written to. */
bam->pipe[pipe_num].fifo.current = (struct bam_desc*)
((uint32_t)bam->pipe[pipe_num].fifo.head + offset);
bam->pipe[pipe_num].fifo.offset = offset + BAM_DESC_SIZE ;
}
/* Function to get the next desc address.
* Keeps track of circular properties of the FIFO
* and returns the appropriate address.
*/
static struct bam_desc* fifo_getnext(struct bam_desc_fifo *fifo,
struct bam_desc* desc)
{
uint16_t offset;
offset = desc - fifo->head;
if (offset == (fifo->size - 1))
return fifo->head;
else
return desc + 1;
}
/* Function to add BAM descriptors for a given fifo.
* bam : BAM instance to be used.
* data_ptr : Memory address for data transfer.
* data_len : Length of the data_ptr.
* flags : Flags to be set on the last desc added.
*
* Note: This function also notifies the BAM about the added descriptors.
*/
int bam_add_desc(struct bam_instance *bam,
unsigned int pipe_num,
unsigned char *data_ptr,
unsigned int data_len,
unsigned flags)
{
int bam_ret = BAM_RESULT_SUCCESS;
unsigned int len = data_len;
unsigned int desc_len;
unsigned int n = 0;
unsigned int desc_flags;
dprintf(INFO, "Data length for BAM transfer is %u\n", data_len);
if (data_ptr == NULL || len == 0)
{
dprintf(CRITICAL, "Wrong params for BAM transfer \n");
bam_ret = BAM_RESULT_FAILURE;
goto bam_add_desc_error;
}
/* Check if we have enough space in FIFO */
if (len > (unsigned)bam->pipe[pipe_num].fifo.size * BAM_MAX_DESC_DATA_LEN)
{
dprintf(CRITICAL, "Data transfer exceeds desc fifo length.\n");
bam_ret = BAM_RESULT_FAILURE;
goto bam_add_desc_error;
}
while (len)
{
/* There are only 16 bits to write data length.
* If more bits are needed, create more
* descriptors.
*/
if (len > BAM_MAX_DESC_DATA_LEN)
{
desc_len = BAM_MAX_DESC_DATA_LEN;
len -= BAM_MAX_DESC_DATA_LEN;
desc_flags = 0;
}
else
{
desc_len = len;
len = 0;
/* Set correct flags on the last desc. */
desc_flags = flags;
}
/* Write descriptor */
bam_add_one_desc(bam, pipe_num, data_ptr, desc_len, desc_flags);
data_ptr += BAM_MAX_DESC_DATA_LEN;
n++;
}
/* Create a read/write event to notify the periperal of the added desc. */
bam_sys_gen_event(bam, pipe_num, n);
bam_add_desc_error:
return bam_ret;
}
/* Function to add a BAM descriptor for a given fifo.
* bam : BAM instance to be used.
* data_ptr : Memory address for data transfer.
* data_len : Length of the data_ptr.
* flags : Flags to be set on the desc added.
*
* Note: This function does not notify the BAM about the added descriptor.
*/
int bam_add_one_desc(struct bam_instance *bam,
unsigned int pipe_num,
unsigned char* data_ptr,
uint32_t len,
uint8_t flags)
{
struct bam_desc *desc = bam->pipe[pipe_num].fifo.current;
int bam_ret = BAM_RESULT_SUCCESS;
if (data_ptr == NULL || len == 0)
{
dprintf(CRITICAL, "Wrong params for BAM transfer \n");
bam_ret = BAM_RESULT_FAILURE;
goto bam_add_one_desc_error;
}
/* Check if the FIFO is allocated for the pipe */
if (!bam->pipe[pipe_num].initialized)
{
dprintf(CRITICAL, "Please allocate the FIFO for the BAM pipe %d\n",
bam->pipe[pipe_num].pipe_num);
bam_ret = BAM_RESULT_FAILURE;
goto bam_add_one_desc_error;
}
if ((flags & BAM_DESC_LOCK_FLAG) && (flags & BAM_DESC_UNLOCK_FLAG))
{
dprintf(CRITICAL, "Can't lock and unlock in the same desc\n");
bam_ret = BAM_RESULT_FAILURE;
goto bam_add_one_desc_error;
}
/* Setting EOT flag on a CMD desc is not valid */
if ((flags & BAM_DESC_EOT_FLAG) && (flags & BAM_DESC_CMD_FLAG))
{
dprintf(CRITICAL, "EOT flag set on the CMD desc\n");
bam_ret = BAM_RESULT_FAILURE;
goto bam_add_one_desc_error;
}
/* Check for the length of the desc. */
if (len > BAM_MAX_DESC_DATA_LEN)
{
dprintf(CRITICAL, "len of the desc exceeds max length"
" %d > %d\n", len, BAM_MAX_DESC_DATA_LEN);
bam_ret = BAM_RESULT_FAILURE;
goto bam_add_one_desc_error;
}
desc->flags = flags;
desc->addr = (uint32_t)data_ptr;
desc->size = (uint16_t)len;
desc->reserved = 0;
/* Update the FIFO to point to the head */
bam->pipe[pipe_num].fifo.current = fifo_getnext(&bam->pipe[pipe_num].fifo, desc);
bam_add_one_desc_error:
return bam_ret;
}
struct cmd_element* bam_add_cmd_element(struct cmd_element *ptr,
uint32_t reg_addr,
uint32_t value,
enum bam_ce_cmd_t cmd_type)
{
/* Write cmd type.
* Also, write the register address.
*/
ptr->addr_n_cmd = (reg_addr & ~(0xFF000000)) | (cmd_type << 24);
/* Do not mask any of the addr bits by default */
ptr->reg_mask = 0xFFFFFFFF;
/* Write the value to be written */
ptr->reg_data = value;
/* Return the address to add the next element to */
return ptr + 1;
}

View File

@ -1,31 +0,0 @@
#ifndef _BAM_PRIVATE_H
#define _BAM_PRIVATE_H
void bam_init(struct bam_instance *bam);
void bam_sys_pipe_init(struct bam_instance *bam,
uint8_t pipe_num);
int bam_pipe_fifo_init(struct bam_instance *bam,
uint8_t pipe_num);
struct cmd_element* bam_add_cmd_element(struct cmd_element *ptr,
uint32_t addr,
uint32_t data,
enum bam_ce_cmd_t cmd_type);
int bam_add_desc(struct bam_instance *bam,
unsigned int pipe_num,
unsigned char *data_ptr,
unsigned int data_len,
unsigned flags);
int bam_add_one_desc(struct bam_instance *bam,
unsigned int pipe_num,
unsigned char*,
uint32_t len,
uint8_t flags);
void bam_sys_gen_event(struct bam_instance *bam,
uint8_t pipe_num,
unsigned int num_desc);
int bam_wait_for_interrupt(struct bam_instance *bam,
uint8_t pipe_num,
enum p_int_type interrupt);
void bam_read_offset_update(struct bam_instance *bam, unsigned int pipe_num);
#endif // _BAM_PRIVATE_H

View File

@ -1,35 +0,0 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ClockDxe
FILE_GUID = 3EBA1869-45CA-41E1-AD6B-40BA8012A538
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = ClockDxeInitialize
[Sources.common]
Driver.c
LibraryImpl.c
clock.c
clock_lib2.c
clock-local.c
clock_pll.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
UefiDriverEntryPoint
QcomPlatformClockInitLib
TimerLib
[BuildOptions.AARCH64]
GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-overflow
[Protocols]
gQcomClockProtocolGuid
[Depex]
TRUE

View File

@ -1,26 +0,0 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ClockImplLib
FILE_GUID = 44790987-E75E-4178-AE98-AC961D33D8FE
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ClockLib
CONSTRUCTOR = ClockImplLibInitialize
[Sources.common]
LibraryImpl.c
clock.c
clock_lib2.c
clock-local.c
clock_pll.c
[BuildOptions.AARCH64]
GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-overflow
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
QcomPlatformClockInitLib

View File

@ -1,28 +0,0 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = ClockLib
FILE_GUID = 84B9E8B0-E69E-451A-8520-0BDBFDCE2364
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ClockLib|DXE_DRIVER UEFI_APPLICATION UEFI_DRIVER
CONSTRUCTOR = ClockLibConstructor
[Sources.common]
LibraryBS.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
UefiBootServicesTableLib
[BuildOptions.AARCH64]
GCC:*_*_*_CC_FLAGS = -Wno-pointer-to-int-cast -Wno-overflow
[Protocols]
gQcomClockProtocolGuid
[Depex]
gQcomClockProtocolGuid

View File

@ -1,22 +0,0 @@
#include <PiDxe.h>
#include <Library/LKEnvLib.h>
#include <Library/QcomClockLib.h>
#include <Library/UefiBootServicesTableLib.h>
EFI_STATUS
EFIAPI
ClockDxeInitialize(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
{
EFI_HANDLE Handle = NULL;
EFI_STATUS Status;
ClockImplLibInitialize();
Status = gBS->InstallMultipleProtocolInterfaces(
&Handle, &gQcomClockProtocolGuid, gClock, NULL);
ASSERT_EFI_ERROR(Status);
return Status;
}

View File

@ -1,20 +0,0 @@
#include <PiDxe.h>
#include <Library/LKEnvLib.h>
#include <Library/QcomClockLib.h>
#include <Library/UefiBootServicesTableLib.h>
QCOM_CLOCK_PROTOCOL *gClock = NULL;
RETURN_STATUS
EFIAPI
ClockLibConstructor(VOID)
{
EFI_STATUS Status;
Status = gBS->LocateProtocol(&gQcomClockProtocolGuid, NULL, (VOID **)&gClock);
ASSERT_EFI_ERROR(Status);
return Status;
}

View File

@ -1,33 +0,0 @@
#include <Base.h>
#include <Library/LKEnvLib.h>
#include <Library/QcomClockLib.h>
#include <Library/QcomPlatformClockInitLib.h>
#include "clock_p.h"
QCOM_CLOCK_PROTOCOL *gClock = NULL;
STATIC QCOM_CLOCK_PROTOCOL mInternalClock = {
clk_get, clk_enable, clk_disable,
clk_get_rate, clk_set_rate, clk_set_parent,
clk_get_parent, clk_get_set_enable, clk_reset,
};
RETURN_STATUS
EFIAPI
ClockImplLibInitialize(VOID)
{
EFI_STATUS Status;
struct clk_lookup *clist = NULL;
unsigned num = 0;
gClock = &mInternalClock;
Status = LibQcomPlatformClockInit(&clist, &num);
ASSERT_EFI_ERROR(Status);
clk_init(clist, num);
return Status;
}

View File

@ -1,3 +0,0 @@
URL: https://source.codeaurora.org/quic/la/kernel/lk
BRANCH: LA.AF.1.1-02810-8064.0
UPDATED FROM: LA.BF64.1.2.3-01510-8x94.0

View File

@ -1,387 +0,0 @@
/*
* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Library/LKEnvLib.h>
#include <Chipset/clock.h>
// Must come in order
#include <Chipset/clock-local.h>
#include "clock_p.h"
/*
* When enabling/disabling a clock, check the halt bit up to this number
* number of times (with a 1 us delay in between) before continuing.
*/
#define HALT_CHECK_MAX_LOOPS 100
/* For clock without halt checking, wait this long after enables/disables. */
#define HALT_CHECK_DELAY_US 10
struct clk_freq_tbl local_dummy_freq = F_END;
/*
* Clock enable/disable functions
*/
static int branch_clk_is_halted(const struct branch *clk)
{
int invert = (clk->halt_check == ENABLE);
int status_bit = readl_relaxed(clk->halt_reg) & BIT(clk->halt_bit);
return invert ? !status_bit : status_bit;
}
static void __branch_clk_enable_reg(const struct branch *clk, const char *name)
{
uint32_t reg_val;
if (clk->en_mask) {
reg_val = readl_relaxed(clk->ctl_reg);
reg_val |= clk->en_mask;
writel_relaxed(reg_val, clk->ctl_reg);
}
/* Wait for clock to enable before returning. */
if (clk->halt_check == DELAY)
udelay(HALT_CHECK_DELAY_US);
else if (
clk->halt_check == ENABLE || clk->halt_check == HALT ||
clk->halt_check == ENABLE_VOTED || clk->halt_check == HALT_VOTED) {
int count;
/* Wait up to HALT_CHECK_MAX_LOOPS for clock to enable. */
for (count = HALT_CHECK_MAX_LOOPS; branch_clk_is_halted(clk) && count > 0;
count--)
udelay(1);
}
}
/* Perform any register operations required to enable the clock. */
static void __local_clk_enable_reg(struct rcg_clk *clk)
{
uint32_t reg_val;
void *const reg = clk->b.ctl_reg;
if (clk->current_freq == &local_dummy_freq)
dprintf(
CRITICAL, "Attempting to enable %s before setting its rate.",
clk->c.dbg_name);
/*
* Program the NS register, if applicable. NS registers are not
* set in the set_rate path because power can be saved by deferring
* the selection of a clocked source until the clock is enabled.
*/
if (clk->ns_mask) {
reg_val = readl_relaxed(clk->ns_reg);
reg_val &= ~(clk->ns_mask);
reg_val |= (clk->current_freq->ns_val & clk->ns_mask);
writel_relaxed(reg_val, clk->ns_reg);
}
/* Enable MN counter, if applicable. */
reg_val = readl_relaxed(reg);
if (clk->current_freq->mnd_en_mask) {
reg_val |= clk->current_freq->mnd_en_mask;
writel_relaxed(reg_val, reg);
}
/* Enable root. */
if (clk->root_en_mask) {
reg_val |= clk->root_en_mask;
writel_relaxed(reg_val, reg);
}
__branch_clk_enable_reg(&clk->b, clk->c.dbg_name);
}
/* Enable a clock and any related power rail. */
int local_clk_enable(struct clk *c)
{
int rc;
struct rcg_clk *clk = to_rcg_clk(c);
rc = clk_enable(clk->depends);
if (rc)
goto err_dep;
__local_clk_enable_reg(clk);
clk->enabled = true;
err_dep:
return rc;
}
/* Disable a clock and any related power rail. */
void local_clk_disable(struct clk *c)
{ /*TODO: Stub function for now.*/
}
/*
* Frequency-related functions
*/
/* Set a clock's frequency. */
static int _local_clk_set_rate(struct rcg_clk *clk, struct clk_freq_tbl *nf)
{
struct clk_freq_tbl *cf;
int rc = 0;
/* Check if frequency is actually changed. */
cf = clk->current_freq;
if (nf == cf)
goto unlock;
if (clk->enabled) {
rc = clk_enable(nf->src_clk);
if (rc) {
goto unlock;
}
}
/* Perform clock-specific frequency switch operations. */
ASSERT(clk->set_rate);
clk->set_rate(clk, nf);
/*
* Current freq must be updated before __local_clk_enable_reg()
* is called to make sure the MNCNTR_EN bit is set correctly.
*/
clk->current_freq = nf;
/* Enable any clocks that were disabled. */
if (clk->bank_masks == NULL) {
if (clk->enabled)
__local_clk_enable_reg(clk);
}
unlock:
return rc;
}
/* Set a clock to an exact rate. */
int local_clk_set_rate(struct clk *c, unsigned rate)
{
struct rcg_clk * clk = to_rcg_clk(c);
struct clk_freq_tbl *nf;
for (nf = clk->freq_tbl; nf->freq_hz != FREQ_END && nf->freq_hz != rate; nf++)
;
if (nf->freq_hz == FREQ_END)
return ERR_INVALID_ARGS;
return _local_clk_set_rate(clk, nf);
}
/* Get the currently-set rate of a clock in Hz. */
unsigned local_clk_get_rate(struct clk *c)
{
/* TODO: Stub function for now. */
return 0;
}
/* Check if a clock is currently enabled. */
int local_clk_is_enabled(struct clk *clk) { return to_rcg_clk(clk)->enabled; }
/* Return a supported rate that's at least the specified rate. */
long local_clk_round_rate(struct clk *c, unsigned rate)
{
struct rcg_clk * clk = to_rcg_clk(c);
struct clk_freq_tbl *f;
for (f = clk->freq_tbl; f->freq_hz != FREQ_END; f++)
if (f->freq_hz >= rate)
return f->freq_hz;
return ERR_INVALID_ARGS;
}
struct clk *local_clk_get_parent(struct clk *clk)
{
return to_rcg_clk(clk)->current_freq->src_clk;
}
/*
* Branch clocks functions
*/
int branch_clk_enable(struct clk *clk)
{
struct branch_clk *branch = to_branch_clk(clk);
__branch_clk_enable_reg(&branch->b, branch->c.dbg_name);
branch->enabled = true;
return 0;
}
void branch_clk_disable(struct clk *clk)
{ /* TODO: Stub function for now */
}
struct clk *branch_clk_get_parent(struct clk *clk)
{
struct branch_clk *branch = to_branch_clk(clk);
return branch->parent;
}
int branch_clk_set_parent(struct clk *clk, struct clk *parent)
{
/* This is a stub function. */
return 0;
}
int branch_clk_is_enabled(struct clk *clk)
{
struct branch_clk *branch = to_branch_clk(clk);
return branch->enabled;
}
/**/
/* For clocks with MND dividers. */
void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf)
{
uint32_t ns_reg_val, ctl_reg_val;
/* Assert MND reset. */
ns_reg_val = readl_relaxed(clk->ns_reg);
ns_reg_val |= BIT(7);
writel_relaxed(ns_reg_val, clk->ns_reg);
/* Program M and D values. */
writel_relaxed(nf->md_val, clk->md_reg);
/* If the clock has a separate CC register, program it. */
if (clk->ns_reg != clk->b.ctl_reg) {
ctl_reg_val = readl_relaxed(clk->b.ctl_reg);
ctl_reg_val &= ~(clk->ctl_mask);
ctl_reg_val |= nf->ctl_val;
writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
}
/* Deassert MND reset. */
ns_reg_val &= ~BIT(7);
writel_relaxed(ns_reg_val, clk->ns_reg);
}
void set_rate_mnd_banked(struct rcg_clk *clk, struct clk_freq_tbl *nf)
{
struct bank_masks * banks = clk->bank_masks;
const struct bank_mask_info *new_bank_masks;
const struct bank_mask_info *old_bank_masks;
uint32_t ns_reg_val, ctl_reg_val;
uint32_t bank_sel;
/*
* Determine active bank and program the other one. If the clock is
* off, program the active bank since bank switching won't work if
* both banks aren't running.
*/
ctl_reg_val = readl_relaxed(clk->b.ctl_reg);
bank_sel = !!(ctl_reg_val & banks->bank_sel_mask);
/* If clock isn't running, don't switch banks. */
bank_sel ^= (!clk->enabled || clk->current_freq->freq_hz == 0);
if (bank_sel == 0) {
new_bank_masks = &banks->bank1_mask;
old_bank_masks = &banks->bank0_mask;
}
else {
new_bank_masks = &banks->bank0_mask;
old_bank_masks = &banks->bank1_mask;
}
ns_reg_val = readl_relaxed(clk->ns_reg);
/* Assert bank MND reset. */
ns_reg_val |= new_bank_masks->rst_mask;
writel_relaxed(ns_reg_val, clk->ns_reg);
/*
* Program NS only if the clock is enabled, since the NS will be set
* as part of the enable procedure and should remain with a low-power
* MUX input selected until then.
*/
if (clk->enabled) {
ns_reg_val &= ~(new_bank_masks->ns_mask);
ns_reg_val |= (nf->ns_val & new_bank_masks->ns_mask);
writel_relaxed(ns_reg_val, clk->ns_reg);
}
writel_relaxed(nf->md_val, new_bank_masks->md_reg);
/* Enable counter only if clock is enabled. */
if (clk->enabled)
ctl_reg_val |= new_bank_masks->mnd_en_mask;
else
ctl_reg_val &= ~(new_bank_masks->mnd_en_mask);
ctl_reg_val &= ~(new_bank_masks->mode_mask);
ctl_reg_val |= (nf->ctl_val & new_bank_masks->mode_mask);
writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
/* Deassert bank MND reset. */
ns_reg_val &= ~(new_bank_masks->rst_mask);
writel_relaxed(ns_reg_val, clk->ns_reg);
/*
* Switch to the new bank if clock is running. If it isn't, then
* no switch is necessary since we programmed the active bank.
*/
if (clk->enabled && clk->current_freq->freq_hz) {
ctl_reg_val ^= banks->bank_sel_mask;
writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
/*
* Wait at least 6 cycles of slowest bank's clock
* for the glitch-free MUX to fully switch sources.
*/
udelay(1);
/* Disable old bank's MN counter. */
ctl_reg_val &= ~(old_bank_masks->mnd_en_mask);
writel_relaxed(ctl_reg_val, clk->b.ctl_reg);
/* Program old bank to a low-power source and divider. */
ns_reg_val &= ~(old_bank_masks->ns_mask);
ns_reg_val |= (clk->freq_tbl->ns_val & old_bank_masks->ns_mask);
writel_relaxed(ns_reg_val, clk->ns_reg);
}
/*
* If this freq requires the MN counter to be enabled,
* update the enable mask to match the current bank.
*/
if (nf->mnd_en_mask)
nf->mnd_en_mask = new_bank_masks->mnd_en_mask;
/* Update the NS mask to match the current bank. */
clk->ns_mask = new_bank_masks->ns_mask;
}
void set_rate_nop(struct rcg_clk *clk, struct clk_freq_tbl *nf)
{
/*
* Nothing to do for fixed-rate or integer-divider clocks. Any settings
* in NS registers are applied in the enable path, since power can be
* saved by leaving an un-clocked or slowly-clocked source selected
* until the clock is enabled.
*/
}

View File

@ -1,193 +0,0 @@
/*
* Copyright (c) 2012, 2014, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Library/LKEnvLib.h>
#include <Chipset/clock.h>
#include "clock_p.h"
static struct clk_list msm_clk_list;
int clk_set_parent(struct clk *clk, struct clk *parent)
{
if (!clk->ops->set_parent)
return 0;
return clk->ops->set_parent(clk, parent);
}
struct clk *clk_get_parent(struct clk *clk)
{
if (!clk->ops->get_parent)
return NULL;
return clk->ops->get_parent(clk);
}
int clk_reset(struct clk *clk, enum clk_reset_action action)
{
if (!clk)
return 0;
if (!clk->ops->reset)
return 0;
return clk->ops->reset(clk, action);
}
/*
* Standard clock functions defined in include/clk.h
*/
int clk_enable(struct clk *clk)
{
int ret = 0;
struct clk *parent;
if (!clk)
return 0;
if (clk->count == 0) {
parent = clk_get_parent(clk);
ret = clk_enable(parent);
if (ret)
goto out;
if (clk->ops->enable)
ret = clk->ops->enable(clk);
if (ret) {
clk_disable(parent);
goto out;
}
}
clk->count++;
out:
return ret;
}
void clk_disable(struct clk *clk)
{
struct clk *parent;
if (!clk)
return;
if (clk->count == 0)
goto out;
if (clk->count == 1) {
if (clk->ops->disable)
clk->ops->disable(clk);
parent = clk_get_parent(clk);
clk_disable(parent);
}
clk->count--;
out:
return;
}
unsigned long clk_get_rate(struct clk *clk)
{
if (!clk->ops->get_rate)
return 0;
return clk->ops->get_rate(clk);
}
int clk_set_rate(struct clk *clk, unsigned long rate)
{
if (!clk->ops->set_rate)
return ERR_NOT_VALID;
return clk->ops->set_rate(clk, rate);
}
void clk_init(struct clk_lookup *clist, unsigned num)
{
if (clist && num) {
msm_clk_list.clist = (struct clk_lookup *)clist;
msm_clk_list.num = num;
}
}
struct clk *clk_get(const char *cid)
{
unsigned i;
struct clk_lookup *cl = msm_clk_list.clist;
unsigned num = msm_clk_list.num;
if (!cl || !num) {
dprintf(CRITICAL, "Alert!! clock list not defined!\n");
return NULL;
}
for (i = 0; i < num; i++, cl++) {
if (!strcmp(cl->con_id, cid)) {
return cl->clk;
}
}
dprintf(CRITICAL, "Alert!! Requested clock \"%s\" is not supported!\n", cid);
return NULL;
}
int clk_get_set_enable(char *id, unsigned long rate, bool enable)
{
int ret = NO_ERROR;
struct clk *cp;
/* Get clk */
cp = clk_get(id);
if (!cp) {
dprintf(CRITICAL, "Can't find clock with id: %s\n", id);
ret = ERR_NOT_VALID;
goto get_set_enable_error;
}
/* Set rate */
if (rate) {
ret = clk_set_rate(cp, rate);
if (ret) {
dprintf(CRITICAL, "Clock set rate failed.\n");
goto get_set_enable_error;
}
}
/* Enable clock */
if (enable) {
ret = clk_enable(cp);
if (ret) {
dprintf(CRITICAL, "Clock enable failed.\n");
}
}
get_set_enable_error:
return ret;
}
#ifdef DEBUG_CLOCK
struct clk_list *clk_get_list() { return &msm_clk_list; }
#endif

View File

@ -1,277 +0,0 @@
/*
* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Library/LKEnvLib.h>
#include <Chipset/clock.h>
// Must come in order
#include <Chipset/clock_lib2.h>
#include <Chipset/clock_pll.h>
#include "clock_p.h"
/*=============== CXO clock ops =============*/
int cxo_clk_enable(struct clk *clk)
{
/* Nothing to do. */
return 0;
}
void cxo_clk_disable(struct clk *clk)
{
/* Nothing to do. */
return;
}
/*=============== Branch clock ops =============*/
/* Branch clock enable */
int clock_lib2_branch_clk_enable(struct clk *clk)
{
int rc = 0;
uint32_t cbcr_val;
struct branch_clk *bclk = to_branch_clk(clk);
cbcr_val = readl(bclk->cbcr_reg);
cbcr_val |= CBCR_BRANCH_ENABLE_BIT;
writel(cbcr_val, bclk->cbcr_reg);
/* wait until status shows it is enabled */
while (readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT)
;
return rc;
}
/* Branch clock disable */
void clock_lib2_branch_clk_disable(struct clk *clk)
{
uint32_t cbcr_val;
struct branch_clk *bclk = to_branch_clk(clk);
cbcr_val = readl(bclk->cbcr_reg);
cbcr_val &= ~CBCR_BRANCH_ENABLE_BIT;
writel(cbcr_val, bclk->cbcr_reg);
/* wait until status shows it is disabled */
while (!(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT))
;
}
/* Branch clock set rate */
int clock_lib2_branch_set_rate(struct clk *c, unsigned rate)
{
struct branch_clk *branch = to_branch_clk(c);
if (!branch->has_sibling)
return clk_set_rate(branch->parent, rate);
return -1;
}
/*=============== Root clock ops =============*/
/* Root enable */
int clock_lib2_rcg_enable(struct clk *c)
{
/* Hardware feedback from branch enable results in root being enabled.
* Nothing to do here.
*/
return 0;
}
/* Root set rate:
* Find the entry in the frequecy table corresponding to the requested rate.
* Enable the source clock required for the new frequency.
* Call the set_rate function defined for this particular root clock.
*/
int clock_lib2_rcg_set_rate(struct clk *c, unsigned rate)
{
struct rcg_clk * rclk = to_rcg_clk(c);
struct clk_freq_tbl *nf; /* new freq */
int rc = 0;
/* ck if new freq is in table */
for (nf = rclk->freq_tbl; nf->freq_hz != FREQ_END && nf->freq_hz != rate;
nf++)
;
/* Frequency not found in the table */
if (nf->freq_hz == FREQ_END)
return ERR_INVALID_ARGS;
/* Check if frequency is actually changed. */
if (nf == rclk->current_freq)
return rc;
/* First enable the source clock for this freq. */
clk_enable(nf->src_clk);
/* Perform clock-specific frequency switch operations. */
ASSERT(rclk->set_rate);
rclk->set_rate(rclk, nf);
/* update current freq */
rclk->current_freq = nf;
return rc;
}
/* root update config: informs h/w to start using the new config values */
static void clock_lib2_rcg_update_config(struct rcg_clk *rclk)
{
uint32_t cmd;
cmd = readl(rclk->cmd_reg);
cmd |= CMD_UPDATE_BIT;
writel(cmd, rclk->cmd_reg);
/* Wait for frequency to be updated. */
while (readl(rclk->cmd_reg) & CMD_UPDATE_MASK)
;
}
/* root set rate for clocks with half integer and MND divider */
void clock_lib2_rcg_set_rate_mnd(
struct rcg_clk *rclk, struct clk_freq_tbl *freq)
{
uint32_t cfg;
/* Program MND values */
writel(freq->m_val, rclk->m_reg);
writel(freq->n_val, rclk->n_reg);
writel(freq->d_val, rclk->d_reg);
/* setup src select and divider */
cfg = readl(rclk->cfg_reg);
cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK | CFG_MODE_MASK);
cfg |= freq->div_src_val;
if (freq->n_val != 0) {
cfg |= (CFG_MODE_DUAL_EDGE << CFG_MODE_OFFSET);
}
writel(cfg, rclk->cfg_reg);
/* Inform h/w to start using the new config. */
clock_lib2_rcg_update_config(rclk);
}
/* root set rate for clocks with half integer divider */
void clock_lib2_rcg_set_rate_hid(
struct rcg_clk *rclk, struct clk_freq_tbl *freq)
{
uint32_t cfg;
/* setup src select and divider */
cfg = readl(rclk->cfg_reg);
cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK);
cfg |= freq->div_src_val;
writel(cfg, rclk->cfg_reg);
clock_lib2_rcg_update_config(rclk);
}
/*=============== Vote clock ops =============*/
/* Vote clock enable */
int clock_lib2_vote_clk_enable(struct clk *c)
{
uint32_t vote_regval;
uint32_t val;
struct vote_clk *vclk = to_local_vote_clk(c);
vote_regval = readl(vclk->vote_reg);
vote_regval |= vclk->en_mask;
writel_relaxed(vote_regval, vclk->vote_reg);
do {
val = readl(vclk->cbcr_reg);
val &= BRANCH_CHECK_MASK;
}
/* wait until status shows it is enabled */
while ((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL));
return 0;
}
/* Vote clock disable */
void clock_lib2_vote_clk_disable(struct clk *c)
{
uint32_t vote_regval;
struct vote_clk *vclk = to_local_vote_clk(c);
vote_regval = readl(vclk->vote_reg);
vote_regval &= ~vclk->en_mask;
writel_relaxed(vote_regval, vclk->vote_reg);
}
/* Reset clock */
static int
__clock_lib2_branch_clk_reset(uint32_t bcr_reg, enum clk_reset_action action)
{
uint32_t reg;
int ret = 0;
reg = readl(bcr_reg);
switch (action) {
case CLK_RESET_ASSERT:
reg |= BIT(0);
break;
case CLK_RESET_DEASSERT:
reg &= ~BIT(0);
break;
default:
ret = 1;
}
writel(reg, bcr_reg);
/* Wait for writes to go through */
dmb();
return ret;
}
int clock_lib2_reset_clk_reset(struct clk *c, enum clk_reset_action action)
{
struct reset_clk *rst = to_reset_clk(c);
if (!rst)
return 0;
return __clock_lib2_branch_clk_reset(rst->bcr_reg, action);
}
int clock_lib2_branch_clk_reset(struct clk *c, enum clk_reset_action action)
{
struct branch_clk *bclk = to_branch_clk(c);
if (!bclk)
return 0;
return __clock_lib2_branch_clk_reset((uint32_t)bclk->bcr_reg, action);
}

View File

@ -1,110 +0,0 @@
#ifndef _CLOCK_PRIVATE_H
#define _CLOCK_PRIVATE_H
/**
* clk_get - lookup and obtain a reference to a clock producer.
* @dev: device for clock "consumer"
* @id: clock comsumer ID
*
* Returns a struct clk corresponding to the clock producer, or
* valid IS_ERR() condition containing errno. The implementation
* uses @dev and @id to determine the clock consumer, and thereby
* the clock producer. (IOW, @id may be identical strings, but
* clk_get may return different clock producers depending on @dev.)
*
* Drivers must assume that the clock source is not enabled.
*
* clk_get should not be called from within interrupt context.
*/
struct clk *clk_get(const char *id);
/**
* clk_enable - inform the system when the clock source should be running.
* @clk: clock source
*
* If the clock can not be enabled/disabled, this should return success.
*
* Returns success (0) or negative errno.
*/
int clk_enable(struct clk *clk);
/**
* clk_disable - inform the system when the clock source is no longer required.
* @clk: clock source
*
* Inform the system that a clock source is no longer required by
* a driver and may be shut down.
*
* Implementation detail: if the clock source is shared between
* multiple drivers, clk_enable() calls must be balanced by the
* same number of clk_disable() calls for the clock source to be
* disabled.
*/
void clk_disable(struct clk *clk);
/**
* clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
* This is only valid once the clock source has been enabled.
* @clk: clock source
*/
unsigned long clk_get_rate(struct clk *clk);
/**
* clk_set_rate - set the clock rate for a clock source
* @clk: clock source
* @rate: desired clock rate in Hz
*
* Returns success (0) or negative errno.
*/
int clk_set_rate(struct clk *clk, unsigned long rate);
/**
* clk_set_parent - set the parent clock source for this clock
* @clk: clock source
* @parent: parent clock source
*
* Returns success (0) or negative errno.
*/
int clk_set_parent(struct clk *clk, struct clk *parent);
/**
* clk_get_parent - get the parent clock source for this clock
* @clk: clock source
*
* Returns struct clk corresponding to parent clock source, or
* valid IS_ERR() condition containing errno.
*/
struct clk *clk_get_parent(struct clk *clk);
/**
* clk_get_set_enable -
* -- get the clock.
* -- set the rate to @rate if @rate is non-zero
* -- enable the clock if @enable = ture;
* @id: clock identifier (char *)
* @rate: desired clock rate in Hz
*
* Returns success (0) or negative errno.
*/
int clk_get_set_enable(char *id, unsigned long rate, bool enable);
#ifdef DEBUG_CLOCK
struct clk_list *clk_get_list(void);
#endif
/**
* clk_init - register all the clocks in the system.
* @clist: pointer to clock list
* @num: number of clocks in the list
*/
void clk_init(struct clk_lookup *clist, unsigned num);
/**
* clk_reset - Reset block using BCR
* @clk: pointer to clock
* @action: clock assert or deassert
*/
int clk_reset(struct clk *clk, enum clk_reset_action);
#endif // _CLOCK_PRIVATE_H

View File

@ -1,139 +0,0 @@
/*
* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of The Linux Foundation nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <Library/LKEnvLib.h>
#include <Chipset/clock.h>
// Must come in order
#include <Chipset/clock_pll.h>
/*
* pll_vote_clk functions
*/
int pll_vote_clk_enable(struct clk *clk)
{
uint32_t ena;
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
ena = readl_relaxed(pll->en_reg);
ena |= pll->en_mask;
writel_relaxed(ena, pll->en_reg);
/* Wait until PLL is enabled */
while ((readl_relaxed(pll->status_reg) & pll->status_mask) == 0)
;
return 0;
}
void pll_vote_clk_disable(struct clk *clk)
{
uint32_t ena;
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
ena = readl_relaxed(pll->en_reg);
ena &= ~(pll->en_mask);
writel_relaxed(ena, pll->en_reg);
}
unsigned pll_vote_clk_get_rate(struct clk *clk)
{
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
return pll->rate;
}
struct clk *pll_vote_clk_get_parent(struct clk *clk)
{
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
return pll->parent;
}
int pll_vote_clk_is_enabled(struct clk *clk)
{
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
return !!(readl_relaxed(pll->status_reg) & pll->status_mask);
}
/*
* PLLs functions
*/
int pll_clk_enable(struct clk *clk)
{
uint32_t mode;
struct pll_clk *pll = to_pll_clk(clk);
mode = readl_relaxed(pll->mode_reg);
/* Disable PLL bypass mode. */
mode |= BIT(1);
writel_relaxed(mode, pll->mode_reg);
/*
* H/W requires a 5us delay between disabling the bypass and
* de-asserting the reset. Delay 10us just to be safe.
*/
udelay(10);
/* De-assert active-low PLL reset. */
mode |= BIT(2);
writel_relaxed(mode, pll->mode_reg);
/* Wait until PLL is locked. */
udelay(50);
/* Enable PLL output. */
mode |= BIT(0);
writel_relaxed(mode, pll->mode_reg);
return 0;
}
void pll_clk_disable(struct clk *clk)
{
uint32_t mode;
struct pll_clk *pll = to_pll_clk(clk);
/*
* Disable the PLL output, disable test mode, enable
* the bypass mode, and assert the reset.
*/
mode = readl_relaxed(pll->mode_reg);
mode &= ~BM(3, 0);
writel_relaxed(mode, pll->mode_reg);
}
unsigned pll_clk_get_rate(struct clk *clk)
{
struct pll_clk *pll = to_pll_clk(clk);
return pll->rate;
}
struct clk *pll_clk_get_parent(struct clk *clk)
{
struct pll_clk *pll = to_pll_clk(clk);
return pll->parent;
}

View File

@ -1,56 +0,0 @@
#include <PiDxe.h>
#include <Protocol/KeypadDevice.h>
#include <Library/DebugLib.h>
#include <Library/KeypadDeviceImplLib.h>
#include <Library/UefiBootServicesTableLib.h>
typedef struct {
VENDOR_DEVICE_PATH Keypad;
EFI_DEVICE_PATH End;
} KEYPAD_DEVICE_PATH;
KEYPAD_DEVICE_PATH mInternalDevicePath = {
{
{
HARDWARE_DEVICE_PATH,
HW_VENDOR_DP,
{
(UINT8)(sizeof(VENDOR_DEVICE_PATH)),
(UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
},
},
EFI_CALLER_ID_GUID,
},
{
END_DEVICE_PATH_TYPE,
END_ENTIRE_DEVICE_PATH_SUBTYPE,
{ sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
}
};
STATIC KEYPAD_DEVICE_PROTOCOL mInternalKeypadDevice = {
KeypadDeviceImplReset,
KeypadDeviceImplGetKeys,
};
EFI_STATUS
EFIAPI
KeypadDeviceDxeInitialize (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
Status = gBS->InstallMultipleProtocolInterfaces(
&ImageHandle,
&gEFIDroidKeypadDeviceProtocolGuid,
&mInternalKeypadDevice,
&gEfiDevicePathProtocolGuid,
&mInternalDevicePath,
NULL
);
ASSERT_EFI_ERROR(Status);
return Status;
}

View File

@ -1,29 +0,0 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = GenericKeypadDeviceDxe
FILE_GUID = 39A24CF8-411E-48EB-8BEA-3ED07327F400
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = KeypadDeviceDxeInitialize
[Sources.common]
GenericKeypadDevice.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
UefiDriverEntryPoint
MemoryAllocationLib
KeypadDeviceImplLib
[Protocols]
gEFIDroidKeypadDeviceProtocolGuid
gEfiDevicePathProtocolGuid
[Depex]
TRUE

View File

@ -1,352 +0,0 @@
/** @file
Routines related Component Name protocol.
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Keypad.h"
//
// EFI Component Name Functions
//
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 4646 or ISO 639-2 language code format.
@param DriverName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
KeypadComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle[in] The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param ChildHandle[in] The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 4646 or ISO 639-2 language code format.
@param ControllerName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
KeypadComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
//
// EFI Component Name Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gKeypadComponentName = {
KeypadComponentNameGetDriverName,
KeypadComponentNameGetControllerName,
"eng"
};
//
// EFI Component Name 2 Protocol
//
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gKeypadComponentName2 = {
(EFI_COMPONENT_NAME2_GET_DRIVER_NAME) KeypadComponentNameGetDriverName,
(EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) KeypadComponentNameGetControllerName,
"en"
};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mKeypadDriverNameTable[] = {
{
"eng;en",
L"Keypad Driver"
},
{
NULL,
NULL
}
};
/**
Retrieves a Unicode string that is the user readable name of the driver.
This function retrieves the user readable name of a driver in the form of a
Unicode string. If the driver specified by This has a user readable name in
the language specified by Language, then a pointer to the driver name is
returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
by This does not support the language specified by Language,
then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified
in RFC 4646 or ISO 639-2 language code format.
@param DriverName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
driver specified by This in the language
specified by Language.
@retval EFI_SUCCESS The Unicode string for the Driver specified by
This and the language specified by Language was
returned in DriverName.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER DriverName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
KeypadComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
{
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
mKeypadDriverNameTable,
DriverName,
(BOOLEAN)(This == &gKeypadComponentName)
);
}
/**
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by a driver.
This function retrieves the user readable name of the controller specified by
ControllerHandle and ChildHandle in the form of a Unicode string. If the
driver specified by This has a user readable name in the language specified by
Language, then a pointer to the controller name is returned in ControllerName,
and EFI_SUCCESS is returned. If the driver specified by This is not currently
managing the controller specified by ControllerHandle and ChildHandle,
then EFI_UNSUPPORTED is returned. If the driver specified by This does not
support the language specified by Language, then EFI_UNSUPPORTED is returned.
@param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
EFI_COMPONENT_NAME_PROTOCOL instance.
@param ControllerHandle[in] The handle of a controller that the driver
specified by This is managing. This handle
specifies the controller whose name is to be
returned.
@param ChildHandle[in] The handle of the child controller to retrieve
the name of. This is an optional parameter that
may be NULL. It will be NULL for device
drivers. It will also be NULL for a bus drivers
that wish to retrieve the name of the bus
controller. It will not be NULL for a bus
driver that wishes to retrieve the name of a
child controller.
@param Language[in] A pointer to a Null-terminated ASCII string
array indicating the language. This is the
language of the driver name that the caller is
requesting, and it must match one of the
languages specified in SupportedLanguages. The
number of languages supported by a driver is up
to the driver writer. Language is specified in
RFC 4646 or ISO 639-2 language code format.
@param ControllerName[out] A pointer to the Unicode string to return.
This Unicode string is the name of the
controller specified by ControllerHandle and
ChildHandle in the language specified by
Language from the point of view of the driver
specified by This.
@retval EFI_SUCCESS The Unicode string for the user readable name in
the language specified by Language for the
driver specified by This was returned in
DriverName.
@retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
@retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
EFI_HANDLE.
@retval EFI_INVALID_PARAMETER Language is NULL.
@retval EFI_INVALID_PARAMETER ControllerName is NULL.
@retval EFI_UNSUPPORTED The driver specified by This is not currently
managing the controller specified by
ControllerHandle and ChildHandle.
@retval EFI_UNSUPPORTED The driver specified by This does not support
the language specified by Language.
**/
EFI_STATUS
EFIAPI
KeypadComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
{
EFI_STATUS Status;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
//
// This is a device driver, so ChildHandle must be NULL.
//
if (ChildHandle != NULL) {
return EFI_UNSUPPORTED;
}
//
// Check Controller's handle
//
Status = EfiTestManagedDevice (ControllerHandle, gKeypadControllerDriver.DriverBindingHandle, &gEFIDroidKeypadDeviceProtocolGuid);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get the device context
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiSimpleTextInProtocolGuid,
(VOID **) &ConIn,
gKeypadControllerDriver.DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS (ConIn);
return LookupUnicodeString2 (
Language,
This->SupportedLanguages,
ConsoleIn->ControllerNameTable,
ControllerName,
(BOOLEAN)(This == &gKeypadComponentName)
);
}

View File

@ -1,583 +0,0 @@
/** @file
Keypad driver. Routines that interacts with callers,
conforming to EFI driver model
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Keypad.h"
#include <Configuration/BootDevices.h>
//
// Function prototypes
//
/**
Test controller is a keypad Controller.
@param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
@param Controller driver's controller
@param RemainingDevicePath children device path
@retval EFI_UNSUPPORTED controller is not floppy disk
@retval EFI_SUCCESS controller is floppy disk
**/
EFI_STATUS
EFIAPI
KeypadControllerDriverSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Create KEYPAD_CONSOLE_IN_DEV instance on controller.
@param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
@param Controller driver controller handle
@param RemainingDevicePath Children's device path
@retval whether success to create floppy control instance.
**/
EFI_STATUS
EFIAPI
KeypadControllerDriverStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
);
/**
Stop this driver on ControllerHandle. Support stopping any child handles
created by this driver.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to stop driver on
@param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
children is zero stop the entire bus driver.
@param ChildHandleBuffer List of Child Handles to Stop.
@retval EFI_SUCCESS This driver is removed ControllerHandle
@retval other This driver was not removed from this device
**/
EFI_STATUS
EFIAPI
KeypadControllerDriverStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
);
/**
Free the waiting key notify list.
@param ListHead Pointer to list head
@retval EFI_INVALID_PARAMETER ListHead is NULL
@retval EFI_SUCCESS Sucess to free NotifyList
**/
EFI_STATUS
KbdFreeNotifyList (
IN OUT LIST_ENTRY *ListHead
);
//
// DriverBinding Protocol Instance
//
EFI_DRIVER_BINDING_PROTOCOL gKeypadControllerDriver = {
KeypadControllerDriverSupported,
KeypadControllerDriverStart,
KeypadControllerDriverStop,
0xa,
NULL,
NULL
};
/**
Test controller is a keypad Controller.
@param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
@param Controller driver's controller
@param RemainingDevicePath children device path
@retval EFI_UNSUPPORTED controller is not floppy disk
@retval EFI_SUCCESS controller is floppy disk
**/
EFI_STATUS
EFIAPI
KeypadControllerDriverSupported (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
KEYPAD_DEVICE_PROTOCOL *KeypadDevice;
//
// Open the IO Abstraction(s) needed to perform the supported test
//
Status = gBS->OpenProtocol (
Controller,
&gEFIDroidKeypadDeviceProtocolGuid,
(VOID **) &KeypadDevice,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Close the I/O Abstraction(s) used to perform the supported test
//
gBS->CloseProtocol (
Controller,
&gEFIDroidKeypadDeviceProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
}
STATIC
VOID
EFIAPI
KeypadReturnApiPushEfikeyBufTail (
KEYPAD_RETURN_API *This,
EFI_KEY_DATA *KeyData
)
{
KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
LIST_ENTRY *Link;
KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_KEYPAD_RETURN_API (This);
//
// If the key can not be converted then just return.
//
if (KeyData->Key.ScanCode == SCAN_NULL && KeyData->Key.UnicodeChar == CHAR_NULL) {
if (!ConsoleIn->IsSupportPartialKey) {
return;
}
}
//
// Signal KeyNotify process event if this key pressed matches any key registered.
//
for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) {
CurrentNotify = CR (
Link,
KEYPAD_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
//
// The key notification function needs to run at TPL_CALLBACK
// while current TPL is TPL_NOTIFY. It will be invoked in
// KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
//
PushEfikeyBufTail (&ConsoleIn->EfiKeyQueueForNotify, KeyData);
gBS->SignalEvent (ConsoleIn->KeyNotifyProcessEvent);
}
}
PushEfikeyBufTail (&ConsoleIn->EfiKeyQueue, KeyData);
}
/**
Create KEYPAD_CONSOLE_IN_DEV instance on controller.
@param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
@param Controller driver controller handle
@param RemainingDevicePath Children's device path
@retval whether success to create floppy control instance.
**/
EFI_STATUS
EFIAPI
KeypadControllerDriverStart (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
)
{
EFI_STATUS Status;
KEYPAD_DEVICE_PROTOCOL *KeypadDevice;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
//
// Get the ISA I/O Protocol on Controller's handle
//
Status = gBS->OpenProtocol (
Controller,
&gEFIDroidKeypadDeviceProtocolGuid,
(VOID **) &KeypadDevice,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Allocate private data
//
ConsoleIn = AllocateZeroPool (sizeof (KEYPAD_CONSOLE_IN_DEV));
if (ConsoleIn == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
//
// Setup the device instance
//
ConsoleIn->Signature = KEYPAD_CONSOLE_IN_DEV_SIGNATURE;
ConsoleIn->Handle = Controller;
(ConsoleIn->ConIn).Reset = KeypadEfiReset;
(ConsoleIn->ConIn).ReadKeyStroke = KeypadReadKeyStroke;
ConsoleIn->KeypadDevice = KeypadDevice;
ConsoleIn->KeypadReturnApi.PushEfikeyBufTail = KeypadReturnApiPushEfikeyBufTail;
ConsoleIn->Last = (UINT64)-1;
ConsoleIn->ConInEx.Reset = KeypadEfiResetEx;
ConsoleIn->ConInEx.ReadKeyStrokeEx = KeypadReadKeyStrokeEx;
ConsoleIn->ConInEx.SetState = KeypadSetState;
ConsoleIn->ConInEx.RegisterKeyNotify = KeypadRegisterKeyNotify;
ConsoleIn->ConInEx.UnregisterKeyNotify = KeypadUnregisterKeyNotify;
InitializeListHead (&ConsoleIn->NotifyList);
//
// Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
// When KBC decode (IO port 0x60/0x64 decode) is not enabled,
// KeypadRead will read back as 0xFF and return status is EFI_SUCCESS.
// So instead we read status register to detect after read if KBC decode is enabled.
//
//
// Setup the WaitForKey event
//
Status = gBS->CreateEvent (
EVT_NOTIFY_WAIT,
TPL_NOTIFY,
KeypadWaitForKey,
ConsoleIn,
&((ConsoleIn->ConIn).WaitForKey)
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
//
// Setup the WaitForKeyEx event
//
Status = gBS->CreateEvent (
EVT_NOTIFY_WAIT,
TPL_NOTIFY,
KeypadWaitForKeyEx,
ConsoleIn,
&(ConsoleIn->ConInEx.WaitForKeyEx)
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
// Setup a periodic timer, used for reading keystrokes at a fixed interval
//
Status = gBS->CreateEvent (
EVT_TIMER | EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
KeypadTimerHandler,
ConsoleIn,
&ConsoleIn->TimerEvent
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
Status = gBS->SetTimer (
ConsoleIn->TimerEvent,
TimerPeriodic,
KEYPAD_TIMER_INTERVAL
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
Status = gBS->CreateEvent (
EVT_NOTIFY_SIGNAL,
TPL_CALLBACK,
KeyNotifyProcessHandler,
ConsoleIn,
&ConsoleIn->KeyNotifyProcessEvent
);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto ErrorExit;
}
//
// Reset the keypad device
//
Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FALSE);
if (EFI_ERROR (Status)) {
Status = EFI_DEVICE_ERROR;
goto ErrorExit;
}
ConsoleIn->ControllerNameTable = NULL;
AddUnicodeString2 (
"eng",
gKeypadComponentName.SupportedLanguages,
&ConsoleIn->ControllerNameTable,
L"Keypad Device",
TRUE
);
AddUnicodeString2 (
"en",
gKeypadComponentName2.SupportedLanguages,
&ConsoleIn->ControllerNameTable,
L"Keypad Device",
FALSE
);
//
// Install protocol interfaces for the keypad device.
//
Status = gBS->InstallMultipleProtocolInterfaces (
&Controller,
&gEfiSimpleTextInProtocolGuid,
&ConsoleIn->ConIn,
&gEfiSimpleTextInputExProtocolGuid,
&ConsoleIn->ConInEx,
NULL
);
if (EFI_ERROR (Status)) {
goto ErrorExit;
}
return Status;
ErrorExit:
if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {
gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey);
}
if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {
gBS->CloseEvent (ConsoleIn->TimerEvent);
}
if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
}
if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) {
gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
}
KbdFreeNotifyList (&ConsoleIn->NotifyList);
if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
}
if (ConsoleIn != NULL) {
gBS->FreePool (ConsoleIn);
}
gBS->CloseProtocol (
Controller,
&gEFIDroidKeypadDeviceProtocolGuid,
This->DriverBindingHandle,
Controller
);
return Status;
}
/**
Stop this driver on ControllerHandle. Support stopping any child handles
created by this driver.
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to stop driver on
@param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
children is zero stop the entire bus driver.
@param ChildHandleBuffer List of Child Handles to Stop.
@retval EFI_SUCCESS This driver is removed ControllerHandle
@retval other This driver was not removed from this device
**/
EFI_STATUS
EFIAPI
KeypadControllerDriverStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
{
EFI_STATUS Status;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
//
// Disable Keypad
//
Status = gBS->OpenProtocol (
Controller,
&gEfiSimpleTextInProtocolGuid,
(VOID **) &ConIn,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
Status = gBS->OpenProtocol (
Controller,
&gEfiSimpleTextInputExProtocolGuid,
NULL,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS (ConIn);
if (ConsoleIn->TimerEvent != NULL) {
gBS->CloseEvent (ConsoleIn->TimerEvent);
ConsoleIn->TimerEvent = NULL;
}
//
// Uninstall the SimpleTextIn and SimpleTextInEx protocols
//
Status = gBS->UninstallMultipleProtocolInterfaces (
Controller,
&gEfiSimpleTextInProtocolGuid,
&ConsoleIn->ConIn,
&gEfiSimpleTextInputExProtocolGuid,
&ConsoleIn->ConInEx,
NULL
);
if (EFI_ERROR (Status)) {
return Status;
}
gBS->CloseProtocol (
Controller,
&gEFIDroidKeypadDeviceProtocolGuid,
This->DriverBindingHandle,
Controller
);
//
// Free other resources
//
if ((ConsoleIn->ConIn).WaitForKey != NULL) {
gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey);
(ConsoleIn->ConIn).WaitForKey = NULL;
}
if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) {
gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
ConsoleIn->ConInEx.WaitForKeyEx = NULL;
}
if (ConsoleIn->KeyNotifyProcessEvent != NULL) {
gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
ConsoleIn->KeyNotifyProcessEvent = NULL;
}
KbdFreeNotifyList (&ConsoleIn->NotifyList);
FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
gBS->FreePool (ConsoleIn);
return EFI_SUCCESS;
}
/**
Free the waiting key notify list.
@param ListHead Pointer to list head
@retval EFI_INVALID_PARAMETER ListHead is NULL
@retval EFI_SUCCESS Sucess to free NotifyList
**/
EFI_STATUS
KbdFreeNotifyList (
IN OUT LIST_ENTRY *ListHead
)
{
KEYPAD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
if (ListHead == NULL) {
return EFI_INVALID_PARAMETER;
}
while (!IsListEmpty (ListHead)) {
NotifyNode = CR (
ListHead->ForwardLink,
KEYPAD_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
RemoveEntryList (ListHead->ForwardLink);
gBS->FreePool (NotifyNode);
}
return EFI_SUCCESS;
}
/**
The module Entry Point for module Keypad.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
InitializeKeypad(
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
//
// Install driver model protocol(s).
//
Status = EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
&gKeypadControllerDriver,
ImageHandle,
&gKeypadComponentName,
&gKeypadComponentName2
);
ASSERT_EFI_ERROR (Status);
return Status;
}

View File

@ -1,402 +0,0 @@
/** @file
Keypad driver header file
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _KEYPAD_H_
#define _KEYPAD_H_
#include <Uefi.h>
#include <Protocol/SimpleTextIn.h>
#include <Protocol/SimpleTextInEx.h>
#include <Protocol/KeypadDevice.h>
#include <Library/IoLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/TimerLib.h>
#include <Library/PcdLib.h>
//
// Global Variables
//
extern EFI_DRIVER_BINDING_PROTOCOL gKeypadControllerDriver;
extern EFI_COMPONENT_NAME_PROTOCOL gKeypadComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL gKeypadComponentName2;
//
// Driver Private Data
//
#define KEYPAD_CONSOLE_IN_DEV_SIGNATURE SIGNATURE_32 ('k', 'k', 'e', 'y')
#define KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('k', 'c', 'e', 'n')
typedef struct _KEYPAD_CONSOLE_IN_EX_NOTIFY {
UINTN Signature;
EFI_KEY_DATA KeyData;
EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
LIST_ENTRY NotifyEntry;
} KEYPAD_CONSOLE_IN_EX_NOTIFY;
#define KEYPAD_EFI_KEY_MAX_COUNT 256
typedef struct {
EFI_KEY_DATA Buffer[KEYPAD_EFI_KEY_MAX_COUNT];
UINTN Head;
UINTN Tail;
} EFI_KEY_QUEUE;
typedef struct {
UINTN Signature;
EFI_HANDLE Handle;
EFI_SIMPLE_TEXT_INPUT_PROTOCOL ConIn;
EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL ConInEx;
EFI_EVENT TimerEvent;
KEYPAD_DEVICE_PROTOCOL *KeypadDevice;
KEYPAD_RETURN_API KeypadReturnApi;
// counter value of the last poll
UINT64 Last;
BOOLEAN LeftCtrl;
BOOLEAN RightCtrl;
BOOLEAN LeftAlt;
BOOLEAN RightAlt;
BOOLEAN LeftShift;
BOOLEAN RightShift;
BOOLEAN LeftLogo;
BOOLEAN RightLogo;
BOOLEAN Menu;
BOOLEAN SysReq;
BOOLEAN CapsLock;
BOOLEAN NumLock;
BOOLEAN ScrollLock;
BOOLEAN IsSupportPartialKey;
//
// Queue storing key scancodes
//
EFI_KEY_QUEUE EfiKeyQueue;
EFI_KEY_QUEUE EfiKeyQueueForNotify;
//
// Error state
//
BOOLEAN KeypadErr;
EFI_UNICODE_STRING_TABLE *ControllerNameTable;
//
// Notification Function List
//
LIST_ENTRY NotifyList;
EFI_EVENT KeyNotifyProcessEvent;
} KEYPAD_CONSOLE_IN_DEV;
#define KEYPAD_CONSOLE_IN_DEV_FROM_KEYPAD_RETURN_API(a) CR (a, KEYPAD_CONSOLE_IN_DEV, KeypadReturnApi, KEYPAD_CONSOLE_IN_DEV_SIGNATURE)
#define KEYPAD_CONSOLE_IN_DEV_FROM_THIS(a) CR (a, KEYPAD_CONSOLE_IN_DEV, ConIn, KEYPAD_CONSOLE_IN_DEV_SIGNATURE)
#define TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS(a) \
CR (a, \
KEYPAD_CONSOLE_IN_DEV, \
ConInEx, \
KEYPAD_CONSOLE_IN_DEV_SIGNATURE \
)
#define TABLE_END 0x0
#define KEYPAD_TIMER_INTERVAL 200000 // 0.02s
//
// Driver entry point
//
/**
The user Entry Point for module KeypadDxe. The user code starts with this function.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The entry point is executed successfully.
@retval other Some error occurs when executing this entry point.
**/
EFI_STATUS
EFIAPI
InstallKeypadDriver (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
//
// Other functions that are used among .c files
//
/**
Process key notify.
@param Event Indicates the event that invoke this function.
@param Context Indicates the calling context.
**/
VOID
EFIAPI
KeyNotifyProcessHandler (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Perform 8042 controller and keypad Initialization.
If ExtendedVerification is TRUE, do additional test for
the keypad interface
@param ConsoleIn - KEYPAD_CONSOLE_IN_DEV instance pointer
@param ExtendedVerification - indicates a thorough initialization
@retval EFI_DEVICE_ERROR Fail to init keypad
@retval EFI_SUCCESS Success to init keypad
**/
EFI_STATUS
InitKeypad (
IN OUT KEYPAD_CONSOLE_IN_DEV *ConsoleIn,
IN BOOLEAN ExtendedVerification
);
/**
Timer event handler: read a series of scancodes from 8042
and put them into memory scancode buffer.
it read as much scancodes to either fill
the memory buffer or empty the keypad buffer.
It is registered as running under TPL_NOTIFY
@param Event - The timer event
@param Context - A KEYPAD_CONSOLE_IN_DEV pointer
**/
VOID
EFIAPI
KeypadTimerHandler (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
logic reset keypad
Implement SIMPLE_TEXT_IN.Reset()
Perform 8042 controller and keypad initialization
@param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
@param ExtendedVerification Indicate that the driver may perform a more
exhaustive verification operation of the device during
reset, now this par is ignored in this driver
**/
EFI_STATUS
EFIAPI
KeypadEfiReset (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
/**
Implement SIMPLE_TEXT_IN.ReadKeyStroke().
Retrieve key values for driver user.
@param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
@param Key The output buffer for key value
@retval EFI_SUCCESS success to read key stroke
**/
EFI_STATUS
EFIAPI
KeypadReadKeyStroke (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key
);
/**
Event notification function for SIMPLE_TEXT_IN.WaitForKey event
Signal the event if there is key available
@param Event the event object
@param Context waitting context
**/
VOID
EFIAPI
KeypadWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
);
/**
Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
Signal the event if there is key available
@param Event event object
@param Context waiting context
**/
VOID
EFIAPI
KeypadWaitForKeyEx (
IN EFI_EVENT Event,
IN VOID *Context
);
//
// Simple Text Input Ex protocol function prototypes
//
/**
Reset the input device and optionaly run diagnostics
@param This - Protocol instance pointer.
@param ExtendedVerification - Driver may perform diagnostics on reset.
@retval EFI_SUCCESS - The device was reset.
@retval EFI_DEVICE_ERROR - The device is not functioning properly and could
not be reset.
**/
EFI_STATUS
EFIAPI
KeypadEfiResetEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
);
/**
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
@param This - Protocol instance pointer.
@param KeyData - A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
@retval EFI_SUCCESS - The keystroke information was returned.
@retval EFI_NOT_READY - There was no keystroke data availiable.
@retval EFI_DEVICE_ERROR - The keystroke information was not returned due to
hardware errors.
@retval EFI_INVALID_PARAMETER - KeyData is NULL.
**/
EFI_STATUS
EFIAPI
KeypadReadKeyStrokeEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
OUT EFI_KEY_DATA *KeyData
);
/**
Set certain state for the input device.
@param This - Protocol instance pointer.
@param KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
state for the input device.
@retval EFI_SUCCESS - The device state was set successfully.
@retval EFI_DEVICE_ERROR - The device is not functioning correctly and could
not have the setting adjusted.
@retval EFI_UNSUPPORTED - The device does not have the ability to set its state.
@retval EFI_INVALID_PARAMETER - KeyToggleState is NULL.
**/
EFI_STATUS
EFIAPI
KeypadSetState (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
);
/**
Register a notification function for a particular keystroke for the input device.
@param This - Protocol instance pointer.
@param KeyData - A pointer to a buffer that is filled in with the keystroke
information data for the key that was pressed.
@param KeyNotificationFunction - Points to the function to be called when the key
sequence is typed specified by KeyData.
@param NotifyHandle - Points to the unique handle assigned to the registered notification.
@retval EFI_SUCCESS - The notification function was registered successfully.
@retval EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures.
@retval EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
**/
EFI_STATUS
EFIAPI
KeypadRegisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
OUT VOID **NotifyHandle
);
/**
Remove a registered notification function from a particular keystroke.
@param This - Protocol instance pointer.
@param NotificationHandle - The handle of the notification function being unregistered.
@retval EFI_SUCCESS - The notification function was unregistered successfully.
@retval EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
@retval EFI_NOT_FOUND - Can not find the matching entry in database.
**/
EFI_STATUS
EFIAPI
KeypadUnregisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN VOID *NotificationHandle
);
/**
Push one key data to the EFI key buffer.
@param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData The key data to push.
**/
VOID
PushEfikeyBufTail (
IN EFI_KEY_QUEUE *Queue,
IN EFI_KEY_DATA *KeyData
);
/**
Judge whether is a registed key
@param RegsiteredData A pointer to a buffer that is filled in with the keystroke
state data for the key that was registered.
@param InputData A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
@retval TRUE Key be pressed matches a registered key.
@retval FLASE Match failed.
**/
BOOLEAN
IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
);
#endif

View File

@ -1,138 +0,0 @@
/** @file
Routines that talk to the KeypadDevice protocol
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Keypad.h"
/**
Display error message.
@param ConsoleIn Pointer to instance of KEYPAD_CONSOLE_IN_DEV
@param ErrMsg Unicode string of error message
**/
VOID
KeypadError (
IN KEYPAD_CONSOLE_IN_DEV *ConsoleIn,
IN CHAR16 *ErrMsg
)
{
ConsoleIn->KeypadErr = TRUE;
}
/**
Timer event handler: read a series of scancodes from 8042
and put them into memory scancode buffer.
it read as much scancodes to either fill
the memory buffer or empty the keypad buffer.
It is registered as running under TPL_NOTIFY
@param Event The timer event
@param Context A KEYPAD_CONSOLE_IN_DEV pointer
**/
VOID
EFIAPI
KeypadTimerHandler (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_TPL OldTpl;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
ConsoleIn = (KEYPAD_CONSOLE_IN_DEV *) Context;
//
// Enter critical section
//
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
if (((KEYPAD_CONSOLE_IN_DEV *) Context)->KeypadErr) {
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
return ;
}
UINT64 CurrentCounterValue = GetPerformanceCounter();
UINT64 DeltaCounter = CurrentCounterValue - ConsoleIn->Last;
ConsoleIn->Last = CurrentCounterValue;
ConsoleIn->KeypadDevice->GetKeys(ConsoleIn->KeypadDevice, &ConsoleIn->KeypadReturnApi, GetTimeInNanoSecond(DeltaCounter));
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
}
/**
Perform 8042 controller and keypad Initialization.
If ExtendedVerification is TRUE, do additional test for
the keypad interface
@param ConsoleIn - KEYPAD_CONSOLE_IN_DEV instance pointer
@param ExtendedVerification - indicates a thorough initialization
@retval EFI_DEVICE_ERROR Fail to init keypad
@retval EFI_SUCCESS Success to init keypad
**/
EFI_STATUS
InitKeypad (
IN OUT KEYPAD_CONSOLE_IN_DEV *ConsoleIn,
IN BOOLEAN ExtendedVerification
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
ConsoleIn->KeypadDevice->Reset(ConsoleIn->KeypadDevice);
//
// Clear Memory Scancode Buffer
//
ConsoleIn->EfiKeyQueue.Head = 0;
ConsoleIn->EfiKeyQueue.Tail = 0;
ConsoleIn->EfiKeyQueueForNotify.Head = 0;
ConsoleIn->EfiKeyQueueForNotify.Tail = 0;
//
// Reset the status indicators
//
ConsoleIn->CapsLock = FALSE;
ConsoleIn->NumLock = FALSE;
ConsoleIn->ScrollLock = FALSE;
ConsoleIn->LeftCtrl = FALSE;
ConsoleIn->RightCtrl = FALSE;
ConsoleIn->LeftAlt = FALSE;
ConsoleIn->RightAlt = FALSE;
ConsoleIn->LeftShift = FALSE;
ConsoleIn->RightShift = FALSE;
ConsoleIn->LeftLogo = FALSE;
ConsoleIn->RightLogo = FALSE;
ConsoleIn->Menu = FALSE;
ConsoleIn->SysReq = FALSE;
ConsoleIn->IsSupportPartialKey = FALSE;
if (!EFI_ERROR (Status)) {
return EFI_SUCCESS;
} else {
return EFI_DEVICE_ERROR;
}
}

View File

@ -1,57 +0,0 @@
## @file
# Keypad Driver.
#
# Keypad Driver for UEFI. The keypad type implemented follows IBM
# compatible PS2 protocol using Scan Code Set 1.
#
# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = KeypadDxe
FILE_GUID = 463C9415-765B-4AE8-9B1A-AA5C6ECB2892
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializeKeypad
[Sources]
ComponentName.c
Keypad.h
KeypadController.c
KeypadTextIn.c
Keypad.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
MSM8916Pkg/MSM8916Pkg.dec
[LibraryClasses]
MemoryAllocationLib
UefiRuntimeServicesTableLib
DebugLib
DevicePathLib
UefiBootServicesTableLib
UefiLib
UefiDriverEntryPoint
BaseLib
BaseMemoryLib
TimerLib
PcdLib
IoLib
[Protocols]
gEfiSimpleTextInProtocolGuid ## BY_START
gEfiSimpleTextInputExProtocolGuid ## BY_START
gEFIDroidKeypadDeviceProtocolGuid

View File

@ -1,700 +0,0 @@
/** @file
Routines implements SIMPLE_TEXT_IN protocol's interfaces based on interfaces
provided by KeypadController.c.
Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "Keypad.h"
/**
Check whether the EFI key buffer is empty.
@param Queue Pointer to instance of EFI_KEY_QUEUE.
@retval TRUE The EFI key buffer is empty.
@retval FALSE The EFI key buffer isn't empty.
**/
BOOLEAN
IsEfikeyBufEmpty (
IN EFI_KEY_QUEUE *Queue
)
{
return (BOOLEAN) (Queue->Head == Queue->Tail);
}
/**
Read & remove one key data from the EFI key buffer.
@param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData Receive the key data.
@retval EFI_SUCCESS The key data is popped successfully.
@retval EFI_NOT_READY There is no key data available.
**/
EFI_STATUS
PopEfikeyBufHead (
IN EFI_KEY_QUEUE *Queue,
OUT EFI_KEY_DATA *KeyData OPTIONAL
)
{
if (IsEfikeyBufEmpty (Queue)) {
return EFI_NOT_READY;
}
//
// Retrieve and remove the values
//
if (KeyData != NULL) {
CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));
}
Queue->Head = (Queue->Head + 1) % KEYPAD_EFI_KEY_MAX_COUNT;
return EFI_SUCCESS;
}
/**
Push one key data to the EFI key buffer.
@param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData The key data to push.
**/
VOID
PushEfikeyBufTail (
IN EFI_KEY_QUEUE *Queue,
IN EFI_KEY_DATA *KeyData
)
{
if ((Queue->Tail + 1) % KEYPAD_EFI_KEY_MAX_COUNT == Queue->Head) {
//
// If Queue is full, pop the one from head.
//
PopEfikeyBufHead (Queue, NULL);
}
CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));
Queue->Tail = (Queue->Tail + 1) % KEYPAD_EFI_KEY_MAX_COUNT;
}
/**
Judge whether is a registed key
@param RegsiteredData A pointer to a buffer that is filled in with the keystroke
state data for the key that was registered.
@param InputData A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
@retval TRUE Key be pressed matches a registered key.
@retval FLASE Match failed.
**/
BOOLEAN
IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
)
{
ASSERT (RegsiteredData != NULL && InputData != NULL);
if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
(RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
return FALSE;
}
//
// Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
//
if (RegsiteredData->KeyState.KeyShiftState != 0 &&
RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {
return FALSE;
}
if (RegsiteredData->KeyState.KeyToggleState != 0 &&
RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {
return FALSE;
}
return TRUE;
}
/**
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
@param ConsoleInDev Keypad private structure
@param KeyData A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
@retval EFI_SUCCESS The keystroke information was returned.
@retval EFI_NOT_READY There was no keystroke data availiable.
@retval EFI_DEVICE_ERROR The keystroke information was not returned due to
hardware errors.
@retval EFI_INVALID_PARAMETER KeyData is NULL.
**/
EFI_STATUS
KeypadReadKeyStrokeWorker (
IN KEYPAD_CONSOLE_IN_DEV *ConsoleInDev,
OUT EFI_KEY_DATA *KeyData
)
{
EFI_STATUS Status;
EFI_TPL OldTpl;
if (KeyData == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Enter critical section
//
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
KeypadTimerHandler (NULL, ConsoleInDev);
if (ConsoleInDev->KeypadErr) {
Status = EFI_DEVICE_ERROR;
} else {
Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);
}
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Perform 8042 controller and keypad initialization which implement SIMPLE_TEXT_IN.Reset()
@param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
@param ExtendedVerification Indicate that the driver may perform a more
exhaustive verification operation of the device during
reset, now this par is ignored in this driver
**/
EFI_STATUS
EFIAPI
KeypadEfiReset (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
EFI_TPL OldTpl;
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This);
if (ConsoleIn->KeypadErr) {
return EFI_DEVICE_ERROR;
}
//
// Enter critical section
//
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
//
// Call InitKeypad to initialize the keypad
//
Status = InitKeypad (ConsoleIn, ExtendedVerification);
if (EFI_ERROR (Status)) {
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
return EFI_DEVICE_ERROR;
}
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
}
/**
Retrieve key values for driver user which implement SIMPLE_TEXT_IN.ReadKeyStroke().
@param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
@param Key The output buffer for key value
@retval EFI_SUCCESS success to read key stroke
**/
EFI_STATUS
EFIAPI
KeypadReadKeyStroke (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
OUT EFI_INPUT_KEY *Key
)
{
EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
EFI_KEY_DATA KeyData;
ConsoleIn = KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This);
//
// Considering if the partial keystroke is enabled, there maybe a partial
// keystroke in the queue, so here skip the partial keystroke and get the
// next key from the queue
//
while (1) {
//
// If there is no pending key, then return.
//
Status = KeypadReadKeyStrokeWorker (ConsoleIn, &KeyData);
if (EFI_ERROR (Status)) {
return Status;
}
//
// If it is partial keystroke, skip it.
//
if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
continue;
}
//
// Translate the CTRL-Alpha characters to their corresponding control value
// (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
//
if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {
KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1);
} else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {
KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1);
}
}
CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
return EFI_SUCCESS;
}
}
/**
Event notification function for SIMPLE_TEXT_IN.WaitForKey event
Signal the event if there is key available
@param Event the event object
@param Context waitting context
**/
VOID
EFIAPI
KeypadWaitForKey (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_TPL OldTpl;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
EFI_KEY_DATA KeyData;
ConsoleIn = (KEYPAD_CONSOLE_IN_DEV *) Context;
//
// Enter critical section
//
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
KeypadTimerHandler (NULL, ConsoleIn);
if (!ConsoleIn->KeypadErr) {
//
// WaitforKey doesn't suppor the partial key.
// Considering if the partial keystroke is enabled, there maybe a partial
// keystroke in the queue, so here skip the partial keystroke and get the
// next key from the queue
//
while (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {
CopyMem (
&KeyData,
&(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),
sizeof (EFI_KEY_DATA)
);
if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData);
continue;
}
//
// if there is pending value key, signal the event.
//
gBS->SignalEvent (Event);
break;
}
}
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
}
/**
Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
Signal the event if there is key available
@param Event event object
@param Context waiting context
**/
VOID
EFIAPI
KeypadWaitForKeyEx (
IN EFI_EVENT Event,
IN VOID *Context
)
{
KeypadWaitForKey (Event, Context);
}
/**
Reset the input device and optionaly run diagnostics
@param This Protocol instance pointer.
@param ExtendedVerification Driver may perform diagnostics on reset.
@retval EFI_SUCCESS The device was reset.
@retval EFI_DEVICE_ERROR The device is not functioning properly and could
not be reset.
**/
EFI_STATUS
EFIAPI
KeypadEfiResetEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
{
KEYPAD_CONSOLE_IN_DEV *ConsoleInDev;
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This);
return ConsoleInDev->ConIn.Reset (
&ConsoleInDev->ConIn,
ExtendedVerification
);
}
/**
Reads the next keystroke from the input device. The WaitForKey Event can
be used to test for existance of a keystroke via WaitForEvent () call.
@param This Protocol instance pointer.
@param KeyData A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
@retval EFI_SUCCESS The keystroke information was returned.
@retval EFI_NOT_READY There was no keystroke data availiable.
@retval EFI_DEVICE_ERROR The keystroke information was not returned due to
hardware errors.
@retval EFI_INVALID_PARAMETER KeyData is NULL.
**/
EFI_STATUS
EFIAPI
KeypadReadKeyStrokeEx (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
OUT EFI_KEY_DATA *KeyData
)
{
KEYPAD_CONSOLE_IN_DEV *ConsoleInDev;
if (KeyData == NULL) {
return EFI_INVALID_PARAMETER;
}
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This);
return KeypadReadKeyStrokeWorker (ConsoleInDev, KeyData);
}
/**
Set certain state for the input device.
@param This Protocol instance pointer.
@param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
state for the input device.
@retval EFI_SUCCESS The device state was set successfully.
@retval EFI_DEVICE_ERROR The device is not functioning correctly and could
not have the setting adjusted.
@retval EFI_UNSUPPORTED The device does not have the ability to set its state.
@retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
**/
EFI_STATUS
EFIAPI
KeypadSetState (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_TOGGLE_STATE *KeyToggleState
)
{
EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleInDev;
EFI_TPL OldTpl;
if (KeyToggleState == NULL) {
return EFI_INVALID_PARAMETER;
}
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This);
//
// Enter critical section
//
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
if (ConsoleInDev->KeypadErr) {
Status = EFI_DEVICE_ERROR;
goto Exit;
}
if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
Status = EFI_UNSUPPORTED;
goto Exit;
}
//
// Update the status light
//
ConsoleInDev->ScrollLock = FALSE;
ConsoleInDev->NumLock = FALSE;
ConsoleInDev->CapsLock = FALSE;
ConsoleInDev->IsSupportPartialKey = FALSE;
if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
ConsoleInDev->ScrollLock = TRUE;
}
if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
ConsoleInDev->NumLock = TRUE;
}
if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
ConsoleInDev->CapsLock = TRUE;
}
if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {
ConsoleInDev->IsSupportPartialKey = TRUE;
}
Exit:
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Register a notification function for a particular keystroke for the input device.
@param This Protocol instance pointer.
@param KeyData A pointer to a buffer that is filled in with the keystroke
information data for the key that was pressed.
@param KeyNotificationFunction Points to the function to be called when the key
sequence is typed specified by KeyData.
@param NotifyHandle Points to the unique handle assigned to the registered notification.
@retval EFI_SUCCESS The notification function was registered successfully.
@retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.
@retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL.
**/
EFI_STATUS
EFIAPI
KeypadRegisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN EFI_KEY_DATA *KeyData,
IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
OUT VOID **NotifyHandle
)
{
EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleInDev;
EFI_TPL OldTpl;
LIST_ENTRY *Link;
KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
KEYPAD_CONSOLE_IN_EX_NOTIFY *NewNotify;
if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
return EFI_INVALID_PARAMETER;
}
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This);
//
// Enter critical section
//
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
//
// Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
//
for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
CurrentNotify = CR (
Link,
KEYPAD_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
*NotifyHandle = CurrentNotify;
Status = EFI_SUCCESS;
goto Exit;
}
}
}
//
// Allocate resource to save the notification function
//
NewNotify = (KEYPAD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYPAD_CONSOLE_IN_EX_NOTIFY));
if (NewNotify == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Exit;
}
NewNotify->Signature = KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
NewNotify->KeyNotificationFn = KeyNotificationFunction;
CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);
*NotifyHandle = NewNotify;
Status = EFI_SUCCESS;
Exit:
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Remove a registered notification function from a particular keystroke.
@param This Protocol instance pointer.
@param NotificationHandle The handle of the notification function being unregistered.
@retval EFI_SUCCESS The notification function was unregistered successfully.
@retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
**/
EFI_STATUS
EFIAPI
KeypadUnregisterKeyNotify (
IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
IN VOID *NotificationHandle
)
{
EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleInDev;
EFI_TPL OldTpl;
LIST_ENTRY *Link;
KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
if (NotificationHandle == NULL) {
return EFI_INVALID_PARAMETER;
}
ConsoleInDev = TEXT_INPUT_EX_KEYPAD_CONSOLE_IN_DEV_FROM_THIS (This);
//
// Enter critical section
//
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
CurrentNotify = CR (
Link,
KEYPAD_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (CurrentNotify == NotificationHandle) {
//
// Remove the notification function from NotifyList and free resources
//
RemoveEntryList (&CurrentNotify->NotifyEntry);
gBS->FreePool (CurrentNotify);
Status = EFI_SUCCESS;
goto Exit;
}
}
//
// Can not find the specified Notification Handle
//
Status = EFI_INVALID_PARAMETER;
Exit:
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
return Status;
}
/**
Process key notify.
@param Event Indicates the event that invoke this function.
@param Context Indicates the calling context.
**/
VOID
EFIAPI
KeyNotifyProcessHandler (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
KEYPAD_CONSOLE_IN_DEV *ConsoleIn;
EFI_KEY_DATA KeyData;
LIST_ENTRY *Link;
LIST_ENTRY *NotifyList;
KEYPAD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
EFI_TPL OldTpl;
ConsoleIn = (KEYPAD_CONSOLE_IN_DEV *) Context;
//
// Invoke notification functions.
//
NotifyList = &ConsoleIn->NotifyList;
while (TRUE) {
//
// Enter critical section
//
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
Status = PopEfikeyBufHead (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);
//
// Leave critical section
//
gBS->RestoreTPL (OldTpl);
if (EFI_ERROR (Status)) {
break;
}
for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
CurrentNotify = CR (Link, KEYPAD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, KEYPAD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
CurrentNotify->KeyNotificationFn (&KeyData);
}
}
}
}

View File

@ -1,2 +0,0 @@
URL: https://github.com/tianocore/edk2/tree/master/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe
BRANCH: master @ 35dadd7c54

View File

@ -43,5 +43,5 @@
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferWidth|720|UINT32|0x0000a401
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferHeight|1520|UINT32|0x0000a402
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferPixelBpp|32|UINT32|0x0000a403
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleWidth|720|UINT32|0x0000a404
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleHeight|1520|UINT32|0x0000a405
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleWidth|1080|UINT32|0x0000a404
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleHeight|1920|UINT32|0x0000a405

View File

@ -82,7 +82,7 @@
PlatformPeiLib|MSM8916Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
# SoC Drivers
QcomPlatformClockInitLib|MSM8916Pkg/Library/QcomPlatformClockInitLib/QcomPlatformClockInitLib.inf
# QcomPlatformClockInitLib|MSM8916Pkg/Library/QcomPlatformClockInitLib/QcomPlatformClockInitLib.inf
[LibraryClasses.common.SEC]
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
@ -91,21 +91,6 @@
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
# SoC Drivers
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockImplLib.inf
[LibraryClasses.common.DXE_DRIVER]
# SoC Drivers
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
[LibraryClasses.common.UEFI_APPLICATION]
# SoC Drivers
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
[LibraryClasses.common.UEFI_DRIVER]
# SoC Drivers
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
################################################################################
#
@ -131,8 +116,8 @@
#
# ARM General Interrupt Controller
#
gArmTokenSpaceGuid.PcdGicDistributorBase|0x0b000000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x0b002000
gArmTokenSpaceGuid.PcdGicDistributorBase|0x123001000
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x123001000
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x12
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x13
@ -211,8 +196,8 @@
# SoC Drivers
#
MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
# MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
# MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
#
# Virtual Keyboard

View File

@ -153,11 +153,6 @@ READ_LOCK_STATUS = TRUE
INF MSM8916Pkg/Drivers/MSM8916PkgDxe/MSM8916PkgDxe.inf
INF MSM8916Pkg/Drivers/SimpleFbDxe/SimpleFbDxe.inf
#
# SoC Drivers
#
INF MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
INF MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
#
# USB Host Support

BIN
boot.img

Binary file not shown.