1337 lines
52 KiB
C
1337 lines
52 KiB
C
/** @file
|
|
Touch Host Controller Driver API
|
|
|
|
@copyright
|
|
INTEL CONFIDENTIAL
|
|
Copyright 2018 - 2021 Intel Corporation.
|
|
|
|
The source code contained or described herein and all documents related to the
|
|
source code ("Material") are owned by Intel Corporation or its suppliers or
|
|
licensors. Title to the Material remains with Intel Corporation or its suppliers
|
|
and licensors. The Material may contain trade secrets and proprietary and
|
|
confidential information of Intel Corporation and its suppliers and licensors,
|
|
and is protected by worldwide copyright and trade secret laws and treaty
|
|
provisions. No part of the Material may be used, copied, reproduced, modified,
|
|
published, uploaded, posted, transmitted, distributed, or disclosed in any way
|
|
without Intel's prior express written permission.
|
|
|
|
No license under any patent, copyright, trade secret or other intellectual
|
|
property right is granted to or conferred upon you by disclosure or delivery
|
|
of the Materials, either expressly, by implication, inducement, estoppel or
|
|
otherwise. Any license under such intellectual property rights must be
|
|
express and approved by Intel in writing.
|
|
|
|
Unless otherwise agreed by Intel in writing, you may not remove or alter
|
|
this notice or any other notice embedded in Materials by Intel or
|
|
Intel's suppliers or licensors in any way.
|
|
|
|
This file contains an 'Intel Peripheral Driver' and is uniquely identified as
|
|
"Intel Reference Module" and is licensed for Intel CPUs and chipsets under
|
|
the terms of your license agreement with Intel or your vendor. This file may
|
|
be modified by the user, subject to additional terms of the license agreement.
|
|
|
|
@par Specification Reference:
|
|
**/
|
|
|
|
#include "ThcLibPrivate.h"
|
|
#include "ThcAbsPtr.h"
|
|
#include "ThcHid.h"
|
|
#include <Library/PchInfoLib.h>
|
|
|
|
|
|
/**
|
|
Sets Frequency based on Touch Capabilities MAX_SPI_FREQUENCY_SUPPORTED accordingly to EDS
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Thc frequency set successfuly
|
|
@retval EFI_DEVICE_ERROR Error during frequency mapping with EDS
|
|
**/
|
|
EFI_STATUS
|
|
ThcSetFrequency (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
UINT32 MaxFrequency;
|
|
UINT32 NewFrequency;
|
|
|
|
NewFrequency = ThcFreqInvalid;
|
|
MaxFrequency = ThcDev->DeviceRegisters.TouchCapabilities.Fields.MaxSpiFrequencySupported;
|
|
|
|
//
|
|
// Map Frequency to match THC and EDS
|
|
//
|
|
if (MaxFrequency == ThcEdsFreq7p812MHz) {
|
|
NewFrequency = ThcFreqLow7p5MHz;
|
|
} else if (MaxFrequency == ThcEdsFreq15p62MHz) {
|
|
NewFrequency = ThcFreqLow15MHz;
|
|
} else if (MaxFrequency == ThcEdsFreq17p86MHz) {
|
|
NewFrequency = ThcFreqHigh17MHz;
|
|
} else if (MaxFrequency == ThcEdsFreq20p83MHz) {
|
|
NewFrequency = ThcFreqHigh20MHz;
|
|
} else if (MaxFrequency == ThcEdsFreq25MHz) {
|
|
NewFrequency = ThcFreqHigh24MHz;
|
|
} else if (MaxFrequency == ThcEdsFreq31p25MHz) {
|
|
NewFrequency = ThcFreqHigh30MHz;
|
|
} else if (MaxFrequency == ThcEdsFreq41p67MHz) {
|
|
NewFrequency = ThcFreqHigh40MHz;
|
|
}
|
|
|
|
if (NewFrequency == ThcFreqInvalid) {
|
|
DEBUG ((DEBUG_ERROR, "ThcSetFrequency error Max Device Frequency does not meet EDS specification:%d\n", MaxFrequency));
|
|
return EFI_DEVICE_ERROR;
|
|
}
|
|
|
|
ThcLibSetPortFrequency (ThcDev->PciBar0, N_THC_MEM_PORT_SPI_CONFIG_READ_FREQUENCY, NewFrequency);
|
|
ThcLibSetPortFrequency (ThcDev->PciBar0, N_THC_MEM_PORT_SPI_CONFIG_WRITE_FREQUENCY, NewFrequency);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Initialize Thc according to procedure described in EDS
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Thc initialized successfully
|
|
@retval other Error during initialization
|
|
**/
|
|
EFI_STATUS
|
|
ThcInitialize (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
UINT8 ResetRetryCount;
|
|
|
|
ResetRetryCount = THC_RESET_RETRY_COUNT;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcInitialize Start ()\n")
|
|
Status = ThcLibIoReady (ThcDev->PciBar0, IoReadyTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcInitialize ThcLibIoReady Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcLibIoReady error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
if (ThcLibIsQuiesceDisabled (ThcDev->PciBar0)) {
|
|
THC_LOCAL_DEBUG(L"ThcInitialize QuiesceDisabled \n")
|
|
Status = ThcLibStartQuiesce (ThcDev->PciBar0, StartQuiesceTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcInitialize ThcLibStartQuiesce Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcLibStartQuiesce error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Configure THC Controller to operate at 7MHz, Single I/O
|
|
//
|
|
THC_LOCAL_DEBUG(L"ThcInitialize Configure THC Controller to operate at 7MHz, Single I/O\n")
|
|
ThcLibSetPortFrequency (ThcDev->PciBar0, N_THC_MEM_PORT_SPI_CONFIG_READ_FREQUENCY, ThcFreqLow7p5MHz);
|
|
ThcLibSetPortFrequency (ThcDev->PciBar0, N_THC_MEM_PORT_SPI_CONFIG_WRITE_FREQUENCY, ThcFreqLow7p5MHz);
|
|
ThcLibSetSingleIoMode (ThcDev->PciBar0);
|
|
|
|
ThcLibSetEdgeInterrupts (ThcDev->PciBar0);
|
|
if (!IsPchS () && (IsPchN () || (PchStepping () >= PCH_A1))) {
|
|
ThcLibSetEwog (ThcDev->PciBar0);
|
|
}
|
|
|
|
//
|
|
// Reset THC and clear THC_DEVINT_QUIESCE_EN
|
|
//
|
|
ThcLibGetOutOfReset (ThcDev->PciBar0, OutOfResetTimeout);
|
|
|
|
Status = ThcLibEndQuiesce (ThcDev->PciBar0, EndQuiesceTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcInitialize ThcLibEndQuiesce Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcLibEndQuiesce error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
do {
|
|
Status = ThcLibWaitForResetOccured (ThcDev->PciBar0, WaitForResetTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcInitialize ThcLibWaitForResetOccured Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_WARN, "ThcLibWaitForResetOccured error, Status %r Reset Count %d\n", Status, ResetRetryCount));
|
|
} else {
|
|
return Status;
|
|
}
|
|
ThcLibGetOutOfReset (ThcDev->PciBar0, OutOfResetTimeout);
|
|
ResetRetryCount--;
|
|
} while (EFI_ERROR (Status) && (ResetRetryCount > 0));
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Reads Touch Panels Device registers (TouchCapabilities, TouchId etc.)
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Thc initialized successfully
|
|
@retval other Error during initialization
|
|
**/
|
|
EFI_STATUS
|
|
ThcReadConfig (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
Status = ThcLibNoCyclesPending (ThcDev->PciBar0, CycleTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcReadConfig ThcLibNoCyclesPending Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcReadConfig error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
ThcLibPrepareReadDevRegCmd (ThcDev->PciBar0);
|
|
ThcLibGo (ThcDev->PciBar0);
|
|
|
|
Status = ThcLibWaitCycleCompleted (ThcDev->PciBar0, CycleTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcReadConfig ThcLibWaitCycleCompleted Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcReadConfig error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
Status = ThcLibReadDeviceRegisters (ThcDev->PciBar0, (UINT32*) &ThcDev->DeviceRegisters);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcLibReadDeviceRegisters error, Status %r\n", Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Prints end Device Configuration
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Thc initialized successfully
|
|
@retval other Error during initialization
|
|
**/
|
|
VOID
|
|
ThcPrintConfig (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
THC_LOCAL_DEBUG(L"ThcPrintConfig () Start\n")
|
|
THC_LOCAL_DEBUG(L"| 0x00 | TouchIntCause | 0x%X\n", ThcDev->DeviceRegisters.TouchIntCause)
|
|
THC_LOCAL_DEBUG(L"| 0x04 | TouchErr | 0x%X\n", ThcDev->DeviceRegisters.TouchErr)
|
|
THC_LOCAL_DEBUG(L"| 0x08 | TouchDataSize | 0x%X\n", ThcDev->DeviceRegisters.TouchDataSize.Data)
|
|
THC_LOCAL_DEBUG(L"| 0x08 | - MAXIMUM_READ_SIZE | %d\n", ThcDev->DeviceRegisters.TouchDataSize.Fields.MaximumReadSize)
|
|
THC_LOCAL_DEBUG(L"| 0x08 | - MAXIMUM_WRITE_SIZE | %d\n", ThcDev->DeviceRegisters.TouchDataSize.Fields.MaximumWriteSize)
|
|
THC_LOCAL_DEBUG(L"| 0x0C | TouchCfg | 0x%X\n", ThcDev->DeviceRegisters.TouchCfg.Data)
|
|
THC_LOCAL_DEBUG(L"| 0x0C | - TOUCH_ENABLE | %d\n", ThcDev->DeviceRegisters.TouchCfg.Fields.TouchEnable)
|
|
THC_LOCAL_DEBUG(L"| 0x0C | - PROP_DATA_ENABLED | %d\n", ThcDev->DeviceRegisters.TouchCfg.Fields.ProprietaryDataModeEnabled)
|
|
THC_LOCAL_DEBUG(L"| 0x0C | - HID_REPORT_ENABLED | %d\n", ThcDev->DeviceRegisters.TouchCfg.Fields.HidReportModeEnabled)
|
|
THC_LOCAL_DEBUG(L"| 0x0C | - POWER_STATE | %d\n", ThcDev->DeviceRegisters.TouchCfg.Fields.PowerState)
|
|
THC_LOCAL_DEBUG(L"| 0x10 | TouchState | 0x%X\n", ThcDev->DeviceRegisters.TouchState.Data)
|
|
THC_LOCAL_DEBUG(L"| 0x10 | - TOUCH_ENABLE | %d\n", ThcDev->DeviceRegisters.TouchState.Fields.TouchEnable)
|
|
THC_LOCAL_DEBUG(L"| 0x10 | - PROP_DATA_ENABLED | %d\n", ThcDev->DeviceRegisters.TouchState.Fields.ProprietaryDataModeEnabled)
|
|
THC_LOCAL_DEBUG(L"| 0x10 | - HID_REPORT_ENABLED | %d\n", ThcDev->DeviceRegisters.TouchState.Fields.HidReportModeEnabled)
|
|
THC_LOCAL_DEBUG(L"| 0x10 | - POWER_STATE | %d\n", ThcDev->DeviceRegisters.TouchState.Fields.PowerState)
|
|
THC_LOCAL_DEBUG(L"| 0x14 | TouchId | 0x%X\n", ThcDev->DeviceRegisters.TouchId)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | TouchCapabilities | 0x%X\n", ThcDev->DeviceRegisters.TouchCapabilities.Data)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - PROPR_DATA_SUPPORT | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.ProprietaryDataModeSupported)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - MAX_SPI_FREQ_SUPPORT | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.MaxSpiFrequencySupported)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - SINGLE_IO_SUPPORTED | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.SingleIoSupported)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - DUAL_IO_SUPPORTED | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.DualIoSupported)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - QUAD_IO_SUPPORTED | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.QuadIoSupported)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - MAXIMUM_TOUCH_POINTS | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.MaximumTouchPoints)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - MINIMUM_RESET_TIME | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.MaximumResetTime)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - HEARTBEAT_REPORT_SUP | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.HeartBeatReportSupported)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - PERFORMANCE_LIMIT | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.PerformanceLimitation)
|
|
THC_LOCAL_DEBUG(L"| 0x18 | - PREP_FOR_REGSTR_READ | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.PrepForRegisterRead)
|
|
THC_LOCAL_DEBUG(L"| 0x1C | TouchIcHwId | 0x%X\n", ThcDev->DeviceRegisters.TouchIcHwId)
|
|
THC_LOCAL_DEBUG(L"| 0x20 | TouchIcHwRev | 0x%X\n", ThcDev->DeviceRegisters.TouchIcHwRev)
|
|
THC_LOCAL_DEBUG(L"| 0x24 | TouchIcFwRev | 0x%X\n", ThcDev->DeviceRegisters.TouchIcFwRev)
|
|
THC_LOCAL_DEBUG(L"| 0x28 | TouchCommand | 0x%X\n", ThcDev->DeviceRegisters.TouchCommand)
|
|
THC_LOCAL_DEBUG(L"| 0x30 | TouchInit | 0x%X\n", ThcDev->DeviceRegisters.TouchInit)
|
|
THC_LOCAL_DEBUG(L"| 0x34 | TouchCompatibilityId | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Data)
|
|
THC_LOCAL_DEBUG(L"| 0x34 | - EDS_MINOR_VERSION | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Fields.EdsMinorVersion)
|
|
THC_LOCAL_DEBUG(L"| 0x34 | - EDS_MAJOR_VERSION | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Fields.EdsMajorVersion)
|
|
THC_LOCAL_DEBUG(L"| 0x34 | - INTERFACE_REV_NUM | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Fields.InterfaceRevisionNumber)
|
|
THC_LOCAL_DEBUG(L"| 0x34 | - EU_KERNEL_VERSION | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Fields.EuKernelCompatibilityVersion)
|
|
THC_LOCAL_DEBUG(L"ThcPrintConfig () End\n")
|
|
DEBUG ((DEBUG_INFO, "ThcPrintConfig () Start\n"));
|
|
DEBUG ((DEBUG_INFO, "| 0x00 | TouchIntCause | 0x%X\n", ThcDev->DeviceRegisters.TouchIntCause));
|
|
DEBUG ((DEBUG_INFO, "| 0x04 | TouchErr | 0x%X\n", ThcDev->DeviceRegisters.TouchErr));
|
|
DEBUG ((DEBUG_INFO, "| 0x08 | TouchDataSize | 0x%X\n", ThcDev->DeviceRegisters.TouchDataSize.Data));
|
|
DEBUG ((DEBUG_INFO, "| 0x08 | - MAXIMUM_READ_SIZE | %d\n", ThcDev->DeviceRegisters.TouchDataSize.Fields.MaximumReadSize));
|
|
DEBUG ((DEBUG_INFO, "| 0x08 | - MAXIMUM_WRITE_SIZE | %d\n", ThcDev->DeviceRegisters.TouchDataSize.Fields.MaximumWriteSize));
|
|
DEBUG ((DEBUG_INFO, "| 0x0C | TouchCfg | 0x%X\n", ThcDev->DeviceRegisters.TouchCfg.Data));
|
|
DEBUG ((DEBUG_INFO, "| 0x0C | - TOUCH_ENABLE | %d\n", ThcDev->DeviceRegisters.TouchCfg.Fields.TouchEnable));
|
|
DEBUG ((DEBUG_INFO, "| 0x0C | - PROP_DATA_ENABLED | %d\n", ThcDev->DeviceRegisters.TouchCfg.Fields.ProprietaryDataModeEnabled));
|
|
DEBUG ((DEBUG_INFO, "| 0x0C | - HID_REPORT_ENABLED | %d\n", ThcDev->DeviceRegisters.TouchCfg.Fields.HidReportModeEnabled));
|
|
DEBUG ((DEBUG_INFO, "| 0x0C | - POWER_STATE | %d\n", ThcDev->DeviceRegisters.TouchCfg.Fields.PowerState));
|
|
DEBUG ((DEBUG_INFO, "| 0x10 | TouchState | 0x%X\n", ThcDev->DeviceRegisters.TouchState.Data));
|
|
DEBUG ((DEBUG_INFO, "| 0x10 | - TOUCH_ENABLE | %d\n", ThcDev->DeviceRegisters.TouchState.Fields.TouchEnable));
|
|
DEBUG ((DEBUG_INFO, "| 0x10 | - PROP_DATA_ENABLED | %d\n", ThcDev->DeviceRegisters.TouchState.Fields.ProprietaryDataModeEnabled));
|
|
DEBUG ((DEBUG_INFO, "| 0x10 | - HID_REPORT_ENABLED | %d\n", ThcDev->DeviceRegisters.TouchState.Fields.HidReportModeEnabled));
|
|
DEBUG ((DEBUG_INFO, "| 0x10 | - POWER_STATE | %d\n", ThcDev->DeviceRegisters.TouchState.Fields.PowerState));
|
|
DEBUG ((DEBUG_INFO, "| 0x14 | TouchId | 0x%X\n", ThcDev->DeviceRegisters.TouchId));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | TouchCapabilities | 0x%X\n", ThcDev->DeviceRegisters.TouchCapabilities.Data));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - PROPR_DATA_SUPPORT | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.ProprietaryDataModeSupported));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - MAX_SPI_FREQ_SUPPORT | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.MaxSpiFrequencySupported));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - SINGLE_IO_SUPPORTED | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.SingleIoSupported));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - DUAL_IO_SUPPORTED | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.DualIoSupported));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - QUAD_IO_SUPPORTED | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.QuadIoSupported));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - MAXIMUM_TOUCH_POINTS | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.MaximumTouchPoints));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - MINIMUM_RESET_TIME | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.MaximumResetTime));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - HEARTBEAT_REPORT_SUP | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.HeartBeatReportSupported));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - PERFORMANCE_LIMIT | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.PerformanceLimitation));
|
|
DEBUG ((DEBUG_INFO, "| 0x18 | - PREP_FOR_REGSTR_READ | %d\n", ThcDev->DeviceRegisters.TouchCapabilities.Fields.PrepForRegisterRead));
|
|
DEBUG ((DEBUG_INFO, "| 0x1C | TouchIcHwId | 0x%X\n", ThcDev->DeviceRegisters.TouchIcHwId));
|
|
DEBUG ((DEBUG_INFO, "| 0x20 | TouchIcHwRev | 0x%X\n", ThcDev->DeviceRegisters.TouchIcHwRev));
|
|
DEBUG ((DEBUG_INFO, "| 0x24 | TouchIcFwRev | 0x%X\n", ThcDev->DeviceRegisters.TouchIcFwRev));
|
|
DEBUG ((DEBUG_INFO, "| 0x28 | TouchCommand | 0x%X\n", ThcDev->DeviceRegisters.TouchCommand));
|
|
DEBUG ((DEBUG_INFO, "| 0x30 | TouchInit | 0x%X\n", ThcDev->DeviceRegisters.TouchInit));
|
|
DEBUG ((DEBUG_INFO, "| 0x34 | TouchCompatibilityId | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Data));
|
|
DEBUG ((DEBUG_INFO, "| 0x34 | - EDS_MINOR_VERSION | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Fields.EdsMinorVersion));
|
|
DEBUG ((DEBUG_INFO, "| 0x34 | - EDS_MAJOR_VERSION | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Fields.EdsMajorVersion));
|
|
DEBUG ((DEBUG_INFO, "| 0x34 | - INTERFACE_REV_NUM | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Fields.InterfaceRevisionNumber));
|
|
DEBUG ((DEBUG_INFO, "| 0x34 | - EU_KERNEL_VERSION | 0x%X\n", ThcDev->DeviceRegisters.TouchCompatibilityId.Fields.EuKernelCompatibilityVersion));
|
|
DEBUG ((DEBUG_INFO, "ThcPrintConfig () End\n"));
|
|
}
|
|
|
|
/**
|
|
Enables Touch Panel connected to the Touch Host Controller
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Touch Panel Enabled
|
|
@retval other Error during device enabling process
|
|
**/
|
|
EFI_STATUS
|
|
ThcEnableEndDevice (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcEnableEndDevice Start ()\n");
|
|
ThcSetFrequency (ThcDev);
|
|
|
|
Status = ThcLibNoCyclesPending (ThcDev->PciBar0, CycleTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcEnableEndDevice ThcLibNoCyclesPending Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcEnableEndDevice error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
ThcLibPrepareWriteConfigCmd (ThcDev->PciBar0);
|
|
ThcDev->DeviceRegisters.TouchCfg.Fields.PowerState = 0x3;
|
|
ThcDev->DeviceRegisters.TouchCfg.Fields.ProprietaryDataModeEnabled = 0x0;
|
|
ThcDev->DeviceRegisters.TouchCfg.Fields.HidReportModeEnabled = 0x1;
|
|
ThcLibWriteSeqData1 (ThcDev->PciBar0, ThcDev->DeviceRegisters.TouchCfg.Data);
|
|
ThcLibGo (ThcDev->PciBar0);
|
|
|
|
Status = ThcLibWaitCycleCompleted (ThcDev->PciBar0, CycleTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcEnableEndDevice ThcLibWaitCycleCompleted Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcEnableEndDevice error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
ThcLibPrepareWriteConfigCmd (ThcDev->PciBar0);
|
|
ThcDev->DeviceRegisters.TouchCfg.Fields.TouchEnable = 0x1;
|
|
ThcLibWriteSeqData1 (ThcDev->PciBar0, ThcDev->DeviceRegisters.TouchCfg.Data);
|
|
ThcLibGo (ThcDev->PciBar0);
|
|
|
|
Status = ThcLibWaitCycleCompleted (ThcDev->PciBar0, CycleTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcEnableEndDevice ThcLibWaitCycleCompleted Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcEnableEndDevice error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Disables Touch Panel connected to the Touch Host Controller
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Touch Panel Disabled
|
|
@retval other Error during device enabling process
|
|
**/
|
|
EFI_STATUS
|
|
ThcDisableEndDevice (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcDisableEndDevice Start ()\n")
|
|
ThcSetFrequency (ThcDev);
|
|
|
|
Status = ThcLibNoCyclesPending (ThcDev->PciBar0, CycleTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcDisableEndDevice ThcLibNoCyclesPending Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDisableEndDevice error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
ThcLibPrepareWriteConfigCmd (ThcDev->PciBar0);
|
|
ThcDev->DeviceRegisters.TouchCfg.Fields.PowerState = 0x0;
|
|
ThcDev->DeviceRegisters.TouchCfg.Fields.ProprietaryDataModeEnabled = 0x0;
|
|
ThcDev->DeviceRegisters.TouchCfg.Fields.HidReportModeEnabled = 0x1;
|
|
ThcLibWriteSeqData1 (ThcDev->PciBar0, ThcDev->DeviceRegisters.TouchCfg.Data);
|
|
ThcLibGo (ThcDev->PciBar0);
|
|
|
|
Status = ThcLibWaitCycleCompleted (ThcDev->PciBar0, CycleTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcDisableEndDevice ThcLibWaitCycleCompleted Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDisableEndDevice error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
ThcLibPrepareWriteConfigCmd (ThcDev->PciBar0);
|
|
ThcDev->DeviceRegisters.TouchCfg.Fields.TouchEnable = 0x0;
|
|
ThcLibWriteSeqData1 (ThcDev->PciBar0, ThcDev->DeviceRegisters.TouchCfg.Data);
|
|
ThcLibGo (ThcDev->PciBar0);
|
|
|
|
Status = ThcLibWaitCycleCompleted (ThcDev->PciBar0, CycleTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcDisableEndDevice ThcLibWaitCycleCompleted Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDisableEndDevice error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Initialize Memory for Prd used by the HW
|
|
Only ReadRx2 and Write are supported by this driver
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Thc Dma Initialized successfuly
|
|
@retval EFI_OUT_OF_RESOURCES Not enough memory available
|
|
**/
|
|
EFI_STATUS
|
|
ThcDmaCreatePrdCommonBuffers (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
|
UINT64 PageCount;
|
|
UINT64 ByteCount;
|
|
EFI_STATUS Status;
|
|
|
|
PciIo = ThcDev->PciIo;
|
|
|
|
PageCount = EFI_SIZE_TO_PAGES (sizeof (PRD_TABLE) * PRD_READ_TABLES_SUPPORTED);
|
|
Status = PciIo->AllocateBuffer (
|
|
PciIo,
|
|
AllocateAnyPages,
|
|
EfiBootServicesData,
|
|
PageCount,
|
|
(VOID*) &ThcDev->DmaRead2.CommonPrdBuffer,
|
|
0
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaCreateCommonBuffers Read2 buffer allocateBuffer failed Status %r\n", Status));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
ByteCount = EFI_PAGES_TO_SIZE (PageCount);
|
|
Status = PciIo->Map (
|
|
PciIo,
|
|
EfiPciIoOperationBusMasterCommonBuffer,
|
|
(VOID*) ThcDev->DmaRead2.CommonPrdBuffer,
|
|
&ByteCount,
|
|
&ThcDev->DmaRead2.CommonPrdBufferDevAddr,
|
|
&ThcDev->DmaRead2.CommonPrdBufferMapping
|
|
);
|
|
if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (PageCount))) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaCreateCommonBuffers Read2 buffer map failed Status %r\n", Status));
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaCreateCommonBuffers Requsted ByteCount: %d Mapped Count: %d\n", EFI_PAGES_TO_SIZE (PageCount), ByteCount));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
ZeroMem ((UINT8*) ThcDev->DmaRead2.CommonPrdBuffer, ByteCount);
|
|
|
|
PageCount = EFI_SIZE_TO_PAGES (sizeof (PRD_TABLE) * PRD_WRITE_TABLES_SUPPORTED);
|
|
Status = PciIo->AllocateBuffer (
|
|
PciIo,
|
|
AllocateAnyPages,
|
|
EfiBootServicesData,
|
|
PageCount,
|
|
(VOID*) &ThcDev->DmaWrite.CommonPrdBuffer,
|
|
0
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaCreateCommonBuffers Read2 buffer allocateBuffer failed Status %r\n", Status));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
ByteCount = EFI_PAGES_TO_SIZE (PageCount);
|
|
Status = PciIo->Map (
|
|
PciIo,
|
|
EfiPciIoOperationBusMasterCommonBuffer,
|
|
(VOID*) ThcDev->DmaWrite.CommonPrdBuffer,
|
|
&ByteCount,
|
|
&ThcDev->DmaWrite.CommonPrdBufferDevAddr,
|
|
&ThcDev->DmaWrite.CommonPrdBufferMapping
|
|
);
|
|
if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (PageCount))) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaCreateCommonBuffers Write buffer map failed Status %r\n", Status));
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaCreateCommonBuffers Requsted ByteCount: %d Mapped Count: %d\n", EFI_PAGES_TO_SIZE (PageCount), ByteCount));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
ZeroMem ((UINT8*) ThcDev->DmaWrite.CommonPrdBuffer, ByteCount);
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Fills single Prd Table with the defualt values
|
|
|
|
@param[in] ThcDma Dma that stores Driver PRD table
|
|
@param[in] PrdTableIndex Index of current Prd table
|
|
|
|
**/
|
|
VOID
|
|
ThcDmaFillSinglePrdTable (
|
|
IN THC_DMA *ThcDma,
|
|
IN UINT16 PrdTableIndex
|
|
)
|
|
{
|
|
PRD_TABLE *PrdTable;
|
|
UINT16 CurrentEntry = 0;
|
|
UINT32 EntryOffset = ThcDma->DriverPrdTable[PrdTableIndex].NumOfConfiguredEntries * PrdTableIndex;
|
|
|
|
PrdTable = (PRD_TABLE*) ThcDma->CommonPrdBuffer;
|
|
|
|
for (CurrentEntry = 0; CurrentEntry < ThcDma->DriverPrdTable[PrdTableIndex].NumOfConfiguredEntries; CurrentEntry++) {
|
|
CopyMem (
|
|
&PrdTable->Entries[CurrentEntry + EntryOffset],
|
|
&ThcDma->DriverPrdTable[PrdTableIndex].Entries[CurrentEntry],
|
|
sizeof (PRD_ENTRY)
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Fills every Prd Table with the defualt values
|
|
|
|
@param[in] ThcDma Dma that stores Driver PRD Table
|
|
|
|
**/
|
|
VOID
|
|
ThcDmaFillPrdTables (
|
|
THC_DMA *ThcDma
|
|
)
|
|
{
|
|
UINT16 PrdTableIndex;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcDmaFillPrdTables Start ()\n")
|
|
|
|
//
|
|
// Loop through total number of Entries in Common Prd
|
|
// Fill every entry with the corresponding data for the HW to use
|
|
//
|
|
for (PrdTableIndex = 0; PrdTableIndex < ThcDma->NumOfPrdTables; PrdTableIndex++) {
|
|
ThcDmaFillSinglePrdTable (ThcDma, PrdTableIndex);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Initialize Driver Prd Tables
|
|
Allocates and maps every single page for each used entry
|
|
besed on the supported BufferSize for each MAXIMUM_READ_SIZE/MAXIMUM_WRITE_SIZE
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
@param[in] ThcDma Dma that stores Driver PRD Table
|
|
@param[in] PciIoOperation BusMasterRead or BusMasterWrite
|
|
|
|
@retval EFI_SUCCESS Thc Dma Initialized successfuly
|
|
@retval EFI_OUT_OF_RESOURCES Not enough memory available
|
|
**/
|
|
EFI_STATUS
|
|
ThcDmaCreatePrds (
|
|
IN THC_DEV *ThcDev,
|
|
IN THC_DMA *ThcDma,
|
|
IN EFI_PCI_IO_PROTOCOL_OPERATION PciIoOperation
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_PCI_IO_PROTOCOL *PciIo;
|
|
UINTN PageCount;
|
|
UINTN ByteCount;
|
|
UINT16 CurrentEntry;
|
|
UINT64 CurrentAddress;
|
|
UINT16 PrdTableIndex;
|
|
UINTN BytesRemaining;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcDmaCreatePrds Start ()\n")
|
|
|
|
PciIo = ThcDev->PciIo;
|
|
|
|
for (PrdTableIndex = 0; PrdTableIndex < ThcDma->NumOfPrdTables; PrdTableIndex++) {
|
|
|
|
PageCount = EFI_SIZE_TO_PAGES (ThcDma->BufferSize);
|
|
Status = PciIo->AllocateBuffer (
|
|
PciIo,
|
|
AllocateAnyPages,
|
|
EfiBootServicesData,
|
|
PageCount,
|
|
(VOID*) &ThcDma->DriverPrdTable[PrdTableIndex].Buffer,
|
|
0
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaCreateReadPrds AllocateBuffer for PrdTableIndex: %d failed with Status %r\n", PrdTableIndex, Status));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
ByteCount = EFI_PAGES_TO_SIZE (PageCount);
|
|
Status = PciIo->Map (
|
|
PciIo,
|
|
PciIoOperation,
|
|
(VOID*) ThcDma->DriverPrdTable[PrdTableIndex].Buffer,
|
|
&ByteCount,
|
|
&ThcDma->DriverPrdTable[PrdTableIndex].DevAddr,
|
|
&ThcDma->DriverPrdTable[PrdTableIndex].Mapping
|
|
);
|
|
|
|
if (EFI_ERROR (Status) || (ByteCount != EFI_PAGES_TO_SIZE (PageCount))) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaCreateReadPrds Read buffer map failed PrdTableIndex: %d Status %r\n", PrdTableIndex, Status));
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaCreateReadPrds Requsted ByteCount: %d Mapped Count: %d\n", EFI_PAGES_TO_SIZE (PageCount), ByteCount));
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
ZeroMem ((UINT8*) ThcDma->DriverPrdTable[PrdTableIndex].Buffer, ByteCount);
|
|
|
|
BytesRemaining = ByteCount;
|
|
CurrentEntry = 0;
|
|
CurrentAddress = ThcDma->DriverPrdTable[PrdTableIndex].Buffer;
|
|
//
|
|
// Loop through total number of Entries
|
|
// Each entry Max length is 4K (size of the single page), max entries is 256.
|
|
// Max allocated total for single PRD table is 1MB
|
|
//
|
|
while (BytesRemaining > 0 && CurrentEntry < 256) {
|
|
ThcDma->DriverPrdTable[PrdTableIndex].Entries[CurrentEntry].DestinationAddress = RShiftU64 (CurrentAddress, ADDRESS_SHIFT);
|
|
ThcDma->DriverPrdTable[PrdTableIndex].Entries[CurrentEntry].EndOfPrd = 0x0;
|
|
ThcDma->DriverPrdTable[PrdTableIndex].Entries[CurrentEntry].Length = EFI_PAGE_SIZE;
|
|
if (BytesRemaining <= EFI_PAGE_SIZE) {
|
|
ThcDma->DriverPrdTable[PrdTableIndex].Entries[CurrentEntry].Length = BytesRemaining;
|
|
ThcDma->DriverPrdTable[PrdTableIndex].Entries[CurrentEntry].EndOfPrd = 0x1;
|
|
break;
|
|
}
|
|
CurrentEntry++;
|
|
CurrentAddress += EFI_PAGE_SIZE;
|
|
BytesRemaining -= EFI_PAGE_SIZE;
|
|
}
|
|
ThcDma->DriverPrdTable[PrdTableIndex].NumOfConfiguredEntries = CurrentEntry + 1;
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Initialize Thc DMA
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Thc Dma Initialized successfuly
|
|
@retval other error during initialization
|
|
**/
|
|
EFI_STATUS
|
|
ThcDmaInitialize (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcDmaInitialize Start ()\n")
|
|
|
|
Status = ThcDmaCreatePrdCommonBuffers (ThcDev);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaInitialize error, failed to CreatePrdCommonBuffers Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
Status = ThcLibSetPrdTablesAddress (ThcDev->PciBar0, ThcDev->DmaWrite.CommonPrdBuffer, ThcDev->DmaRead2.CommonPrdBuffer);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaInitialize error, failed to SetPrdTablesAddress Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
ThcDev->DmaRead2.BufferSize = (ThcDev->DeviceRegisters.TouchDataSize.Fields.MaximumReadSize + 1) * SIZE_FIELD_RESOLUTION;
|
|
ThcDev->DmaRead2.NumOfPrdTables = PRD_READ_TABLES_SUPPORTED;
|
|
ThcDev->DmaWrite.BufferSize = (ThcDev->DeviceRegisters.TouchDataSize.Fields.MaximumWriteSize + 1) * SIZE_FIELD_RESOLUTION;
|
|
ThcDev->DmaWrite.NumOfPrdTables = PRD_WRITE_TABLES_SUPPORTED;
|
|
|
|
Status = ThcDmaCreatePrds (ThcDev, &ThcDev->DmaRead2, EfiPciIoOperationBusMasterCommonBuffer);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaInitialize error, failed to Create Read Prds Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
ThcDmaFillPrdTables (&ThcDev->DmaRead2);
|
|
|
|
Status = ThcDmaCreatePrds (ThcDev, &ThcDev->DmaWrite, EfiPciIoOperationBusMasterCommonBuffer);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaInitialize error, failed to Create Write Prds Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
ThcDmaFillPrdTables (&ThcDev->DmaWrite);
|
|
|
|
ThcLibSetLengthInPrd (ThcDev->PciBar0,
|
|
(UINT8) ThcDev->DmaRead2.DriverPrdTable[0].NumOfConfiguredEntries,
|
|
PRD_READ_TABLES_SUPPORTED,
|
|
(UINT8) ThcDev->DmaWrite.DriverPrdTable[0].NumOfConfiguredEntries
|
|
);
|
|
|
|
ThcLibSetReadRx2StartBit (ThcDev->PciBar0);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Calculates the length of the current message
|
|
|
|
@param[in] ThcDma Dma that stores Driver PRD Table
|
|
@param[in] PrdTable Prd Table updated by the THC HW
|
|
@param[in] PrdTableIndex Index of the Prd Table
|
|
@param[in] EntryOffset Entry offset
|
|
|
|
@retval MessageLength Size of the message
|
|
**/
|
|
UINT64
|
|
ThcDmaGetMessageLength (
|
|
IN THC_DMA *ThcDma,
|
|
IN PRD_TABLE *PrdTable,
|
|
IN UINT16 PrdTableIndex,
|
|
IN UINT32 EntryOffset
|
|
)
|
|
{
|
|
UINT32 Index;
|
|
UINT64 MessageLength = 0;
|
|
|
|
for (Index = 0; Index < ThcDma->DriverPrdTable[PrdTableIndex].NumOfConfiguredEntries; Index++) {
|
|
MessageLength += PrdTable->Entries[EntryOffset + Index].Length;
|
|
if (PrdTable->Entries[EntryOffset + Index].EndOfPrd == 1) {
|
|
return MessageLength;
|
|
}
|
|
}
|
|
return MessageLength;
|
|
}
|
|
|
|
/**
|
|
Reads first PRD Table Entry and checks if header data type
|
|
equals to TouchReadDataTypeHidReport
|
|
and Report Id is equal to SINGLE_FINGER_REPORT_ID.
|
|
If passed report data is copied to the Thc Context.
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
@param[in] ThcDma Dma that stores Driver PRD Table
|
|
@param[in] CurrentPrdTable Index of current Prd table
|
|
|
|
@retval EFI_SUCCESS Data read done
|
|
@retval EFI_BAD_BUFFER_SIZE MessageLength is smaller then its header
|
|
@retval EFI_BUFFER_TOO_SMALL Allocated entry length is smaller then one present in Prd
|
|
**/
|
|
EFI_STATUS
|
|
ThcDmaReadSingleReport (
|
|
IN THC_DEV *ThcDev,
|
|
IN THC_DMA *ThcDma,
|
|
IN UINT16 CurrentPrdTable
|
|
)
|
|
{
|
|
READ_DATA_BUFF *ReadDataBuff;
|
|
PRD_TABLE *PrdTable;
|
|
UINT64 MessageLength = 0;
|
|
UINT64 DataAddress = 0;
|
|
UINT32 EntryOffset = 0;
|
|
HID_TOUCH_OUTPUT TouchOutput;
|
|
HID_XY_BOUNDARY XyBoundary;
|
|
EFI_STATUS Status;
|
|
|
|
EntryOffset = (UINT32)(ThcDma->DriverPrdTable[CurrentPrdTable].NumOfConfiguredEntries) * CurrentPrdTable;
|
|
PrdTable = (PRD_TABLE *) ThcDma->CommonPrdBuffer;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcDmaReadSingleReport Start ()\n")
|
|
ReadDataBuff = AllocateZeroPool (sizeof (READ_DATA_BUFF));
|
|
if (ReadDataBuff == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
|
|
MessageLength = ThcDmaGetMessageLength (ThcDma, PrdTable, CurrentPrdTable, EntryOffset);
|
|
THC_LOCAL_DEBUG(L"MessageLength %d \n", MessageLength)
|
|
if (MessageLength < sizeof (RAW_DATA_HEADER)) {
|
|
FreePool (ReadDataBuff);
|
|
return EFI_BAD_BUFFER_SIZE;
|
|
}
|
|
if (ThcDma->DriverPrdTable[CurrentPrdTable].Entries[0].Length < PrdTable->Entries[EntryOffset].Length) {
|
|
FreePool (ReadDataBuff);
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
DataAddress = LShiftU64 (PrdTable->Entries[EntryOffset].DestinationAddress, ADDRESS_SHIFT);
|
|
CopyMem ((UINT8*) ReadDataBuff, (UINT8*) DataAddress, sizeof (READ_DATA_BUFF));
|
|
|
|
THC_LOCAL_DEBUG(L"ReadDataBuff->Header.DataType %d\n", ReadDataBuff->Header.DataType)
|
|
|
|
//ShowBuffer ((UINT8*)(DataAddress), (UINT32) MessageLength); // Uncomment when THC_LOCAL_DEBUG is enabled
|
|
|
|
if ((ReadDataBuff->Header.DataType == TouchReadDataTypeHidReport) && (ReadDataBuff->ReadData[0] == SINGLE_FINGER_REPORT_ID)) {
|
|
CopyMem ((UINT8*) &ThcDev->Report, (UINT8*) DataAddress + sizeof (RAW_DATA_HEADER), sizeof (SINGLE_FINGER_REPORT));
|
|
THC_LOCAL_DEBUG(L"X:%d Y:%d Btn: %d \n",
|
|
(ThcDev->Report.HigherXByte << 8) + ThcDev->Report.LowerXByte,
|
|
(ThcDev->Report.HigherYByte << 8) + ThcDev->Report.LowerYByte,
|
|
ThcDev->Report.TouchSts);
|
|
|
|
ThcDev->AbsPtrDataAvailable = TRUE;
|
|
gBS->SignalEvent (ThcDev->AbsPtrProtocol.WaitForInput);
|
|
} else if ((ReadDataBuff->Header.DataType == TouchReadDataTypeGetFeatures) &&
|
|
(ThcDev->HidActive == TRUE) &&
|
|
(ThcDev->HidBuffer != NULL)) {
|
|
THC_LOCAL_DEBUG(L"ThcDmaReadSingleReport TouchReadDataTypeGetFeatures\n")
|
|
DEBUG ((DEBUG_ERROR, "TouchReadDataTypeGetFeatures\n"));
|
|
CopyMem ((UINT8*) ThcDev->HidBuffer, (UINT8*) DataAddress + sizeof (RAW_DATA_HEADER), MessageLength);
|
|
ThcDev->HidBuffer += MessageLength;
|
|
ThcDev->HidDataAvailable = TRUE;
|
|
} else if ((ReadDataBuff->Header.DataType == TouchReadDataTypeTctlRsp) &&
|
|
(ThcDev->HidActive == TRUE) &&
|
|
(ThcDev->HidBuffer != NULL)) {
|
|
THC_LOCAL_DEBUG(L"ThcDmaReadSingleReport TouchReadDataTypeTctlRsp\n")
|
|
CopyMem ((UINT8*) ThcDev->HidBuffer, (UINT8*) DataAddress, MessageLength);
|
|
ThcDev->HidBuffer += MessageLength;
|
|
ThcDev->HidDataAvailable = TRUE;
|
|
} else if ((ReadDataBuff->Header.DataType == TouchReadDataTypeHidReport || ReadDataBuff->Header.DataType == TouchReadDataTypeResetOccurred) &&
|
|
(ThcDev->HidActive == TRUE) &&
|
|
(ThcDev->HidBuffer != NULL)) {
|
|
THC_LOCAL_DEBUG(L"ThcDmaReadSingleReport Warning! Consuming HidReport as Get/Set Feature response\n")
|
|
DEBUG ((DEBUG_WARN, "ThcDmaReadSingleReport Warning! Consuming HidReport as Get/Set Feature response\n"));
|
|
CopyMem ((UINT8*) ThcDev->HidBuffer, (UINT8*) DataAddress + sizeof (RAW_DATA_HEADER), MessageLength);
|
|
ThcDev->HidBuffer += MessageLength;
|
|
ThcDev->HidDataAvailable = TRUE;
|
|
} else if (ReadDataBuff->Header.DataType == TouchReadDataTypeHidReport) {
|
|
Status = HidParseInput (ThcDev->InputReportTable, (UINT8*) DataAddress + (sizeof (RAW_DATA_HEADER)), &TouchOutput, &XyBoundary);
|
|
if (Status == EFI_SUCCESS) {
|
|
ThcDev->Report.HigherXByte = (UINT8)(((TouchOutput.X) & 0xFF00) >> 8);
|
|
ThcDev->Report.LowerXByte = (UINT8)(TouchOutput.X) & 0xFF;
|
|
ThcDev->Report.HigherYByte = (UINT8)(((TouchOutput.Y) & 0xFF00) >> 8);
|
|
ThcDev->Report.LowerYByte = (UINT8)(TouchOutput.Y) & 0xFF;
|
|
ThcDev->Report.TouchSts = (UINT8) TouchOutput.B;
|
|
ThcDev->AbsPtrProtocol.Mode->AbsoluteMaxX = XyBoundary.MaxX;
|
|
ThcDev->AbsPtrProtocol.Mode->AbsoluteMinX = XyBoundary.MinX;
|
|
ThcDev->AbsPtrProtocol.Mode->AbsoluteMaxY = XyBoundary.MaxY;
|
|
ThcDev->AbsPtrProtocol.Mode->AbsoluteMinY = XyBoundary.MinY;
|
|
ThcDev->AbsPtrDataAvailable = TRUE;
|
|
gBS->SignalEvent (ThcDev->AbsPtrProtocol.WaitForInput);
|
|
}
|
|
}
|
|
|
|
FreePool (ReadDataBuff);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Reads data from each Read Rx2 DMA PRD Table Entry until write pointer is equal to read pointer
|
|
Write pointer is updated after each PRD Table read is finished
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
@param[in] CurrentCBReadPointer Circullar Buffer Read Pointer
|
|
@param[in] CurrentCBWritePointer Circullar Buffer Write Pointer
|
|
|
|
**/
|
|
VOID
|
|
ThcDmaReadRx2 (
|
|
IN THC_DEV *ThcDev,
|
|
IN UINT8 CurrentCBWritePointer,
|
|
IN UINT8 CurrentCBReadPointer
|
|
)
|
|
{
|
|
THC_M_PRT_READ_DMA_CNTRL_2 ReadDmaCntrl2;
|
|
EFI_STATUS Status;
|
|
UINT8 CurrentPrdTable;
|
|
|
|
while ((CurrentCBWritePointer & POINTER_MASK) != (CurrentCBReadPointer & POINTER_MASK)) {
|
|
CurrentPrdTable = (UINT8) (CurrentCBWritePointer & POINTER_MASK);
|
|
THC_LOCAL_DEBUG(L"PrdTable %d CBWritePointer %d CBReadPointer %d CB 0x%X \n",
|
|
CurrentPrdTable,
|
|
CurrentCBWritePointer & POINTER_MASK,
|
|
CurrentCBReadPointer & POINTER_MASK,
|
|
CurrentCBWritePointer
|
|
)
|
|
Status = ThcDmaReadSingleReport (ThcDev, &ThcDev->DmaRead2, CurrentPrdTable);
|
|
if (EFI_ERROR (Status)) {
|
|
THC_LOCAL_DEBUG(L"ThcDmaReadRx2 ThcDmaReadbuffer error, failed to Read Data Buffer Status %r\n", Status)
|
|
DEBUG ((DEBUG_ERROR, "ThcDmaReadRx2 Error Read Data Buffer Status %r\n", Status));
|
|
//no return to avoid dead loop, always change Write Pointer, even on bad data
|
|
}
|
|
|
|
//Return PRD table to its initial state
|
|
ThcDmaFillSinglePrdTable (&ThcDev->DmaRead2, CurrentPrdTable);
|
|
|
|
if ((CurrentCBWritePointer + 1) == WRAPAROUND_VALUE_16) {
|
|
THC_LOCAL_DEBUG(L"WRAPAROUND_VALUE_16 \n")
|
|
ThcLibSetReadRx2WritePointer (ThcDev->PciBar0, POINTER_WRAPAROUND);
|
|
} else if ((CurrentCBWritePointer + 1) == WRAPAROUND_VALUE_0X90) {
|
|
THC_LOCAL_DEBUG(L"WRAPAROUND_VALUE_0X90 \n")
|
|
ThcLibSetReadRx2WritePointer (ThcDev->PciBar0, 0x0);
|
|
} else {
|
|
THC_LOCAL_DEBUG(L"WP +1\n")
|
|
ThcLibSetReadRx2WritePointer (ThcDev->PciBar0, CurrentCBWritePointer + 1);
|
|
}
|
|
|
|
ReadDmaCntrl2.Data = ThcLibGetReadRx2Data (ThcDev->PciBar0);
|
|
CurrentCBWritePointer = (UINT8) ReadDmaCntrl2.Fields.ThcPrdCbWritePointer;
|
|
}
|
|
}
|
|
|
|
/**
|
|
Writes data to a single Tx DMA PRD Table
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
@param[in] Buffer Data Container that will be sent to external device
|
|
@param[in] DataHeader Write Data Header
|
|
|
|
@retval EFI_BUFFER_TOO_SMALL THC DMA buffer is unable to fit that much data
|
|
@retval EFI_TIMEOUT DMA transaction did not finish in time
|
|
@retval EFI_SUCCESS Data sent
|
|
**/
|
|
EFI_STATUS
|
|
ThcDmaWriteTx (
|
|
IN THC_DEV *ThcDev,
|
|
IN UINT8 *Buffer,
|
|
IN THC_WRITE_DATA_HDR *DataHeader
|
|
)
|
|
{
|
|
PRD_TABLE *PrdTable;
|
|
UINT64 DataAddress;
|
|
UINT32 PrdEntryLength;
|
|
UINT32 WriteLength;
|
|
UINT16 EntryIndex;
|
|
UINT8 ByteAlignmentCount;
|
|
|
|
DataAddress = 0;
|
|
PrdEntryLength = 0;
|
|
EntryIndex = 0;
|
|
ByteAlignmentCount = 0;
|
|
PrdTable = (PRD_TABLE *) ThcDev->DmaWrite.CommonPrdBuffer;
|
|
|
|
if (DataHeader->WriteDataLength % 4 > 0) {
|
|
ByteAlignmentCount = 4 - DataHeader->WriteDataLength % 4;
|
|
}
|
|
|
|
if ((PrdTable->Entries[0].Length * PRD_MAX_ENTRIES) < (DataHeader->WriteDataLength + ByteAlignmentCount + sizeof (THC_WRITE_DATA_HDR))) {
|
|
return EFI_BUFFER_TOO_SMALL;
|
|
}
|
|
|
|
//
|
|
// Copy Header information, increase address and set remaining length of the first entry
|
|
//
|
|
DataAddress = LShiftU64 (PrdTable->Entries[EntryIndex].DestinationAddress, ADDRESS_SHIFT);
|
|
//
|
|
// To make sure DW alignment requirement is met driver will increase MSG size
|
|
//
|
|
if (ByteAlignmentCount > 0) {
|
|
DataHeader->WriteDataLength = DataHeader->WriteDataLength + ByteAlignmentCount;
|
|
}
|
|
CopyMem ((UINT8*) DataAddress, (UINT8*) DataHeader, sizeof (THC_WRITE_DATA_HDR));
|
|
DataHeader->WriteDataLength = DataHeader->WriteDataLength - ByteAlignmentCount;
|
|
DataAddress += sizeof (THC_WRITE_DATA_HDR);
|
|
PrdEntryLength = (UINT32) PrdTable->Entries[EntryIndex].Length - sizeof (THC_WRITE_DATA_HDR);
|
|
|
|
do {
|
|
PrdTable->Entries[EntryIndex].EndOfPrd = 0;
|
|
//
|
|
// Set write length for given Prd Entry
|
|
//
|
|
if (DataHeader->WriteDataLength >= PrdEntryLength) {
|
|
WriteLength = PrdEntryLength;
|
|
} else {
|
|
WriteLength = DataHeader->WriteDataLength;
|
|
}
|
|
//
|
|
// Put the data in the destination address
|
|
//
|
|
THC_LOCAL_DEBUG(L"ThcDmaWriteTx WriteLength %d\n", WriteLength)
|
|
CopyMem ((UINT8*) DataAddress, Buffer, WriteLength);
|
|
//
|
|
// Substract copied data from the WriteDataLength
|
|
//
|
|
DataHeader->WriteDataLength = DataHeader->WriteDataLength - WriteLength;
|
|
|
|
//
|
|
// Store new write length along with the header in Prd entry.
|
|
//
|
|
if (EntryIndex == 0) {
|
|
WriteLength += sizeof (THC_WRITE_DATA_HDR);
|
|
}
|
|
PrdTable->Entries[EntryIndex].Length = WriteLength;
|
|
|
|
if (DataHeader->WriteDataLength > 0) {
|
|
Buffer += WriteLength;
|
|
EntryIndex++;
|
|
DataAddress = LShiftU64 (PrdTable->Entries[EntryIndex].DestinationAddress, ADDRESS_SHIFT);
|
|
PrdEntryLength = (UINT32) PrdTable->Entries[EntryIndex].Length;
|
|
} else {
|
|
break;
|
|
}
|
|
} while (EntryIndex < ThcDev->DmaWrite.DriverPrdTable[0].NumOfConfiguredEntries);
|
|
|
|
//
|
|
// Fill Prd to meet DW alignment
|
|
//
|
|
if (ByteAlignmentCount > 0) {
|
|
PrdTable->Entries[EntryIndex].Length += ByteAlignmentCount;
|
|
DataAddress += WriteLength;
|
|
ZeroMem ((UINT8*) DataAddress, ByteAlignmentCount);
|
|
}
|
|
|
|
//
|
|
// Set End on the last PRD entry used
|
|
//
|
|
PrdTable->Entries[EntryIndex].EndOfPrd = 1;
|
|
|
|
//
|
|
// Start transfer
|
|
//
|
|
ThcLibSetWriteStartBit (ThcDev->PciBar0);
|
|
|
|
//
|
|
// Poll for Dma Complete
|
|
//
|
|
if (EFI_ERROR (ThcLibPollDmaComplete (ThcDev->PciBar0, WritePollingTimeout))) {
|
|
return EFI_TIMEOUT;
|
|
}
|
|
|
|
//
|
|
// Reset PRD table settings
|
|
//
|
|
ThcDmaFillSinglePrdTable (&ThcDev->DmaWrite, 0);
|
|
|
|
return EFI_SUCCESS;
|
|
}
|
|
|
|
/**
|
|
Unmaps and frees Driver Prd Tables
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
@param[in] ThcDma Dma that stores Driver PRD Table
|
|
|
|
**/
|
|
VOID
|
|
ThcDmaFreePrds (
|
|
IN THC_DEV *ThcDev,
|
|
IN THC_DMA *ThcDma
|
|
)
|
|
{
|
|
UINT16 PrdTableIndex;
|
|
|
|
for (PrdTableIndex = 0; PrdTableIndex < ThcDma->NumOfPrdTables; PrdTableIndex++) {
|
|
ThcDev->PciIo->Unmap (
|
|
ThcDev->PciIo,
|
|
ThcDma->DriverPrdTable[PrdTableIndex].Mapping
|
|
);
|
|
ThcDev->PciIo->FreeBuffer (
|
|
ThcDev->PciIo,
|
|
EFI_SIZE_TO_PAGES (ThcDma->BufferSize),
|
|
(UINT8 *) ThcDma->DriverPrdTable[PrdTableIndex].Buffer
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
Stop Touch Panel, brings it back to reset state
|
|
Freees all allocated memory and Thc device context
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
ThcStop (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
if (ThcDev == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "ThcStop ThcDev is already Stopped\n"));
|
|
return;
|
|
}
|
|
|
|
THC_LOCAL_DEBUG(L"ThcStop\n")
|
|
|
|
ThcStopAbsPtr (ThcDev);
|
|
ThcDisableEndDevice (ThcDev);
|
|
ThcPrintConfig (ThcDev);
|
|
ThcLibCleanUp (ThcDev->PciBar0);
|
|
|
|
//
|
|
// Free/Unmap Common Buffers and Prd Tables
|
|
//
|
|
if (ThcDev->DmaRead2.CommonPrdBuffer != 0) {
|
|
THC_LOCAL_DEBUG(L"ThcStop Free DmaRead2.CommonPrdBuffer\n")
|
|
ThcDev->PciIo->Unmap (
|
|
ThcDev->PciIo,
|
|
ThcDev->DmaRead2.CommonPrdBufferMapping
|
|
);
|
|
ThcDev->PciIo->FreeBuffer (
|
|
ThcDev->PciIo,
|
|
EFI_SIZE_TO_PAGES (sizeof (PRD_TABLE) * PRD_READ_TABLES_SUPPORTED),
|
|
(UINT8 *) ThcDev->DmaRead2.CommonPrdBuffer
|
|
);
|
|
ThcDmaFreePrds (ThcDev, &ThcDev->DmaRead2);
|
|
}
|
|
if (ThcDev->DmaWrite.CommonPrdBuffer != 0) {
|
|
THC_LOCAL_DEBUG(L"ThcStop Free DmaWrite.CommonPrdBuffer\n")
|
|
ThcDev->PciIo->Unmap (
|
|
ThcDev->PciIo,
|
|
ThcDev->DmaWrite.CommonPrdBufferMapping
|
|
);
|
|
ThcDev->PciIo->FreeBuffer (
|
|
ThcDev->PciIo,
|
|
EFI_SIZE_TO_PAGES (sizeof (PRD_TABLE) * PRD_WRITE_TABLES_SUPPORTED),
|
|
(UINT8 *) ThcDev->DmaWrite.CommonPrdBuffer
|
|
);
|
|
ThcDmaFreePrds (ThcDev, &ThcDev->DmaWrite);
|
|
}
|
|
|
|
//
|
|
// Restore original PCI attributes
|
|
//
|
|
ThcDev->PciIo->Attributes (
|
|
ThcDev->PciIo,
|
|
EfiPciIoAttributeOperationSet,
|
|
ThcDev->PciAttributes,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Close and Uninstall PCI I/O Protocol that was opened with PROTOCOL_BY_DRIVER
|
|
//
|
|
gBS->CloseProtocol (
|
|
ThcDev->ControllerHandle,
|
|
&gEfiPciIoProtocolGuid,
|
|
&ThcDev->PciIo,
|
|
ThcDev->ControllerHandle
|
|
);
|
|
gBS->UninstallMultipleProtocolInterfaces (
|
|
ThcDev->ControllerHandle,
|
|
&gEfiPciIoProtocolGuid,
|
|
&ThcDev->PciIo,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Done with the controller name table
|
|
//
|
|
FreeUnicodeStringTable (ThcDev->ControllerNameTable);
|
|
|
|
//
|
|
// Done with the driver context
|
|
//
|
|
ZeroMem (ThcDev, sizeof (THC_DEV));
|
|
FreePool (ThcDev);
|
|
}
|
|
|
|
/**
|
|
Polls on Thc Rx2 Circullar Buffers state
|
|
If CB Write and Read Pointer are not equal Read Rx2 Dma is trigerred
|
|
|
|
@param[in] Event Polling event
|
|
@param[in] Context Context of Thc device
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
ThcPolling (
|
|
IN EFI_EVENT Event,
|
|
IN VOID *Context
|
|
)
|
|
{
|
|
THC_DEV *ThcDev;
|
|
THC_M_PRT_READ_DMA_CNTRL_2 ReadDmaCntrl2;
|
|
UINT32 Timeout;
|
|
|
|
ThcDev = (THC_DEV *) Context;
|
|
|
|
if (ThcDev == NULL) {
|
|
DEBUG ((DEBUG_ERROR, "ThcPolling ThcDev is Null\n"));
|
|
return;
|
|
}
|
|
if (ThcDev->ReadDone) {
|
|
Timeout = PollingLoopTimeout;
|
|
ReadDmaCntrl2.Data = ThcLibGetReadRx2Data (ThcDev->PciBar0);
|
|
while (((UINT8)(ReadDmaCntrl2.Fields.ThcPrdCbWritePointer & POINTER_MASK)) != ((UINT8)(ReadDmaCntrl2.Fields.ThcPrdCbReadPointer & POINTER_MASK))) {
|
|
ThcDev->ReadDone = FALSE;
|
|
ThcDmaReadRx2 (ThcDev, (UINT8) ReadDmaCntrl2.Fields.ThcPrdCbWritePointer, (UINT8) ReadDmaCntrl2.Fields.ThcPrdCbReadPointer);
|
|
ReadDmaCntrl2.Data = ThcLibGetReadRx2Data (ThcDev->PciBar0);
|
|
if (((UINT8)(ReadDmaCntrl2.Fields.ThcPrdCbWritePointer & POINTER_MASK)) == ((UINT8)(ReadDmaCntrl2.Fields.ThcPrdCbReadPointer & POINTER_MASK))) {
|
|
ThcDev->ReadDone = TRUE;
|
|
}
|
|
if (Timeout == 0) {
|
|
DEBUG ((DEBUG_ERROR, "ThcPolling Timeout while reading DMA, possible interrupt storm\n"));
|
|
ASSERT (FALSE);
|
|
ThcDev->ReadDone = TRUE;
|
|
return;
|
|
}
|
|
MicroSecondDelay (10);
|
|
Timeout -= 10;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
Enables end point device.
|
|
- Reads all Touch Panels devices registers
|
|
- Sets TouchEnable
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Enabling completed
|
|
@retval EFI_DEVICE_ERROR TSSDONE not set or ERR set
|
|
@retval EFI_TIMEOUT Timeout
|
|
**/
|
|
EFI_STATUS
|
|
ThcEnableAfterReset (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
ThcReadConfig (ThcDev);
|
|
ThcPrintConfig (ThcDev);
|
|
|
|
ThcLibPrepareWriteConfigCmd (ThcDev->PciBar0);
|
|
ThcDev->DeviceRegisters.TouchCfg.Fields.TouchEnable = 0x1;
|
|
ThcLibWriteSeqData1 (ThcDev->PciBar0, ThcDev->DeviceRegisters.TouchCfg.Data);
|
|
ThcLibGo (ThcDev->PciBar0);
|
|
|
|
Status = ThcLibWaitCycleCompleted (ThcDev->PciBar0, CycleTimeout);
|
|
THC_LOCAL_DEBUG(L"ThcEnableEndDevice ThcLibWaitCycleCompleted Status: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "ThcEnableEndDevice error, Status %r\n", Status));
|
|
return Status;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/**
|
|
Reads HID Descriptor for non EDS complaint devices that do not support Single Finger Report.
|
|
Flow:
|
|
- send TCTL_REQUEST with Get Hid desc command
|
|
- waits for response
|
|
- Run Descriptor parser and populate all known Report Ids in Thc HID_INPUT_REPORT_TABLE
|
|
|
|
@param[in] ThcDev Context of Thc device
|
|
|
|
@retval EFI_SUCCESS Enabling completed
|
|
@retval EFI_NO_RESPONSE Device Did not respond to TCTLCMD
|
|
@retval EFI_TIMEOUT Timeout while waiting for response from the device
|
|
@retval EFI_OUT_OF_RESOURCES Unable to allocate buffer for Thc HID support
|
|
**/
|
|
EFI_STATUS
|
|
ThcReadHidDescriptor (
|
|
IN THC_DEV *ThcDev
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
THC_WRITE_DATA_HDR WriteData;
|
|
UINT32 Timeout;
|
|
THC_CTL ThcCtl;
|
|
UINT32 HidMessageLength;
|
|
UINT8 *Buffer;
|
|
|
|
THC_LOCAL_DEBUG(L"ThcReadHidDescriptor\n")
|
|
|
|
ThcCtl.TctlCmdCode = TCTL_GET_HID_REPORT_DESCRIPTOR;
|
|
ThcCtl.TctlStatus = TCTL_SUCCESS;
|
|
|
|
WriteData.WriteDataType = TCTL_REQUEST;
|
|
WriteData.WriteDataLength = sizeof (ThcCtl);
|
|
|
|
ThcDev->HidDataAvailable = FALSE;
|
|
ThcDev->HidActive = TRUE;
|
|
ThcDev->HidBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES (THC_MAX_HID_BUFFER_SIZE), sizeof (UINT8));
|
|
if (ThcDev->HidBuffer == NULL) {
|
|
return EFI_OUT_OF_RESOURCES;
|
|
}
|
|
Buffer = ThcDev->HidBuffer;
|
|
|
|
ZeroMem (ThcDev->HidBuffer, THC_MAX_HID_BUFFER_SIZE);
|
|
|
|
Status = ThcDmaWriteTx (ThcDev, (UINT8*) &ThcCtl, &WriteData);
|
|
THC_LOCAL_DEBUG(L"ThcReadHidDescriptor ThcDmaWriteTx: %r\n", Status)
|
|
if (EFI_ERROR (Status)) {
|
|
return Status;
|
|
}
|
|
|
|
Timeout = HidResponseTimeout;
|
|
|
|
//
|
|
// Wait for Response
|
|
//
|
|
if (Timeout > 0) {
|
|
THC_LOCAL_DEBUG(L"ThcReadHidDescriptor Waiting for Response \n")
|
|
DEBUG ((DEBUG_INFO, "ThcReadHidDescriptor Waiting for Response \n"));
|
|
do {
|
|
if (ThcDev->HidDataAvailable == TRUE && ThcDev->ReadDone == TRUE) {
|
|
Status = EFI_SUCCESS;
|
|
break;
|
|
}
|
|
MicroSecondDelay (1000);
|
|
Timeout--;
|
|
} while (Timeout > 0);
|
|
|
|
if (Timeout == 0) {
|
|
THC_LOCAL_DEBUG(L"ThcReadHidDescriptor Response Timeout\n")
|
|
DEBUG ((DEBUG_ERROR, "ThcReadHidDescriptor Response Timeout\n"));
|
|
return EFI_TIMEOUT;
|
|
}
|
|
}
|
|
|
|
ThcDev->HidDataAvailable = FALSE;
|
|
ThcDev->HidActive = FALSE;
|
|
|
|
//
|
|
// Restore initial pointer
|
|
//
|
|
ThcDev->HidBuffer = Buffer;
|
|
//
|
|
// Calculate Recieved data length
|
|
//
|
|
HidMessageLength = ((RAW_DATA_HEADER*) (ThcDev->HidBuffer))->ReadDataSize;
|
|
//
|
|
// Shift the pointer to data location
|
|
//
|
|
ThcDev->HidBuffer += sizeof (RAW_DATA_HEADER);
|
|
//
|
|
// Capture TCTL result
|
|
//
|
|
CopyMem (&ThcCtl, ThcDev->HidBuffer, sizeof (THC_CTL));
|
|
DEBUG ((DEBUG_INFO, "ThcReadHidDescriptor\n ThcCtl.TctlCmdCode = %d\n ThcCtl.TctlStatus = %d\n", ThcCtl.TctlCmdCode, ThcCtl.TctlStatus));
|
|
THC_LOCAL_DEBUG(L"ThcReadHidDescriptor\n ThcCtl.TctlCmdCode = %d\n ThcCtl.TctlStatus = %d\n", ThcCtl.TctlCmdCode, ThcCtl.TctlStatus)
|
|
if (ThcCtl.TctlStatus != TCTL_SUCCESS) {
|
|
return EFI_NO_RESPONSE;
|
|
}
|
|
|
|
//
|
|
// Shift the pointer to the actual HID Descriptor
|
|
//
|
|
ThcDev->HidBuffer += sizeof (THC_CTL) -1; // Ignore TctlData
|
|
THC_LOCAL_DEBUG(L"ThcReadHidDescriptor HidMessageLength = %d\n", HidMessageLength)
|
|
//
|
|
// Parse HID data
|
|
//
|
|
HidParseDescriptor (ThcDev, ThcDev->HidBuffer, HidMessageLength - sizeof (THC_CTL));
|
|
|
|
THC_LOCAL_DEBUG(L"ThcReadHidDescriptor End\n")
|
|
return Status;
|
|
}
|