drivers/phy/renesas/phy-rcar-gen3-usb2.c

Source file repositories/reference/linux-study-clean/drivers/phy/renesas/phy-rcar-gen3-usb2.c

File Facts

System
Linux kernel
Corpus path
drivers/phy/renesas/phy-rcar-gen3-usb2.c
Extension
.c
Size
29253 bytes
Lines
1117
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 rcar_gen3_phy {
	struct phy *phy;
	struct rcar_gen3_chan *ch;
	u32 int_enable_bits;
	bool initialized;
	bool powered;
};

struct rcar_gen3_chan {
	void __iomem *base;
	struct device *dev;	/* platform_device's device */
	const struct rcar_gen3_phy_drv_data *phy_data;
	struct extcon_dev *extcon;
	struct reset_control *rstc;
	struct rcar_gen3_phy rphys[NUM_OF_PHYS];
	struct regulator *vbus;
	struct work_struct work;
	spinlock_t lock;	/* protects access to hardware and driver data structure. */
	enum usb_dr_mode dr_mode;
	bool extcon_host;
	bool is_otg_channel;
	bool uses_otg_pins;
	bool otg_internal_reg;
};

struct rcar_gen3_phy_drv_data {
	const struct phy_ops *phy_usb2_ops;
	bool no_adp_ctrl;
	bool init_bus;
	bool utmi_ctrl;
	bool vblvl_ctrl;
	u32 obint_enable_bits;
};

/*
 * Combination about is_otg_channel and uses_otg_pins:
 *
 * Parameters				|| Behaviors
 * is_otg_channel	| uses_otg_pins	|| irqs		| role sysfs
 * ---------------------+---------------++--------------+------------
 * true			| true		|| enabled	| enabled
 * true                 | false		|| disabled	| enabled
 * false                | any		|| disabled	| disabled
 */

static void rcar_gen3_phy_usb2_work(struct work_struct *work)
{
	struct rcar_gen3_chan *ch = container_of(work, struct rcar_gen3_chan,
						 work);

	if (ch->extcon_host) {
		extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, true);
		extcon_set_state_sync(ch->extcon, EXTCON_USB, false);
	} else {
		extcon_set_state_sync(ch->extcon, EXTCON_USB_HOST, false);
		extcon_set_state_sync(ch->extcon, EXTCON_USB, true);
	}
}

static void rcar_gen3_set_host_mode(struct rcar_gen3_chan *ch, int host)
{
	void __iomem *usb2_base = ch->base;
	u32 val = readl(usb2_base + USB2_COMMCTRL);

	dev_vdbg(ch->dev, "%s: %08x, %d\n", __func__, val, host);
	if (host)
		val &= ~USB2_COMMCTRL_OTG_PERI;
	else
		val |= USB2_COMMCTRL_OTG_PERI;
	writel(val, usb2_base + USB2_COMMCTRL);
}

static void rcar_gen3_set_linectrl(struct rcar_gen3_chan *ch, int dp, int dm)
{
	void __iomem *usb2_base = ch->base;
	u32 val = readl(usb2_base + USB2_LINECTRL1);

	dev_vdbg(ch->dev, "%s: %08x, %d, %d\n", __func__, val, dp, dm);
	val &= ~(USB2_LINECTRL1_DP_RPD | USB2_LINECTRL1_DM_RPD);
	if (dp)
		val |= USB2_LINECTRL1_DP_RPD;
	if (dm)
		val |= USB2_LINECTRL1_DM_RPD;
	writel(val, usb2_base + USB2_LINECTRL1);
}

static void rcar_gen3_phy_usb2_set_vbus(struct rcar_gen3_chan *ch,
					u32 vbus_ctrl_reg,
					u32 vbus_ctrl_val,
					bool enable)

Annotation

Implementation Notes