Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 943c1397 authored by Felipe Balbi's avatar Felipe Balbi
Browse files

usb: musb: dsps: implement ->set_mode()



this will let us support broken designs such
as AM335x EVM SK where ID pin isn't routed
anywhere on a host port.

With this we can toggle internal IDDIG signal
and make sure MUSB goes into host mode as
necessary.

Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 989c78dd
Loading
Loading
Loading
Loading
+51 −0
Original line number Original line Diff line number Diff line
@@ -106,6 +106,7 @@ struct dsps_musb_wrapper {


	/* bit positions for mode */
	/* bit positions for mode */
	unsigned	iddig:5;
	unsigned	iddig:5;
	unsigned	iddig_mux:5;
	/* miscellaneous stuff */
	/* miscellaneous stuff */
	u8		poll_seconds;
	u8		poll_seconds;
};
};
@@ -406,6 +407,54 @@ static int dsps_musb_exit(struct musb *musb)
	return 0;
	return 0;
}
}


static int dsps_musb_set_mode(struct musb *musb, u8 mode)
{
	struct device *dev = musb->controller;
	struct dsps_glue *glue = dev_get_drvdata(dev->parent);
	const struct dsps_musb_wrapper *wrp = glue->wrp;
	void __iomem *ctrl_base = musb->ctrl_base;
	void __iomem *base = musb->mregs;
	u32 reg;

	reg = dsps_readl(base, wrp->mode);

	switch (mode) {
	case MUSB_HOST:
		reg &= ~(1 << wrp->iddig);

		/*
		 * if we're setting mode to host-only or device-only, we're
		 * going to ignore whatever the PHY sends us and just force
		 * ID pin status by SW
		 */
		reg |= (1 << wrp->iddig_mux);

		dsps_writel(base, wrp->mode, reg);
		dsps_writel(ctrl_base, wrp->phy_utmi, 0x02);
		break;
	case MUSB_PERIPHERAL:
		reg |= (1 << wrp->iddig);

		/*
		 * if we're setting mode to host-only or device-only, we're
		 * going to ignore whatever the PHY sends us and just force
		 * ID pin status by SW
		 */
		reg |= (1 << wrp->iddig_mux);

		dsps_writel(base, wrp->mode, reg);
		break;
	case MUSB_OTG:
		dsps_writel(base, wrp->phy_utmi, 0x02);
		break;
	default:
		dev_err(glue->dev, "unsupported mode %d\n", mode);
		return -EINVAL;
	}

	return 0;
}

static struct musb_platform_ops dsps_ops = {
static struct musb_platform_ops dsps_ops = {
	.init		= dsps_musb_init,
	.init		= dsps_musb_init,
	.exit		= dsps_musb_exit,
	.exit		= dsps_musb_exit,
@@ -414,6 +463,7 @@ static struct musb_platform_ops dsps_ops = {
	.disable	= dsps_musb_disable,
	.disable	= dsps_musb_disable,


	.try_idle	= dsps_musb_try_idle,
	.try_idle	= dsps_musb_try_idle,
	.set_mode	= dsps_musb_set_mode,
};
};


static u64 musb_dmamask = DMA_BIT_MASK(32);
static u64 musb_dmamask = DMA_BIT_MASK(32);
@@ -608,6 +658,7 @@ static const struct dsps_musb_wrapper am33xx_driver_data = {
	.reset			= 0,
	.reset			= 0,
	.otg_disable		= 21,
	.otg_disable		= 21,
	.iddig			= 8,
	.iddig			= 8,
	.iddig_mux		= 7,
	.usb_shift		= 0,
	.usb_shift		= 0,
	.usb_mask		= 0x1ff,
	.usb_mask		= 0x1ff,
	.usb_bitmap		= (0x1ff << 0),
	.usb_bitmap		= (0x1ff << 0),