⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmic.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
字号:
//------------------------------------------------------------------------------
//
//  Copyright (C) 2004 - 2005, Freescale Semiconductor, Inc. All Rights Reserved
//  THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
//  BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
//  FREESCALE SEMICONDUCTOR, INC.
//
//------------------------------------------------------------------------------
//
//  File:  pmic.c
//
//  This file contains the OAL support code for the PMIC interface.
//
//-----------------------------------------------------------------------------
#include <bsp.h>
#include "regs.h"
#include "regs_regulator.h"

//-----------------------------------------------------------------------------
// External Functions
extern void SC_Sleep(DWORD);
extern BOOL SC_ReleaseMutex(HANDLE hMutex);
extern DWORD SC_WaitForMultiple(DWORD cObjects, 
    CONST HANDLE * lphObjects, BOOL fWaitAll, DWORD dwTimeout);
extern VOID OALClockSetGatingMode(DDK_CLOCK_GATE_INDEX index, 
    DDK_CLOCK_GATE_MODE mode);
    
//-----------------------------------------------------------------------------
// External Variables
extern PCSP_IOMUX_REGS g_pIOMUX;
extern PCSP_EPIT_REG g_pEPIT;
extern BOOL g_oalPostInit;
extern HANDLE g_oalPmicMutex;

//-----------------------------------------------------------------------------
// Defines

#define CSPI_MAX_DIV            9     // 2^9= 512

#define PMIC_SPI_DATA_LSH       0
#define PMIC_SPI_NULL_LSH       24
#define PMIC_SPI_ADDR_LSH       25
#define PMIC_SPI_RW_LSH         31

#define PMIC_SPI_DATA_WID       24
#define PMIC_SPI_NULL_WID       1
#define PMIC_SPI_ADDR_WID       6
#define PMIC_SPI_RW_WID         1

#define PMIC_SPI_RW_READ        0
#define PMIC_SPI_RW_WRITE       1

//-----------------------------------------------------------------------------
// Types


//-----------------------------------------------------------------------------
// Global Variables


//-----------------------------------------------------------------------------
// Local Variables
static PCSP_CSPI_REG g_pCSPI;
static UINT32 g_INTREG;
static DDK_CLOCK_GATE_INDEX g_CGI;


//-----------------------------------------------------------------------------
// Functions


//-----------------------------------------------------------------------------
//
//  Function: OALPmicLock
//
//  Obtains a lock for the CSPI hardware so that the OAL and PMIC core driver
//  can safely share access.
//
//  Parameters:
//      None.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void OALPmicLock(void)
{    
        
    if (g_oalPostInit)
    {
        SC_WaitForMultiple(1, &g_oalPmicMutex, FALSE, INFINITE);        
    }

    OALClockSetGatingMode(g_CGI, DDK_CLOCK_GATE_MODE_ENABLED_ALL);
    INSREG32BF(&g_pCSPI->CONREG, CSPI_CONREG_EN, CSPI_CONREG_EN_ENABLE);

    // Store the current INTREG configuration and turn
    // off all interrupts
    g_INTREG = INREG32(&g_pCSPI->INTREG);
    OUTREG32(&g_pCSPI->INTREG, 0);

}


//-----------------------------------------------------------------------------
//
//  Function: OALPmicUnlock
//
//  Release the lock previously obtained by OALPmicLock.
//
//  Parameters:
//      None.
//
//  Returns:
//      None.
//
//-----------------------------------------------------------------------------
static void OALPmicUnlock(void)
{    
    // Restore INTREG configuration
    OUTREG32(&g_pCSPI->INTREG, g_INTREG);

    INSREG32BF(&g_pCSPI->CONREG, CSPI_CONREG_EN, CSPI_CONREG_EN_DISABLE);
    OALClockSetGatingMode(g_CGI, DDK_CLOCK_GATE_MODE_DISABLED);

    if (g_oalPostInit)
    {
        SC_ReleaseMutex(g_oalPmicMutex);
    }
}


//-----------------------------------------------------------------------------
//
//  Function: OALPmicCalcDiv
//
//  Calculates the CSPI data rate divider needed to obtain the specified
//  data transfer frequency.
//
//  Parameters:
//      freq
//          [in] Target CSPI bit clock frequency.
//
//  Returns:
//      Calculated divider for the CSPI DATARATE bits.
//
//-----------------------------------------------------------------------------
static UINT32 OALPmicCalcDiv(UINT32 freq)
{    
    UINT32 div;
    UINT32 cspiClk;

    // CSPI uses IPG_CLK as clock input
    cspiClk = ((BSP_ARGS *)IMAGE_SHARE_ARGS_UA_START)->clockFreq[DDK_CLOCK_SIGNAL_IPG];

    for (div = 2; (div < CSPI_MAX_DIV) && ((cspiClk >> div) > freq); div++);

    return div - 2;
}

//-----------------------------------------------------------------------------
//
//  Function: OALPmicExchange
//
//  Performs a data exchange with the PMIC.
//
//  Parameters:
//      packet
//          [in] Read/Write packet sent to the PMIC
//
//      data
//          [in] data read from the exchange
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
static BOOL OALPmicExchange(UINT32 packet, PUINT32 pData)
{   
    // Write the packet to the TXFIFO
    OUTREG32(&g_pCSPI->TXDATA, packet);

    // Start the exchange
    INSREG32BF(&g_pCSPI->CONREG, CSPI_CONREG_XCH, CSPI_CONREG_XCH_EN);
    
    // Wait until transaction is complete
    while (!(INREG32(&g_pCSPI->STATREG) & CSP_BITFMASK(CSPI_STATREG_RR)))
    {
        if (g_oalPostInit)
        {
            SC_Sleep(0);
        }
    };

    // Read the data
    *pData = INREG32(&g_pCSPI->RXDATA);
    
    return TRUE;
    
}


//-----------------------------------------------------------------------------
//
//  Function: OALPmicWrite
//
//  Writes data to the specified PMIC register address.
//
//  Parameters:
//      addr
//          [in] PMIC register address
//
//      data
//          [in] data to write
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL OALPmicWrite(UINT32 addr, UINT32 data)
{
    BOOL rc;
    UINT32 temp;    
    
    UINT32 packet = CSP_BITFVAL(PMIC_SPI_RW, PMIC_SPI_RW_WRITE);

    CSP_BITFINS(packet, PMIC_SPI_DATA, data);
    CSP_BITFINS(packet, PMIC_SPI_ADDR, addr);    

    // Transfer the packet and discard the data
    OALPmicLock();
    rc = OALPmicExchange(packet, &temp);
    OALPmicUnlock();

    return rc;
    
}

//-----------------------------------------------------------------------------
//
//  Function: OALPmicRead
//
//  Reads data from the specified PMIC register address.
//
//  Parameters:
//      addr
//          [in] PMIC register address
//
//      data
//          [out] data read
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL OALPmicRead(UINT32 addr, PUINT32 pData)
{
    BOOL rc;
    
    UINT32 packet = CSP_BITFVAL(PMIC_SPI_RW, PMIC_SPI_RW_READ);

    CSP_BITFINS(packet, PMIC_SPI_ADDR, addr);

    // Transfer the packet and read the data
    OALPmicLock();
    rc = OALPmicExchange(packet, pData);
    OALPmicUnlock();

    return rc;
}


//-----------------------------------------------------------------------------
//
//  Function: OALPmicWriteMasked
//
//  Writes data to particular set of bits within a specified PMIC register 
//  address.
//
//  Parameters:
//      addr
//          [in] PMIC register address
//
//      mask
//          [in] Bit mask for specifying the bits to be written
//
//      data
//          [in] data to write
//
// Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL OALPmicWriteMasked(UINT32 addr, UINT32 mask, UINT32 data)
{   
    BOOL rc = FALSE;
    UINT32 temp;    
    UINT32 packet = CSP_BITFVAL(PMIC_SPI_RW, PMIC_SPI_RW_READ);

    CSP_BITFINS(packet, PMIC_SPI_ADDR, addr);

    // Transfer the packet and read the data
    OALPmicLock();
    if (!OALPmicExchange(packet, &temp))
    {
        ERRORMSG(TRUE, (_T("OALPmicExchange failed\r\n")));
        goto cleanUp;
    }

    CSP_BITFINS(packet, PMIC_SPI_RW, PMIC_SPI_RW_WRITE);
    CSP_BITFINS(packet, PMIC_SPI_DATA, (temp & (~mask)) | (data & mask));
        
    // Transfer the packet and discard the data    
    if (!OALPmicExchange(packet, &temp))
    {
        ERRORMSG(TRUE, (_T("OALPmicExchange failed\r\n")));
        goto cleanUp;
    }

    rc = TRUE;
    
cleanUp:
    OALPmicUnlock();

    return rc;
    
}


//-----------------------------------------------------------------------------
//
//  Function: OALPmicSetSupplyVoltages
//
//  Configures the normal and standby voltages for the CPU.
//
//  Parameters:
//      voltCodeNormal
//          [in] Voltage code for the PMIC normal (non-DVS) voltage
//
//      voltCodeStandby
//          [in] Voltage code for the PMIC standby voltage
//
//  Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL OALPmicSetSupplyVoltages(UINT32 voltCodeNormal, UINT32 voltCodeStandby)
{
    BOOL rc;
    DWORD dwStart;
    
    rc = OALPmicWriteMasked(MC13783_SW0_ADDR, 
        CSP_BITFMASK(MC13783_SW0_SW1A) | 
        CSP_BITFMASK(MC13783_SW0_SW1ASTBY), 
        CSP_BITFVAL(MC13783_SW0_SW1A, voltCodeNormal) |
        CSP_BITFVAL(MC13783_SW0_SW1ASTBY, voltCodeStandby));

    // Wait ~1 msec for the supply voltage to settle
    dwStart = INREG32(&g_pEPIT->CNT);
    while((INT32) (dwStart - INREG32(&g_pEPIT->CNT) - g_oalTimer.countsPerMSec) < 0);

    return rc;
}


//-----------------------------------------------------------------------------
//
//  Function: OALPmicInit
//
//  Initializes the PMIC interface for OAL communication.
//
//  Parameters:
//      voltCodeNormal
//          [in] Voltage code for the PMIC normal (non-DVS) voltage
//
//      voltCodeStandby
//          [in] Voltage code for the PMIC standby voltage
//
//  Returns:
//      Returns TRUE if successful, otherwise returns FALSE.
//
//-----------------------------------------------------------------------------
BOOL OALPmicInit(UINT32 voltCodeNormal, UINT32 voltCodeStandby)
{
    BOOL rc = FALSE;
    UINT32 temp;

#if (BSP_PMIC_CSPI_PORT == 1)
    g_CGI = DDK_CLOCK_GATE_INDEX_CSPI1;

    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI1_SPI_RDY, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI1_SCLK, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI1_SS2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI1_SS1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI1_SS0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI1_MISO, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI1_MOSI, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    g_pCSPI = (PCSP_CSPI_REG) OALPAtoUA(CSP_BASE_REG_PA_CSPI1);
#elif (BSP_PMIC_CSPI_PORT == 2)
    g_CGI = DDK_CLOCK_GATE_INDEX_CSPI2;

    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI2_SPI_RDY, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI2_SCLK, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI2_SS2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI2_SS1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI2_SS0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI2_MISO, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_CSPI2_MOSI, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    g_pCSPI = (PCSP_CSPI_REG) OALPAtoUA(CSP_BASE_REG_PA_CSPI2);
#else
    #error "Invalid PMIC CSPI port"
#endif

    if (g_pCSPI == NULL)
    {
        OALMSG(OAL_ERROR, (_T("OALPmicInit: OALPAtoUA returned NULL\r\n")));
        goto cleanUp;
    }

    // Turn on CSPI clocks
    OALClockSetGatingMode(g_CGI, DDK_CLOCK_GATE_MODE_ENABLED_ALL);

    // Configure the CSPI interface and enable it before writing to  
    // other CSPI registers
    OUTREG32(&g_pCSPI->CONREG,
        CSP_BITFVAL(CSPI_CONREG_EN, CSPI_CONREG_EN_ENABLE) |
        CSP_BITFVAL(CSPI_CONREG_MODE, CSPI_CONREG_MODE_MASTER) |
        CSP_BITFVAL(CSPI_CONREG_XCH, CSPI_CONREG_XCH_IDLE) |
        CSP_BITFVAL(CSPI_CONREG_SMC, CSPI_CONREG_SMC_XCH) |
        CSP_BITFVAL(CSPI_CONREG_POL, CSPI_CONREG_POL_ACTIVE_HIGH) |
        CSP_BITFVAL(CSPI_CONREG_PHA, CSPI_CONREG_PHA0) |
        CSP_BITFVAL(CSPI_CONREG_SSCTL, CSPI_CONREG_SSCTL_ASSERT) |
        CSP_BITFVAL(CSPI_CONREG_SSPOL, CSPI_CONREG_SSPOL_ACTIVE_HIGH) |
        CSP_BITFVAL(CSPI_CONREG_BITCOUNT, CSPI_CONREG_BITCOUNT_32BIT) |
        CSP_BITFVAL(CSPI_CONREG_DATARATE, OALPmicCalcDiv(BSP_PMIC_CSPI_FREQ)) |
        CSP_BITFVAL(CSPI_CONREG_DRCTL, CSPI_CONREG_DRCTL_DONTCARE) |
        CSP_BITFVAL(CSPI_CONREG_CHIPSELECT, CSPI_CONREG_SS0));

    OUTREG32(&g_pCSPI->INTREG, 0);
    OUTREG32(&g_pCSPI->DMAREG, 0);
    OUTREG32(&g_pCSPI->TESTREG, 0);

    // Turn the CSPI module and clocks off to save power between transfers
    INSREG32BF(&g_pCSPI->CONREG, CSPI_CONREG_EN, CSPI_CONREG_EN_DISABLE);
    OALClockSetGatingMode(g_CGI, DDK_CLOCK_GATE_MODE_DISABLED);

    // Configure muxing for IPP_PMIC_INT (PWRREADY) pin
    OAL_IOMUX_SET_MUX(g_pIOMUX, DDK_IOMUX_PIN_GPIO1_5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);

    rc = OALPmicSetSupplyVoltages(voltCodeNormal, voltCodeStandby);

    OALPmicRead(MC13783_SW0_ADDR, &temp);
    OALMSGS(OAL_INFO, (_T("SW1A voltages:  0x%x (normal = %d, DVS = %d, standby = %d)\r\n"), 
        temp, CSP_BITFEXT(temp, MC13783_SW0_SW1A), CSP_BITFEXT(temp, MC13783_SW0_SW1A),
        CSP_BITFEXT(temp, MC13783_SW0_SW1ASTBY)));

    OALPmicRead(MC13783_SW4_ADDR, &temp);
    OALMSGS(OAL_INFO, (_T("SW1A configuration: 0x%x (mode = %d, standby mode = %d, DVS speed = %d, panic = %d, soft start = %d)\r\n"), 
        temp, CSP_BITFEXT(temp, MC13783_SW4_SW1AMODE), CSP_BITFEXT(temp, MC13783_SW4_SW1ASTBYMODE),
        CSP_BITFEXT(temp, MC13783_SW4_SW1ADVSSPEED), CSP_BITFEXT(temp, MC13783_SW4_SW1APANIC), 
        CSP_BITFEXT(temp, MC13783_SW4_SW1ASFST)));
    
cleanUp:
    
    return rc;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -