diff options
Diffstat (limited to 'drivers/usb/host/pci-quirks.c')
| -rw-r--r-- | drivers/usb/host/pci-quirks.c | 54 | 
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index a9a1e4c40480..c8989c62a262 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c @@ -77,6 +77,16 @@  #define USB_INTEL_USB3_PSSEN   0xD8  #define USB_INTEL_USB3PRM      0xDC +/* ASMEDIA quirk use */ +#define ASMT_DATA_WRITE0_REG	0xF8 +#define ASMT_DATA_WRITE1_REG	0xFC +#define ASMT_CONTROL_REG	0xE0 +#define ASMT_CONTROL_WRITE_BIT	0x02 +#define ASMT_WRITEREG_CMD	0x10423 +#define ASMT_FLOWCTL_ADDR	0xFA30 +#define ASMT_FLOWCTL_DATA	0xBA +#define ASMT_PSEUDO_DATA	0 +  /*   * amd_chipset_gen values represent AMD different chipset generations   */ @@ -412,6 +422,50 @@ void usb_amd_quirk_pll_disable(void)  }  EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_disable); +static int usb_asmedia_wait_write(struct pci_dev *pdev) +{ +	unsigned long retry_count; +	unsigned char value; + +	for (retry_count = 1000; retry_count > 0; --retry_count) { + +		pci_read_config_byte(pdev, ASMT_CONTROL_REG, &value); + +		if (value == 0xff) { +			dev_err(&pdev->dev, "%s: check_ready ERROR", __func__); +			return -EIO; +		} + +		if ((value & ASMT_CONTROL_WRITE_BIT) == 0) +			return 0; + +		usleep_range(40, 60); +	} + +	dev_warn(&pdev->dev, "%s: check_write_ready timeout", __func__); +	return -ETIMEDOUT; +} + +void usb_asmedia_modifyflowcontrol(struct pci_dev *pdev) +{ +	if (usb_asmedia_wait_write(pdev) != 0) +		return; + +	/* send command and address to device */ +	pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_WRITEREG_CMD); +	pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_FLOWCTL_ADDR); +	pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT); + +	if (usb_asmedia_wait_write(pdev) != 0) +		return; + +	/* send data to device */ +	pci_write_config_dword(pdev, ASMT_DATA_WRITE0_REG, ASMT_FLOWCTL_DATA); +	pci_write_config_dword(pdev, ASMT_DATA_WRITE1_REG, ASMT_PSEUDO_DATA); +	pci_write_config_byte(pdev, ASMT_CONTROL_REG, ASMT_CONTROL_WRITE_BIT); +} +EXPORT_SYMBOL_GPL(usb_asmedia_modifyflowcontrol); +  void usb_amd_quirk_pll_enable(void)  {  	usb_amd_quirk_pll(0);  | 
