Skip to content

Commit 766c485

Browse files
Badhri Jagan Sridharangregkh
authored andcommitted
usb: typec: tcpci: Add support to report vSafe0V
This change adds vbus_vsafe0v which when set, makes TCPM query for VSAFE0V by assigning the tcpc.is_vbus_vsafe0v callback. Also enables ALERT.ExtendedStatus which is triggered when status of EXTENDED_STATUS.vSafe0V changes. EXTENDED_STATUS.vSafe0V is set when vbus is at vSafe0V and cleared otherwise. Reviewed-by: Guenter Roeck <[email protected]> Acked-by: Heikki Krogerus <[email protected]> Signed-off-by: Badhri Jagan Sridharan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 28b43d3 commit 766c485

File tree

2 files changed

+40
-5
lines changed

2 files changed

+40
-5
lines changed

drivers/usb/typec/tcpm/tcpci.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,19 @@ static int tcpci_get_vbus(struct tcpc_dev *tcpc)
403403
return !!(reg & TCPC_POWER_STATUS_VBUS_PRES);
404404
}
405405

406+
static bool tcpci_is_vbus_vsafe0v(struct tcpc_dev *tcpc)
407+
{
408+
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
409+
unsigned int reg;
410+
int ret;
411+
412+
ret = regmap_read(tcpci->regmap, TCPC_EXTENDED_STATUS, &reg);
413+
if (ret < 0)
414+
return false;
415+
416+
return !!(reg & TCPC_EXTENDED_STATUS_VSAFE0V);
417+
}
418+
406419
static int tcpci_set_vbus(struct tcpc_dev *tcpc, bool source, bool sink)
407420
{
408421
struct tcpci *tcpci = tcpc_to_tcpci(tcpc);
@@ -556,12 +569,22 @@ static int tcpci_init(struct tcpc_dev *tcpc)
556569
TCPC_ALERT_RX_HARD_RST | TCPC_ALERT_CC_STATUS;
557570
if (tcpci->controls_vbus)
558571
reg |= TCPC_ALERT_POWER_STATUS;
572+
/* Enable VSAFE0V status interrupt when detecting VSAFE0V is supported */
573+
if (tcpci->data->vbus_vsafe0v) {
574+
reg |= TCPC_ALERT_EXTENDED_STATUS;
575+
ret = regmap_write(tcpci->regmap, TCPC_EXTENDED_STATUS_MASK,
576+
TCPC_EXTENDED_STATUS_VSAFE0V);
577+
if (ret < 0)
578+
return ret;
579+
}
559580
return tcpci_write16(tcpci, TCPC_ALERT_MASK, reg);
560581
}
561582

562583
irqreturn_t tcpci_irq(struct tcpci *tcpci)
563584
{
564585
u16 status;
586+
int ret;
587+
unsigned int raw;
565588

566589
tcpci_read16(tcpci, TCPC_ALERT, &status);
567590

@@ -577,15 +600,12 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
577600
tcpm_cc_change(tcpci->port);
578601

579602
if (status & TCPC_ALERT_POWER_STATUS) {
580-
unsigned int reg;
581-
582-
regmap_read(tcpci->regmap, TCPC_POWER_STATUS_MASK, &reg);
583-
603+
regmap_read(tcpci->regmap, TCPC_POWER_STATUS_MASK, &raw);
584604
/*
585605
* If power status mask has been reset, then the TCPC
586606
* has reset.
587607
*/
588-
if (reg == 0xff)
608+
if (raw == 0xff)
589609
tcpm_tcpc_reset(tcpci->port);
590610
else
591611
tcpm_vbus_change(tcpci->port);
@@ -624,6 +644,12 @@ irqreturn_t tcpci_irq(struct tcpci *tcpci)
624644
tcpm_pd_receive(tcpci->port, &msg);
625645
}
626646

647+
if (status & TCPC_ALERT_EXTENDED_STATUS) {
648+
ret = regmap_read(tcpci->regmap, TCPC_EXTENDED_STATUS, &raw);
649+
if (!ret && (raw & TCPC_EXTENDED_STATUS_VSAFE0V))
650+
tcpm_vbus_change(tcpci->port);
651+
}
652+
627653
if (status & TCPC_ALERT_RX_HARD_RST)
628654
tcpm_pd_hard_reset(tcpci->port);
629655

@@ -701,6 +727,9 @@ struct tcpci *tcpci_register_port(struct device *dev, struct tcpci_data *data)
701727
tcpci_set_auto_vbus_discharge_threshold;
702728
}
703729

730+
if (tcpci->data->vbus_vsafe0v)
731+
tcpci->tcpc.is_vbus_vsafe0v = tcpci_is_vbus_vsafe0v;
732+
704733
err = tcpci_parse_config(tcpci);
705734
if (err < 0)
706735
return ERR_PTR(err);

drivers/usb/typec/tcpm/tcpci.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
#define TCPC_TCPC_CTRL_ORIENTATION BIT(0)
5050
#define TCPC_TCPC_CTRL_BIST_TM BIT(1)
5151

52+
#define TCPC_EXTENDED_STATUS 0x20
53+
#define TCPC_EXTENDED_STATUS_VSAFE0V BIT(0)
54+
5255
#define TCPC_ROLE_CTRL 0x1a
5356
#define TCPC_ROLE_CTRL_DRP BIT(6)
5457
#define TCPC_ROLE_CTRL_RP_VAL_SHIFT 4
@@ -155,11 +158,14 @@ struct tcpci;
155158
* is sourcing vbus.
156159
* @auto_discharge_disconnect:
157160
* Optional; Enables TCPC to autonously discharge vbus on disconnect.
161+
* @vbus_vsafe0v:
162+
* optional; Set when TCPC can detect whether vbus is at VSAFE0V.
158163
*/
159164
struct tcpci_data {
160165
struct regmap *regmap;
161166
unsigned char TX_BUF_BYTE_x_hidden:1;
162167
unsigned char auto_discharge_disconnect:1;
168+
unsigned char vbus_vsafe0v:1;
163169

164170
int (*init)(struct tcpci *tcpci, struct tcpci_data *data);
165171
int (*set_vconn)(struct tcpci *tcpci, struct tcpci_data *data,

0 commit comments

Comments
 (0)