summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2018-03-20 08:57:06 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-03-22 08:40:10 -0400
commitc6962c29729cc64177f56a466766daa7de9f87ac (patch)
treec08521ad2213d5a7086ab56f3dbb7078b17c19b1
parentceeb162500c3480b660a47d509db7955a7913271 (diff)
usb: typec: tcpm: Set USB role switch to device mode when configured as such
Setting the mux to MUX_NONE and the switch to USB_SWITCH_DISCONNECT when the data-role is device is not correct. Plenty of devices support operating as USB device through a (separate) USB device controller. We really need 2 different versions of USB_SWITCH_CONNECT, USB_SWITCH_CONNECT_HOST and USB_SWITCH_DEVICE. Rather then modifying the tcpc_usb_switch enum for this, simply remove it and switch to the usb_role enum which provides exactly this, this will save use needing to convert betweent the 2 enums when calling an usb-role-switch driver later. Besides switching to the usb_role type, this commit also actually sets the mux to TYPEC_MUX_USB and the switch to USB_ROLE_DEVICE instead of setting both to none when the data-role is device. This commit also makes tcpm_reset_port() call tcpm_mux_set(port, TYPEC_MUX_NONE, USB_ROLE_NONE) so that the mux and switch do _not_ stay in their last mode after a detach. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/typec/tcpm.c22
-rw-r--r--include/linux/usb/tcpm.h8
2 files changed, 13 insertions, 17 deletions
diff --git a/drivers/usb/typec/tcpm.c b/drivers/usb/typec/tcpm.c
index 62e710bb6367..2519b0d17f1f 100644
--- a/drivers/usb/typec/tcpm.c
+++ b/drivers/usb/typec/tcpm.c
@@ -604,15 +604,15 @@ void tcpm_pd_transmit_complete(struct tcpm_port *port,
604EXPORT_SYMBOL_GPL(tcpm_pd_transmit_complete); 604EXPORT_SYMBOL_GPL(tcpm_pd_transmit_complete);
605 605
606static int tcpm_mux_set(struct tcpm_port *port, enum tcpc_mux_mode mode, 606static int tcpm_mux_set(struct tcpm_port *port, enum tcpc_mux_mode mode,
607 enum tcpc_usb_switch config) 607 enum usb_role usb_role)
608{ 608{
609 int ret = 0; 609 int ret = 0;
610 610
611 tcpm_log(port, "Requesting mux mode %d, config %d, polarity %d", 611 tcpm_log(port, "Requesting mux mode %d, usb-role %d, polarity %d",
612 mode, config, port->polarity); 612 mode, usb_role, port->polarity);
613 613
614 if (port->tcpc->mux) 614 if (port->tcpc->mux)
615 ret = port->tcpc->mux->set(port->tcpc->mux, mode, config, 615 ret = port->tcpc->mux->set(port->tcpc->mux, mode, usb_role,
616 port->polarity); 616 port->polarity);
617 617
618 return ret; 618 return ret;
@@ -728,14 +728,15 @@ static int tcpm_set_attached_state(struct tcpm_port *port, bool attached)
728static int tcpm_set_roles(struct tcpm_port *port, bool attached, 728static int tcpm_set_roles(struct tcpm_port *port, bool attached,
729 enum typec_role role, enum typec_data_role data) 729 enum typec_role role, enum typec_data_role data)
730{ 730{
731 enum usb_role usb_role;
731 int ret; 732 int ret;
732 733
733 if (data == TYPEC_HOST) 734 if (data == TYPEC_HOST)
734 ret = tcpm_mux_set(port, TYPEC_MUX_USB, 735 usb_role = USB_ROLE_HOST;
735 TCPC_USB_SWITCH_CONNECT);
736 else 736 else
737 ret = tcpm_mux_set(port, TYPEC_MUX_NONE, 737 usb_role = USB_ROLE_DEVICE;
738 TCPC_USB_SWITCH_DISCONNECT); 738
739 ret = tcpm_mux_set(port, TYPEC_MUX_USB, usb_role);
739 if (ret < 0) 740 if (ret < 0)
740 return ret; 741 return ret;
741 742
@@ -2028,7 +2029,7 @@ out_disable_vconn:
2028out_disable_pd: 2029out_disable_pd:
2029 port->tcpc->set_pd_rx(port->tcpc, false); 2030 port->tcpc->set_pd_rx(port->tcpc, false);
2030out_disable_mux: 2031out_disable_mux:
2031 tcpm_mux_set(port, TYPEC_MUX_NONE, TCPC_USB_SWITCH_DISCONNECT); 2032 tcpm_mux_set(port, TYPEC_MUX_NONE, USB_ROLE_NONE);
2032 return ret; 2033 return ret;
2033} 2034}
2034 2035
@@ -2072,6 +2073,7 @@ static void tcpm_reset_port(struct tcpm_port *port)
2072 tcpm_init_vconn(port); 2073 tcpm_init_vconn(port);
2073 tcpm_set_current_limit(port, 0, 0); 2074 tcpm_set_current_limit(port, 0, 0);
2074 tcpm_set_polarity(port, TYPEC_POLARITY_CC1); 2075 tcpm_set_polarity(port, TYPEC_POLARITY_CC1);
2076 tcpm_mux_set(port, TYPEC_MUX_NONE, USB_ROLE_NONE);
2075 tcpm_set_attached_state(port, false); 2077 tcpm_set_attached_state(port, false);
2076 port->try_src_count = 0; 2078 port->try_src_count = 0;
2077 port->try_snk_count = 0; 2079 port->try_snk_count = 0;
@@ -2122,8 +2124,6 @@ static int tcpm_snk_attach(struct tcpm_port *port)
2122static void tcpm_snk_detach(struct tcpm_port *port) 2124static void tcpm_snk_detach(struct tcpm_port *port)
2123{ 2125{
2124 tcpm_detach(port); 2126 tcpm_detach(port);
2125
2126 /* XXX: (Dis)connect SuperSpeed mux? */
2127} 2127}
2128 2128
2129static int tcpm_acc_attach(struct tcpm_port *port) 2129static int tcpm_acc_attach(struct tcpm_port *port)
diff --git a/include/linux/usb/tcpm.h b/include/linux/usb/tcpm.h
index 5a5e1d8c5b65..3e8bdaa5085a 100644
--- a/include/linux/usb/tcpm.h
+++ b/include/linux/usb/tcpm.h
@@ -16,6 +16,7 @@
16#define __LINUX_USB_TCPM_H 16#define __LINUX_USB_TCPM_H
17 17
18#include <linux/bitops.h> 18#include <linux/bitops.h>
19#include <linux/usb/role.h>
19#include <linux/usb/typec.h> 20#include <linux/usb/typec.h>
20#include "pd.h" 21#include "pd.h"
21 22
@@ -98,11 +99,6 @@ struct tcpc_config {
98 const struct typec_altmode_desc *alt_modes; 99 const struct typec_altmode_desc *alt_modes;
99}; 100};
100 101
101enum tcpc_usb_switch {
102 TCPC_USB_SWITCH_CONNECT,
103 TCPC_USB_SWITCH_DISCONNECT,
104};
105
106/* Mux state attributes */ 102/* Mux state attributes */
107#define TCPC_MUX_USB_ENABLED BIT(0) /* USB enabled */ 103#define TCPC_MUX_USB_ENABLED BIT(0) /* USB enabled */
108#define TCPC_MUX_DP_ENABLED BIT(1) /* DP enabled */ 104#define TCPC_MUX_DP_ENABLED BIT(1) /* DP enabled */
@@ -119,7 +115,7 @@ enum tcpc_mux_mode {
119 115
120struct tcpc_mux_dev { 116struct tcpc_mux_dev {
121 int (*set)(struct tcpc_mux_dev *dev, enum tcpc_mux_mode mux_mode, 117 int (*set)(struct tcpc_mux_dev *dev, enum tcpc_mux_mode mux_mode,
122 enum tcpc_usb_switch usb_config, 118 enum usb_role usb_role,
123 enum typec_cc_polarity polarity); 119 enum typec_cc_polarity polarity);
124 bool dfp_only; 120 bool dfp_only;
125 void *priv_data; 121 void *priv_data;