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 }
void imx233_power_set_stop_current(unsigned current) { #if IMX233_SUBTARGET >= 3700 BF_CLR(POWER_CHARGE, STOP_ILIMIT); #else BF_CLR(POWER_BATTCHRG, STOP_ILIMIT); #endif /* find closest current GREATHER THAN OR EQUAL TO the expected current */ unsigned sum = 0; for(unsigned i = 0; i < ARRAYLEN(g_charger_stop_current_bits); i++) sum += g_charger_stop_current_bits[i].current; for(unsigned i = 0; i < ARRAYLEN(g_charger_stop_current_bits); i++) { sum -= g_charger_stop_current_bits[i].current; if(current > sum) { current -= g_charger_stop_current_bits[i].current; #if IMX233_SUBTARGET >= 3700 BF_WR(POWER_CHARGE_SET, STOP_ILIMIT(g_charger_stop_current_bits[i].bit)); #else BF_WR(POWER_BATTCHRG_SET, STOP_ILIMIT(g_charger_stop_current_bits[i].bit)); #endif } } }
void imx233_lcdif_enable_vsync_edge_irq(bool en) { if(en) BF_SET(LCDIF_CTRL1, VSYNC_EDGE_IRQ_EN); else BF_CLR(LCDIF_CTRL1, VSYNC_EDGE_IRQ_EN); BF_CLR(LCDIF_CTRL1, VSYNC_EDGE_IRQ); }
void imx233_lcdif_enable_frame_done_irq(bool en) { if(en) BF_SET(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ_EN); else BF_CLR(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ_EN); BF_CLR(LCDIF_CTRL1, CUR_FRAME_DONE_IRQ); }
/* only works for channels <=7, always divide by 2, never accumulates */ static inline void __attribute__((always_inline)) setup_lradc(int src) { BF_CLR(LRADC_CTRL0, SFTRST); BF_CLR(LRADC_CTRL0, CLKGATE); /* don't bother changing the source, we are early enough at boot so that * channel x is mapped to source x */ HW_LRADC_CHn_CLR(src) = BM_OR2(LRADC_CHn, NUM_SAMPLES, ACCUMULATE); BF_SETV(LRADC_CTRL2, DIVIDE_BY_TWO, 1 << src); }
void imx233_lcdif_reset_lcd(bool enable) { #if IMX233_SUBTARGET < 3700 if(enable) BF_SET(LCDIF_CTRL, RESET); else BF_CLR(LCDIF_CTRL, RESET); #else if(enable) BF_SET(LCDIF_CTRL1, RESET); else BF_CLR(LCDIF_CTRL1, RESET); #endif }
//////////////////////////////////////////////////////////////////////////////// //! See hw_lradc.h for details. //////////////////////////////////////////////////////////////////////////////// void hw_lradc_EnableTouchDetectXDrive(bool bValue) { if(bValue) { //Enable the X-Drive BF_SET(LRADC_CTRL0, XMINUS_ENABLE); BF_SET(LRADC_CTRL0, XPLUS_ENABLE); } else { // Disable the X-Drive BF_CLR(LRADC_CTRL0, XMINUS_ENABLE); BF_CLR(LRADC_CTRL0, XPLUS_ENABLE); } }
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); } }
void imx233_enable_usb_phy(bool enable) { if(enable) { BF_CLR(USBPHY_CTRL, SFTRST); BF_CLR(USBPHY_CTRL, CLKGATE); HW_USBPHY_PWD_CLR = 0xffffffff; } else { HW_USBPHY_PWD_SET = 0xffffffff; BF_SET(USBPHY_CTRL, SFTRST); BF_SET(USBPHY_CTRL, CLKGATE); } }
//////////////////////////////////////////////////////////////////////////////// //! 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); } }
void imx233_lcdif_enable(bool enable) { if(enable) BF_CLR(LCDIF_CTRL, CLKGATE); else BF_SET(LCDIF_CTRL, CLKGATE); }
void mipi_csi2_clock_set(void) { //set VIDPLL(PLL5) to 596MHz HW_CCM_ANALOG_PLL_VIDEO_WR(BF_CCM_ANALOG_PLL_VIDEO_DIV_SELECT(0) | BF_CCM_ANALOG_PLL_VIDEO_ENABLE(1)); HW_CCM_ANALOG_PLL_VIDEO_NUM_WR(0x00000000); HW_CCM_ANALOG_PLL_VIDEO_DENOM_WR(0x00000001); while (!HW_CCM_ANALOG_PLL_VIDEO.B.LOCK) ; //waiting for PLL lock BF_CLR(CCM_ANALOG_PLL_VIDEO, BYPASS); //select CSI0_HSYNC osc_clk 24MHz, CKO1 output drives cko2 clock HW_IOMUXC_SW_MUX_CTL_PAD_CSI0_HSYNC_WR( BF_IOMUXC_SW_MUX_CTL_PAD_CSI0_HSYNC_SION_V(DISABLED) | BF_IOMUXC_SW_MUX_CTL_PAD_CSI0_HSYNC_MUX_MODE_V(ALT3)); HW_IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC_WR( BF_IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC_HYS_V(ENABLED) | BF_IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC_PUS_V(100K_OHM_PU) | BF_IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC_PUE_V(PULL) | BF_IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC_PKE_V(ENABLED) | BF_IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC_ODE_V(DISABLED) | BF_IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC_SPEED_V(100MHZ) | BF_IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC_DSE_V(40_OHM) | BF_IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC_SRE_V(SLOW)); HW_CCM_CCOSR_WR( BF_CCM_CCOSR_CLKO1_SEL(0) | BF_CCM_CCOSR_CLKO1_DIV(0) | BF_CCM_CCOSR_CLKO1_EN(1) | BF_CCM_CCOSR_CLKO_SEL(1) | // select cko2 for cko1 output BF_CCM_CCOSR_CLKO2_SEL(0xe) | // osc_clk BF_CCM_CCOSR_CLKO2_DIV(0) | // div 1 BF_CCM_CCOSR_CLKO2_EN(1)); }
void imx233_enable_usb_controller(bool enable) { if(enable) BF_CLR(DIGCTL_CTRL, USB_CLKGATE); else BF_SET(DIGCTL_CTRL, USB_CLKGATE); }
void imx233_pwm_enable(int channel, bool enable) { if(enable) BF_SET(PWM_CTRL, PWMx_ENABLE(channel)); else BF_CLR(PWM_CTRL, PWMx_ENABLE(channel)); }
void imx233_lcdif_enable_bus_master(bool enable) { if(enable) BF_SET(LCDIF_CTRL, LCDIF_MASTER); else BF_CLR(LCDIF_CTRL, LCDIF_MASTER); }
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); }
void imx233_lcdif_enable_underflow_recover(bool enable) { if(enable) BF_SET(LCDIF_CTRL1, RECOVER_ON_UNDERFLOW); else BF_CLR(LCDIF_CTRL1, RECOVER_ON_UNDERFLOW); }
static int hp_unmute_cb(struct timeout *tmo) { (void) tmo; /* unmute HP */ BF_CLR(AUDIOOUT_HPVOL, MUTE); return 0; }
void imx233_i2c_begin(void) { mutex_lock(&i2c_mutex); /* wakeup */ BF_CLR(I2C_CTRL0, CLKGATE); i2c_nr_stages = 0; i2c_buffer_end = 0; }
static void lcd_underflow(void) { /* on underflow, current frame is dead so stop lcdif and prepare for next frame * don't bother with the errata, fifo is empty since we are underflowing ! */ BF_CLR(LCDIF_CTRL, DOTCLK_MODE); imx233_dma_reset_channel(APB_LCDIF); imx233_dma_start_command(APB_LCDIF, &lcdif_dma[0].dma); }
void imx233_audioout_preinit(void) { /* Enable AUDIOOUT block */ imx233_reset_block(&HW_AUDIOOUT_CTRL); /* Enable digital filter clock */ imx233_clkctrl_enable(CLK_FILT, true); /* Enable DAC */ BF_CLR(AUDIOOUT_ANACLKCTRL, CLKGATE); /* Set capless mode */ #if IMX233_AUDIO_COUPLING_MODE == ACM_CAP BF_SET(AUDIOOUT_PWRDN, CAPLESS); #else BF_CLR(AUDIOOUT_PWRDN, CAPLESS); #endif /* Set word-length to 16-bit */ BF_SET(AUDIOOUT_CTRL, WORD_LENGTH); /* Power up DAC */ BF_CLR(AUDIOOUT_PWRDN, DAC); /* Hold HP to ground to avoid pop, then release and power up HP */ BF_SET(AUDIOOUT_ANACTRL, HP_HOLD_GND); BF_CLR(AUDIOOUT_PWRDN, HEADPHONE); /* Set HP mode to AB */ BF_SET(AUDIOOUT_ANACTRL, HP_CLASSAB); /* change bias to -50% */ BF_WR(AUDIOOUT_TEST, HP_I1_ADJ, 1); BF_WR(AUDIOOUT_REFCTRL, BIAS_CTRL, 1); #if IMX233_SUBTARGET >= 3700 BF_SET(AUDIOOUT_REFCTRL, RAISE_REF); #endif BF_SET(AUDIOOUT_REFCTRL, XTAL_BGR_BIAS); /* Stop holding to ground */ BF_CLR(AUDIOOUT_ANACTRL, HP_HOLD_GND); /* Set dmawait count to 31 (see errata, workaround random stop) */ BF_WR(AUDIOOUT_CTRL, DMAWAIT_COUNT, 31); /* start converting audio */ BF_SET(AUDIOOUT_CTRL, RUN); /* unmute DAC */ HW_AUDIOOUT_DACVOLUME_CLR = BM_OR2(AUDIOOUT_DACVOLUME, MUTE_LEFT, MUTE_RIGHT); /* send a few samples to avoid pop */ HW_AUDIOOUT_DATA = 0; HW_AUDIOOUT_DATA = 0; HW_AUDIOOUT_DATA = 0; HW_AUDIOOUT_DATA = 0; }
//////////////////////////////////////////////////////////////////////////////// //! 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); } }
void imx233_power_set_charge_current(unsigned current) { #if IMX233_SUBTARGET >= 3700 BF_CLR(POWER_CHARGE, BATTCHRG_I); #else BF_CLR(POWER_BATTCHRG, BATTCHRG_I); #endif /* find closest current LOWER THAN OR EQUAL TO the expected current */ for(unsigned i = 0; i < ARRAYLEN(g_charger_current_bits); i++) if(current >= g_charger_current_bits[i].current) { current -= g_charger_current_bits[i].current; #if IMX233_SUBTARGET >= 3700 BF_WR(POWER_CHARGE_SET, BATTCHRG_I(g_charger_current_bits[i].bit)); #else BF_WR(POWER_BATTCHRG_SET, BATTCHRG_I(g_charger_current_bits[i].bit)); #endif } }
//////////////////////////////////////////////////////////////////////////////// //! See hw_power.h for details. //////////////////////////////////////////////////////////////////////////////// void hw_power_EnableDcOkInterrupt(bool bEnable) { if(bEnable) { BF_SET(POWER_CTRL, ENIRQ_DC_OK); } else { BF_CLR(POWER_CTRL, ENIRQ_DC_OK); } }
//////////////////////////////////////////////////////////////////////////////// //! See hw_power.h for details. //////////////////////////////////////////////////////////////////////////////// void hw_power_SetPswitchInterruptSource(bool bSource) { if(bSource == HW_POWER_STS_PSWITCH_BIT_0) { BF_CLR(POWER_CTRL, PSWITCH_IRQ_SRC); } else // bSource == HW_POWER_STS_PSWITCH_BIT_1 { BF_SET(POWER_CTRL, PSWITCH_IRQ_SRC); } }
//////////////////////////////////////////////////////////////////////////////// //! See hw_lradc.h for details. //////////////////////////////////////////////////////////////////////////////// void hw_lradc_EnableTouchDetectInterrupt(bool bValue) { if(bValue) { //Enable the touch detector interrupt BF_SET(LRADC_CTRL1, TOUCH_DETECT_IRQ_EN); } else { // Disable the touch detector interrupt BF_CLR(LRADC_CTRL1, TOUCH_DETECT_IRQ_EN); } }
//////////////////////////////////////////////////////////////////////////////// //! See hw_lradc.h for details. //////////////////////////////////////////////////////////////////////////////// void hw_lradc_EnableTouchDetect(bool bValue) { if(bValue) { //Enable the touch detector BF_SET(LRADC_CTRL0, TOUCH_DETECT_ENABLE); } else { // Disable the touch detector BF_CLR(LRADC_CTRL0, TOUCH_DETECT_ENABLE); } }
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); } }
void imx233_audioout_close(void) { /* Switch to class A */ BF_CLR(AUDIOOUT_ANACTRL, HP_CLASSAB); /* Hold HP to ground */ BF_SET(AUDIOOUT_ANACTRL, HP_HOLD_GND); /* Mute HP and power down */ BF_SET(AUDIOOUT_HPVOL, MUTE); /* Power down HP */ BF_SET(AUDIOOUT_PWRDN, HEADPHONE); /* Mute DAC */ BF_SET(AUDIOOUT_DACVOLUME, MUTE_LEFT, MUTE_RIGHT); /* Power down DAC */ BF_SET(AUDIOOUT_PWRDN, DAC); /* Gate off DAC */ BF_SET(AUDIOOUT_ANACLKCTRL, CLKGATE); /* Disable digital filter clock */ imx233_clkctrl_enable(CLK_FILT, false); /* will also gate off the module */ BF_CLR(AUDIOOUT_CTRL, RUN); }
//////////////////////////////////////////////////////////////////////////////// //! See hw_power.h for details. //////////////////////////////////////////////////////////////////////////////// void hw_power_SetPswitchInterruptPolarity(bool bPolarity) { if(bPolarity == HW_POWER_CHECK_PSWITCH_LOW) { BF_CLR(POWER_CTRL, POLARITY_PSWITCH); } // bPolarity == HW_POWER_CHECK_PSWITCH_HIGH else { BF_SET(POWER_CTRL, POLARITY_PSWITCH); } }