aaaaaaaaaaaaaaaaaaaaaaaa
This commit is contained in:
parent
77f7c07180
commit
5d995b114c
@ -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
|
|
@ -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;
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
URL: https://source.codeaurora.org/quic/la/kernel/lk
|
|
||||||
BRANCH: LA.AF.1.1-02810-8064.0
|
|
@ -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;
|
|
||||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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
|
|
@ -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.
|
|
||||||
*/
|
|
||||||
}
|
|
@ -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
|
|
@ -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);
|
|
||||||
}
|
|
@ -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
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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
|
|
@ -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)
|
|
||||||
);
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -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
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
|||||||
URL: https://github.com/tianocore/edk2/tree/master/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe
|
|
||||||
BRANCH: master @ 35dadd7c54
|
|
@ -43,5 +43,5 @@
|
|||||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferWidth|720|UINT32|0x0000a401
|
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferWidth|720|UINT32|0x0000a401
|
||||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferHeight|1520|UINT32|0x0000a402
|
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferHeight|1520|UINT32|0x0000a402
|
||||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferPixelBpp|32|UINT32|0x0000a403
|
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferPixelBpp|32|UINT32|0x0000a403
|
||||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleWidth|720|UINT32|0x0000a404
|
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleWidth|1080|UINT32|0x0000a404
|
||||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleHeight|1520|UINT32|0x0000a405
|
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleHeight|1920|UINT32|0x0000a405
|
||||||
|
@ -82,7 +82,7 @@
|
|||||||
PlatformPeiLib|MSM8916Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
|
PlatformPeiLib|MSM8916Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
|
||||||
|
|
||||||
# SoC Drivers
|
# SoC Drivers
|
||||||
QcomPlatformClockInitLib|MSM8916Pkg/Library/QcomPlatformClockInitLib/QcomPlatformClockInitLib.inf
|
# QcomPlatformClockInitLib|MSM8916Pkg/Library/QcomPlatformClockInitLib/QcomPlatformClockInitLib.inf
|
||||||
|
|
||||||
[LibraryClasses.common.SEC]
|
[LibraryClasses.common.SEC]
|
||||||
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
|
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
|
||||||
@ -91,21 +91,6 @@
|
|||||||
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
|
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
|
||||||
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.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
|
# ARM General Interrupt Controller
|
||||||
#
|
#
|
||||||
gArmTokenSpaceGuid.PcdGicDistributorBase|0x0b000000
|
gArmTokenSpaceGuid.PcdGicDistributorBase|0x123001000
|
||||||
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x0b002000
|
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x123001000
|
||||||
|
|
||||||
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x12
|
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x12
|
||||||
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x13
|
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x13
|
||||||
@ -211,8 +196,8 @@
|
|||||||
# SoC Drivers
|
# SoC Drivers
|
||||||
#
|
#
|
||||||
|
|
||||||
MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
# MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
||||||
MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
|
# MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# Virtual Keyboard
|
# Virtual Keyboard
|
||||||
|
@ -153,11 +153,6 @@ READ_LOCK_STATUS = TRUE
|
|||||||
INF MSM8916Pkg/Drivers/MSM8916PkgDxe/MSM8916PkgDxe.inf
|
INF MSM8916Pkg/Drivers/MSM8916PkgDxe/MSM8916PkgDxe.inf
|
||||||
INF MSM8916Pkg/Drivers/SimpleFbDxe/SimpleFbDxe.inf
|
INF MSM8916Pkg/Drivers/SimpleFbDxe/SimpleFbDxe.inf
|
||||||
|
|
||||||
#
|
|
||||||
# SoC Drivers
|
|
||||||
#
|
|
||||||
INF MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
|
||||||
INF MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# USB Host Support
|
# USB Host Support
|
||||||
|
Loading…
Reference in New Issue
Block a user