static int axp20x_usb_power_set_property(struct power_supply *psy,
					 enum power_supply_property psp,
					 const union power_supply_propval *val)
{
	struct axp20x_usb_power *power = power_supply_get_drvdata(psy);

	switch (psp) {
	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
		return axp20x_usb_power_set_voltage_min(power, val->intval);

	case POWER_SUPPLY_PROP_CURRENT_MAX:
		return axp20x_usb_power_set_current_max(power, val->intval);

	default:
		return -EINVAL;
	}

	return -EINVAL;
}
Exemple #2
0
static int ac_get_property(struct power_supply *psy,
			enum power_supply_property psp,
			union power_supply_propval *val)
{
	struct pcf50633_mbc *mbc = power_supply_get_drvdata(psy);
	int ret = 0;
	u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
						PCF50633_MBCC7_USB_MASK;

	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		val->intval = mbc->usb_online &&
				(usblim == PCF50633_MBCC7_USB_1000mA);
		break;
	default:
		ret = -EINVAL;
		break;
	}
	return ret;
}
Exemple #3
0
static int ltc294x_get_property(struct power_supply *psy,
                                enum power_supply_property prop,
                                union power_supply_propval *val)
{
        struct ltc294x_info *info = power_supply_get_drvdata(psy);

        switch (prop) {
        case POWER_SUPPLY_PROP_CHARGE_NOW:
                return ltc294x_get_charge_now(info, &val->intval);
        case POWER_SUPPLY_PROP_CHARGE_COUNTER:
                return ltc294x_get_charge_counter(info, &val->intval);
        case POWER_SUPPLY_PROP_VOLTAGE_NOW:
                return ltc294x_get_voltage(info, &val->intval);
        case POWER_SUPPLY_PROP_CURRENT_NOW:
                return ltc294x_get_current(info, &val->intval);
        case POWER_SUPPLY_PROP_TEMP:
                return ltc294x_get_temperature(info, &val->intval);
        default:
                return -EINVAL;
        }
}
static void wm97xx_bat_update(struct power_supply *bat_ps)
{
	int old_status = bat_status;
	struct wm97xx_batt_pdata *pdata = power_supply_get_drvdata(bat_ps);

	mutex_lock(&work_lock);

	bat_status = (pdata->charge_gpio >= 0) ?
			(gpio_get_value(pdata->charge_gpio) ?
			POWER_SUPPLY_STATUS_DISCHARGING :
			POWER_SUPPLY_STATUS_CHARGING) :
			POWER_SUPPLY_STATUS_UNKNOWN;

	if (old_status != bat_status) {
		pr_debug("%s: %i -> %i\n", bat_ps->desc->name, old_status,
					bat_status);
		power_supply_changed(bat_ps);
	}

	mutex_unlock(&work_lock);
}
Exemple #5
0
static int pm860x_usb_get_prop(struct power_supply *psy,
                               enum power_supply_property psp,
                               union power_supply_propval *val)
{
    struct pm860x_charger_info *info = power_supply_get_drvdata(psy);

    switch (psp) {
    case POWER_SUPPLY_PROP_STATUS:
        if (info->state == FSM_FASTCHARGE ||
                info->state == FSM_PRECHARGE)
            val->intval = POWER_SUPPLY_STATUS_CHARGING;
        else
            val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
        break;
    case POWER_SUPPLY_PROP_ONLINE:
        val->intval = info->online;
        break;
    default:
        return -ENODEV;
    }
    return 0;
}
Exemple #6
0
static int goldfish_ac_get_property(struct power_supply *psy,
			enum power_supply_property psp,
			union power_supply_propval *val)
{
	struct goldfish_battery_data *data = power_supply_get_drvdata(psy);
	int ret = 0;

	switch (psp) {
	case POWER_SUPPLY_PROP_ONLINE:
		val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_AC_ONLINE);
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_MAX:
		val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_VOLTAGE_MAX);
		break;
	case POWER_SUPPLY_PROP_CURRENT_MAX:
		val->intval = GOLDFISH_BATTERY_READ(data, BATTERY_CURRENT_MAX);
		break;
	default:
		ret = -EINVAL;
		break;
	}
	return ret;
}
static int max17040_get_property(struct power_supply *psy,
			    enum power_supply_property psp,
			    union power_supply_propval *val)
{
	struct max17040_chip *chip = power_supply_get_drvdata(psy);

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		val->intval = chip->status;
		break;
	case POWER_SUPPLY_PROP_ONLINE:
		val->intval = chip->online;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval = chip->vcell;
		break;
	case POWER_SUPPLY_PROP_CAPACITY:
		val->intval = chip->soc;
		break;
	default:
		return -EINVAL;
	}
	return 0;
}
static int bq27x00_battery_get_property(struct power_supply *psy,
					enum power_supply_property psp,
					union power_supply_propval *val)
{
	int ret = 0;
	struct bq27x00_device_info *di = power_supply_get_drvdata(psy);

	mutex_lock(&di->lock);
	if (time_is_before_jiffies(di->last_update + 5 * HZ)) {
		cancel_delayed_work_sync(&di->work);
		bq27x00_battery_poll(&di->work.work);
	}
	mutex_unlock(&di->lock);

	if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0)
		return -ENODEV;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		ret = bq27x00_battery_status(di, val);
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		ret = bq27x00_battery_voltage(di, val);
		break;
	case POWER_SUPPLY_PROP_PRESENT:
		val->intval = di->cache.flags < 0 ? 0 : 1;
		break;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		ret = bq27x00_battery_current(di, val);
		break;
	case POWER_SUPPLY_PROP_CAPACITY:
		ret = bq27x00_simple_value(di->cache.capacity, val);
		break;
	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
		ret = bq27x00_battery_capacity_level(di, val);
		break;
	case POWER_SUPPLY_PROP_TEMP:
		ret = bq27x00_simple_value(di->cache.temperature, val);
		if (ret == 0)
			val->intval -= 2731;
		break;
	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
		ret = bq27x00_simple_value(di->cache.time_to_empty, val);
		break;
	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
		ret = bq27x00_simple_value(di->cache.time_to_empty_avg, val);
		break;
	case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
		ret = bq27x00_simple_value(di->cache.time_to_full, val);
		break;
	case POWER_SUPPLY_PROP_TECHNOLOGY:
		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
		break;
	case POWER_SUPPLY_PROP_CHARGE_NOW:
		ret = bq27x00_simple_value(bq27x00_battery_read_nac(di), val);
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL:
		ret = bq27x00_simple_value(di->cache.charge_full, val);
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
		ret = bq27x00_simple_value(di->charge_design_full, val);
		break;
	case POWER_SUPPLY_PROP_CYCLE_COUNT:
		ret = bq27x00_simple_value(di->cache.cycle_count, val);
		break;
	case POWER_SUPPLY_PROP_ENERGY_NOW:
		ret = bq27x00_simple_value(di->cache.energy, val);
		break;
	case POWER_SUPPLY_PROP_POWER_AVG:
		ret = bq27x00_simple_value(di->cache.power_avg, val);
		break;
	case POWER_SUPPLY_PROP_HEALTH:
		ret = bq27x00_simple_value(di->cache.health, val);
		break;
	case POWER_SUPPLY_PROP_MANUFACTURER:
		val->strval = BQ27XXX_MANUFACTURER;
		break;
	default:
		return -EINVAL;
	}

	return ret;
}
Exemple #9
0
static inline struct bq24735 *to_bq24735(struct power_supply *psy)
{
	return power_supply_get_drvdata(psy);
}
Exemple #10
0
static int max77650_charger_get_property(struct power_supply *psy,
					 enum power_supply_property psp,
					 union power_supply_propval *val)
{
	struct max77650_charger_data *chg = power_supply_get_drvdata(psy);
	int rv, reg;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		rv = regmap_read(chg->map, MAX77650_REG_STAT_CHG_B, &reg);
		if (rv)
			return rv;

		if (MAX77650_CHARGER_CHG_CHARGING(reg)) {
			val->intval = POWER_SUPPLY_STATUS_CHARGING;
			break;
		}

		switch (MAX77650_CHG_DETAILS_BITS(reg)) {
		case MAX77650_CHG_OFF:
		case MAX77650_CHG_SUSP_PREQ_TIM_FAULT:
		case MAX77650_CHG_SUSP_FAST_CHG_TIM_FAULT:
		case MAX77650_CHG_SUSP_BATT_TEMP_FAULT:
			val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
			break;
		case MAX77650_CHG_PREQ:
		case MAX77650_CHG_ON_CURR:
		case MAX77650_CHG_ON_CURR_JEITA:
		case MAX77650_CHG_ON_VOLT:
		case MAX77650_CHG_ON_VOLT_JEITA:
		case MAX77650_CHG_ON_TOPOFF:
		case MAX77650_CHG_ON_TOPOFF_JEITA:
			val->intval = POWER_SUPPLY_STATUS_CHARGING;
			break;
		case MAX77650_CHG_DONE:
			val->intval = POWER_SUPPLY_STATUS_FULL;
			break;
		default:
			val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
		}
		break;
	case POWER_SUPPLY_PROP_ONLINE:
		rv = regmap_read(chg->map, MAX77650_REG_STAT_CHG_B, &reg);
		if (rv)
			return rv;

		val->intval = MAX77650_CHARGER_CHG_CHARGING(reg);
		break;
	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		rv = regmap_read(chg->map, MAX77650_REG_STAT_CHG_B, &reg);
		if (rv)
			return rv;

		if (!MAX77650_CHARGER_CHG_CHARGING(reg)) {
			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
			break;
		}

		switch (MAX77650_CHG_DETAILS_BITS(reg)) {
		case MAX77650_CHG_PREQ:
		case MAX77650_CHG_ON_CURR:
		case MAX77650_CHG_ON_CURR_JEITA:
		case MAX77650_CHG_ON_VOLT:
		case MAX77650_CHG_ON_VOLT_JEITA:
			val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
			break;
		case MAX77650_CHG_ON_TOPOFF:
		case MAX77650_CHG_ON_TOPOFF_JEITA:
			val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
			break;
		default:
			val->intval = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
		}
		break;
	default:
		return -EINVAL;
	}

	return 0;
}
Exemple #11
0
static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy)
{
	return power_supply_get_drvdata(psy);
}
Exemple #12
0
static int s3c_adc_bat_get_property(struct power_supply *psy,
				    enum power_supply_property psp,
				    union power_supply_propval *val)
{
	struct s3c_adc_bat *bat = power_supply_get_drvdata(psy);

	int new_level;
	int full_volt;
	const struct s3c_adc_bat_thresh *lut;
	unsigned int lut_size;

	if (!bat) {
		dev_err(&psy->dev, "no battery infos ?!\n");
		return -EINVAL;
	}

	lut = bat->pdata->lut_noac;
	lut_size = bat->pdata->lut_noac_cnt;

	if (bat->volt_value < 0 || bat->cur_value < 0 ||
		jiffies_to_msecs(jiffies - bat->timestamp) >
			BAT_POLL_INTERVAL) {
		bat->volt_value = gather_samples(bat->client,
			bat->pdata->volt_samples,
			bat->pdata->volt_channel) * bat->pdata->volt_mult;
		bat->cur_value = gather_samples(bat->client,
			bat->pdata->current_samples,
			bat->pdata->current_channel) * bat->pdata->current_mult;
		bat->timestamp = jiffies;
	}

	if (bat->cable_plugged &&
		((bat->pdata->gpio_charge_finished < 0) ||
		!charge_finished(bat))) {
		lut = bat->pdata->lut_acin;
		lut_size = bat->pdata->lut_acin_cnt;
	}

	new_level = 100000;
	full_volt = calc_full_volt((bat->volt_value / 1000),
		(bat->cur_value / 1000), bat->pdata->internal_impedance);

	if (full_volt < calc_full_volt(lut->volt, lut->cur,
		bat->pdata->internal_impedance)) {
		lut_size--;
		while (lut_size--) {
			int lut_volt1;
			int lut_volt2;

			lut_volt1 = calc_full_volt(lut[0].volt, lut[0].cur,
				bat->pdata->internal_impedance);
			lut_volt2 = calc_full_volt(lut[1].volt, lut[1].cur,
				bat->pdata->internal_impedance);
			if (full_volt < lut_volt1 && full_volt >= lut_volt2) {
				new_level = (lut[1].level +
					(lut[0].level - lut[1].level) *
					(full_volt - lut_volt2) /
					(lut_volt1 - lut_volt2)) * 1000;
				break;
			}
			new_level = lut[1].level * 1000;
			lut++;
		}
	}

	bat->level = new_level;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		if (bat->pdata->gpio_charge_finished < 0)
			val->intval = bat->level == 100000 ?
				POWER_SUPPLY_STATUS_FULL : bat->status;
		else
			val->intval = bat->status;
		return 0;
	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
		val->intval = 100000;
		return 0;
	case POWER_SUPPLY_PROP_CHARGE_EMPTY_DESIGN:
		val->intval = 0;
		return 0;
	case POWER_SUPPLY_PROP_CHARGE_NOW:
		val->intval = bat->level;
		return 0;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval = bat->volt_value;
		return 0;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		val->intval = bat->cur_value;
		return 0;
	default:
		return -EINVAL;
	}
}
Exemple #13
0
static inline struct ds2780_device_info *
to_ds2780_device_info(struct power_supply *psy)
{
	return power_supply_get_drvdata(psy);
}
Exemple #14
0
static struct gab *to_generic_bat(struct power_supply *psy)
{
	return power_supply_get_drvdata(psy);
}
static int twl4030_madc_bat_get_property(struct power_supply *psy,
					enum power_supply_property psp,
					union power_supply_propval *val)
{
	struct twl4030_madc_battery *bat = power_supply_get_drvdata(psy);

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		if (twl4030_madc_bat_voltscale(bat,
				twl4030_madc_bat_get_voltage(bat)) > 95)
			val->intval = POWER_SUPPLY_STATUS_FULL;
		else {
			if (twl4030_madc_bat_get_charging_status(bat))
				val->intval = POWER_SUPPLY_STATUS_CHARGING;
			else
				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
		}
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		val->intval = twl4030_madc_bat_get_voltage(bat) * 1000;
		break;
	case POWER_SUPPLY_PROP_TECHNOLOGY:
		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
		break;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		val->intval = twl4030_madc_bat_get_current(bat);
		break;
	case POWER_SUPPLY_PROP_PRESENT:
		/* assume battery is always present */
		val->intval = 1;
		break;
	case POWER_SUPPLY_PROP_CHARGE_NOW: {
			int percent = twl4030_madc_bat_voltscale(bat,
					twl4030_madc_bat_get_voltage(bat));
			val->intval = (percent * bat->pdata->capacity) / 100;
			break;
		}
	case POWER_SUPPLY_PROP_CAPACITY:
		val->intval = twl4030_madc_bat_voltscale(bat,
					twl4030_madc_bat_get_voltage(bat));
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL:
		val->intval = bat->pdata->capacity;
		break;
	case POWER_SUPPLY_PROP_TEMP:
		val->intval = twl4030_madc_bat_get_temp(bat);
		break;
	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW: {
			int percent = twl4030_madc_bat_voltscale(bat,
					twl4030_madc_bat_get_voltage(bat));
			/* in mAh */
			int chg = (percent * (bat->pdata->capacity/1000))/100;

			/* assume discharge with 400 mA (ca. 1.5W) */
			val->intval = (3600l * chg) / 400;
			break;
		}
	default:
		return -EINVAL;
	}

	return 0;
}
Exemple #16
0
/*********************************************************************
 *		Battery properties
 *********************************************************************/
static int olpc_bat_get_property(struct power_supply *psy,
				 enum power_supply_property psp,
				 union power_supply_propval *val)
{
	struct olpc_battery_data *data = power_supply_get_drvdata(psy);
	int ret = 0;
	u16 ec_word;
	uint8_t ec_byte;
	__be64 ser_buf;

	ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &ec_byte, 1);
	if (ret)
		return ret;

	/* Theoretically there's a race here -- the battery could be
	   removed immediately after we check whether it's present, and
	   then we query for some other property of the now-absent battery.
	   It doesn't matter though -- the EC will return the last-known
	   information, and it's as if we just ran that _little_ bit faster
	   and managed to read it out before the battery went away. */
	if (!(ec_byte & (BAT_STAT_PRESENT | BAT_STAT_TRICKLE)) &&
			psp != POWER_SUPPLY_PROP_PRESENT)
		return -ENODEV;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		ret = olpc_bat_get_status(data, val, ec_byte);
		if (ret)
			return ret;
		break;
	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		if (ec_byte & BAT_STAT_TRICKLE)
			val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
		else if (ec_byte & BAT_STAT_CHARGING)
			val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
		else
			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
		break;
	case POWER_SUPPLY_PROP_PRESENT:
		val->intval = !!(ec_byte & (BAT_STAT_PRESENT |
					    BAT_STAT_TRICKLE));
		break;

	case POWER_SUPPLY_PROP_HEALTH:
		if (ec_byte & BAT_STAT_DESTROY)
			val->intval = POWER_SUPPLY_HEALTH_DEAD;
		else {
			ret = olpc_bat_get_health(val);
			if (ret)
				return ret;
		}
		break;

	case POWER_SUPPLY_PROP_MANUFACTURER:
		ret = olpc_bat_get_mfr(val);
		if (ret)
			return ret;
		break;
	case POWER_SUPPLY_PROP_TECHNOLOGY:
		ret = olpc_bat_get_tech(val);
		if (ret)
			return ret;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_AVG:
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		ret = olpc_ec_cmd(EC_BAT_VOLTAGE, NULL, 0, (void *)&ec_word, 2);
		if (ret)
			return ret;

		val->intval = ecword_to_cpu(data, ec_word) * 9760L / 32;
		break;
	case POWER_SUPPLY_PROP_CURRENT_AVG:
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		ret = olpc_ec_cmd(EC_BAT_CURRENT, NULL, 0, (void *)&ec_word, 2);
		if (ret)
			return ret;

		val->intval = ecword_to_cpu(data, ec_word) * 15625L / 120;
		break;
	case POWER_SUPPLY_PROP_CAPACITY:
		ret = olpc_ec_cmd(EC_BAT_SOC, NULL, 0, &ec_byte, 1);
		if (ret)
			return ret;
		val->intval = ec_byte;
		break;
	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
		if (ec_byte & BAT_STAT_FULL)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_FULL;
		else if (ec_byte & BAT_STAT_LOW)
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_LOW;
		else
			val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
		break;
	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
		ret = olpc_bat_get_charge_full_design(val);
		if (ret)
			return ret;
		break;
	case POWER_SUPPLY_PROP_CHARGE_NOW:
		ret = olpc_bat_get_charge_now(val);
		if (ret)
			return ret;
		break;
	case POWER_SUPPLY_PROP_TEMP:
		ret = olpc_ec_cmd(EC_BAT_TEMP, NULL, 0, (void *)&ec_word, 2);
		if (ret)
			return ret;

		val->intval = ecword_to_cpu(data, ec_word) * 10 / 256;
		break;
	case POWER_SUPPLY_PROP_TEMP_AMBIENT:
		ret = olpc_ec_cmd(EC_AMB_TEMP, NULL, 0, (void *)&ec_word, 2);
		if (ret)
			return ret;

		val->intval = (int)ecword_to_cpu(data, ec_word) * 10 / 256;
		break;
	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
		ret = olpc_ec_cmd(EC_BAT_ACR, NULL, 0, (void *)&ec_word, 2);
		if (ret)
			return ret;

		val->intval = ecword_to_cpu(data, ec_word) * 6250 / 15;
		break;
	case POWER_SUPPLY_PROP_SERIAL_NUMBER:
		ret = olpc_ec_cmd(EC_BAT_SERIAL, NULL, 0, (void *)&ser_buf, 8);
		if (ret)
			return ret;

		sprintf(data->bat_serial, "%016llx", (long long)be64_to_cpu(ser_buf));
		val->strval = data->bat_serial;
		break;
	case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
		ret = olpc_bat_get_voltage_max_design(val);
		if (ret)
			return ret;
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}
Exemple #17
0
static int axp20x_usb_power_get_property(struct power_supply *psy,
	enum power_supply_property psp, union power_supply_propval *val)
{
	struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
	unsigned int input, v;
	int ret;

	switch (psp) {
	case POWER_SUPPLY_PROP_VOLTAGE_MIN:
		ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
		if (ret)
			return ret;

		val->intval = AXP20X_VBUS_VHOLD_uV(v);
		return 0;
	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
		if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
			ret = iio_read_channel_processed(power->vbus_v,
							 &val->intval);
			if (ret)
				return ret;

			/*
			 * IIO framework gives mV but Power Supply framework
			 * gives uV.
			 */
			val->intval *= 1000;
			return 0;
		}

		ret = axp20x_read_variable_width(power->regmap,
						 AXP20X_VBUS_V_ADC_H, 12);
		if (ret < 0)
			return ret;

		val->intval = ret * 1700; /* 1 step = 1.7 mV */
		return 0;
	case POWER_SUPPLY_PROP_CURRENT_MAX:
		ret = regmap_read(power->regmap, AXP20X_VBUS_IPSOUT_MGMT, &v);
		if (ret)
			return ret;

		switch (v & AXP20X_VBUS_CLIMIT_MASK) {
		case AXP20X_VBUC_CLIMIT_100mA:
			if (power->axp20x_id == AXP221_ID)
				val->intval = -1; /* No 100mA limit */
			else
				val->intval = 100000;
			break;
		case AXP20X_VBUC_CLIMIT_500mA:
			val->intval = 500000;
			break;
		case AXP20X_VBUC_CLIMIT_900mA:
			val->intval = 900000;
			break;
		case AXP20X_VBUC_CLIMIT_NONE:
			val->intval = -1;
			break;
		}
		return 0;
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
			ret = iio_read_channel_processed(power->vbus_i,
							 &val->intval);
			if (ret)
				return ret;

			/*
			 * IIO framework gives mA but Power Supply framework
			 * gives uA.
			 */
			val->intval *= 1000;
			return 0;
		}

		ret = axp20x_read_variable_width(power->regmap,
						 AXP20X_VBUS_I_ADC_H, 12);
		if (ret < 0)
			return ret;

		val->intval = ret * 375; /* 1 step = 0.375 mA */
		return 0;
	default:
		break;
	}

	/* All the properties below need the input-status reg value */
	ret = regmap_read(power->regmap, AXP20X_PWR_INPUT_STATUS, &input);
	if (ret)
		return ret;

	switch (psp) {
	case POWER_SUPPLY_PROP_HEALTH:
		if (!(input & AXP20X_PWR_STATUS_VBUS_PRESENT)) {
			val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
			break;
		}

		val->intval = POWER_SUPPLY_HEALTH_GOOD;

		if (power->axp20x_id == AXP202_ID) {
			ret = regmap_read(power->regmap,
					  AXP20X_USB_OTG_STATUS, &v);
			if (ret)
				return ret;

			if (!(v & AXP20X_USB_STATUS_VBUS_VALID))
				val->intval =
					POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
		}
		break;
	case POWER_SUPPLY_PROP_PRESENT:
		val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_PRESENT);
		break;
	case POWER_SUPPLY_PROP_ONLINE:
		val->intval = !!(input & AXP20X_PWR_STATUS_VBUS_USED);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}
Exemple #18
0
static int axp288_charger_usb_get_property(struct power_supply *psy,
				    enum power_supply_property psp,
				    union power_supply_propval *val)
{
	struct axp288_chrg_info *info = power_supply_get_drvdata(psy);
	int ret = 0;

	mutex_lock(&info->lock);

	switch (psp) {
	case POWER_SUPPLY_PROP_PRESENT:
		/* Check for OTG case first */
		if (info->otg.id_short) {
			val->intval = 0;
			break;
		}
		ret = axp288_charger_is_present(info);
		if (ret < 0)
			goto psy_get_prop_fail;
		info->present = ret;
		val->intval = info->present;
		break;
	case POWER_SUPPLY_PROP_ONLINE:
		/* Check for OTG case first */
		if (info->otg.id_short) {
			val->intval = 0;
			break;
		}
		ret = axp288_charger_is_online(info);
		if (ret < 0)
			goto psy_get_prop_fail;
		info->online = ret;
		val->intval = info->online;
		break;
	case POWER_SUPPLY_PROP_HEALTH:
		val->intval = axp288_get_charger_health(info);
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
		val->intval = info->cc * 1000;
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
		val->intval = info->max_cc * 1000;
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
		val->intval = info->cv * 1000;
		break;
	case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
		val->intval = info->max_cv * 1000;
		break;
	case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
		val->intval = info->inlmt * 1000;
		break;
	default:
		ret = -EINVAL;
		goto psy_get_prop_fail;
	}

psy_get_prop_fail:
	mutex_unlock(&info->lock);
	return ret;
}