drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c

Source file repositories/reference/linux-study-clean/drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/typec/tcpm/qcom/qcom_pmic_typec_port.c
Extension
.c
Size
21327 bytes
Lines
810
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct pmic_typec_port_irq_data {
	int				virq;
	int				irq;
	struct pmic_typec_port		*pmic_typec_port;
};

struct pmic_typec_port {
	struct device			*dev;
	struct tcpm_port		*tcpm_port;
	struct regmap			*regmap;
	u32				base;
	unsigned int			nr_irqs;
	struct pmic_typec_port_irq_data	*irq_data;

	struct regulator		*vdd_vbus;
	bool				vbus_enabled;
	struct mutex			vbus_lock;		/* VBUS state serialization */

	int				cc;
	bool				debouncing_cc;
	struct delayed_work		cc_debounce_dwork;

	spinlock_t			lock;	/* Register atomicity */
};

static const char * const typec_cc_status_name[] = {
	[TYPEC_CC_OPEN]		= "Open",
	[TYPEC_CC_RA]		= "Ra",
	[TYPEC_CC_RD]		= "Rd",
	[TYPEC_CC_RP_DEF]	= "Rp-def",
	[TYPEC_CC_RP_1_5]	= "Rp-1.5",
	[TYPEC_CC_RP_3_0]	= "Rp-3.0",
};

static const char *rp_unknown = "unknown";

static const char *cc_to_name(enum typec_cc_status cc)
{
	if (cc > TYPEC_CC_RP_3_0)
		return rp_unknown;

	return typec_cc_status_name[cc];
}

static const char * const rp_sel_name[] = {
	[TYPEC_SRC_RP_SEL_80UA]		= "Rp-def-80uA",
	[TYPEC_SRC_RP_SEL_180UA]	= "Rp-1.5-180uA",
	[TYPEC_SRC_RP_SEL_330UA]	= "Rp-3.0-330uA",
};

static const char *rp_sel_to_name(int rp_sel)
{
	if (rp_sel > TYPEC_SRC_RP_SEL_330UA)
		return rp_unknown;

	return rp_sel_name[rp_sel];
}

#define misc_to_cc(msic) !!(misc & CC_ORIENTATION) ? "cc1" : "cc2"
#define misc_to_vconn(msic) !!(misc & CC_ORIENTATION) ? "cc2" : "cc1"

static void qcom_pmic_typec_port_cc_debounce(struct work_struct *work)
{
	struct pmic_typec_port *pmic_typec_port =
		container_of(work, struct pmic_typec_port, cc_debounce_dwork.work);
	unsigned long flags;

	spin_lock_irqsave(&pmic_typec_port->lock, flags);
	pmic_typec_port->debouncing_cc = false;
	spin_unlock_irqrestore(&pmic_typec_port->lock, flags);

	dev_dbg(pmic_typec_port->dev, "Debounce cc complete\n");
}

static irqreturn_t pmic_typec_port_isr(int irq, void *dev_id)
{
	struct pmic_typec_port_irq_data *irq_data = dev_id;
	struct pmic_typec_port *pmic_typec_port = irq_data->pmic_typec_port;
	u32 misc_stat;
	bool vbus_change = false;
	bool cc_change = false;
	unsigned long flags;
	int ret;

	spin_lock_irqsave(&pmic_typec_port->lock, flags);

	ret = regmap_read(pmic_typec_port->regmap,
			  pmic_typec_port->base + TYPEC_MISC_STATUS_REG,
			  &misc_stat);
	if (ret)

Annotation

Implementation Notes