static irqreturn_t isl_valid_handler(int irq, void *dev_id) { int val; struct isl9519q_struct *isl_chg; struct i2c_client *client = dev_id; isl_chg = i2c_get_clientdata(client); val = gpio_get_value_cansleep(isl_chg->valid_n_gpio); if (val < 0) { dev_err(&isl_chg->client->dev, "%s gpio_get_value failed for %d ret=%d\n", __func__, isl_chg->valid_n_gpio, val); goto err; } dev_dbg(&isl_chg->client->dev, "%s val=%d\n", __func__, val); if (val) { if (isl_chg->present == 1) { msm_charger_notify_event(&isl_chg->adapter_hw_chg, CHG_REMOVED_EVENT); isl_chg->present = 0; } } else { if (isl_chg->present == 0) { msm_charger_notify_event(&isl_chg->adapter_hw_chg, CHG_INSERTED_EVENT); isl_chg->present = 1; } } err: return IRQ_HANDLED; }
/* * store_usb_chg_enable() - Enable/Disable max8903 usb charge */ static ssize_t store_usb_chg_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct max8903_struct *max_chg; char *after; unsigned long num; max_chg = dev_get_drvdata(dev); num = simple_strtoul(buf, &after, 10); if (num == 0) { /* disable max8903 usb charge */ max_chg->usb_chg_enable = 0; /* * if current is USB charger, need to stop it * set the source current to 0 mA */ if (USB_CHG_TYPE__SDP == cur_chg_type){ cancel_delayed_work(&max_chg->charge_work); /* cancel the charger work */ msm_set_source_current(&max_chg->adapter_hw_chg, 0); msm_charger_notify_event(&max_chg->adapter_hw_chg, CHG_ENUMERATED_EVENT); } /* pull the USUS up */ gpio_direction_output(max_chg->usus, 1); } else { /* enable max8903 usb charge */ max_chg->usb_chg_enable = 1; /* pull the USUS down */ gpio_direction_output(max_chg->usus, 0); /* * if current is USB charger, need to start it * set the source current to 500 mA */ if (USB_CHG_TYPE__SDP == cur_chg_type){ msm_set_source_current(&max_chg->adapter_hw_chg, 500); msm_charger_notify_event(&max_chg->adapter_hw_chg, CHG_ENUMERATED_EVENT); } } return count; }
static void pm8058_chg_determine_initial_state(struct msm_hardware_charger *pchg) { if (pchg->get_charger_status(pchg->gpio_num)) { msm_charger_notify_event(pchg, CHG_INSERTED_EVENT); } enable_irq(pchg->irq); }
static irqreturn_t pm8058_chg_handler(int irq, void *dev_id) { struct msm_hardware_charger *pchg = dev_id; //if (pchg->get_charger_status(pchg->gpio_num)) { /*this debounces it */ msm_charger_notify_event(pchg, CHG_STAT_EVENT); //} else { //msm_charger_notify_event(pchg, CHG_REMOVED_EVENT); //} return IRQ_HANDLED; }
static irqreturn_t soc_irqhandler(int irq, void *dev_id) { int status = 0, temp = 0; temp = if_notify_msm_charger(&status); update_current_battery_status(status); if (temp) msm_charger_notify_event(NULL, CHG_BATT_STATUS_CHANGE); return IRQ_HANDLED; }
static void isl9519q_charge(struct work_struct *isl9519_work) { u16 temp; int ret; struct isl9519q_struct *isl_chg; int isl_charger_current; int mv_reading; isl_chg = container_of(isl9519_work, struct isl9519q_struct, charge_work.work); dev_dbg(&isl_chg->client->dev, "%s\n", __func__); if (isl_chg->charging) { isl_charger_current = isl_read_adc(CHANNEL_ADC_BATT_AMON, &mv_reading); dev_dbg(&isl_chg->client->dev, "%s mv_reading=%d\n", __func__, mv_reading); dev_dbg(&isl_chg->client->dev, "%s isl_charger_current=%d\n", __func__, isl_charger_current); if (isl_charger_current >= 0 && isl_charger_current <= isl_chg->term_current) { msm_charger_notify_event( &isl_chg->adapter_hw_chg, CHG_DONE_EVENT); } isl9519q_write_reg(isl_chg->client, CHG_CURRENT_REG, isl_chg->chgcurrent); ret = isl9519q_read_reg(isl_chg->client, CONTROL_REG, &temp); if (!ret) { if (!(temp & TRCKL_CHG_STATUS_BIT)) msm_charger_notify_event( &isl_chg->adapter_hw_chg, CHG_BATT_BEGIN_FAST_CHARGING); } else { dev_err(&isl_chg->client->dev, "%s couldnt read cntrl reg\n", __func__); } schedule_delayed_work(&isl_chg->charge_work, ISL9519_CHG_PERIOD); } }
static void battery_status_poller(struct work_struct *work) { int status = 0, temp = 0; temp = if_notify_msm_charger(&status); update_current_battery_status(status); if (temp) msm_charger_notify_event(NULL, CHG_BATT_STATUS_CHANGE); schedule_delayed_work(¤t_battery_status.poller, BQ27520_POLLING_STATUS); }
static void isl_adapter_check_ichg(struct isl9519q_struct *isl_chg) { int ichg; /* isl charger current */ int mv_reading = 0; ichg = isl_read_adc(CHANNEL_ADC_BATT_AMON, &mv_reading); dev_dbg(&isl_chg->client->dev, "%s mv_reading=%d\n", __func__, mv_reading); dev_dbg(&isl_chg->client->dev, "%s isl_charger_current=%d\n", __func__, ichg); if (ichg >= 0 && ichg <= isl_chg->term_current) msm_charger_notify_event(&isl_chg->adapter_hw_chg, CHG_DONE_EVENT); isl_chg->trickle = is_trickle_charging(isl_chg); if (isl_chg->trickle) msm_charger_notify_event(&isl_chg->adapter_hw_chg, CHG_BATT_BEGIN_FAST_CHARGING); }
static void bq27520_hw_config(struct work_struct *work) { int ret = 0, flags = 0, type = 0, fw_ver = 0, status = 0; struct bq27520_device_info *di; di = container_of(work, struct bq27520_device_info, hw_config.work); pr_debug(KERN_INFO "Enter bq27520_hw_config\n"); ret = bq27520_chip_config(di); if (ret) { dev_err(di->dev, "Failed to config Bq27520 ret = %d\n", ret); return; } /* bq27520 is ready for access, update current_battery_status by reading * from hardware */ if_notify_msm_charger(&status); update_current_battery_status(status); msm_battery_gauge_register(&bq27520_batt_gauge); msm_charger_notify_event(NULL, CHG_BATT_STATUS_CHANGE); enable_irq(di->irq); /* poll battery status every 3 seconds, if charging status changes, * notify msm_charger */ schedule_delayed_work(¤t_battery_status.poller, BQ27520_POLLING_STATUS); if (di->pdata->enable_dlog) { schedule_work(&di->counter); init_timer(&timer); timer.function = &bq27520_every_30secs; timer.data = (unsigned long)di; timer.expires = jiffies + BQ27520_COULOMB_POLL; add_timer(&timer); } bq27520_cntl_cmd(di, BQ27520_SUBCMD_CTNL_STATUS); udelay(66); bq27520_read(BQ27520_REG_CNTL, &flags, 0, di); bq27520_cntl_cmd(di, BQ27520_SUBCMD_DEVCIE_TYPE); udelay(66); bq27520_read(BQ27520_REG_CNTL, &type, 0, di); bq27520_cntl_cmd(di, BQ27520_SUBCMD_FW_VER); udelay(66); bq27520_read(BQ27520_REG_CNTL, &fw_ver, 0, di); dev_info(di->dev, "DEVICE_TYPE is 0x%02X, FIRMWARE_VERSION\ is 0x%02X\n", type, fw_ver); dev_info(di->dev, "Complete bq27520 configuration 0x%02X\n", flags); }
static int __devexit isl9519q_remove(struct i2c_client *client) { struct isl_platform_data *pdata; struct isl9519q_struct *isl_chg = i2c_get_clientdata(client); pdata = client->dev.platform_data; gpio_free(pdata->valid_n_gpio); free_irq(client->irq, client); cancel_delayed_work_sync(&isl_chg->charge_work); msm_charger_notify_event(&isl_chg->adapter_hw_chg, CHG_REMOVED_EVENT); msm_charger_unregister(&isl_chg->adapter_hw_chg); return 0; }
/* * max8903_chg_connected() - notify the charger connected event * @chg_type: charger type */ void max8903_chg_connected(enum chg_type chg_type) { cur_chg_type = chg_type; pr_info("%s:chg type =%d\n", __func__, cur_chg_type); if (delay_ac_charger_detect){ delay_ac_charger_detect = 0; cancel_delayed_work(&saved_msm_chg->ac_charger); pr_info("%s: queue a insert event\n", __func__); msm_charger_notify_event(&saved_msm_chg->adapter_hw_chg, CHG_INSERTED_EVENT); } }
static irqreturn_t max_valid_handler(int irq, void *dev_id) { struct max8903_struct *max_chg; struct platform_device *pdev; struct pm8058_chip *chip; int state; pdev = (struct platform_device *)dev_id; max_chg = platform_get_drvdata(pdev); chip = get_irq_data(irq); #if 0 /* Dock insert, think it as AC charger */ if (gpio_get_value_cansleep(max_chg->dock_det) && (BOARD_NUM(hw_ver) != BOARD_NUM_V11)) max_chg->adapter_hw_chg.type = CHG_TYPE_USB; else max_chg->adapter_hw_chg.type = CHG_TYPE_AC; #endif /* reinitialize charger type */ if ((BOARD_NUM(hw_ver) == BOARD_NUM_V11)) max_chg->adapter_hw_chg.type = CHG_TYPE_AC; else max_chg->adapter_hw_chg.type = CHG_TYPE_USB; state = pm8058_irq_get_rt_status(chip, irq); pr_info("%s:charge state=%d, hw_chg_type=%d\n", __func__, state, max_chg->adapter_hw_chg.type); if(state){ /* delay to queue charge insert envent when charger inserted, * need to detect if it is an ac charger */ //msm_charger_notify_event(&max_chg->adapter_hw_chg, // CHG_INSERTED_EVENT); delay_ac_charger_detect = 1; pr_info("%s:delay_ac_charger_detect=%d start ac charger delay work\n", __func__, delay_ac_charger_detect); schedule_delayed_work(&max_chg->ac_charger, AC_CHARGER_DETECT_DELAY); max_chg->present = 1; wake_lock(&max_chg->wl); }else{ delay_ac_charger_detect = 0; pr_info("%s:delay_ac_charger_detect=%d cancel ac charger delay work\n", __func__, delay_ac_charger_detect); cancel_delayed_work(&saved_msm_chg->ac_charger); msm_charger_notify_event(&max_chg->adapter_hw_chg, CHG_REMOVED_EVENT); max_chg->present = 0; wake_unlock(&max_chg->wl); } return IRQ_HANDLED; }
static int __devexit pm8058_charger_remove(struct platform_device *pdev) { struct msm_hardware_charger *pchg = dev_get_drvdata(&pdev->dev); // container_of(&pdev, struct msm_hardware_charger, pdev); pchg->chg_detection_config(0, pchg->gpio_num); msm_charger_notify_event(pchg, CHG_REMOVED_EVENT); msm_charger_unregister(pchg); // //#ifdef CONFIG_HAS_EARLYSUSPEND // unregister_early_suspend(&pchg->early_suspend); //#endif // free_irqs(pchg); kfree(pchg); return 0; }
static int __devexit isl9519q_remove(struct i2c_client *client) { struct isl_platform_data *pdata; struct isl9519q_struct *isl_chg = i2c_get_clientdata(client); pdata = client->dev.platform_data; gpio_free(pdata->valid_n_gpio); free_irq(client->irq, client); cancel_delayed_work_sync(&isl_chg->charge_work); if (isl_chg->notify_by_pmic) { power_supply_unregister(&isl_chg->dc_psy); } else { msm_charger_notify_event(&isl_chg->adapter_hw_chg, CHG_REMOVED_EVENT); msm_charger_unregister(&isl_chg->adapter_hw_chg); } remove_debugfs_entries(isl_chg); the_isl_chg = NULL; kfree(isl_chg); return 0; }
static __devexit int max8903_remove(struct platform_device *pdev) { struct max8903_struct *max_chg; max_chg = platform_get_drvdata(pdev); if (max_chg) { device_remove_file(max_chg->dev, &usb_chg_enable_attr); free_irq(max_chg->irq, pdev); free_irq(gpio_to_irq(max_chg->flt), pdev); gpio_free(max_chg->flt); gpio_free(max_chg->chg); gpio_free(max_chg->cen); cancel_delayed_work_sync(&max_chg->charge_work); msm_charger_notify_event(&max_chg->adapter_hw_chg, CHG_REMOVED_EVENT); msm_charger_unregister(&max_chg->adapter_hw_chg); kfree(max_chg); } return 0; }
static void max8903_charge(struct work_struct *max8903_work) { struct max8903_struct *max_chg; int current_capacity; int current_voltage; max_chg = container_of(max8903_work, struct max8903_struct, charge_work.work); dev_info(max_chg->dev, "%s\n", __func__); if (max_chg->charging) { current_capacity = max17040_get_soc(max17040_bak_client); current_voltage = max17040_get_vcell(max17040_bak_client); pr_info("%s:capacity=%d voltage=%d\n ", __func__, current_capacity, current_voltage); //get the charger status value if ((gpio_get_value(max_chg->chg) == 1) && (current_capacity > MAX8903_BATTERY_FULL)) msm_charger_notify_event(&max_chg->adapter_hw_chg, CHG_DONE_EVENT); schedule_delayed_work(&max_chg->charge_work, MAX8903_CHG_PERIOD); } }
static void ac_charger_detect(struct work_struct *max8903_work) { struct max8903_struct *max_chg; max_chg = container_of(max8903_work, struct max8903_struct, ac_charger.work); dev_info(max_chg->dev, "%s\n", __func__); /* * if it's not a stadard USB charger * think it as an AC charger */ if (delay_ac_charger_detect){ delay_ac_charger_detect = 0; /* change charger type */ max_chg->adapter_hw_chg.type = CHG_TYPE_AC; /* queue a insert envent */ pr_info("%s: queue a insert event\n", __func__); msm_charger_notify_event(&max_chg->adapter_hw_chg, CHG_INSERTED_EVENT); } }
static int __devinit isl9519q_init_adapter(struct isl9519q_struct *isl_chg) { int ret; struct i2c_client *client = isl_chg->client; struct isl_platform_data *pdata = client->dev.platform_data; isl_chg->adapter_hw_chg.type = CHG_TYPE_AC; isl_chg->adapter_hw_chg.rating = 2; isl_chg->adapter_hw_chg.name = "isl-adapter"; isl_chg->adapter_hw_chg.start_charging = isl_adapter_start_charging; isl_chg->adapter_hw_chg.stop_charging = isl_adapter_stop_charging; isl_chg->adapter_hw_chg.charging_switched = isl9519q_charging_switched; ret = gpio_request(pdata->valid_n_gpio, "isl_charger_valid"); if (ret) { dev_err(&client->dev, "%s gpio_request failed " "for %d ret=%d\n", __func__, pdata->valid_n_gpio, ret); goto out; } ret = msm_charger_register(&isl_chg->adapter_hw_chg); if (ret) { dev_err(&client->dev, "%s msm_charger_register failed for ret =%d\n", __func__, ret); goto free_gpio; } ret = request_threaded_irq(client->irq, NULL, isl_valid_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "isl_charger_valid", client); if (ret) { dev_err(&client->dev, "%s request_threaded_irq failed " "for %d ret =%d\n", __func__, client->irq, ret); goto unregister; } irq_set_irq_wake(client->irq, 1); ret = gpio_get_value_cansleep(isl_chg->valid_n_gpio); if (ret < 0) { dev_err(&client->dev, "%s gpio_get_value failed for %d ret=%d\n", __func__, pdata->valid_n_gpio, ret); /* assume absent */ ret = 1; } if (!ret) { msm_charger_notify_event(&isl_chg->adapter_hw_chg, CHG_INSERTED_EVENT); isl_chg->present = 1; } return 0; unregister: msm_charger_unregister(&isl_chg->adapter_hw_chg); free_gpio: gpio_free(pdata->valid_n_gpio); out: return ret; }
static int __devinit max8903_probe(struct platform_device *pdev) { struct max8903_struct *max_chg; struct device *dev = &pdev->dev; struct max8903_platform_data *pdata = pdev->dev.platform_data; struct pm8058_chip *chip; int ret = 0; //printk("%s\n", __func__); max_chg = kzalloc(sizeof(struct max8903_struct), GFP_KERNEL); if (max_chg == NULL) { dev_err(dev, "Cannot allocate memory.\n"); return -ENOMEM; } saved_msm_chg = max_chg; if (pdata == NULL) { dev_err(&pdev->dev, "%s no platform data\n", __func__); ret = -EINVAL; goto out; } INIT_DELAYED_WORK(&max_chg->charge_work, max8903_charge); INIT_DELAYED_WORK(&max_chg->ac_charger, ac_charger_detect); wake_lock_init(&max_chg->wl, WAKE_LOCK_SUSPEND, "max8903"); max_chg->dev = &pdev->dev;; max_chg->irq = pdata->irq; max_chg->cen = pdata->cen; max_chg->chg = pdata->chg; max_chg->flt = pdata->flt; max_chg->usus = pdata->usus; max_chg->dock_det = pdata->dock_det; max_chg->usb_chg_enable = 1; /* enable usb charge */ if (BOARD_NUM(hw_ver) == BOARD_NUM_V11) max_chg->adapter_hw_chg.type = CHG_TYPE_AC; else max_chg->adapter_hw_chg.type = CHG_TYPE_USB; max_chg->adapter_hw_chg.rating = 2; max_chg->adapter_hw_chg.name = "max8903-charger"; max_chg->adapter_hw_chg.start_charging = max8903_start_charging; max_chg->adapter_hw_chg.stop_charging = max8903_stop_charging; max_chg->adapter_hw_chg.charging_switched = max8903_charging_switched; platform_set_drvdata(pdev, max_chg); ret = gpio_request(max_chg->cen, "CHARGER_CEN_N"); if (ret) { dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n", __func__, max_chg->cen, ret); goto free_max_chg; } ret = gpio_request(max_chg->chg, "CHARGER_STATUS"); if (ret) { dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n", __func__, max_chg->chg, ret); goto free_cen; } gpio_direction_input(max_chg->chg); ret = gpio_request(max_chg->flt, "CHARGER_FAULT_N"); if (ret) { dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n", __func__, max_chg->flt, ret); goto free_chg; } gpio_direction_input(max_chg->flt); ret = request_threaded_irq(gpio_to_irq(max_chg->flt), NULL, max8903_fault, IRQF_TRIGGER_FALLING ,"MAX8903 Fault", pdev); if (ret) { dev_err(dev, "Cannot request irq %d for Fault (%d)\n", gpio_to_irq(max_chg->flt), ret); goto free_flt; } ret = gpio_request(max_chg->usus, "USUS_CTRL"); if (ret) { dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n", __func__, max_chg->usus, ret); goto err_flt_irq; } ret = gpio_request(max_chg->dock_det, "DOCK_DET"); if (ret) { dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n", __func__, max_chg->dock_det, ret); goto free_usus; } gpio_direction_input(max_chg->dock_det); ret = msm_charger_register(&max_chg->adapter_hw_chg); if (ret) { dev_err(max_chg->dev, "%s msm_charger_register failed for ret =%d\n", __func__, ret); goto free_dock_det; } ret = device_create_file(max_chg->dev, &usb_chg_enable_attr); if (ret) { dev_err(max_chg->dev, "failed: create usb_chg_enable file\n"); } ret = request_threaded_irq(max_chg->irq, NULL, max_valid_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "max_valid_handler", pdev); if (ret) { dev_err(max_chg->dev, "%s request_threaded_irq failed for %d ret =%d\n", __func__, max_chg->irq, ret); goto unregister; } set_irq_wake(max_chg->irq, 1); chip = get_irq_data(max_chg->irq); ret = pm8058_irq_get_rt_status(chip, max_chg->irq); if (ret) { #if 0 if (!gpio_get_value_cansleep(max_chg->dock_det)) /* Dock insert, think it as AC charger */ max_chg->adapter_hw_chg.type = CHG_TYPE_AC; msm_charger_notify_event(&max_chg->adapter_hw_chg, CHG_INSERTED_EVENT); #else /* Charger inserted, but not a valid USB charger * think it as a AC charger */ if (USB_CHG_TYPE__INVALID == cur_chg_type) max_chg->adapter_hw_chg.type = CHG_TYPE_AC; msm_charger_notify_event(&max_chg->adapter_hw_chg, CHG_INSERTED_EVENT); #endif max_chg->present = 1; wake_lock(&max_chg->wl); } msm_register_usb_charger_state(max8903_usb_charger_state); pr_info("%s OK chg_present=%d\n", __func__, max_chg->present); return 0; unregister: msm_charger_unregister(&max_chg->adapter_hw_chg); free_dock_det: gpio_free(max_chg->dock_det); free_usus: gpio_free(max_chg->usus); err_flt_irq: free_irq(gpio_to_irq(max_chg->flt), pdev); free_flt: gpio_free(max_chg->flt); free_chg: gpio_free(max_chg->chg); free_cen: gpio_free(max_chg->cen); free_max_chg: kfree(max_chg); out: return ret; }
static void bq24160_charge(struct work_struct *bq24160_work) { #ifdef BQ24160_WORKAROUND_CHG_DONE /* work around for charge done*/ int val; #endif u8 temp = 0; u8 status = 0; int rc; struct bq24160_chip *bq24160_chg; bq24160_chg = container_of(bq24160_work, struct bq24160_chip, charge_work.work); dev_dbg(&bq24160_chg->client->dev, "%s\n", __func__); /* Watchdog timer reset */ bq24160_set_bits(bq24160_chg->client, BQ24160_REG_STAT_CTRL, BQ24160_WDOG_TMR_MASK, (1<<BQ24160_WDOG_TMR_SHFT)); if (bq24160_chg->chg_online) { temp = bq24160_read_reg(bq24160_chg->client, BQ24160_REG_BATTNPS_STAT); dev_dbg(&bq24160_chg->client->dev, "%s STATUS Register[#1]: 0x%x\n", __func__,temp); temp = bq24160_read_reg(bq24160_chg->client, BQ24160_REG_STAT_CTRL); dev_dbg(&bq24160_chg->client->dev, "%s STATUS Register[#0]: 0x%x\n", __func__,temp); status = temp & BQ24160_STAT_MASK; status = status >> BQ24160_STAT_SHFT; dev_dbg(&bq24160_chg->client->dev, "%s STATUS: %d\n", __func__,status); switch(status) { case BQ24160_STAT_NO_VALID_SRC_DETECTED: break; case BQ24160_STAT_IN_READY: break; case BQ24160_STAT_USB_READY: break; case BQ24160_STAT_CHARGING_FROM_IN: break; case BQ24160_STAT_CHARGING_FROM_USB: break; case BQ24160_STAT_CHARGE_DONE: dev_dbg(&bq24160_chg->client->dev, "%s Charge done by Status Register!!!\n", __func__); rc = gpio_direction_output(WIRELESS_CHARGE_COMPLETE, 1); if (rc) { dev_err(&bq24160_chg->client->dev,"%s: gpio_direction_output failed for %d\n", __func__, WIRELESS_CHARGE_COMPLETE); } msm_charger_notify_event(&bq24160_chg->adapter_hw_chg, CHG_DONE_EVENT); wake_lock(&bq24160_chg->wl); //schedule_delayed_work(&bq24160_chg->charge_done_work, BQ24160_CHG_DONE_WORK_PERIOD); queue_delayed_work(local_charge_done_wq, &bq24160_chg->charge_done_work, BQ24160_CHG_DONE_WORK_PERIOD); break; case BQ24160_STAT_NA: break; case BQ24160_STAT_FAULT: break; } #ifdef BQ24160_WORKAROUND_CHG_DONE /* work around for charge done*/ val = gpio_get_value_cansleep(WIRELESS_CHARGE_INT); if (val < 0) { dev_err(&bq24160_chg->client->dev, "%s gpio_get_value failed for %d ret=%d\n", __func__, WIRELESS_CHARGE_INT, val); } dev_dbg(&bq24160_chg->client->dev, "%s val=%d\n", __func__, val); if(val) { chg_done_cnt++; if(chg_done_cnt >= 2) { dev_dbg(&bq24160_chg->client->dev, "%s Charge done by Interrupt High!!!\n", __func__); rc = gpio_direction_output(WIRELESS_CHARGE_COMPLETE, 1); if (rc) { dev_err(&bq24160_chg->client->dev,"%s: gpio_direction_output failed for %d\n", __func__, WIRELESS_CHARGE_COMPLETE); } msm_charger_notify_event(&bq24160_chg->adapter_hw_chg, CHG_DONE_EVENT); wake_lock(&bq24160_chg->wl); //schedule_delayed_work(&bq24160_chg->charge_done_work, BQ24160_CHG_DONE_WORK_PERIOD); queue_delayed_work(local_charge_done_wq, &bq24160_chg->charge_done_work, BQ24160_CHG_DONE_WORK_PERIOD); } } else { chg_done_cnt = 0; } #endif //schedule_delayed_work(&bq24160_chg->charge_work, BQ24160_CHG_WORK_PERIOD); queue_delayed_work(local_charge_wq, &bq24160_chg->charge_work, BQ24160_CHG_WORK_PERIOD); }
static int __devinit isl9519q_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct isl_platform_data *pdata; struct isl9519q_struct *isl_chg; int ret; ret = 0; pdata = client->dev.platform_data; if (pdata == NULL) { dev_err(&client->dev, "%s no platform data\n", __func__); ret = -EINVAL; goto out; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) { ret = -EIO; goto out; } isl_chg = kzalloc(sizeof(*isl_chg), GFP_KERNEL); if (!isl_chg) { ret = -ENOMEM; goto out; } INIT_DELAYED_WORK(&isl_chg->charge_work, isl9519q_charge); isl_chg->client = client; isl_chg->chgcurrent = pdata->chgcurrent; isl_chg->term_current = pdata->term_current; isl_chg->input_current = pdata->input_current; isl_chg->max_system_voltage = pdata->max_system_voltage; isl_chg->min_system_voltage = pdata->min_system_voltage; isl_chg->valid_n_gpio = pdata->valid_n_gpio; /* h/w ignores lower 7 bits of charging current and input current */ isl_chg->chgcurrent &= ~0x7F; isl_chg->input_current &= ~0x7F; isl_chg->adapter_hw_chg.type = CHG_TYPE_AC; isl_chg->adapter_hw_chg.rating = 2; isl_chg->adapter_hw_chg.name = "isl-adapter"; isl_chg->adapter_hw_chg.start_charging = isl9519q_start_charging; isl_chg->adapter_hw_chg.stop_charging = isl9519q_stop_charging; isl_chg->adapter_hw_chg.charging_switched = isl9519q_charging_switched; if (pdata->chg_detection_config) { ret = pdata->chg_detection_config(); if (ret) { dev_err(&client->dev, "%s valid config failed ret=%d\n", __func__, ret); goto free_isl_chg; } } ret = gpio_request(pdata->valid_n_gpio, "isl_charger_valid"); if (ret) { dev_err(&client->dev, "%s gpio_request failed for %d ret=%d\n", __func__, pdata->valid_n_gpio, ret); goto free_isl_chg; } i2c_set_clientdata(client, isl_chg); ret = msm_charger_register(&isl_chg->adapter_hw_chg); if (ret) { dev_err(&client->dev, "%s msm_charger_register failed for ret =%d\n", __func__, ret); goto free_gpio; } ret = request_threaded_irq(client->irq, NULL, isl_valid_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "isl_charger_valid", client); if (ret) { dev_err(&client->dev, "%s request_threaded_irq failed for %d ret =%d\n", __func__, client->irq, ret); goto unregister; } set_irq_wake(client->irq, 1); isl_chg->max_system_voltage &= MAX_VOLTAGE_REG_MASK; isl_chg->min_system_voltage &= MIN_VOLTAGE_REG_MASK; if (isl_chg->max_system_voltage == 0) isl_chg->max_system_voltage = DEFAULT_MAX_VOLTAGE_REG_VALUE; if (isl_chg->min_system_voltage == 0) isl_chg->min_system_voltage = DEFAULT_MIN_VOLTAGE_REG_VALUE; ret = isl9519q_write_reg(isl_chg->client, MAX_SYS_VOLTAGE_REG, isl_chg->max_system_voltage); if (ret) { dev_err(&client->dev, "%s couldnt write to MAX_SYS_VOLTAGE_REG ret=%d\n", __func__, ret); goto free_irq; } ret = isl9519q_write_reg(isl_chg->client, MIN_SYS_VOLTAGE_REG, isl_chg->min_system_voltage); if (ret) { dev_err(&client->dev, "%s couldnt write to MIN_SYS_VOLTAGE_REG ret=%d\n", __func__, ret); goto free_irq; } if (isl_chg->input_current) { ret = isl9519q_write_reg(isl_chg->client, INPUT_CURRENT_REG, isl_chg->input_current); if (ret) { dev_err(&client->dev, "%s couldnt write INPUT_CURRENT_REG ret=%d\n", __func__, ret); goto free_irq; } } ret = gpio_get_value_cansleep(isl_chg->valid_n_gpio); if (ret < 0) { dev_err(&client->dev, "%s gpio_get_value failed for %d ret=%d\n", __func__, pdata->valid_n_gpio, ret); /* assume absent */ ret = 1; } if (!ret) { msm_charger_notify_event(&isl_chg->adapter_hw_chg, CHG_INSERTED_EVENT); isl_chg->present = 1; } pr_debug("%s OK chg_present=%d\n", __func__, isl_chg->present); return 0; free_irq: free_irq(client->irq, NULL); unregister: msm_charger_unregister(&isl_chg->adapter_hw_chg); free_gpio: gpio_free(pdata->valid_n_gpio); free_isl_chg: kfree(isl_chg); out: return ret; }