Files
banban/ql-bootloader/common/src/pmic.c
T

1984 lines
60 KiB
C

/*--------------------------------------------------------------------------------------------------------------------
(C) Copyright 2006, 2007 Marvell DSPC Ltd. All Rights Reserved.
-------------------------------------------------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------------------------------------------------
INTEL CONFIDENTIAL
Copyright 2006 Intel Corporation All Rights Reserved.
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 contains trade secrets and proprietary and confidential information of
Intel or its suppliers and licensors. The Material 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.
-------------------------------------------------------------------------------------------------------------------*/
/*********************************************************************
* M O D U L E B O D Y *
**********************************************************************
* Title: I2C package *
* *
* Filename: I2C.c *
* *
* Target, platform: Common Platform, HW platform *
* *
* Authors: Adi Dayan *
* *
* Description: *
* *
* Notes: *
**********************************************************************/
/************* External include definitions ***************************/
/************************** MACROS ***************************************/
#include "pmic.h"
#include "ningbo.h"
#include "guilin.h"
#include "guilin_lite.h"
#include "guilin_lite2.h"
#include "guilin_lite3.h"
#include "bsp.h"
unsigned char pmic_id=PMIC_UNAVAILABLE;
/************* External include definitions ***************************/
volatile unsigned long I2C_REGISTER_BASE_ADDR = 0xD4037000;
#define PMU_XCGR_READ (( volatile UINT32 *)(0xD4051024))
#define I2C_FUN_CLK_ADD (( volatile UINT32 *)(0xD4051024))
#define I2C_APB_CLK_ADD (( volatile UINT32 *)(0xD401502c))
#define PMU_XCGR_EN_I2C_FUN_CLK ((0x1 << 22) |(0x1 << 6))
#define I2C_APB_CLK_ENABLE 0x3
#define I2C_APB_RESET 0x4
#define I2C_DEVICE_ERROR 0xDEADBEEF
#define I2C_STATUS_ARRAY_SIZE 4
#define I2C_RECORD_FLAG 0x494E4954
/*********************** Sub-Package Parameters *************************/
/* I2C device status*/
typedef struct I2CDeviceStatus
{
UINT32 RecordFlag;
UINT32 BaseAddress;
UINT32 SlaveAddress;
UINT32 DeviceStatus;
} I2CDeviceStatus;
I2CDeviceStatus I2CStatusArray[I2C_STATUS_ARRAY_SIZE];
typedef void (*I2CMasterNotifyDataReceived)( UINT8 * , UINT16 , UINT16 );
typedef struct
{
UINT8 activeSlaveAddress;
UINT8 *RxBufferPtr;
UINT16 dataSize;
UINT16 ID;
I2CMasterNotifyDataReceived callBack;
} I2C_ReceiveRequestParams;
/**********************************************************************************/
static BOOL _repeat_start = TRUE;
static I2C_ReceiveRequestParams _receiveReqParams;
/****** These structures are use to send/received data by valye only *********/
void ustica_I2CInit()
{
*((volatile UINT32 *)0xd401E140) = 0xd0c2|1<<3|1<<9; //PMR_SCL ->CP_TWSI_SCL
*((volatile UINT32 *)0xd401E144) = 0xd0c2|1<<3|1<<9; //PWR_SDA ->CP_TWSI_SDA
}
void ustica_I2CEnableclockandPin(void)
{
*(volatile unsigned long*)0xD4090104 |= 0x2; //enable PLL1_614 for PWIC I2C
return;
}
static void ustica_I2CResetUnitDi ( void )
{
UINT32 ICRRegValue;
// Read the control register
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_MASTER_ABORT; // Clear the abort bit
ICRRegValue &= ~I2C_ICR_START; // Clear the start bit
ICRRegValue &= ~I2C_ICR_STOP; // Clear the stop bit
ICRRegValue &= ~I2C_ICR_ACK_NACK_CONTROL; // Clear the ACK bit
ICRRegValue &= ~I2C_ICR_TRANSFER_BYTE; // Clear the transfer_byte bit
// clear the ICR register
I2C_REG_WRITE(I2C_ICR_REG, I2C_REG_CLEAR_VALUE);
// Set the RESET bit in the ICR rewgister
I2C_REG_BIT_WRITE(I2C_ICR_REG, I2C_ICR_UNIT_RESET_BIT, SET);
// clear the ISR register after reset
I2C_REG_WRITE(I2C_ISR_REG, I2C_ISR_CLEAR_ALL_INTERRUPTS);
// Clear the RESET bit in the ICR rewgister
I2C_REG_BIT_WRITE(I2C_ICR_REG, I2C_ICR_UNIT_RESET_BIT, CLEAR);
// Restore the ICR register
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue);
}
void ustica_I2CConfigureDi( void )
{
UINT32 controlRegValue = I2C_ICR_REG_INIT_VALUE;
// reset the I2C unit
ustica_I2CResetUnitDi();
/// controlRegValue |= FAST_MODE_ENABLE;
controlRegValue |= HIGH_MODE_ENABLE; //1.8Mbps for I2C.
I2C_REG_WRITE(I2C_ICR_REG, controlRegValue);
I2C_REG_WRITE(I2C_ISAR_REG, I2C_OWN_SLAVE_ADDRESS);
}
/************************************************************************
* Function: i2cWaitStatusDirect
*************************************************************************
* Description: - waits for specific status register value
* - time is limited
* - breaks when _error_was_detected indicates error detected by interrupt
* - breaks when _arbitration_loss_was_detected indicates error detected by interrupt
*
* Parameters: bitsSet contains '1' where 1 is expected
* bitsCleared contains '1' where 0 is expected
* Return value: I2C_RC_OK if got it or error code otherwise
*
* Notes:
************************************************************************/
static I2C_ReturnCode ustica_i2cWaitStatusDirect ( UINT32 bitsSet , UINT32 bitsCleared )
{
UINT32 statusRegValue;
UINT32 countLimit = LOOP_COUNTER_LIMIT;
UINT32 mask = bitsSet|bitsCleared; // all bits we care of
UINT32 value = bitsSet;
do
{
I2C_REG_READ(I2C_ISR_REG,statusRegValue);
countLimit--;
}
while ( (( statusRegValue & mask ) != value ) &&
(!( I2C_REG_BIT_READ(statusRegValue, I2C_ISR_BUS_ERROR_DETECTED_BIT) ) &&
(countLimit > 0) &&
(!( I2C_REG_BIT_READ(statusRegValue, I2C_ISR_ARBITRATION_LOSS_DETECTED_BIT) )) ));
if ( I2C_REG_BIT_READ(statusRegValue, I2C_ISR_ARBITRATION_LOSS_DETECTED_BIT) )
return I2C_ISR_ARBITRATION_LOSS;
// check for timeout, reset the I2C device for next operations and return error if needed
if ( countLimit == 0 )
{
UINT32 ICRRegValue = 0;
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue |= I2C_ICR_MASTER_ABORT;
ICRRegValue &= ~I2C_ICR_TRANSFER_BYTE;
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
return I2C_RC_TIMEOUT_ERROR;
}
else
if ( ( I2C_REG_BIT_READ(statusRegValue, I2C_ISR_BUS_ERROR_DETECTED_BIT) ))
return I2C_ISR_BUS_ERROR;
return I2C_RC_OK;
}
/************************************************************************
* Function: masterSendDirect
*************************************************************************
* Description: This function is used to write data to I2C slaves in the
* boot stage only while the OS system and INTC are not up.
*
* Parameters:
*
* Return value:
*
* Notes:
************************************************************************/
static I2C_ReturnCode ustica_masterSendDirect(UINT8 *data, UINT16 dataSize, UINT8 slaveAddress, BOOL repeatedStart , BOOL MasterReceiveCalled )
{
UINT32 ICRRegValue = 0;
int i;
I2C_ReturnCode I2CReturnCode = I2C_RC_OK;
/* Check the bus for free - If there is an arbitration loss, stay until it become free */
do
{
// check if 'Arbitration Loss' was detected
if ( I2CReturnCode == I2C_ISR_ARBITRATION_LOSS )
{
I2C_STATUS_REG_CLEAR_BIT(I2C_ISR_ARBITRATION_LOSS_DETECTED_BIT);
// Read the control register
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_START; // Clear the start bit
ICRRegValue &= ~I2C_ICR_TRANSFER_BYTE; // Clear the transfer_byte bit
// Write to the ICR register
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue);
for ( i = 0; i < 50000; i++ ); /* A little delay to enable others master to finish without interruption */
/* the bus arbiter, and reduce the arbitration sequences */
}
// write IDBR register: target slave address and R/W# bit=0 for write transaction.
I2C_REG_WRITE(I2C_IDBR_REG, I2C_SLAVE_WRITE(slaveAddress) );
// write ICR register: set START bit, clear STOP bit, set Transfer Byte bit to initiate the access
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_STOP;
ICRRegValue |= (I2C_ICR_START | I2C_ICR_TRANSFER_BYTE);
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
I2CReturnCode = ustica_i2cWaitStatusDirect ( (I2C_REG_BIT(I2C_ISR_IDBR_TRANSMIT_EMPTY_BIT) | I2C_REG_BIT(I2C_ISR_UNIT_BUSY_BIT)),
I2C_REG_BIT(I2C_ISR_READ_WRITE_MODE_BIT) );
// clear 'IDBR Transmit Empty' bit (write '1')
I2C_STATUS_REG_CLEAR_BIT(I2C_ISR_IDBR_TRANSMIT_EMPTY_BIT);
if ( ( I2CReturnCode != I2C_ISR_ARBITRATION_LOSS ) && ( I2CReturnCode != I2C_RC_OK ))
{
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= 0xfff0;
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
return I2CReturnCode;
}
}
// check if 'Arbitration Loss' was detected
while ( I2CReturnCode == I2C_ISR_ARBITRATION_LOSS );
// write ICR register: clear START bit, clear STOP bit
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_STOP;
ICRRegValue &= ~I2C_ICR_START;
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
/*** Send data bytes - all, except the last byte ***/
for ( i = 0; i < ( dataSize - 1 ); i++ )
{
// write data byte to the IDBR register
I2C_REG_WRITE(I2C_IDBR_REG, *data);
data++;
// Set 'Tranfer Byte' bit to intiate the access
I2C_REG_BIT_WRITE(I2C_ICR_REG, I2C_ICR_TRANSFER_BYTE_BIT, SET);
if((I2CReturnCode = ustica_i2cWaitStatusDirect(I2C_REG_BIT(I2C_ISR_IDBR_TRANSMIT_EMPTY_BIT)|I2C_REG_BIT(I2C_ISR_UNIT_BUSY_BIT),
I2C_REG_BIT(I2C_ISR_READ_WRITE_MODE_BIT))) != I2C_RC_OK)
return I2CReturnCode;
// clear 'IDBR Transmit Empty' bit (write '1')
I2C_STATUS_REG_CLEAR_BIT(I2C_ISR_IDBR_TRANSMIT_EMPTY_BIT);
}
/*** Send the last byte with STOP bit ***/
// write the last data byte to the IDBR register
I2C_REG_WRITE(I2C_IDBR_REG, *data);
// write ICR: clear START bit
I2C_REG_BIT_WRITE(I2C_ICR_REG, I2C_ICR_START_BIT, CLEAR);
if (( repeatedStart == FALSE ) || ( MasterReceiveCalled == FALSE ))
I2C_REG_BIT_WRITE(I2C_ICR_REG, I2C_ICR_STOP_BIT, SET);
I2C_REG_BIT_WRITE(I2C_ICR_REG, I2C_ICR_TRANSFER_BYTE_BIT, SET);
// if (repeatedStart)
// {
// if ((I2CReturnCode = i2cWaitStatusDirect (I2C_REG_BIT(I2C_ISR_IDBR_TRANSMIT_EMPTY_BIT)|I2C_REG_BIT(I2C_ISR_UNIT_BUSY_BIT),
// I2C_REG_BIT(I2C_ISR_READ_WRITE_MODE_BIT)))!=I2C_RC_OK)
// return I2CReturnCode;
// }
// else
if ((I2CReturnCode = ustica_i2cWaitStatusDirect (I2C_REG_BIT(I2C_ISR_IDBR_TRANSMIT_EMPTY_BIT),
I2C_REG_BIT(I2C_ISR_READ_WRITE_MODE_BIT)))!=I2C_RC_OK)
return I2CReturnCode;
// clear 'IDBR Transmit Empty' bit (write '1')
I2C_STATUS_REG_CLEAR_BIT(I2C_ISR_IDBR_TRANSMIT_EMPTY_BIT);
I2C_REG_BIT_WRITE(I2C_ICR_REG, I2C_ICR_STOP_BIT, CLEAR);
return I2C_RC_OK;
}
/************************************************************************
* Function: I2CBusStateGetDirect
*************************************************************************
* Description: This function is used to read the I2C Bus Monitor
* Register - IBMR.
*
* Parameters:
*
* Return value:
*
* Notes:
************************************************************************/
/************************************************************************
* Function: I2CMasterSendDataDirect
*************************************************************************
* Description: This function is used to write data to I2C slaves in the
* boot stage only while the OS system and INTC are not up.
*
* Parameters:
*
* Return value:
*
* Notes:
************************************************************************/
I2C_ReturnCode ustica_I2CMasterSendDataDirect( UINT8 *data , UINT16 dataSize , UINT8 slaveAddress , BOOL protected , UINT16 userId )
{
UINT32 XCGR_val;
I2C_ReturnCode I2CReturnCode;
BOOL chipBusy;
#if 0
return I2C_RC_OK; //qianying, for FPGA ONLY
#ifndef EDEN_1928
XCGR_val = *PMU_XCGR_READ;
*I2C_FUN_CLK_ADD = XCGR_val | PMU_XCGR_EN_I2C_FUN_CLK; //
if(AC_IS_CPONLY)
{
*I2C_APB_CLK_ADD = I2C_APB_CLK_ENABLE; //1920 // I2c APB Clock ;I2c Functional Clock
}
#endif
#endif
CHECK_IF_CHIP_BUSY(chipBusy);
if ( chipBusy == TRUE )
return I2C_RC_CHIP_BUSY;
I2CReturnCode = ustica_masterSendDirect(data, dataSize, slaveAddress, _repeat_start , FALSE);
#if 0
#ifndef EDEN_1928
if(!AC_IS_SHM)
{
//clock off
XCGR_val = *PMU_XCGR_READ;
*I2C_FUN_CLK_ADD = XCGR_val &(~PMU_XCGR_EN_I2C_FUN_CLK); //
if(AC_IS_CPONLY)
{
XCGR_val = *I2C_APB_CLK_ADD;//1920
*I2C_APB_CLK_ADD = XCGR_val & (~I2C_APB_CLK_ENABLE); // I2c APB Clock ;I2c Functional Clock
}
}
#endif
#endif
return I2CReturnCode;
}
/************************************************************************/
/************************************************************************/
static UINT16 ustica_I2CIntLISRDirect ( void )
{
UINT32 statusRegValue , ICRRegValue = 0;
//check interrupt source
I2C_REG_READ(I2C_ISR_REG,statusRegValue);
if ( I2C_REG_BIT_READ(statusRegValue, I2C_ISR_IDBR_RECEIVE_FULL_BIT) )
{
// clear 'IDBR Receive Full' bit (write '1')
I2C_STATUS_REG_CLEAR_BIT(I2C_ISR_IDBR_RECEIVE_FULL_BIT);
{
// read the received byte
I2C_REG_READ(I2C_IDBR_REG,*_receiveReqParams.RxBufferPtr);
_receiveReqParams.RxBufferPtr++;
_receiveReqParams.dataSize--;
// write ICR: clear STOP bit(1), clear ACK/NACK bit(2)
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_STOP;
ICRRegValue &= ~I2C_ICR_ACK_NACK_CONTROL;
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
if ( _receiveReqParams.dataSize > 1 )
{
// write ICR: clear START bit, clear STOP bit, send ACK bit (0 for ACK),
// set Transfer Byte bit to initiate the access
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_START;
ICRRegValue &= ~I2C_ICR_STOP;
ICRRegValue &= ~I2C_ICR_ACK_NACK_CONTROL;
ICRRegValue |= I2C_ICR_TRANSFER_BYTE;
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
}
else if ( _receiveReqParams.dataSize == 1 ) //last byte remaing to read (with STOP signal)
{
// write ICR: clear START bit, set STOP bit, send NACK bit (1 for NACK),
// set Transfer Byte bit to initiate the access
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_START;
ICRRegValue |= (I2C_ICR_STOP | I2C_ICR_ACK_NACK_CONTROL | I2C_ICR_TRANSFER_BYTE);
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
}
else
{
// disable 'IDBR Buffer Full' interrupt
I2C_REG_BIT_WRITE(I2C_ICR_REG, I2C_ICR_IDBR_RECEIVE_FULL_INT_ENABLE_BIT, CLEAR);
}
}
}
if ( I2C_REG_BIT_READ(statusRegValue, I2C_ISR_BUS_ERROR_DETECTED_BIT) )
{
// clear 'Bus Error Detected' bit (write '1')
I2C_STATUS_REG_CLEAR_BIT(I2C_ISR_BUS_ERROR_DETECTED_BIT);
}
if ( statusRegValue & I2C_ISR_UNEXPECTED_INTERRUPTS )
{
// clear 'I2C_ISR_UNEXPECTED_INTERRUPTS ' bits (write '1')
I2C_REG_WRITE(I2C_ISR_REG,I2C_ISR_UNEXPECTED_INTERRUPTS);
}
return _receiveReqParams.dataSize;
}
/************************************************************************
* Function: I2CMasterReceiveDataDirect
*************************************************************************
* Description: This function is used to read data from I2C slaves in the
* boot stage only while the OS system and INTC are not up.
*
* Parameters:
*
* Return value:
*
* Notes:
************************************************************************/
I2C_ReturnCode ustica_I2CMasterReceiveDataDirect ( UINT8 *cmd,
UINT16 cmdLength,
UINT8 writeSlaveAddress,
BOOL protected,
UINT8 *designatedRxBufferPtr,
UINT16 dataSize,
UINT8 readSlaveAddress )
{
UINT32 XCGR_val;
I2C_ReturnCode I2CReturnCode;
UINT32 ICRRegValue = 0;
BOOL chipBusy;
int result;
// store the request parameters (to be used from the ISR and by the I2C task when error)
_receiveReqParams.RxBufferPtr = designatedRxBufferPtr;
_receiveReqParams.dataSize = dataSize;
#if 0
return I2C_RC_OK; //qianying, for FPGA ONLY
if ( dataSize == 0 )
return I2C_RC_INVALID_DATA_SIZE;
#ifndef EDEN_1928
XCGR_val = *PMU_XCGR_READ;
*I2C_FUN_CLK_ADD = XCGR_val | PMU_XCGR_EN_I2C_FUN_CLK; // I2c Functional Clock
if(AC_IS_CPONLY)
{
*I2C_APB_CLK_ADD = I2C_APB_CLK_ENABLE; //1920 // I2c APB Clock
}
#endif
#endif
CHECK_IF_CHIP_BUSY(chipBusy);
if(chipBusy)
return I2C_RC_CHIP_BUSY;
if ( (cmdLength != 0) && (cmd != NULL) ) /* if command is associated with the received request */
{
I2CReturnCode = ustica_masterSendDirect(cmd, cmdLength, writeSlaveAddress, _repeat_start, TRUE);
if( I2CReturnCode != I2C_RC_OK )
return I2CReturnCode;
}
/*** send Read Request ***/
// write IDBR: target slave address and R/W# bit (1 for read)
I2C_REG_WRITE(I2C_IDBR_REG, I2C_SLAVE_READ(readSlaveAddress) );
// write ICR: set START bit, clear STOP bit, set Transfer Byte bit to initiate the access
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_STOP;
ICRRegValue |= (I2C_ICR_START | I2C_ICR_TRANSFER_BYTE);
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
I2CReturnCode = ustica_i2cWaitStatusDirect(I2C_REG_BIT(I2C_ISR_IDBR_TRANSMIT_EMPTY_BIT)|I2C_REG_BIT(I2C_ISR_UNIT_BUSY_BIT)|I2C_REG_BIT(I2C_ISR_READ_WRITE_MODE_BIT), 0 );
// clear 'IDBR Transmit Empty' bit (write '1')
I2C_STATUS_REG_CLEAR_BIT(I2C_ISR_IDBR_TRANSMIT_EMPTY_BIT);
if ( I2CReturnCode != I2C_RC_OK )
return I2CReturnCode;
// Initiate the read process:
if ( dataSize == 1 ) // only one byte to read
{
// write ICR: set STOP bit, set ACK/NACK bit (1 for NACK)
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_START;
ICRRegValue |= (I2C_ICR_STOP | I2C_ICR_ACK_NACK_CONTROL);
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
}
else // more than one byte to read
{
// write ICR: clear STOP bit, clear ACK/NACK bit (0 for ACK)
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_STOP;
ICRRegValue &= ~I2C_ICR_ACK_NACK_CONTROL;
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
}
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue &= ~I2C_ICR_START;
ICRRegValue |= I2C_ICR_TRANSFER_BYTE;
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
while ( ustica_I2CIntLISRDirect() );
return I2C_RC_OK;
}
/*************************************************************************
* Function: I2CRecordDeviceStatus
*
* Descrioption
* The function record I2C device status.
*
* Parameters:
* Inputs :
* error: The I2C device status.
* slaveAddress: The slave address of device.
* Outputs:
* N/A.
*
* Returns:
* N/A.
*
* Notes:
* N/A.
**************************************************************************/
BOOL I2CRecordDeviceStatus(UINT32 SlaveAddress, BOOL error)
{
UINT8 i = 0;
// UINT32 cpsr = 0;
BOOL status = FALSE;
/*---------------------------------------------------------------------*/
for ( i = 0; i < I2C_STATUS_ARRAY_SIZE; i++ )
{
// cpsr = disableInterrupts();
if ( I2C_RECORD_FLAG != I2CStatusArray[i].RecordFlag )
{
I2CStatusArray[i].RecordFlag = I2C_RECORD_FLAG;
I2CStatusArray[i].BaseAddress = I2C_REGISTER_BASE_ADDR;
I2CStatusArray[i].SlaveAddress = SlaveAddress;
if(error)
{
I2CStatusArray[i].DeviceStatus = I2C_DEVICE_ERROR;
}
else
{
I2CStatusArray[i].DeviceStatus = 0;
}
status = TRUE;
}
// restoreInterrupts(cpsr);
}
return status;
}
/*************************************************************************
* Function: I2CDeviceCheckStatus
*
* Descrioption
* The function check the I2C device status.
*
* Parameters:
* Inputs :
* slaveAddress: The slave address of decice.
* Outputs:
* N/A.
*
* Returns:
* N/A.
*
* Notes:
* N/A.
**************************************************************************/
BOOL I2CDeviceCheckStatus(UINT32 SlaveAddress)
{
UINT8 i = 0;
// UINT32 cpsr = 0;
BOOL status = TRUE;
/*---------------------------------------------------------------------*/
for ( i = 0; i < I2C_STATUS_ARRAY_SIZE; i++ )
{
// cpsr = disableInterrupts();
if (( I2CStatusArray[i].BaseAddress == I2C_REGISTER_BASE_ADDR )&&
( I2CStatusArray[i].SlaveAddress == SlaveAddress )&&
( I2CStatusArray[i].RecordFlag == I2C_RECORD_FLAG )&&
( I2CStatusArray[i].DeviceStatus == I2C_DEVICE_ERROR))
{
status = FALSE;
}
// restoreInterrupts(cpsr);
}
return status;
} /* End at_client_get_callback_function() */
/*************************************************************************
* Function: MastI2CSend
*
* Descrioption
* The i2c reading with not re-entery.
*
* Parameters:
* Inputs :
* I2CAddr : The address of device register.
* slaveAddress : The slave address of decice.
* Outputs:
* N/A.
*
* Returns:
* RegData : The data of reading from device register.
*
* Notes:
* N/A.
**************************************************************************/
static void MastI2CSend(UINT8 Slave_addr, UINT8 RegAddr, UINT8 RegData )
{
UINT16 read_times = 0;
UINT32 i = 0;
volatile UINT32 ICRRegValue = 0;
UINT8 param_data[3] = {0};
I2C_ReturnCode status = I2C_RC_NOT_OK;
param_data[0] = RegAddr;
param_data[1] = RegData;
param_data[2] = 0;
status = ustica_I2CMasterSendDataDirect(param_data , 2 , Slave_addr , FALSE, 0 );
read_times = 0;
while ( status != I2C_RC_OK )
{
read_times ++;
if (read_times >= 3)
{
uart_printf("Send: reset I2Cbus\r\n");
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue |= I2C_ICR_BUS_RESET;
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
do
{
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
}while (ICRRegValue & I2C_ICR_BUS_RESET);
uart_printf("Send: reset I2Cbus ends\r\n");
}
usticaInit();
for( i = 0; i < 0x10000; i++ ); /* Short delay. */
status = ustica_I2CMasterSendDataDirect(param_data , 2 , Slave_addr , FALSE, 0 );
if( read_times >= 6 )
{
uart_printf("\r\nMastI2CSend: 0x%x, Slave_addr = 0x%x, I2CRegAddr = 0x%x, RegData = 0x%x.\r\n",status, Slave_addr, RegAddr, RegData);
break;
}
}
}
/*************************************************************************
* Function: I2CMastReceive
*
* Descrioption
* The i2c reading with not re-entery.
*
* Parameters:
* Inputs :
* I2CAddr : The address of device register.
* slaveAddress : The slave address of decice.
* Outputs:
* N/A.
*
* Returns:
* RegData : The data of reading from device register.
*
* Notes:
* N/A.
**************************************************************************/
static UINT8 MastI2CReceive(UINT8 Slave_addr, UINT8 I2CRegAddr)
{
UINT32 i = 0;
volatile UINT32 ICRRegValue = 0;
UINT16 read_times = 0;
UINT8 I2CRegData = 0;
I2C_ReturnCode status = I2C_RC_NOT_OK;
Slave_addr &=0xFE;
status = ustica_I2CMasterReceiveDataDirect( &I2CRegAddr,
1 /*cmd lenght*/,
Slave_addr,
FALSE /*not protected*/,
&I2CRegData,
0x1,
(Slave_addr|0x1));
read_times = 0;
while ( status != I2C_RC_OK )
{
read_times ++;
if (read_times >= 3)
{
uart_printf("Rcv: reset I2Cbus\r\n");
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
ICRRegValue |= I2C_ICR_BUS_RESET;
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue );
do
{
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
}while (ICRRegValue & I2C_ICR_BUS_RESET);
uart_printf("Rcv: reset I2Cbus ends\r\n");
}
usticaInit();
for(i=0;i<0x10000;i++);
status = ustica_I2CMasterReceiveDataDirect( &I2CRegAddr,
1 /*cmd lenght*/,
Slave_addr,
FALSE /*not protected*/,
&I2CRegData,
0x1,
(Slave_addr|0x1));
if( read_times >= 6 )
{
uart_printf("\r\nMastI2CReceive: 0x%x, Slave_addr = 0x%x, I2CRegAddr = 0x%x.\r\n",status, Slave_addr, I2CRegAddr);
break;
}
}
return I2CRegData;
}
/*************************************************************************
* Function: I2CSend
*
* Descrioption
* The i2c writting with re-entery.
*
* Parameters:
* Inputs :
* RegAddr : The address of device register.
* RegData : The data of writing into device register.
* slaveAddress : The slave address of decice.
* Outputs:
* N/A.
*
* Returns:
* N/A.
*
* Notes:
* N/A.
**************************************************************************/
void I2CSend( UINT8 Slave_addr, UINT8 RegAddr, UINT8 RegData )
{
MastI2CSend(Slave_addr, RegAddr,RegData);
}
/*************************************************************************
* Function: I2CReceive
*
* Descrioption
* The i2c reading with re-entery.
*
* Parameters:
* Inputs :
* I2CAddr : The address of device register.
* slaveAddress : The slave address of decice.
* Outputs:
* N/A.
*
* Returns:
* RegData : The data of reading from device register.
*
* Notes:
* N/A.
**************************************************************************/
UINT8 I2CReceive( UINT8 Slave_addr, UINT8 I2CRegAddr )
{
UINT8 res = 0;
res = MastI2CReceive( Slave_addr, I2CRegAddr );
return res;
}
void USTICAI2CWriteDi_base(unsigned char I2CRegAddr, unsigned char I2CRegData)
{
I2CSend(PMC_I2C_WRITE_BASE_SLAVE_ADDRESS, I2CRegAddr, I2CRegData);
}
unsigned char USTICAI2CReadDi_base(unsigned char I2CRegAddr)
{
return I2CReceive(PMC_I2C_WRITE_BASE_SLAVE_ADDRESS, I2CRegAddr);
}
void USTICAI2CWriteDi_power(unsigned char I2CRegAddr, unsigned char I2CRegData)
{
I2CSend(PMC_I2C_WRITE_POWER_SLAVE_ADDRESS, I2CRegAddr, I2CRegData);
}
unsigned char USTICAI2CReadDi_power(unsigned char I2CRegAddr)
{
return I2CReceive(PMC_I2C_WRITE_POWER_SLAVE_ADDRESS, I2CRegAddr);
}
//add by zhangwl for write/read GPADC register
void USTICAI2CWriteDi_GPADC(unsigned char I2CRegAddr, unsigned char I2CRegData)
{
I2CSend(PMC_I2C_WRITE_GPADC_SLAVE_ADDRESS, I2CRegAddr, I2CRegData);
}
unsigned char USTICAI2CReadDi_GPADC(unsigned char I2CRegAddr)
{
return I2CReceive(PMC_I2C_WRITE_GPADC_SLAVE_ADDRESS, I2CRegAddr);
}
void USTICAI2CWriteDi_TEST(unsigned char I2CRegAddr, unsigned char I2CRegData)
{
I2CSend(PMC_I2C_WRITE_TEST_SLAVE_ADDRESS, I2CRegAddr, I2CRegData);
}
unsigned char USTICAI2CReadDi_TEST(unsigned char I2CRegAddr)
{
return I2CReceive(PMC_I2C_READ_TEST_SLAVE_ADDRESS, I2CRegAddr);
}
void USTICAI2CWriteDi_AUDIO(unsigned char I2CRegAddr, unsigned char I2CRegData)
{
I2CSend(PMC_I2C_WRITE_AUDIO_SLAVE_ADDRESS, I2CRegAddr, I2CRegData);
}
unsigned char USTICAI2CReadDi_AUDIO(unsigned char I2CRegAddr)
{
return I2CReceive(PMC_I2C_WRITE_AUDIO_SLAVE_ADDRESS, I2CRegAddr);
}
//ICAT EXPORTED FUNCTION - ADEMO,START_PS,usticaInit
void usticaInit(void)
{
ustica_I2CEnableclockandPin();
ustica_I2CConfigureDi();
}
void PM812_Ldo_8_set_2_8(void)
{
PM812_LDO_VOUT_CFG(PM812_LDO8_VOUT_REG, PM812_LDO3_TO_LDO17_2V80_ACT,PM812_LDO3_TO_LDO17_2V80_SLP);
}
void PM812_Ldo_8_set(BOOL OnOff)
{
PM812_LDO_Enable(8,OnOff);
}
unsigned char GetPMICID(void)
{
unsigned char regval;
int result;
UINT32 ICRRegValue;
UINT32 ISARRegValue;
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
I2C_REG_READ(I2C_ISAR_REG,ISARRegValue);
ustica_I2CEnableclockandPin();
ustica_I2CConfigureDi();
regval = USTICAI2CReadDi_base(0x00);
I2C_REG_WRITE(I2C_ISAR_REG,ISARRegValue);
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue);
CP_LOGD("PMIC_ID = 0x%x\r\n", regval);
return regval;
}
static void PI2C_WRITE_REG(UINT8 page,UINT8 addr, UINT8 value)
{
//INT32 result;
//UINT32 ICRRegValue;
//UINT32 ISARRegValue;
switch(page)
{
case PMC_I2C_WRITE_BASE_SLAVE_ADDRESS:
USTICAI2CWriteDi_base(addr,value);
break;
case PMC_I2C_WRITE_POWER_SLAVE_ADDRESS:
USTICAI2CWriteDi_power(addr,value);
break;
case PMC_I2C_WRITE_GPADC_SLAVE_ADDRESS:
USTICAI2CWriteDi_GPADC(addr,value);
break;
case PMC_I2C_WRITE_TEST_SLAVE_ADDRESS:
USTICAI2CWriteDi_TEST(addr,value);
break;
case PMC_I2C_WRITE_AUDIO_SLAVE_ADDRESS:
USTICAI2CWriteDi_AUDIO(addr,value);
break;
default:
ASSERT(0);
}
return;
}
static UINT8 PI2C_READ_REG(UINT8 page,UINT8 addr)
{
UINT8 ret=0;
switch(page)
{
case PMC_I2C_READ_BASE_SLAVE_ADDRESS:
ret = USTICAI2CReadDi_base(addr);
break;
case PMC_I2C_READ_POWER_SLAVE_ADDRESS:
ret = USTICAI2CReadDi_power(addr);
break;
case PMC_I2C_READ_GPADC_SLAVE_ADDRESS:
ret = USTICAI2CReadDi_GPADC(addr);
break;
case PMC_I2C_READ_TEST_SLAVE_ADDRESS:
ret = USTICAI2CReadDi_TEST(addr);
break;
case PMC_I2C_READ_AUDIO_SLAVE_ADDRESS:
ret = USTICAI2CReadDi_AUDIO(addr);
break;
default:
ASSERT(0);
}
return ret;
}
void PMIC_WRITE_REG_GPADC(UINT8 addr, UINT8 value) {PI2C_WRITE_REG(PMC_I2C_WRITE_GPADC_SLAVE_ADDRESS,addr,value);}
UINT8 PMIC_READ_REG_GPADC(UINT8 addr) {return PI2C_READ_REG(PMC_I2C_READ_GPADC_SLAVE_ADDRESS,addr);}
void PMIC_WRITE_REG_POWER(UINT8 addr, UINT8 value) {PI2C_WRITE_REG(PMC_I2C_WRITE_POWER_SLAVE_ADDRESS,addr, value);}
UINT8 PMIC_READ_REG_POWER(UINT8 addr) {return PI2C_READ_REG(PMC_I2C_READ_POWER_SLAVE_ADDRESS,addr);}
void PMIC_WRITE_REG_BASE(UINT8 addr, UINT8 value) {PI2C_WRITE_REG(PMC_I2C_WRITE_BASE_SLAVE_ADDRESS,addr,value);}
UINT8 PMIC_READ_REG_BASE(UINT8 addr) {return PI2C_READ_REG(PMC_I2C_READ_BASE_SLAVE_ADDRESS,addr);}
void PMIC_WRITE_REG_AUDIO(UINT8 addr, UINT8 value) {PI2C_WRITE_REG(PMC_I2C_WRITE_AUDIO_SLAVE_ADDRESS,addr,value);}
UINT8 PMIC_READ_REG_AUDIO(UINT8 addr) {return PI2C_READ_REG(PMC_I2C_READ_AUDIO_SLAVE_ADDRESS,addr);}
void PMIC_FAULT_WU_EN_ENABLE()
{
UINT8 tmp;
switch(pmic_id){
case PMIC_812:
tmp = PMIC_READ_REG_BASE(PM812_RTC_MISC_5_REG);
tmp |= (PM812_RTC_FAULT_WU_EN_BIT);
PMIC_WRITE_REG_BASE(PM812_RTC_MISC_5_REG,tmp);
break;
case PMIC_813:
case PMIC_813A3:
case PMIC_813S:
tmp = PMIC_READ_REG_BASE(NINGBO_FAULT_WU_REG);
tmp |= (NINGBO_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(NINGBO_FAULT_WU_REG,tmp);
break;
case PMIC_802:
case PMIC_802S:
tmp = PMIC_READ_REG_BASE(GUILIN_FAULT_WU_REG);
tmp |= (GUILIN_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_FAULT_WU_REG,tmp);
break;
case PMIC_803:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE_FAULT_WU_REG);
tmp |= (GUILIN_LITE_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE_FAULT_WU_REG,tmp);
break;
case PMIC_803L:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE2_FAULT_WU_REG);
tmp |= (GUILIN_LITE2_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE2_FAULT_WU_REG,tmp);
break;
case PMIC_807:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE3_FAULT_WU_REG);
tmp |= (GUILIN_LITE3_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE3_FAULT_WU_REG,tmp);
break;
default:
break;
}
}
void PMIC_FAULT_WU_ENABLE()
{
UINT8 tmp;
switch(pmic_id){
case PMIC_812:
tmp = PMIC_READ_REG_BASE(PM812_RTC_MISC_5_REG);
tmp |= (PM812_RTC_FAULT_WU_BIT);
PMIC_WRITE_REG_BASE(PM812_RTC_MISC_5_REG,tmp);
break;
case PMIC_813:
case PMIC_813A3:
tmp = PMIC_READ_REG_BASE(NINGBO_FAULT_WU_REG);
tmp |= (NINGBO_FAULT_WU_BIT);
PMIC_WRITE_REG_BASE(NINGBO_FAULT_WU_REG,tmp);
break;
case PMIC_802:
case PMIC_802S:
tmp = PMIC_READ_REG_BASE(GUILIN_FAULT_WU_REG);
tmp |= (GUILIN_FAULT_WU_BIT);
PMIC_WRITE_REG_BASE(GUILIN_FAULT_WU_REG,tmp);
break;
case PMIC_803:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE_FAULT_WU_REG);
tmp |= (GUILIN_LITE_FAULT_WU_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE_FAULT_WU_REG,tmp);
break;
case PMIC_803L:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE2_FAULT_WU_REG);
tmp |= (GUILIN_LITE2_FAULT_WU_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE2_FAULT_WU_REG,tmp);
break;
case PMIC_813S:
tmp = PMIC_READ_REG_BASE(NINGBO_FAULT_WU_REG);
tmp |= (NINGBO2_FAULT_WU_BIT);
PMIC_WRITE_REG_BASE(NINGBO_FAULT_WU_REG,tmp);
break;
case PMIC_807:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE3_FAULT_WU_REG);
tmp |= (GUILIN_LITE3_FAULT_WU_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE3_FAULT_WU_REG,tmp);
break;
default:
break;
}
}
void dump_pmic_registers(void)
{
unsigned long i;
uart_printf("\r\nBase Page: \r\n");
for (i=0;i<0xF8;i++)
{
uart_printf("@BP_0x%02x = 0x%02x\r\n",i,PMIC_READ_REG_BASE(i));
//uart_printf("\r\n");
}
uart_printf("\r\nPower Page: \r\n");
for (i=0;i<0x97;i++)
{
uart_printf("@PP_0x%02x = 0x%02x\r\n",i,PMIC_READ_REG_POWER(i));
//uart_printf("\r\n");
}
uart_printf("\r\nGPADC Page: \r\n");
for (i=0;i<0x72;i++)
{
uart_printf("@GP_0x%02x = 0x%02x\r\n",i,PMIC_READ_REG_GPADC(i));
// uart_printf("\r\n");
}
}
#ifdef QUECTEL_OPEN_CPU
#define AIB_UART_IO_REG 0xD401E81C
#define BU_REG_READ(x) (*(volatile unsigned long *)(x))
#define BU_REG_WRITE(x,y) ((*(volatile unsigned long *)(x)) = y )
void AIB_Secure_Write(unsigned int address, unsigned int value)
{
BU_REG_WRITE(0xd4015050, 0xBABA);
BU_REG_WRITE(0xd4015054, 0xEB10);
BU_REG_WRITE(address, value);
}
UINT32 AIB_Secure_Read(unsigned int address)
{
UINT32 val;
BU_REG_WRITE(0xd4015050, 0xBABA);
BU_REG_WRITE(0xd4015054, 0xEB10);
val = BU_REG_READ(address);
return val;
}
static void AIB_UART_IO_Set_3_3V(void)
{
volatile unsigned int val = 0;
val = AIB_Secure_Read(AIB_UART_IO_REG); //AIB_UART_IO_REG
val &= ~(0x4);
AIB_Secure_Write(AIB_UART_IO_REG, val);
}
void PMIC_Set_CP_UART_PowerOff_and_AIB_3_3V(void)
{
if(PMIC_IS_PM803())
{
GuilinLite_Ldo_7_set(FALSE);//SDIO
}
AIB_UART_IO_Set_3_3V();
}
#endif
void PMIC_SW_RESET(void)
{
UINT8 tmp;
UINT32 callerAddress ;
//dump_pmic_registers();
#if defined(__ARMCC_VERSION)
callerAddress= (__ARMCC_VERSION >= 200000) ? __return_address() : 0 ; // Keep first.
#else
callerAddress = 0;
#endif
#ifdef QUECTEL_OPEN_CPU
if (CHIP_IS_CRANEL)
{
PMIC_Set_CP_UART_PowerOff_and_AIB_3_3V();
}
#endif
PMIC_WRITE_REG_BASE(NINGBO_INT_ENABLE_REG1,0x00);
PMIC_WRITE_REG_BASE(NINGBO_INT_ENABLE_REG2,0x00);
//PMIC_WRITE_REG_GPADC(NINGBO_GPADC_MODE_CONTROL_REG,0);
//PMIC_WRITE_REG_BASE(0xef,0x03);
//mdelay(10000);
uart_printf("SW_RESET @0x%x\r\n",callerAddress);
//mdelay(5000);
PMIC_FAULT_WU_EN_ENABLE();
PMIC_FAULT_WU_ENABLE();
//PMIC_WRITE_REG_POWER(NINGBO_VBUCK2_ACTIVE_VOUT_REG,0xDB); //buck2=2.15v
//uart_printf("BP_0x15 @0x%x\r\n",PMIC_READ_REG_BASE(NINGBO_BAT_TEMP_CTRL_REG));
//uart_printf("BP_0x12 @0x%x\r\n",PMIC_READ_REG_BASE(0x12));
mdelay(5);
//SW_PDOWN
switch(pmic_id){
case PMIC_812:
tmp = PMIC_READ_REG_BASE(PM812_WAKEUP_1_REG);
tmp |= PM812_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(PM812_WAKEUP_1_REG,tmp);
break;
case PMIC_813:
case PMIC_813A3:
case PMIC_813S:
PMIC_WRITE_REG_BASE(0x4C,0x0); //disable PWM
tmp = PMIC_READ_REG_BASE(NINGBO_MISC_CFG_REG1);
tmp |= NINGBO_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(NINGBO_MISC_CFG_REG1,tmp);
break;
case PMIC_802:
case PMIC_802S:
/*TODO*/
#ifdef FOTA_ASRSPI
/* CP reset for 2-chip solution */
Guilin_SW_Reset();
#endif
#ifdef QUECTEL_FOTA
tmp = PMIC_READ_REG_BASE(GUILIN_WAKEUP_REG1);
tmp |= GUILIN_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(GUILIN_WAKEUP_REG1,tmp);
#endif
break;
case PMIC_803:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE_WAKEUP_REG1);
tmp |= GUILIN_LITE_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(GUILIN_LITE_WAKEUP_REG1,tmp);
break;
case PMIC_803L:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE2_WAKEUP_REG1);
tmp |= GUILIN_LITE2_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(GUILIN_LITE2_WAKEUP_REG1,tmp);
break;
case PMIC_807:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE3_WAKEUP_REG1);
tmp |= GUILIN_LITE3_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(GUILIN_LITE3_WAKEUP_REG1,tmp);
break;
default:
break;
}
mdelay(10000);
uart_printf("RST end\r\n");
while(1);
}
BOOL PMIC_ID_GET(void)
{
if (pmic_id == PMIC_UNAVAILABLE)
pmic_id = (GetPMICID()&0xF8)>>3;//initial pmic_id after boot
return pmic_id;
}
/* Following APIs reflect PMIC series. */
BOOL PMIC_IS_PM812(void)
{
return (pmic_id == PMIC_812);
}
BOOL PMIC_IS_PM813(void)
{
return ((pmic_id == PMIC_813)||(pmic_id == PMIC_813A3));
}
BOOL PMIC_IS_PM802(void)
{
return (pmic_id == PMIC_802);
}
BOOL PMIC_IS_PM803(void)
{
return (PMIC_ID_GET() == PMIC_803);
}
BOOL PMIC_IS_PM813S(void)
{
return (pmic_id == PMIC_813S);
}
BOOL PMIC_IS_PM802S(void)
{
return (PMIC_ID_GET() == PMIC_802S);
}
BOOL PMIC_IS_PM803L(void)
{
return (PMIC_ID_GET() == PMIC_803L);
}
BOOL PMIC_IS_PM807(void)
{
return (PMIC_ID_GET() == PMIC_807);
}
void PMIC_Init(void)
{
pmic_id = PMIC_ID_GET();
usticaInit(); //init clock and TWSI ctrl
if (PMIC_IS_PM802()||PMIC_IS_PM802S())
{
GuilinClkInit();
}
else if (PMIC_IS_PM813()||PMIC_IS_PM813S())
{
NingboClkInit();
}else if (PMIC_IS_PM803())
{
GuilinLiteClkInit();
}
}
static void PM812_LDO_VOUT_CFG(int addr,int act_vol,int slp_vol)
{
UINT32 ICRRegValue;
UINT32 ISARRegValue;
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
I2C_REG_READ(I2C_ISAR_REG,ISARRegValue);
usticaInit();
if(act_vol & slp_vol)ASSERT(0);
USTICAI2CWriteDi_power(addr,(act_vol|slp_vol));
I2C_REG_WRITE(I2C_ISAR_REG,ISARRegValue);
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue);
}
static void PM812_LDO_Enable(int ldo_num,BOOL OnOff)
{
unsigned char regval;
UINT32 ICRRegValue;
UINT32 ISARRegValue;
I2C_REG_READ(I2C_ICR_REG,ICRRegValue);
I2C_REG_READ(I2C_ISAR_REG,ISARRegValue);
usticaInit();
//cfg enable reg-1
regval = USTICAI2CReadDi_power(PM812_LDO_ENABLE_REG_1(ldo_num));
USTICAI2CWriteDi_power( PM812_LDO_ENABLE_REG_1(ldo_num),
OnOff?(regval|PM812_LDO_ENABLE_BIT(ldo_num)):(regval &(~ PM812_LDO_ENABLE_BIT(ldo_num)))
);
//cfg enable reg-2
regval = USTICAI2CReadDi_power(PM812_LDO_ENABLE_REG_2(ldo_num));
USTICAI2CWriteDi_power( PM812_LDO_ENABLE_REG_2(ldo_num),
OnOff?(regval|PM812_LDO_ENABLE_BIT(ldo_num)):(regval &(~ PM812_LDO_ENABLE_BIT(ldo_num)))
);
I2C_REG_WRITE(I2C_ISAR_REG,ISARRegValue);
I2C_REG_WRITE(I2C_ICR_REG, ICRRegValue);
}
void PM812_Ldo_12_set_1_8(void)
{
PM812_LDO_VOUT_CFG(PM812_LDO12_VOUT_REG,PM812_LDO3_TO_LDO17_1V80_ACT,PM812_LDO3_TO_LDO17_1V80_SLP);
}
void PM812_Ldo_12_set_2_8(void)
{
PM812_LDO_VOUT_CFG(PM812_LDO12_VOUT_REG, PM812_LDO3_TO_LDO17_2V80_ACT,PM812_LDO3_TO_LDO17_2V80_SLP);
}
void PM812_Ldo_12_set_3_0(void)
{
PM812_LDO_VOUT_CFG(PM812_LDO12_VOUT_REG,PM812_LDO3_TO_LDO17_3V00_ACT,PM812_LDO3_TO_LDO17_3V00_SLP);
}
void PM812_Ldo_12_set(BOOL OnOff)
{
PM812_LDO_Enable(12,OnOff);
}
void PM812_Ldo_13_set_2_8(void)
{
PM812_LDO_VOUT_CFG(PM812_LDO13_VOUT_REG, PM812_LDO3_TO_LDO17_2V80_ACT,PM812_LDO3_TO_LDO17_2V80_SLP);
}
void PM812_Ldo_13_set(BOOL OnOff)
{
PM812_LDO_Enable(13,OnOff);
}
BOOL PMIC_COMP_ID_GET(void)
{
static UINT8 pmic_complete_id = PMIC_UNAVAILABLE;
if (pmic_complete_id == PMIC_UNAVAILABLE)
pmic_complete_id = GetPMICID();
return pmic_complete_id;
}
BOOL PMIC_IS_PM813_A3(void)
{
return (PMIC_COMP_ID_GET() == PMIC_813_A3);
}
BOOL PM812_EXTON_IS_DETECTED(void)
{
//check whether EXTON pin is connected
switch (PMIC_ID_GET())
{
case PMIC_813:
return ((PMIC_READ_REG_BASE(NINGBO_STATUS_REG1) & (NINGBO_VBUS_STATUS_BIT | NINGBO_VBUS_OVP_BIT | NINGBO_VBUS_UVLO_BIT)) ? TRUE : FALSE);
case PMIC_813A3:
case PMIC_813S:
return ((PMIC_READ_REG_BASE(NINGBO_READONLY_DATA_2_REG) & (NINGBO_RONLY_DATA_CHG_OK)) ? TRUE : FALSE);
case PMIC_802:
case PMIC_802S:
return ((PMIC_READ_REG_BASE(GUILIN_STATUS_REG1) & GUILIN_EXTON1_DETECT) ? TRUE : FALSE);
case PMIC_803:
return ((PMIC_READ_REG_BASE(GUILIN_LITE_STATUS_REG1) & GUILIN_LITE_EXTON1_DETECT) ? TRUE : FALSE);
case PMIC_803L:
return ((PMIC_READ_REG_BASE(GUILIN_LITE2_STATUS_REG1) & GUILIN_LITE2_EXTON1_DETECT) ? TRUE : FALSE);
case PMIC_807:
return ((PMIC_READ_REG_BASE(GUILIN_LITE3_STATUS_REG1) & GUILIN_LITE3_EXTON1_DETECT) ? TRUE : FALSE);
default:
ASSERT(0);
return FALSE;
}
}
BOOL PM812_CHARGER_IS_DETECTED(void)
{
//for FIH board only check EXTON_STATUS
return PM812_EXTON_IS_DETECTED();
}
void PM812_FAULT_WU_EN_DISABLE()
{
UINT8 tmp;
#ifdef QUECTEL_OPEN_CPU
switch (PMIC_ID_GET())
{
case PMIC_813:
case PMIC_813A3:
case PMIC_813S:
tmp = PMIC_READ_REG_BASE(NINGBO_FAULT_WU_REG);
tmp &= ~(NINGBO_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(NINGBO_FAULT_WU_REG,tmp);
break;
case PMIC_802:
tmp = PMIC_READ_REG_BASE(GUILIN_FAULT_WU_REG);
tmp &= ~(GUILIN_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_FAULT_WU_REG,tmp);
break;
case PMIC_803:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE_FAULT_WU_REG);
tmp &= ~(GUILIN_LITE_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE_FAULT_WU_REG,tmp);
break;
case PMIC_803L:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE2_FAULT_WU_REG);
tmp &= ~(GUILIN_LITE2_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE2_FAULT_WU_REG,tmp);
break;
case PMIC_807:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE3_FAULT_WU_REG);
tmp &= ~(GUILIN_LITE3_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE3_FAULT_WU_REG,tmp);
break;
default:
ASSERT(0);
break;
}
#else
if (PMIC_IS_PM812())
{
tmp = PMIC_READ_REG_BASE(PM812_RTC_MISC_5_REG);
tmp &= ~(PM812_RTC_FAULT_WU_EN_BIT);
PMIC_WRITE_REG_BASE(PM812_RTC_MISC_5_REG,tmp);
}
else
{
tmp = PMIC_READ_REG_BASE(NINGBO_FAULT_WU_REG);
tmp &= ~(NINGBO_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(NINGBO_FAULT_WU_REG,tmp);
}
#endif
}
void PMIC_PowerDown(void)
{
UINT8 tmp;
uart_printf("PDOWN!\r\n");
PM812_FAULT_WU_EN_DISABLE();
if (PMIC_IS_PM812())
{
tmp = PMIC_READ_REG_BASE(PM812_WAKEUP_1_REG);
tmp |= PM812_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(PM812_WAKEUP_1_REG,tmp);
}
else
{
PMIC_WRITE_REG_BASE(0x4C,0x0); //disable PWM
tmp = PMIC_READ_REG_BASE(NINGBO_MISC_CFG_REG1);
tmp |= NINGBO_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(NINGBO_MISC_CFG_REG1,tmp);
}
}
void PM812_VBUCK1_CFG(UINT8 value)
{
PMIC_BUCK_T val = (PMIC_BUCK_T)value;
if((val<BUCK_0_800)||(val>BUCK_1_300)){
uart_printf("wrong buck1 value input! \r\n");
return;
}
PMIC_WRITE_REG_POWER(USTICA_VBUCK_1_SET_0_REG,val);
}
void PlatformVcoreConfigTop(void)
{
//uart_printf("PlatformVcoreConfigTop! PMIC_ID_GET[%08x]\r\n",PMIC_ID_GET());
//Set 1.10V by default for top level
switch(PMIC_ID_GET())
{
case PMIC_812:
PM812_VBUCK1_CFG(BUCK_1_100);
break;
case PMIC_813:
case PMIC_813A3:
case PMIC_813S:
if (CHIP_IS_CRANELS)
Ningbo_VBUCK1_CFG(NINGBO_VBUCK_1V0000);
else
Ningbo_VBUCK1_CFG(NINGBO_VBUCK_1V1000);
break;
case PMIC_802:
case PMIC_802S:
if(CHIP_IS_CRANEL || CHIP_IS_CRANELS){
Guilin_VBUCK1_CFG(GUILIN_VBUCK_0V9000);
}else{
Guilin_VBUCK1_CFG(GUILIN_VBUCK_1V1000);
}
break;
case PMIC_803:
if(CHIP_IS_CRANEL || CHIP_IS_CRANELS){
GuilinLite_VBUCK1_CFG(GUILIN_LITE_VBUCK_0V9000);
}else{
GuilinLite_VBUCK1_CFG(GUILIN_LITE_VBUCK_0V9500);
}
break;
case PMIC_803L:
if (CHIP_IS_CRANELR || CHIP_IS_CRANELS || CHIP_IS_CRANELG || CHIP_IS_CRANELRH)
GuilinLite2_VBUCK1_CFG(GUILIN_LITE2_VBUCK_1V00);
break;
case PMIC_807:
if (CHIP_IS_CRANELR || CHIP_IS_CRANELS || CHIP_IS_CRANELG || CHIP_IS_CRANELRH)
GuilinLite3_VBUCK1_CFG(GUILIN_LITE3_VBUCK_1V00);
break;
default:
// ASSERT(0);
break;
}
}
void PlatformVcoreConfigHigh(void)
{
//uart_printf("PlatformVcoreConfigHigh! PMIC_ID_GET[%08x]\r\n",PMIC_ID_GET());
//Set 1.05V by default for higher level
switch(PMIC_ID_GET())
{
case PMIC_812:
PM812_VBUCK1_CFG(BUCK_1_050);
break;
case PMIC_813:
case PMIC_813A3:
case PMIC_813S:
if (CHIP_IS_CRANELS)
Ningbo_VBUCK1_CFG(NINGBO_VBUCK_0V9000);
else
Ningbo_VBUCK1_CFG(NINGBO_VBUCK_1V0500);
break;
case PMIC_802:
case PMIC_802S:
if(CHIP_IS_CRANEL || CHIP_IS_CRANELS){
Guilin_VBUCK1_CFG(GUILIN_VBUCK_0V9000);
}else{
Guilin_VBUCK1_CFG(GUILIN_VBUCK_1V0500);
}
break;
case PMIC_803:
if(CHIP_IS_CRANEL || CHIP_IS_CRANELS){
GuilinLite_VBUCK1_CFG(GUILIN_LITE_VBUCK_0V9000);
}else{
GuilinLite_VBUCK1_CFG(GUILIN_LITE_VBUCK_0V9500);
}
break;
case PMIC_803L:
if (CHIP_IS_CRANELR || CHIP_IS_CRANELS || CHIP_IS_CRANELG || CHIP_IS_CRANELRH)
GuilinLite2_VBUCK1_CFG(GUILIN_LITE2_VBUCK_0V90);
break;
case PMIC_807:
if (CHIP_IS_CRANELR || CHIP_IS_CRANELS || CHIP_IS_CRANELG || CHIP_IS_CRANELRH)
GuilinLite3_VBUCK1_CFG(GUILIN_LITE3_VBUCK_0V90);
break;
default:
// ASSERT(0);
break;
}
}
void PlatformVcoreConfigLow(void)
{
//uart_printf("PlatformVcoreConfigLow! PMIC_ID_GET[%08x]\r\n",PMIC_ID_GET());
//Set 1.00V by default
switch(PMIC_ID_GET())
{
case PMIC_812:
PM812_VBUCK1_CFG(BUCK_1_000);
break;
case PMIC_813:
case PMIC_813A3:
case PMIC_813S:
if (CHIP_IS_CRANELS)
Ningbo_VBUCK1_CFG(NINGBO_VBUCK_0V9000);
else
Ningbo_VBUCK1_CFG(NINGBO_VBUCK_1V0000);
break;
case PMIC_802:
case PMIC_802S:
if(CHIP_IS_CRANEL || CHIP_IS_CRANELS){
Guilin_VBUCK1_CFG(GUILIN_VBUCK_0V9000);
}else{
Guilin_VBUCK1_CFG(GUILIN_VBUCK_1V0000);
}
break;
case PMIC_803:
if(CHIP_IS_CRANEL || CHIP_IS_CRANELS){
GuilinLite_VBUCK1_CFG(GUILIN_LITE_VBUCK_0V9000);
}else{
GuilinLite_VBUCK1_CFG(GUILIN_LITE_VBUCK_0V9000);
}
break;
case PMIC_803L:
if (CHIP_IS_CRANELR || CHIP_IS_CRANELS || CHIP_IS_CRANELG || CHIP_IS_CRANELRH)
GuilinLite2_VBUCK1_CFG(GUILIN_LITE2_VBUCK_0V90);
break;
case PMIC_807:
if (CHIP_IS_CRANELR || CHIP_IS_CRANELS || CHIP_IS_CRANELG || CHIP_IS_CRANELRH)
GuilinLite3_VBUCK1_CFG(GUILIN_LITE3_VBUCK_0V90);
break;
default:
// ASSERT(0);
break;
}
}
#if QUECTEL_OPEN_CPU
BOOL Quec_PMIC_GET_PWEKY_STATUS(void)
{
if (PMIC_IS_PM812())
return ((PMIC_READ_REG_BASE(PM812_STATUS_1_REG) & PM812_EXTON_STATUS_BIT) ? TRUE : FALSE);
else
return ((PMIC_READ_REG_BASE(NINGBO_STATUS_REG1) & NINGBO_EXTON1_STATUS_BIT) ? TRUE : FALSE);
}
#endif
void pmic_user_defined_flags_set(UINT8 flag)
{
UINT8 var = 0;
if(PMIC_IS_PM813()||PMIC_IS_PM813S())
{
var=PMIC_READ_REG_BASE(PMIC_REG_FOR_USR_DEF_FLAGS_STR);
var &= ~0xF;
var |= (flag & 0xF); //only use low 4 bits
PMIC_WRITE_REG_BASE(PMIC_REG_FOR_USR_DEF_FLAGS_STR, var);
}
else if(PMIC_IS_PM802()||PMIC_IS_PM803()||PMIC_IS_PM802S())
{
var=PMIC_READ_REG_BASE(PM802_REG_FOR_USR_DEF_FLAGS_STR);
var &= ~0xF0;
var |= (flag<<4); //only use high 4 bits
PMIC_WRITE_REG_BASE(PM802_REG_FOR_USR_DEF_FLAGS_STR, var);
}
}
UINT8 pmic_user_defined_flags_get(void)
{
UINT8 var = 0;
if(PMIC_IS_PM813()||PMIC_IS_PM813S())
{
var = PMIC_READ_REG_BASE(PMIC_REG_FOR_USR_DEF_FLAGS_STR);
return (var & 0xF); //only use low 4 bits
}
else if(PMIC_IS_PM802()||PMIC_IS_PM803()||PMIC_IS_PM802S())
{
var=PMIC_READ_REG_BASE(PM802_REG_FOR_USR_DEF_FLAGS_STR);
return (var>>4); //only use high 4 bits
}
else
{
return var;
}
}
void Updater_Reset(void)
{
UINT32 callerAddress ;
#if defined(__ARMCC_VERSION)
callerAddress= (__ARMCC_VERSION >= 200000) ? __return_address() : 0 ; // Keep first.
#else
callerAddress = 0;
#endif
uart_printf("%s @0x%x\r\n",__func__,callerAddress);
//uart_printf("01-@BP_0x%02x = 0x%02x\r\n",NINGBO_RTC_USER_DATA_4_REG,PMIC_READ_REG_BASE(NINGBO_RTC_USER_DATA_4_REG));
pmic_user_defined_flags_set(RESET_FOTA_FLAG);
//uart_printf("02-@BP_0x%02x = 0x%02x\r\n",NINGBO_RTC_USER_DATA_4_REG,PMIC_READ_REG_BASE(NINGBO_RTC_USER_DATA_4_REG));
PMIC_SW_RESET();
}
UINT8 PMIC_GET_POWER_UP_LOG()
{
UINT8 reason=0;
switch(PMIC_ID_GET())
{
case PMIC_812:
reason=PMIC_READ_REG_BASE(PM812_POWERUP_LOG_REG);
break;
case PMIC_813:
case PMIC_813A3:
case PMIC_813S:
reason=PMIC_READ_REG_BASE(NINGBO_PWRUP_LOG_REG);
break;
case PMIC_802:
case PMIC_802S:
reason=PMIC_READ_REG_BASE(GUILIN_PWRUP_LOG_REG);
break;
case PMIC_803:
reason=PMIC_READ_REG_BASE(GUILIN_LITE_PWRUP_LOG_REG);
break;
case PMIC_803L:
reason=PMIC_READ_REG_BASE(GUILIN_LITE2_PWRUP_LOG_REG);
break;
case PMIC_807:
reason=PMIC_READ_REG_BASE(GUILIN_LITE3_PWRUP_LOG_REG);
break;
default:
// ASSERT(0);
break;
}
return reason;
}
void uudelay(int us)
{
volatile UINT32 i;
for(i=0; i<us*20;i++);
}
void mdelay(int ms){
volatile UINT32 i;
for(i=0; i<ms;i++)
uudelay(1000);
}
/* Get Restart Reson*/
UINT8 SysRestartReasonGlobal=0;
UINT32 SysRestartReasonGetFlag=0;
UINT8 SysRestartReasonGet(void)
{
UINT8 reason;
if(SysRestartReasonGetFlag==0)
{
#ifdef QUECTEL_OPEN_CPU
switch (PMIC_ID_GET())
{
#if !defined(NOT_SUPPORT_PM813)
case PMIC_813:
case PMIC_813A3:
case PMIC_813S:
reason=PMIC_READ_REG_BASE(PMIC_REG_FOR_SW_RESTART_REASON_STR);
break;
#endif
#if !defined(NOT_SUPPORT_PM802)
case PMIC_802:
#endif
case PMIC_803:
reason=PMIC_READ_REG_BASE(PMIC_REG_FOR_USR_DEF_FLAGS_STR);
break;
case PMIC_803L:
reason=PMIC_READ_REG_BASE(PM803L_REG_FOR_USR_DEF_FLAGS_STR);
break;
case PMIC_807:
reason=PMIC_READ_REG_BASE(PM807_REG_FOR_USR_DEF_FLAGS_STR);
break;
#if !defined(NOT_SUPPORT_PM802)
case PMIC_802S:
reason=PMIC_READ_REG_BASE(PM802_REG_FOR_USR_DEF_FLAGS_STR);
break;
#endif
default:
ASSERT(0);
break;
}
#else
reason=PMIC_READ_REG_BASE(PMIC_REG_FOR_SW_RESTART_REASON_STR);
#endif
}
else
reason = SysRestartReasonGlobal;
if(reason==0)
reason='N';
switch (reason)
{
case 'C':
case 'R':
case 'A':
case 'N':
case 'E':
break;
default:
return 0;
}
return reason;
}
UINT8 isSysRestartByRdProduction(void)
{
return (SysRestartReasonGet() == 'R');
}
#ifdef QUECTEL_OPEN_CPU
void PMIC_FAULT_WU_EN_DISABLE()
{
UINT8 tmp;
switch(pmic_id)
{
case PMIC_813:
case PMIC_813A3: //forrest.liu@20201130 add for ASR new interface for PMIC_ID_GET
case PMIC_813S:
tmp = PMIC_READ_REG_BASE(NINGBO_FAULT_WU_REG);
tmp &= ~(NINGBO_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(NINGBO_FAULT_WU_REG,tmp);
break;
case PMIC_802:
tmp = PMIC_READ_REG_BASE(GUILIN_FAULT_WU_REG);
tmp &= ~(GUILIN_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_FAULT_WU_REG,tmp);
break;
case PMIC_803:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE_FAULT_WU_REG);
tmp &= ~(GUILIN_LITE_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE_FAULT_WU_REG,tmp);
break;
case PMIC_803L:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE2_FAULT_WU_REG);
tmp &= ~(GUILIN_LITE2_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE2_FAULT_WU_REG,tmp);
break;
case PMIC_807:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE3_FAULT_WU_REG);
tmp &= ~(GUILIN_LITE3_FAULT_WU_ENABLE_BIT);
PMIC_WRITE_REG_BASE(GUILIN_LITE3_FAULT_WU_REG,tmp);
break;
case PMIC_812:
tmp = PMIC_READ_REG_BASE(PM812_RTC_MISC_5_REG);
tmp &= ~(PM812_RTC_FAULT_WU_BIT);
PMIC_WRITE_REG_BASE(PM812_RTC_MISC_5_REG,tmp);
break;
default:
break;
}
}
void ql_set_power_down(void)
{
UINT8 tmp;
uart_printf("+PMIC_SW_POWERDOWN,pmic_id=0x%x\r\n",pmic_id);
/*
½â¾öbug STASR1601-235. powerkey ¿ª»úºó£¬ÔÙʹÓÃpowerkey¹Ø»ú£¬Ï´ÎÔÙʹÓÃpowerkey¿ª»úʱÀ­µÍ10ms¾Í¿ÉÒÔ¿ª»úÎÞdebounceЧ¹û
¸ÃÎÊÌâ¸ù±¾Ô­ÒòÊÇϵͳÅжÏÀäÆô¶¯½èÓõÄÊÇGUILIN_BASE_Reg Õâ¸ö¼Ä´æÆ÷bit5~bit7³õʼֵΪ0£¬ Èç¹û²»Îª0˵Ã÷²»ÊÇÀäÆô¶¯£¬
Ôò²»»áÈ¥×öpowerkey·À¶¶¼ì²é(reset, cfun=1,1ÖØÆôµÄ²»ÄÜ×öpowerkey·À¶¶¼ì²â)£¬¶øÕý³£Ä£¿é¹Ø»úʱGUILIN_BASE_Reg ¼Ä´æÆ÷bit5-7ÊDz»Îª0µÄ
ËùÒÔµ¼ÖÂÔÙ´Îpowerkey¿ª»úʱûÓÐÈ¥×ö·À¶¶¼ì²â£¬µ¼ÖÂpowerkeyÖ»ÒªÀ­µÍÁ¢¼´¿ª»ú£¬Òò´ËÔÙÕâÀï¹Ø»úǰ½«¸Ã¼Ä´æÆ÷±Èbit5-7ÉèÖÃΪ0
*/
//ÀäÈÈÆô¶¯ÅжÏĿǰ¼Ä´æÆ÷µØÖ·ÐÞ¸ÄΪ0xeb,¹Ø»úºó£¬°Ñ¼Ä´æÆ÷ÇåÁã
if(PMIC_IS_PM803())
{
unsigned char var = 0;
GuilinLiteRead(GUILIN_LITE_BASE_Reg, 0xeb, &var);
var &= ~0x80;
GuilinLiteWrite(GUILIN_LITE_BASE_Reg, 0xeb, var);
}
PMIC_FAULT_WU_EN_DISABLE();
//SW_PDOWN
switch(pmic_id){
case PMIC_812:
tmp = PMIC_READ_REG_BASE(PM812_WAKEUP_1_REG);
tmp |= PM812_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(PM812_WAKEUP_1_REG,tmp);
break;
case PMIC_813:
case PMIC_813A3: //forrest.liu@20201130 add for ASR new interface for PMIC_ID_GET
case PMIC_813S:
PMIC_WRITE_REG_BASE(0x4C,0x0); //disable PWM
tmp = PMIC_READ_REG_BASE(NINGBO_MISC_CFG_REG1);
tmp |= NINGBO_SW_PDOWN_BIT;
PMIC_WRITE_REG_BASE(NINGBO_MISC_CFG_REG1,tmp);
break;
case PMIC_802:
/*TODO*/
tmp = PMIC_READ_REG_BASE(GUILIN_WAKEUP_REG1);
tmp |= GUILIN_SW_PDOWN;
PMIC_WRITE_REG_BASE(GUILIN_WAKEUP_REG1,tmp);
break;
case PMIC_803:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE_WAKEUP_REG1);
tmp |= GUILIN_LITE_SW_PDOWN;
PMIC_WRITE_REG_BASE(GUILIN_LITE_WAKEUP_REG1,tmp);
break;
case PMIC_803L:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE2_WAKEUP_REG1);
tmp |= GUILIN_LITE2_SW_PDOWN;
PMIC_WRITE_REG_BASE(GUILIN_LITE2_WAKEUP_REG1,tmp);
break;
case PMIC_807:
tmp = PMIC_READ_REG_BASE(GUILIN_LITE3_WAKEUP_REG1);
tmp |= GUILIN_LITE3_SW_PDOWN;
PMIC_WRITE_REG_BASE(GUILIN_LITE3_WAKEUP_REG1,tmp);
break;
default:
break;
}
}
#endif