drivers/phy/ti/phy-gmii-sel.c

Source file repositories/reference/linux-study-clean/drivers/phy/ti/phy-gmii-sel.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/ti/phy-gmii-sel.c
Extension
.c
Size
15620 bytes
Lines
574
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 phy_gmii_sel_phy_priv {
	struct phy_gmii_sel_priv *priv;
	u32		id;
	struct phy	*if_phy;
	int		rmii_clock_external;
	int		phy_if_mode;
	struct regmap_field *fields[PHY_GMII_SEL_LAST];
};

struct phy_gmii_sel_soc_data {
	u32 num_ports;
	u32 features;
	const struct reg_field (*regfields)[PHY_GMII_SEL_LAST];
	bool use_of_data;
	u64 extra_modes;
	u32 num_qsgmii_main_ports;
};

struct phy_gmii_sel_priv {
	struct device *dev;
	const struct phy_gmii_sel_soc_data *soc_data;
	struct regmap *regmap;
	struct phy_provider *phy_provider;
	struct phy_gmii_sel_phy_priv *if_phys;
	u32 num_ports;
	u32 reg_offset;
	u32 qsgmii_main_ports;
	bool no_offset;
};

static int phy_gmii_sel_mode(struct phy *phy, enum phy_mode mode, int submode)
{
	struct phy_gmii_sel_phy_priv *if_phy = phy_get_drvdata(phy);
	const struct phy_gmii_sel_soc_data *soc_data = if_phy->priv->soc_data;
	struct device *dev = if_phy->priv->dev;
	struct regmap_field *regfield;
	int ret, rgmii_id = 0;
	u32 gmii_sel_mode = 0;

	if (mode != PHY_MODE_ETHERNET)
		return -EINVAL;

	switch (submode) {
	case PHY_INTERFACE_MODE_RMII:
		gmii_sel_mode = AM33XX_GMII_SEL_MODE_RMII;
		break;

	case PHY_INTERFACE_MODE_RGMII:
	case PHY_INTERFACE_MODE_RGMII_RXID:
		gmii_sel_mode = AM33XX_GMII_SEL_MODE_RGMII;
		break;

	case PHY_INTERFACE_MODE_RGMII_ID:
	case PHY_INTERFACE_MODE_RGMII_TXID:
		gmii_sel_mode = AM33XX_GMII_SEL_MODE_RGMII;
		rgmii_id = 1;
		break;

	case PHY_INTERFACE_MODE_MII:
	case PHY_INTERFACE_MODE_GMII:
		gmii_sel_mode = AM33XX_GMII_SEL_MODE_MII;
		break;

	case PHY_INTERFACE_MODE_QSGMII:
		if (!(soc_data->extra_modes & BIT(PHY_INTERFACE_MODE_QSGMII)))
			goto unsupported;
		if (if_phy->priv->qsgmii_main_ports & BIT(if_phy->id - 1))
			gmii_sel_mode = J72XX_GMII_SEL_MODE_QSGMII;
		else
			gmii_sel_mode = J72XX_GMII_SEL_MODE_QSGMII_SUB;
		break;

	case PHY_INTERFACE_MODE_SGMII:
		if (!(soc_data->extra_modes & BIT(PHY_INTERFACE_MODE_SGMII)))
			goto unsupported;
		else
			gmii_sel_mode = J72XX_GMII_SEL_MODE_SGMII;
		break;

	case PHY_INTERFACE_MODE_USXGMII:
		if (!(soc_data->extra_modes & BIT(PHY_INTERFACE_MODE_USXGMII)))
			goto unsupported;
		else
			gmii_sel_mode = J72XX_GMII_SEL_MODE_USXGMII;
		break;

	default:
		goto unsupported;
	}

Annotation

Implementation Notes