drivers/usb/phy/phy-mxs-usb.c

Source file repositories/reference/linux-study-clean/drivers/usb/phy/phy-mxs-usb.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/phy/phy-mxs-usb.c
Extension
.c
Size
27333 bytes
Lines
978
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 mxs_phy_data {
	unsigned int flags;
};

static const struct mxs_phy_data imx23_phy_data = {
	.flags = MXS_PHY_ABNORMAL_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST,
};

static const struct mxs_phy_data imx6q_phy_data = {
	.flags = MXS_PHY_SENDING_SOF_TOO_FAST |
		MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
		MXS_PHY_NEED_IP_FIX |
		MXS_PHY_HARDWARE_CONTROL_PHY2_CLK,
};

static const struct mxs_phy_data imx6sl_phy_data = {
	.flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
		MXS_PHY_NEED_IP_FIX |
		MXS_PHY_HARDWARE_CONTROL_PHY2_CLK,
};

static const struct mxs_phy_data vf610_phy_data = {
	.flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
		MXS_PHY_NEED_IP_FIX,
};

static const struct mxs_phy_data imx6sx_phy_data = {
	.flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
		MXS_PHY_HARDWARE_CONTROL_PHY2_CLK,
};

static const struct mxs_phy_data imx6ul_phy_data = {
	.flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
		MXS_PHY_HARDWARE_CONTROL_PHY2_CLK,
};

static const struct mxs_phy_data imx7ulp_phy_data = {
};

static const struct of_device_id mxs_phy_dt_ids[] = {
	{ .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
	{ .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
	{ .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
	{ .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
	{ .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
	{ .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
	{ .compatible = "fsl,imx7ulp-usbphy", .data = &imx7ulp_phy_data, },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);

struct mxs_phy {
	struct usb_phy phy;
	struct clk *clk;
	const struct mxs_phy_data *data;
	struct regmap *regmap_anatop;
	struct regmap *regmap_sim;
	int port_id;
	u32 tx_reg_set;
	u32 tx_reg_mask;
	struct regulator *phy_3p0;
};

static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy)
{
	return mxs_phy->data == &imx6q_phy_data;
}

static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
{
	return mxs_phy->data == &imx6sl_phy_data;
}

static inline bool is_imx7ulp_phy(struct mxs_phy *mxs_phy)
{
	return mxs_phy->data == &imx7ulp_phy_data;
}

static inline bool is_imx6ul_phy(struct mxs_phy *mxs_phy)
{
	return mxs_phy->data == &imx6ul_phy_data;
}

/*
 * PHY needs some 32K cycles to switch from 32K clock to
 * bus (such as AHB/AXI, etc) clock.
 */
static void mxs_phy_clock_switch_delay(void)
{
	usleep_range(300, 400);

Annotation

Implementation Notes