diff mbox series

[2/2] platform/chrome: cros_ec_typec: Register port altmodes

Message ID 20220712210318.2671292-2-pmalani@chromium.org (mailing list archive)
State Accepted
Commit 1ff5d97f070c31b0bac438034c64baa3f840f4da
Headers show
Series [1/2] platform/chrome: cros_ec_typec: Rename port altmode array | expand

Commit Message

Prashant Malani July 12, 2022, 9:03 p.m. UTC
Instead of using manually managed altmode structs, register the port's
altmodes with the Type-C framework. This facilitates matching them to
partner altmodes later.

Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Prashant Malani <pmalani@chromium.org>
---
 drivers/platform/chrome/cros_ec_typec.c | 51 +++++++++++++++++++------
 1 file changed, 40 insertions(+), 11 deletions(-)

Comments

Heikki Krogerus July 18, 2022, 8:38 a.m. UTC | #1
On Tue, Jul 12, 2022 at 09:03:18PM +0000, Prashant Malani wrote:
> Instead of using manually managed altmode structs, register the port's
> altmodes with the Type-C framework. This facilitates matching them to
> partner altmodes later.
> 
> Cc: Heikki Krogerus <heikki.krogerus@linux.intel.com>
> Signed-off-by: Prashant Malani <pmalani@chromium.org>

Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>

> ---
>  drivers/platform/chrome/cros_ec_typec.c | 51 +++++++++++++++++++------
>  1 file changed, 40 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
> index b9848e80f372..e67cccb9ac78 100644
> --- a/drivers/platform/chrome/cros_ec_typec.c
> +++ b/drivers/platform/chrome/cros_ec_typec.c
> @@ -25,6 +25,8 @@
>  
>  #define DRV_NAME "cros-ec-typec"
>  
> +#define DP_PORT_VDO	(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D) | DP_CAP_DFP_D)
> +
>  /* Supported alt modes. */
>  enum {
>  	CROS_EC_ALTMODE_DP = 0,
> @@ -60,7 +62,7 @@ struct cros_typec_port {
>  	uint8_t mux_flags;
>  	uint8_t role;
>  
> -	struct typec_altmode port_altmode[CROS_EC_ALTMODE_MAX];
> +	struct typec_altmode *port_altmode[CROS_EC_ALTMODE_MAX];
>  
>  	/* Flag indicating that PD partner discovery data parsing is completed. */
>  	bool sop_disc_done;
> @@ -253,6 +255,14 @@ static void cros_typec_remove_cable(struct cros_typec_data *typec,
>  	port->sop_prime_disc_done = false;
>  }
>  
> +static void cros_typec_unregister_port_altmodes(struct cros_typec_port *port)
> +{
> +	int i;
> +
> +	for (i = 0; i < CROS_EC_ALTMODE_MAX; i++)
> +		typec_unregister_altmode(port->port_altmode[i]);
> +}
> +
>  static void cros_unregister_ports(struct cros_typec_data *typec)
>  {
>  	int i;
> @@ -267,34 +277,49 @@ static void cros_unregister_ports(struct cros_typec_data *typec)
>  		usb_role_switch_put(typec->ports[i]->role_sw);
>  		typec_switch_put(typec->ports[i]->ori_sw);
>  		typec_mux_put(typec->ports[i]->mux);
> +		cros_typec_unregister_port_altmodes(typec->ports[i]);
>  		typec_unregister_port(typec->ports[i]->port);
>  	}
>  }
>  
>  /*
> - * Fake the alt mode structs until we actually start registering Type C port
> - * and partner alt modes.
> + * Register port alt modes with known values till we start retrieving
> + * port capabilities from the EC.
>   */
> -static void cros_typec_register_port_altmodes(struct cros_typec_data *typec,
> +static int cros_typec_register_port_altmodes(struct cros_typec_data *typec,
>  					      int port_num)
>  {
>  	struct cros_typec_port *port = typec->ports[port_num];
> +	struct typec_altmode_desc desc;
> +	struct typec_altmode *amode;
>  
>  	/* All PD capable CrOS devices are assumed to support DP altmode. */
> -	port->port_altmode[CROS_EC_ALTMODE_DP].svid = USB_TYPEC_DP_SID;
> -	port->port_altmode[CROS_EC_ALTMODE_DP].mode = USB_TYPEC_DP_MODE;
> +	desc.svid = USB_TYPEC_DP_SID,
> +	desc.mode = USB_TYPEC_DP_MODE,
> +	desc.vdo = DP_PORT_VDO,
> +	amode = typec_port_register_altmode(port->port, &desc);
> +	if (IS_ERR(amode))
> +		return PTR_ERR(amode);
> +	port->port_altmode[CROS_EC_ALTMODE_DP] = amode;
>  
>  	/*
>  	 * Register TBT compatibility alt mode. The EC will not enter the mode
>  	 * if it doesn't support it, so it's safe to register it unconditionally
>  	 * here for now.
>  	 */
> -	port->port_altmode[CROS_EC_ALTMODE_TBT].svid = USB_TYPEC_TBT_SID;
> -	port->port_altmode[CROS_EC_ALTMODE_TBT].mode = TYPEC_ANY_MODE;
> +	memset(&desc, 0, sizeof(desc));
> +	desc.svid = USB_TYPEC_TBT_SID,
> +	desc.mode = TYPEC_ANY_MODE,
> +	amode = typec_port_register_altmode(port->port, &desc);
> +	if (IS_ERR(amode))
> +		return PTR_ERR(amode);
> +	port->port_altmode[CROS_EC_ALTMODE_TBT] = amode;
>  
>  	port->state.alt = NULL;
>  	port->state.mode = TYPEC_STATE_USB;
>  	port->state.data = NULL;
> +
> +	return 0;
>  }
>  
>  static int cros_typec_init_ports(struct cros_typec_data *typec)
> @@ -361,7 +386,11 @@ static int cros_typec_init_ports(struct cros_typec_data *typec)
>  			dev_dbg(dev, "No switch control for port %d\n",
>  				port_num);
>  
> -		cros_typec_register_port_altmodes(typec, port_num);
> +		ret = cros_typec_register_port_altmodes(typec, port_num);
> +		if (ret) {
> +			dev_err(dev, "Failed to register port altmodes\n");
> +			goto unregister_ports;
> +		}
>  
>  		cros_port->disc_data = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
>  		if (!cros_port->disc_data) {
> @@ -430,7 +459,7 @@ static int cros_typec_enable_tbt(struct cros_typec_data *typec,
>  		data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
>  
>  	if (!port->state.alt) {
> -		port->state.alt = &port->port_altmode[CROS_EC_ALTMODE_TBT];
> +		port->state.alt = port->port_altmode[CROS_EC_ALTMODE_TBT];
>  		ret = cros_typec_usb_safe_state(port);
>  		if (ret)
>  			return ret;
> @@ -472,7 +501,7 @@ static int cros_typec_enable_dp(struct cros_typec_data *typec,
>  	/* Configuration VDO. */
>  	dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);
>  	if (!port->state.alt) {
> -		port->state.alt = &port->port_altmode[CROS_EC_ALTMODE_DP];
> +		port->state.alt = port->port_altmode[CROS_EC_ALTMODE_DP];
>  		ret = cros_typec_usb_safe_state(port);
>  		if (ret)
>  			return ret;
> -- 
> 2.37.0.144.g8ac04bfd2-goog
diff mbox series

Patch

diff --git a/drivers/platform/chrome/cros_ec_typec.c b/drivers/platform/chrome/cros_ec_typec.c
index b9848e80f372..e67cccb9ac78 100644
--- a/drivers/platform/chrome/cros_ec_typec.c
+++ b/drivers/platform/chrome/cros_ec_typec.c
@@ -25,6 +25,8 @@ 
 
 #define DRV_NAME "cros-ec-typec"
 
+#define DP_PORT_VDO	(BIT(DP_PIN_ASSIGN_C) | BIT(DP_PIN_ASSIGN_D) | DP_CAP_DFP_D)
+
 /* Supported alt modes. */
 enum {
 	CROS_EC_ALTMODE_DP = 0,
@@ -60,7 +62,7 @@  struct cros_typec_port {
 	uint8_t mux_flags;
 	uint8_t role;
 
-	struct typec_altmode port_altmode[CROS_EC_ALTMODE_MAX];
+	struct typec_altmode *port_altmode[CROS_EC_ALTMODE_MAX];
 
 	/* Flag indicating that PD partner discovery data parsing is completed. */
 	bool sop_disc_done;
@@ -253,6 +255,14 @@  static void cros_typec_remove_cable(struct cros_typec_data *typec,
 	port->sop_prime_disc_done = false;
 }
 
+static void cros_typec_unregister_port_altmodes(struct cros_typec_port *port)
+{
+	int i;
+
+	for (i = 0; i < CROS_EC_ALTMODE_MAX; i++)
+		typec_unregister_altmode(port->port_altmode[i]);
+}
+
 static void cros_unregister_ports(struct cros_typec_data *typec)
 {
 	int i;
@@ -267,34 +277,49 @@  static void cros_unregister_ports(struct cros_typec_data *typec)
 		usb_role_switch_put(typec->ports[i]->role_sw);
 		typec_switch_put(typec->ports[i]->ori_sw);
 		typec_mux_put(typec->ports[i]->mux);
+		cros_typec_unregister_port_altmodes(typec->ports[i]);
 		typec_unregister_port(typec->ports[i]->port);
 	}
 }
 
 /*
- * Fake the alt mode structs until we actually start registering Type C port
- * and partner alt modes.
+ * Register port alt modes with known values till we start retrieving
+ * port capabilities from the EC.
  */
-static void cros_typec_register_port_altmodes(struct cros_typec_data *typec,
+static int cros_typec_register_port_altmodes(struct cros_typec_data *typec,
 					      int port_num)
 {
 	struct cros_typec_port *port = typec->ports[port_num];
+	struct typec_altmode_desc desc;
+	struct typec_altmode *amode;
 
 	/* All PD capable CrOS devices are assumed to support DP altmode. */
-	port->port_altmode[CROS_EC_ALTMODE_DP].svid = USB_TYPEC_DP_SID;
-	port->port_altmode[CROS_EC_ALTMODE_DP].mode = USB_TYPEC_DP_MODE;
+	desc.svid = USB_TYPEC_DP_SID,
+	desc.mode = USB_TYPEC_DP_MODE,
+	desc.vdo = DP_PORT_VDO,
+	amode = typec_port_register_altmode(port->port, &desc);
+	if (IS_ERR(amode))
+		return PTR_ERR(amode);
+	port->port_altmode[CROS_EC_ALTMODE_DP] = amode;
 
 	/*
 	 * Register TBT compatibility alt mode. The EC will not enter the mode
 	 * if it doesn't support it, so it's safe to register it unconditionally
 	 * here for now.
 	 */
-	port->port_altmode[CROS_EC_ALTMODE_TBT].svid = USB_TYPEC_TBT_SID;
-	port->port_altmode[CROS_EC_ALTMODE_TBT].mode = TYPEC_ANY_MODE;
+	memset(&desc, 0, sizeof(desc));
+	desc.svid = USB_TYPEC_TBT_SID,
+	desc.mode = TYPEC_ANY_MODE,
+	amode = typec_port_register_altmode(port->port, &desc);
+	if (IS_ERR(amode))
+		return PTR_ERR(amode);
+	port->port_altmode[CROS_EC_ALTMODE_TBT] = amode;
 
 	port->state.alt = NULL;
 	port->state.mode = TYPEC_STATE_USB;
 	port->state.data = NULL;
+
+	return 0;
 }
 
 static int cros_typec_init_ports(struct cros_typec_data *typec)
@@ -361,7 +386,11 @@  static int cros_typec_init_ports(struct cros_typec_data *typec)
 			dev_dbg(dev, "No switch control for port %d\n",
 				port_num);
 
-		cros_typec_register_port_altmodes(typec, port_num);
+		ret = cros_typec_register_port_altmodes(typec, port_num);
+		if (ret) {
+			dev_err(dev, "Failed to register port altmodes\n");
+			goto unregister_ports;
+		}
 
 		cros_port->disc_data = devm_kzalloc(dev, EC_PROTO2_MAX_RESPONSE_SIZE, GFP_KERNEL);
 		if (!cros_port->disc_data) {
@@ -430,7 +459,7 @@  static int cros_typec_enable_tbt(struct cros_typec_data *typec,
 		data.enter_vdo |= TBT_ENTER_MODE_ACTIVE_CABLE;
 
 	if (!port->state.alt) {
-		port->state.alt = &port->port_altmode[CROS_EC_ALTMODE_TBT];
+		port->state.alt = port->port_altmode[CROS_EC_ALTMODE_TBT];
 		ret = cros_typec_usb_safe_state(port);
 		if (ret)
 			return ret;
@@ -472,7 +501,7 @@  static int cros_typec_enable_dp(struct cros_typec_data *typec,
 	/* Configuration VDO. */
 	dp_data.conf = DP_CONF_SET_PIN_ASSIGN(pd_ctrl->dp_mode);
 	if (!port->state.alt) {
-		port->state.alt = &port->port_altmode[CROS_EC_ALTMODE_DP];
+		port->state.alt = port->port_altmode[CROS_EC_ALTMODE_DP];
 		ret = cros_typec_usb_safe_state(port);
 		if (ret)
 			return ret;