From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752219AbdLGCNB (ORCPT ); Wed, 6 Dec 2017 21:13:01 -0500 Received: from mailout2.samsung.com ([203.254.224.25]:56684 "EHLO mailout2.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751950AbdLGCM7 (ORCPT ); Wed, 6 Dec 2017 21:12:59 -0500 DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.samsung.com 20171207021257epoutp02404ea2ae16347730e2ee2f9aeea8a697~94U55G0qo1692716927epoutp02p X-AuditID: b6c32a35-c51ff700000010dd-28-5a28a3a84add MIME-version: 1.0 Content-transfer-encoding: 8BIT Content-type: text/plain; charset="UTF-8" Message-id: <5A28A3A8.4020302@samsung.com> Date: Thu, 07 Dec 2017 11:12:56 +0900 From: Chanwoo Choi Organization: Samsung Electronics User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 To: Enric Balletbo i Serra , MyungJoo Ham , Lee Jones , Rob Herring , Heiko Stuebner Cc: groeck@chromium.org, devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org, Benson Leung Subject: Re: [PATCH 1/3] extcon: usbc-cros-ec: add support to notify USB type cables. In-reply-to: <20171206111008.3079-1-enric.balletbo@collabora.com> X-Brightmail-Tracker: H4sIAAAAAAAAA01SWUwTURTNY9rpoBaHAvqCWx3jUhJqpywOCkYC4iRqAvIhqTE4wrAonZJO UcuH4IpUoxIQDaiIEFkkYioKao0JSzQINZZQiQsQUKy4RmRJFHHa0ejfufeec5eTiyGKCjQQ y+RMrJFjsgh0luROm0oTXFu1SqdxNauo8296JFRFu11KNbxsBVTn6DWEmhn6IKUGxjsAZR12 SqmeexdR6tvgDEK9PFSLUscetMs2zKbL859J6JbX1YC21hei9CunDaVvVefRp5vqAd3svIzQ Y9bF8ZiOjcxgmVTWqGS5FENqJpceRWxOTI5JDgvXkMFkBLWGUHKMno0iYrfEB8dlZgmLEsp9 TFaOkIpneJ5YvT7SaMgxscoMA2+KInaQpFZNataotVqtOjRk51ptmEDZxWb0zthl2ZPbDkyP fJXkg/5oC/DGIB4KL3ROSNxYgbcAeK6RsoBZAp4EsLbuI/hLOlx4B4iFmwCOjFbL3AU57gun ivsFNYYh+BLY7tjrTiO4Ct6+3ygT+f0APnZelYj8IPizzyV1Ywm+HJ7s7vJgVMg/dPWhbjwX Xwp7p4Y9gwPwJHi3YsLTyB/vAvBmw3lPgOBtAI5ZnJ6ufvh2OHTE5lF449GwunzUQ4L4ERkc c7oQ8YZYWPXxhpeI/eDooyaZe22IL4COjiiRXwBgwYPLiBiUAGh/3v9HEAJHKi1e4nE+8PP4 KakolsMTxxUihYZnfhX+mRUNX9Q+QcX7hT4Tn5yys2Bx2X+Wlf2zrOw/y64ApB7MY7N5fTrL k9mkmmf0fA6Xrk4x6K3A85xBYS2gxL6lFeAYIObIBydX6hRSZh9v1rcCiCGEv/zHmVU6hTyV MeeyRkOyMSeL5VtBmOB4ERIYkGIQXp0zJZOhEZrQcK3wYBEkScyXBzQ6kxR4OmNi97JsNmv8 q/PCvAPzwXVElzA5O7EmL+lEwsLvPgqu90tBUe5IqXXa1xWzrAco4hyb0GNpiVs7wsvN+2s2 fu42rLgf/n538aVtseagIttFG2drUpWeGlrn41h49K4s5Hb30LuffeMDwwuaC6YX+eePVyqn +uY8LdyT2+ClSqtz+HEBby1v8w4e5Mgpe9w3QsJnMGQQYuSZ39UGaNeyAwAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFmpikeLIzCtJLcpLzFFi42I5/e+xoO6KxRpRBnP6xS2mP7nMYjH/yDlW izW3DzFanHq1jNni/6PXrBb3vx5ltNj0+BqrxeVdc9gsPj34z2xxu3EFm0Xr3iPsDtwesxsu snjsuLuE0WPTqk42jzvX9rB5bF5S79G3ZRWjx/Zr85g9Pm+SC+CI4rJJSc3JLEst0rdL4Mq4 +v8ce8H3oIq/zz6wNDDec+xi5OSQEDCRaOrcxtjFyMUhJLCOUWJ25z9mkASvgKDEj8n3WLoY OTiYBeQljlzKBgkzC6hLTJq3iBmi/gGjxMot/xkh6rUk/tx4wQpiswioSnSfPQNmswHF97+4 wQZi8wsoSlz98ZgRZKaoQIRE94lKkDkiAmcYJa5/nw92BLPAYUaJpgOXwIYKC4RLfOmdCnXd NEaJhs9tYNdxCjhKLJn9in0Co8AsJMfOQjh2FpJjFzAyr2KUTC0ozk3PLTYqMMxLLdcrTswt Ls1L10vOz93ECIyZbYe1+nYw3l8Sf4hRgINRiYf3xT/1KCHWxLLiytxDjBIczEoivL/7NaKE eFMSK6tSi/Lji0pzUosPMUpzsCiJ897OOxYpJJCeWJKanZpakFoEk2Xi4JRqYBQUvLiCK7rk h5OsWvzeY7/LthiK//qseXDZE9ZalpC9+kf4VO6F9nVo3o7Ntw7yPHv031LFyuCvQb+kb5ze 1OIT/NmuefKHhUzeMTfDZZzsrIRq//gfXWAc6mfwaxf7IS9/Gb4zXPFBp+fd52DmnsZ8d13u ykkHj9TbdIoHMU30EAlYcCCvVomlOCPRUIu5qDgRALD5ApCVAgAA X-CMS-MailID: 20171207021256epcas1p2605b6b27ec758acc8bfdf013be630140 X-Msg-Generator: CA CMS-TYPE: 101P DLP-Filter: Pass X-CFilter-Loop: Reflected X-CMS-RootMailID: 20171206111048epcas3p2b412288717b0f8197c85edaab5c9a242 X-RootMTR: 20171206111048epcas3p2b412288717b0f8197c85edaab5c9a242 References: <20171206111008.3079-1-enric.balletbo@collabora.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Enric, On 2017년 12월 06일 20:10, Enric Balletbo i Serra wrote: > From: Benson Leung > > Extend the driver to notify host and device type cables and the presence > of power. > > Signed-off-by: Benson Leung > Signed-off-by: Enric Balletbo i Serra > --- > drivers/extcon/extcon-usbc-cros-ec.c | 142 ++++++++++++++++++++++++++++++++++- > include/linux/mfd/cros_ec_commands.h | 17 +++++ > 2 files changed, 155 insertions(+), 4 deletions(-) Looks good to me. After you uses the BIT() macro as the Lee's comment on v2, I'll merge this patch. Reviewed-by: Chanwoo Choi > > diff --git a/drivers/extcon/extcon-usbc-cros-ec.c b/drivers/extcon/extcon-usbc-cros-ec.c > index 6187f73..6721ab0 100644 > --- a/drivers/extcon/extcon-usbc-cros-ec.c > +++ b/drivers/extcon/extcon-usbc-cros-ec.c > @@ -34,16 +34,26 @@ struct cros_ec_extcon_info { > > struct notifier_block notifier; > > + unsigned int dr; /* data role */ > + bool pr; /* power role (true if VBUS enabled) */ > bool dp; /* DisplayPort enabled */ > bool mux; /* SuperSpeed (usb3) enabled */ > unsigned int power_type; > }; > > static const unsigned int usb_type_c_cable[] = { > + EXTCON_USB, > + EXTCON_USB_HOST, > EXTCON_DISP_DP, > EXTCON_NONE, > }; > > +enum usb_data_roles { > + DR_NONE, > + DR_HOST, > + DR_DEVICE, > +}; > + > /** > * cros_ec_pd_command() - Send a command to the EC. > * @info: pointer to struct cros_ec_extcon_info > @@ -150,6 +160,7 @@ static int cros_ec_usb_get_role(struct cros_ec_extcon_info *info, > pd_control.port = info->port_id; > pd_control.role = USB_PD_CTRL_ROLE_NO_CHANGE; > pd_control.mux = USB_PD_CTRL_MUX_NO_CHANGE; > + pd_control.swap = USB_PD_CTRL_SWAP_NONE; > ret = cros_ec_pd_command(info, EC_CMD_USB_PD_CONTROL, 1, > &pd_control, sizeof(pd_control), > &resp, sizeof(resp)); > @@ -183,11 +194,72 @@ static int cros_ec_pd_get_num_ports(struct cros_ec_extcon_info *info) > return resp.num_ports; > } > > +static const char *cros_ec_usb_role_string(unsigned int role) > +{ > + return role == DR_NONE ? "DISCONNECTED" : > + (role == DR_HOST ? "DFP" : "UFP"); > +} > + > +static const char *cros_ec_usb_power_type_string(unsigned int type) > +{ > + switch (type) { > + case USB_CHG_TYPE_NONE: > + return "USB_CHG_TYPE_NONE"; > + case USB_CHG_TYPE_PD: > + return "USB_CHG_TYPE_PD"; > + case USB_CHG_TYPE_PROPRIETARY: > + return "USB_CHG_TYPE_PROPRIETARY"; > + case USB_CHG_TYPE_C: > + return "USB_CHG_TYPE_C"; > + case USB_CHG_TYPE_BC12_DCP: > + return "USB_CHG_TYPE_BC12_DCP"; > + case USB_CHG_TYPE_BC12_CDP: > + return "USB_CHG_TYPE_BC12_CDP"; > + case USB_CHG_TYPE_BC12_SDP: > + return "USB_CHG_TYPE_BC12_SDP"; > + case USB_CHG_TYPE_OTHER: > + return "USB_CHG_TYPE_OTHER"; > + case USB_CHG_TYPE_VBUS: > + return "USB_CHG_TYPE_VBUS"; > + case USB_CHG_TYPE_UNKNOWN: > + return "USB_CHG_TYPE_UNKNOWN"; > + default: > + return "USB_CHG_TYPE_UNKNOWN"; > + } > +} > + > +static bool cros_ec_usb_power_type_is_wall_wart(unsigned int type, > + unsigned int role) > +{ > + switch (type) { > + /* FIXME : Guppy, Donnettes, and other chargers will be miscategorized > + * because they identify with USB_CHG_TYPE_C, but we can't return true > + * here from that code because that breaks Suzy-Q and other kinds of > + * USB Type-C cables and peripherals. > + */ > + case USB_CHG_TYPE_PROPRIETARY: > + case USB_CHG_TYPE_BC12_DCP: > + return true; > + case USB_CHG_TYPE_PD: > + case USB_CHG_TYPE_C: > + case USB_CHG_TYPE_BC12_CDP: > + case USB_CHG_TYPE_BC12_SDP: > + case USB_CHG_TYPE_OTHER: > + case USB_CHG_TYPE_VBUS: > + case USB_CHG_TYPE_UNKNOWN: > + case USB_CHG_TYPE_NONE: > + default: > + return false; > + } > +} > + > static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, > bool force) > { > struct device *dev = info->dev; > int role, power_type; > + unsigned int dr = DR_NONE; > + bool pr = false; > bool polarity = false; > bool dp = false; > bool mux = false; > @@ -206,9 +278,12 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, > dev_err(dev, "failed getting role err = %d\n", role); > return role; > } > + dev_dbg(dev, "disconnected\n"); > } else { > int pd_mux_state; > > + dr = (role & PD_CTRL_RESP_ROLE_DATA) ? DR_HOST : DR_DEVICE; > + pr = (role & PD_CTRL_RESP_ROLE_POWER); > pd_mux_state = cros_ec_usb_get_pd_mux_state(info); > if (pd_mux_state < 0) > pd_mux_state = USB_PD_MUX_USB_ENABLED; > @@ -216,20 +291,62 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, > dp = pd_mux_state & USB_PD_MUX_DP_ENABLED; > mux = pd_mux_state & USB_PD_MUX_USB_ENABLED; > hpd = pd_mux_state & USB_PD_MUX_HPD_IRQ; > - } > > - if (force || info->dp != dp || info->mux != mux || > - info->power_type != power_type) { > + dev_dbg(dev, > + "connected role 0x%x pwr type %d dr %d pr %d pol %d mux %d dp %d hpd %d\n", > + role, power_type, dr, pr, polarity, mux, dp, hpd); > + } > > + /* > + * When there is no USB host (e.g. USB PD charger), > + * we are not really a UFP for the AP. > + */ > + if (dr == DR_DEVICE && > + cros_ec_usb_power_type_is_wall_wart(power_type, role)) > + dr = DR_NONE; > + > + if (force || info->dr != dr || info->pr != pr || info->dp != dp || > + info->mux != mux || info->power_type != power_type) { > + bool host_connected = false, device_connected = false; > + > + dev_dbg(dev, "Type/Role switch! type = %s role = %s\n", > + cros_ec_usb_power_type_string(power_type), > + cros_ec_usb_role_string(dr)); > + info->dr = dr; > + info->pr = pr; > info->dp = dp; > info->mux = mux; > info->power_type = power_type; > > - extcon_set_state(info->edev, EXTCON_DISP_DP, dp); > + if (dr == DR_DEVICE) > + device_connected = true; > + else if (dr == DR_HOST) > + host_connected = true; > > + extcon_set_state(info->edev, EXTCON_USB, device_connected); > + extcon_set_state(info->edev, EXTCON_USB_HOST, host_connected); > + extcon_set_state(info->edev, EXTCON_DISP_DP, dp); > + extcon_set_property(info->edev, EXTCON_USB, > + EXTCON_PROP_USB_VBUS, > + (union extcon_property_value)(int)pr); > + extcon_set_property(info->edev, EXTCON_USB_HOST, > + EXTCON_PROP_USB_VBUS, > + (union extcon_property_value)(int)pr); > + extcon_set_property(info->edev, EXTCON_USB, > + EXTCON_PROP_USB_TYPEC_POLARITY, > + (union extcon_property_value)(int)polarity); > + extcon_set_property(info->edev, EXTCON_USB_HOST, > + EXTCON_PROP_USB_TYPEC_POLARITY, > + (union extcon_property_value)(int)polarity); > extcon_set_property(info->edev, EXTCON_DISP_DP, > EXTCON_PROP_USB_TYPEC_POLARITY, > (union extcon_property_value)(int)polarity); > + extcon_set_property(info->edev, EXTCON_USB, > + EXTCON_PROP_USB_SS, > + (union extcon_property_value)(int)mux); > + extcon_set_property(info->edev, EXTCON_USB_HOST, > + EXTCON_PROP_USB_SS, > + (union extcon_property_value)(int)mux); > extcon_set_property(info->edev, EXTCON_DISP_DP, > EXTCON_PROP_USB_SS, > (union extcon_property_value)(int)mux); > @@ -237,6 +354,8 @@ static int extcon_cros_ec_detect_cable(struct cros_ec_extcon_info *info, > EXTCON_PROP_DISP_HPD, > (union extcon_property_value)(int)hpd); > > + extcon_sync(info->edev, EXTCON_USB); > + extcon_sync(info->edev, EXTCON_USB_HOST); > extcon_sync(info->edev, EXTCON_DISP_DP); > > } else if (hpd) { > @@ -322,13 +441,28 @@ static int extcon_cros_ec_probe(struct platform_device *pdev) > return ret; > } > > + extcon_set_property_capability(info->edev, EXTCON_USB, > + EXTCON_PROP_USB_VBUS); > + extcon_set_property_capability(info->edev, EXTCON_USB_HOST, > + EXTCON_PROP_USB_VBUS); > + extcon_set_property_capability(info->edev, EXTCON_USB, > + EXTCON_PROP_USB_TYPEC_POLARITY); > + extcon_set_property_capability(info->edev, EXTCON_USB_HOST, > + EXTCON_PROP_USB_TYPEC_POLARITY); > extcon_set_property_capability(info->edev, EXTCON_DISP_DP, > EXTCON_PROP_USB_TYPEC_POLARITY); > + extcon_set_property_capability(info->edev, EXTCON_USB, > + EXTCON_PROP_USB_SS); > + extcon_set_property_capability(info->edev, EXTCON_USB_HOST, > + EXTCON_PROP_USB_SS); > extcon_set_property_capability(info->edev, EXTCON_DISP_DP, > EXTCON_PROP_USB_SS); > extcon_set_property_capability(info->edev, EXTCON_DISP_DP, > EXTCON_PROP_DISP_HPD); > > + info->dr = DR_NONE; > + info->pr = false; > + > platform_set_drvdata(pdev, info); > > /* Get PD events from the EC */ > diff --git a/include/linux/mfd/cros_ec_commands.h b/include/linux/mfd/cros_ec_commands.h > index 2b16e95..c907353 100644 > --- a/include/linux/mfd/cros_ec_commands.h > +++ b/include/linux/mfd/cros_ec_commands.h > @@ -2904,16 +2904,33 @@ enum usb_pd_control_mux { > USB_PD_CTRL_MUX_AUTO = 5, > }; > > +enum usb_pd_control_swap { > + USB_PD_CTRL_SWAP_NONE = 0, > + USB_PD_CTRL_SWAP_DATA = 1, > + USB_PD_CTRL_SWAP_POWER = 2, > + USB_PD_CTRL_SWAP_VCONN = 3, > + USB_PD_CTRL_SWAP_COUNT > +}; > + > struct ec_params_usb_pd_control { > uint8_t port; > uint8_t role; > uint8_t mux; > + uint8_t swap; > } __packed; > > #define PD_CTRL_RESP_ENABLED_COMMS (1 << 0) /* Communication enabled */ > #define PD_CTRL_RESP_ENABLED_CONNECTED (1 << 1) /* Device connected */ > #define PD_CTRL_RESP_ENABLED_PD_CAPABLE (1 << 2) /* Partner is PD capable */ > > +#define PD_CTRL_RESP_ROLE_POWER (1 << 0) /* 0=SNK/1=SRC */ > +#define PD_CTRL_RESP_ROLE_DATA (1 << 1) /* 0=UFP/1=DFP */ > +#define PD_CTRL_RESP_ROLE_VCONN (1 << 2) /* Vconn status */ > +#define PD_CTRL_RESP_ROLE_DR_POWER (1 << 3) /* Partner is dualrole power */ > +#define PD_CTRL_RESP_ROLE_DR_DATA (1 << 4) /* Partner is dualrole data */ > +#define PD_CTRL_RESP_ROLE_USB_COMM (1 << 5) /* Partner USB comm capable */ > +#define PD_CTRL_RESP_ROLE_EXT_POWERED (1 << 6) /* Partner externally powerd */ > + > struct ec_response_usb_pd_control_v1 { > uint8_t enabled; > uint8_t role; > -- Best Regards, Chanwoo Choi Samsung Electronics