-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
usb: dwc3: add ULPI interface support
Registers DWC3's ULPI interface with the ULPI bus when it's available. Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> Acked-by: David Cohen <david.a.cohen@linux.intel.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
- Loading branch information
Heikki Krogerus
authored and
Felipe Balbi
committed
May 13, 2015
1 parent
a89d977
commit 88bc9d1
Showing
5 changed files
with
147 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/** | ||
* ulpi.c - DesignWare USB3 Controller's ULPI PHY interface | ||
* | ||
* Copyright (C) 2015 Intel Corporation | ||
* | ||
* Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
*/ | ||
|
||
#include <linux/ulpi/regs.h> | ||
|
||
#include "core.h" | ||
#include "io.h" | ||
|
||
#define DWC3_ULPI_ADDR(a) \ | ||
((a >= ULPI_EXT_VENDOR_SPECIFIC) ? \ | ||
DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \ | ||
DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a)) | ||
|
||
static int dwc3_ulpi_busyloop(struct dwc3 *dwc) | ||
{ | ||
unsigned count = 1000; | ||
u32 reg; | ||
|
||
while (count--) { | ||
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); | ||
if (!(reg & DWC3_GUSB2PHYACC_BUSY)) | ||
return 0; | ||
cpu_relax(); | ||
} | ||
|
||
return -ETIMEDOUT; | ||
} | ||
|
||
static int dwc3_ulpi_read(struct ulpi_ops *ops, u8 addr) | ||
{ | ||
struct dwc3 *dwc = dev_get_drvdata(ops->dev); | ||
u32 reg; | ||
int ret; | ||
|
||
reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); | ||
dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); | ||
|
||
ret = dwc3_ulpi_busyloop(dwc); | ||
if (ret) | ||
return ret; | ||
|
||
reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0)); | ||
|
||
return DWC3_GUSB2PHYACC_DATA(reg); | ||
} | ||
|
||
static int dwc3_ulpi_write(struct ulpi_ops *ops, u8 addr, u8 val) | ||
{ | ||
struct dwc3 *dwc = dev_get_drvdata(ops->dev); | ||
u32 reg; | ||
|
||
reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr); | ||
reg |= DWC3_GUSB2PHYACC_WRITE | val; | ||
dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg); | ||
|
||
return dwc3_ulpi_busyloop(dwc); | ||
} | ||
|
||
static struct ulpi_ops dwc3_ulpi_ops = { | ||
.read = dwc3_ulpi_read, | ||
.write = dwc3_ulpi_write, | ||
}; | ||
|
||
int dwc3_ulpi_init(struct dwc3 *dwc) | ||
{ | ||
/* Register the interface */ | ||
dwc->ulpi = ulpi_register_interface(dwc->dev, &dwc3_ulpi_ops); | ||
if (IS_ERR(dwc->ulpi)) { | ||
dev_err(dwc->dev, "failed to register ULPI interface"); | ||
return PTR_ERR(dwc->ulpi); | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
void dwc3_ulpi_exit(struct dwc3 *dwc) | ||
{ | ||
if (dwc->ulpi) { | ||
ulpi_unregister_interface(dwc->ulpi); | ||
dwc->ulpi = NULL; | ||
} | ||
} |