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); }
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; }
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; }