Ejemplo n.º 1
0
static irqreturn_t gpio_irq_flow_ctrl(int irq, void *data)
{
	struct cbp_wait_event *cbp_flow_ctrl = (struct cbp_wait_event *)data;
	int level;
    //hr_t1 = sched_clock();
	level = !!oem_gpio_get_value(cbp_flow_ctrl->wait_gpio);
	
	//oem_gpio_set_irq_type(cbp_flow_ctrl->wait_gpio, IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING);
	//oem_gpio_set_irq_type(cbp_flow_ctrl->wait_gpio, IRQF_TRIGGER_FALLING );
	//oem_gpio_set_irq_type(cbp_flow_ctrl->wait_gpio, IRQ_TYPE_LEVEL_LOW |IRQ_TYPE_LEVEL_HIGH);
	oem_gpio_irq_unmask(cbp_flow_ctrl->wait_gpio);

	if(level == cbp_flow_ctrl->wait_polar){
		atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_ENABLE);
		//LOGPRT(LOG_DEBUG,  "%s: flow control is enable, please write later!\n", __func__);
	}
	else{
		atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_DISABLE);
		//LOGPRT(LOG_DEBUG,  "%s: %d flow control is disable, can write now!\n", __func__,flw_count);
		wake_up(&cbp_flow_ctrl->wait_q);
	}
	
	//hr_t2 = sched_clock();
	//printk("[sdio] t1=%llu,t2 =%llu,delta=%llu \n",hr_t1, hr_t2, hr_t2-hr_t1);
	return IRQ_HANDLED;
}
Ejemplo n.º 2
0
static irqreturn_t modem_reset_indication_irq(int irq, void *data)
{
    if(GPIO_OEM_VALID(cbp_rst_ind_gpio )){
        printk("%s %d oem_gpio_get_value(GPIO_VIATEL_MDM_RST_IND)=%d \n",__func__,__LINE__,oem_gpio_get_value(cbp_rst_ind_gpio));
        if(oem_gpio_get_value(cbp_rst_ind_gpio)){
            if(first_irq_flag == 1){
                printk("%s %d first irq read rest_gpio is high,return. \n",__func__,__LINE__);
                return IRQ_HANDLED;
            }
            wake_lock_timeout(&vmdata->wlock, MDM_RST_LOCK_TIME * HZ);
            modem_notify_event(MDM_EVT_NOTIFY_RESET_ON);
            via_modem_state = MODEM_STATE_POWER;
            via_monitor_uevent_notify(MODEM_STATE_POWER);
        }else{
            if(first_irq_flag == 1){
                printk("%s %d set first_irq_flag=0. \n",__func__,__LINE__);
                first_irq_flag = 0;
            }
            modem_notify_event(MDM_EVT_NOTIFY_RESET_OFF);
        }
    }
    irq_set_irq_type(irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
    gpio_irq_cbp_rst_ind();
    oem_gpio_irq_unmask(cbp_rst_ind_gpio);
    return IRQ_HANDLED;
}
Ejemplo n.º 3
0
static irqreturn_t modem_reset_indication_irq(int irq, void *data)
{
    printk("%s %d \n",__FUNCTION__,__LINE__);
    if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST_IND)){
        oem_gpio_set_irq_type(GPIO_VIATEL_MDM_RST_IND, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
        if(oem_gpio_get_value(GPIO_VIATEL_MDM_RST_IND)){
            printk("%s %d ON\n",__FUNCTION__,__LINE__);
			wake_lock_timeout(&vmdata->wlock, MDM_RST_LOCK_TIME * HZ);
            modem_notify_event(MDM_EVT_NOTIFY_RESET_ON);
        }else{
            printk("%s %d OFF\n",__FUNCTION__,__LINE__);
            modem_notify_event(MDM_EVT_NOTIFY_RESET_OFF);
        }
    }
    gpio_irq_cbp_rst_ind();
    oem_gpio_irq_unmask(GPIO_VIATEL_MDM_RST_IND);
    return IRQ_HANDLED;
}
Ejemplo n.º 4
0
static irqreturn_t gpio_irq_via_spi_tx_rx_fifo_empty_ack(int irq, void *data)
{
	struct cbp_wait_event *cbp_data_ack = (struct cbp_wait_event *)data;
	int level;
	int ret = -1;

	ret = irq_set_irq_type(irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);

	level = !!oem_gpio_get_value(cbp_data_ack->wait_gpio);
	hwlog_debug("%s enter, level = %d.\n", __func__, level);

	atomic_set(&cbp_data_ack->state, MODEM_ST_READY);
	wake_up(&cbp_data_ack->wait_q);

	oem_gpio_irq_unmask(cbp_data_ack->wait_gpio);

	return IRQ_HANDLED;
}
Ejemplo n.º 5
0
static irqreturn_t gpio_irq_flow_ctrl(int irq, void *data)
{
	struct cbp_wait_event *cbp_flow_ctrl = (struct cbp_wait_event *)data;
	int level;

	level = !!oem_gpio_get_value(cbp_flow_ctrl->wait_gpio);
	oem_gpio_irq_unmask(cbp_flow_ctrl->wait_gpio);

	if(level == cbp_flow_ctrl->wait_polar){
		atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_ENABLE);
	}
	else{
		atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_DISABLE);
		wake_up(&cbp_flow_ctrl->wait_q);
	}

	return IRQ_HANDLED;
}
Ejemplo n.º 6
0
static irqreturn_t gpio_irq_data_ack(int irq, void *data)
{
	struct cbp_wait_event *cbp_data_ack = (struct cbp_wait_event *)data;
	int level;
	//unsigned long long hr_t1,hr_t2;
	//hr_t1 = sched_clock();

	level = !!oem_gpio_get_value(cbp_data_ack->wait_gpio);
	//LOGPRT(LOG_NOTICE,  "%s enter, level = %d!\n", __func__, level);

	if(level == cbp_data_ack->wait_polar){
		atomic_set(&cbp_data_ack->state, MODEM_ST_READY);
		wake_up(&cbp_data_ack->wait_q);
	}
	oem_gpio_irq_unmask(cbp_data_ack->wait_gpio);
	//hr_t2 = sched_clock();
	//printk("[sdio]ack: t1=%llu,t2 =%llu,delta=%llu \n",hr_t1, hr_t2, hr_t2-hr_t1);
	return IRQ_HANDLED;
}
Ejemplo n.º 7
0
static int __init modem_init(void)
{
    int ret = 0;

    vmdata = kzalloc(sizeof(struct viatel_modem_data), GFP_KERNEL);
    if(!vmdata){
        ret = -ENOMEM;
        printk("No memory to alloc vmdata");
        goto err_create_vmdata;
    }

    ret = modem_data_init(vmdata);
    if(ret < 0){
        printk("Fail to init modem data\n");
        goto err_init_modem_data;
    }

    ret = platform_device_register(&platform_modem_device);
    if (ret) {
        printk("platform_device_register failed\n");
        goto err_platform_device_register;
    }
    ret = platform_driver_register(&platform_modem_driver);
    if (ret) {
        printk("platform_driver_register failed\n");
        goto err_platform_driver_register;
    }

    ret = misc_register(&misc_modem_device);
    if(ret < 0){
        printk("misc regiser via modem failed\n");
        goto err_misc_device_register;
    }

    //make the default ETS output through USB
    if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_ETS_SEL)){
        oem_gpio_direction_output(GPIO_VIATEL_MDM_ETS_SEL, 0);
    }

    if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_PWR_IND)){
        oem_gpio_irq_mask(GPIO_VIATEL_MDM_PWR_IND);
        oem_gpio_direction_input_for_irq(GPIO_VIATEL_MDM_PWR_IND);
        oem_gpio_set_irq_type(GPIO_VIATEL_MDM_PWR_IND, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
        ret = oem_gpio_request_irq(GPIO_VIATEL_MDM_PWR_IND, modem_power_indication_irq, \
                     IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, \
                     "mdm_power_ind", vmdata);
        oem_gpio_irq_unmask(GPIO_VIATEL_MDM_PWR_IND);
        if (ret < 0) {
            printk("fail to request mdm_power_ind irq\n");
        }
        modem_register_notifier(&vmdata->pwr_ntf);
    }

    if(GPIO_OEM_VALID(GPIO_VIATEL_MDM_RST_IND)){
        oem_gpio_irq_mask(GPIO_VIATEL_MDM_RST_IND);
        oem_gpio_direction_input_for_irq(GPIO_VIATEL_MDM_RST_IND);
        oem_gpio_set_irq_type(GPIO_VIATEL_MDM_RST_IND, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
        ret = oem_gpio_request_irq(GPIO_VIATEL_MDM_RST_IND, modem_reset_indication_irq, \
                     IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, \
                     "mdm_reset_ind", vmdata);
        oem_gpio_irq_unmask(GPIO_VIATEL_MDM_RST_IND);
        if (ret < 0) {
            printk("fail to request mdm_rst_ind irq\n");
        }
        modem_register_notifier(&vmdata->rst_ntf);
    }

    //oem_gpio_direction_output(GPIO_VIATEL_MDM_RST, 0);
    //oem_gpio_direction_output(GPIO_VIATEL_MDM_PWR_EN, 1);
    ret = sysfs_create_group(vmdata->modem_kobj, &g_attr_group);

    if(ret){
        printk("sysfs_create_group failed\n");
        goto err_sysfs_create_group; 
    }

    return 0;
err_sysfs_create_group:
    misc_deregister(&misc_modem_device);
err_misc_device_register:
    platform_driver_unregister(&platform_modem_driver);
err_platform_driver_register:
	platform_device_unregister(&platform_modem_device);
err_platform_device_register:
err_init_modem_data:
    kfree(vmdata);
    vmdata = NULL;
err_create_vmdata:
    return ret;
}
Ejemplo n.º 8
0
static int modem_boot_probe(struct platform_device *dev)
{
    int ret = 0;

    vmdata = kzalloc(sizeof(struct viatel_modem_data), GFP_KERNEL);
    if(!vmdata)
    {
        ret = -ENOMEM;
        printk("No memory to alloc vmdata");
        goto err_create_vmdata;
    }

    vmdata->via_pdev = dev;
    vmdata->tail = 0;
    vmdata->head = 0;

    ret = modem_data_init(vmdata);
    if(ret < 0)
    {
        printk("Fail to init modem data\n");
        goto err_init_modem_data;
    }

    ret = device_create_file(&(dev->dev), &dev_attr_state);
    if(ret < 0)
    {
        dev_err(&dev->dev, "Failed to create sysfs entry state\n");
        goto err_create_sysfs_state;
    }

    ret = device_create_file(&(dev->dev), &dev_attr_modem_state);
    if(ret < 0)
    {
        dev_err(&dev->dev, "Failed to create sysfs entry modem_state\n");
        goto err_create_sysfs_modem_state;
    }

    ret = device_create_file(&(dev->dev), &dev_attr_sim_switch);
    if(ret < 0)
    {
        dev_err(&dev->dev, "Failed to create sysfs entry sim_switch\n");
        goto err_create_sysfs_sim_switch;
    }

    ret = oem_get_gpio_number(CBP_VIATEL_RST_IND_STR,&cbp_rst_ind_gpio);
    if (ret)
        goto err_get_gpio;
    pr_info("%s get CBP_VIATEL_RST_IND_STR gpio %d\n", __func__, cbp_rst_ind_gpio);

    if(GPIO_OEM_VALID(cbp_rst_ind_gpio)){
        ret = oem_gpio_request(cbp_rst_ind_gpio, "GPIO_VIATEL_MDM_RST_IND");
        oem_gpio_irq_mask(cbp_rst_ind_gpio);
        oem_gpio_direction_input_for_irq(cbp_rst_ind_gpio);
        oem_gpio_set_irq_type(cbp_rst_ind_gpio, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);
        ret = oem_gpio_request_irq(cbp_rst_ind_gpio, modem_reset_indication_irq, \
                     IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_TRIGGER_FALLING, \
                     "mdm_reset_ind", vmdata);
        oem_gpio_irq_unmask(cbp_rst_ind_gpio);

        if (ret < 0) {
            printk("fail to request mdm_rst_ind irq\n");
        }
        modem_register_notifier(&vmdata->rst_ntf);
    }

    ret = oem_get_gpio_number(CBP_VIATEL_PWR_EN_STR, &cbp_pwr_en_gpio);
    if (ret)
            goto err_get_gpio;
    pr_info(">>>> %s get gpio %d\n", __func__, cbp_pwr_en_gpio);
    if(GPIO_OEM_VALID(cbp_pwr_en_gpio)){
		ret = oem_gpio_request(cbp_pwr_en_gpio, "GPIO_VIATEL_MDM_PWR_EN");

	    if (0 > ret) {
	        printk("%s: gpio request GPIO_VIATEL_MDM_PWR_EN failed", __FUNCTION__);
	    }
		oem_gpio_direction_output(cbp_pwr_en_gpio, 0);
    }

    ret = oem_get_gpio_number(CBP_VIATEL_RST_STR, &cbp_rst_gpio);
    if (ret)
            goto err_get_gpio;
    pr_info(">>>> %s get gpio %d\n", __func__,cbp_rst_gpio);

    if(GPIO_OEM_VALID(cbp_rst_gpio)){
		ret = oem_gpio_request(cbp_rst_gpio, "GPIO_VIATEL_MDM_RST");
	    if (0 > ret) {
	        printk("%s: gpio request GPIO_VIATEL_MDM_RST failed", __FUNCTION__);
	    }
		oem_gpio_direction_output(cbp_rst_gpio, 0);
    }

    ret = oem_get_gpio_number(CBP_VIATEL_SIM_SWITCH_STR, &cbp_sim_switch_gpio);
    if(ret){
        printk("%s: Sim connection switch isn't supported on this board", __FUNCTION__);
    }else{
        printk("%s: Sim connection switch is supported on this board", __FUNCTION__);
    }
    pr_info(">>>> %s get gpio %d\n", __func__,cbp_sim_switch_gpio);
    if(GPIO_OEM_VALID(cbp_sim_switch_gpio)){
        ret = oem_gpio_request(cbp_sim_switch_gpio, "GPIO_VIATEL_MDM_SIM_SWITCH");
        if(0 > ret){
            printk("%s: gpio request GPIO_VIATEL_MDM_PWR_EN failed", __FUNCTION__);
        }
        oem_gpio_direction_output(cbp_sim_switch_gpio, 0);
    }

    /*add gpio function to make cp ramdump*/
    ret = oem_get_gpio_number(CBP_VIATEL_GPIO_BACKUP_STR, &cbp_backup_gpio);
    if (ret)
            goto err_get_gpio;

    ret = oem_gpio_request(cbp_backup_gpio, "gpio_cbp_crash");
    if(0 > ret){
        printk("%s: gpio request GPIO_6_0 failed", __FUNCTION__);
    }

    oem_gpio_direction_output(cbp_backup_gpio, 0);

    return 0;

err_get_gpio:
    device_remove_file(&(dev->dev), &dev_attr_sim_switch);
err_create_sysfs_sim_switch:
    device_remove_file(&(dev->dev), &dev_attr_modem_state);
err_create_sysfs_modem_state:
    device_remove_file(&(dev->dev), &dev_attr_state);
err_create_sysfs_state:
err_init_modem_data:
    kfree(vmdata);
    vmdata = NULL;
err_create_vmdata:

    return ret;

}
Ejemplo n.º 9
0
//static int __devinit cbp_probe(struct platform_device *pdev)
static int cbp_probe(struct platform_device *pdev)
{
	struct cbp_platform_data *plat = pdev->dev.platform_data;
	int ret = -1;
	
	/* must have platform data */
	if (!plat) {
		LOGPRT(LOG_ERR,  "%s: no platform data!\n", __func__);
		ret = -EINVAL;
		goto out;
	}
	
	if(plat->bus && !strcmp(plat->bus,"sdio")){
		if(plat->detect_host){
			ret = plat->detect_host(plat->host_id);
			if(ret){
				LOGPRT(LOG_ERR,  "%s: host %s dectect failed!\n", __func__, plat->host_id);
				goto out;
			}
		}
		else{
			LOGPRT(LOG_ERR,  "%s: bus %s have no dectect function!\n", __func__, plat->bus);
			goto out;
		}
	}
	else{
		LOGPRT(LOG_ERR,  "%s: unknow bus!\n", __func__);
		goto out;
	}

	if((GPIO_OEM_VALID(plat->gpio_sd_select)) && (GPIO_OEM_VALID(plat->gpio_mc3_enable))){
		ret = oem_gpio_request(plat->gpio_mc3_enable, DRIVER_NAME"(MC3_EN_N)");
		if(ret < 0){
			LOGPRT(LOG_ERR,  "%s: %d fail to requset MC3_EN_N gpio %d ret =%d!!\n",
				__func__, __LINE__, plat->gpio_mc3_enable,ret);
			goto out;
		}
		ret = oem_gpio_request(plat->gpio_sd_select, DRIVER_NAME"(SD_SEL_N)");
		if(ret < 0){
			LOGPRT(LOG_ERR,  "%s: %d fail to requset SD_SEL_N gpio %d ret =%d!!\n", 
				__func__, __LINE__, plat->gpio_sd_select,ret);
			goto err_req_sd_sel;
		}
		oem_gpio_direction_output(GPIO_VIATEL_MC3_EN_N, 0); //MC3_EN_N
		oem_gpio_direction_output(GPIO_VIATEL_SD_SEL_N, 0); //SD_SEL_N
	}

	if(GPIO_OEM_VALID(plat->gpio_data_ack)){
		cbp_data_ack = kzalloc(sizeof(struct cbp_wait_event), GFP_KERNEL);
		if (!cbp_data_ack){
			ret = -ENOMEM;
			LOGPRT(LOG_ERR,  "%s %d kzalloc cbp_data_ack failed \n",__func__, __LINE__);
			goto err_kzalloc_cbp_data_ack;    
		}

		init_waitqueue_head(&cbp_data_ack->wait_q);
		atomic_set(&cbp_data_ack->state, MODEM_ST_UNKNOW);
		cbp_data_ack->wait_gpio = plat->gpio_data_ack;
		cbp_data_ack->wait_polar = plat->gpio_data_ack_polar;
		LOGPRT(LOG_ERR,  "cbp_data_ack->wait_gpio=%d\n",cbp_data_ack->wait_gpio);
		LOGPRT(LOG_ERR,  "cbp_data_ack->wait_polar=%d\n",cbp_data_ack->wait_polar);
		ret = oem_gpio_request(plat->gpio_data_ack, DRIVER_NAME "(data_ack)");
		if(ret < 0){
			LOGPRT(LOG_ERR,  "%s: %d fail to requset data_ack gpio %d ret =%d!!\n", 
				__func__, __LINE__, plat->gpio_data_ack, ret);
			goto err_req_data_ack;
		}
		oem_gpio_irq_mask(plat->gpio_data_ack);
		oem_gpio_direction_input_for_irq(plat->gpio_data_ack);
		oem_gpio_set_irq_type(plat->gpio_data_ack, IRQF_TRIGGER_FALLING);
		ret = oem_gpio_request_irq(plat->gpio_data_ack, gpio_irq_data_ack, 
				IRQF_SHARED | IRQF_TRIGGER_FALLING, DRIVER_NAME "(data_ack)", cbp_data_ack);
		oem_gpio_irq_unmask(plat->gpio_data_ack);
		if (ret < 0) {
			LOGPRT(LOG_ERR,  "%s: %d fail to request irq for data_ack!!\n", __func__, __LINE__);
			goto err_req_irq_data_ack;
		}
		plat->cbp_data_ack = cbp_data_ack;
		plat->data_ack_wait_event = data_ack_wait_event;
		plat->data_ack_enable =true;
	}

	if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){
		cbp_flow_ctrl = kzalloc(sizeof(struct cbp_wait_event), GFP_KERNEL);
		if (!cbp_flow_ctrl){
			ret = -ENOMEM;
			LOGPRT(LOG_ERR,  "%s %d kzalloc cbp_flow_ctrl failed \n",__func__, __LINE__);
			goto err_kzalloc_cbp_flow_ctrl;    
		}

		init_waitqueue_head(&cbp_flow_ctrl->wait_q);
		atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_DISABLE);
		cbp_flow_ctrl->wait_gpio = plat->gpio_flow_ctrl;
		cbp_flow_ctrl->wait_polar = plat->gpio_flow_ctrl_polar;
		LOGPRT(LOG_ERR,  "cbp_flow_ctrl->wait_gpio=%d\n",cbp_flow_ctrl->wait_gpio);
		LOGPRT(LOG_ERR,  "cbp_flow_ctrl->wait_polar=%d\n",cbp_flow_ctrl->wait_polar);
		ret = oem_gpio_request(plat->gpio_flow_ctrl, DRIVER_NAME "(flow_ctrl)");
		if(ret < 0){
			LOGPRT(LOG_ERR,  "%s: %d fail to requset flow_ctrl gpio %d ret =%d!!\n", 
				__func__, __LINE__, plat->gpio_flow_ctrl, ret);
			goto err_req_flow_ctrl;
		}
		oem_gpio_irq_mask(plat->gpio_flow_ctrl);
		oem_gpio_direction_input_for_irq(plat->gpio_flow_ctrl);
		//oem_gpio_set_irq_type(plat->gpio_flow_ctrl, IRQ_TYPE_LEVEL_LOW |IRQ_TYPE_LEVEL_HIGH);
		oem_gpio_set_irq_type(plat->gpio_flow_ctrl, IRQF_TRIGGER_FALLING);
		ret = oem_gpio_request_irq(plat->gpio_flow_ctrl, gpio_irq_flow_ctrl, 
				IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 
				DRIVER_NAME "(flow_ctrl)", cbp_flow_ctrl);
		oem_gpio_irq_unmask(plat->gpio_flow_ctrl);
		if (ret < 0) {
			LOGPRT(LOG_ERR,  "%s: %d fail to request irq for flow_ctrl!!\n", __func__, __LINE__);
			goto err_req_irq_flow_ctrl;
		}
		
		plat->cbp_flow_ctrl= cbp_flow_ctrl;
		plat->flow_ctrl_wait_event = flow_ctrl_wait_event;
		plat->flow_ctrl_enable = true;
	}
	
	
	if(GPIO_OEM_VALID(plat->gpio_rst_ind)){
		cbp_rst_ind = kzalloc(sizeof(struct cbp_reset), GFP_KERNEL);
		if (!cbp_rst_ind){
			ret = -ENOMEM;
			LOGPRT(LOG_ERR,  "%s %d kzalloc cbp_rst_ind failed \n",__func__, __LINE__);
			goto err_kzalloc_cbp_rst_ind;    
		}

		cbp_rst_ind->name = "cbp_rst_ind_wq";
		cbp_rst_ind->reset_wq = create_singlethread_workqueue(cbp_rst_ind->name);
		if (cbp_rst_ind->reset_wq == NULL) {
			ret = -ENOMEM;
			LOGPRT(LOG_ERR,  "%s %d error creat rst_ind_workqueue \n",__func__, __LINE__);
			goto err_create_work_queue;
		}
		INIT_WORK(&cbp_rst_ind->reset_work, modem_detect);
		cbp_rst_ind->rst_ind_gpio = plat->gpio_rst_ind;
		cbp_rst_ind->rst_ind_polar = plat->gpio_rst_ind_polar;
		cbp_rst_ind->host = NULL;
#if 0		
		ret = oem_gpio_request(plat->gpio_rst_ind, DRIVER_NAME "(rst_ind)");
		if(ret < 0){
			LOGPRT(LOG_ERR,  "%s: %d fail to requset rst_ind gpio %d ret =%d!!\n", 
				__func__, __LINE__, plat->gpio_rst_ind, ret);
			goto err_req_rst_ind;
		}

		oem_gpio_irq_mask(plat->gpio_rst_ind);
		oem_gpio_direction_input_for_irq(plat->gpio_rst_ind);
		oem_gpio_set_irq_type(plat->gpio_rst_ind, IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING);
		ret = oem_gpio_request_irq(plat->gpio_rst_ind, gpio_irq_cbp_rst_ind, 
			IRQF_SHARED |IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING, 
			DRIVER_NAME "(rst_ind)", cbp_rst_ind);
		oem_gpio_irq_unmask(plat->gpio_rst_ind);
		if (ret < 0) {
			LOGPRT(LOG_ERR,  "%s: %d fail to request irq for rst_ind!!\n", __func__, __LINE__);
			goto err_req_irq_rst_ind;
		}
#endif
		plat->rst_ind_enable = true;
	}

	if((GPIO_OEM_VALID(plat->gpio_ap_wkup_cp)) && (GPIO_OEM_VALID(plat->gpio_cp_ready)) &&
		(GPIO_OEM_VALID(plat->gpio_cp_wkup_ap))  && (GPIO_OEM_VALID(plat->gpio_ap_ready))){
		sdio_tx_handle.gpio_wake = plat->gpio_ap_wkup_cp;
		sdio_tx_handle.gpio_ready = plat->gpio_cp_ready;
		sdio_tx_handle.polar = plat->gpio_sync_polar;
		ret = asc_tx_register_handle(&sdio_tx_handle);
		if(ret){
			LOGPRT(LOG_ERR,  "%s %d asc_tx_register_handle failed.\n",__FUNCTION__,__LINE__);
			goto err_ipc;
		}
		ret = asc_tx_add_user(sdio_tx_handle.name, &sdio_tx_user);
		if(ret){
			LOGPRT(LOG_ERR,  "%s %d asc_tx_add_user failed.\n",__FUNCTION__,__LINE__);
			goto err_ipc;
		}

		sdio_rx_handle.gpio_wake = plat->gpio_cp_wkup_ap;
		sdio_rx_handle.gpio_ready = plat->gpio_ap_ready;
		sdio_rx_handle.polar = plat->gpio_sync_polar;
		ret = asc_rx_register_handle(&sdio_rx_handle);
		if(ret){
			LOGPRT(LOG_ERR,  "%s %d asc_rx_register_handle failed.\n",__FUNCTION__,__LINE__);
			goto err_ipc;
		}
		ret = asc_rx_add_user(sdio_rx_handle.name, &sdio_rx_user);
		if(ret){
			LOGPRT(LOG_ERR,  "%s %d asc_rx_add_user failed.\n",__FUNCTION__,__LINE__);
			goto err_ipc;
		}
		plat->ipc_enable = true;
		plat->tx_handle = &sdio_tx_handle;
	}
	
	ret = plat->cbp_setup(plat);
	if(ret){
		LOGPRT(LOG_ERR,  "%s: host %s setup failed!\n", __func__, plat->host_id);
		goto err_ipc;
	}
	cbp_power_kobj = viatel_kobject_add("power");
	if (!cbp_power_kobj){
		LOGPRT(LOG_ERR,  "error viatel_kobject_add!\n");
		ret = -ENOMEM;
		goto err_create_kobj;
	}
	LOGPRT(LOG_INFO,  " cbp initialized on host %s successfully, bus is %s !\n", plat->host_id, plat->bus);
	return sysfs_create_group(cbp_power_kobj, &g_power_attr_group);
	
err_create_kobj:
	plat->cbp_destroy();
err_ipc:
#if 0
	if(GPIO_OEM_VALID(plat->gpio_rst_ind)){
		free_irq(oem_gpio_to_irq(plat->gpio_rst_ind), cbp_rst_ind);
	}
err_req_irq_rst_ind:
	if(GPIO_OEM_VALID(plat->gpio_rst_ind)){
		oem_gpio_free(plat->gpio_rst_ind);
	}
#endif
err_req_rst_ind:
	if(GPIO_OEM_VALID(plat->gpio_rst_ind)){
		destroy_workqueue(cbp_rst_ind->reset_wq);
	}
err_create_work_queue:
	if(GPIO_OEM_VALID(plat->gpio_rst_ind)){
		kfree(cbp_rst_ind);
	}
err_kzalloc_cbp_rst_ind:
	if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){
		free_irq(oem_gpio_to_irq(plat->gpio_flow_ctrl), cbp_flow_ctrl);
	}
err_req_irq_flow_ctrl:
	if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){
		oem_gpio_free(plat->gpio_flow_ctrl);
	}
err_req_flow_ctrl:
	if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){
		kfree(cbp_flow_ctrl);
	}
err_kzalloc_cbp_flow_ctrl:
	if(GPIO_OEM_VALID(plat->gpio_data_ack)){
		free_irq(oem_gpio_to_irq(plat->gpio_data_ack), cbp_data_ack);
	}
err_req_irq_data_ack:
	if(GPIO_OEM_VALID(plat->gpio_data_ack)){
		oem_gpio_free(plat->gpio_data_ack);
	}
err_req_data_ack:
	if(GPIO_OEM_VALID(plat->gpio_data_ack)){
		kfree(cbp_data_ack);
	}
err_kzalloc_cbp_data_ack:
	if((GPIO_OEM_VALID(plat->gpio_sd_select)) && (GPIO_OEM_VALID(plat->gpio_mc3_enable))){
		oem_gpio_free(plat->gpio_sd_select);
	}
err_req_sd_sel:
	if((GPIO_OEM_VALID(plat->gpio_sd_select)) && (GPIO_OEM_VALID(plat->gpio_mc3_enable))){
		oem_gpio_free(plat->gpio_mc3_enable);
	}
out:
	return ret;
}
Ejemplo n.º 10
0
static int cbp_probe(struct platform_device *pdev)
{
	struct cbp_platform_data *plat = NULL;
	int ret = -1;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;

	ret = platform_device_add_data(pdev, &cbp_data, sizeof(struct cbp_platform_data));
	if (ret < 0) {
		hwlog_err("%s: add platform_data failed!\n", __func__);
		goto err_add_data_to_platform_device;
	}

	plat = pdev->dev.platform_data;
	/* must have platform data */
	if (!plat) {
		hwlog_err("%s: no platform data!\n", __func__);
		ret = -EINVAL;
		goto err_add_data_to_platform_device;
	}

	plat->gpio_data_ack = of_get_named_gpio(np, "via_data_ack", 0);
	hwlog_info(">>>> %s get via_data_ack gpio %d\n", __func__, plat->gpio_data_ack);
	if(GPIO_OEM_VALID(plat->gpio_data_ack)){
		cbp_data_ack = kzalloc(sizeof(struct cbp_wait_event), GFP_KERNEL);
		if (!cbp_data_ack){
			ret = -ENOMEM;
			hwlog_err("%s %d kzalloc cbp_data_ack failed \n",__func__, __LINE__);
			goto err_kzalloc_cbp_data_ack;
		}

		init_waitqueue_head(&cbp_data_ack->wait_q);
		atomic_set(&cbp_data_ack->state, MODEM_ST_UNKNOW);
		cbp_data_ack->wait_gpio = plat->gpio_data_ack;
		cbp_data_ack->wait_polar = plat->gpio_data_ack_polar;
		hwlog_info("cbp_data_ack->wait_gpio=%d\n",cbp_data_ack->wait_gpio);
		hwlog_info("cbp_data_ack->wait_polar=%d\n",cbp_data_ack->wait_polar);
		ret = oem_gpio_request(plat->gpio_data_ack, DRIVER_NAME "(data_ack)");
		if(ret < 0){
			hwlog_err("%s: %d fail to requset data_ack gpio %d ret =%d!!\n",
				__func__, __LINE__, plat->gpio_data_ack, ret);
			goto err_req_data_ack;
		}
		oem_gpio_irq_mask(plat->gpio_data_ack);
		oem_gpio_direction_input_for_irq(plat->gpio_data_ack);
		//on powerup, there is ack low level to high level jump.
		oem_gpio_set_irq_type(plat->gpio_data_ack, IRQF_TRIGGER_FALLING);
		ret = oem_gpio_request_irq(plat->gpio_data_ack, gpio_irq_via_spi_tx_rx_fifo_empty_ack,
				IRQF_SHARED | IRQF_TRIGGER_FALLING, DRIVER_NAME "(data_ack)", cbp_data_ack);
		oem_gpio_irq_unmask(plat->gpio_data_ack);
		if (ret < 0) {
			hwlog_err("%s: %d fail to request irq for data_ack!!\n", __func__, __LINE__);
			goto err_req_irq_data_ack;
		}
		plat->cbp_data_ack = cbp_data_ack;
		plat->data_ack_wait_event = data_ack_wait_event;
		plat->data_ack_enable =true;
	}

	plat->gpio_flow_ctrl = of_get_named_gpio(np, "via_flow_ctrl", 0);
	hwlog_info(">>>> %s get via_flow_ctrl gpio %d\n", __func__, plat->gpio_flow_ctrl);
	if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){
		cbp_flow_ctrl = kzalloc(sizeof(struct cbp_wait_event), GFP_KERNEL);
		if (!cbp_flow_ctrl){
			ret = -ENOMEM;
			hwlog_err("%s %d kzalloc cbp_flow_ctrl failed \n",__func__, __LINE__);
			goto err_kzalloc_cbp_flow_ctrl;
		}

		init_waitqueue_head(&cbp_flow_ctrl->wait_q);
		atomic_set(&cbp_flow_ctrl->state, FLOW_CTRL_DISABLE);
		cbp_flow_ctrl->wait_gpio = plat->gpio_flow_ctrl;
		cbp_flow_ctrl->wait_polar = plat->gpio_flow_ctrl_polar;
		hwlog_info("cbp_flow_ctrl->wait_gpio=%d\n",cbp_flow_ctrl->wait_gpio);
		hwlog_info("cbp_flow_ctrl->wait_polar=%d\n",cbp_flow_ctrl->wait_polar);
		ret = oem_gpio_request(plat->gpio_flow_ctrl, DRIVER_NAME "(flow_ctrl)");
		if(ret < 0){
			hwlog_err("%s: %d fail to requset flow_ctrl gpio %d ret =%d!!\n",
				__func__, __LINE__, plat->gpio_flow_ctrl, ret);
			goto err_req_flow_ctrl;
		}
		oem_gpio_irq_mask(plat->gpio_flow_ctrl);
		oem_gpio_direction_input_for_irq(plat->gpio_flow_ctrl);
		oem_gpio_set_irq_type(plat->gpio_flow_ctrl, IRQF_TRIGGER_FALLING);
		ret = oem_gpio_request_irq(plat->gpio_flow_ctrl, gpio_irq_flow_ctrl,
				IRQF_SHARED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				DRIVER_NAME "(flow_ctrl)", cbp_flow_ctrl);
		oem_gpio_irq_unmask(plat->gpio_flow_ctrl);
		if (ret < 0) {
			hwlog_err("%s: %d fail to request irq for flow_ctrl!!\n", __func__, __LINE__);
			goto err_req_irq_flow_ctrl;
		}

		plat->cbp_flow_ctrl= cbp_flow_ctrl;
		plat->flow_ctrl_wait_event = flow_ctrl_wait_event;
		plat->flow_ctrl_enable = true;
	}

	plat->gpio_via_requst_to_send = of_get_named_gpio(np, "via_requst_to_send", 0);
	hwlog_info(">>>> %s get via_requst_to_send gpio %d\n", __func__, plat->gpio_via_requst_to_send);
	if(GPIO_OEM_VALID(plat->gpio_via_requst_to_send)){
		ret = oem_gpio_request(plat->gpio_via_requst_to_send, DRIVER_NAME "(via_requst_to_send)");
		if(ret < 0){
			hwlog_err("%s: %d fail to requset flow_ctrl gpio %d ret =%d!!\n",
				__func__, __LINE__, plat->gpio_via_requst_to_send, ret);
			goto err_req_via_requst_to_send;
		}
		oem_gpio_irq_mask(plat->gpio_via_requst_to_send);
		oem_gpio_direction_input_for_irq(plat->gpio_via_requst_to_send);
		oem_gpio_set_irq_type(plat->gpio_via_requst_to_send, IRQF_TRIGGER_FALLING);
		ret = oem_gpio_request_irq(plat->gpio_via_requst_to_send, gpio_irq_via_rts,
				IRQF_SHARED | IRQF_TRIGGER_RISING,
				DRIVER_NAME "(via_requst_to_send)", &cbp_data); //api request the fifth argu NOT NULL.
		oem_gpio_irq_unmask(plat->gpio_via_requst_to_send);
		if (ret < 0) {
			hwlog_err("%s: %d fail to request irq for via_requst_to_send!!\n", __func__, __LINE__);
			goto err_req_irq_via_requst_to_send;
		}
	}

	plat->gpio_rst_ind = of_get_named_gpio(np, "via_reset_ind", 0);
	hwlog_info(">>>> %s get rst_ind gpio %d\n", __func__, plat->gpio_rst_ind);
	if(GPIO_OEM_VALID(plat->gpio_rst_ind)){
		cbp_data.gpio_rst_ind= plat->gpio_rst_ind;
		cbp_data.gpio_rst_ind_polar = plat->gpio_rst_ind_polar;

		atomic_set(&cbp_rst_ind_finished, 0);
		plat->rst_ind_enable = true;
	}
	plat->gpio_ap_wkup_cp= of_get_named_gpio(np, "via_ap_wkup_cp", 0);
	hwlog_info(">>>> %s get ap_wkup_cp gpio %d\n", __func__, plat->gpio_ap_wkup_cp);

	plat->gpio_cp_ready= of_get_named_gpio(np, "via_cp_ready", 0);
	hwlog_info(">>>> %s get cp_ready gpio %d\n", __func__, plat->gpio_cp_ready);

	plat->gpio_cp_wkup_ap= of_get_named_gpio(np, "via_cp_wkup_ap", 0);
	hwlog_info(">>>> %s get cp_wkup_ap gpio %d\n", __func__, plat->gpio_cp_wkup_ap);

	plat->gpio_ap_ready= of_get_named_gpio(np, "via_ap_ready", 0);
	hwlog_info(">>>> %s get ap_ready gpio %d\n", __func__, plat->gpio_ap_ready);
	if((GPIO_OEM_VALID(plat->gpio_ap_wkup_cp)) && (GPIO_OEM_VALID(plat->gpio_cp_ready)) &&
		(GPIO_OEM_VALID(plat->gpio_cp_wkup_ap))  && (GPIO_OEM_VALID(plat->gpio_ap_ready))){
		spi_tx_handle.gpio_wake = plat->gpio_ap_wkup_cp;
		spi_tx_handle.gpio_ready = plat->gpio_cp_ready;
		spi_tx_handle.polar = plat->gpio_sync_polar;
		ret = asc_tx_register_handle(&spi_tx_handle);
		if(ret){
			hwlog_err("%s %d asc_tx_register_handle failed.\n",__FUNCTION__,__LINE__);
			goto err_ipc;
		}
		ret = asc_tx_add_user(spi_tx_handle.name, &spi_tx_user);
		if(ret){
			hwlog_err("%s %d asc_tx_add_user failed.\n",__FUNCTION__,__LINE__);
			goto err_ipc;
		}

		spi_rx_handle.gpio_wake = plat->gpio_cp_wkup_ap;
		spi_rx_handle.gpio_ready = plat->gpio_ap_ready;
		spi_rx_handle.polar = plat->gpio_sync_polar;
		ret = asc_rx_register_handle(&spi_rx_handle);
		if(ret){
			hwlog_err("%s %d asc_rx_register_handle failed.\n",__FUNCTION__,__LINE__);
			goto err_ipc;
		}
		ret = asc_rx_add_user(spi_rx_handle.name, &spi_rx_user);
		if(ret){
			hwlog_err("%s %d asc_rx_add_user failed.\n",__FUNCTION__,__LINE__);
			goto err_ipc;
		}
		plat->ipc_enable = true;
		plat->tx_handle = &spi_tx_handle;
	}

	ret = plat->cbp_setup(plat);
	if(ret){
		hwlog_err("%s: host %s setup failed!\n", __func__, plat->host_id);
		goto err_ipc;
	}

	cbp_power_kobj = viatel_kobject_add("power");
	if (!cbp_power_kobj){
		hwlog_err("error viatel_kobject_add!\n");
		ret = -ENOMEM;
		goto err_create_kobj;
	}

	hwlog_debug(" cbp initialized on host %s successfully, bus is %s !\n", plat->host_id, plat->bus);
	return sysfs_create_group(cbp_power_kobj, &g_power_attr_group);

err_create_kobj:
	plat->cbp_destroy();
err_ipc:
	if(GPIO_OEM_VALID(plat->gpio_via_requst_to_send)){
		free_irq(oem_gpio_to_irq(plat->gpio_via_requst_to_send), NULL);
	}
err_req_irq_via_requst_to_send:
	if(GPIO_OEM_VALID(plat->gpio_via_requst_to_send)){
		oem_gpio_free(plat->gpio_via_requst_to_send);
	}
err_req_via_requst_to_send:
	if(GPIO_OEM_VALID(plat->gpio_data_ack)){
		free_irq(oem_gpio_to_irq(plat->gpio_flow_ctrl), cbp_flow_ctrl);
	}
err_req_irq_flow_ctrl:
	if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){
		oem_gpio_free(plat->gpio_flow_ctrl);
	}
err_req_flow_ctrl:
	if(GPIO_OEM_VALID(plat->gpio_flow_ctrl)){
		kfree(cbp_flow_ctrl);
	}
err_kzalloc_cbp_flow_ctrl:
	if(GPIO_OEM_VALID(plat->gpio_data_ack)){
		free_irq(oem_gpio_to_irq(plat->gpio_data_ack), cbp_data_ack);
	}
err_req_irq_data_ack:
	if(GPIO_OEM_VALID(plat->gpio_data_ack)){
		oem_gpio_free(plat->gpio_data_ack);
	}
err_req_data_ack:
	if(GPIO_OEM_VALID(plat->gpio_data_ack)){
		kfree(cbp_data_ack);
	}
err_kzalloc_cbp_data_ack:
err_add_data_to_platform_device:
	return ret;
}
static int modem_boot_probe(struct platform_device *pdev)
{
    int ret = 0;
    struct device *dev = &pdev->dev;
    struct device_node *np = dev->of_node;

    vmdata = kzalloc(sizeof(struct viatel_modem_data), GFP_KERNEL);
    if(!vmdata)
    {
        ret = -ENOMEM;
        hwlog_err("No memory to alloc vmdata");
        goto err_create_vmdata;
    }

    vmdata->via_pdev = pdev;
    vmdata->tail = 0;
    vmdata->head = 0;

    ret = modem_data_init(vmdata);
    if(ret < 0)
    {
        hwlog_err("Fail to init modem data\n");
        goto err_init_modem_data;
    }

    ret = platform_device_register(&viacbp82d_3rd_modem_info);
    if (ret) {
        hwlog_err( "%s: platform_device_register failed, ret:%d.\n",
                __func__, ret);
        goto err_register_platform_device;
    }

    ret = sysfs_create_group(&viacbp82d_3rd_modem_info.dev.kobj, &viacbp82d_3rd_modem_node);
    if (ret) {
        hwlog_err( "sensor_input_info_init sysfs_create_group error ret =%d", ret);
        platform_device_unregister(&viacbp82d_3rd_modem_info);
        goto err_create_sysfs_group;
    }

    ret = of_property_read_u32(np, "via_reset_ind_connect_to_codec", &cbp_reset_ind_connect_to_codec);
    if(ret) {
        hwlog_err("can't get cbp_reset_ind_connect_to_codec property in viacbp82d_power device node\n");
        goto err_get_gpio;
    }

    hwlog_info("get cbp_reset_ind_connect_to_codec:%u\n", cbp_reset_ind_connect_to_codec);

    /* rst_ind is connect to hi6402 codec in fifa */
    cbp_rst_ind_gpio = of_get_named_gpio(np, "via_reset_ind", 0);//gpio is 254
    hwlog_info("%s get CBP_VIATEL_RST_IND_STR gpio %d\n", __func__, cbp_rst_ind_gpio);
    if(GPIO_OEM_VALID(cbp_rst_ind_gpio)){
        int irq = 0;
        ret = oem_gpio_request(cbp_rst_ind_gpio, "GPIO_VIATEL_MDM_RST_IND");
        if(ret < 0 )
        {
            hwlog_err("%s:%d gpio_request %d fail, return:%d\n", __func__, __LINE__, cbp_rst_ind_gpio, ret);
        }
        oem_gpio_irq_mask(cbp_rst_ind_gpio);
        ret = oem_gpio_direction_input_for_irq(cbp_rst_ind_gpio);
        if(ret < 0 )
        {
            hwlog_err("%s:%d gpio_direction_inout_for_irq %d fail, return:%d\n", __func__, __LINE__, cbp_rst_ind_gpio, ret);
        }

        irq = oem_gpio_to_irq(cbp_rst_ind_gpio);
        hwlog_info("%s:%d cbp_rst_ind_gpio:%d irq is:%d\n", __func__, __LINE__,  cbp_rst_ind_gpio, irq);

        oem_gpio_set_irq_type(cbp_rst_ind_gpio, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);

        if( cbp_reset_ind_connect_to_codec ) {
            //connected to hi6402, then use task context api to register irq handler.
            ret = oem_gpio_request_threaded_irq(cbp_rst_ind_gpio, modem_reset_indication_irq, \
                            IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_TRIGGER_FALLING, \
                            "mdm_reset_ind", vmdata);
        } else {
            ret = oem_gpio_request_irq(cbp_rst_ind_gpio, modem_reset_indication_irq, \
                            IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_TRIGGER_FALLING, \
                            "mdm_reset_ind", vmdata);
        }

        oem_gpio_irq_unmask(cbp_rst_ind_gpio);

        if (ret < 0) {
            hwlog_err("%s:%d fail to request mdm_rst_ind %d irq, return:%d\n", __func__, __LINE__, cbp_rst_ind_gpio, ret);
        }
        hwlog_info("%s:%d gpio via_reset_ind %d init successfully\n", __func__, __LINE__, cbp_rst_ind_gpio);

        modem_register_notifier(&vmdata->rst_ntf);
    } else {
        hwlog_err("%s:%d via_reset_ind is invalid gpio\n", __func__, __LINE__);
        goto err_get_gpio;
    }

    cbp_pwr_en_gpio = of_get_named_gpio(np, "via_pwr_en", 0);
    hwlog_info("%s get CBP_VIATEL_PWR_EN_STR gpio %d\n", __func__, cbp_pwr_en_gpio);
    if(GPIO_OEM_VALID(cbp_pwr_en_gpio)){
        ret = oem_gpio_request(cbp_pwr_en_gpio, "GPIO_VIATEL_MDM_PWR_EN");
        if (0 > ret) {
            hwlog_err("%s: gpio request GPIO_VIATEL_MDM_PWR_EN failed", __FUNCTION__);
        }
        oem_gpio_direction_output(cbp_pwr_en_gpio, 0);
    } else {
        goto err_get_gpio;
    }

    cbp_rst_gpio = of_get_named_gpio(np, "via_rst_mdm", 0);
    hwlog_info("%s get CBP_VIATEL_CBP_RST_STR gpio %d\n", __func__, cbp_rst_gpio);
    if(GPIO_OEM_VALID(cbp_rst_gpio)){
        ret = oem_gpio_request(cbp_rst_gpio, "GPIO_VIATEL_MDM_RST");
        if (0 > ret) {
            hwlog_err("%s: gpio request GPIO_VIATEL_MDM_RST failed", __FUNCTION__);
        }
        oem_gpio_direction_output(cbp_rst_gpio, 0);
    } else {
        goto err_get_gpio;
    }

#if 0 //don't delete. there is no gpio for sim switch
    cbp_sim_switch_gpio = of_get_named_gpio(np, "via_sim_switch", 0);
    hwlog_info("%s get CBP_VIATEL_CBP_SIM_SWITCH gpio %d\n", __func__, cbp_sim_switch_gpio);
    if(GPIO_OEM_VALID(cbp_sim_switch_gpio)){
        ret = oem_gpio_request(cbp_sim_switch_gpio, "GPIO_VIATEL_MDM_SIM_SWITCH");
        if(0 > ret){
            hwlog_err("%s: gpio request GPIO_VIATEL_MDM_SIM_SWITCH failed", __FUNCTION__);
        }
        oem_gpio_direction_output(cbp_sim_switch_gpio, 0);
    } else {
        goto err_get_gpio;
    }
#endif

    /*add gpio function to make cp ramdump*/
    cbp_backup_gpio = of_get_named_gpio(np, "via_backup", 0);
    hwlog_info("%s get CBP_VIATEL_CBP_BACKUP gpio %d\n", __func__, cbp_backup_gpio);
    if(GPIO_OEM_VALID(cbp_backup_gpio)){
        ret = oem_gpio_request(cbp_backup_gpio, "gpio_cbp_crash");
        if(0 > ret){
            hwlog_err("%s: gpio request gpio_cbp_crash failed", __FUNCTION__);
        }
        oem_gpio_direction_output(cbp_backup_gpio, 0);
        setup_timer(&cbp_backup_timer, cbp_backup_check_ramdump_timer, (unsigned long)NULL);
    } else {
        goto err_get_gpio;
    }

    return 0;

err_get_gpio:
    sysfs_remove_group(&viacbp82d_3rd_modem_info.dev.kobj, &viacbp82d_3rd_modem_node);
err_create_sysfs_group:
    platform_device_unregister(&viacbp82d_3rd_modem_info);
err_register_platform_device:
err_init_modem_data:
    kfree(vmdata);
    vmdata = NULL;
err_create_vmdata:

    return ret;
}