mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 05:39:54 -04:00
ucsi: Add usage of USB role switch functionality
This change adds usage of USB role switch framework to notify USB role to start USB host/device stack to USB driver. Change-Id: I9778e0e3d2db2aaccf2f19c6dfd2482dad6acbfc Signed-off-by: Mayank Rana <mrana@codeaurora.org>
This commit is contained in:
parent
0390237bf3
commit
a1d126aa4e
2 changed files with 35 additions and 0 deletions
|
|
@ -473,15 +473,19 @@ static void ucsi_unregister_partner(struct ucsi_connector *con)
|
|||
static void ucsi_partner_change(struct ucsi_connector *con)
|
||||
{
|
||||
int ret;
|
||||
struct ucsi *ucsi = con->ucsi;
|
||||
enum usb_role u_role = USB_ROLE_NONE;
|
||||
|
||||
if (!con->partner)
|
||||
return;
|
||||
|
||||
switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
|
||||
case UCSI_CONSTAT_PARTNER_TYPE_UFP:
|
||||
u_role = USB_ROLE_HOST;
|
||||
typec_set_data_role(con->port, TYPEC_HOST);
|
||||
break;
|
||||
case UCSI_CONSTAT_PARTNER_TYPE_DFP:
|
||||
u_role = USB_ROLE_DEVICE;
|
||||
typec_set_data_role(con->port, TYPEC_DEVICE);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -492,6 +496,11 @@ static void ucsi_partner_change(struct ucsi_connector *con)
|
|||
if (!completion_done(&con->complete))
|
||||
complete(&con->complete);
|
||||
|
||||
ret = usb_role_switch_set_role(ucsi->usb_role_sw, u_role);
|
||||
if (ret)
|
||||
dev_err(ucsi->dev, "%s(): failed to set role(%d):%d\n",
|
||||
__func__, u_role, ret);
|
||||
|
||||
/* Can't rely on Partner Flags field. Always checking the alt modes. */
|
||||
ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
|
||||
if (ret)
|
||||
|
|
@ -510,6 +519,7 @@ static void ucsi_handle_connector_change(struct work_struct *work)
|
|||
enum typec_role role;
|
||||
u64 command;
|
||||
int ret;
|
||||
enum usb_role u_role = USB_ROLE_NONE;
|
||||
|
||||
mutex_lock(&con->lock);
|
||||
|
||||
|
|
@ -540,9 +550,11 @@ static void ucsi_handle_connector_change(struct work_struct *work)
|
|||
|
||||
switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
|
||||
case UCSI_CONSTAT_PARTNER_TYPE_UFP:
|
||||
u_role = USB_ROLE_HOST;
|
||||
typec_set_data_role(con->port, TYPEC_HOST);
|
||||
break;
|
||||
case UCSI_CONSTAT_PARTNER_TYPE_DFP:
|
||||
u_role = USB_ROLE_DEVICE;
|
||||
typec_set_data_role(con->port, TYPEC_DEVICE);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -553,6 +565,11 @@ static void ucsi_handle_connector_change(struct work_struct *work)
|
|||
ucsi_register_partner(con);
|
||||
else
|
||||
ucsi_unregister_partner(con);
|
||||
|
||||
ret = usb_role_switch_set_role(ucsi->usb_role_sw, u_role);
|
||||
if (ret)
|
||||
dev_err(ucsi->dev, "%s(): failed to set role(%d):%d\n",
|
||||
__func__, u_role, ret);
|
||||
}
|
||||
|
||||
if (con->status.change & UCSI_CONSTAT_CAM_CHANGE) {
|
||||
|
|
@ -776,6 +793,7 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
|
|||
enum typec_accessory *accessory = cap->accessory;
|
||||
u64 command;
|
||||
int ret;
|
||||
enum usb_role role = USB_ROLE_NONE;
|
||||
|
||||
INIT_WORK(&con->work, ucsi_handle_connector_change);
|
||||
init_completion(&con->complete);
|
||||
|
|
@ -840,9 +858,11 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
|
|||
|
||||
switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
|
||||
case UCSI_CONSTAT_PARTNER_TYPE_UFP:
|
||||
role = USB_ROLE_HOST;
|
||||
typec_set_data_role(con->port, TYPEC_HOST);
|
||||
break;
|
||||
case UCSI_CONSTAT_PARTNER_TYPE_DFP:
|
||||
role = USB_ROLE_DEVICE;
|
||||
typec_set_data_role(con->port, TYPEC_DEVICE);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -857,6 +877,11 @@ static int ucsi_register_port(struct ucsi *ucsi, int index)
|
|||
ucsi_register_partner(con);
|
||||
}
|
||||
|
||||
ret = usb_role_switch_set_role(ucsi->usb_role_sw, role);
|
||||
if (ret)
|
||||
dev_err(ucsi->dev, "%s(): failed to set role(%d):%d\n",
|
||||
__func__, role, ret);
|
||||
|
||||
if (con->partner) {
|
||||
ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
|
||||
if (ret)
|
||||
|
|
@ -920,6 +945,13 @@ int ucsi_init(struct ucsi *ucsi)
|
|||
goto err_reset;
|
||||
}
|
||||
|
||||
ucsi->usb_role_sw = fwnode_usb_role_switch_get(dev_fwnode(ucsi->dev));
|
||||
if (IS_ERR_OR_NULL(ucsi->usb_role_sw)) {
|
||||
dev_err(ucsi->dev, "%s(): Unable to find usb role switch\n",
|
||||
__func__);
|
||||
ucsi->usb_role_sw = NULL;
|
||||
}
|
||||
|
||||
/* Register all connectors */
|
||||
for (i = 0; i < ucsi->cap.num_connectors; i++) {
|
||||
ret = ucsi_register_port(ucsi, i);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <linux/device.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/usb/typec.h>
|
||||
#include <linux/usb/role.h>
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
|
|
@ -277,6 +278,8 @@ struct ucsi {
|
|||
#define EVENT_PENDING 0
|
||||
#define COMMAND_PENDING 1
|
||||
#define ACK_PENDING 2
|
||||
|
||||
struct usb_role_switch *usb_role_sw;
|
||||
};
|
||||
|
||||
#define UCSI_MAX_SVID 5
|
||||
|
|
|
|||
Loading…
Reference in a new issue