Example #1
0
static int pd_send_host_command(struct ec_params_pd_status *ec_status,
	struct ec_response_pd_status *pd_status)
{
	int rv;

	rv = pd_host_command(EC_CMD_PD_EXCHANGE_STATUS, 1, ec_status,
			     sizeof(struct ec_params_pd_status), pd_status,
			     sizeof(struct ec_response_pd_status));

	/* If PD doesn't support new command version, try old version */
	if (rv == -EC_RES_INVALID_VERSION)
		rv = pd_host_command(EC_CMD_PD_EXCHANGE_STATUS, 0, ec_status,
			     sizeof(struct ec_params_pd_status), pd_status,
			     sizeof(struct ec_response_pd_status));
	return rv;
}
Example #2
0
static void pd_exchange_status(void)
{
	struct ec_params_pd_status ec_status;
	struct ec_response_pd_status pd_status;
	int rv = 0;
#ifdef CONFIG_HOSTCMD_PD_PANIC
	static int pd_in_rw;
#endif

	/* Send PD charge state and battery state of charge */
	ec_status.charge_state = charge_state;
	if (charge_get_flags() & CHARGE_FLAG_BATT_RESPONSIVE)
		ec_status.batt_soc = charge_get_percent();
	else
		ec_status.batt_soc = -1;

	rv = pd_host_command(EC_CMD_PD_EXCHANGE_STATUS, 1, &ec_status,
			     sizeof(struct ec_params_pd_status), &pd_status,
			     sizeof(struct ec_response_pd_status));

	/* If PD doesn't support new command version, try old version */
	if (rv == -EC_RES_INVALID_VERSION)
		rv = pd_host_command(EC_CMD_PD_EXCHANGE_STATUS, 0, &ec_status,
			     sizeof(struct ec_params_pd_status), &pd_status,
			     sizeof(struct ec_response_pd_status));

	if (rv < 0) {
		CPRINTS("Host command to PD MCU failed");
		return;
	}

#ifdef CONFIG_HOSTCMD_PD_PANIC
	/*
	 * Check if PD MCU is in RW. If PD MCU was in RW and is now in RO
	 * AND it did not sysjump to RO, then it must have crashed, and
	 * therefore we should panic as well.
	 */
	if (pd_status.status & PD_STATUS_IN_RW) {
		pd_in_rw = 1;
	} else if (pd_in_rw &&
		   !(pd_status.status & PD_STATUS_JUMPED_TO_IMAGE)) {
		panic_printf("PD crash");
		software_panic(PANIC_SW_PD_CRASH, 0);
	}
#endif

#ifdef HAS_TASK_LIGHTBAR
	/*
	 * If charge port has changed, and it was initialized, then show
	 * battery status on lightbar.
	 */
	if (pd_status.active_charge_port != charge_port) {
		if (charge_port != CHARGE_PORT_UNINITIALIZED) {
			charge_port = pd_status.active_charge_port;
			lightbar_sequence(LIGHTBAR_TAP);
		} else {
			charge_port = pd_status.active_charge_port;
		}
	}
#else
	/* Store the active charge port */
	charge_port = pd_status.active_charge_port;
#endif

	/* Set input current limit */
	rv = charge_set_input_current_limit(MAX(pd_status.curr_lim_ma,
					CONFIG_CHARGER_INPUT_CURRENT));
	if (rv < 0)
		CPRINTS("Failed to set input current limit from PD MCU");

	/* If PD is signalling host event, then pass it up to AP */
	if (pd_status.status & PD_STATUS_HOST_EVENT)
		host_set_single_event(EC_HOST_EVENT_PD_MCU);
}