static void balong_sim2_set_status(struct work_struct *work)
{
    
    /*anti-jitter, msleep(10)*/
    msleep(SIM_DEBOUNCE_TIME);
    sim2_plat_data->sim_status = get_sim_status(sim2_plat_data->sim_detection_gpio, g_sim2_present_electrical_lvl);
    pr_info("balong_sim2_set_status  sim_status [%d]\n", sim2_plat_data->sim_status);
}
Ejemplo n.º 2
0
void balong_sim1_set_status(struct work_struct *work)
{




    /*anti-jitter, msleep(10)*/
    msleep(SIM_DEBOUNCE_TIME);
    sim1_plat_data->sim_status = get_sim_status(sim1_plat_data->sim_detection_gpio, g_sim1_present_electrical_lvl);
    pr_info("balong_sim1_set_status  sim_status [%d]\n", sim1_plat_data->sim_status);
#ifndef SIM_HPD
    set_sim_en_int(sim1_plat_data->name, sim1_plat_data->sim_status);
#endif
}
static int balong_sim_probe(struct platform_device *pdev)
{
    struct balong_sim_plat_data *plat = NULL;
    const struct of_device_id *match;
    enum of_gpio_flags gpio_flags;
    int err;

    dev_dbg(&pdev->dev, "balong_sim_probe\n");

    if ((match = of_match_node(balong_sim_match, pdev->dev.of_node)) == NULL) {
        dev_err(&pdev->dev, "dev node is not match. exiting.\n");
        return -ENODEV;   
    }
    
    plat = (struct balong_sim_plat_data *)match->data;
    if (plat == NULL) {
        dev_err(&pdev->dev, "no platform data\n");
        return -EINVAL;
    }

    pr_err("balong_sim_probe, enter %s\n",plat->name);

    if (!strcmp(SIM1 , plat->name))
    {
        sim1_plat_data = plat;               
        sim1_plat_data->sim_detection_gpio = of_get_gpio_by_prop(pdev->dev.of_node,"gpio-sim1_detect,gpio-irq",0,0, &gpio_flags);

        err = of_property_read_u32(pdev->dev.of_node, "gpio_sim1_in_val", &g_sim1_present_electrical_lvl);
        if (err < 0) 
        {
            dev_err(&pdev->dev, "sim1 obtain the ele lvl failed err = %d\n",err);  
            return -EINVAL;
        }
	                 
    }
    
    if (!strcmp(SIM2 , plat->name))
    {
        sim2_plat_data = plat;
        sim2_plat_data->sim_detection_gpio = of_get_gpio_by_prop(pdev->dev.of_node,"gpio-sim2_detect,gpio-irq",0,0, &gpio_flags);

        err = of_property_read_u32(pdev->dev.of_node, "gpio_sim2_in_val", &g_sim2_present_electrical_lvl);
        if (err < 0) 
        {
            dev_err(&pdev->dev, "sim2 obtain the ele lvl failed err = %d\n",err);  
            return -EINVAL;
        }
	          
    }


    err = gpio_request_one(plat->sim_detection_gpio, GPIOF_IN, plat->name);
    if (err) {
        dev_warn(&pdev->dev, "no sim-detect pin available!\n");
        return err;
    }

    /*Initialize sim status when booting*/
    if (!strcmp(SIM1 , plat->name))
    {
        plat->sim_status = get_sim_status(plat->sim_detection_gpio, g_sim1_present_electrical_lvl);
    }

    if (!strcmp(SIM2 , plat->name))
    {
        plat->sim_status = get_sim_status(plat->sim_detection_gpio, g_sim2_present_electrical_lvl);
    }
    /*以下代码只执行一次,SIM1和SIM2共用一个任务队列*/
    if (!workqueue) {
        /* Initialize works */
        workqueue = create_singlethread_workqueue("balong_sim_workqueue");
        if (!workqueue) {
            dev_err(&pdev->dev, "Create workqueue failed\n");
            err = -1;
            goto err_init_workqueue;
        }
        else
        {
            pr_info("balong_sim_probe, Initialization of workqueue succeed\n");
        }
    }

    /*request SIM irq*/
    if (!strcmp(SIM1 , plat->name))
    {
        /*request irq for sim1*/
        INIT_WORK(&sim1_irq_work, balong_sim1_set_status);
        
        err = request_irq(gpio_to_irq(sim1_plat_data->sim_detection_gpio), sim1_detection_irq_handler,
    	    IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
    	    pdev->name, pdev);
        if (err) {
            dev_warn(&pdev->dev, "sim1:request gpio irq error\n");
            goto no_sim_detect_irq;
        }
           
        /* sysfs entries for IO control */
        err = device_create_file(&(pdev->dev), &dev_attr_sim1_status);
        if (err) {
            dev_err(&pdev->dev, "sim1:Failed to create sysfs entry\n");
            goto err_create_device_file;
        }
    }

    if (!strcmp(SIM2 , plat->name))
    {
        INIT_WORK(&sim2_irq_work, balong_sim2_set_status);

        err = request_irq(gpio_to_irq(sim2_plat_data->sim_detection_gpio), sim2_detection_irq_handler,
    	    IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
    	    pdev->name, pdev);
        if (err) {
            dev_warn(&pdev->dev, "sim2:request gpio irq error\n");
            goto no_sim_detect_irq;
        }
        
        /* sysfs entries for IO control */
        err = device_create_file(&(pdev->dev), &dev_attr_sim2_status);
        if (err) {
            dev_err(&pdev->dev, "sim2:Failed to create sysfs entry\n");
            goto err_create_device_file;
        }
    }
    return 0;

err_create_device_file:
no_sim_detect_irq:
    destroy_workqueue(workqueue);
    workqueue = NULL;
err_init_workqueue:
    gpio_free(plat->sim_detection_gpio);
    return err;
}
Ejemplo n.º 4
0
static int balong_sim_probe(struct platform_device *pdev)
{
    struct balong_sim_plat_data *plat = NULL;
    int err;

    dev_dbg(&pdev->dev, "balong_sim_probe\n");

    plat = pdev->dev.platform_data;

    if (!strcmp(SIM1 , plat->name))
    {
        sim1_plat_data = pdev->dev.platform_data;
        if (!get_hw_config_int("sim/sim1_detection_gpio", &(sim1_plat_data->sim_detection_gpio), NULL))
        {
            pr_err("Get sim/sim1_detection_gpio failed\n");
            return -EINVAL;
        }

        /*if there are no sim gpio detection on hw platform, simX_detection_gpio should be 0xffffffff*/
        if(NO_SIM_GPIO == sim1_plat_data->sim_detection_gpio)
        {
            pr_info("balong_sim_probe, this hw platform doesn't support sim1 gpio detection! \n");
            set_sim_en_int(plat->name, 1);
            return 0;
        }

        if (!get_hw_config_int("sim/sim1_present_electrical_lvl", &(g_sim1_present_electrical_lvl), NULL))
        {
            pr_err("Get sim/sim1_detection_gpio failed\n");
            return -EINVAL;
        }
        pr_info("balong_sim_probe SIM1 dev name [%s], sim1_detection_gpio [%d], sim1_present_electrical_lvl [%d]\n",
                plat->name, sim1_plat_data->sim_detection_gpio, g_sim1_present_electrical_lvl);
    }

    if (!strcmp(SIM2 , plat->name))
    {
        sim2_plat_data = pdev->dev.platform_data;
        if (!get_hw_config_int("sim/sim2_detection_gpio", &(sim2_plat_data->sim_detection_gpio), NULL))
        {
            pr_err("Get sim/sim2_detection_gpio failed\n");
            return -EINVAL;
        }

        /*if there are no sim gpio detection on hw platform, simX_detection_gpio should be 0xffffffff*/
        if(NO_SIM_GPIO == sim2_plat_data->sim_detection_gpio)
        {
            pr_info("balong_sim_probe, this hw platform doesn't support sim2 gpio detection! \n");
            set_sim_en_int(plat->name, 1);
            return 0;
        }

        if (!get_hw_config_int("sim/sim2_present_electrical_lvl", &(g_sim2_present_electrical_lvl), NULL))
        {
            pr_err("Get sim/sim2_detection_gpio failed\n");
            return -EINVAL;
        }
        pr_info("balong_sim_probe SIM2 dev name [%s], sim2_detection_gpio [%d], sim2_present_electrical_lvl [%d]\n",
                plat->name, sim2_plat_data->sim_detection_gpio, g_sim2_present_electrical_lvl);
    }

    err = gpio_request_one(plat->sim_detection_gpio, GPIOF_IN, plat->name);
    if (err) {
        dev_warn(&pdev->dev, "no sim-detect pin available!\n");
        return err;
    }

    /*Initialize sim status when booting*/
    if (!strcmp(SIM1 , plat->name))
    {
        plat->sim_status = get_sim_status(plat->sim_detection_gpio, g_sim1_present_electrical_lvl);
    }

    if (!strcmp(SIM2 , plat->name))
    {
        plat->sim_status = get_sim_status(plat->sim_detection_gpio, g_sim2_present_electrical_lvl);
    }

    pr_info("balong_sim_probe sim_status [%d]\n", plat->sim_status);

    /*Temp: set sim_en_int of register SIMCARD_EN*/
    /*TODO:需要找到软件哪里设置了sim_en_int位*/
    set_sim_en_int(plat->name, plat->sim_status);

    /*以下代码只执行一次,SIM1和SIM2共用一个任务队列*/
    if (!workqueue)
    {
        /* Initialize works */
        workqueue = create_singlethread_workqueue("balong_sim_workqueue");
        if (!workqueue) {
            dev_err(&pdev->dev, "Create workqueue failed\n");
            err = -1;
            goto err_init_workqueue;
        }
        else
        {
            pr_info("balong_sim_probe, Initialization of workqueue succeed\n");
        }
    }

    /*request SIM irq*/
    if (!strcmp(SIM1 , plat->name))
    {
        INIT_WORK(&sim1_irq_work, balong_sim1_set_status);

        err = request_irq(gpio_to_irq(plat->sim_detection_gpio), sim1_detection_irq_handler,
                          IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
                          pdev->name, pdev);
        if (err) {
            dev_warn(&pdev->dev, "request gpio irq error\n");
            goto no_sim_detect_irq;
        }

#ifdef SIM_HPD
        pr_info(" SIM1 sim_hpd_out_f [%d]\n", plat->sim_hpd_out_f);
        pr_info(" SIM1 sim_hpd_in_f [%d]\n", plat->sim_hpd_in_f);
        /*SIM HPD out irq request*/
        err = request_irq(plat->sim_hpd_out_f, sim1_hpd_out_irq_handler,
                          IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, pdev->name, pdev);
        if (err) {
            dev_warn(&pdev->dev, "request sim_hpd_out_f irq error\n");
            goto no_sim_hpd_out_irq;
        }

        /*SIM HPD in irq request*/
        err = request_irq(plat->sim_hpd_in_f, sim1_hpd_in_irq_handler,
                          IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, pdev->name, pdev);
        if (err) {
            dev_warn(&pdev->dev, "request sim_hpd_in_f irq error\n");
            goto no_sim_hpd_in_irq;
        }
#endif

        /* sysfs entries for IO control */
        err = device_create_file(&(pdev->dev), &dev_attr_sim1_status);
        if (err) {
            dev_err(&pdev->dev, "Failed to create sysfs entry\n");
            goto err_create_device_file;
        }
    }

    if (!strcmp(SIM2 , plat->name))
    {
        INIT_WORK(&sim2_irq_work, balong_sim2_set_status);

        err = request_irq(gpio_to_irq(plat->sim_detection_gpio), sim2_detection_irq_handler,
                          IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND,
                          pdev->name, pdev);
        if (err) {
            dev_warn(&pdev->dev, "request gpio irq error\n");
            goto no_sim_detect_irq;
        }

#ifdef SIM_HPD
        pr_info(" SIM2 sim_hpd_out_f [%d]\n", plat->sim_hpd_out_f);
        pr_info(" SIM2 sim_hpd_in_f [%d]\n", plat->sim_hpd_in_f);
        /*SIM HPD out irq request*/
        err = request_irq(plat->sim_hpd_out_f, sim2_hpd_out_irq_handler,
                          IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, pdev->name, pdev);
        if (err) {
            dev_warn(&pdev->dev, "request sim_hpd_out_f irq error\n");
            goto no_sim_hpd_out_irq;
        }

        /*SIM HPD in irq request*/
        err = request_irq(plat->sim_hpd_in_f, sim2_hpd_in_irq_handler,
                          IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, pdev->name, pdev);
        if (err) {
            dev_warn(&pdev->dev, "request sim_hpd_in_f irq error\n");
            goto no_sim_hpd_in_irq;
        }
#endif

        /* sysfs entries for IO control */
        err = device_create_file(&(pdev->dev), &dev_attr_sim2_status);
        if (err) {
            dev_err(&pdev->dev, "Failed to create sysfs entry\n");
            goto err_create_device_file;
        }
    }
    return 0;

err_create_device_file:
#ifdef SIM_HPD
    if (!strcmp(SIM1 , plat->name)) free_irq(plat->sim_hpd_in_f, sim1_hpd_in_irq_handler);
    if (!strcmp(SIM2 , plat->name)) free_irq(plat->sim_hpd_in_f, sim2_hpd_in_irq_handler);
no_sim_hpd_in_irq:
    if (!strcmp(SIM1 , plat->name)) free_irq(plat->sim_hpd_out_f, sim1_hpd_out_irq_handler);
    if (!strcmp(SIM2 , plat->name)) free_irq(plat->sim_hpd_out_f, sim2_hpd_out_irq_handler);
no_sim_hpd_out_irq:
#endif
    if (!strcmp(SIM1 , plat->name)) free_irq(gpio_to_irq(plat->sim_detection_gpio), sim1_detection_irq_handler);
    if (!strcmp(SIM2 , plat->name)) free_irq(gpio_to_irq(plat->sim_detection_gpio), sim2_detection_irq_handler);
no_sim_detect_irq:
    destroy_workqueue(workqueue);
    workqueue = NULL;
err_init_workqueue:
    gpio_free(plat->sim_detection_gpio);
    return err;
}