static void li_ion_work(struct work_struct *work) { struct li_ion_charger *li_ion; int status; int online; li_ion = container_of(work, struct li_ion_charger, work.work); online = gpio_get_value(li_ion->pdata->gpio) ^ li_ion->pdata->gpio_active_low; pr_info("li_ion: li_ion_work: online=%d \n", online); if (online != li_ion->online) { status = online ? POWER_SUPPLY_STATUS_CHARGING : POWER_SUPPLY_STATUS_NOT_CHARGING; if (status == POWER_SUPPLY_STATUS_NOT_CHARGING && is_ac_online()) status = POWER_SUPPLY_STATUS_FULL; if (li_ion->status != status) { pr_info("li_ion: update status: %s -> %s\n", status_dbg(li_ion->status), status_dbg(status)); li_ion->status = status; update_battery(li_ion, status);// power_supply_changed(&li_ion->charger); } li_ion->online = online; } enable_irq(li_ion->irq); }
//export this interface for other driver int act8xxx_is_ac_online(void) { if(this_client == NULL) { pr_err("act8xxx: have not init now, wait.... \n"); return 1; } return is_ac_online(); }
static void li_ion_external_power_changed(struct power_supply *psy) { struct li_ion_charger *li_ion = psy_to_li_ion(psy); if (li_ion->status == POWER_SUPPLY_STATUS_FULL && !is_ac_online()) { pr_info("li_ion: ac offline: FULL -> NOT_CHARGING\n"); li_ion->status = POWER_SUPPLY_STATUS_NOT_CHARGING; update_battery(li_ion, li_ion->status);// power_supply_changed(&li_ion->charger); } else pr_info("li_ion: ac changed (skip)\n"); }
static int get_pmu_status(void *pmu_interface, int status) { struct li_ion_charger *li_ion = (struct li_ion_charger *)pmu_interface; switch (status) { case AC: return is_ac_online(); case USB: return 0; case STATUS: return li_ion->status; } return -1; }
static inline int do_ac_online (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #ifdef CONFIG_PLATFORM_HAS_PMU struct aml_pmu_driver *pmu_driver; pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_get_extern_power_status) { return !pmu_driver->pmu_get_extern_power_status(); } else { printf("ERROR!! No pmu_get_battery_capacity hooks!\n"); return 0; } #else return !is_ac_online(); #endif }
static int stmp3xxx_bat_resume(struct platform_device *pdev) { struct stmp3xxx_info *info = platform_get_drvdata(pdev); ddi_bc_Cfg_t *cfg = info->sm_cfg; mutex_lock(&info->sm_lock); if (is_ac_online()) { /* ac supply connected */ dev_info(info->dev, "ac/5v present, enabling state machine\n"); info->is_ac_online = 1; info->is_usb_online = 0; ddi_bc_SetCurrentLimit( NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA /*mA*/); ddi_bc_SetEnable(); } else if (is_usb_online()) { /* usb supply connected */ dev_info(info->dev, "usb/5v present, enabling state machine\n"); info->is_ac_online = 0; info->is_usb_online = 1; ddi_bc_SetCurrentLimit(POWERED_USB_5V_CURRENT_LIMIT_MA /*mA*/); ddi_bc_SetEnable(); } else { /* not powered */ dev_info(info->dev, "%s: 5v not present\n", __func__); info->is_ac_online = 0; info->is_usb_online = 0; } /* enable 5v irq */ __raw_writel(BM_POWER_CTRL_ENIRQ_VDD5V_GT_VDDIO, REGS_POWER_BASE + HW_POWER_CTRL_SET); /* reschedule calls to state machine */ mod_timer(&info->sm_timer, jiffies + msecs_to_jiffies(cfg->u32StateMachinePeriod)); mutex_unlock(&info->sm_lock); return 0; }
static int stmp3xxx_power_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) { switch (psp) { case POWER_SUPPLY_PROP_ONLINE: if (psy->type == POWER_SUPPLY_TYPE_MAINS) /* ac online */ val->intval = is_ac_online(); else /* usb online */ val->intval = is_usb_online(); break; default: return -EINVAL; } return 0; }
static void update_work_func(struct work_struct *work) { int capacity,bat_status; capacity = measure_capacity_advanced(); bat_status = get_bat_status(); if(act8xxx_dev->ac_status != is_ac_online()) { power_supply_changed(&act8xxx_dev->ac); } if(act8xxx_dev->capacity != capacity) { act8xxx_dev->capacity = capacity; power_supply_changed(&act8xxx_dev->bat); } if(act8xxx_dev->bat_status != bat_status) { act8xxx_dev->bat_status = bat_status; power_supply_changed(&act8xxx_dev->bat); } }
/* * Assumption: * AC power can't be switched to USB w/o system reboot * and vice-versa */ static void state_machine_work(struct work_struct *work) { struct stmp3xxx_info *info = container_of(work, struct stmp3xxx_info, sm_work); mutex_lock(&info->sm_lock); handle_battery_voltage_changes(info); check_and_handle_5v_connection(info); if ((info->sm_5v_connection_status != _5v_connected_verified) || !(info->regulator)) { mod_timer(&info->sm_timer, jiffies + msecs_to_jiffies(100)); goto out; } /* if we made it here, we have a verified 5v connection */ if (is_ac_online()) { if (info->is_ac_online) goto done; /* ac supply connected */ dev_info(info->dev, "changed power connection to ac/5v.\n)"); dev_info(info->dev, "5v current limit set to %u.\n", NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA); info->is_ac_online = 1; info->is_usb_online = 0; ddi_power_set_4p2_ilimit( NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA); ddi_bc_SetCurrentLimit( NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA /*mA*/); if (regulator_set_current_limit(info->regulator, 0, NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA*1000)) { dev_err(info->dev, "reg_set_current(%duA) failed\n", NON_USB_5V_SUPPLY_CURRENT_LIMIT_MA*1000); } ddi_bc_SetEnable(); goto done; } if (!is_usb_online()) goto out; if (info->is_usb_online & USB_REG_SET) goto done; info->is_ac_online = 0; info->is_usb_online |= USB_ONLINE; if (!(info->is_usb_online & USB_N_SEND)) { info->is_usb_online |= USB_N_SEND; } dev_dbg(info->dev, "%s: charge current set to %dmA\n", __func__, POWERED_USB_5V_CURRENT_LIMIT_MA); if (regulator_set_current_limit(info->regulator, 0, POWERED_USB_5V_CURRENT_LIMIT_MA*1000)) { dev_err(info->dev, "reg_set_current(%duA) failed\n", POWERED_USB_5V_CURRENT_LIMIT_MA*1000); } else { ddi_bc_SetCurrentLimit(POWERED_USB_5V_CURRENT_LIMIT_MA/*mA*/); ddi_bc_SetEnable(); } if (info->is_usb_online & USB_SM_RESTART) { info->is_usb_online &= ~USB_SM_RESTART; ddi_bc_SetEnable(); } info->is_usb_online |= USB_REG_SET; dev_info(info->dev, "changed power connection to usb/5v present\n"); done: ddi_bc_StateMachine(); out: mutex_unlock(&info->sm_lock); }