void tsdemux_release(void)
{


    WRITE_MPEG_REG(PARSER_INT_ENABLE, 0);
    WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0);
    WRITE_MPEG_REG(PARSER_AUDIO_HOLE, 0);
    free_irq(INT_PARSER, (void *)tsdemux_fetch_id);

#ifndef ENABLE_DEMUX_DRIVER
    WRITE_MPEG_REG(STB_INT_MASK, 0);
    free_irq(INT_DEMUX, (void *)tsdemux_irq_id);
#else

    tsdemux_set_aid(0xffff);
    tsdemux_set_vid(0xffff);
    tsdemux_set_sid(0xffff);
    tsdemux_free_irq();

#endif


    pts_stop(PTS_TYPE_VIDEO);
    pts_stop(PTS_TYPE_AUDIO);

#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6
    switch_mod_gate_by_type(MOD_DEMUX, 0);
#endif

}
s32 tsdemux_init(u32 vid, u32 aid, u32 sid, u32 pcrid)
#endif
{
    s32 r;
    u32 parser_sub_start_ptr;
    u32 parser_sub_end_ptr;
    u32 parser_sub_rp;
    u32 pcr_num;

#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6
    switch_mod_gate_by_type(MOD_DEMUX, 1);
#endif

    parser_sub_start_ptr = READ_MPEG_REG(PARSER_SUB_START_PTR);
    parser_sub_end_ptr = READ_MPEG_REG(PARSER_SUB_END_PTR);
    parser_sub_rp = READ_MPEG_REG(PARSER_SUB_RP);

    WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER);

#ifdef ENABLE_DEMUX_DRIVER
    tsdemux_reset();
#else
    WRITE_MPEG_REG(RESET1_REGISTER, RESET_PARSER | RESET_DEMUXSTB);

    WRITE_MPEG_REG(STB_TOP_CONFIG, 0);
    WRITE_MPEG_REG(DEMUX_CONTROL, 0);
#endif

    /* set PID filter */
    printk("tsdemux video_pid = 0x%x, audio_pid = 0x%x, sub_pid = 0x%x, pcrid = 0x%x\n",
           vid, aid, sid, pcrid);

#ifndef ENABLE_DEMUX_DRIVER
    WRITE_MPEG_REG(FM_WR_DATA,
                   (((vid & 0x1fff) | (VIDEO_PACKET << 13)) << 16) |
                   ((aid & 0x1fff) | (AUDIO_PACKET << 13)));
    WRITE_MPEG_REG(FM_WR_ADDR, 0x8000);
    while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) {
        ;
    }

    WRITE_MPEG_REG(FM_WR_DATA,
                   (((sid & 0x1fff) | (SUB_PACKET << 13)) << 16) | 0xffff);
    WRITE_MPEG_REG(FM_WR_ADDR, 0x8001);
    while (READ_MPEG_REG(FM_WR_ADDR) & 0x8000) {
        ;
    }

    WRITE_MPEG_REG(MAX_FM_COMP_ADDR, 1);

    WRITE_MPEG_REG(STB_INT_MASK, 0);
    WRITE_MPEG_REG(STB_INT_STATUS, 0xffff);

    /* TS data path */
    WRITE_MPEG_REG(FEC_INPUT_CONTROL, 0x7000);
    WRITE_MPEG_REG(DEMUX_MEM_REQ_EN,
                   (1 << VIDEO_PACKET) |
                   (1 << AUDIO_PACKET) |
                   (1 << SUB_PACKET));
    WRITE_MPEG_REG(DEMUX_ENDIAN,
                   (7 << OTHER_ENDIAN)  |
                   (7 << BYPASS_ENDIAN) |
                   (0 << SECTION_ENDIAN));
    WRITE_MPEG_REG(TS_HIU_CTL, 1 << USE_HI_BSF_INTERFACE);
    WRITE_MPEG_REG(TS_FILE_CONFIG,
                   (demux_skipbyte << 16)                  |
                   (6 << DES_OUT_DLY)                      |
                   (3 << TRANSPORT_SCRAMBLING_CONTROL_ODD) |
                   (1 << TS_HIU_ENABLE)                    |
                   (4 << FEC_FILE_CLK_DIV));

    /* enable TS demux */
    WRITE_MPEG_REG(DEMUX_CONTROL, (1 << STB_DEMUX_ENABLE) | (1 << KEEP_DUPLICATE_PACKAGE));
#endif

    if (fetchbuf == 0) {
        printk("%s: no fetchbuf\n", __FUNCTION__);
        return -ENOMEM;
    }

    /* hook stream buffer with PARSER */
#if HAS_HEVC_VDEC
    if (is_hevc) {
        WRITE_MPEG_REG(PARSER_VIDEO_START_PTR,
                       READ_VREG(HEVC_STREAM_START_ADDR));
        WRITE_MPEG_REG(PARSER_VIDEO_END_PTR,
                       READ_VREG(HEVC_STREAM_END_ADDR) - 8);

        CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR);

        WRITE_VREG(DOS_GEN_CTRL0, 3<<1);    // set vififo_vbuf_rp_sel=>hevc

        SET_VREG_MASK(HEVC_STREAM_CONTROL, (1<<3)|(0<<4)); // set use_parser_vbuf_wp
        SET_VREG_MASK(HEVC_STREAM_CONTROL, 1); // set stream_fetch_enable
        SET_VREG_MASK(HEVC_STREAM_FIFO_CTL, (1<<29)); // set stream_buffer_hole with 256 bytes
    } else {
#endif
        WRITE_MPEG_REG(PARSER_VIDEO_START_PTR,
                       READ_VREG(VLD_MEM_VIFIFO_START_PTR));
        WRITE_MPEG_REG(PARSER_VIDEO_END_PTR,
                       READ_VREG(VLD_MEM_VIFIFO_END_PTR));
        CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_VID_MAN_RD_PTR);

        WRITE_VREG(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
        CLEAR_VREG_MASK(VLD_MEM_VIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);

#if HAS_HEVC_VDEC
        WRITE_VREG(DOS_GEN_CTRL0, 0);    // set vififo_vbuf_rp_sel=>vdec
    }
#endif

    WRITE_MPEG_REG(PARSER_AUDIO_START_PTR,
                   READ_MPEG_REG(AIU_MEM_AIFIFO_START_PTR));
    WRITE_MPEG_REG(PARSER_AUDIO_END_PTR,
                   READ_MPEG_REG(AIU_MEM_AIFIFO_END_PTR));
    CLEAR_MPEG_REG_MASK(PARSER_ES_CONTROL, ES_AUD_MAN_RD_PTR);

    WRITE_MPEG_REG(PARSER_CONFIG,
                   (10 << PS_CFG_PFIFO_EMPTY_CNT_BIT) |
                   (1  << PS_CFG_MAX_ES_WR_CYCLE_BIT) |
                   (16 << PS_CFG_MAX_FETCH_CYCLE_BIT));

    WRITE_MPEG_REG(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);
    CLEAR_MPEG_REG_MASK(AIU_MEM_AIFIFO_BUF_CNTL, MEM_BUFCTRL_INIT);

    WRITE_MPEG_REG(PARSER_SUB_START_PTR, parser_sub_start_ptr);
    WRITE_MPEG_REG(PARSER_SUB_END_PTR, parser_sub_end_ptr);
    WRITE_MPEG_REG(PARSER_SUB_RP, parser_sub_rp);
    SET_MPEG_REG_MASK(PARSER_ES_CONTROL, (7 << ES_SUB_WR_ENDIAN_BIT) | ES_SUB_MAN_RD_PTR);

#if HAS_HEVC_VDEC
    if ((r = pts_start((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO)) < 0) {
#else
    if ((r = pts_start(PTS_TYPE_VIDEO)) < 0) {
#endif
        printk("Video pts start failed.(%d)\n", r);
        goto err1;
    }

    if ((r = pts_start(PTS_TYPE_AUDIO)) < 0) {
        printk("Audio pts start failed.(%d)\n", r);
        goto err2;
    }

    r = request_irq(INT_PARSER, parser_isr,
                    IRQF_SHARED, "tsdemux-fetch",
                    (void *)tsdemux_fetch_id);
    if (r) {
        goto err3;
    }

    WRITE_MPEG_REG(PARSER_INT_STATUS, 0xffff);
    WRITE_MPEG_REG(PARSER_INT_ENABLE, PARSER_INTSTAT_FETCH_CMD << PARSER_INT_HOST_EN_BIT);

    WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0x400);
    WRITE_MPEG_REG(PARSER_AUDIO_HOLE, 0x400);

    discontinued_counter = 0;
#ifndef ENABLE_DEMUX_DRIVER
    r = request_irq(INT_DEMUX, tsdemux_isr,
                    IRQF_SHARED, "tsdemux-irq",
                    (void *)tsdemux_irq_id);
    WRITE_MPEG_REG(STB_INT_MASK,
                   (1 << SUB_PES_READY)
                   | (1 << NEW_PDTS_READY)
                   | (1 << DIS_CONTINUITY_PACKET));
    if (r) {
        goto err4;
    }
#else
    tsdemux_config();
    tsdemux_request_irq(tsdemux_isr, (void *)tsdemux_irq_id);
    if (vid < 0x1FFF) {
        tsdemux_set_vid(vid);
    }
    if (aid < 0x1FFF) {
        tsdemux_set_aid(aid);
    }
    if (sid < 0x1FFF) {
        tsdemux_set_sid(sid);
    }
    if ((pcrid < 0x1FFF) && (pcrid != vid) && (pcrid != aid) && (pcrid != sid)) {
    	tsdemux_set_pcrid(pcrid);
	}
#endif

    /* set paramater to fetch pcr */  
    pcr_num=0;
    if(pcrid == vid)
    	pcr_num=0;
    else if(pcrid == aid)
    	pcr_num=1;
    else
    	pcr_num=3;

    if(READ_MPEG_REG(TS_HIU_CTL_2) & 0x40){
    	WRITE_MPEG_REG(PCR90K_CTL_2, 12 << 1);    
    	WRITE_MPEG_REG(ASSIGN_PID_NUMBER_2, pcr_num);    
    	printk("[tsdemux_init] To use device 2,pcr_num=%d \n",pcr_num);
    }
    else if(READ_MPEG_REG(TS_HIU_CTL_3) & 0x40){
    	WRITE_MPEG_REG(PCR90K_CTL_3, 12 << 1); 
    	WRITE_MPEG_REG(ASSIGN_PID_NUMBER_3, pcr_num);    
    	printk("[tsdemux_init] To use device 3,pcr_num=%d \n",pcr_num);
    }
    else{
    	WRITE_MPEG_REG(PCR90K_CTL, 12 << 1); 
    	WRITE_MPEG_REG(ASSIGN_PID_NUMBER, pcr_num);    
    	printk("[tsdemux_init] To use device 1,pcr_num=%d \n",pcr_num);
    }
    pcrscr_valid=1;

    return 0;

#ifndef ENABLE_DEMUX_DRIVER
err4:
    free_irq(INT_PARSER, (void *)tsdemux_fetch_id);
#endif
err3:
    pts_stop(PTS_TYPE_AUDIO);
err2:
#if HAS_HEVC_VDEC
    pts_stop((is_hevc) ? PTS_TYPE_HEVC : PTS_TYPE_VIDEO);
#else
    pts_stop(PTS_TYPE_VIDEO);
#endif
err1:
    printk("TS Demux init failed.\n");
    return -ENOENT;
}

void tsdemux_release(void)
{
    pcrscr_valid=0;

    WRITE_MPEG_REG(PARSER_INT_ENABLE, 0);
    WRITE_MPEG_REG(PARSER_VIDEO_HOLE, 0);
    WRITE_MPEG_REG(PARSER_AUDIO_HOLE, 0);
    free_irq(INT_PARSER, (void *)tsdemux_fetch_id);

#ifndef ENABLE_DEMUX_DRIVER
    WRITE_MPEG_REG(STB_INT_MASK, 0);
    free_irq(INT_DEMUX, (void *)tsdemux_irq_id);
#else

    tsdemux_set_aid(0xffff);
    tsdemux_set_vid(0xffff);
    tsdemux_set_sid(0xffff);
    tsdemux_set_pcrid(0xffff);
    tsdemux_free_irq();

#endif


    pts_stop(PTS_TYPE_VIDEO);
    pts_stop(PTS_TYPE_AUDIO);

#if MESON_CPU_TYPE >= MESON_CPU_TYPE_MESON6
    switch_mod_gate_by_type(MOD_DEMUX, 0);
#endif

}