static irqreturn_t str8100_i2s_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
{
	u32 interrupt_status;
	DEBUG_PRINT("%s: this_irq=%d, I2S_INTERRUPT_STATUS_REG=0x%.8x\n",__FUNCTION__,this_irq,I2S_INTERRUPT_STATUS_REG);

	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
	//todo:
	interrupt_status = I2S_INTERRUPT_STATUS_REG;   

		I2S_RIGHT_TRANSMIT_DATA_REG=0;


	if ((interrupt_status & (I2S_RXBF_R_FULL_FLAG | I2S_RXBF_L_FULL_FLAG | I2S_TXBF_R_EMPTY_FLAG | I2S_TXBF_L_EMPTY_FLAG))){
		printk("%s: Error! wrong i2s empty/full flag\n",__FUNCTION__);
	
	}

	if ((interrupt_status & (I2S_RXBF_R_OR_FLAG | I2S_RXBF_L_OR_FLAG |I2S_TXBF_R_UR_FLAG | I2S_TXBF_L_UR_FLAG))){
		// Clear I2S interrupt status
		i2s_err_lur++;
		if(i2s_err_lur>10)
			I2S_INTERRUPT_ENABLE_REG &= ~(I2S_TXBF_L_UR_FLAG);
//			HAL_I2S_DISABLE_I2S();
		
		printk("%s: Left Channel Tx Underrun!, interrupt_status=%.8x,i2s_err_lur=%d\n",__FUNCTION__,interrupt_status,i2s_err_lur);
	}
	I2S_INTERRUPT_STATUS_REG &= 0xf0;

	
	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);

    return IRQ_HANDLED;
}
Exemplo n.º 2
0
static irqreturn_t str8100_gpio_irq_handler(int this_irq, void *dev_id/*, struct pt_regs *regs*/)
{
	unsigned int volatile    statusA,statusB;
	int i;

	if(debug) printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);

	HAL_INTC_DISABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);

	HAL_GPIOA_READ_INTERRUPT_MASKED_STATUS(statusA);
	HAL_GPIOB_READ_INTERRUPT_MASKED_STATUS(statusB);
//printk("%s: %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x \n",__FUNCTION__,GPIOA_DATA_OUTPUT_REG,GPIOA_DATA_INPUT_REG,GPIOA_DIRECTION_REG,GPIOA_INTERRUPT_ENABLE_REG,GPIOA_INTERRUPT_RAW_STATUS_REG,GPIOA_INTERRUPT_MASKED_STATUS_REG,GPIOA_INTERRUPT_MASKED_STATUS_REG,GPIOA_INTERRUPT_MASK_REG,GPIOA_INTERRUPT_TRIGGER_METHOD_REG,GPIOA_INTERRUPT_TRIGGER_BOTH_EDGES_REG,GPIOA_INTERRUPT_TRIGGER_TYPE_REG,GPIOA_BOUNCE_ENABLE_REG,GPIOA_BOUNCE_CLOCK_PRESCALE_REG);
	for (i = 0; i < 32; i++)
	{
		if (statusA & (1 << i)){
       			if(debug) printk("%s: GPIOA Int %d\n",__FUNCTION__,i);
       			if(gpioA_irq_handler){
       				gpioA_irq_handler(i,dev_id,NULL/*regs*/);
       			}
		}	 
		if (statusB & (1 << i)){
       			if(debug) printk("%s: GPIOB Int %d\n",__FUNCTION__,i);
       			if(gpioB_irq_handler){
       				gpioB_irq_handler(i,dev_id,NULL/*regs*/);
       			}
		}	 
	}
	HAL_GPIOA_CLEAR_INTERRUPT(statusA);
	HAL_GPIOB_CLEAR_INTERRUPT(statusB);

	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);
	HAL_INTC_ENABLE_INTERRUPT_SOURCE(INTC_GPIO_EXTERNAL_INT_BIT_INDEX);

    return IRQ_HANDLED;
}
Exemplo n.º 3
0
static irqreturn_t str8100_ext_irq_handler(int this_irq, void *dev_id/*, struct pt_regs *regs*/)
{
	if(debug) printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);

	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
	if(ext_irq_handler){
		ext_irq_handler(this_irq,dev_id,NULL/*regs*/);
	}
	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);

    return IRQ_HANDLED;
}
Exemplo n.º 4
0
static irqreturn_t str8100_ext_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
{
	void (*fnptr)(void)=NULL;
	printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);
	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);

	if(mode==1) while(1);
	else fnptr();

	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);

    return IRQ_HANDLED;
}
static irqreturn_t str8100_dma_tc_irq_handler(int this_irq, void *dev_id, struct pt_regs *regs)
{
	u32 dma_tc_status,tot_size;
	u32 len;
//printk("%s: this_irq=%d\n",__FUNCTION__,this_irq);

	HAL_INTC_DISABLE_INTERRUPT_SOURCE(this_irq);
	//todo:

    HAL_DMAC_READ_TERMINAL_COUNT_INTERRUPT_STATUS(dma_tc_status);
printk("%s: this_irq=%d, dma_tc_status=%.8x\n",__FUNCTION__,this_irq,dma_tc_status);

#ifdef I2S_WM8772_DMAC_LLP_RING_TEST
	u32 i;
    /*
     * For LLP ring test, the TC interrupt shoule not happen!!
     */
	for(i=0;i<8;i++)
	if (dma_tc_status & DMAC_CH_ID(i)){                      
		HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i));
		printk("%s: channel %d: Error!! there should be no tc irq happened!!\n",__FUNCTION__,i);
	}

#else
    /*
     * For this case, it's recommended to set I2S_WM8772_DMAC_LLP_NUM = 1
     */
    /*
     * For DMA's Tx for I2S Left Channel
     */
    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_left_tx_channel))
    {                      
        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_left_tx_channel);
        
        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_left_tx_channel));

        /*
         * Re-initialize DMA's channel for Left_Tx
         */
        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_left_tx_channel) = i2s_left_tx_channel_dma_llp_desc[0].SrcAddr;

        DMAC_CH_DST_ADDR(i2s_wm8772_dma_left_tx_channel) = i2s_left_tx_channel_dma_llp_desc[0].DstAddr;

        /*
         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
         * number of source transfer width!
         */        
        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);

        DMAC_CH_SIZE(i2s_wm8772_dma_left_tx_channel) = tot_size & 0x0FFF;

        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_left_tx_channel);
    }


    /*
     * For DMA's Tx for I2S Right Channel
     */
    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_right_tx_channel))
    {                      
        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_right_tx_channel);
        
        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_right_tx_channel));

        /*
         * Re-initialize DMA's channel for Right_Tx
         */
        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_right_tx_channel) = i2s_right_tx_channel_dma_llp_desc[0].SrcAddr;

        DMAC_CH_DST_ADDR(i2s_wm8772_dma_right_tx_channel) = i2s_right_tx_channel_dma_llp_desc[0].DstAddr;

        /*
         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
         * number of source transfer width!
         */        
        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);

        DMAC_CH_SIZE(i2s_wm8772_dma_right_tx_channel) = tot_size & 0x0FFF;

        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_right_tx_channel);
    }


    /*
     * For DMA's Rx for I2S Left Channel
     */
    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_left_rx_channel))
    {                      
        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_left_rx_channel);
        
        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_left_rx_channel));

        /*
         * Re-initialize DMA's channel for Left_Rx
         */
        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_left_rx_channel) = i2s_left_rx_channel_dma_llp_desc[0].SrcAddr;

        DMAC_CH_DST_ADDR(i2s_wm8772_dma_left_rx_channel) = i2s_left_rx_channel_dma_llp_desc[0].DstAddr;

        /*
         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
         * number of source transfer width!
         */        
        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);

        DMAC_CH_SIZE(i2s_wm8772_dma_left_rx_channel) = tot_size & 0x0FFF;

        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_left_rx_channel);
    }


    /*
     * For DMA's Rx for I2S Right Channel
     */
    if (dma_tc_status & DMAC_CH_ID(i2s_wm8772_dma_right_rx_channel))
    {                      
        HAL_DMAC_DISABLE_CHANNEL(i2s_wm8772_dma_right_rx_channel);
        
        HAL_DMAC_CLEAR_TERMINAL_COUNT_INTERRUPT_STATUS(DMAC_CH_ID(i2s_wm8772_dma_right_rx_channel));

        /*
         * Re-initialize DMA's channel for Right_Rx
         */
        DMAC_CH_SRC_ADDR(i2s_wm8772_dma_right_rx_channel) = i2s_right_rx_channel_dma_llp_desc[0].SrcAddr;

        DMAC_CH_DST_ADDR(i2s_wm8772_dma_right_rx_channel) = i2s_right_rx_channel_dma_llp_desc[0].DstAddr;

        /*
         * Note this macro DMAC_CH_SIZE is to configure TOT_SIZE field which is the total transfer
         * number of source transfer width!
         */        
        tot_size = Hal_Dmac_Get_Channel_Transfer_Unit_Number(I2S_WM8772_BUFFER_SIZE * 4, DMAC_CH_SRC_WIDTH_32_BITS);

        DMAC_CH_SIZE(i2s_wm8772_dma_right_rx_channel) = tot_size & 0x0FFF;

        HAL_DMAC_ENABLE_CHANNEL(i2s_wm8772_dma_right_rx_channel);
    }
#endif



	HAL_INTC_CLEAR_EDGE_TRIGGER_INTERRUPT(this_irq);
	HAL_INTC_ENABLE_INTERRUPT_SOURCE(this_irq);

    return IRQ_HANDLED;
}