void INT_VDD5V(void)
{
#ifdef USE_VBUSVALID
    if(BF_RD(POWER_CTRL, VBUSVALID_IRQ))
    {
        if(BF_RD(POWER_STS, VBUSVALID))
            usb_insert_int();
        else
            usb_remove_int();
        /* reverse polarity */
        BF_WR(POWER_CTRL_TOG, POLARITY_VBUSVALID(1));
        /* clear int */
        BF_CLR(POWER_CTRL, VBUSVALID_IRQ);
    }
#else
    if(BF_RD(POWER_CTRL, VDD5V_GT_VDDIO_IRQ))
    {
        if(BF_RD(POWER_STS, VDD5V_GT_VDDIO))
            usb_insert_int();
        else
            usb_remove_int();
        /* reverse polarity */
        BF_WR(POWER_CTRL_TOG, POLARITY_VDD5V_GT_VDDIO(1));
        /* clear int */
        BF_CLR(POWER_CTRL, VDD5V_GT_VDDIO_IRQ);
    }
#endif
}
Exemple #2
0
void imx233_lcdif_wait_fifo(void)
{
#if IMX233_SUBTARGET >= 3700
    while(BF_RD(LCDIF_STAT, TXFIFO_FULL));
#else
    while(!BF_RD(LCDIF_CTRL, FIFO_STATUS));
#endif
}
Exemple #3
0
static inline int __attribute__((always_inline)) read_pswitch(void)
{
#if IMX233_SUBTARGET >= 3700
    return BF_RD(POWER_STS, PSWITCH);
#else
    return BF_RD(DIGCTL_STATUS, PSWITCH);
#endif
}
bool imx233_power_usb_detect(void)
{
#ifdef USE_VBUSVALID
    return BF_RD(POWER_STS, VBUSVALID);
#else
    return BF_RD(POWER_STS, VDD5V_GT_VDDIO);
#endif
}
void imx233_power_init(void)
{
#if IMX233_SUBTARGET >= 3700
    BF_CLR(POWER_MINPWR, HALF_FETS);
#endif
    /* setup vbusvalid parameters: set threshold to 4v and power up comparators */
    BF_CS(POWER_5VCTRL, VBUSVALID_TRSH(1));
#if IMX233_SUBTARGET >= 3780
    BF_SET(POWER_5VCTRL, PWRUP_VBUS_CMPS);
#else
    BF_SET(POWER_5VCTRL, OTG_PWRUP_CMPS);
#endif
    /* enable vbusvalid detection method for the dcdc (improves efficiency) */
    BF_SET(POWER_5VCTRL, VBUSVALID_5VDETECT);
    /* disable shutdown on 5V fail */
    BF_CLR(POWER_5VCTRL, PWDN_5VBRNOUT);
#ifdef USE_VBUSVALID
    /* make sure VBUSVALID is unlocked */
    BF_CLR(POWER_DEBUG, VBUSVALIDPIOLOCK);
    /* clear vbusvalid irq and set correct polarity */
    BF_CLR(POWER_CTRL, VBUSVALID_IRQ);
    if(BF_RD(POWER_STS, VBUSVALID))
        BF_CLR(POWER_CTRL, POLARITY_VBUSVALID);
    else
        BF_SET(POWER_CTRL, POLARITY_VBUSVALID);
    BF_SET(POWER_CTRL, ENIRQ_VBUS_VALID);
    /* make sure old detection way is not enabled */
    BF_CLR(POWER_CTRL, ENIRQ_VDD5V_GT_VDDIO);
#else
    BF_CLR(POWER_CTRL,  VDD5V_GT_VDDIO_IRQ);
    if(BF_RD(POWER_STS, VDD5V_GT_VDDIO))
        BF_CLR(POWER_CTRL, POLARITY_VDD5V_GT_VDDIO);
    else
        BF_SET(POWER_CTRL, POLARITY_VDD5V_GT_VDDIO);
    BF_SET(POWER_CTRL, ENIRQ_VDD5V_GT_VDDIO);
    /* make the vbusvalid detection way is not enabled */
#if IMX233_SUBTARGET >= 3700
    BF_CLR(POWER_CTRL, ENIRQ_VBUS_VALID);
#endif
#endif
    /* the VDD5V IRQ is shared by several sources, disable them */
#if IMX233_SUBTARGET >= 3700
    BF_CLR(POWER_CTRL, ENIRQ_PSWITCH);
    BF_CLR(POWER_CTRL, ENIRQ_DC_OK);
#if IMX233_SUBTARGET < 3780
    BF_CLR(POWER_CTRL, ENIRQ_LINREG_OK);
#endif /* IMX233_SUBTARGET < 3780 */
#endif /* IMX233_SUBTARGET >= 3700 */
    imx233_icoll_enable_interrupt(INT_SRC_VDD5V, true);
}
Exemple #6
0
void INT_LCDIF_ERROR(void)
{
    if(BF_RD(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ))
    {
        if(g_cur_frame_cb)
            g_cur_frame_cb();
        BF_CLR(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ);
    }
    if(BF_RD(LCDIF_CTRL1, VSYNC_EDGE_IRQ))
    {
        if(g_vsync_edge_cb)
            g_vsync_edge_cb();
        BF_CLR(LCDIF_CTRL1, VSYNC_EDGE_IRQ);
    }
}
Exemple #7
0
int button_read_device(void)
{
    int btn = 0;
    if(BF_RD(POWER_STS, PSWITCH) == 1)
        btn |= BUTTON_POWER;
    return imx233_button_lradc_read(btn);
}
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
void hw_power_ClearVbusValidInterrupt(void)
{
    while( BF_RD(POWER_CTRL, VBUSVALID_IRQ) != 0 )
    {
        BF_CLR(POWER_CTRL, VBUSVALID_IRQ);
    }
}
Exemple #9
0
static inline int __attribute__((always_inline)) read_lradc(int src)
{
    BF_CLR(LRADC_CTRL1, LRADCx_IRQ(src));
    BF_SETV(LRADC_CTRL0, SCHEDULE, 1 << src);
    while(!BF_RD(LRADC_CTRL1, LRADCx_IRQ(src)));
    return BF_RDn(LRADC_CHn, src, VALUE);
}
Exemple #10
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
uint16_t hw_power_GetBatteryChargeCurrentThreshold(void)
{
    uint16_t u16Threshold;

    u16Threshold = BF_RD(POWER_CHARGE, STOP_ILIMIT);

    return hw_power_ConvertSettingToCurrent(u16Threshold);
}
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
void hw_power_ClearVdd5vDroopInterrupt(void)
{

    while( BF_RD(POWER_CTRL, VDD5V_DROOP_IRQ) != 0 )
    {
        BF_CLR(POWER_CTRL, VDD5V_DROOP_IRQ);
    }

}
Exemple #12
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
uint16_t hw_power_GetMaxBatteryChargeCurrent(void)
{
    uint8_t u8Bits;

    // Get the raw data from register
    u8Bits = BF_RD(POWER_CHARGE, BATTCHRG_I);

    // Translate raw data to current (in mA) and return it
    return hw_power_ConvertSettingToCurrent(u8Bits);
}
Exemple #13
0
/* clear RTC ALARM wakeup or AUTORESTART bits here. */
void PowerPrep_ClearAutoRestart( void )
{
	HW_RTC_CTRL_CLR( BM_ICOLL_CTRL_SFTRST );
	while( HW_RTC_CTRL.B.SFTRST == 1 );
	HW_RTC_CTRL_CLR( BM_ICOLL_CTRL_CLKGATE );
	while( HW_RTC_CTRL.B.CLKGATE == 1 );
        /* Due to the hardware design bug of mx28 EVK-A
        * we need to set the AUTO_RESTART bit.
	*/
	if(HW_RTC_PERSISTENT0.B.AUTO_RESTART==0)
	{
		while(BF_RD( RTC_STAT, NEW_REGS));
		HW_RTC_PERSISTENT0.B.AUTO_RESTART = 1;
		BF_SET(RTC_CTRL, FORCE_UPDATE);
		BF_CLR(RTC_CTRL, FORCE_UPDATE);
		while(BF_RD( RTC_STAT, NEW_REGS));
		while(BF_RD( RTC_STAT, STALE_REGS));
	}
}
Exemple #14
0
enum imx233_i2c_error_t imx233_i2c_end(unsigned timeout)
{
    if(i2c_nr_stages == 0)
        return I2C_ERROR;
    i2c_stage[i2c_nr_stages - 1].dma.cmd |= BM_APB_CHx_CMD_SEMAPHORE | BM_APB_CHx_CMD_IRQONCMPLT;

    BF_CLR(I2C_CTRL1, ALL_IRQ);
    imx233_dma_reset_channel(APB_I2C);
    imx233_icoll_enable_interrupt(INT_SRC_I2C_DMA, true);
    imx233_icoll_enable_interrupt(INT_SRC_I2C_ERROR, true);
    imx233_dma_enable_channel_interrupt(APB_I2C, true);
    imx233_dma_start_command(APB_I2C, &i2c_stage[0].dma);

    enum imx233_i2c_error_t ret;
    if(semaphore_wait(&i2c_sema, timeout) == OBJ_WAIT_TIMEDOUT)
    {
        imx233_dma_reset_channel(APB_I2C);
        imx233_i2c_reset();
        ret = I2C_TIMEOUT;
    }
    else if(BF_RD(I2C_CTRL1, MASTER_LOSS_IRQ))
        ret = I2C_MASTER_LOSS;
    else if(BF_RD(I2C_CTRL1, NO_SLAVE_ACK_IRQ))
    {
        /* the core doesn't like this error, this is a workaround to prevent lock up */
#if IMX233_SUBTARGET >= 3780
        BF_SET(I2C_CTRL1, CLR_GOT_A_NAK);
#endif
        imx233_dma_reset_channel(APB_I2C);
        imx233_i2c_reset();
        ret = I2C_NO_SLAVE_ACK;
    }
    else if(BF_RD(I2C_CTRL1, EARLY_TERM_IRQ))
        ret = I2C_SLAVE_NAK;
    else
        ret = imx233_i2c_finalize();
    /* sleep */
    BF_SET(I2C_CTRL0, CLKGATE);
    mutex_unlock(&i2c_mutex);
    return ret;
}
Exemple #15
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
uint16_t  hw_power_SetBatteryChargeCurrentThreshold(uint16_t u16Threshold)
{
    uint16_t   u16OldSetting;
    uint16_t   u16NewSetting;
    uint16_t   u16ToggleMask;

    //--------------------------------------------------------------------------
    // See hw_power_SetMaxBatteryChargeCurrent for an explanation of why we're
    // using the toggle register here.
    //
    // Since this function doesn't have any major hardware effect, we could use
    // the usual macros for writing to this bit field. But, for the sake of
    // parallel construction and any potentially odd effects on the status bit,
    // we use the toggle register in the same way as ddi_bc_hwSetMaxCurrent.
    //--------------------------------------------------------------------------

    //--------------------------------------------------------------------------
    // The threshold hardware can't express as large a range as the max
    // current setting, but we can use the same functions as long as we add an
    // extra check here.
    //
    // Thresholds larger than 180mA can't be expressed.
    //--------------------------------------------------------------------------

    if (u16Threshold > 180) u16Threshold = 180;

    ////////////////////////////////////////
    // Create the mask
    ////////////////////////////////////////

    // Get the old setting.
    u16OldSetting = BF_RD(POWER_CHARGE, STOP_ILIMIT);

    // Convert the new threshold into a setting.
    u16NewSetting = hw_power_ConvertCurrentToSetting(u16Threshold);

    // Compute the toggle mask.
    u16ToggleMask = u16OldSetting ^ u16NewSetting;

    // Shift to the correct bit position
    u16ToggleMask = BF_POWER_CHARGE_STOP_ILIMIT(u16ToggleMask);


    /////////////////////////////////////////
    // Write to the register
    /////////////////////////////////////////

    // Write to the toggle register.
    HW_POWER_CHARGE_TOG(u16ToggleMask);

    // Tell the caller what current we're set at now.
    return(hw_power_ConvertSettingToCurrent(u16NewSetting));
}
Exemple #16
0
bool gpmi_is_dma_active(uint32_t chipSelect)
{
    uint32_t    u32Sema;
    reg32_t     r32ChipDmaNumber    = (NAND0_APBH_CH); //+chipSelect);
    uint32_t    u32Run;

    u32Sema = HW_APBH_CHn_SEMA_RD(r32ChipDmaNumber) & BM_APBH_CHn_SEMA_PHORE;

    u32Run = BF_RD(GPMI_CTRL0, RUN);

    // A nonzero value for either of these means a DMA is running.
    return ( u32Sema | u32Run );
}
Exemple #17
0
/**
 * Context functions
 */
static inline enum context_t get_context(void)
{
#if IMX233_SUBTARGET >= 3780
    /* On the imx233 it's easy because we know the power up source */
    unsigned pwrup_src = BF_RD(POWER_STS, PWRUP_SOURCE);
    if(pwrup_src & (1 << 5))
        return CONTEXT_USB;
    else if(pwrup_src & (1 << 4))
        return CONTEXT_RTC;
    else
        return CONTEXT_NORMAL;
#else
    /* On the other targets, we need to poke a few more registers */
#endif
}
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_power_EnablePswitchInterrupt(bool bEnable)
{
    bool bPrev = BF_RD(POWER_CTRL, ENIRQ_PSWITCH);

    if(bEnable)
    {
        BF_SET(POWER_CTRL, ENIRQ_PSWITCH);
    }
    else
    {
        BF_CLR(POWER_CTRL, ENIRQ_PSWITCH);
    }

    return bPrev;
}
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_power_EnableVdd5vGtVddioInterrupt(bool bEnable)
{
    bool bPrev = BF_RD(POWER_CTRL, ENIRQ_VDD5V_GT_VDDIO);

    if(bEnable)
    {
        BF_SET(POWER_CTRL, ENIRQ_VDD5V_GT_VDDIO);
    }
    else
    {
        BF_CLR(POWER_CTRL, ENIRQ_VDD5V_GT_VDDIO);
    }

    return bPrev;
}
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_power_EnableVbusValidInterrupt(bool bEnable)
{
    bool bPrev = BF_RD(POWER_CTRL, ENIRQ_VBUS_VALID);

    if(bEnable)
    {
        BF_SET(POWER_CTRL, ENIRQ_VBUS_VALID);
    }
    else
    {
        BF_CLR(POWER_CTRL, ENIRQ_VBUS_VALID);
    }

    return bPrev;
}
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_power_EnableVdddBrownoutInterrupt(bool bEnable)
{
    bool bPrev = BF_RD(POWER_CTRL, ENIRQ_VDDD_BO);

    if(bEnable)
    {
        BF_SET(POWER_CTRL, ENIRQ_VDDD_BO);
    }
    else
    {
        BF_CLR(POWER_CTRL, ENIRQ_VDDD_BO);
    }

    return bPrev;
}
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_power_EnableBatteryBrownoutInterrupt(bool bEnable)
{
    bool bPrev = BF_RD(POWER_CTRL, ENIRQBATT_BO);

    if(bEnable)
    {
        BF_SET(POWER_CTRL, ENIRQBATT_BO);
    }
    else
    {
        BF_CLR(POWER_CTRL, ENIRQBATT_BO);
    }

    return bPrev;
}
Exemple #23
0
void lcd_enable(bool enable)
{
    if(lcd_active() == enable)
        return;

    lcd_set_active(enable);
    if(lcd_active())
    {
        // enable spi
        spi_enable(true);
        // reset
        imx233_lcdif_reset_lcd(true);
        imx233_lcdif_reset_lcd(false);
        mdelay(1);
        imx233_lcdif_reset_lcd(true);
        mdelay(1);
        // "power" on
        lcd_power(true);
        // setup registers
        lcd_power_seq();
        lcd_init_seq();
        lcd_display_on_seq();

        imx233_dma_reset_channel(APB_LCDIF);
        imx233_dma_start_command(APB_LCDIF, &lcdif_dma[0].dma);
    }
    else
    {
        // power down
        lcd_display_off_seq();
        lcd_power(false);
        // stop lcdif
        BF_CLR(LCDIF_CTRL, DOTCLK_MODE);
        /* stmp37xx errata: clearing DOTCLK_MODE won't clear RUN: wait until
         * fifo is empty and then clear manually */
        while(!BF_RD(LCDIF_STAT, TXFIFO_EMPTY));
        BF_CLR(LCDIF_CTRL, RUN);
        // disable spi
        spi_enable(false);
    }
}
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_power_EnableVdd5vDroopInterrupt(bool bEnable)
{
    bool bPrev = false;



    bPrev = BF_RD(POWER_CTRL, ENIRQ_VDD5V_DROOP);

    if(bEnable)
    {
        BF_SET(POWER_CTRL, ENIRQ_VDD5V_DROOP);
    }
    else
    {
        BF_CLR(POWER_CTRL, ENIRQ_VDD5V_DROOP);
    }



    return bPrev;
}
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_power_Enable4p2BrownoutInterrupt(bool bEnable)
{
    bool bPrev = false;



    bPrev = BF_RD(POWER_CTRL, ENIRQ_DCDC4P2_BO);

    if(bEnable)
    {
        BF_SET(POWER_CTRL, ENIRQ_DCDC4P2_BO);
    }
    else
    {
        BF_CLR(POWER_CTRL, ENIRQ_DCDC4P2_BO);
    }



    return bPrev;
}
Exemple #26
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_lradc.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_lradc_GetInterruptFlag(hw_lradc_Channel_t eChannel)
{
    bool bRtn;

    // Returns LRADC interrupt flag
    switch (eChannel)
    {
        case LRADC_CH0:
            bRtn = BF_RD(LRADC_CTRL1, LRADC0_IRQ);
            break;
        case LRADC_CH1:
            bRtn = BF_RD(LRADC_CTRL1, LRADC1_IRQ);
            break;
        case LRADC_CH2:
            bRtn = BF_RD(LRADC_CTRL1, LRADC2_IRQ);
            break;
        case LRADC_CH3:
            bRtn = BF_RD(LRADC_CTRL1, LRADC3_IRQ);
            break;
        case LRADC_CH4:
            bRtn = BF_RD(LRADC_CTRL1, LRADC4_IRQ);
            break;
        case LRADC_CH5:
            bRtn = BF_RD(LRADC_CTRL1, LRADC5_IRQ);
            break;
        case LRADC_CH6:
            bRtn = BF_RD(LRADC_CTRL1, LRADC6_IRQ);
            break;
        case LRADC_CH7:
            bRtn = BF_RD(LRADC_CTRL1, LRADC7_IRQ);
            break;
        default:
            bRtn = 0;
            break;
    }
    return bRtn;
}
Exemple #27
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_lradc.h for details.
////////////////////////////////////////////////////////////////////////////////
bool hw_lradc_GetChannelPresent(hw_lradc_Channel_t eChannel)
{
    bool bRtn;

    // Read a bit field of HW_LRADC_STATUS register
    switch (eChannel)
    {
        case LRADC_CH0:
            bRtn =  BF_RD(LRADC_STATUS, CHANNEL0_PRESENT);
            break;
        case LRADC_CH1:
            bRtn =  BF_RD(LRADC_STATUS, CHANNEL1_PRESENT);
            break;
        case LRADC_CH2:
            bRtn =  BF_RD(LRADC_STATUS, CHANNEL2_PRESENT);
            break;
        case LRADC_CH3:
            bRtn =  BF_RD(LRADC_STATUS, CHANNEL3_PRESENT);
            break;
        case LRADC_CH4:
            bRtn =  BF_RD(LRADC_STATUS, CHANNEL4_PRESENT);
            break;
        case LRADC_CH5:
            bRtn =  BF_RD(LRADC_STATUS, CHANNEL5_PRESENT);
            break;
        case LRADC_CH6:
            bRtn =  BF_RD(LRADC_STATUS, CHANNEL6_PRESENT);
            break;
        case LRADC_CH7:
            bRtn =  BF_RD(LRADC_STATUS, CHANNEL7_PRESENT);
            break;
        default:
            bRtn = 0;
            break;
    }
    return bRtn;
}
Exemple #28
0
void imx233_lcdif_pio_send(bool data_mode, unsigned len, void *buf)
{
    imx233_lcdif_wait_ready();
    if(len == 0)
        return;
#if IMX233_SUBTARGET >= 3780
    imx233_lcdif_enable_bus_master(false);
#endif
    if(data_mode)
        BF_SET(LCDIF_CTRL, DATA_SELECT);
    else
        BF_CLR(LCDIF_CTRL, DATA_SELECT);

    switch(BF_RD(LCDIF_CTRL, WORD_LENGTH))
    {
        case BV_LCDIF_CTRL_WORD_LENGTH__8_BIT: pio_send(len, 1, buf); break;
        case BV_LCDIF_CTRL_WORD_LENGTH__16_BIT: pio_send(len, 2, buf); break;
#if IMX233_SUBTARGET >= 3780
        case BV_LCDIF_CTRL_WORD_LENGTH__18_BIT: pio_send(len, 4, buf); break;
#endif
        default: panicf("Don't know how to handle this word length");
    }
}
Exemple #29
0
////////////////////////////////////////////////////////////////////////////////
//! See hw_power.h for details.
////////////////////////////////////////////////////////////////////////////////
uint16_t hw_power_SetMaxBatteryChargeCurrent(uint16_t u16Current)
{
    uint16_t   u16OldSetting;
    uint16_t   u16NewSetting;
    uint16_t   u16ToggleMask;

    if(u16Current > 780)
        u16Current = 780;

    // Get the old setting.
    u16OldSetting = BF_RD(POWER_CHARGE, BATTCHRG_I);

    // Convert the new threshold into a setting.
    u16NewSetting = hw_power_ConvertCurrentToSetting(u16Current);

    // Compute the toggle mask.
    u16ToggleMask = u16OldSetting ^ u16NewSetting;

    // Write to the toggle register.
    HW_POWER_CHARGE_TOG(u16ToggleMask << BP_POWER_CHARGE_BATTCHRG_I);

    // Tell the caller what current we're set at now.
    return(hw_power_ConvertSettingToCurrent(u16NewSetting));
}
bool charging_state(void)
{
    return BF_RD(POWER_STS, CHRGSTS);
}