mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
usb: typec: tipd: add TPS66993 support
Derive power status from the STATUS register (0x1A) now that TPS66993 deprecates the Power_Status register (0x3F). Add support for the "APP1" mode string. TPS66993 controller is configured in polling mode and only type-c flip orientation feature is supported on AMD Versal AI Edge Gen 2 VEK385 Evaluation Kit. Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Link: https://patch.msgid.link/20260714061820.537792-4-radhey.shyam.pandey@amd.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
1b21957eec
commit
c7ca309d57
|
|
@ -130,6 +130,7 @@ enum {
|
|||
TPS_MODE_BIST,
|
||||
TPS_MODE_DISC,
|
||||
TPS_MODE_PTCH,
|
||||
TPS_MODE_APP1,
|
||||
};
|
||||
|
||||
static const char *const modes[] = {
|
||||
|
|
@ -138,6 +139,7 @@ static const char *const modes[] = {
|
|||
[TPS_MODE_BIST] = "BIST",
|
||||
[TPS_MODE_DISC] = "DISC",
|
||||
[TPS_MODE_PTCH] = "PTCH",
|
||||
[TPS_MODE_APP1] = "APP1",
|
||||
};
|
||||
|
||||
/* Unrecognized commands will be replaced with "!CMD" */
|
||||
|
|
@ -631,6 +633,34 @@ static bool tps6598x_read_power_status(struct tps6598x *tps)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* TPS66993 deprecated Power_Status register (0x3F). BC1.2 is not supported
|
||||
* and the remaining bits are redundant with STATUS register (0x1A).
|
||||
* Synthesize pwr_status from the already-read STATUS register.
|
||||
*/
|
||||
static bool tps66993_read_power_status(struct tps6598x *tps)
|
||||
{
|
||||
u16 pwr_status = 0;
|
||||
|
||||
/* Same masks as TPS_POWER_STATUS_CONNECTION() / SOURCESINK() / PWROPMODE() in tps6598x.h */
|
||||
if (tps->status & TPS_STATUS_PLUG_PRESENT)
|
||||
pwr_status |= FIELD_PREP(TPS_POWER_STATUS_CONNECTION_MASK, 1);
|
||||
|
||||
/* SOURCESINK: 1=sink; STATUS.PortRole 1=source, opposite convention */
|
||||
if (!TPS_STATUS_TO_TYPEC_PORTROLE(tps->status))
|
||||
pwr_status |= FIELD_PREP(TPS_POWER_STATUS_SOURCESINK_MASK, 1);
|
||||
|
||||
if (TPS_STATUS_VBUS_STATUS(tps->status) == TPS_STATUS_VBUS_STATUS_PD)
|
||||
pwr_status |= FIELD_PREP(TPS_POWER_STATUS_TYPEC_CURRENT_MASK,
|
||||
TPS_POWER_STATUS_TYPEC_CURRENT_PD);
|
||||
|
||||
tps->pwr_status = pwr_status;
|
||||
|
||||
tps->data->trace_power_status(pwr_status);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tps6598x_handle_plug_event(struct tps6598x *tps, u32 status)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -1026,6 +1056,8 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data)
|
|||
if (!tps6598x_read_status(tps, &status))
|
||||
goto err_unlock;
|
||||
|
||||
tps->status = status;
|
||||
|
||||
if ((event1[0] | event2[0]) & TPS_REG_INT_POWER_STATUS_UPDATE)
|
||||
if (!tps->data->read_power_status(tps))
|
||||
goto err_unlock;
|
||||
|
|
@ -1034,9 +1066,15 @@ static irqreturn_t tps6598x_interrupt(int irq, void *data)
|
|||
if (!tps->data->read_data_status(tps))
|
||||
goto err_unlock;
|
||||
|
||||
/* Handle plug insert or removal */
|
||||
if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT)
|
||||
/*
|
||||
* Refresh power status before connect - needed for TPS66993 which
|
||||
* synthesizes pwr_status from STATUS and never gets POWER_STATUS_UPDATE.
|
||||
*/
|
||||
if ((event1[0] | event2[0]) & TPS_REG_INT_PLUG_EVENT) {
|
||||
if (!tps->data->read_power_status(tps))
|
||||
goto err_unlock;
|
||||
tps6598x_handle_plug_event(tps, status);
|
||||
}
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&tps->lock);
|
||||
|
|
@ -1072,6 +1110,7 @@ static int tps6598x_check_mode(struct tps6598x *tps)
|
|||
|
||||
switch (ret) {
|
||||
case TPS_MODE_APP:
|
||||
case TPS_MODE_APP1:
|
||||
case TPS_MODE_PTCH:
|
||||
return ret;
|
||||
case TPS_MODE_BOOT:
|
||||
|
|
@ -1813,6 +1852,8 @@ static int tps6598x_probe(struct i2c_client *client)
|
|||
goto err_clear_mask;
|
||||
}
|
||||
|
||||
tps->status = status;
|
||||
|
||||
/*
|
||||
* This fwnode has a "compatible" property, but is never populated as a
|
||||
* struct device. Instead we simply parse it to read the properties.
|
||||
|
|
@ -2007,6 +2048,24 @@ static const struct tipd_data tps6598x_data = {
|
|||
.connect = tps6598x_connect,
|
||||
};
|
||||
|
||||
static const struct tipd_data tps66993_data = {
|
||||
.irq_handler = tps6598x_interrupt,
|
||||
.irq_mask1 = TPS_REG_INT_DATA_STATUS_UPDATE |
|
||||
TPS_REG_INT_PLUG_EVENT,
|
||||
.tps_struct_size = sizeof(struct tps6598x),
|
||||
.register_port = tps6598x_register_port,
|
||||
.unregister_port = tps6598x_unregister_port,
|
||||
.trace_data_status = trace_tps6598x_data_status,
|
||||
.trace_power_status = trace_tps6598x_power_status,
|
||||
.trace_status = trace_tps6598x_status,
|
||||
.apply_patch = tps6598x_apply_patch,
|
||||
.init = tps6598x_init,
|
||||
.read_data_status = tps6598x_read_data_status,
|
||||
.read_power_status = tps66993_read_power_status,
|
||||
.reset = tps6598x_reset,
|
||||
.connect = tps6598x_connect,
|
||||
};
|
||||
|
||||
static const struct tipd_data tps25750_data = {
|
||||
.irq_handler = tps25750_interrupt,
|
||||
.irq_mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
|
||||
|
|
@ -2028,6 +2087,7 @@ static const struct tipd_data tps25750_data = {
|
|||
|
||||
static const struct of_device_id tps6598x_of_match[] = {
|
||||
{ .compatible = "ti,tps6598x", &tps6598x_data},
|
||||
{ .compatible = "ti,tps66993", &tps66993_data},
|
||||
{ .compatible = "apple,cd321x", &cd321x_data},
|
||||
{ .compatible = "ti,tps25750", &tps25750_data},
|
||||
{}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user