drivers/phy/ti/phy-tusb1210.c

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

File Facts

System
Linux kernel
Corpus path
drivers/phy/ti/phy-tusb1210.c
Extension
.c
Size
16443 bytes
Lines
587
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 tusb1210 {
	struct device *dev;
	struct phy *phy;
	struct gpio_desc *gpio_reset;
	struct gpio_desc *gpio_cs;
	u8 otg_ctrl;
	u8 vendor_specific2;
#ifdef CONFIG_POWER_SUPPLY
	enum power_supply_usb_type chg_type;
	enum tusb1210_chg_det_state chg_det_state;
	int chg_det_retries;
	struct delayed_work chg_det_work;
	struct notifier_block psy_nb;
	struct power_supply *psy;
#endif
};

static int tusb1210_ulpi_write(struct tusb1210 *tusb, u8 reg, u8 val)
{
	struct device *dev = tusb->dev;
	int ret;

	ret = ulpi_write(to_ulpi_dev(dev), reg, val);
	if (ret)
		dev_err(dev, "error %d writing val 0x%02x to reg 0x%02x\n", ret, val, reg);

	return ret;
}

static int tusb1210_ulpi_read(struct tusb1210 *tusb, u8 reg, u8 *val)
{
	struct device *dev = tusb->dev;
	int ret;

	ret = ulpi_read(to_ulpi_dev(dev), reg);
	if (ret >= 0) {
		*val = ret;
		ret = 0;
	} else {
		dev_err(dev, "error %d reading reg 0x%02x\n", ret, reg);
	}

	return ret;
}

static int tusb1210_power_on(struct phy *phy)
{
	struct tusb1210 *tusb = phy_get_drvdata(phy);

	gpiod_set_value_cansleep(tusb->gpio_reset, 1);
	gpiod_set_value_cansleep(tusb->gpio_cs, 1);

	msleep(TUSB1210_RESET_TIME_MS);

	/* Restore the optional eye diagram optimization value */
	tusb1210_ulpi_write(tusb, TUSB1210_VENDOR_SPECIFIC2, tusb->vendor_specific2);

	return 0;
}

static int tusb1210_power_off(struct phy *phy)
{
	struct tusb1210 *tusb = phy_get_drvdata(phy);

	gpiod_set_value_cansleep(tusb->gpio_reset, 0);
	gpiod_set_value_cansleep(tusb->gpio_cs, 0);

	return 0;
}

static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
	struct tusb1210 *tusb = phy_get_drvdata(phy);
	int ret;
	u8 reg;

	ret = tusb1210_ulpi_read(tusb, ULPI_OTG_CTRL, &reg);
	if (ret < 0)
		return ret;

	switch (mode) {
	case PHY_MODE_USB_HOST:
		reg |= (ULPI_OTG_CTRL_DRVVBUS_EXT
			| ULPI_OTG_CTRL_ID_PULLUP
			| ULPI_OTG_CTRL_DP_PULLDOWN
			| ULPI_OTG_CTRL_DM_PULLDOWN);
		tusb1210_ulpi_write(tusb, ULPI_OTG_CTRL, reg);
		reg |= ULPI_OTG_CTRL_DRVVBUS;
		break;
	case PHY_MODE_USB_DEVICE:

Annotation

Implementation Notes