chrome platform changes for 5.11
cros_ec_typec: * A series from Prashant for Type-C to implement TYPEC_STATUS, parsing USB PD Partner ID VDOs, and registering partner altmodes. cros_ec misc: * Don't treat RTC events as wakeup sources in cros_ec_proto -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQQCtZK6p/AktxXfkOlzbaomhzOwwgUCX+JsPAAKCRBzbaomhzOw woHeAQD0j6D+m38NgLKr3mwVqkSwaHW7/NNmDIdXBikrRgiw0AD/c/kMZzSzwCGV hgSOjg3A4uPq1gyDAW+wYmjngylv3g0= =hT9E -----END PGP SIGNATURE----- Merge tag 'tag-chrome-platform-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux Pull chrome platform updates from Benson Leung: "cros_ec_typec: - A series from Prashant for Type-C to implement TYPEC_STATUS, parsing USB PD Partner ID VDOs, and registering partner altmodes. cros_ec misc: - Don't treat RTC events as wakeup sources in cros_ec_proto" * tag 'tag-chrome-platform-for-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux: platform/chrome: cros_ec_typec: Tolerate unrecognized mux flags platform/chrome: cros_ec_typec: Register partner altmodes platform/chrome: cros_ec_typec: Parse partner PD ID VDOs platform/chrome: cros_ec_typec: Introduce TYPEC_STATUS platform/chrome: cros_ec: Import Type C host commands platform/chrome: cros_ec_typec: Clear partner identity on device removal platform/chrome: cros_ec_typec: Fix remove partner logic platform/chrome: cros_ec_typec: Relocate set_port_params_v*() functions platform/chrome: Don't treat RTC events as wakeup sources
This commit is contained in:
Коммит
a088159675
|
@ -742,12 +742,16 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
|
|||
* Sensor events need to be parsed by the sensor sub-device.
|
||||
* Defer them, and don't report the wakeup here.
|
||||
*/
|
||||
if (event_type == EC_MKBP_EVENT_SENSOR_FIFO)
|
||||
*wake_event = false;
|
||||
/* Masked host-events should not count as wake events. */
|
||||
else if (host_event &&
|
||||
!(host_event & ec_dev->host_event_wake_mask))
|
||||
if (event_type == EC_MKBP_EVENT_SENSOR_FIFO) {
|
||||
*wake_event = false;
|
||||
} else if (host_event) {
|
||||
/* rtc_update_irq() already handles wakeup events. */
|
||||
if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_RTC))
|
||||
*wake_event = false;
|
||||
/* Masked host-events should not count as wake events. */
|
||||
if (!(host_event & ec_dev->host_event_wake_mask))
|
||||
*wake_event = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_data/cros_ec_commands.h>
|
||||
|
@ -14,6 +15,7 @@
|
|||
#include <linux/platform_data/cros_usbpd_notify.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/usb/pd.h>
|
||||
#include <linux/usb/pd_vdo.h>
|
||||
#include <linux/usb/typec.h>
|
||||
#include <linux/usb/typec_altmode.h>
|
||||
#include <linux/usb/typec_dp.h>
|
||||
|
@ -30,6 +32,12 @@ enum {
|
|||
CROS_EC_ALTMODE_MAX,
|
||||
};
|
||||
|
||||
/* Container for altmode pointer nodes. */
|
||||
struct cros_typec_altmode_node {
|
||||
struct typec_altmode *amode;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* Per port data. */
|
||||
struct cros_typec_port {
|
||||
struct typec_port *port;
|
||||
|
@ -48,6 +56,11 @@ struct cros_typec_port {
|
|||
|
||||
/* Port alt modes. */
|
||||
struct typec_altmode p_altmode[CROS_EC_ALTMODE_MAX];
|
||||
|
||||
/* Flag indicating that PD discovery data parsing is completed. */
|
||||
bool disc_done;
|
||||
struct ec_response_typec_discovery *sop_disc;
|
||||
struct list_head partner_mode_list;
|
||||
};
|
||||
|
||||
/* Platform-specific data for the Chrome OS EC Type C controller. */
|
||||
|
@ -60,6 +73,7 @@ struct cros_typec_data {
|
|||
struct cros_typec_port *ports[EC_USB_PD_MAX_PORTS];
|
||||
struct notifier_block nb;
|
||||
struct work_struct port_work;
|
||||
bool typec_cmd_supported;
|
||||
};
|
||||
|
||||
static int cros_typec_parse_port_props(struct typec_capability *cap,
|
||||
|
@ -166,11 +180,25 @@ static int cros_typec_add_partner(struct cros_typec_data *typec, int port_num,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void cros_typec_unregister_altmodes(struct cros_typec_data *typec, int port_num)
|
||||
{
|
||||
struct cros_typec_port *port = typec->ports[port_num];
|
||||
struct cros_typec_altmode_node *node, *tmp;
|
||||
|
||||
list_for_each_entry_safe(node, tmp, &port->partner_mode_list, list) {
|
||||
list_del(&node->list);
|
||||
typec_unregister_altmode(node->amode);
|
||||
devm_kfree(typec->dev, node);
|
||||
}
|
||||
}
|
||||
|
||||
static void cros_typec_remove_partner(struct cros_typec_data *typec,
|
||||
int port_num)
|
||||
{
|
||||
struct cros_typec_port *port = typec->ports[port_num];
|
||||
|
||||
cros_typec_unregister_altmodes(typec, port_num);
|
||||
|
||||
port->state.alt = NULL;
|
||||
port->state.mode = TYPEC_STATE_USB;
|
||||
port->state.data = NULL;
|
||||
|
@ -181,6 +209,8 @@ static void cros_typec_remove_partner(struct cros_typec_data *typec,
|
|||
|
||||
typec_unregister_partner(port->partner);
|
||||
port->partner = NULL;
|
||||
memset(&port->p_identity, 0, sizeof(port->p_identity));
|
||||
port->disc_done = false;
|
||||
}
|
||||
|
||||
static void cros_unregister_ports(struct cros_typec_data *typec)
|
||||
|
@ -190,7 +220,10 @@ static void cros_unregister_ports(struct cros_typec_data *typec)
|
|||
for (i = 0; i < typec->num_ports; i++) {
|
||||
if (!typec->ports[i])
|
||||
continue;
|
||||
cros_typec_remove_partner(typec, i);
|
||||
|
||||
if (typec->ports[i]->partner)
|
||||
cros_typec_remove_partner(typec, i);
|
||||
|
||||
usb_role_switch_put(typec->ports[i]->role_sw);
|
||||
typec_switch_put(typec->ports[i]->ori_sw);
|
||||
typec_mux_put(typec->ports[i]->mux);
|
||||
|
@ -289,6 +322,14 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
|
|||
port_num);
|
||||
|
||||
cros_typec_register_port_altmodes(typec, port_num);
|
||||
|
||||
cros_port->sop_disc = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
|
||||
if (!cros_port->sop_disc) {
|
||||
ret = -ENOMEM;
|
||||
goto unregister_ports;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&cros_port->partner_mode_list);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -329,74 +370,6 @@ static int cros_typec_ec_command(struct cros_typec_data *typec,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void cros_typec_set_port_params_v0(struct cros_typec_data *typec,
|
||||
int port_num, struct ec_response_usb_pd_control *resp)
|
||||
{
|
||||
struct typec_port *port = typec->ports[port_num]->port;
|
||||
enum typec_orientation polarity;
|
||||
|
||||
if (!resp->enabled)
|
||||
polarity = TYPEC_ORIENTATION_NONE;
|
||||
else if (!resp->polarity)
|
||||
polarity = TYPEC_ORIENTATION_NORMAL;
|
||||
else
|
||||
polarity = TYPEC_ORIENTATION_REVERSE;
|
||||
|
||||
typec_set_pwr_role(port, resp->role ? TYPEC_SOURCE : TYPEC_SINK);
|
||||
typec_set_orientation(port, polarity);
|
||||
}
|
||||
|
||||
static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
|
||||
int port_num, struct ec_response_usb_pd_control_v1 *resp)
|
||||
{
|
||||
struct typec_port *port = typec->ports[port_num]->port;
|
||||
enum typec_orientation polarity;
|
||||
bool pd_en;
|
||||
int ret;
|
||||
|
||||
if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED))
|
||||
polarity = TYPEC_ORIENTATION_NONE;
|
||||
else if (!resp->polarity)
|
||||
polarity = TYPEC_ORIENTATION_NORMAL;
|
||||
else
|
||||
polarity = TYPEC_ORIENTATION_REVERSE;
|
||||
typec_set_orientation(port, polarity);
|
||||
typec_set_data_role(port, resp->role & PD_CTRL_RESP_ROLE_DATA ?
|
||||
TYPEC_HOST : TYPEC_DEVICE);
|
||||
typec_set_pwr_role(port, resp->role & PD_CTRL_RESP_ROLE_POWER ?
|
||||
TYPEC_SOURCE : TYPEC_SINK);
|
||||
typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ?
|
||||
TYPEC_SOURCE : TYPEC_SINK);
|
||||
|
||||
/* Register/remove partners when a connect/disconnect occurs. */
|
||||
if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) {
|
||||
if (typec->ports[port_num]->partner)
|
||||
return;
|
||||
|
||||
pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE;
|
||||
ret = cros_typec_add_partner(typec, port_num, pd_en);
|
||||
if (ret)
|
||||
dev_warn(typec->dev,
|
||||
"Failed to register partner on port: %d\n",
|
||||
port_num);
|
||||
} else {
|
||||
if (!typec->ports[port_num]->partner)
|
||||
return;
|
||||
cros_typec_remove_partner(typec, port_num);
|
||||
}
|
||||
}
|
||||
|
||||
static int cros_typec_get_mux_info(struct cros_typec_data *typec, int port_num,
|
||||
struct ec_response_usb_pd_mux_info *resp)
|
||||
{
|
||||
struct ec_params_usb_pd_mux_info req = {
|
||||
.port = port_num,
|
||||
};
|
||||
|
||||
return cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_MUX_INFO, &req,
|
||||
sizeof(req), resp, sizeof(*resp));
|
||||
}
|
||||
|
||||
static int cros_typec_usb_safe_state(struct cros_typec_port *port)
|
||||
{
|
||||
port->state.mode = TYPEC_STATE_SAFE;
|
||||
|
@ -563,15 +536,210 @@ static int cros_typec_configure_mux(struct cros_typec_data *typec, int port_num,
|
|||
port->state.mode = TYPEC_STATE_USB;
|
||||
ret = typec_mux_set(port->mux, &port->state);
|
||||
} else {
|
||||
dev_info(typec->dev,
|
||||
"Unsupported mode requested, mux flags: %x\n",
|
||||
mux_flags);
|
||||
ret = -ENOTSUPP;
|
||||
dev_dbg(typec->dev,
|
||||
"Unrecognized mode requested, mux flags: %x\n",
|
||||
mux_flags);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cros_typec_set_port_params_v0(struct cros_typec_data *typec,
|
||||
int port_num, struct ec_response_usb_pd_control *resp)
|
||||
{
|
||||
struct typec_port *port = typec->ports[port_num]->port;
|
||||
enum typec_orientation polarity;
|
||||
|
||||
if (!resp->enabled)
|
||||
polarity = TYPEC_ORIENTATION_NONE;
|
||||
else if (!resp->polarity)
|
||||
polarity = TYPEC_ORIENTATION_NORMAL;
|
||||
else
|
||||
polarity = TYPEC_ORIENTATION_REVERSE;
|
||||
|
||||
typec_set_pwr_role(port, resp->role ? TYPEC_SOURCE : TYPEC_SINK);
|
||||
typec_set_orientation(port, polarity);
|
||||
}
|
||||
|
||||
static void cros_typec_set_port_params_v1(struct cros_typec_data *typec,
|
||||
int port_num, struct ec_response_usb_pd_control_v1 *resp)
|
||||
{
|
||||
struct typec_port *port = typec->ports[port_num]->port;
|
||||
enum typec_orientation polarity;
|
||||
bool pd_en;
|
||||
int ret;
|
||||
|
||||
if (!(resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED))
|
||||
polarity = TYPEC_ORIENTATION_NONE;
|
||||
else if (!resp->polarity)
|
||||
polarity = TYPEC_ORIENTATION_NORMAL;
|
||||
else
|
||||
polarity = TYPEC_ORIENTATION_REVERSE;
|
||||
typec_set_orientation(port, polarity);
|
||||
typec_set_data_role(port, resp->role & PD_CTRL_RESP_ROLE_DATA ?
|
||||
TYPEC_HOST : TYPEC_DEVICE);
|
||||
typec_set_pwr_role(port, resp->role & PD_CTRL_RESP_ROLE_POWER ?
|
||||
TYPEC_SOURCE : TYPEC_SINK);
|
||||
typec_set_vconn_role(port, resp->role & PD_CTRL_RESP_ROLE_VCONN ?
|
||||
TYPEC_SOURCE : TYPEC_SINK);
|
||||
|
||||
/* Register/remove partners when a connect/disconnect occurs. */
|
||||
if (resp->enabled & PD_CTRL_RESP_ENABLED_CONNECTED) {
|
||||
if (typec->ports[port_num]->partner)
|
||||
return;
|
||||
|
||||
pd_en = resp->enabled & PD_CTRL_RESP_ENABLED_PD_CAPABLE;
|
||||
ret = cros_typec_add_partner(typec, port_num, pd_en);
|
||||
if (ret)
|
||||
dev_warn(typec->dev,
|
||||
"Failed to register partner on port: %d\n",
|
||||
port_num);
|
||||
} else {
|
||||
if (!typec->ports[port_num]->partner)
|
||||
return;
|
||||
cros_typec_remove_partner(typec, port_num);
|
||||
}
|
||||
}
|
||||
|
||||
static int cros_typec_get_mux_info(struct cros_typec_data *typec, int port_num,
|
||||
struct ec_response_usb_pd_mux_info *resp)
|
||||
{
|
||||
struct ec_params_usb_pd_mux_info req = {
|
||||
.port = port_num,
|
||||
};
|
||||
|
||||
return cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_MUX_INFO, &req,
|
||||
sizeof(req), resp, sizeof(*resp));
|
||||
}
|
||||
|
||||
static int cros_typec_register_altmodes(struct cros_typec_data *typec, int port_num)
|
||||
{
|
||||
struct cros_typec_port *port = typec->ports[port_num];
|
||||
struct ec_response_typec_discovery *sop_disc = port->sop_disc;
|
||||
struct cros_typec_altmode_node *node;
|
||||
struct typec_altmode_desc desc;
|
||||
struct typec_altmode *amode;
|
||||
int ret = 0;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < sop_disc->svid_count; i++) {
|
||||
for (j = 0; j < sop_disc->svids[i].mode_count; j++) {
|
||||
memset(&desc, 0, sizeof(desc));
|
||||
desc.svid = sop_disc->svids[i].svid;
|
||||
desc.mode = j;
|
||||
desc.vdo = sop_disc->svids[i].mode_vdo[j];
|
||||
|
||||
amode = typec_partner_register_altmode(port->partner, &desc);
|
||||
if (IS_ERR(amode)) {
|
||||
ret = PTR_ERR(amode);
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
/* If no memory is available we should unregister and exit. */
|
||||
node = devm_kzalloc(typec->dev, sizeof(*node), GFP_KERNEL);
|
||||
if (!node) {
|
||||
ret = -ENOMEM;
|
||||
typec_unregister_altmode(amode);
|
||||
goto err_cleanup;
|
||||
}
|
||||
|
||||
node->amode = amode;
|
||||
list_add_tail(&node->list, &port->partner_mode_list);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup:
|
||||
cros_typec_unregister_altmodes(typec, port_num);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cros_typec_handle_sop_disc(struct cros_typec_data *typec, int port_num)
|
||||
{
|
||||
struct cros_typec_port *port = typec->ports[port_num];
|
||||
struct ec_response_typec_discovery *sop_disc = port->sop_disc;
|
||||
struct ec_params_typec_discovery req = {
|
||||
.port = port_num,
|
||||
.partner_type = TYPEC_PARTNER_SOP,
|
||||
};
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
if (!port->partner) {
|
||||
dev_err(typec->dev,
|
||||
"SOP Discovery received without partner registered, port: %d\n",
|
||||
port_num);
|
||||
ret = -EINVAL;
|
||||
goto disc_exit;
|
||||
}
|
||||
|
||||
memset(sop_disc, 0, EC_PROTO2_MAX_RESPONSE_SIZE);
|
||||
ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_DISCOVERY, &req, sizeof(req),
|
||||
sop_disc, EC_PROTO2_MAX_RESPONSE_SIZE);
|
||||
if (ret < 0) {
|
||||
dev_err(typec->dev, "Failed to get SOP discovery data for port: %d\n", port_num);
|
||||
goto disc_exit;
|
||||
}
|
||||
|
||||
/* First, update the PD identity VDOs for the partner. */
|
||||
if (sop_disc->identity_count > 0)
|
||||
port->p_identity.id_header = sop_disc->discovery_vdo[0];
|
||||
if (sop_disc->identity_count > 1)
|
||||
port->p_identity.cert_stat = sop_disc->discovery_vdo[1];
|
||||
if (sop_disc->identity_count > 2)
|
||||
port->p_identity.product = sop_disc->discovery_vdo[2];
|
||||
|
||||
/* Copy the remaining identity VDOs till a maximum of 6. */
|
||||
for (i = 3; i < sop_disc->identity_count && i < VDO_MAX_OBJECTS; i++)
|
||||
port->p_identity.vdo[i - 3] = sop_disc->discovery_vdo[i];
|
||||
|
||||
ret = typec_partner_set_identity(port->partner);
|
||||
if (ret < 0) {
|
||||
dev_err(typec->dev, "Failed to update partner PD identity, port: %d\n", port_num);
|
||||
goto disc_exit;
|
||||
}
|
||||
|
||||
ret = cros_typec_register_altmodes(typec, port_num);
|
||||
if (ret < 0) {
|
||||
dev_err(typec->dev, "Failed to register partner altmodes, port: %d\n", port_num);
|
||||
goto disc_exit;
|
||||
}
|
||||
|
||||
disc_exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cros_typec_handle_status(struct cros_typec_data *typec, int port_num)
|
||||
{
|
||||
struct ec_response_typec_status resp;
|
||||
struct ec_params_typec_status req = {
|
||||
.port = port_num,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = cros_typec_ec_command(typec, 0, EC_CMD_TYPEC_STATUS, &req, sizeof(req),
|
||||
&resp, sizeof(resp));
|
||||
if (ret < 0) {
|
||||
dev_warn(typec->dev, "EC_CMD_TYPEC_STATUS failed for port: %d\n", port_num);
|
||||
return;
|
||||
}
|
||||
|
||||
if (typec->ports[port_num]->disc_done)
|
||||
return;
|
||||
|
||||
/* Handle any events appropriately. */
|
||||
if (resp.events & PD_STATUS_EVENT_SOP_DISC_DONE) {
|
||||
ret = cros_typec_handle_sop_disc(typec, port_num);
|
||||
if (ret < 0) {
|
||||
dev_err(typec->dev, "Couldn't parse SOP Disc data, port: %d\n", port_num);
|
||||
return;
|
||||
}
|
||||
|
||||
typec->ports[port_num]->disc_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
static int cros_typec_port_update(struct cros_typec_data *typec, int port_num)
|
||||
{
|
||||
struct ec_params_usb_pd_control req;
|
||||
|
@ -608,6 +776,9 @@ static int cros_typec_port_update(struct cros_typec_data *typec, int port_num)
|
|||
cros_typec_set_port_params_v0(typec, port_num,
|
||||
(struct ec_response_usb_pd_control *) &resp);
|
||||
|
||||
if (typec->typec_cmd_supported)
|
||||
cros_typec_handle_status(typec, port_num);
|
||||
|
||||
/* Update the switches if they exist, according to requested state */
|
||||
ret = cros_typec_get_mux_info(typec, port_num, &mux_resp);
|
||||
if (ret < 0) {
|
||||
|
@ -656,6 +827,23 @@ static int cros_typec_get_cmd_version(struct cros_typec_data *typec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Check the EC feature flags to see if TYPEC_* commands are supported. */
|
||||
static int cros_typec_cmds_supported(struct cros_typec_data *typec)
|
||||
{
|
||||
struct ec_response_get_features resp = {};
|
||||
int ret;
|
||||
|
||||
ret = cros_typec_ec_command(typec, 0, EC_CMD_GET_FEATURES, NULL, 0,
|
||||
&resp, sizeof(resp));
|
||||
if (ret < 0) {
|
||||
dev_warn(typec->dev,
|
||||
"Failed to get features, assuming typec commands unsupported.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return resp.flags[EC_FEATURE_TYPEC_CMD / 32] & EC_FEATURE_MASK_1(EC_FEATURE_TYPEC_CMD);
|
||||
}
|
||||
|
||||
static void cros_typec_port_work(struct work_struct *work)
|
||||
{
|
||||
struct cros_typec_data *typec = container_of(work, struct cros_typec_data, port_work);
|
||||
|
@ -715,6 +903,8 @@ static int cros_typec_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
typec->typec_cmd_supported = !!cros_typec_cmds_supported(typec);
|
||||
|
||||
ret = cros_typec_ec_command(typec, 0, EC_CMD_USB_PD_PORTS, NULL, 0,
|
||||
&resp, sizeof(resp));
|
||||
if (ret < 0)
|
||||
|
|
|
@ -1284,6 +1284,8 @@ enum ec_feature_code {
|
|||
EC_FEATURE_SCP = 39,
|
||||
/* The MCU is an Integrated Sensor Hub */
|
||||
EC_FEATURE_ISH = 40,
|
||||
/* New TCPMv2 TYPEC_ prefaced commands supported */
|
||||
EC_FEATURE_TYPEC_CMD = 41,
|
||||
};
|
||||
|
||||
#define EC_FEATURE_MASK_0(event_code) BIT(event_code % 32)
|
||||
|
@ -5528,6 +5530,159 @@ struct ec_response_regulator_get_voltage {
|
|||
uint32_t voltage_mv;
|
||||
} __ec_align4;
|
||||
|
||||
/*
|
||||
* Gather all discovery information for the given port and partner type.
|
||||
*
|
||||
* Note that if discovery has not yet completed, only the currently completed
|
||||
* responses will be filled in. If the discovery data structures are changed
|
||||
* in the process of the command running, BUSY will be returned.
|
||||
*
|
||||
* VDO field sizes are set to the maximum possible number of VDOs a VDM may
|
||||
* contain, while the number of SVIDs here is selected to fit within the PROTO2
|
||||
* maximum parameter size.
|
||||
*/
|
||||
#define EC_CMD_TYPEC_DISCOVERY 0x0131
|
||||
|
||||
enum typec_partner_type {
|
||||
TYPEC_PARTNER_SOP = 0,
|
||||
TYPEC_PARTNER_SOP_PRIME = 1,
|
||||
};
|
||||
|
||||
struct ec_params_typec_discovery {
|
||||
uint8_t port;
|
||||
uint8_t partner_type; /* enum typec_partner_type */
|
||||
} __ec_align1;
|
||||
|
||||
struct svid_mode_info {
|
||||
uint16_t svid;
|
||||
uint16_t mode_count; /* Number of modes partner sent */
|
||||
uint32_t mode_vdo[6]; /* Max VDOs allowed after VDM header is 6 */
|
||||
};
|
||||
|
||||
struct ec_response_typec_discovery {
|
||||
uint8_t identity_count; /* Number of identity VDOs partner sent */
|
||||
uint8_t svid_count; /* Number of SVIDs partner sent */
|
||||
uint16_t reserved;
|
||||
uint32_t discovery_vdo[6]; /* Max VDOs allowed after VDM header is 6 */
|
||||
struct svid_mode_info svids[0];
|
||||
} __ec_align1;
|
||||
|
||||
/*
|
||||
* Gather all status information for a port.
|
||||
*
|
||||
* Note: this covers many of the return fields from the deprecated
|
||||
* EC_CMD_USB_PD_CONTROL command, except those that are redundant with the
|
||||
* discovery data. The "enum pd_cc_states" is defined with the deprecated
|
||||
* EC_CMD_USB_PD_CONTROL command.
|
||||
*
|
||||
* This also combines in the EC_CMD_USB_PD_MUX_INFO flags.
|
||||
*/
|
||||
#define EC_CMD_TYPEC_STATUS 0x0133
|
||||
|
||||
/*
|
||||
* Power role.
|
||||
*
|
||||
* Note this is also used for PD header creation, and values align to those in
|
||||
* the Power Delivery Specification Revision 3.0 (See
|
||||
* 6.2.1.1.4 Port Power Role).
|
||||
*/
|
||||
enum pd_power_role {
|
||||
PD_ROLE_SINK = 0,
|
||||
PD_ROLE_SOURCE = 1
|
||||
};
|
||||
|
||||
/*
|
||||
* Data role.
|
||||
*
|
||||
* Note this is also used for PD header creation, and the first two values
|
||||
* align to those in the Power Delivery Specification Revision 3.0 (See
|
||||
* 6.2.1.1.6 Port Data Role).
|
||||
*/
|
||||
enum pd_data_role {
|
||||
PD_ROLE_UFP = 0,
|
||||
PD_ROLE_DFP = 1,
|
||||
PD_ROLE_DISCONNECTED = 2,
|
||||
};
|
||||
|
||||
enum pd_vconn_role {
|
||||
PD_ROLE_VCONN_OFF = 0,
|
||||
PD_ROLE_VCONN_SRC = 1,
|
||||
};
|
||||
|
||||
/*
|
||||
* Note: BIT(0) may be used to determine whether the polarity is CC1 or CC2,
|
||||
* regardless of whether a debug accessory is connected.
|
||||
*/
|
||||
enum tcpc_cc_polarity {
|
||||
/*
|
||||
* _CCx: is used to indicate the polarity while not connected to
|
||||
* a Debug Accessory. Only one CC line will assert a resistor and
|
||||
* the other will be open.
|
||||
*/
|
||||
POLARITY_CC1 = 0,
|
||||
POLARITY_CC2 = 1,
|
||||
|
||||
/*
|
||||
* _CCx_DTS is used to indicate the polarity while connected to a
|
||||
* SRC Debug Accessory. Assert resistors on both lines.
|
||||
*/
|
||||
POLARITY_CC1_DTS = 2,
|
||||
POLARITY_CC2_DTS = 3,
|
||||
|
||||
/*
|
||||
* The current TCPC code relies on these specific POLARITY values.
|
||||
* Adding in a check to verify if the list grows for any reason
|
||||
* that this will give a hint that other places need to be
|
||||
* adjusted.
|
||||
*/
|
||||
POLARITY_COUNT
|
||||
};
|
||||
|
||||
#define PD_STATUS_EVENT_SOP_DISC_DONE BIT(0)
|
||||
#define PD_STATUS_EVENT_SOP_PRIME_DISC_DONE BIT(1)
|
||||
|
||||
struct ec_params_typec_status {
|
||||
uint8_t port;
|
||||
} __ec_align1;
|
||||
|
||||
struct ec_response_typec_status {
|
||||
uint8_t pd_enabled; /* PD communication enabled - bool */
|
||||
uint8_t dev_connected; /* Device connected - bool */
|
||||
uint8_t sop_connected; /* Device is SOP PD capable - bool */
|
||||
uint8_t source_cap_count; /* Number of Source Cap PDOs */
|
||||
|
||||
uint8_t power_role; /* enum pd_power_role */
|
||||
uint8_t data_role; /* enum pd_data_role */
|
||||
uint8_t vconn_role; /* enum pd_vconn_role */
|
||||
uint8_t sink_cap_count; /* Number of Sink Cap PDOs */
|
||||
|
||||
uint8_t polarity; /* enum tcpc_cc_polarity */
|
||||
uint8_t cc_state; /* enum pd_cc_states */
|
||||
uint8_t dp_pin; /* DP pin mode (MODE_DP_IN_[A-E]) */
|
||||
uint8_t mux_state; /* USB_PD_MUX* - encoded mux state */
|
||||
|
||||
char tc_state[32]; /* TC state name */
|
||||
|
||||
uint32_t events; /* PD_STATUS_EVENT bitmask */
|
||||
|
||||
/*
|
||||
* BCD PD revisions for partners
|
||||
*
|
||||
* The format has the PD major reversion in the upper nibble, and PD
|
||||
* minor version in the next nibble. Following two nibbles are
|
||||
* currently 0.
|
||||
* ex. PD 3.2 would map to 0x3200
|
||||
*
|
||||
* PD major/minor will be 0 if no PD device is connected.
|
||||
*/
|
||||
uint16_t sop_revision;
|
||||
uint16_t sop_prime_revision;
|
||||
|
||||
uint32_t source_cap_pdos[7]; /* Max 7 PDOs can be present */
|
||||
|
||||
uint32_t sink_cap_pdos[7]; /* Max 7 PDOs can be present */
|
||||
} __ec_align1;
|
||||
|
||||
/*****************************************************************************/
|
||||
/* The command range 0x200-0x2FF is reserved for Rotor. */
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче