drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c

Source file repositories/reference/linux-study-clean/drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/qualcomm/phy-qcom-usb-hs-28nm.c
Extension
.c
Size
9482 bytes
Lines
426
Domain
Driver Families
Bucket
drivers/phy
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 hsphy_init_seq {
	int offset;
	int val;
	int delay;
};

struct hsphy_data {
	const struct hsphy_init_seq *init_seq;
	unsigned int init_seq_num;
};

struct hsphy_priv {
	void __iomem *base;
	struct clk_bulk_data *clks;
	int num_clks;
	struct reset_control *phy_reset;
	struct reset_control *por_reset;
	struct regulator_bulk_data vregs[VREG_NUM];
	const struct hsphy_data *data;
	enum phy_mode mode;
};

static int qcom_snps_hsphy_set_mode(struct phy *phy, enum phy_mode mode,
				    int submode)
{
	struct hsphy_priv *priv = phy_get_drvdata(phy);

	priv->mode = PHY_MODE_INVALID;

	if (mode > 0)
		priv->mode = mode;

	return 0;
}

static void qcom_snps_hsphy_enable_hv_interrupts(struct hsphy_priv *priv)
{
	u32 val;

	/* Clear any existing interrupts before enabling the interrupts */
	val = readb(priv->base + PHY_INTR_CLEAR0);
	val |= DPDM_MASK;
	writeb(val, priv->base + PHY_INTR_CLEAR0);

	writeb(0x0, priv->base + PHY_IRQ_CMD);
	usleep_range(200, 220);
	writeb(0x1, priv->base + PHY_IRQ_CMD);

	/* Make sure the interrupts are cleared */
	usleep_range(200, 220);

	val = readb(priv->base + PHY_INTR_MASK0);
	switch (priv->mode) {
	case PHY_MODE_USB_HOST_HS:
	case PHY_MODE_USB_HOST_FS:
	case PHY_MODE_USB_DEVICE_HS:
	case PHY_MODE_USB_DEVICE_FS:
		val |= DP_1_0 | DM_0_1;
		break;
	case PHY_MODE_USB_HOST_LS:
	case PHY_MODE_USB_DEVICE_LS:
		val |= DP_0_1 | DM_1_0;
		break;
	default:
		/* No device connected */
		val |= DP_0_1 | DM_0_1;
		break;
	}
	writeb(val, priv->base + PHY_INTR_MASK0);
}

static void qcom_snps_hsphy_disable_hv_interrupts(struct hsphy_priv *priv)
{
	u32 val;

	val = readb(priv->base + PHY_INTR_MASK0);
	val &= ~DPDM_MASK;
	writeb(val, priv->base + PHY_INTR_MASK0);

	/* Clear any pending interrupts */
	val = readb(priv->base + PHY_INTR_CLEAR0);
	val |= DPDM_MASK;
	writeb(val, priv->base + PHY_INTR_CLEAR0);

	writeb(0x0, priv->base + PHY_IRQ_CMD);
	usleep_range(200, 220);

	writeb(0x1, priv->base + PHY_IRQ_CMD);
	usleep_range(200, 220);
}

Annotation

Implementation Notes