diff options
Diffstat (limited to 'drivers/usb/mtu3/mtu3_host.c')
| -rw-r--r-- | drivers/usb/mtu3/mtu3_host.c | 115 | 
1 files changed, 56 insertions, 59 deletions
diff --git a/drivers/usb/mtu3/mtu3_host.c b/drivers/usb/mtu3/mtu3_host.c index d237d7e65c44..c871b94f3e6f 100644 --- a/drivers/usb/mtu3/mtu3_host.c +++ b/drivers/usb/mtu3/mtu3_host.c @@ -18,66 +18,77 @@  #include "mtu3.h"  #include "mtu3_dr.h" -#define PERI_WK_CTRL1		0x404 -#define UWK_CTL1_IS_C(x)	(((x) & 0xf) << 26) -#define UWK_CTL1_IS_E		BIT(25) -#define UWK_CTL1_IDDIG_C(x)	(((x) & 0xf) << 11)  /* cycle debounce */ -#define UWK_CTL1_IDDIG_E	BIT(10) /* enable debounce */ -#define UWK_CTL1_IDDIG_P	BIT(9)  /* polarity */ -#define UWK_CTL1_IS_P		BIT(6)  /* polarity for ip sleep */ +/* mt8173 etc */ +#define PERI_WK_CTRL1	0x4 +#define WC1_IS_C(x)	(((x) & 0xf) << 26)  /* cycle debounce */ +#define WC1_IS_EN	BIT(25) +#define WC1_IS_P	BIT(6)  /* polarity for ip sleep */ + +/* mt2712 etc */ +#define PERI_SSUSB_SPM_CTRL	0x0 +#define SSC_IP_SLEEP_EN	BIT(4) +#define SSC_SPM_INT_EN		BIT(1) + +enum ssusb_uwk_vers { +	SSUSB_UWK_V1 = 1, +	SSUSB_UWK_V2, +};  /*   * ip-sleep wakeup mode:   * all clocks can be turn off, but power domain should be kept on   */ -static void ssusb_wakeup_ip_sleep_en(struct ssusb_mtk *ssusb) +static void ssusb_wakeup_ip_sleep_set(struct ssusb_mtk *ssusb, bool enable)  { -	u32 tmp; -	struct regmap *pericfg = ssusb->pericfg; - -	regmap_read(pericfg, PERI_WK_CTRL1, &tmp); -	tmp &= ~UWK_CTL1_IS_P; -	tmp &= ~(UWK_CTL1_IS_C(0xf)); -	tmp |= UWK_CTL1_IS_C(0x8); -	regmap_write(pericfg, PERI_WK_CTRL1, tmp); -	regmap_write(pericfg, PERI_WK_CTRL1, tmp | UWK_CTL1_IS_E); - -	regmap_read(pericfg, PERI_WK_CTRL1, &tmp); -	dev_dbg(ssusb->dev, "%s(): WK_CTRL1[P6,E25,C26:29]=%#x\n", -		__func__, tmp); -} - -static void ssusb_wakeup_ip_sleep_dis(struct ssusb_mtk *ssusb) -{ -	u32 tmp; - -	regmap_read(ssusb->pericfg, PERI_WK_CTRL1, &tmp); -	tmp &= ~UWK_CTL1_IS_E; -	regmap_write(ssusb->pericfg, PERI_WK_CTRL1, tmp); +	u32 reg, msk, val; + +	switch (ssusb->uwk_vers) { +	case SSUSB_UWK_V1: +		reg = ssusb->uwk_reg_base + PERI_WK_CTRL1; +		msk = WC1_IS_EN | WC1_IS_C(0xf) | WC1_IS_P; +		val = enable ? (WC1_IS_EN | WC1_IS_C(0x8)) : 0; +		break; +	case SSUSB_UWK_V2: +		reg = ssusb->uwk_reg_base + PERI_SSUSB_SPM_CTRL; +		msk = SSC_IP_SLEEP_EN | SSC_SPM_INT_EN; +		val = enable ? msk : 0; +		break; +	default: +		return; +	} +	regmap_update_bits(ssusb->uwk, reg, msk, val);  }  int ssusb_wakeup_of_property_parse(struct ssusb_mtk *ssusb,  				struct device_node *dn)  { -	struct device *dev = ssusb->dev; +	struct of_phandle_args args; +	int ret; -	/* -	 * Wakeup function is optional, so it is not an error if this property -	 * does not exist, and in such case, no need to get relative -	 * properties anymore. -	 */ -	ssusb->wakeup_en = of_property_read_bool(dn, "mediatek,enable-wakeup"); -	if (!ssusb->wakeup_en) +	/* wakeup function is optional */ +	ssusb->uwk_en = of_property_read_bool(dn, "wakeup-source"); +	if (!ssusb->uwk_en)  		return 0; -	ssusb->pericfg = syscon_regmap_lookup_by_phandle(dn, -						"mediatek,syscon-wakeup"); -	if (IS_ERR(ssusb->pericfg)) { -		dev_err(dev, "fail to get pericfg regs\n"); -		return PTR_ERR(ssusb->pericfg); -	} +	ret = of_parse_phandle_with_fixed_args(dn, +				"mediatek,syscon-wakeup", 2, 0, &args); +	if (ret) +		return ret; -	return 0; +	ssusb->uwk_reg_base = args.args[0]; +	ssusb->uwk_vers = args.args[1]; +	ssusb->uwk = syscon_node_to_regmap(args.np); +	of_node_put(args.np); +	dev_info(ssusb->dev, "uwk - reg:0x%x, version:%d\n", +			ssusb->uwk_reg_base, ssusb->uwk_vers); + +	return PTR_ERR_OR_ZERO(ssusb->uwk); +} + +void ssusb_wakeup_set(struct ssusb_mtk *ssusb, bool enable) +{ +	if (ssusb->uwk_en) +		ssusb_wakeup_ip_sleep_set(ssusb, enable);  }  static void host_ports_num_get(struct ssusb_mtk *ssusb) @@ -235,17 +246,3 @@ void ssusb_host_exit(struct ssusb_mtk *ssusb)  	of_platform_depopulate(ssusb->dev);  	ssusb_host_cleanup(ssusb);  } - -int ssusb_wakeup_enable(struct ssusb_mtk *ssusb) -{ -	if (ssusb->wakeup_en) -		ssusb_wakeup_ip_sleep_en(ssusb); - -	return 0; -} - -void ssusb_wakeup_disable(struct ssusb_mtk *ssusb) -{ -	if (ssusb->wakeup_en) -		ssusb_wakeup_ip_sleep_dis(ssusb); -}  |