usb: typec: ucsi: yoga-c630: fake AltModes for port 0

EC firmware provides information about partner AltModes and handles the
DisplayPort AltMode internally, however it doesn't report AltModes of
the port to the host. Fake the DP AltMode for port0 in order to let
Linux bind displayport AltMode driver.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20250621-c630-ucsi-v1-5-a86de5e11361@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Dmitry Baryshkov
2025-06-21 21:13:00 +03:00
committed by Greg Kroah-Hartman
parent eebd39f8a8
commit 442392f98d
2 changed files with 23 additions and 0 deletions

View File

@@ -50,6 +50,7 @@ struct dentry;
/* Command Status and Connector Change Indication (CCI) bits */
#define UCSI_CCI_CONNECTOR(_c_) (((_c_) & GENMASK(7, 1)) >> 1)
#define UCSI_CCI_LENGTH(_c_) (((_c_) & GENMASK(15, 8)) >> 8)
#define UCSI_SET_CCI_LENGTH(_c_) ((_c_) << 8)
#define UCSI_CCI_NOT_SUPPORTED BIT(25)
#define UCSI_CCI_CANCEL_COMPLETE BIT(26)
#define UCSI_CCI_RESET_COMPLETE BIT(27)

View File

@@ -76,6 +76,28 @@ static int yoga_c630_ucsi_sync_control(struct ucsi *ucsi,
u32 *cci,
void *data, size_t size)
{
int ret;
/*
* EC doesn't return connector's DP mode even though it is supported.
* Fake it.
*/
if (UCSI_COMMAND(command) == UCSI_GET_ALTERNATE_MODES &&
UCSI_GET_ALTMODE_GET_CONNECTOR_NUMBER(command) == 1 &&
UCSI_ALTMODE_RECIPIENT(command) == UCSI_RECIPIENT_CON &&
UCSI_ALTMODE_OFFSET(command) == 0) {
static const struct ucsi_altmode alt = {
.svid = USB_TYPEC_DP_SID,
.mid = USB_TYPEC_DP_MODE,
};
dev_dbg(ucsi->dev, "faking DP altmode for con1\n");
memset(data, 0, size);
memcpy(data, &alt, min(sizeof(alt), size));
*cci = UCSI_CCI_COMMAND_COMPLETE | UCSI_SET_CCI_LENGTH(sizeof(alt));
return 0;
}
/*
* EC can return AltModes present on CON1 (port0, right) for CON2
* (port1, left) too. Ignore all requests going to CON2 (it doesn't