static int rt8547_fled_get_mode(struct rt_fled_info *info)
{
	struct rt8547_chip *fi = (struct rt8547_chip *)info;

	RT_DBG("\n");
	return fi->in_use_mode;
}
static int rt8547_fled_suspend(struct rt_fled_info *info, pm_message_t state)
{
	struct rt8547_chip *fi = (struct rt8547_chip *)info;

	RT_DBG("\n");
	fi->suspend = 1;
	return 0;
}
static int rt8547_fled_resume(struct rt_fled_info *info)
{
	struct rt8547_chip *fi = (struct rt8547_chip *)info;

	RT_DBG("\n");
	fi->suspend = 0;
	return 0;
}
static int rt8547_fled_strobe(struct rt_fled_info *info)
{
	struct rt8547_chip *fi = (struct rt8547_chip *)info;

	RT_DBG("\n");
	rt8547_fled_flash_en(fi->pdata, 0);
	rt8547_fled_ctrl_en(fi->pdata, 0);
	rt8547_fled_ctrl_en(fi->pdata, 1);
	rt8547_fled_flash_en(fi->pdata, 1);
	return 0;
}
static inline void rt8547_fled_flash_en(struct rt8547_platform_data *pdata,
					int en)
{
    if (gpio_is_valid(pdata->flen_gpio)){
    	if (en)
    		gpio_set_value(pdata->flen_gpio, ((pdata->flen_active) & 0x1));
    	else
    		gpio_set_value(pdata->flen_gpio, (~(pdata->flen_active) & 0x1));
	}
	RT_DBG("en %d\n", en);
}
static void rt8547_reg_init(struct rt8547_chip *chip)
{
	RT_DBG("\n");
	rt8547_send_data(chip, RT8547_FLED_REG0,
			 rt8547_reg_initval[RT8547_FLED_REG0 - 1]);
	rt8547_send_data(chip, RT8547_FLED_REG1,
			 rt8547_reg_initval[RT8547_FLED_REG1 - 1]);
	rt8547_send_data(chip, RT8547_FLED_REG2,
			 rt8547_reg_initval[RT8547_FLED_REG2 - 1]);
	rt8547_send_data(chip, RT8547_FLED_REG3,
			 rt8547_reg_initval[RT8547_FLED_REG3 - 1]);
}
static int rt8547_fled_set_strobe_current_sel(struct rt_fled_info *info,
					      int selector)
{
	struct rt8547_chip *fi = (struct rt8547_chip *)info;
	unsigned char tmp = 0;

	RT_DBG("selector=%d\n", selector);
	tmp = rt8547_reg_initval[RT8547_FLED_REG1 - 1];
	tmp &= ~RT8547_SCLEVEL_MASK;
	tmp |= selector;
	rt8547_send_data(fi, RT8547_FLED_REG1, tmp);
	return 0;
}
static int rt8547_fled_set_strobe_timeout_sel(struct rt_fled_info *info,
					      int selector)
{
	struct rt8547_chip *fi = (struct rt8547_chip *)info;
	unsigned char tmp = 0;

	RT_DBG("selector=%d\n", selector);
	if (selector > RT8547_STO_MAX)
		return -EINVAL;
	tmp = rt8547_reg_initval[RT8547_FLED_REG3 - 1];
	tmp &= ~RT8547_STO_MASK;
	tmp |= selector;
	rt8547_send_data(fi, RT8547_FLED_REG3, tmp);
	return 0;
}
static int rt8547_fled_set_timeout_level_sel(struct rt_fled_info *info,
					     int selector)
{
	struct rt8547_chip *fi = (struct rt8547_chip *)info;
	unsigned char tmp = 0;

	RT_DBG("selector=%d\n", selector);
	if (selector > RT8547_TOL_MAX)
		return -EINVAL;
	tmp = rt8547_reg_initval[RT8547_FLED_REG1 - 1];
	tmp &= ~RT8547_TOCLEVEL_MASK;
	tmp |= (selector << RT8547_TOCLEVEL_SHFT);
	rt8547_send_data(fi, RT8547_FLED_REG1, tmp);
	return 0;
}
static void rt8547_create_debugfs(struct rt8547_chip *chip)
{
	RT_DBG("add debugfs for RT8547\n");
	debugfs_rt_dent = debugfs_create_dir("rt8547_dbg", 0);
	if (!IS_ERR(debugfs_rt_dent)) {
		rtdbg_data[0].info = chip;
		rtdbg_data[0].id = RT8547_DBG_REG;
		debugfs_file[0] = debugfs_create_file("reg",
						      S_IFREG | S_IRUGO,
						      debugfs_rt_dent,
						      (void *)&rtdbg_data[0],
						      &reg_debug_ops);

		rtdbg_data[1].info = chip;
		rtdbg_data[1].id = RT8547_DBG_DATA;
		debugfs_file[1] = debugfs_create_file("data",
						      S_IFREG | S_IRUGO,
						      debugfs_rt_dent,
						      (void *)&rtdbg_data[1],
						      &reg_debug_ops);

		rtdbg_data[2].info = chip;
		rtdbg_data[2].id = RT8547_DBG_REGS;
		debugfs_file[2] = debugfs_create_file("regs",
						      S_IFREG | S_IRUGO,
						      debugfs_rt_dent,
						      (void *)&rtdbg_data[2],
						      &reg_debug_ops);

		rtdbg_data[3].info = chip;
		rtdbg_data[3].id = RT8547_DBG_FLED;
		debugfs_file[3] = debugfs_create_file("fled",
						      S_IFREG | S_IRUGO,
						      debugfs_rt_dent,
						      (void *)&rtdbg_data[3],
						      &reg_debug_ops);
	} else {
		dev_err(chip->dev, "create debugfs failed\n");
	}
}
static int rt8547_fled_set_mode(struct rt_fled_info *info,
				flashlight_mode_t mode)
{
	struct rt8547_chip *fi = (struct rt8547_chip *)info;
	unsigned char tmp = 0;
	int ret = 0;

	RT_DBG("mode=%d\n", mode);
	switch (mode) {
	case FLASHLIGHT_MODE_TORCH:
		if (fi->in_use_mode == FLASHLIGHT_MODE_OFF)
			rt8547_fled_power_on(fi->pdata);
		tmp = rt8547_reg_initval[RT8547_FLED_REG2 - 1];
		tmp |= RT8547_MODESEL_MASK;
		rt8547_send_data(fi, RT8547_FLED_REG2, tmp);
		rt8547_fled_ctrl_en(fi->pdata, 1);
		rt8547_fled_flash_en(fi->pdata, 1);
		fi->in_use_mode = mode;
		break;
	case FLASHLIGHT_MODE_FLASH:
		if (fi->in_use_mode == FLASHLIGHT_MODE_OFF)
			rt8547_fled_power_on(fi->pdata);
		tmp = rt8547_reg_initval[RT8547_FLED_REG2 - 1];
		tmp &= ~RT8547_MODESEL_MASK;
		rt8547_send_data(fi, RT8547_FLED_REG2, tmp);
		fi->in_use_mode = mode;
		break;
	case FLASHLIGHT_MODE_OFF:
		rt8547_fled_flash_en(fi->pdata, 0);
		rt8547_fled_ctrl_en(fi->pdata, 0);
		if (fi->in_use_mode != FLASHLIGHT_MODE_OFF)
			rt8547_fled_power_off(fi->pdata);
		fi->in_use_mode = mode;
		break;
	case FLASHLIGHT_MODE_MIXED:
	default:
		ret = -EINVAL;
	}
	return 0;
}
static int rt8547_send_data(struct rt8547_chip *chip, unsigned char reg,
			    unsigned char data)
{
	struct rt8547_platform_data *pdata = chip->pdata;
	unsigned long flags;
	unsigned char xfer_data[3];	/*0: adddr, 1: reg, 2: reg data*/

	xfer_data[0] = RT8547_ONEWIRE_ADDR;
	xfer_data[1] = reg;
	xfer_data[2] = data;
	RT_DBG("rt8547-> 0: 0x%02x, 1: 0x%02x, 2: 0x%02x\n", xfer_data[0],
	       xfer_data[1], xfer_data[2]);
	spin_lock_irqsave(&chip->io_lock, flags);
	rt8547_start_xfer(pdata);
	rt8547_send_byte(pdata, xfer_data[0]);
	rt8547_send_special_byte(pdata, xfer_data[1]);
	rt8547_send_byte(pdata, xfer_data[2]);
	rt8547_stop_xfer(pdata);
	spin_unlock_irqrestore(&chip->io_lock, flags);
	/*write back to reg array*/
	rt8547_reg_initval[reg - 1] = data;
	return 0;
}
static int rt8547_fled_strobe_timeout_list(struct rt_fled_info *info,
					   int selector)
{
	RT_DBG("selector=%d\n", selector);
	return 64 + selector * 32;	/* unit: mS */
}
static int rt8547_fled_lv_protection_list(struct rt_fled_info *info,
					  int selector)
{
	RT_DBG("selector=%d\n", selector);
	return 3000 + selector * 100;	/* unit: mV */
}
static int rt8547_fled_timeout_level_list(struct rt_fled_info *info,
					  int selector)
{
	RT_DBG("selector=%d\n", selector);
	return 100000 + selector * 50000;	/* unit: uA */
}
static int rt8547_fled_init(struct rt_fled_info *info)
{
	RT_DBG("\n");
	return 0;
}
void RT_staticrt_allset(void)
{
	int i=0;
	char rtent[100];

	struct in_addr dst, mask, gw;
	int metric;

#ifdef	CONFIG_FIXED_STATIC_RT_TABLE
	for (i=0; i<CONFIG_STATIC_RT_NUM; i++)
	{
		if (CFG_get(CFG_RT_ENTRY+i+1, rtent) == -1)
			continue;
#else
	for (i=0; CFG_get(CFG_RT_ENTRY+i+1, rtent) != -1; i++)
	{
#endif
		if (RT_staticrt_parse(rtent, &dst, &mask, &gw, &metric) != 0)
			continue;

		RT_add(NULL, &dst, &mask, &gw, metric);
	}
}


//------------------------------------------------------------------------------
// FUNCTION
//
//
// DESCRIPTION
//
//  
// PARAMETERS
//
//  
// RETURN
//
//  
//------------------------------------------------------------------------------
int RT_add_del_staticrt(char *rtent, int set)
{
	char buf[100];
	struct in_addr dst, mask, gw;
	int metric;
	int rc;
	
	memcpy(buf, rtent, 100);

	if (RT_staticrt_parse(buf, &dst, &mask, &gw, &metric) != 0)
		return -1;

	/* no need ?? */
	//dst.s_addr = htonl( ntohl(dst.s_addr) & ntohl(mask.s_addr));
	if (set)
		rc = RT_add(NULL, &dst, &mask, &gw, metric);
	else
		rc = RT_del(NULL, &dst, &mask, &gw, metric);

	ip_forward_cache_clear();
	RT_DBG("[RT]: %s dst:%x mask:%x gw:%x rc:%s\n", set ? "add" : "del", dst.s_addr, mask.s_addr, gw.s_addr, (rc==0) ? "OK" : "FAIL");
	return rc;
}
static int rt8547_fled_strobe_current_list(struct rt_fled_info *info,
					   int selector)
{
	RT_DBG("selector=%d\n", selector);
	return 100000 + selector * 50000;	/* unit: uA */
}