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.PcdMipiFrameBufferHeight|1520|UINT32|0x0000a402
|
||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferPixelBpp|32|UINT32|0x0000a403
|
||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleWidth|720|UINT32|0x0000a404
|
||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleHeight|1520|UINT32|0x0000a405
|
||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleWidth|1080|UINT32|0x0000a404
|
||||
gMSM8916PkgTokenSpaceGuid.PcdMipiFrameBufferVisibleHeight|1920|UINT32|0x0000a405
|
||||
|
@ -82,7 +82,7 @@
|
||||
PlatformPeiLib|MSM8916Pkg/Library/PlatformPeiLib/PlatformPeiLib.inf
|
||||
|
||||
# SoC Drivers
|
||||
QcomPlatformClockInitLib|MSM8916Pkg/Library/QcomPlatformClockInitLib/QcomPlatformClockInitLib.inf
|
||||
# QcomPlatformClockInitLib|MSM8916Pkg/Library/QcomPlatformClockInitLib/QcomPlatformClockInitLib.inf
|
||||
|
||||
[LibraryClasses.common.SEC]
|
||||
PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
|
||||
@ -91,21 +91,6 @@
|
||||
MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
|
||||
PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
|
||||
|
||||
# SoC Drivers
|
||||
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockImplLib.inf
|
||||
|
||||
[LibraryClasses.common.DXE_DRIVER]
|
||||
# SoC Drivers
|
||||
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
|
||||
|
||||
[LibraryClasses.common.UEFI_APPLICATION]
|
||||
# SoC Drivers
|
||||
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
|
||||
|
||||
[LibraryClasses.common.UEFI_DRIVER]
|
||||
# SoC Drivers
|
||||
ClockLib|MSM8916Pkg/Drivers/ClockDxe/ClockLib.inf
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
@ -131,8 +116,8 @@
|
||||
#
|
||||
# ARM General Interrupt Controller
|
||||
#
|
||||
gArmTokenSpaceGuid.PcdGicDistributorBase|0x0b000000
|
||||
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x0b002000
|
||||
gArmTokenSpaceGuid.PcdGicDistributorBase|0x123001000
|
||||
gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x123001000
|
||||
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerIntrNum|0x12
|
||||
gArmTokenSpaceGuid.PcdArmArchTimerVirtIntrNum|0x13
|
||||
@ -211,8 +196,8 @@
|
||||
# SoC Drivers
|
||||
#
|
||||
|
||||
MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
||||
MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
|
||||
# MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
||||
# MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
|
||||
|
||||
#
|
||||
# Virtual Keyboard
|
||||
|
@ -153,11 +153,6 @@ READ_LOCK_STATUS = TRUE
|
||||
INF MSM8916Pkg/Drivers/MSM8916PkgDxe/MSM8916PkgDxe.inf
|
||||
INF MSM8916Pkg/Drivers/SimpleFbDxe/SimpleFbDxe.inf
|
||||
|
||||
#
|
||||
# SoC Drivers
|
||||
#
|
||||
INF MSM8916Pkg/Drivers/ClockDxe/ClockDxe.inf
|
||||
INF MSM8916Pkg/Drivers/BamDxe/BamDxe.inf
|
||||
|
||||
#
|
||||
# USB Host Support
|
||||
|
Loading…
Reference in New Issue
Block a user