int ssw_switch_mode(char *buf, unsigned int len)
{
	int ret = 0;
	unsigned int mode = *((unsigned int *)buf);

	SSW_DBG("sim switch: %s(%d) \n", mode?"Single Talk":"Dual Talk", curr_ssw_mode);

	mutex_lock(&ssw_mutex);
	
	if (curr_ssw_mode != mode) {
		curr_ssw_mode = mode;
		
		if (curr_ssw_mode == SSW_DUAL_TALK)
			mt_set_gpio_out(ch_swap, GPIO_OUT_ONE);		
		else if (curr_ssw_mode == SSW_SING_TALK)
			mt_set_gpio_out(ch_swap, GPIO_OUT_ZERO);		
	}
	
	mutex_unlock(&ssw_mutex);

	SSW_DBG("sim switch(%d) OK, ch_swap=%d, en=%d \n", curr_ssw_mode,
		mt_get_gpio_out(ch_swap), mt_get_gpio_out(en));

	return 0;
	
}
ssize_t ssw_mode_store(struct kobject *kobj, const char *buffer, size_t size)
{
	unsigned int mode;
	int res = kstrtoint(buffer, 0, &mode);
	unsigned int type;

	if (res != 1) {
		SSW_DBG("%s: expect 1 numbers\n", __func__);
	} else {
		SSW_DBG("ssw_mode_store %x\n", mode);
		/*Switch sim mode */
		type = (mode & 0xFFFF0000) >> 16;
		mode = mode & 0x0000FFFF;
		if (type == 0) {	/*Internal */
			SSW_DBG("Internal sim switch: %d-->%d\n", sim_mode_curr,
				mode);
			if ((sim_mode_curr != mode)
			    && (SSW_SUCCESS == set_sim_gpio(mode))) {
				sim_mode_curr = mode;
			}
		} else {
			SSW_DBG("External sim switch: %d-->%d\n",
				ext_ssw_mode_curr, mode);
			if (ext_ssw_mode_curr != mode
			    && (SSW_SUCCESS == set_ext_sim_gpio(mode))) {
				ext_ssw_mode_curr = mode;
			}
		}
	}
	return size;
}
static int __init ssw_driver_init(void)
{
	int ret = 0;

	ret = platform_driver_register(&ssw_driver);
	if (ret) {
		SSW_DBG("ssw_driver register fail(%d)\n", ret);
		return ret;
	}
	 
	return ret;
}
ssize_t ssw_mode_show(struct kobject *kobj, char *buffer)
{
	int remain = PAGE_SIZE;
	int len;
	char *ptr = buffer;

	len = scnprintf(ptr, remain, "0x%x\n", get_ext_current_ssw_mode());
	ptr += len;
	remain -= len;
	SSW_DBG("ssw_mode_show\n");

	return PAGE_SIZE - remain;
}
//sim switch hardware initial
static int ssw_init(unsigned int mode) 
{
	SSW_DBG("ssw_init: %s \n", mode?"Single Talk":"Dual Talk");

	unsigned int ch_mode, en_mode;
	//ch_swap = GPIO_SSW_CH_SWAP_PIN;
	//en = GPIO_SSW_EN_PIN;
	//ch_mode = GPIO_SSW_CH_SWAP_PIN_M_GPIO;
	//en_mode = GPIO_SSW_EN_PIN_M_GPIO;
	ch_swap = GPIO101;
	en = GPIO105;
	ch_mode = GPIO_MODE_00;
	en_mode = GPIO_MODE_00;
	
	//initial Ch_Swap pin: 1, host1->sim slot1, host2->sim slot2; 0, host1->sim slot2, host2->sim slot1
	mt_set_gpio_mode(ch_swap, ch_mode);
	mt_set_gpio_dir(ch_swap, GPIO_DIR_OUT);

	//initial EN pin: 1, enable sim slot; 0, disable sim slot
	mt_set_gpio_mode(en, en_mode);
	mt_set_gpio_dir(en, GPIO_DIR_OUT);

	curr_ssw_mode = mode;
	if (mode == SSW_DUAL_TALK) {
		mt_set_gpio_out(ch_swap, GPIO_OUT_ONE);
		
	} else if (mode == SSW_SING_TALK) {
		mt_set_gpio_out(ch_swap, GPIO_OUT_ZERO);
	}

	mt_set_gpio_out(en, GPIO_OUT_ONE);

	SSW_DBG("ssw_init: ch_swap=(%d %d %d), en=(%d %d %d) \n", 
		ch_swap, ch_mode, mt_get_gpio_out(ch_swap),
		en, en_mode, mt_get_gpio_out(en));

	return 0;
}
unsigned int get_sim_switch_type(void)
{
	SSW_DBG("[ccci/ssw]COMBO_FXLA2203_V2\n");
	return SSW_EXT_DUAL_1X2;
}
static int ssw_resume(struct platform_device *dev)
{
	SSW_DBG("ssw_resume \n");
	return 0;
}
static int ssw_suspend(struct platform_device *dev, pm_message_t state)
{
	SSW_DBG("ssw_suspend \n");
	return 0;
}
static void ssw_shutdown(struct platform_device *dev)
{
	SSW_DBG("ssw_shutdown \n");
}