Exemplo n.º 1
0
int pd_choose_voltage(int cnt, uint32_t *src_caps, uint32_t *rdo)
{
	int i;
	int sel_mv;
	int max_uw = 0;
	int max_i = -1;

	/* Get max power */
	for (i = 0; i < cnt; i++) {
		int uw;
		int mv = ((src_caps[i] >> 10) & 0x3FF) * 50;
		if ((src_caps[i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
			uw = 250000 * (src_caps[i] & 0x3FF);
		} else {
			int ma = (src_caps[i] & 0x3FF) * 10;
			uw = ma * mv;
		}
		if ((uw > max_uw) && (mv <= max_mv)) {
			max_i = i;
			max_uw = uw;
			sel_mv = mv;
		}
	}
	if (max_i < 0)
		return -EC_ERROR_UNKNOWN;

	/* request all the power ... */
	if ((src_caps[max_i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
		int uw = 250000 * (src_caps[i] & 0x3FF);
		*rdo = RDO_BATT(max_i + 1, uw/2, uw, 0);
		ccprintf("Request [%d] %dV %d/%d mW\n",
			 max_i, sel_mv/1000, uw/1000, uw/1000);
	} else {
		int ma = 10 * (src_caps[max_i] & 0x3FF);
		*rdo = RDO_FIXED(max_i + 1, ma / 2, ma, 0);
		ccprintf("Request [%d] %dV %d/%d mA\n",
			 max_i, sel_mv/1000, max_i, ma/2, ma);
	}
	return EC_SUCCESS;
}
Exemplo n.º 2
0
int pd_choose_voltage_common(int cnt, uint32_t *src_caps, uint32_t *rdo,
			     uint32_t *curr_limit, uint32_t *supply_voltage,
			     int choose_min)
{
	int i;
	int sel_mv;
	int max_uw = 0;
	int max_ma;
	int max_i = -1;
	int max;
	uint32_t flags;

	/* Get max power */
	for (i = 0; i < cnt; i++) {
		int uw;
		int mv = ((src_caps[i] >> 10) & 0x3FF) * 50;
		if ((src_caps[i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
			uw = 250000 * (src_caps[i] & 0x3FF);
		} else {
			int ma = (src_caps[i] & 0x3FF) * 10;
			uw = ma * mv;
		}
		if ((uw > max_uw) && (mv <= max_mv)) {
			max_i = i;
			max_uw = uw;
			sel_mv = mv;
		}
		/*
		 * Choose the first entry if seaching for minimum, which will
		 * always be vSafe5V.
		 */
		if (choose_min)
			break;
	}
	if (max_i < 0)
		return -EC_ERROR_UNKNOWN;

	/* build rdo for desired power */
	if ((src_caps[max_i] & PDO_TYPE_MASK) == PDO_TYPE_BATTERY) {
		int uw = 250000 * (src_caps[max_i] & 0x3FF);
		max = MIN(1000 * uw, MAX_POWER_MW);
		flags = (max < OPERATING_POWER_MW) ? RDO_CAP_MISMATCH : 0;
		max_ma = 1000 * max / sel_mv;
		*rdo = RDO_BATT(max_i + 1, max, max, flags);
		CPRINTF("Request [%d] %dV %dmW",
			max_i, sel_mv/1000, max);
	} else {
		int ma = 10 * (src_caps[max_i] & 0x3FF);
		/*
		 * If we're choosing the minimum charge mode, limit our current
		 * to what we can set with ilim PWM (500mA)
		 */
		max = MIN(ma, choose_min ? CONFIG_CHARGER_INPUT_CURRENT :
					   MAX_CURRENT_MA);
		flags = (max * sel_mv) < (1000 * OPERATING_POWER_MW) ?
				RDO_CAP_MISMATCH : 0;
		max_ma = max;
		*rdo = RDO_FIXED(max_i + 1, max, max, flags);
		CPRINTF("Request [%d] %dV %dmA",
			max_i, sel_mv/1000, max);
	}
	/* Mismatch bit set if less power offered than the operating power */
	if (flags & RDO_CAP_MISMATCH)
		CPRINTF(" Mismatch");
	CPRINTF("\n");

	*curr_limit = max_ma;
	*supply_voltage = sel_mv;
	return EC_SUCCESS;
}