static void tcpal_work_read_fic(struct work_struct *_param)
{
	s32 size = TCBD_FIC_SIZE, ret;
	u8 buff[TCBD_FIC_SIZE];
	u64 diff;
	struct tcbd_irq_data *irq_data = container_of(_param,
						struct tcbd_irq_data, work);
	struct tcbd_device *device = irq_data->device;

	diff = tcpal_diff_time(irq_data->start_tick);
	tcbd_debug(DEBUG_INTRRUPT, "work delay :%d\n", (u32)diff);

	ret = tcbd_read_fic_data(device, buff, size);
	if (ret < 0) {
		tcbd_debug(DEBUG_ERROR, "failed to read fic! %d\n", ret);
		goto exit_work;
	}

#ifndef CONFIG_SKY_TDMB
	tcbd_enqueue_data(buff, size, 0, 1);
#endif

	if (!start_tune) /* set by tune_frequency*/
		goto exit_work;

	ret = tcc_fic_run_decoder(buff, MAX_FIC_SIZE);
	if (ret > 0) {
		tcc_fic_get_ensbl_info(1);
		start_tune = 0;
		tcc_fic_parser_init();
	}
exit_work:
	enable_irq(irq_data->tcbd_irq);
}
static s32 __set_frequency(unsigned long freqKHz, bool scan_mode)
{
	s32 ret = 0;
	u8 status;

	tcbd_disable_irq(&tcc3170_device, 0);
	tcc_fic_parser_init();
	ret = tcbd_tune_frequency(&tcc3170_device, freqKHz, 1500);
	if (ret < 0) {
		DPRINTK("tcbd_tune_frequency fail %d\n", ret);
		return -EFAULT;
	}

	if (scan_mode) {
		ret = tcbd_wait_tune(&tcc3170_device, &status);
		if (ret < 0) {
			DPRINTK("wait_tune fail status:0x%02X, ret:0x%x\n", \
				status, ret);
			ret =  -EFAULT;
		}
	}
	DPRINTK("%s : status:0x%02X, ret:0x%x\n", __func__, status, ret);

	if (ret == TCERR_SUCCESS) {
#if defined(__CSPI_ONLY__)
		tcbd_enable_irq(&tcc3170_device, TCBD_IRQ_EN_DATAINT);
#else
#error
#endif
	}
	return ret;
}
static s32 tcpal_irq_stream_callback(
#endif
	s32 _dev_idx,
	u8 *_stream,
	s32 _size,
	u8 _subch_id,
	u8 _type)
{
	/*static u64 time = 0;*/
	/*struct tcbd_status_data status;*/
#if 0 //ndef CONFIG_SKY_TDMB
	s32 ret, i = 0;
#endif

	switch (_type) {
	case 0: /*MSC*/
		/* write your own code!!*/
	case 1: /*FIC*/
		/* write your own code!!*/

#ifdef CONFIG_SKY_TDMB
    tcc3170_put_data(_stream, _size, _type);
#endif

#if 0 //ndef CONFIG_SKY_TDMB
		if (!start_tune) /* set by tune_frequency*/
			goto skip_fic_parse;

		for (i = 0; i < _size/TCBD_FIC_SIZE; i++) {
			ret = tcc_fic_run_decoder(_stream + (i * TCBD_FIC_SIZE),
					MAX_FIC_SIZE);
			if (ret > 0) {
				tcc_fic_get_ensbl_info(1);
				start_tune = 0;
				tcc_fic_parser_init();
			}
		}
		/*tcbd_read_signal_info(tcbd_irq_handler_data.device, &status);
		tcbd_debug(DEBUG_ERROR,
			"PCBER:%d, SNR:%d, RSSI:%d, VBER:%d, TSPER:%d\n",
				status.pcber, status.snr, status.rssi,
				status.vber, status.tsper);*/
		/*if (tcpal_diff_time(time) > 1000) {
			tcbd_check_dsp_status(tcbd_irq_handler_data.device);
			time = tcpal_get_time();
		}*/
skip_fic_parse:
		tcbd_enqueue_data(_stream, _size, _subch_id, _type);
#endif
		break;
	case 2: /*STATUS*/
		tcbd_debug(DEBUG_STATUS, "status size:%d\n", _size);
		tcbd_update_status(_stream, _size, NULL);
		break;
	default:
		break;
	}
	return 0;
}
static bool tcc3170_scan_ch(struct ensemble_info_type *e_info
							, unsigned long freq)
{
	bool ret = false;

	if (tcc3170_pwr_on == true && e_info != NULL) {
		if (prev_subch != 0xFF) {
			tcbd_unregister_service(&tcc3170_device, prev_subch);
			prev_subch = 0xFF;
		}

		tcc_fic_parser_init();
		scan_done = false;
		if (__set_frequency((freq/1000), true) == TCERR_SUCCESS) {
			msleep(1200); /* optimize this point */

			if (scan_done == true)
				ret = __get_ensemble_info(e_info, freq);
		}
	}

	return ret;
}