예제 #1
0
static irqreturn_t pm860x_done_handler(int irq, void *data)
{
    struct pm860x_charger_info *info = data;
    struct power_supply *psy;
    union power_supply_propval val;
    int ret;
    int vbatt;

    mutex_lock(&info->lock);
    /* pre-charge done, will transimit to fast-charge stage */
    if (info->state == FSM_PRECHARGE) {
        info->allowed = 1;
        goto out;
    }
    /*
     * Fast charge done, delay to read
     * the correct status of CHG_DET.
     */
    mdelay(5);
    info->allowed = 0;
    psy = power_supply_get_by_name(pm860x_supplied_to[0]);
    if (!psy)
        goto out;
    ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_NOW,
                                    &val);
    if (ret)
        goto out_psy_put;
    vbatt = val.intval / 1000;
    /*
     * CHG_DONE interrupt is faster than CHG_DET interrupt when
     * plug in/out usb, So we can not rely on info->online, we
     * need check pm8607 status register to check usb is online
     * or not, then we can decide it is real charge done
     * automatically or it is triggered by usb plug out;
     */
    ret = pm860x_reg_read(info->i2c, PM8607_STATUS_2);
    if (ret < 0)
        goto out_psy_put;
    if (vbatt > CHARGE_THRESHOLD && ret & STATUS2_CHG)
        power_supply_set_property(psy, POWER_SUPPLY_PROP_CHARGE_FULL,
                                  &val);

out_psy_put:
    power_supply_put(psy);
out:
    mutex_unlock(&info->lock);
    dev_dbg(info->dev, "%s, Allowed: %d\n", __func__, info->allowed);
    set_charging_fsm(info);

    return IRQ_HANDLED;
}
예제 #2
0
static ssize_t power_supply_store_property(struct device *dev,
					   struct device_attribute *attr,
					   const char *buf, size_t count) {
	ssize_t ret;
	struct power_supply *psy = dev_get_drvdata(dev);
	const ptrdiff_t off = attr - power_supply_attrs;
	union power_supply_propval value;
	long long_val;

	/* TODO: support other types than int */
	ret = kstrtol(buf, 10, &long_val);
	if (ret < 0)
		return ret;

	value.intval = long_val;

	ret = power_supply_set_property(psy, off, &value);
	if (ret < 0)
		return ret;

	return count;
}