drivers/phy/freescale/phy-fsl-imx8mq-usb.c

Source file repositories/reference/linux-study-clean/drivers/phy/freescale/phy-fsl-imx8mq-usb.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/freescale/phy-fsl-imx8mq-usb.c
Extension
.c
Size
19119 bytes
Lines
762
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 tca_blk {
	struct typec_switch_dev *sw;
	void __iomem *base;
	struct mutex mutex;
	enum typec_orientation orientation;
};

struct imx8mq_usb_phy {
	struct phy *phy;
	struct clk *clk;
	struct clk *alt_clk;
	void __iomem *base;
	struct regulator *vbus;
	struct tca_blk *tca;
	u32 pcs_tx_swing_full;
	u32 pcs_tx_deemph_3p5db;
	u32 tx_vref_tune;
	u32 tx_rise_tune;
	u32 tx_preemp_amp_tune;
	u32 tx_vboost_level;
	u32 comp_dis_tune;
};


static void tca_blk_orientation_set(struct tca_blk *tca,
				enum typec_orientation orientation);

static int tca_blk_typec_switch_set(struct typec_switch_dev *sw,
				enum typec_orientation orientation)
{
	struct imx8mq_usb_phy *imx_phy = typec_switch_get_drvdata(sw);
	struct tca_blk *tca = imx_phy->tca;
	int ret;

	if (tca->orientation == orientation)
		return 0;

	ret = clk_prepare_enable(imx_phy->clk);
	if (ret)
		return ret;

	tca_blk_orientation_set(tca, orientation);
	clk_disable_unprepare(imx_phy->clk);

	return 0;
}

static struct typec_switch_dev *tca_blk_get_typec_switch(struct platform_device *pdev,
					struct imx8mq_usb_phy *imx_phy)
{
	struct device *dev = &pdev->dev;
	struct typec_switch_dev *sw;
	struct typec_switch_desc sw_desc = { };

	sw_desc.drvdata = imx_phy;
	sw_desc.fwnode = dev->fwnode;
	sw_desc.set = tca_blk_typec_switch_set;
	sw_desc.name = NULL;

	sw = typec_switch_register(dev, &sw_desc);
	if (IS_ERR(sw)) {
		dev_err(dev, "Error register tca orientation switch: %ld",
				PTR_ERR(sw));
		return NULL;
	}

	return sw;
}

static void tca_blk_put_typec_switch(struct typec_switch_dev *sw)
{
	typec_switch_unregister(sw);
}

static void tca_blk_orientation_set(struct tca_blk *tca,
				enum typec_orientation orientation)
{
	u32 val;

	mutex_lock(&tca->mutex);

	if (orientation == TYPEC_ORIENTATION_NONE) {
		/*
		 * use Controller Synced Mode for TCA low power enable and
		 * put PHY to USB safe state.
		 */
		val = FIELD_PREP(TCA_GCFG_OP_MODE, TCA_GCFG_OP_MODE_SYNCMODE);
		writel(val, tca->base + TCA_GCFG);

		val = TCA_TCPC_VALID | TCA_TCPC_LOW_POWER_EN;

Annotation

Implementation Notes