📄 pmic_connectivity.cpp
字号:
/*---------------------------------------------------------------------------
* Copyright (C) 2006, Freescale Semiconductor, Inc. All Rights Reserved.
* THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
* AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
*--------------------------------------------------------------------------*/
//
// File:pmic_connectivity.cpp
//
// This file contains the SDK interface that is used by applications and other drivers
// to access connectivity feature of the MC13783.
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <Devload.h>
#include <ceddk.h>
#include "socarm_macros.h"
#include "regs.h"
#include "regs_connectivity.h"
#include "pmic_lla.h"
#include "pmic_ioctl.h"
#include "pmic_connectivity.h"
#include "pmic_convity_priv.h"
#ifdef DEBUG
// Debug zone bit positions
#define ZONEID_ERROR 0
#define ZONEID_WARN 1
#define ZONEID_INIT 2
#define ZONEID_FUNC 3
#define ZONEID_INFO 4
// Debug zone masks
#define ZONEMASK_ERROR (1 << ZONEID_ERROR)
#define ZONEMASK_WARN (1 << ZONEID_WARN)
#define ZONEMASK_INIT (1 << ZONEID_INIT)
#define ZONEMASK_FUNC (1 << ZONEID_FUNC)
#define ZONEMASK_INFO (1 << ZONEID_INFO)
// Debug zone args to DEBUGMSG
#define ZONE_ERROR DEBUGZONE(ZONEID_ERROR)
#define ZONE_WARN DEBUGZONE(ZONEID_WARN)
#define ZONE_INIT DEBUGZONE(ZONEID_INIT)
#define ZONE_FUNC DEBUGZONE(ZONEID_FUNC)
#define ZONE_INFO DEBUGZONE(ZONEID_INFO)
extern DBGPARAM dpCurSettings;
#endif// DEBUG
//-----------------------------------------------------------------------------
// External Functions
//-----------------------------------------------------------------------------
// External Variables
extern HANDLE hPMI;
//-----------------------------------------------------------------------------
// Defines
#define CONVITY_INTR_USBI 0
#define CONVITY_INTR_IDI 1
#define CONVITY_INTR_SE1I 2
#define CONVITY_INTR_CKDETI 3
#define NUM_CONVITY_INTR 4
#define MC13783_INT_SEN0_CONVITYBITS_LSH 16
#define MC13783_INT_SEN0_CONVITYBITS_WID 7
#define MC13783_INT_SEN0_CONVITYBITS_USB4V4S (1 << 0)
#define MC13783_INT_SEN0_CONVITYBITS_USB2V0S (1 << 1)
#define MC13783_INT_SEN0_CONVITYBITS_USB0V8S (1 << 2)
#define MC13783_INT_SEN0_CONVITYBITS_IDFLOATS (1 << 3)
#define MC13783_INT_SEN0_CONVITYBITS_IDGNDS (1 << 4)
#define MC13783_INT_SEN0_CONVITYBITS_SE1S (1 << 5)
#define MC13783_INT_SEN0_CONVITYBITS_CKDETS (1 << 6)
#define ENTRY_MSG DEBUGMSG(ZONE_FUNC, (TEXT("+%s()\r\n"), __WFUNCTION__))
#define EXIT_MSG DEBUGMSG(ZONE_FUNC, (TEXT("-%s()\r\n"), __WFUNCTION__))
//-----------------------------------------------------------------------------
// Types
// This enumeration is used to track the current state of each device handle.
typedef enum
{
HANDLE_FREE, /* Handle is available for use. */
HANDLE_IN_USE /* Handle is currently in use. */
} HANDLE_STATE;
/*
* This structure maintains the current state of the connectivity driver. This
* includes both the PMIC hardware state as well as the device handle and
* callback states.
*/
typedef struct
{
PMIC_CONVITY_HANDLE handle; /* Device handle. */
HANDLE_STATE handleState; /* Device handle
state. */
PMIC_CONVITY_MODE mode; /* Device mode. */
PMIC_CONVITY_CALLBACK callback; /* Event callback
function pointer. */
PMIC_CONVITY_EVENTS eventMask; /* Event mask. */
PMIC_CONVITY_USB_SPEED usbSpeed; /* USB connection
speed. */
PMIC_CONVITY_USB_MODE usbMode; /* USB connection
mode. */
PMIC_CONVITY_USB_POWER_IN usbPowerIn; /* USB transceiver
power source. */
PMIC_CONVITY_USB_POWER_OUT usbPowerOut; /* USB transceiver
power output
level. */
PMIC_CONVITY_USB_TRANSCEIVER_MODE usbXcvrMode; /* USB transceiver
mode. */
unsigned int usbDlpDuration; /* USB Data Line
Pulsing duration. */
PMIC_CONVITY_USB_OTG_CONFIG usbOtgCfg; /* USB OTG
configuration
options. */
PMIC_CONVITY_RS232_INTERNAL rs232CfgInternal; /* RS-232 internal
connections. */
PMIC_CONVITY_RS232_EXTERNAL rs232CfgExternal; /* RS-232 external
connections. */
BOOL rs232TxTristated; /* RS-232 TX state */
PMIC_CONVITY_CEA936_DETECTION_CONFIG cea936DetectCfg; /* CEA-936 device
detection circuitry */
} PMIC_CONVITY_STATE_STRUCT;
//-----------------------------------------------------------------------------
// Global Variables
// This structure defines the reset/power on state for the Connectivity driver.
static const PMIC_CONVITY_STATE_STRUCT reset =
{
0,
HANDLE_FREE,
USB,
NULL,
(PMIC_CONVITY_EVENTS)0,
USB_FULL_SPEED,
USB_PERIPHERAL,
USB_POWER_INTERNAL,
USB_POWER_3V3,
USB_TRANSCEIVER_OFF,
0,
(PMIC_CONVITY_USB_OTG_CONFIG)(USB_VBUS_CURRENT_LIMIT_HIGH),
RS232_TX_USE0VM_RX_UDATVP,
RS232_TX_UDM_RX_UDP,
FALSE,
ACCESSORY_ID_DP150KPU
};
// This structure maintains the current state of the Connectivity driver.
static PMIC_CONVITY_STATE_STRUCT convity;
/*
* We use a mutex to ensure that no race condition arises in register states (inside ioctl handlers)
* as well as convity data structure between the API calls and interrupt service thread.
*/
static CRITICAL_SECTION mutex;
static PMIC_PARAM_CONVITY_OP param;
static HANDLE hThread = NULL;
static bool threadContinue = 0;
// data structures that help handle all the connectivity interrupts in a loop.
static HANDLE hEventTab[] = {NULL, NULL, NULL, NULL};
static WCHAR* evtNames[] =
{
TEXT("EVENT_CONVITY_USBI"),
TEXT("EVENT_CONVITY_IDI"),
TEXT("EVENT_CONVITY_SE1I"),
TEXT("EVENT_CONVITY_CKDETI")
};
static PMIC_INT_ID interruptTab[] =
{
PMIC_MC13783_INT_USBI,
PMIC_MC13783_INT_IDI,
PMIC_MC13783_INT_SE1I,
PMIC_MC13783_INT_CKDETI
};
//-----------------------------------------------------------------------------
// Local Variables
//-----------------------------------------------------------------------------
// Local Functions
PMIC_STATUS PmicConvityInit(void)
{
ENTRY_MSG;
// Initialize the driver state to default state.
convity = reset;
// Initialize mutex.
InitializeCriticalSection(&mutex);
EXIT_MSG;
return PMIC_SUCCESS;
}
void PmicConvityDeinit(void)
{
ENTRY_MSG;
// Free mutex.
DeleteCriticalSection(&mutex);
EXIT_MSG;
}
// Read the sense bits relevant to Connectivity from MC13783 interrupt sense
// 0 register.
static UINT32 GetSenseBits()
{
UINT32 addr, temp;
addr = MC13783_INT_SEN0_ADDR;
if(!DeviceIoControl(hPMI, PMIC_IOCTL_LLA_READ_REG, &addr, sizeof(addr),
&temp, sizeof(temp), NULL, NULL))
return 0;
return CSP_BITFEXT(temp, MC13783_INT_SEN0_CONVITYBITS);
}
// Look at the interrupt, new and previous sense bits and find out the occurred events
static PMIC_CONVITY_EVENTS GetSignalledEvents(int intrIndex, UINT32 oldSenseBits,
UINT32 newSenseBits)
{
UINT32 signals = 0;
switch (intrIndex)
{
case CONVITY_INTR_USBI:
// Check if 4.4V sense bit has changed.
if ((oldSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB4V4S) ^
(newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB4V4S))
{
signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB4V4S) ?
USB_DETECT_4V4_RISE : USB_DETECT_4V4_FALL;
}
// Check if 2.0V sense bit has changed.
if ((oldSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB2V0S) ^
(newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB2V0S))
{
signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB2V0S) ?
USB_DETECT_2V0_RISE : USB_DETECT_2V0_FALL;
}
// Check if 0.8V sense bit has changed.
if ((oldSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB0V8S) ^
(newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB0V8S))
{
signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_USB0V8S) ?
USB_DETECT_0V8_RISE : USB_DETECT_0V8_FALL;
}
break;
case CONVITY_INTR_IDI:
// Look at the current value of IDFLOATS and IDGNDS bits and determine the event.
// IDFLOATS IDGNDS Meaning
// ============================================
// 0 0 Non-USB accessory is attached.
// 0 1 A type plug (USB host) is attached.
// 1 0 B type plug (USB peripheral, OTG device
// or no device) is attached.
// 1 1 Factory mode.
if (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_IDFLOATS)
{
signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_IDGNDS) ?
USB_DETECT_FACTORY_MODE : USB_DETECT_MINI_B;
}
else
{
signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_IDGNDS) ?
USB_DETECT_MINI_A : USB_DETECT_NON_USB_ACCESORY;
}
break;
case CONVITY_INTR_SE1I:
// Look at SE1S to find out if it is rise or fall event.
signals |= (newSenseBits & MC13783_INT_SEN0_CONVITYBITS_SE1S) ?
USB_DETECT_SE1_RISE : USB_DETECT_SE1_FALL;
break;
case CONVITY_INTR_CKDETI:
// CKDETI occurs only when CKDETS changed from 0 to 1. (CKDETS is L2H only).
signals |= USB_DETECT_CKDETECT;
break;
default:
break;
}
return (PMIC_CONVITY_EVENTS)signals;
}
// Thread that waits for interrupt events to be signalled. Upon occurrence of an interrupt,
// it finds out the event bits to inform the callback function.
static BOOL PmicConvityIsrThreadProc(LPVOID lpParam)
{
// This variable keeps the previous known value of the sense bits. Upon occurrence
// of an interrupt, the current values of sense bits and this (previous) value is used
// to find out which event has occurred. Needed for USBI related sense bits only.
static UINT32 senseBits = 0;
int iRetVal;
int iCount = 0;
UINT32 newSenseBits;
UINT32 events;
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
senseBits = GetSenseBits();
while(threadContinue != 0)
{
iRetVal = WaitForMultipleObjects(NUM_CONVITY_INTR, hEventTab, FALSE, INFINITE);
if ((iRetVal >= WAIT_OBJECT_0) && (iRetVal <= WAIT_OBJECT_0 + NUM_CONVITY_INTR - 1))
{
iRetVal -= WAIT_OBJECT_0;
newSenseBits = GetSenseBits();
events = GetSignalledEvents(iRetVal, senseBits, newSenseBits);
events &= convity.eventMask;
if ((convity.callback != NULL) && events)
(*convity.callback)(events);
// save the new sense bits in the global variable senseBits.
senseBits = newSenseBits;
// inform the system that interrupt handling is complete.
PmicInterruptHandlingComplete(interruptTab[iRetVal]);
}
}
ExitThread(TRUE);
return TRUE;
}
// cleans up callback related data structures.
static PMIC_STATUS cleanup()
{
int i;
threadContinue = 0;
for (i = 0; i < NUM_CONVITY_INTR; i++)
{
if (hEventTab[i])
{
PmicInterruptDeregister(interruptTab[i]);
hEventTab[i] = NULL;
}
}
hThread = NULL;
convity.callback = (PMIC_CONVITY_CALLBACK)NULL;
convity.eventMask = (PMIC_CONVITY_EVENTS)0;
return PMIC_SUCCESS;
}
/*!
* Attempt to open and gain exclusive access to the PMIC connectivity
* hardware. An initial operating mode must also be specified.
*
* If the open request is successful, then a numeric handle is returned
* and this handle must be used in all subsequent function calls. The
* same handle must also be used in the pmic_convity_close() call when use
* of the PMIC connectivity hardware is no longer required.
*
* @param handle device handle from open() call
* @param mode initial connectivity operating mode
*
* @return PMIC_SUCCESS if the open request was successful
*/
PMIC_STATUS PmicConvityOpen(
PMIC_CONVITY_HANDLE *const handle,
const PMIC_CONVITY_MODE mode)
{
PMIC_STATUS rc = PMIC_ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -