mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 14:42:24 +00:00
USB/PHY patches for 4.13-rc1
Here is the big patchset of USB and PHY driver updates for 4.13-rc1. On the PHY side, they decided to move files around to "make things easier" in their tree. Hopefully that wasn't a mistake, but in linux-next testing, we haven't had any reported problems. There's the usual set of gadget and xhci and musb updates in here as well, along with a number of smaller updates for a raft of different USB drivers. Full details in the shortlog, nothing really major. All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWVpavQ8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymJrgCgp8Pso8bs+bnIknUSQFSguWd3wM0AnA8X3NHf lrdCuqw+2oxGOQrecacz =5L4Q -----END PGP SIGNATURE----- Merge tag 'usb-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb Pull USB/PHY updates from Greg KH: "Here is the big patchset of USB and PHY driver updates for 4.13-rc1. On the PHY side, they decided to move files around to "make things easier" in their tree. Hopefully that wasn't a mistake, but in linux-next testing, we haven't had any reported problems. There's the usual set of gadget and xhci and musb updates in here as well, along with a number of smaller updates for a raft of different USB drivers. Full details in the shortlog, nothing really major. All of these have been in linux-next for a while with no reported issues" * tag 'usb-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (173 commits) Add USB quirk for HVR-950q to avoid intermittent device resets USB hub_probe: rework ugly goto-into-compound-statement usb: host: ohci-pxa27x: Handle return value of clk_prepare_enable USB: serial: cp210x: add ID for CEL EM3588 USB ZigBee stick usbip: Fix uninitialized variable bug in vhci usb: core: read USB ports from DT in the usbport LED trigger driver dt-bindings: leds: document new trigger-sources property usb: typec: ucsi: Add ACPI driver usb: typec: Add support for UCSI interface usb: musb: compress return logic into one line USB: serial: propagate late probe errors USB: serial: refactor port endpoint setup usb: musb: tusb6010_omap: Convert to DMAengine API ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines usb: musb: tusb6010: Handle DMA TX completion in DMA callback as well usb: musb: tusb6010_omap: Allocate DMA channels upfront usb: musb: tusb6010_omap: Create new struct for DMA data/parameters usb: musb: tusb6010_omap: Use one musb_ep_select call in tusb_omap_dma_program usb: musb: tusb6010: Add MUSB_G_NO_SKB_RESERVE to quirks usb: musb: Add quirk to avoid skb reserve in gadget mode ...
This commit is contained in:
commit
362f6729cb
@ -55,14 +55,6 @@ Description:
|
||||
Indicates the maximum USB speed supported by this port.
|
||||
Users:
|
||||
|
||||
What: /sys/class/udc/<udc>/maximum_speed
|
||||
Date: June 2011
|
||||
KernelVersion: 3.1
|
||||
Contact: Felipe Balbi <balbi@kernel.org>
|
||||
Description:
|
||||
Indicates the maximum USB speed supported by this port.
|
||||
Users:
|
||||
|
||||
What: /sys/class/udc/<udc>/soft_connect
|
||||
Date: June 2011
|
||||
KernelVersion: 3.1
|
||||
@ -91,3 +83,11 @@ Description:
|
||||
'configured', and 'suspended'; however not all USB Device
|
||||
Controllers support reporting all states.
|
||||
Users:
|
||||
|
||||
What: /sys/class/udc/<udc>/function
|
||||
Date: June 2017
|
||||
KernelVersion: 4.13
|
||||
Contact: Felipe Balbi <balbi@kernel.org>
|
||||
Description:
|
||||
Prints out name of currently running USB Gadget Driver.
|
||||
Users:
|
||||
|
@ -1,12 +1,14 @@
|
||||
What: /config/usb-gadget/gadget/functions/uac1.name
|
||||
Date: Sep 2014
|
||||
KernelVersion: 3.18
|
||||
Date: June 2017
|
||||
KernelVersion: 4.14
|
||||
Description:
|
||||
The attributes:
|
||||
|
||||
audio_buf_size - audio buffer size
|
||||
fn_cap - capture pcm device file name
|
||||
fn_cntl - control device file name
|
||||
fn_play - playback pcm device file name
|
||||
req_buf_size - ISO OUT endpoint request buffer size
|
||||
req_count - ISO OUT endpoint request count
|
||||
c_chmask - capture channel mask
|
||||
c_srate - capture sampling rate
|
||||
c_ssize - capture sample size (bytes)
|
||||
p_chmask - playback channel mask
|
||||
p_srate - playback sampling rate
|
||||
p_ssize - playback sample size (bytes)
|
||||
req_number - the number of pre-allocated request
|
||||
for both capture and playback
|
||||
|
12
Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy
Normal file
12
Documentation/ABI/testing/configfs-usb-gadget-uac1_legacy
Normal file
@ -0,0 +1,12 @@
|
||||
What: /config/usb-gadget/gadget/functions/uac1_legacy.name
|
||||
Date: Sep 2014
|
||||
KernelVersion: 3.18
|
||||
Description:
|
||||
The attributes:
|
||||
|
||||
audio_buf_size - audio buffer size
|
||||
fn_cap - capture pcm device file name
|
||||
fn_cntl - control device file name
|
||||
fn_play - playback pcm device file name
|
||||
req_buf_size - ISO OUT endpoint request buffer size
|
||||
req_count - ISO OUT endpoint request count
|
@ -30,6 +30,21 @@ Description:
|
||||
|
||||
Valid values: source, sink
|
||||
|
||||
What: /sys/class/typec/<port>/port_type
|
||||
Date: May 2017
|
||||
Contact: Badhri Jagan Sridharan <Badhri@google.com>
|
||||
Description:
|
||||
Indicates the type of the port. This attribute can be used for
|
||||
requesting a change in the port type. Port type change is
|
||||
supported as a synchronous operation, so write(2) to the
|
||||
attribute will not return until the operation has finished.
|
||||
|
||||
Valid values:
|
||||
- source (The port will behave as source only DFP port)
|
||||
- sink (The port will behave as sink only UFP port)
|
||||
- dual (The port will behave as dual-role-data and
|
||||
dual-role-power port)
|
||||
|
||||
What: /sys/class/typec/<port>/vconn_source
|
||||
Date: April 2017
|
||||
Contact: Heikki Krogerus <heikki.krogerus@linux.intel.com>
|
||||
|
@ -1,4 +1,4 @@
|
||||
Common leds properties.
|
||||
* Common leds properties.
|
||||
|
||||
LED and flash LED devices provide the same basic functionality as current
|
||||
regulators, but extended with LED and flash LED specific features like
|
||||
@ -49,6 +49,22 @@ Optional properties for child nodes:
|
||||
- panic-indicator : This property specifies that the LED should be used,
|
||||
if at all possible, as a panic indicator.
|
||||
|
||||
- trigger-sources : List of devices which should be used as a source triggering
|
||||
this LED activity. Some LEDs can be related to a specific
|
||||
device and should somehow indicate its state. E.g. USB 2.0
|
||||
LED may react to device(s) in a USB 2.0 port(s).
|
||||
Another common example is switch or router with multiple
|
||||
Ethernet ports each of them having its own LED assigned
|
||||
(assuming they are not hardwired). In such cases this
|
||||
property should contain phandle(s) of related source
|
||||
device(s).
|
||||
In many cases LED can be related to more than one device
|
||||
(e.g. one USB LED vs. multiple USB ports). Each source
|
||||
should be represented by a node in the device tree and be
|
||||
referenced by a phandle and a set of phandle arguments. A
|
||||
length of arguments should be specified by the
|
||||
#trigger-source-cells property in the source node.
|
||||
|
||||
Required properties for flash LED child nodes:
|
||||
- flash-max-microamp : Maximum flash LED supply current in microamperes.
|
||||
- flash-max-timeout-us : Maximum timeout in microseconds after which the flash
|
||||
@ -59,7 +75,17 @@ property can be omitted.
|
||||
For controllers that have no configurable timeout the flash-max-timeout-us
|
||||
property can be omitted.
|
||||
|
||||
Examples:
|
||||
* Trigger source providers
|
||||
|
||||
Each trigger source should be represented by a device tree node. It may be e.g.
|
||||
a USB port or an Ethernet device.
|
||||
|
||||
Required properties for trigger source:
|
||||
- #trigger-source-cells : Number of cells in a source trigger. Typically 0 for
|
||||
nodes of simple trigger sources (e.g. a specific USB
|
||||
port).
|
||||
|
||||
* Examples
|
||||
|
||||
gpio-leds {
|
||||
compatible = "gpio-leds";
|
||||
@ -69,6 +95,11 @@ gpio-leds {
|
||||
linux,default-trigger = "heartbeat";
|
||||
gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
usb {
|
||||
gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
|
||||
trigger-sources = <&ohci_port1>, <&ehci_port1>;
|
||||
};
|
||||
};
|
||||
|
||||
max77693-led {
|
||||
|
@ -3,9 +3,10 @@ Driver for Broadcom Northstar USB 3.0 PHY
|
||||
Required properties:
|
||||
|
||||
- compatible: one of: "brcm,ns-ax-usb3-phy", "brcm,ns-bx-usb3-phy".
|
||||
- reg: register mappings for DMP (Device Management Plugin) and ChipCommon B
|
||||
MMI.
|
||||
- reg-names: "dmp" and "ccb-mii"
|
||||
- reg: address of MDIO bus device
|
||||
- usb3-dmp-syscon: phandle to syscon with DMP (Device Management Plugin)
|
||||
registers
|
||||
- #phy-cells: must be 0
|
||||
|
||||
Initialization of USB 3.0 PHY depends on Northstar version. There are currently
|
||||
three known series: Ax, Bx and Cx.
|
||||
@ -15,9 +16,19 @@ Known B1: BCM4707 rev 6
|
||||
Known C0: BCM47094 rev 0
|
||||
|
||||
Example:
|
||||
usb3-phy {
|
||||
mdio: mdio@0 {
|
||||
reg = <0x0>;
|
||||
#size-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
|
||||
usb3-phy@10 {
|
||||
compatible = "brcm,ns-ax-usb3-phy";
|
||||
reg = <0x18105000 0x1000>, <0x18003000 0x1000>;
|
||||
reg-names = "dmp", "ccb-mii";
|
||||
reg = <0x10>;
|
||||
usb3-dmp-syscon = <&usb3_dmp>;
|
||||
#phy-cells = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
usb3_dmp: syscon@18105000 {
|
||||
reg = <0x18105000 0x1000>;
|
||||
};
|
||||
|
30
Documentation/devicetree/bindings/phy/brcm,ns2-drd-phy.txt
Normal file
30
Documentation/devicetree/bindings/phy/brcm,ns2-drd-phy.txt
Normal file
@ -0,0 +1,30 @@
|
||||
BROADCOM NORTHSTAR2 USB2 (DUAL ROLE DEVICE) PHY
|
||||
|
||||
Required properties:
|
||||
- compatible: brcm,ns2-drd-phy
|
||||
- reg: offset and length of the NS2 PHY related registers.
|
||||
- reg-names
|
||||
The below registers must be provided.
|
||||
icfg - for DRD ICFG configurations
|
||||
rst-ctrl - for DRD IDM reset
|
||||
crmu-ctrl - for CRMU core vdd, PHY and PHY PLL reset
|
||||
usb2-strap - for port over current polarity reversal
|
||||
- #phy-cells: Must be 0. No args required.
|
||||
- vbus-gpios: vbus gpio binding
|
||||
- id-gpios: id gpio binding
|
||||
|
||||
Refer to phy/phy-bindings.txt for the generic PHY binding properties
|
||||
|
||||
Example:
|
||||
usbdrd_phy: phy@66000960 {
|
||||
#phy-cells = <0>;
|
||||
compatible = "brcm,ns2-drd-phy";
|
||||
reg = <0x66000960 0x24>,
|
||||
<0x67012800 0x4>,
|
||||
<0x6501d148 0x4>,
|
||||
<0x664d0700 0x4>;
|
||||
reg-names = "icfg", "rst-ctrl",
|
||||
"crmu-ctrl", "usb2-strap";
|
||||
id-gpios = <&gpio_g 30 0>;
|
||||
vbus-gpios = <&gpio_g 31 0>;
|
||||
};
|
@ -7,12 +7,13 @@ Required properties:
|
||||
"brcm,iproc-ns2-sata-phy"
|
||||
"brcm,iproc-nsp-sata-phy"
|
||||
"brcm,phy-sata3"
|
||||
"brcm,iproc-sr-sata-phy"
|
||||
- address-cells: should be 1
|
||||
- size-cells: should be 0
|
||||
- reg: register ranges for the PHY PCB interface
|
||||
- reg-names: should be "phy" and "phy-ctrl"
|
||||
The "phy-ctrl" registers are only required for
|
||||
"brcm,iproc-ns2-sata-phy".
|
||||
"brcm,iproc-ns2-sata-phy" and "brcm,iproc-sr-sata-phy".
|
||||
|
||||
Sub-nodes:
|
||||
Each port's PHY should be represented as a sub-node.
|
||||
@ -23,8 +24,8 @@ Sub-nodes required properties:
|
||||
|
||||
Sub-nodes optional properties:
|
||||
- brcm,enable-ssc: use spread spectrum clocking (SSC) on this port
|
||||
This property is not applicable for "brcm,iproc-ns2-sata-phy" and
|
||||
"brcm,iproc-nsp-sata-phy".
|
||||
This property is not applicable for "brcm,iproc-ns2-sata-phy",
|
||||
"brcm,iproc-nsp-sata-phy" and "brcm,iproc-sr-sata-phy".
|
||||
|
||||
Example:
|
||||
sata-phy@f0458100 {
|
||||
|
17
Documentation/devicetree/bindings/phy/meson-gxl-usb2-phy.txt
Normal file
17
Documentation/devicetree/bindings/phy/meson-gxl-usb2-phy.txt
Normal file
@ -0,0 +1,17 @@
|
||||
* Amlogic Meson GXL and GXM USB2 PHY binding
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "amlogic,meson-gxl-usb2-phy"
|
||||
- reg: The base address and length of the registers
|
||||
- #phys-cells: must be 0 (see phy-bindings.txt in this directory)
|
||||
|
||||
Optional properties:
|
||||
- phy-supply: see phy-bindings.txt in this directory
|
||||
|
||||
|
||||
Example:
|
||||
usb2_phy0: phy@78000 {
|
||||
compatible = "amlogic,meson-gxl-usb2-phy";
|
||||
#phy-cells = <0>;
|
||||
reg = <0x0 0x78000 0x0 0x20>;
|
||||
};
|
@ -1,7 +1,8 @@
|
||||
* Amlogic Meson8b and GXBB USB2 PHY
|
||||
* Amlogic Meson8, Meson8b and GXBB USB2 PHY
|
||||
|
||||
Required properties:
|
||||
- compatible: Depending on the platform this should be one of:
|
||||
"amlogic,meson8-usb2-phy"
|
||||
"amlogic,meson8b-usb2-phy"
|
||||
"amlogic,meson-gxbb-usb2-phy"
|
||||
- reg: The base address and length of the registers
|
||||
|
40
Documentation/devicetree/bindings/phy/phy-cpcap-usb.txt
Normal file
40
Documentation/devicetree/bindings/phy/phy-cpcap-usb.txt
Normal file
@ -0,0 +1,40 @@
|
||||
Motorola CPCAP PMIC USB PHY binding
|
||||
|
||||
Required properties:
|
||||
compatible: Shall be either "motorola,cpcap-usb-phy" or
|
||||
"motorola,mapphone-cpcap-usb-phy"
|
||||
#phy-cells: Shall be 0
|
||||
interrupts: CPCAP PMIC interrupts used by the USB PHY
|
||||
interrupt-names: Interrupt names
|
||||
io-channels: IIO ADC channels used by the USB PHY
|
||||
io-channel-names: IIO ADC channel names
|
||||
vusb-supply: Regulator for the PHY
|
||||
|
||||
Optional properties:
|
||||
pinctrl: Optional alternate pin modes for the PHY
|
||||
pinctrl-names: Names for optional pin modes
|
||||
mode-gpios: Optional GPIOs for configuring alternate modes
|
||||
|
||||
Example:
|
||||
cpcap_usb2_phy: phy {
|
||||
compatible = "motorola,mapphone-cpcap-usb-phy";
|
||||
pinctrl-0 = <&usb_gpio_mux_sel1 &usb_gpio_mux_sel2>;
|
||||
pinctrl-1 = <&usb_ulpi_pins>;
|
||||
pinctrl-2 = <&usb_utmi_pins>;
|
||||
pinctrl-3 = <&uart3_pins>;
|
||||
pinctrl-names = "default", "ulpi", "utmi", "uart";
|
||||
#phy-cells = <0>;
|
||||
interrupts-extended = <
|
||||
&cpcap 15 0 &cpcap 14 0 &cpcap 28 0 &cpcap 19 0
|
||||
&cpcap 18 0 &cpcap 17 0 &cpcap 16 0 &cpcap 49 0
|
||||
&cpcap 48 1
|
||||
>;
|
||||
interrupt-names =
|
||||
"id_ground", "id_float", "se0conn", "vbusvld",
|
||||
"sessvld", "sessend", "se1", "dm", "dp";
|
||||
mode-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH
|
||||
&gpio1 0 GPIO_ACTIVE_HIGH>;
|
||||
io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
|
||||
io-channel-names = "vbus", "id";
|
||||
vusb-supply = <&vusb>;
|
||||
};
|
@ -2,6 +2,7 @@ ROCKCHIP USB2.0 PHY WITH INNO IP BLOCK
|
||||
|
||||
Required properties (phy (parent) node):
|
||||
- compatible : should be one of the listed compatibles:
|
||||
* "rockchip,rk3228-usb2phy"
|
||||
* "rockchip,rk3328-usb2phy"
|
||||
* "rockchip,rk3366-usb2phy"
|
||||
* "rockchip,rk3399-usb2phy"
|
||||
|
46
Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt
Normal file
46
Documentation/devicetree/bindings/phy/rcar-gen3-phy-usb3.txt
Normal file
@ -0,0 +1,46 @@
|
||||
* Renesas R-Car generation 3 USB 3.0 PHY
|
||||
|
||||
This file provides information on what the device node for the R-Car generation
|
||||
3 USB 3.0 PHY contains.
|
||||
If you want to enable spread spectrum clock (ssc), you should use USB_EXTAL
|
||||
instead of USB3_CLK. However, if you don't want to these features, you don't
|
||||
need this driver.
|
||||
|
||||
Required properties:
|
||||
- compatible: "renesas,r8a7795-usb3-phy" if the device is a part of an R8A7795
|
||||
SoC.
|
||||
"renesas,r8a7796-usb3-phy" if the device is a part of an R8A7796
|
||||
SoC.
|
||||
"renesas,rcar-gen3-usb3-phy" for a generic R-Car Gen3 compatible
|
||||
device.
|
||||
|
||||
When compatible with the generic version, nodes must list the
|
||||
SoC-specific version corresponding to the platform first
|
||||
followed by the generic version.
|
||||
|
||||
- reg: offset and length of the USB 3.0 PHY register block.
|
||||
- clocks: A list of phandles and clock-specifier pairs.
|
||||
- clock-names: Name of the clocks.
|
||||
- The funcional clock must be "usb3-if".
|
||||
- The usb3's external clock must be "usb3s_clk".
|
||||
- The usb2's external clock must be "usb_extal". If you want to use the ssc,
|
||||
the clock-frequency must not be 0.
|
||||
- #phy-cells: see phy-bindings.txt in the same directory, must be <0>.
|
||||
|
||||
Optional properties:
|
||||
- renesas,ssc-range: Enable/disable spread spectrum clock (ssc) by using
|
||||
the following values as u32:
|
||||
- 0 (or the property doesn't exist): disable the ssc
|
||||
- 4980: enable the ssc as -4980 ppm
|
||||
- 4492: enable the ssc as -4492 ppm
|
||||
- 4003: enable the ssc as -4003 ppm
|
||||
|
||||
Example (R-Car H3):
|
||||
|
||||
usb-phy@e65ee000 {
|
||||
compatible = "renesas,r8a7795-usb3-phy",
|
||||
"renesas,rcar-gen3-usb3-phy";
|
||||
reg = <0 0xe65ee000 0 0x90>;
|
||||
clocks = <&cpg CPG_MOD 328>, <&usb3s0_clk>, <&usb_extal>;
|
||||
clock-names = "usb3-if", "usb3s_clk", "usb_extal";
|
||||
};
|
@ -45,6 +45,8 @@ Optional properties:
|
||||
a free-running PHY clock.
|
||||
- snps,dis-del-phy-power-chg-quirk: when set core will change PHY power
|
||||
from P0 to P1/P2/P3 without delay.
|
||||
- snps,dis-tx-ipgap-linecheck-quirk: when set, disable u2mac linestate check
|
||||
during HS transmit.
|
||||
- snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
|
||||
utmi_l1_suspend_n, false when asserts utmi_sleep_n
|
||||
- snps,hird-threshold: HIRD threshold
|
||||
|
21
Documentation/devicetree/bindings/usb/iproc-udc.txt
Normal file
21
Documentation/devicetree/bindings/usb/iproc-udc.txt
Normal file
@ -0,0 +1,21 @@
|
||||
Broadcom IPROC USB Device controller.
|
||||
|
||||
The device node is used for UDCs integrated into Broadcom's
|
||||
iProc family (Northstar2, Cygnus) of SoCs'. The UDC is based
|
||||
on Synopsys Designware Cores AHB Subsystem Device Controller
|
||||
IP.
|
||||
|
||||
Required properties:
|
||||
- compatible: Add the compatibility strings for supported platforms.
|
||||
For Broadcom NS2 platform, add "brcm,ns2-udc","brcm,iproc-udc".
|
||||
For Broadcom Cygnus platform, add "brcm,cygnus-udc", "brcm,iproc-udc".
|
||||
- reg: Offset and length of UDC register set
|
||||
- interrupts: description of interrupt line
|
||||
- phys: phandle to phy node.
|
||||
|
||||
Example:
|
||||
udc_dwc: usb@664e0000 {
|
||||
compatible = "brcm,ns2-udc", "brcm,iproc-udc";
|
||||
reg = <0x664e0000 0x2000>;
|
||||
interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>;
|
||||
phys = <&usbdrd_phy>;
|
@ -10,6 +10,7 @@ Optional properties:
|
||||
- big-endian-desc : boolean, set this for hcds with big-endian descriptors
|
||||
- big-endian : boolean, for hcds with big-endian-regs + big-endian-desc
|
||||
- no-big-frame-no : boolean, set if frame_no lives in bits [15:0] of HCCA
|
||||
- remote-wakeup-connected: remote wakeup is wired on the platform
|
||||
- num-ports : u32, to override the detected port count
|
||||
- clocks : a list of phandle + clock specifier pairs
|
||||
- phys : phandle + phy specifier pair
|
||||
|
712
Documentation/driver-api/usb/dwc3.rst
Normal file
712
Documentation/driver-api/usb/dwc3.rst
Normal file
@ -0,0 +1,712 @@
|
||||
===============================================================
|
||||
Synopsys DesignWare Core SuperSpeed USB 3.0 Controller
|
||||
===============================================================
|
||||
|
||||
:Author: Felipe Balbi <felipe.balbi@linux.intel.com>
|
||||
:Date: April 2017
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The *Synopsys DesignWare Core SuperSpeed USB 3.0 Controller*
|
||||
(hereinafter referred to as *DWC3*) is a USB SuperSpeed compliant
|
||||
controller which can be configured in one of 4 ways:
|
||||
|
||||
1. Peripheral-only configuration
|
||||
2. Host-only configuration
|
||||
3. Dual-Role configuration
|
||||
4. Hub configuration
|
||||
|
||||
Linux currently supports several versions of this controller. In all
|
||||
likelyhood, the version in your SoC is already supported. At the time
|
||||
of this writing, known tested versions range from 2.02a to 3.10a. As a
|
||||
rule of thumb, anything above 2.02a should work reliably well.
|
||||
|
||||
Currently, we have many known users for this driver. In alphabetical
|
||||
order:
|
||||
|
||||
1. Cavium
|
||||
2. Intel Corporation
|
||||
3. Qualcomm
|
||||
4. Rockchip
|
||||
5. ST
|
||||
6. Samsung
|
||||
7. Texas Instruments
|
||||
8. Xilinx
|
||||
|
||||
Summary of Features
|
||||
======================
|
||||
|
||||
For details about features supported by your version of DWC3, consult
|
||||
your IP team and/or *Synopsys DesignWare Core SuperSpeed USB 3.0
|
||||
Controller Databook*. Following is a list of features supported by the
|
||||
driver at the time of this writing:
|
||||
|
||||
1. Up to 16 bidirectional endpoints (including the control
|
||||
pipe - ep0)
|
||||
2. Flexible endpoint configuration
|
||||
3. Simultaneous IN and OUT transfer support
|
||||
4. Scatter-list support
|
||||
5. Up to 256 TRBs [#trb]_ per endpoint
|
||||
6. Support for all transfer types (*Control*, *Bulk*,
|
||||
*Interrupt*, and *Isochronous*)
|
||||
7. SuperSpeed Bulk Streams
|
||||
8. Link Power Management
|
||||
9. Trace Events for debugging
|
||||
10. DebugFS [#debugfs]_ interface
|
||||
|
||||
These features have all been exercised with many of the **in-tree**
|
||||
gadget drivers. We have verified both *ConfigFS* [#configfs]_ and
|
||||
legacy gadget drivers.
|
||||
|
||||
Driver Design
|
||||
==============
|
||||
|
||||
The DWC3 driver sits on the *drivers/usb/dwc3/* directory. All files
|
||||
related to this driver are in this one directory. This makes it easy
|
||||
for new-comers to read the code and understand how it behaves.
|
||||
|
||||
Because of DWC3's configuration flexibility, the driver is a little
|
||||
complex in some places but it should be rather straightforward to
|
||||
understand.
|
||||
|
||||
The biggest part of the driver refers to the Gadget API.
|
||||
|
||||
Known Limitations
|
||||
===================
|
||||
|
||||
Like any other HW, DWC3 has its own set of limitations. To avoid
|
||||
constant questions about such problems, we decided to document them
|
||||
here and have a single location to where we could point users.
|
||||
|
||||
OUT Transfer Size Requirements
|
||||
---------------------------------
|
||||
|
||||
According to Synopsys Databook, all OUT transfer TRBs [#trb]_ must
|
||||
have their *size* field set to a value which is integer divisible by
|
||||
the endpoint's *wMaxPacketSize*. This means that *e.g.* in order to
|
||||
receive a Mass Storage *CBW* [#cbw]_, req->length must either be set
|
||||
to a value that's divisible by *wMaxPacketSize* (1024 on SuperSpeed,
|
||||
512 on HighSpeed, etc), or DWC3 driver must add a Chained TRB pointing
|
||||
to a throw-away buffer for the remaining length. Without this, OUT
|
||||
transfers will **NOT** start.
|
||||
|
||||
Note that as of this writing, this won't be a problem because DWC3 is
|
||||
fully capable of appending a chained TRB for the remaining length and
|
||||
completely hide this detail from the gadget driver. It's still worth
|
||||
mentioning because this seems to be the largest source of queries
|
||||
about DWC3 and *non-working transfers*.
|
||||
|
||||
TRB Ring Size Limitation
|
||||
-------------------------
|
||||
|
||||
We, currently, have a hard limit of 256 TRBs [#trb]_ per endpoint,
|
||||
with the last TRB being a Link TRB [#link_trb]_ pointing back to the
|
||||
first. This limit is arbitrary but it has the benefit of adding up to
|
||||
exactly 4096 bytes, or 1 Page.
|
||||
|
||||
DWC3 driver will try its best to cope with more than 255 requests and,
|
||||
for the most part, it should work normally. However this is not
|
||||
something that has been exercised very frequently. If you experience
|
||||
any problems, see section **Reporting Bugs** below.
|
||||
|
||||
Reporting Bugs
|
||||
================
|
||||
|
||||
Whenever you encounter a problem with DWC3, first and foremost you
|
||||
should make sure that:
|
||||
|
||||
1. You're running latest tag from `Linus' tree`_
|
||||
2. You can reproduce the error without any out-of-tree changes
|
||||
to DWC3
|
||||
3. You have checked that it's not a fault on the host machine
|
||||
|
||||
After all these are verified, then here's how to capture enough
|
||||
information so we can be of any help to you.
|
||||
|
||||
Required Information
|
||||
---------------------
|
||||
|
||||
DWC3 relies exclusively on Trace Events for debugging. Everything is
|
||||
exposed there, with some extra bits being exposed to DebugFS
|
||||
[#debugfs]_.
|
||||
|
||||
In order to capture DWC3's Trace Events you should run the following
|
||||
commands **before** plugging the USB cable to a host machine:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# mkdir -p /d
|
||||
# mkdir -p /t
|
||||
# mount -t debugfs none /d
|
||||
# mount -t tracefs none /t
|
||||
# echo 81920 > /t/buffer_size_kb
|
||||
# echo 1 > /t/events/dwc3/enable
|
||||
|
||||
After this is done, you can connect your USB cable and reproduce the
|
||||
problem. As soon as the fault is reproduced, make a copy of files
|
||||
``trace`` and ``regdump``, like so:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# cp /t/trace /root/trace.txt
|
||||
# cat /d/*dwc3*/regdump > /root/regdump.txt
|
||||
|
||||
Make sure to compress ``trace.txt`` and ``regdump.txt`` in a tarball
|
||||
and email it to `me`_ with `linux-usb`_ in Cc. If you want to be extra
|
||||
sure that I'll help you, write your subject line in the following
|
||||
format:
|
||||
|
||||
**[BUG REPORT] usb: dwc3: Bug while doing XYZ**
|
||||
|
||||
On the email body, make sure to detail what you doing, which gadget
|
||||
driver you were using, how to reproduce the problem, what SoC you're
|
||||
using, which OS (and its version) was running on the Host machine.
|
||||
|
||||
With all this information, we should be able to understand what's
|
||||
going on and be helpful to you.
|
||||
|
||||
Debugging
|
||||
===========
|
||||
|
||||
First and foremost a disclaimer::
|
||||
|
||||
DISCLAIMER: The information available on DebugFS and/or TraceFS can
|
||||
change at any time at any Major Linux Kernel Release. If writing
|
||||
scripts, do **NOT** assume information to be available in the
|
||||
current format.
|
||||
|
||||
With that out of the way, let's carry on.
|
||||
|
||||
If you're willing to debug your own problem, you deserve a round of
|
||||
applause :-)
|
||||
|
||||
Anyway, there isn't much to say here other than Trace Events will be
|
||||
really helpful in figuring out issues with DWC3. Also, access to
|
||||
Synopsys Databook will be **really** valuable in this case.
|
||||
|
||||
A USB Sniffer can be helpful at times but it's not entirely required,
|
||||
there's a lot that can be understood without looking at the wire.
|
||||
|
||||
Feel free to email `me`_ and Cc `linux-usb`_ if you need any help.
|
||||
|
||||
``DebugFS``
|
||||
-------------
|
||||
|
||||
``DebugFS`` is very good for gathering snapshots of what's going on
|
||||
with DWC3 and/or any endpoint.
|
||||
|
||||
On DWC3's ``DebugFS`` directory, you will find the following files and
|
||||
directories:
|
||||
|
||||
``ep[0..15]{in,out}/``
|
||||
``link_state``
|
||||
``regdump``
|
||||
``testmode``
|
||||
|
||||
``link_state``
|
||||
``````````````
|
||||
|
||||
When read, ``link_state`` will print out one of ``U0``, ``U1``,
|
||||
``U2``, ``U3``, ``SS.Disabled``, ``RX.Detect``, ``SS.Inactive``,
|
||||
``Polling``, ``Recovery``, ``Hot Reset``, ``Compliance``,
|
||||
``Loopback``, ``Reset``, ``Resume`` or ``UNKNOWN link state``.
|
||||
|
||||
This file can also be written to in order to force link to one of the
|
||||
states above.
|
||||
|
||||
``regdump``
|
||||
`````````````
|
||||
|
||||
File name is self-explanatory. When read, ``regdump`` will print out a
|
||||
register dump of DWC3. Note that this file can be grepped to find the
|
||||
information you want.
|
||||
|
||||
``testmode``
|
||||
``````````````
|
||||
|
||||
When read, ``testmode`` will print out a name of one of the specified
|
||||
USB 2.0 Testmodes (``test_j``, ``test_k``, ``test_se0_nak``,
|
||||
``test_packet``, ``test_force_enable``) or the string ``no test`` in
|
||||
case no tests are currently being executed.
|
||||
|
||||
In order to start any of these test modes, the same strings can be
|
||||
written to the file and DWC3 will enter the requested test mode.
|
||||
|
||||
|
||||
``ep[0..15]{in,out}``
|
||||
``````````````````````
|
||||
|
||||
For each endpoint we expose one directory following the naming
|
||||
convention ``ep$num$dir`` *(ep0in, ep0out, ep1in, ...)*. Inside each
|
||||
of these directories you will find the following files:
|
||||
|
||||
``descriptor_fetch_queue``
|
||||
``event_queue``
|
||||
``rx_fifo_queue``
|
||||
``rx_info_queue``
|
||||
``rx_request_queue``
|
||||
``transfer_type``
|
||||
``trb_ring``
|
||||
``tx_fifo_queue``
|
||||
``tx_request_queue``
|
||||
|
||||
With access to Synopsys Databook, you can decode the information on
|
||||
them.
|
||||
|
||||
``transfer_type``
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When read, ``transfer_type`` will print out one of ``control``,
|
||||
``bulk``, ``interrupt`` or ``isochronous`` depending on what the
|
||||
endpoint descriptor says. If the endpoint hasn't been enabled yet, it
|
||||
will print ``--``.
|
||||
|
||||
``trb_ring``
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
When read, ``trb_ring`` will print out details about all TRBs on the
|
||||
ring. It will also tell you where our enqueue and dequeue pointers are
|
||||
located in the ring:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo
|
||||
000000002c754000,481,normal,1,0,1,0,0,0
|
||||
000000002c75c000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c754000,481,normal,1,0,1,0,0,0
|
||||
000000002c75c000,481,normal,1,0,1,0,0,0
|
||||
000000002c784000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c784000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c754000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c784000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c784000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c754000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c75c000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c754000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c754000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c754000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c75c000,481,normal,1,0,1,0,0,0
|
||||
000000002c780000,481,normal,1,0,1,0,0,0
|
||||
000000002c784000,481,normal,1,0,1,0,0,0
|
||||
000000002c788000,481,normal,1,0,1,0,0,0
|
||||
000000002c78c000,481,normal,1,0,1,0,0,0
|
||||
000000002c790000,481,normal,1,0,1,0,0,0
|
||||
000000002c754000,481,normal,1,0,1,0,0,0
|
||||
000000002c758000,481,normal,1,0,1,0,0,0
|
||||
000000002c75c000,512,normal,1,0,1,0,0,1 D
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 E
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
0000000000000000,0,UNKNOWN,0,0,0,0,0,0
|
||||
00000000381ab000,0,link,0,0,0,0,0,1
|
||||
|
||||
|
||||
Trace Events
|
||||
-------------
|
||||
|
||||
DWC3 also provides several trace events which help us gathering
|
||||
information about the behavior of the driver during runtime.
|
||||
|
||||
In order to use these events, you must enable ``CONFIG_FTRACE`` in
|
||||
your kernel config.
|
||||
|
||||
For details about how enable DWC3 events, see section **Reporting
|
||||
Bugs**.
|
||||
|
||||
The following subsections will give details about each Event Class and
|
||||
each Event defined by DWC3.
|
||||
|
||||
MMIO
|
||||
```````
|
||||
|
||||
It is sometimes useful to look at every MMIO access when looking for
|
||||
bugs. Because of that, DWC3 offers two Trace Events (one for
|
||||
dwc3_readl() and one for dwc3_writel()). ``TP_printk`` follows::
|
||||
|
||||
TP_printk("addr %p value %08x", __entry->base + __entry->offset,
|
||||
__entry->value)
|
||||
|
||||
Interrupt Events
|
||||
````````````````
|
||||
|
||||
Every IRQ event can be logged and decoded into a human readable
|
||||
string. Because every event will be different, we don't give an
|
||||
example other than the ``TP_printk`` format used::
|
||||
|
||||
TP_printk("event (%08x): %s", __entry->event,
|
||||
dwc3_decode_event(__entry->event, __entry->ep0state))
|
||||
|
||||
Control Request
|
||||
`````````````````
|
||||
|
||||
Every USB Control Request can be logged to the trace buffer. The
|
||||
output format is::
|
||||
|
||||
TP_printk("%s", dwc3_decode_ctrl(__entry->bRequestType,
|
||||
__entry->bRequest, __entry->wValue,
|
||||
__entry->wIndex, __entry->wLength)
|
||||
)
|
||||
|
||||
Note that Standard Control Requests will be decoded into
|
||||
human-readable strings with their respective arguments. Class and
|
||||
Vendor requests will be printed out a sequence of 8 bytes in hex
|
||||
format.
|
||||
|
||||
Lifetime of a ``struct usb_request``
|
||||
```````````````````````````````````````
|
||||
|
||||
The entire lifetime of a ``struct usb_request`` can be tracked on the
|
||||
trace buffer. We have one event for each of allocation, free,
|
||||
queueing, dequeueing, and giveback. Output format is::
|
||||
|
||||
TP_printk("%s: req %p length %u/%u %s%s%s ==> %d",
|
||||
__get_str(name), __entry->req, __entry->actual, __entry->length,
|
||||
__entry->zero ? "Z" : "z",
|
||||
__entry->short_not_ok ? "S" : "s",
|
||||
__entry->no_interrupt ? "i" : "I",
|
||||
__entry->status
|
||||
)
|
||||
|
||||
Generic Commands
|
||||
````````````````````
|
||||
|
||||
We can log and decode every Generic Command with its completion
|
||||
code. Format is::
|
||||
|
||||
TP_printk("cmd '%s' [%x] param %08x --> status: %s",
|
||||
dwc3_gadget_generic_cmd_string(__entry->cmd),
|
||||
__entry->cmd, __entry->param,
|
||||
dwc3_gadget_generic_cmd_status_string(__entry->status)
|
||||
)
|
||||
|
||||
Endpoint Commands
|
||||
````````````````````
|
||||
|
||||
Endpoints commands can also be logged together with completion
|
||||
code. Format is::
|
||||
|
||||
TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x --> status: %s",
|
||||
__get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd),
|
||||
__entry->cmd, __entry->param0,
|
||||
__entry->param1, __entry->param2,
|
||||
dwc3_ep_cmd_status_string(__entry->cmd_status)
|
||||
)
|
||||
|
||||
Lifetime of a ``TRB``
|
||||
``````````````````````
|
||||
|
||||
A ``TRB`` Lifetime is simple. We are either preparing a ``TRB`` or
|
||||
completing it. With these two events, we can see how a ``TRB`` changes
|
||||
over time. Format is::
|
||||
|
||||
TP_printk("%s: %d/%d trb %p buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)",
|
||||
__get_str(name), __entry->queued, __entry->allocated,
|
||||
__entry->trb, __entry->bph, __entry->bpl,
|
||||
({char *s;
|
||||
int pcm = ((__entry->size >> 24) & 3) + 1;
|
||||
switch (__entry->type) {
|
||||
case USB_ENDPOINT_XFER_INT:
|
||||
case USB_ENDPOINT_XFER_ISOC:
|
||||
switch (pcm) {
|
||||
case 1:
|
||||
s = "1x ";
|
||||
break;
|
||||
case 2:
|
||||
s = "2x ";
|
||||
break;
|
||||
case 3:
|
||||
s = "3x ";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
s = "";
|
||||
} s; }),
|
||||
DWC3_TRB_SIZE_LENGTH(__entry->size), __entry->ctrl,
|
||||
__entry->ctrl & DWC3_TRB_CTRL_HWO ? 'H' : 'h',
|
||||
__entry->ctrl & DWC3_TRB_CTRL_LST ? 'L' : 'l',
|
||||
__entry->ctrl & DWC3_TRB_CTRL_CHN ? 'C' : 'c',
|
||||
__entry->ctrl & DWC3_TRB_CTRL_CSP ? 'S' : 's',
|
||||
__entry->ctrl & DWC3_TRB_CTRL_ISP_IMI ? 'S' : 's',
|
||||
__entry->ctrl & DWC3_TRB_CTRL_IOC ? 'C' : 'c',
|
||||
dwc3_trb_type_string(DWC3_TRBCTL_TYPE(__entry->ctrl))
|
||||
)
|
||||
|
||||
Lifetime of an Endpoint
|
||||
```````````````````````
|
||||
|
||||
And endpoint's lifetime is summarized with enable and disable
|
||||
operations, both of which can be traced. Format is::
|
||||
|
||||
TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c%c:%c:%c",
|
||||
__get_str(name), __entry->maxpacket,
|
||||
__entry->maxpacket_limit, __entry->max_streams,
|
||||
__entry->maxburst, __entry->trb_enqueue,
|
||||
__entry->trb_dequeue,
|
||||
__entry->flags & DWC3_EP_ENABLED ? 'E' : 'e',
|
||||
__entry->flags & DWC3_EP_STALL ? 'S' : 's',
|
||||
__entry->flags & DWC3_EP_WEDGE ? 'W' : 'w',
|
||||
__entry->flags & DWC3_EP_BUSY ? 'B' : 'b',
|
||||
__entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p',
|
||||
__entry->flags & DWC3_EP_MISSED_ISOC ? 'M' : 'm',
|
||||
__entry->flags & DWC3_EP_END_TRANSFER_PENDING ? 'E' : 'e',
|
||||
__entry->direction ? '<' : '>'
|
||||
)
|
||||
|
||||
|
||||
Structures, Methods and Definitions
|
||||
====================================
|
||||
|
||||
.. kernel-doc:: drivers/usb/dwc3/core.h
|
||||
:doc: main data structures
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/usb/dwc3/gadget.h
|
||||
:doc: gadget-only helpers
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/usb/dwc3/gadget.c
|
||||
:doc: gadget-side implementation
|
||||
:internal:
|
||||
|
||||
.. kernel-doc:: drivers/usb/dwc3/core.c
|
||||
:doc: core driver (probe, PM, etc)
|
||||
:internal:
|
||||
|
||||
.. [#trb] Transfer Request Block
|
||||
.. [#link_trb] Transfer Request Block pointing to another Transfer
|
||||
Request Block.
|
||||
.. [#debugfs] The Debug File System
|
||||
.. [#configfs] The Config File System
|
||||
.. [#cbw] Command Block Wrapper
|
||||
.. _Linus' tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
|
||||
.. _me: felipe.balbi@linux.intel.com
|
||||
.. _linux-usb: linux-usb@vger.kernel.org
|
@ -16,7 +16,10 @@ Linux USB API
|
||||
persist
|
||||
error-codes
|
||||
writing_usb_driver
|
||||
dwc3
|
||||
writing_musb_glue_layer
|
||||
typec
|
||||
usb3-debug-port
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
|
@ -16,10 +16,11 @@ provided by gadgets.
|
||||
13. RNDIS function
|
||||
14. SERIAL function
|
||||
15. SOURCESINK function
|
||||
16. UAC1 function
|
||||
16. UAC1 function (legacy implementation)
|
||||
17. UAC2 function
|
||||
18. UVC function
|
||||
19. PRINTER function
|
||||
20. UAC1 function (new API)
|
||||
|
||||
|
||||
1. ACM function
|
||||
@ -589,15 +590,16 @@ device: run the gadget
|
||||
host: test-usb (tools/usb/testusb.c)
|
||||
|
||||
|
||||
16. UAC1 function
|
||||
16. UAC1 function (legacy implementation)
|
||||
=================
|
||||
|
||||
The function is provided by usb_f_uac1.ko module.
|
||||
The function is provided by usb_f_uac1_legacy.ko module.
|
||||
|
||||
Function-specific configfs interface
|
||||
------------------------------------
|
||||
|
||||
The function name to use when creating the function directory is "uac1".
|
||||
The function name to use when creating the function directory
|
||||
is "uac1_legacy".
|
||||
The uac1 function provides these attributes in its function directory:
|
||||
|
||||
audio_buf_size - audio buffer size
|
||||
@ -772,3 +774,46 @@ host:
|
||||
|
||||
More advanced testing can be done with the prn_example
|
||||
described in Documentation/usb/gadget-printer.txt.
|
||||
|
||||
|
||||
20. UAC1 function (virtual ALSA card, using u_audio API)
|
||||
=================
|
||||
|
||||
The function is provided by usb_f_uac1.ko module.
|
||||
It will create a virtual ALSA card and the audio streams are simply
|
||||
sinked to and sourced from it.
|
||||
|
||||
Function-specific configfs interface
|
||||
------------------------------------
|
||||
|
||||
The function name to use when creating the function directory is "uac1".
|
||||
The uac1 function provides these attributes in its function directory:
|
||||
|
||||
c_chmask - capture channel mask
|
||||
c_srate - capture sampling rate
|
||||
c_ssize - capture sample size (bytes)
|
||||
p_chmask - playback channel mask
|
||||
p_srate - playback sampling rate
|
||||
p_ssize - playback sample size (bytes)
|
||||
req_number - the number of pre-allocated request for both capture
|
||||
and playback
|
||||
|
||||
The attributes have sane default values.
|
||||
|
||||
Testing the UAC1 function
|
||||
-------------------------
|
||||
|
||||
device: run the gadget
|
||||
host: aplay -l # should list our USB Audio Gadget
|
||||
|
||||
This function does not require real hardware support, it just
|
||||
sends a stream of audio data to/from the host. In order to
|
||||
actually hear something at the device side, a command similar
|
||||
to this must be used at the device side:
|
||||
|
||||
$ arecord -f dat -t wav -D hw:2,0 | aplay -D hw:0,0 &
|
||||
|
||||
e.g.:
|
||||
|
||||
$ arecord -f dat -t wav -D hw:CARD=UAC1Gadget,DEV=0 | \
|
||||
aplay -D default:CARD=OdroidU3
|
||||
|
20
MAINTAINERS
20
MAINTAINERS
@ -1843,8 +1843,8 @@ F: drivers/i2c/busses/i2c-st.c
|
||||
F: drivers/media/rc/st_rc.c
|
||||
F: drivers/media/platform/sti/c8sectpfe/
|
||||
F: drivers/mmc/host/sdhci-st.c
|
||||
F: drivers/phy/phy-miphy28lp.c
|
||||
F: drivers/phy/phy-stih407-usb.c
|
||||
F: drivers/phy/st/phy-miphy28lp.c
|
||||
F: drivers/phy/st/phy-stih407-usb.c
|
||||
F: drivers/pinctrl/pinctrl-st.c
|
||||
F: drivers/remoteproc/st_remoteproc.c
|
||||
F: drivers/remoteproc/st_slim_rproc.c
|
||||
@ -10840,11 +10840,11 @@ L: linux-iio@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/iio/adc/rcar_gyro_adc.c
|
||||
|
||||
RENESAS USB2 PHY DRIVER
|
||||
RENESAS USB PHY DRIVER
|
||||
M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/phy/phy-rcar-gen3-usb2.c
|
||||
F: drivers/phy/renesas/phy-rcar-gen3-usb*.c
|
||||
|
||||
RESET CONTROLLER FRAMEWORK
|
||||
M: Philipp Zabel <p.zabel@pengutronix.de>
|
||||
@ -11246,12 +11246,12 @@ L: linux-kernel@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/phy/samsung-phy.txt
|
||||
F: Documentation/phy/samsung-usb2.txt
|
||||
F: drivers/phy/phy-exynos4210-usb2.c
|
||||
F: drivers/phy/phy-exynos4x12-usb2.c
|
||||
F: drivers/phy/phy-exynos5250-usb2.c
|
||||
F: drivers/phy/phy-s5pv210-usb2.c
|
||||
F: drivers/phy/phy-samsung-usb2.c
|
||||
F: drivers/phy/phy-samsung-usb2.h
|
||||
F: drivers/phy/samsung/phy-exynos4210-usb2.c
|
||||
F: drivers/phy/samsung/phy-exynos4x12-usb2.c
|
||||
F: drivers/phy/samsung/phy-exynos5250-usb2.c
|
||||
F: drivers/phy/samsung/phy-s5pv210-usb2.c
|
||||
F: drivers/phy/samsung/phy-samsung-usb2.c
|
||||
F: drivers/phy/samsung/phy-samsung-usb2.h
|
||||
|
||||
SERIAL DRIVERS
|
||||
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
@ -249,6 +249,24 @@ static const struct dma_slave_map omap24xx_sdma_map[] = {
|
||||
{ "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) },
|
||||
{ "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) },
|
||||
{ "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) },
|
||||
|
||||
/* external DMA requests when tusb6010 is used */
|
||||
{ "musb-tusb", "dmareq0", SDMA_FILTER_PARAM(2) },
|
||||
{ "musb-tusb", "dmareq1", SDMA_FILTER_PARAM(3) },
|
||||
{ "musb-tusb", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */
|
||||
{ "musb-tusb", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */
|
||||
{ "musb-tusb", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */
|
||||
{ "musb-tusb", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */
|
||||
};
|
||||
|
||||
static const struct dma_slave_map omap24xx_sdma_dt_map[] = {
|
||||
/* external DMA requests when tusb6010 is used */
|
||||
{ "musb-hdrc.1.auto", "dmareq0", SDMA_FILTER_PARAM(2) },
|
||||
{ "musb-hdrc.1.auto", "dmareq1", SDMA_FILTER_PARAM(3) },
|
||||
{ "musb-hdrc.1.auto", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */
|
||||
{ "musb-hdrc.1.auto", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */
|
||||
{ "musb-hdrc.1.auto", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */
|
||||
{ "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */
|
||||
};
|
||||
|
||||
static const struct dma_slave_map omap3xxx_sdma_map[] = {
|
||||
@ -346,6 +364,12 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
|
||||
__func__);
|
||||
return -ENODEV;
|
||||
}
|
||||
} else {
|
||||
if (soc_is_omap24xx()) {
|
||||
/* DMA slave map for drivers not yet converted to DT */
|
||||
p.slave_map = omap24xx_sdma_dt_map;
|
||||
p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map);
|
||||
}
|
||||
}
|
||||
|
||||
pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
|
||||
|
@ -2884,3 +2884,19 @@ void set_secondary_fwnode(struct device *dev, struct fwnode_handle *fwnode)
|
||||
else
|
||||
dev->fwnode = fwnode;
|
||||
}
|
||||
|
||||
/**
|
||||
* device_set_of_node_from_dev - reuse device-tree node of another device
|
||||
* @dev: device whose device-tree node is being set
|
||||
* @dev2: device whose device-tree node is being reused
|
||||
*
|
||||
* Takes another reference to the new device-tree node after first dropping
|
||||
* any reference held to the old node.
|
||||
*/
|
||||
void device_set_of_node_from_dev(struct device *dev, const struct device *dev2)
|
||||
{
|
||||
of_node_put(dev->of_node);
|
||||
dev->of_node = of_node_get(dev2->of_node);
|
||||
dev->of_node_reused = true;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(device_set_of_node_from_dev);
|
||||
|
@ -23,6 +23,9 @@ int pinctrl_bind_pins(struct device *dev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (dev->of_node_reused)
|
||||
return 0;
|
||||
|
||||
dev->pins = devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL);
|
||||
if (!dev->pins)
|
||||
return -ENOMEM;
|
||||
|
@ -916,12 +916,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* When the port_window is used, one frame must cover the window */
|
||||
if (port_window) {
|
||||
burst = port_window;
|
||||
port_window_bytes = port_window * es_bytes[es];
|
||||
}
|
||||
|
||||
/* Now allocate and setup the descriptor. */
|
||||
d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
|
||||
if (!d)
|
||||
@ -931,6 +925,21 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
|
||||
d->dev_addr = dev_addr;
|
||||
d->es = es;
|
||||
|
||||
/* When the port_window is used, one frame must cover the window */
|
||||
if (port_window) {
|
||||
burst = port_window;
|
||||
port_window_bytes = port_window * es_bytes[es];
|
||||
|
||||
d->ei = 1;
|
||||
/*
|
||||
* One frame covers the port_window and by configure
|
||||
* the source frame index to be -1 * (port_window - 1)
|
||||
* we instruct the sDMA that after a frame is processed
|
||||
* it should move back to the start of the window.
|
||||
*/
|
||||
d->fi = -(port_window_bytes - 1);
|
||||
}
|
||||
|
||||
d->ccr = c->ccr | CCR_SYNC_FRAME;
|
||||
if (dir == DMA_DEV_TO_MEM) {
|
||||
d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED;
|
||||
@ -955,14 +964,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
|
||||
d->ccr |= CCR_SRC_AMODE_POSTINC;
|
||||
if (port_window) {
|
||||
d->ccr |= CCR_DST_AMODE_DBLIDX;
|
||||
d->ei = 1;
|
||||
/*
|
||||
* One frame covers the port_window and by configure
|
||||
* the source frame index to be -1 * (port_window - 1)
|
||||
* we instruct the sDMA that after a frame is processed
|
||||
* it should move back to the start of the window.
|
||||
*/
|
||||
d->fi = -(port_window_bytes - 1);
|
||||
|
||||
if (port_window_bytes >= 64)
|
||||
d->csdp |= CSDP_DST_BURST_64;
|
||||
@ -1018,16 +1019,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
|
||||
osg->addr = sg_dma_address(sgent);
|
||||
osg->en = en;
|
||||
osg->fn = sg_dma_len(sgent) / frame_bytes;
|
||||
if (port_window && dir == DMA_DEV_TO_MEM) {
|
||||
osg->ei = 1;
|
||||
/*
|
||||
* One frame covers the port_window and by configure
|
||||
* the source frame index to be -1 * (port_window - 1)
|
||||
* we instruct the sDMA that after a frame is processed
|
||||
* it should move back to the start of the window.
|
||||
*/
|
||||
osg->fi = -(port_window_bytes - 1);
|
||||
}
|
||||
|
||||
if (d->using_ll) {
|
||||
osg->t2_desc = dma_pool_alloc(od->desc_pool, GFP_ATOMIC,
|
||||
|
@ -115,6 +115,7 @@ config EXTCON_PALMAS
|
||||
|
||||
config EXTCON_QCOM_SPMI_MISC
|
||||
tristate "Qualcomm USB extcon support"
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
help
|
||||
Say Y here to enable SPMI PMIC based USB cable detection
|
||||
support on Qualcomm PMICs such as PM8941.
|
||||
|
@ -1271,9 +1271,7 @@ static int arizona_extcon_get_micd_configs(struct device *dev,
|
||||
goto out;
|
||||
|
||||
nconfs /= entries_per_config;
|
||||
|
||||
micd_configs = devm_kzalloc(dev,
|
||||
nconfs * sizeof(struct arizona_micd_range),
|
||||
micd_configs = devm_kcalloc(dev, nconfs, sizeof(*micd_configs),
|
||||
GFP_KERNEL);
|
||||
if (!micd_configs) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -94,8 +94,7 @@ static int int3496_probe(struct platform_device *pdev)
|
||||
struct int3496_data *data;
|
||||
int ret;
|
||||
|
||||
ret = acpi_dev_add_driver_gpios(ACPI_COMPANION(dev),
|
||||
acpi_int3496_default_gpios);
|
||||
ret = devm_acpi_dev_add_driver_gpios(dev, acpi_int3496_default_gpios);
|
||||
if (ret) {
|
||||
dev_err(dev, "can't add GPIO ACPI mapping\n");
|
||||
return ret;
|
||||
@ -169,8 +168,6 @@ static int int3496_remove(struct platform_device *pdev)
|
||||
devm_free_irq(&pdev->dev, data->usb_id_irq, data);
|
||||
cancel_delayed_work_sync(&data->work);
|
||||
|
||||
acpi_dev_remove_driver_gpios(ACPI_COMPANION(&pdev->dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -964,12 +964,12 @@ EXPORT_SYMBOL_GPL(extcon_unregister_notifier);
|
||||
|
||||
/**
|
||||
* extcon_register_notifier_all() - Register a notifier block for all connectors
|
||||
* @edev: the extcon device that has the external connecotr.
|
||||
* @edev: the extcon device that has the external connector.
|
||||
* @nb: a notifier block to be registered.
|
||||
*
|
||||
* This fucntion registers a notifier block in order to receive the state
|
||||
* This function registers a notifier block in order to receive the state
|
||||
* change of all supported external connectors from extcon device.
|
||||
* And The second parameter given to the callback of nb (val) is
|
||||
* And the second parameter given to the callback of nb (val) is
|
||||
* the current state and third parameter is the edev pointer.
|
||||
*
|
||||
* Returns 0 if success or error number if fail
|
||||
@ -1252,9 +1252,8 @@ int extcon_dev_register(struct extcon_dev *edev)
|
||||
}
|
||||
|
||||
spin_lock_init(&edev->lock);
|
||||
|
||||
edev->nh = devm_kzalloc(&edev->dev,
|
||||
sizeof(*edev->nh) * edev->max_supported, GFP_KERNEL);
|
||||
edev->nh = devm_kcalloc(&edev->dev, edev->max_supported,
|
||||
sizeof(*edev->nh), GFP_KERNEL);
|
||||
if (!edev->nh) {
|
||||
ret = -ENOMEM;
|
||||
goto err_dev;
|
||||
|
@ -15,73 +15,6 @@ config GENERIC_PHY
|
||||
phy users can obtain reference to the PHY. All the users of this
|
||||
framework should select this config.
|
||||
|
||||
config PHY_BCM_NS_USB2
|
||||
tristate "Broadcom Northstar USB 2.0 PHY Driver"
|
||||
depends on ARCH_BCM_IPROC || COMPILE_TEST
|
||||
depends on HAS_IOMEM && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support Broadcom USB 2.0 PHY connected to the USB
|
||||
controller on Northstar family.
|
||||
|
||||
config PHY_BCM_NS_USB3
|
||||
tristate "Broadcom Northstar USB 3.0 PHY Driver"
|
||||
depends on ARCH_BCM_IPROC || COMPILE_TEST
|
||||
depends on HAS_IOMEM && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support Broadcom USB 3.0 PHY connected to the USB
|
||||
controller on Northstar family.
|
||||
|
||||
config PHY_BERLIN_USB
|
||||
tristate "Marvell Berlin USB PHY Driver"
|
||||
depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the USB PHY on Marvell Berlin SoCs.
|
||||
|
||||
config PHY_BERLIN_SATA
|
||||
tristate "Marvell Berlin SATA PHY driver"
|
||||
depends on ARCH_BERLIN && HAS_IOMEM && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the SATA PHY on Marvell Berlin SoCs.
|
||||
|
||||
config ARMADA375_USBCLUSTER_PHY
|
||||
def_bool y
|
||||
depends on MACH_ARMADA_375 || COMPILE_TEST
|
||||
depends on OF && HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
|
||||
config PHY_DA8XX_USB
|
||||
tristate "TI DA8xx USB PHY Driver"
|
||||
depends on ARCH_DAVINCI_DA8XX
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Enable this to support the USB PHY on DA8xx SoCs.
|
||||
|
||||
This driver controls both the USB 1.1 PHY and the USB 2.0 PHY.
|
||||
|
||||
config PHY_DM816X_USB
|
||||
tristate "TI dm816x USB PHY driver"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
depends on USB_SUPPORT
|
||||
select GENERIC_PHY
|
||||
select USB_PHY
|
||||
help
|
||||
Enable this for dm816x USB to work.
|
||||
|
||||
config PHY_EXYNOS_MIPI_VIDEO
|
||||
tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
|
||||
depends on HAS_IOMEM
|
||||
depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
default y if ARCH_S5PV210 || ARCH_EXYNOS
|
||||
help
|
||||
Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P
|
||||
and EXYNOS SoCs.
|
||||
|
||||
config PHY_LPC18XX_USB_OTG
|
||||
tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver"
|
||||
depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
|
||||
@ -93,146 +26,6 @@ config PHY_LPC18XX_USB_OTG
|
||||
This driver is need for USB0 support on LPC18xx/43xx and takes
|
||||
care of enabling and clock setup.
|
||||
|
||||
config PHY_PXA_28NM_HSIC
|
||||
tristate "Marvell USB HSIC 28nm PHY Driver"
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support Marvell USB HSIC PHY driver for Marvell
|
||||
SoC. This driver will do the PHY initialization and shutdown.
|
||||
The PHY driver will be used by Marvell ehci driver.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
||||
config PHY_PXA_28NM_USB2
|
||||
tristate "Marvell USB 2.0 28nm PHY Driver"
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support Marvell USB 2.0 PHY driver for Marvell
|
||||
SoC. This driver will do the PHY initialization and shutdown.
|
||||
The PHY driver will be used by Marvell udc/ehci/otg driver.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
||||
config PHY_MVEBU_SATA
|
||||
def_bool y
|
||||
depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
|
||||
config PHY_MIPHY28LP
|
||||
tristate "STMicroelectronics MIPHY28LP PHY driver for STiH407"
|
||||
depends on ARCH_STI
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the miphy transceiver (for SATA/PCIE/USB3)
|
||||
that is part of STMicroelectronics STiH407 SoC.
|
||||
|
||||
config PHY_RCAR_GEN2
|
||||
tristate "Renesas R-Car generation 2 USB PHY driver"
|
||||
depends on ARCH_RENESAS
|
||||
depends on GENERIC_PHY
|
||||
help
|
||||
Support for USB PHY found on Renesas R-Car generation 2 SoCs.
|
||||
|
||||
config PHY_RCAR_GEN3_USB2
|
||||
tristate "Renesas R-Car generation 3 USB 2.0 PHY driver"
|
||||
depends on ARCH_RENESAS
|
||||
depends on EXTCON
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
|
||||
|
||||
config OMAP_CONTROL_PHY
|
||||
tristate "OMAP CONTROL PHY Driver"
|
||||
depends on ARCH_OMAP2PLUS || COMPILE_TEST
|
||||
help
|
||||
Enable this to add support for the PHY part present in the control
|
||||
module. This driver has API to power on the USB2 PHY and to write to
|
||||
the mailbox. The mailbox is present only in omap4 and the register to
|
||||
power on the USB2 PHY is present in OMAP4 and OMAP5. OMAP5 has an
|
||||
additional register to power on USB3 PHY/SATA PHY/PCIE PHY
|
||||
(PIPE3 PHY).
|
||||
|
||||
config OMAP_USB2
|
||||
tristate "OMAP USB2 PHY Driver"
|
||||
depends on ARCH_OMAP2PLUS
|
||||
depends on USB_SUPPORT
|
||||
select GENERIC_PHY
|
||||
select USB_PHY
|
||||
select OMAP_CONTROL_PHY
|
||||
depends on OMAP_OCP2SCP
|
||||
help
|
||||
Enable this to support the transceiver that is part of SOC. This
|
||||
driver takes care of all the PHY functionality apart from comparator.
|
||||
The USB OTG controller communicates with the comparator using this
|
||||
driver.
|
||||
|
||||
config TI_PIPE3
|
||||
tristate "TI PIPE3 PHY Driver"
|
||||
depends on ARCH_OMAP2PLUS || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
select OMAP_CONTROL_PHY
|
||||
depends on OMAP_OCP2SCP
|
||||
help
|
||||
Enable this to support the PIPE3 PHY that is part of TI SOCs. This
|
||||
driver takes care of all the PHY functionality apart from comparator.
|
||||
This driver interacts with the "OMAP Control PHY Driver" to power
|
||||
on/off the PHY.
|
||||
|
||||
config TWL4030_USB
|
||||
tristate "TWL4030 USB Transceiver Driver"
|
||||
depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
|
||||
depends on USB_SUPPORT
|
||||
depends on USB_GADGET || !USB_GADGET # if USB_GADGET=m, this can't 'y'
|
||||
select GENERIC_PHY
|
||||
select USB_PHY
|
||||
help
|
||||
Enable this to support the USB OTG transceiver on TWL4030
|
||||
family chips (including the TWL5030 and TPS659x0 devices).
|
||||
This transceiver supports high and full speed devices plus,
|
||||
in host mode, low speed.
|
||||
|
||||
config PHY_EXYNOS_DP_VIDEO
|
||||
tristate "EXYNOS SoC series Display Port PHY driver"
|
||||
depends on OF
|
||||
depends on ARCH_EXYNOS || COMPILE_TEST
|
||||
default ARCH_EXYNOS
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for Display Port PHY found on Samsung EXYNOS SoCs.
|
||||
|
||||
config BCM_KONA_USB2_PHY
|
||||
tristate "Broadcom Kona USB2 PHY Driver"
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Broadcom Kona USB 2.0 PHY.
|
||||
|
||||
config PHY_EXYNOS5250_SATA
|
||||
tristate "Exynos5250 Sata SerDes/PHY driver"
|
||||
depends on SOC_EXYNOS5250
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
select I2C
|
||||
select I2C_S3C2410
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Enable this to support SATA SerDes/Phy found on Samsung's
|
||||
Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s,
|
||||
SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host
|
||||
port to accept one SATA device.
|
||||
|
||||
config PHY_HIX5HD2_SATA
|
||||
tristate "HIX5HD2 SATA PHY Driver"
|
||||
depends on ARCH_HIX5HD2 && OF && HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Support for SATA PHY on Hisilicon hix5hd2 Soc.
|
||||
|
||||
config PHY_MT65XX_USB3
|
||||
tristate "Mediatek USB3.0 PHY Driver"
|
||||
depends on ARCH_MEDIATEK && OF
|
||||
@ -241,104 +34,6 @@ config PHY_MT65XX_USB3
|
||||
Say 'Y' here to add support for Mediatek USB3.0 PHY driver,
|
||||
it supports multiple usb2.0 and usb3.0 ports.
|
||||
|
||||
config PHY_HI6220_USB
|
||||
tristate "hi6220 USB PHY support"
|
||||
depends on (ARCH_HISI && ARM64) || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Enable this to support the HISILICON HI6220 USB PHY.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
||||
config PHY_SUN4I_USB
|
||||
tristate "Allwinner sunxi SoC USB PHY driver"
|
||||
depends on ARCH_SUNXI && HAS_IOMEM && OF
|
||||
depends on RESET_CONTROLLER
|
||||
depends on EXTCON
|
||||
depends on POWER_SUPPLY
|
||||
depends on USB_SUPPORT
|
||||
select GENERIC_PHY
|
||||
select USB_COMMON
|
||||
help
|
||||
Enable this to support the transceiver that is part of Allwinner
|
||||
sunxi SoCs.
|
||||
|
||||
This driver controls the entire USB PHY block, both the USB OTG
|
||||
parts, as well as the 2 regular USB 2 host PHYs.
|
||||
|
||||
config PHY_SUN9I_USB
|
||||
tristate "Allwinner sun9i SoC USB PHY driver"
|
||||
depends on ARCH_SUNXI && HAS_IOMEM && OF
|
||||
depends on RESET_CONTROLLER
|
||||
depends on USB_SUPPORT
|
||||
select USB_COMMON
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the transceiver that is part of Allwinner
|
||||
sun9i SoCs.
|
||||
|
||||
This driver controls each individual USB 2 host PHY.
|
||||
|
||||
config PHY_SAMSUNG_USB2
|
||||
tristate "Samsung USB 2.0 PHY driver"
|
||||
depends on HAS_IOMEM
|
||||
depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
default ARCH_EXYNOS
|
||||
help
|
||||
Enable this to support the Samsung USB 2.0 PHY driver for Samsung
|
||||
SoCs. This driver provides the interface for USB 2.0 PHY. Support
|
||||
for particular PHYs will be enabled based on the SoC type in addition
|
||||
to this driver.
|
||||
|
||||
config PHY_S5PV210_USB2
|
||||
bool "Support for S5PV210"
|
||||
depends on PHY_SAMSUNG_USB2
|
||||
depends on ARCH_S5PV210
|
||||
help
|
||||
Enable USB PHY support for S5PV210. This option requires that Samsung
|
||||
USB 2.0 PHY driver is enabled and means that support for this
|
||||
particular SoC is compiled in the driver. In case of S5PV210 two phys
|
||||
are available - device and host.
|
||||
|
||||
config PHY_EXYNOS4210_USB2
|
||||
bool
|
||||
depends on PHY_SAMSUNG_USB2
|
||||
default CPU_EXYNOS4210
|
||||
|
||||
config PHY_EXYNOS4X12_USB2
|
||||
bool
|
||||
depends on PHY_SAMSUNG_USB2
|
||||
default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412
|
||||
|
||||
config PHY_EXYNOS5250_USB2
|
||||
bool
|
||||
depends on PHY_SAMSUNG_USB2
|
||||
default SOC_EXYNOS5250 || SOC_EXYNOS5420
|
||||
|
||||
config PHY_EXYNOS5_USBDRD
|
||||
tristate "Exynos5 SoC series USB DRD PHY driver"
|
||||
depends on ARCH_EXYNOS && OF
|
||||
depends on HAS_IOMEM
|
||||
depends on USB_DWC3_EXYNOS
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
default y
|
||||
help
|
||||
Enable USB DRD PHY support for Exynos 5 SoC series.
|
||||
This driver provides PHY interface for USB 3.0 DRD controller
|
||||
present on Exynos5 SoC series.
|
||||
|
||||
config PHY_EXYNOS_PCIE
|
||||
bool "Exynos PCIe PHY driver"
|
||||
depends on OF && (ARCH_EXYNOS || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable PCIe PHY support for Exynos SoC series.
|
||||
This driver provides PHY interface for Exynos PCIe controller.
|
||||
|
||||
config PHY_PISTACHIO_USB
|
||||
tristate "IMG Pistachio USB2.0 PHY driver"
|
||||
depends on MACH_PISTACHIO
|
||||
@ -346,83 +41,6 @@ config PHY_PISTACHIO_USB
|
||||
help
|
||||
Enable this to support the USB2.0 PHY on the IMG Pistachio SoC.
|
||||
|
||||
config PHY_QCOM_APQ8064_SATA
|
||||
tristate "Qualcomm APQ8064 SATA SerDes/PHY driver"
|
||||
depends on ARCH_QCOM
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
|
||||
config PHY_QCOM_IPQ806X_SATA
|
||||
tristate "Qualcomm IPQ806x SATA SerDes/PHY driver"
|
||||
depends on ARCH_QCOM
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
|
||||
config PHY_ROCKCHIP_USB
|
||||
tristate "Rockchip USB2 PHY Driver"
|
||||
depends on ARCH_ROCKCHIP && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Rockchip USB 2.0 PHY.
|
||||
|
||||
config PHY_ROCKCHIP_INNO_USB2
|
||||
tristate "Rockchip INNO USB2PHY Driver"
|
||||
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
|
||||
depends on COMMON_CLK
|
||||
depends on EXTCON
|
||||
depends on USB_SUPPORT
|
||||
select GENERIC_PHY
|
||||
select USB_COMMON
|
||||
help
|
||||
Support for Rockchip USB2.0 PHY with Innosilicon IP block.
|
||||
|
||||
config PHY_ROCKCHIP_EMMC
|
||||
tristate "Rockchip EMMC PHY Driver"
|
||||
depends on ARCH_ROCKCHIP && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Rockchip EMMC PHY.
|
||||
|
||||
config PHY_ROCKCHIP_DP
|
||||
tristate "Rockchip Display Port PHY Driver"
|
||||
depends on ARCH_ROCKCHIP && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Rockchip Display Port PHY.
|
||||
|
||||
config PHY_ROCKCHIP_PCIE
|
||||
tristate "Rockchip PCIe PHY Driver"
|
||||
depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Enable this to support the Rockchip PCIe PHY.
|
||||
|
||||
config PHY_ROCKCHIP_TYPEC
|
||||
tristate "Rockchip TYPEC PHY Driver"
|
||||
depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
|
||||
select EXTCON
|
||||
select GENERIC_PHY
|
||||
select RESET_CONTROLLER
|
||||
help
|
||||
Enable this to support the Rockchip USB TYPEC PHY.
|
||||
|
||||
config PHY_ST_SPEAR1310_MIPHY
|
||||
tristate "ST SPEAR1310-MIPHY driver"
|
||||
select GENERIC_PHY
|
||||
depends on MACH_SPEAR1310 || COMPILE_TEST
|
||||
help
|
||||
Support for ST SPEAr1310 MIPHY which can be used for PCIe and SATA.
|
||||
|
||||
config PHY_ST_SPEAR1340_MIPHY
|
||||
tristate "ST SPEAR1340-MIPHY driver"
|
||||
select GENERIC_PHY
|
||||
depends on MACH_SPEAR1340 || COMPILE_TEST
|
||||
help
|
||||
Support for ST SPEAr1340 MIPHY which can be used for PCIe and SATA.
|
||||
|
||||
config PHY_XGENE
|
||||
tristate "APM X-Gene 15Gbps PHY support"
|
||||
depends on HAS_IOMEM && OF && (ARM64 || COMPILE_TEST)
|
||||
@ -430,104 +48,18 @@ config PHY_XGENE
|
||||
help
|
||||
This option enables support for APM X-Gene SoC multi-purpose PHY.
|
||||
|
||||
config PHY_STIH407_USB
|
||||
tristate "STMicroelectronics USB2 picoPHY driver for STiH407 family"
|
||||
depends on RESET_CONTROLLER
|
||||
depends on ARCH_STI || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this support to enable the picoPHY device used by USB2
|
||||
and USB3 controllers on STMicroelectronics STiH407 SoC families.
|
||||
|
||||
config PHY_QCOM_QMP
|
||||
tristate "Qualcomm QMP PHY Driver"
|
||||
depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the QMP PHY transceiver that is used
|
||||
with controllers such as PCIe, UFS, and USB on Qualcomm chips.
|
||||
|
||||
config PHY_QCOM_QUSB2
|
||||
tristate "Qualcomm QUSB2 PHY Driver"
|
||||
depends on OF && (ARCH_QCOM || COMPILE_TEST)
|
||||
depends on NVMEM || !NVMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the HighSpeed QUSB2 PHY transceiver for USB
|
||||
controllers on Qualcomm chips. This driver supports the high-speed
|
||||
PHY which is usually paired with either the ChipIdea or Synopsys DWC3
|
||||
USB IPs on MSM SOCs.
|
||||
|
||||
config PHY_QCOM_UFS
|
||||
tristate "Qualcomm UFS PHY driver"
|
||||
depends on OF && ARCH_QCOM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for UFS PHY on QCOM chipsets.
|
||||
|
||||
config PHY_QCOM_USB_HS
|
||||
tristate "Qualcomm USB HS PHY module"
|
||||
depends on USB_ULPI_BUS
|
||||
depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for the USB high-speed ULPI compliant phy on Qualcomm
|
||||
chipsets.
|
||||
|
||||
config PHY_QCOM_USB_HSIC
|
||||
tristate "Qualcomm USB HSIC ULPI PHY module"
|
||||
depends on USB_ULPI_BUS
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
|
||||
|
||||
config PHY_TUSB1210
|
||||
tristate "TI TUSB1210 ULPI PHY module"
|
||||
depends on USB_ULPI_BUS
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for TI TUSB1210 USB ULPI PHY.
|
||||
|
||||
config PHY_BRCM_SATA
|
||||
tristate "Broadcom SATA PHY driver"
|
||||
depends on ARCH_BRCMSTB || ARCH_BCM_IPROC || BMIPS_GENERIC || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
default ARCH_BCM_IPROC
|
||||
help
|
||||
Enable this to support the Broadcom SATA PHY.
|
||||
If unsure, say N.
|
||||
|
||||
config PHY_CYGNUS_PCIE
|
||||
tristate "Broadcom Cygnus PCIe PHY driver"
|
||||
depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
default ARCH_BCM_CYGNUS
|
||||
help
|
||||
Enable this to support the Broadcom Cygnus PCIe PHY.
|
||||
If unsure, say N.
|
||||
|
||||
source "drivers/phy/allwinner/Kconfig"
|
||||
source "drivers/phy/amlogic/Kconfig"
|
||||
source "drivers/phy/broadcom/Kconfig"
|
||||
source "drivers/phy/hisilicon/Kconfig"
|
||||
source "drivers/phy/marvell/Kconfig"
|
||||
source "drivers/phy/motorola/Kconfig"
|
||||
source "drivers/phy/qualcomm/Kconfig"
|
||||
source "drivers/phy/renesas/Kconfig"
|
||||
source "drivers/phy/rockchip/Kconfig"
|
||||
source "drivers/phy/samsung/Kconfig"
|
||||
source "drivers/phy/st/Kconfig"
|
||||
source "drivers/phy/tegra/Kconfig"
|
||||
|
||||
config PHY_NS2_PCIE
|
||||
tristate "Broadcom Northstar2 PCIe PHY driver"
|
||||
depends on OF && MDIO_BUS_MUX_BCM_IPROC
|
||||
select GENERIC_PHY
|
||||
default ARCH_BCM_IPROC
|
||||
help
|
||||
Enable this to support the Broadcom Northstar2 PCIe PHY.
|
||||
If unsure, say N.
|
||||
|
||||
config PHY_MESON8B_USB2
|
||||
tristate "Meson8b and GXBB USB2 PHY driver"
|
||||
default ARCH_MESON
|
||||
depends on OF && (ARCH_MESON || COMPILE_TEST)
|
||||
depends on USB_SUPPORT
|
||||
select USB_COMMON
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Meson USB2 PHYs found in Meson8b
|
||||
and GXBB SoCs.
|
||||
If unsure, say N.
|
||||
source "drivers/phy/ti/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
@ -3,64 +3,21 @@
|
||||
#
|
||||
|
||||
obj-$(CONFIG_GENERIC_PHY) += phy-core.o
|
||||
obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o
|
||||
obj-$(CONFIG_PHY_BCM_NS_USB3) += phy-bcm-ns-usb3.o
|
||||
obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o
|
||||
obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
|
||||
obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
|
||||
obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.o
|
||||
obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
|
||||
obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o
|
||||
obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
|
||||
obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
|
||||
obj-$(CONFIG_PHY_LPC18XX_USB_OTG) += phy-lpc18xx-usb-otg.o
|
||||
obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o
|
||||
obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o
|
||||
obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
|
||||
obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o
|
||||
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
|
||||
obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o
|
||||
obj-$(CONFIG_OMAP_CONTROL_PHY) += phy-omap-control.o
|
||||
obj-$(CONFIG_OMAP_USB2) += phy-omap-usb2.o
|
||||
obj-$(CONFIG_TI_PIPE3) += phy-ti-pipe3.o
|
||||
obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
|
||||
obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o
|
||||
obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
|
||||
obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o
|
||||
obj-$(CONFIG_PHY_MT65XX_USB3) += phy-mt65xx-usb3.o
|
||||
obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
|
||||
obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o
|
||||
obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o
|
||||
phy-exynos-usb2-y += phy-samsung-usb2.o
|
||||
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
|
||||
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
|
||||
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
|
||||
phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
|
||||
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
|
||||
obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o
|
||||
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
|
||||
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
|
||||
obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
|
||||
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
|
||||
obj-$(CONFIG_PHY_XGENE) += phy-xgene.o
|
||||
obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
|
||||
obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o
|
||||
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
|
||||
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o
|
||||
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o
|
||||
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o
|
||||
obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
|
||||
obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
|
||||
obj-$(CONFIG_PHY_TUSB1210) += phy-tusb1210.o
|
||||
obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
|
||||
obj-$(CONFIG_PHY_PISTACHIO_USB) += phy-pistachio-usb.o
|
||||
obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
|
||||
|
||||
obj-$(CONFIG_ARCH_SUNXI) += allwinner/
|
||||
obj-$(CONFIG_ARCH_MESON) += amlogic/
|
||||
obj-$(CONFIG_ARCH_RENESAS) += renesas/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
|
||||
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
|
||||
obj-y += broadcom/ \
|
||||
hisilicon/ \
|
||||
marvell/ \
|
||||
motorola/ \
|
||||
qualcomm/ \
|
||||
samsung/ \
|
||||
st/ \
|
||||
ti/
|
||||
|
31
drivers/phy/allwinner/Kconfig
Normal file
31
drivers/phy/allwinner/Kconfig
Normal file
@ -0,0 +1,31 @@
|
||||
#
|
||||
# Phy drivers for Allwinner platforms
|
||||
#
|
||||
config PHY_SUN4I_USB
|
||||
tristate "Allwinner sunxi SoC USB PHY driver"
|
||||
depends on ARCH_SUNXI && HAS_IOMEM && OF
|
||||
depends on RESET_CONTROLLER
|
||||
depends on EXTCON
|
||||
depends on POWER_SUPPLY
|
||||
depends on USB_SUPPORT
|
||||
select GENERIC_PHY
|
||||
select USB_COMMON
|
||||
help
|
||||
Enable this to support the transceiver that is part of Allwinner
|
||||
sunxi SoCs.
|
||||
|
||||
This driver controls the entire USB PHY block, both the USB OTG
|
||||
parts, as well as the 2 regular USB 2 host PHYs.
|
||||
|
||||
config PHY_SUN9I_USB
|
||||
tristate "Allwinner sun9i SoC USB PHY driver"
|
||||
depends on ARCH_SUNXI && HAS_IOMEM && OF
|
||||
depends on RESET_CONTROLLER
|
||||
depends on USB_SUPPORT
|
||||
select USB_COMMON
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the transceiver that is part of Allwinner
|
||||
sun9i SoCs.
|
||||
|
||||
This driver controls each individual USB 2 host PHY.
|
2
drivers/phy/allwinner/Makefile
Normal file
2
drivers/phy/allwinner/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_PHY_SUN4I_USB) += phy-sun4i-usb.o
|
||||
obj-$(CONFIG_PHY_SUN9I_USB) += phy-sun9i-usb.o
|
27
drivers/phy/amlogic/Kconfig
Normal file
27
drivers/phy/amlogic/Kconfig
Normal file
@ -0,0 +1,27 @@
|
||||
#
|
||||
# Phy drivers for Amlogic platforms
|
||||
#
|
||||
config PHY_MESON8B_USB2
|
||||
tristate "Meson8, Meson8b and GXBB USB2 PHY driver"
|
||||
default ARCH_MESON
|
||||
depends on OF && (ARCH_MESON || COMPILE_TEST)
|
||||
depends on USB_SUPPORT
|
||||
select USB_COMMON
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Meson USB2 PHYs found in Meson8,
|
||||
Meson8b and GXBB SoCs.
|
||||
If unsure, say N.
|
||||
|
||||
config PHY_MESON_GXL_USB2
|
||||
tristate "Meson GXL and GXM USB2 PHY drivers"
|
||||
default ARCH_MESON
|
||||
depends on OF && (ARCH_MESON || COMPILE_TEST)
|
||||
depends on USB_SUPPORT
|
||||
select USB_COMMON
|
||||
select GENERIC_PHY
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Enable this to support the Meson USB2 PHYs found in Meson
|
||||
GXL and GXM SoCs.
|
||||
If unsure, say N.
|
2
drivers/phy/amlogic/Makefile
Normal file
2
drivers/phy/amlogic/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
|
||||
obj-$(CONFIG_PHY_MESON_GXL_USB2) += phy-meson-gxl-usb2.o
|
273
drivers/phy/amlogic/phy-meson-gxl-usb2.c
Normal file
273
drivers/phy/amlogic/phy-meson-gxl-usb2.c
Normal file
@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Meson GXL and GXM USB2 PHY driver
|
||||
*
|
||||
* Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/usb/of.h>
|
||||
|
||||
/* bits [31:27] are read-only */
|
||||
#define U2P_R0 0x0
|
||||
#define U2P_R0_BYPASS_SEL BIT(0)
|
||||
#define U2P_R0_BYPASS_DM_EN BIT(1)
|
||||
#define U2P_R0_BYPASS_DP_EN BIT(2)
|
||||
#define U2P_R0_TXBITSTUFF_ENH BIT(3)
|
||||
#define U2P_R0_TXBITSTUFF_EN BIT(4)
|
||||
#define U2P_R0_DM_PULLDOWN BIT(5)
|
||||
#define U2P_R0_DP_PULLDOWN BIT(6)
|
||||
#define U2P_R0_DP_VBUS_VLD_EXT_SEL BIT(7)
|
||||
#define U2P_R0_DP_VBUS_VLD_EXT BIT(8)
|
||||
#define U2P_R0_ADP_PRB_EN BIT(9)
|
||||
#define U2P_R0_ADP_DISCHARGE BIT(10)
|
||||
#define U2P_R0_ADP_CHARGE BIT(11)
|
||||
#define U2P_R0_DRV_VBUS BIT(12)
|
||||
#define U2P_R0_ID_PULLUP BIT(13)
|
||||
#define U2P_R0_LOOPBACK_EN_B BIT(14)
|
||||
#define U2P_R0_OTG_DISABLE BIT(15)
|
||||
#define U2P_R0_COMMON_ONN BIT(16)
|
||||
#define U2P_R0_FSEL_MASK GENMASK(19, 17)
|
||||
#define U2P_R0_REF_CLK_SEL_MASK GENMASK(21, 20)
|
||||
#define U2P_R0_POWER_ON_RESET BIT(22)
|
||||
#define U2P_R0_V_ATE_TEST_EN_B_MASK GENMASK(24, 23)
|
||||
#define U2P_R0_ID_SET_ID_DQ BIT(25)
|
||||
#define U2P_R0_ATE_RESET BIT(26)
|
||||
#define U2P_R0_FSV_MINUS BIT(27)
|
||||
#define U2P_R0_FSV_PLUS BIT(28)
|
||||
#define U2P_R0_BYPASS_DM_DATA BIT(29)
|
||||
#define U2P_R0_BYPASS_DP_DATA BIT(30)
|
||||
|
||||
#define U2P_R1 0x4
|
||||
#define U2P_R1_BURN_IN_TEST BIT(0)
|
||||
#define U2P_R1_ACA_ENABLE BIT(1)
|
||||
#define U2P_R1_DCD_ENABLE BIT(2)
|
||||
#define U2P_R1_VDAT_SRC_EN_B BIT(3)
|
||||
#define U2P_R1_VDAT_DET_EN_B BIT(4)
|
||||
#define U2P_R1_CHARGES_SEL BIT(5)
|
||||
#define U2P_R1_TX_PREEMP_PULSE_TUNE BIT(6)
|
||||
#define U2P_R1_TX_PREEMP_AMP_TUNE_MASK GENMASK(8, 7)
|
||||
#define U2P_R1_TX_RES_TUNE_MASK GENMASK(10, 9)
|
||||
#define U2P_R1_TX_RISE_TUNE_MASK GENMASK(12, 11)
|
||||
#define U2P_R1_TX_VREF_TUNE_MASK GENMASK(16, 13)
|
||||
#define U2P_R1_TX_FSLS_TUNE_MASK GENMASK(20, 17)
|
||||
#define U2P_R1_TX_HSXV_TUNE_MASK GENMASK(22, 21)
|
||||
#define U2P_R1_OTG_TUNE_MASK GENMASK(25, 23)
|
||||
#define U2P_R1_SQRX_TUNE_MASK GENMASK(28, 26)
|
||||
#define U2P_R1_COMP_DIS_TUNE_MASK GENMASK(31, 29)
|
||||
|
||||
/* bits [31:14] are read-only */
|
||||
#define U2P_R2 0x8
|
||||
#define U2P_R2_DATA_IN_MASK GENMASK(3, 0)
|
||||
#define U2P_R2_DATA_IN_EN_MASK GENMASK(7, 4)
|
||||
#define U2P_R2_ADDR_MASK GENMASK(11, 8)
|
||||
#define U2P_R2_DATA_OUT_SEL BIT(12)
|
||||
#define U2P_R2_CLK BIT(13)
|
||||
#define U2P_R2_DATA_OUT_MASK GENMASK(17, 14)
|
||||
#define U2P_R2_ACA_PIN_RANGE_C BIT(18)
|
||||
#define U2P_R2_ACA_PIN_RANGE_B BIT(19)
|
||||
#define U2P_R2_ACA_PIN_RANGE_A BIT(20)
|
||||
#define U2P_R2_ACA_PIN_GND BIT(21)
|
||||
#define U2P_R2_ACA_PIN_FLOAT BIT(22)
|
||||
#define U2P_R2_CHARGE_DETECT BIT(23)
|
||||
#define U2P_R2_DEVICE_SESSION_VALID BIT(24)
|
||||
#define U2P_R2_ADP_PROBE BIT(25)
|
||||
#define U2P_R2_ADP_SENSE BIT(26)
|
||||
#define U2P_R2_SESSION_END BIT(27)
|
||||
#define U2P_R2_VBUS_VALID BIT(28)
|
||||
#define U2P_R2_B_VALID BIT(29)
|
||||
#define U2P_R2_A_VALID BIT(30)
|
||||
#define U2P_R2_ID_DIG BIT(31)
|
||||
|
||||
#define U2P_R3 0xc
|
||||
|
||||
#define RESET_COMPLETE_TIME 500
|
||||
|
||||
struct phy_meson_gxl_usb2_priv {
|
||||
struct regmap *regmap;
|
||||
enum phy_mode mode;
|
||||
int is_enabled;
|
||||
};
|
||||
|
||||
static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.max_register = U2P_R3,
|
||||
};
|
||||
|
||||
static int phy_meson_gxl_usb2_reset(struct phy *phy)
|
||||
{
|
||||
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
|
||||
|
||||
if (priv->is_enabled) {
|
||||
/* reset the PHY and wait until settings are stabilized */
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
|
||||
U2P_R0_POWER_ON_RESET);
|
||||
udelay(RESET_COMPLETE_TIME);
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
|
||||
0);
|
||||
udelay(RESET_COMPLETE_TIME);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode)
|
||||
{
|
||||
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
|
||||
|
||||
switch (mode) {
|
||||
case PHY_MODE_USB_HOST:
|
||||
case PHY_MODE_USB_OTG:
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
|
||||
U2P_R0_DM_PULLDOWN);
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
|
||||
U2P_R0_DP_PULLDOWN);
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, 0);
|
||||
break;
|
||||
|
||||
case PHY_MODE_USB_DEVICE:
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
|
||||
0);
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
|
||||
0);
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP,
|
||||
U2P_R0_ID_PULLUP);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
phy_meson_gxl_usb2_reset(phy);
|
||||
|
||||
priv->mode = mode;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int phy_meson_gxl_usb2_power_off(struct phy *phy)
|
||||
{
|
||||
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
|
||||
|
||||
priv->is_enabled = 0;
|
||||
|
||||
/* power off the PHY by putting it into reset mode */
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
|
||||
U2P_R0_POWER_ON_RESET);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int phy_meson_gxl_usb2_power_on(struct phy *phy)
|
||||
{
|
||||
struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
priv->is_enabled = 1;
|
||||
|
||||
/* power on the PHY by taking it out of reset mode */
|
||||
regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0);
|
||||
|
||||
ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode);
|
||||
if (ret) {
|
||||
phy_meson_gxl_usb2_power_off(phy);
|
||||
|
||||
dev_err(&phy->dev, "Failed to initialize PHY with mode %d\n",
|
||||
priv->mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops phy_meson_gxl_usb2_ops = {
|
||||
.power_on = phy_meson_gxl_usb2_power_on,
|
||||
.power_off = phy_meson_gxl_usb2_power_off,
|
||||
.set_mode = phy_meson_gxl_usb2_set_mode,
|
||||
.reset = phy_meson_gxl_usb2_reset,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int phy_meson_gxl_usb2_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct phy_provider *phy_provider;
|
||||
struct resource *res;
|
||||
struct phy_meson_gxl_usb2_priv *priv;
|
||||
struct phy *phy;
|
||||
void __iomem *base;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
switch (of_usb_get_dr_mode_by_phy(dev->of_node, -1)) {
|
||||
case USB_DR_MODE_PERIPHERAL:
|
||||
priv->mode = PHY_MODE_USB_DEVICE;
|
||||
break;
|
||||
case USB_DR_MODE_OTG:
|
||||
priv->mode = PHY_MODE_USB_OTG;
|
||||
break;
|
||||
case USB_DR_MODE_HOST:
|
||||
default:
|
||||
priv->mode = PHY_MODE_USB_HOST;
|
||||
break;
|
||||
}
|
||||
|
||||
priv->regmap = devm_regmap_init_mmio(dev, base,
|
||||
&phy_meson_gxl_usb2_regmap_conf);
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
phy = devm_phy_create(dev, NULL, &phy_meson_gxl_usb2_ops);
|
||||
if (IS_ERR(phy)) {
|
||||
dev_err(dev, "failed to create PHY\n");
|
||||
return PTR_ERR(phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(phy, priv);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
}
|
||||
|
||||
static const struct of_device_id phy_meson_gxl_usb2_of_match[] = {
|
||||
{ .compatible = "amlogic,meson-gxl-usb2-phy", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, phy_meson_gxl_usb2_of_match);
|
||||
|
||||
static struct platform_driver phy_meson_gxl_usb2_driver = {
|
||||
.probe = phy_meson_gxl_usb2_probe,
|
||||
.driver = {
|
||||
.name = "phy-meson-gxl-usb2",
|
||||
.of_match_table = phy_meson_gxl_usb2_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(phy_meson_gxl_usb2_driver);
|
||||
|
||||
MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
|
||||
MODULE_DESCRIPTION("Meson GXL and GXM USB2 PHY driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Meson8b and GXBB USB2 PHY driver
|
||||
* Meson8, Meson8b and GXBB USB2 PHY driver
|
||||
*
|
||||
* Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
||||
*
|
||||
@ -266,6 +266,7 @@ static int phy_meson8b_usb2_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
static const struct of_device_id phy_meson8b_usb2_of_match[] = {
|
||||
{ .compatible = "amlogic,meson8-usb2-phy", },
|
||||
{ .compatible = "amlogic,meson8b-usb2-phy", },
|
||||
{ .compatible = "amlogic,meson-gxbb-usb2-phy", },
|
||||
{ },
|
||||
@ -282,5 +283,5 @@ static struct platform_driver phy_meson8b_usb2_driver = {
|
||||
module_platform_driver(phy_meson8b_usb2_driver);
|
||||
|
||||
MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
|
||||
MODULE_DESCRIPTION("Meson8b and GXBB USB2 PHY driver");
|
||||
MODULE_DESCRIPTION("Meson8, Meson8b and GXBB USB2 PHY driver");
|
||||
MODULE_LICENSE("GPL");
|
69
drivers/phy/broadcom/Kconfig
Normal file
69
drivers/phy/broadcom/Kconfig
Normal file
@ -0,0 +1,69 @@
|
||||
#
|
||||
# Phy drivers for Broadcom platforms
|
||||
#
|
||||
config PHY_CYGNUS_PCIE
|
||||
tristate "Broadcom Cygnus PCIe PHY driver"
|
||||
depends on OF && (ARCH_BCM_CYGNUS || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
default ARCH_BCM_CYGNUS
|
||||
help
|
||||
Enable this to support the Broadcom Cygnus PCIe PHY.
|
||||
If unsure, say N.
|
||||
|
||||
config BCM_KONA_USB2_PHY
|
||||
tristate "Broadcom Kona USB2 PHY Driver"
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Broadcom Kona USB 2.0 PHY.
|
||||
|
||||
config PHY_BCM_NS_USB2
|
||||
tristate "Broadcom Northstar USB 2.0 PHY Driver"
|
||||
depends on ARCH_BCM_IPROC || COMPILE_TEST
|
||||
depends on HAS_IOMEM && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support Broadcom USB 2.0 PHY connected to the USB
|
||||
controller on Northstar family.
|
||||
|
||||
config PHY_BCM_NS_USB3
|
||||
tristate "Broadcom Northstar USB 3.0 PHY Driver"
|
||||
depends on ARCH_BCM_IPROC || COMPILE_TEST
|
||||
depends on HAS_IOMEM && OF
|
||||
select GENERIC_PHY
|
||||
select MDIO_DEVICE
|
||||
help
|
||||
Enable this to support Broadcom USB 3.0 PHY connected to the USB
|
||||
controller on Northstar family.
|
||||
|
||||
config PHY_NS2_PCIE
|
||||
tristate "Broadcom Northstar2 PCIe PHY driver"
|
||||
depends on OF && MDIO_BUS_MUX_BCM_IPROC
|
||||
select GENERIC_PHY
|
||||
default ARCH_BCM_IPROC
|
||||
help
|
||||
Enable this to support the Broadcom Northstar2 PCIe PHY.
|
||||
If unsure, say N.
|
||||
|
||||
config PHY_NS2_USB_DRD
|
||||
tristate "Broadcom Northstar2 USB DRD PHY support"
|
||||
depends on OF && (ARCH_BCM_IPROC || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
select EXTCON
|
||||
default ARCH_BCM_IPROC
|
||||
help
|
||||
Enable this to support the Broadcom Northstar2 USB DRD PHY.
|
||||
This driver initializes the PHY in either HOST or DEVICE mode.
|
||||
The host or device configuration is read from device tree.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PHY_BRCM_SATA
|
||||
tristate "Broadcom SATA PHY driver"
|
||||
depends on ARCH_BRCMSTB || ARCH_BCM_IPROC || BMIPS_GENERIC || COMPILE_TEST
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
default ARCH_BCM_IPROC
|
||||
help
|
||||
Enable this to support the Broadcom SATA PHY.
|
||||
If unsure, say N.
|
7
drivers/phy/broadcom/Makefile
Normal file
7
drivers/phy/broadcom/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
|
||||
obj-$(CONFIG_BCM_KONA_USB2_PHY) += phy-bcm-kona-usb2.o
|
||||
obj-$(CONFIG_PHY_BCM_NS_USB2) += phy-bcm-ns-usb2.o
|
||||
obj-$(CONFIG_PHY_BCM_NS_USB3) += phy-bcm-ns-usb3.o
|
||||
obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
|
||||
obj-$(CONFIG_PHY_NS2_USB_DRD) += phy-bcm-ns2-usbdrd.o
|
||||
obj-$(CONFIG_PHY_BRCM_SATA) += phy-brcm-sata.o
|
@ -16,7 +16,9 @@
|
||||
#include <linux/bcma/bcma.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mdio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/phy/phy.h>
|
||||
@ -52,7 +54,10 @@ struct bcm_ns_usb3 {
|
||||
enum bcm_ns_family family;
|
||||
void __iomem *dmp;
|
||||
void __iomem *ccb_mii;
|
||||
struct mdio_device *mdiodev;
|
||||
struct phy *phy;
|
||||
|
||||
int (*phy_write)(struct bcm_ns_usb3 *usb3, u16 reg, u16 value);
|
||||
};
|
||||
|
||||
static const struct of_device_id bcm_ns_usb3_id_table[] = {
|
||||
@ -68,63 +73,16 @@ static const struct of_device_id bcm_ns_usb3_id_table[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcm_ns_usb3_id_table);
|
||||
|
||||
static int bcm_ns_usb3_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr,
|
||||
u32 mask, u32 value, unsigned long timeout)
|
||||
{
|
||||
unsigned long deadline = jiffies + timeout;
|
||||
u32 val;
|
||||
|
||||
do {
|
||||
val = readl(addr);
|
||||
if ((val & mask) == value)
|
||||
return 0;
|
||||
cpu_relax();
|
||||
udelay(10);
|
||||
} while (!time_after_eq(jiffies, deadline));
|
||||
|
||||
dev_err(usb3->dev, "Timeout waiting for register %p\n", addr);
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3)
|
||||
{
|
||||
return bcm_ns_usb3_wait_reg(usb3, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL,
|
||||
0x0100, 0x0000,
|
||||
usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US));
|
||||
}
|
||||
|
||||
static int bcm_ns_usb3_mdio_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
|
||||
u16 value)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
int err;
|
||||
|
||||
err = bcm_ns_usb3_mii_mng_wait_idle(usb3);
|
||||
if (err < 0) {
|
||||
dev_err(usb3->dev, "Couldn't write 0x%08x value\n", value);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* TODO: Use a proper MDIO bus layer */
|
||||
tmp |= 0x58020000; /* Magic value for MDIO PHY write */
|
||||
tmp |= reg << 18;
|
||||
tmp |= value;
|
||||
writel(tmp, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA);
|
||||
|
||||
return 0;
|
||||
return usb3->phy_write(usb3, reg, value);
|
||||
}
|
||||
|
||||
static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Enable MDIO. Setting MDCDIV as 26 */
|
||||
writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
|
||||
|
||||
/* Wait for MDIO? */
|
||||
udelay(2);
|
||||
|
||||
/* USB3 PLL Block */
|
||||
err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
|
||||
BCM_NS_USB3_PHY_PLL30_BLOCK);
|
||||
@ -143,9 +101,6 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
|
||||
/* Deaaserting PLL Reset */
|
||||
bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PLLA_CONTROL1, 0x8000);
|
||||
|
||||
/* Waiting MII Mgt interface idle */
|
||||
bcm_ns_usb3_mii_mng_wait_idle(usb3);
|
||||
|
||||
/* Deasserting USB3 system reset */
|
||||
writel(0, usb3->dmp + BCMA_RESET_CTL);
|
||||
|
||||
@ -169,9 +124,6 @@ static int bcm_ns_usb3_phy_init_ns_bx(struct bcm_ns_usb3 *usb3)
|
||||
/* Enabling SSC */
|
||||
bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003);
|
||||
|
||||
/* Waiting MII Mgt interface idle */
|
||||
bcm_ns_usb3_mii_mng_wait_idle(usb3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -179,12 +131,6 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Enable MDIO. Setting MDCDIV as 26 */
|
||||
writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
|
||||
|
||||
/* Wait for MDIO? */
|
||||
udelay(2);
|
||||
|
||||
/* PLL30 block */
|
||||
err = bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_PHY_BASE_ADDR_REG,
|
||||
BCM_NS_USB3_PHY_PLL30_BLOCK);
|
||||
@ -205,9 +151,6 @@ static int bcm_ns_usb3_phy_init_ns_ax(struct bcm_ns_usb3 *usb3)
|
||||
|
||||
bcm_ns_usb3_mdio_phy_write(usb3, BCM_NS_USB3_TX_PMD_CONTROL1, 0x1003);
|
||||
|
||||
/* Waiting MII Mgt interface idle */
|
||||
bcm_ns_usb3_mii_mng_wait_idle(usb3);
|
||||
|
||||
/* Deasserting USB3 system reset */
|
||||
writel(0, usb3->dmp + BCMA_RESET_CTL);
|
||||
|
||||
@ -242,6 +185,128 @@ static const struct phy_ops ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* MDIO driver code
|
||||
**************************************************/
|
||||
|
||||
static int bcm_ns_usb3_mdiodev_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
|
||||
u16 value)
|
||||
{
|
||||
struct mdio_device *mdiodev = usb3->mdiodev;
|
||||
|
||||
return mdiobus_write(mdiodev->bus, mdiodev->addr, reg, value);
|
||||
}
|
||||
|
||||
static int bcm_ns_usb3_mdio_probe(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct device *dev = &mdiodev->dev;
|
||||
const struct of_device_id *of_id;
|
||||
struct phy_provider *phy_provider;
|
||||
struct device_node *syscon_np;
|
||||
struct bcm_ns_usb3 *usb3;
|
||||
struct resource res;
|
||||
int err;
|
||||
|
||||
usb3 = devm_kzalloc(dev, sizeof(*usb3), GFP_KERNEL);
|
||||
if (!usb3)
|
||||
return -ENOMEM;
|
||||
|
||||
usb3->dev = dev;
|
||||
usb3->mdiodev = mdiodev;
|
||||
|
||||
of_id = of_match_device(bcm_ns_usb3_id_table, dev);
|
||||
if (!of_id)
|
||||
return -EINVAL;
|
||||
usb3->family = (enum bcm_ns_family)of_id->data;
|
||||
|
||||
syscon_np = of_parse_phandle(dev->of_node, "usb3-dmp-syscon", 0);
|
||||
err = of_address_to_resource(syscon_np, 0, &res);
|
||||
of_node_put(syscon_np);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
usb3->dmp = devm_ioremap_resource(dev, &res);
|
||||
if (IS_ERR(usb3->dmp)) {
|
||||
dev_err(dev, "Failed to map DMP regs\n");
|
||||
return PTR_ERR(usb3->dmp);
|
||||
}
|
||||
|
||||
usb3->phy_write = bcm_ns_usb3_mdiodev_phy_write;
|
||||
|
||||
usb3->phy = devm_phy_create(dev, NULL, &ops);
|
||||
if (IS_ERR(usb3->phy)) {
|
||||
dev_err(dev, "Failed to create PHY\n");
|
||||
return PTR_ERR(usb3->phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(usb3->phy, usb3);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
|
||||
return PTR_ERR_OR_ZERO(phy_provider);
|
||||
}
|
||||
|
||||
static struct mdio_driver bcm_ns_usb3_mdio_driver = {
|
||||
.mdiodrv = {
|
||||
.driver = {
|
||||
.name = "bcm_ns_mdio_usb3",
|
||||
.of_match_table = bcm_ns_usb3_id_table,
|
||||
},
|
||||
},
|
||||
.probe = bcm_ns_usb3_mdio_probe,
|
||||
};
|
||||
|
||||
/**************************************************
|
||||
* Platform driver code
|
||||
**************************************************/
|
||||
|
||||
static int bcm_ns_usb3_wait_reg(struct bcm_ns_usb3 *usb3, void __iomem *addr,
|
||||
u32 mask, u32 value, unsigned long timeout)
|
||||
{
|
||||
unsigned long deadline = jiffies + timeout;
|
||||
u32 val;
|
||||
|
||||
do {
|
||||
val = readl(addr);
|
||||
if ((val & mask) == value)
|
||||
return 0;
|
||||
cpu_relax();
|
||||
udelay(10);
|
||||
} while (!time_after_eq(jiffies, deadline));
|
||||
|
||||
dev_err(usb3->dev, "Timeout waiting for register %p\n", addr);
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static inline int bcm_ns_usb3_mii_mng_wait_idle(struct bcm_ns_usb3 *usb3)
|
||||
{
|
||||
return bcm_ns_usb3_wait_reg(usb3, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL,
|
||||
0x0100, 0x0000,
|
||||
usecs_to_jiffies(BCM_NS_USB3_MII_MNG_TIMEOUT_US));
|
||||
}
|
||||
|
||||
static int bcm_ns_usb3_platform_phy_write(struct bcm_ns_usb3 *usb3, u16 reg,
|
||||
u16 value)
|
||||
{
|
||||
u32 tmp = 0;
|
||||
int err;
|
||||
|
||||
err = bcm_ns_usb3_mii_mng_wait_idle(usb3);
|
||||
if (err < 0) {
|
||||
dev_err(usb3->dev, "Couldn't write 0x%08x value\n", value);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* TODO: Use a proper MDIO bus layer */
|
||||
tmp |= 0x58020000; /* Magic value for MDIO PHY write */
|
||||
tmp |= reg << 18;
|
||||
tmp |= value;
|
||||
writel(tmp, usb3->ccb_mii + BCMA_CCB_MII_MNG_CMD_DATA);
|
||||
|
||||
return bcm_ns_usb3_mii_mng_wait_idle(usb3);
|
||||
}
|
||||
|
||||
static int bcm_ns_usb3_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@ -275,6 +340,14 @@ static int bcm_ns_usb3_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(usb3->ccb_mii);
|
||||
}
|
||||
|
||||
/* Enable MDIO. Setting MDCDIV as 26 */
|
||||
writel(0x0000009a, usb3->ccb_mii + BCMA_CCB_MII_MNG_CTL);
|
||||
|
||||
/* Wait for MDIO? */
|
||||
udelay(2);
|
||||
|
||||
usb3->phy_write = bcm_ns_usb3_platform_phy_write;
|
||||
|
||||
usb3->phy = devm_phy_create(dev, NULL, &ops);
|
||||
if (IS_ERR(usb3->phy)) {
|
||||
dev_err(dev, "Failed to create PHY\n");
|
||||
@ -298,6 +371,35 @@ static struct platform_driver bcm_ns_usb3_driver = {
|
||||
.of_match_table = bcm_ns_usb3_id_table,
|
||||
},
|
||||
};
|
||||
module_platform_driver(bcm_ns_usb3_driver);
|
||||
|
||||
static int __init bcm_ns_usb3_module_init(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
/*
|
||||
* For backward compatibility we register as MDIO and platform driver.
|
||||
* After getting MDIO binding commonly used (e.g. switching all DT files
|
||||
* to use it) we should deprecate the old binding and eventually drop
|
||||
* support for it.
|
||||
*/
|
||||
|
||||
err = mdio_driver_register(&bcm_ns_usb3_mdio_driver);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = platform_driver_register(&bcm_ns_usb3_driver);
|
||||
if (err)
|
||||
mdio_driver_unregister(&bcm_ns_usb3_mdio_driver);
|
||||
|
||||
return err;
|
||||
}
|
||||
module_init(bcm_ns_usb3_module_init);
|
||||
|
||||
static void __exit bcm_ns_usb3_module_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bcm_ns_usb3_driver);
|
||||
mdio_driver_unregister(&bcm_ns_usb3_mdio_driver);
|
||||
}
|
||||
module_exit(bcm_ns_usb3_module_exit)
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
437
drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
Normal file
437
drivers/phy/broadcom/phy-bcm-ns2-usbdrd.c
Normal file
@ -0,0 +1,437 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Broadcom
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/extcon.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#define ICFG_DRD_AFE 0x0
|
||||
#define ICFG_MISC_STAT 0x18
|
||||
#define ICFG_DRD_P0CTL 0x1C
|
||||
#define ICFG_STRAP_CTRL 0x20
|
||||
#define ICFG_FSM_CTRL 0x24
|
||||
|
||||
#define ICFG_DEV_BIT BIT(2)
|
||||
#define IDM_RST_BIT BIT(0)
|
||||
#define AFE_CORERDY_VDDC BIT(18)
|
||||
#define PHY_PLL_RESETB BIT(15)
|
||||
#define PHY_RESETB BIT(14)
|
||||
#define PHY_PLL_LOCK BIT(0)
|
||||
|
||||
#define DRD_DEV_MODE BIT(20)
|
||||
#define OHCI_OVRCUR_POL BIT(11)
|
||||
#define ICFG_OFF_MODE BIT(6)
|
||||
#define PLL_LOCK_RETRY 1000
|
||||
|
||||
#define EVT_DEVICE 0
|
||||
#define EVT_HOST 1
|
||||
|
||||
#define DRD_HOST_MODE (BIT(2) | BIT(3))
|
||||
#define DRD_DEVICE_MODE (BIT(4) | BIT(5))
|
||||
#define DRD_HOST_VAL 0x803
|
||||
#define DRD_DEV_VAL 0x807
|
||||
#define GPIO_DELAY 20
|
||||
|
||||
struct ns2_phy_data;
|
||||
struct ns2_phy_driver {
|
||||
void __iomem *icfgdrd_regs;
|
||||
void __iomem *idmdrd_rst_ctrl;
|
||||
void __iomem *crmu_usb2_ctrl;
|
||||
void __iomem *usb2h_strap_reg;
|
||||
struct ns2_phy_data *data;
|
||||
struct extcon_dev *edev;
|
||||
struct gpio_desc *vbus_gpiod;
|
||||
struct gpio_desc *id_gpiod;
|
||||
int id_irq;
|
||||
int vbus_irq;
|
||||
unsigned long debounce_jiffies;
|
||||
struct delayed_work wq_extcon;
|
||||
};
|
||||
|
||||
struct ns2_phy_data {
|
||||
struct ns2_phy_driver *driver;
|
||||
struct phy *phy;
|
||||
int new_state;
|
||||
};
|
||||
|
||||
static const unsigned int usb_extcon_cable[] = {
|
||||
EXTCON_USB,
|
||||
EXTCON_USB_HOST,
|
||||
EXTCON_NONE,
|
||||
};
|
||||
|
||||
static inline int pll_lock_stat(u32 usb_reg, int reg_mask,
|
||||
struct ns2_phy_driver *driver)
|
||||
{
|
||||
int retry = PLL_LOCK_RETRY;
|
||||
u32 val;
|
||||
|
||||
do {
|
||||
udelay(1);
|
||||
val = readl(driver->icfgdrd_regs + usb_reg);
|
||||
if (val & reg_mask)
|
||||
return 0;
|
||||
} while (--retry > 0);
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static int ns2_drd_phy_init(struct phy *phy)
|
||||
{
|
||||
struct ns2_phy_data *data = phy_get_drvdata(phy);
|
||||
struct ns2_phy_driver *driver = data->driver;
|
||||
u32 val;
|
||||
|
||||
val = readl(driver->icfgdrd_regs + ICFG_FSM_CTRL);
|
||||
|
||||
if (data->new_state == EVT_HOST) {
|
||||
val &= ~DRD_DEVICE_MODE;
|
||||
val |= DRD_HOST_MODE;
|
||||
} else {
|
||||
val &= ~DRD_HOST_MODE;
|
||||
val |= DRD_DEVICE_MODE;
|
||||
}
|
||||
writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns2_drd_phy_poweroff(struct phy *phy)
|
||||
{
|
||||
struct ns2_phy_data *data = phy_get_drvdata(phy);
|
||||
struct ns2_phy_driver *driver = data->driver;
|
||||
u32 val;
|
||||
|
||||
val = readl(driver->crmu_usb2_ctrl);
|
||||
val &= ~AFE_CORERDY_VDDC;
|
||||
writel(val, driver->crmu_usb2_ctrl);
|
||||
|
||||
val = readl(driver->crmu_usb2_ctrl);
|
||||
val &= ~DRD_DEV_MODE;
|
||||
writel(val, driver->crmu_usb2_ctrl);
|
||||
|
||||
/* Disable Host and Device Mode */
|
||||
val = readl(driver->icfgdrd_regs + ICFG_FSM_CTRL);
|
||||
val &= ~(DRD_HOST_MODE | DRD_DEVICE_MODE | ICFG_OFF_MODE);
|
||||
writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ns2_drd_phy_poweron(struct phy *phy)
|
||||
{
|
||||
struct ns2_phy_data *data = phy_get_drvdata(phy);
|
||||
struct ns2_phy_driver *driver = data->driver;
|
||||
u32 extcon_event = data->new_state;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
if (extcon_event == EVT_DEVICE) {
|
||||
writel(DRD_DEV_VAL, driver->icfgdrd_regs + ICFG_DRD_P0CTL);
|
||||
|
||||
val = readl(driver->idmdrd_rst_ctrl);
|
||||
val &= ~IDM_RST_BIT;
|
||||
writel(val, driver->idmdrd_rst_ctrl);
|
||||
|
||||
val = readl(driver->crmu_usb2_ctrl);
|
||||
val |= (AFE_CORERDY_VDDC | DRD_DEV_MODE);
|
||||
writel(val, driver->crmu_usb2_ctrl);
|
||||
|
||||
/* Bring PHY and PHY_PLL out of Reset */
|
||||
val = readl(driver->crmu_usb2_ctrl);
|
||||
val |= (PHY_PLL_RESETB | PHY_RESETB);
|
||||
writel(val, driver->crmu_usb2_ctrl);
|
||||
|
||||
ret = pll_lock_stat(ICFG_MISC_STAT, PHY_PLL_LOCK, driver);
|
||||
if (ret < 0) {
|
||||
dev_err(&phy->dev, "Phy PLL lock failed\n");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
writel(DRD_HOST_VAL, driver->icfgdrd_regs + ICFG_DRD_P0CTL);
|
||||
|
||||
val = readl(driver->crmu_usb2_ctrl);
|
||||
val |= AFE_CORERDY_VDDC;
|
||||
writel(val, driver->crmu_usb2_ctrl);
|
||||
|
||||
ret = pll_lock_stat(ICFG_MISC_STAT, PHY_PLL_LOCK, driver);
|
||||
if (ret < 0) {
|
||||
dev_err(&phy->dev, "Phy PLL lock failed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
val = readl(driver->idmdrd_rst_ctrl);
|
||||
val &= ~IDM_RST_BIT;
|
||||
writel(val, driver->idmdrd_rst_ctrl);
|
||||
|
||||
/* port over current Polarity */
|
||||
val = readl(driver->usb2h_strap_reg);
|
||||
val |= OHCI_OVRCUR_POL;
|
||||
writel(val, driver->usb2h_strap_reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void connect_change(struct ns2_phy_driver *driver)
|
||||
{
|
||||
u32 extcon_event;
|
||||
u32 val;
|
||||
|
||||
extcon_event = driver->data->new_state;
|
||||
val = readl(driver->icfgdrd_regs + ICFG_FSM_CTRL);
|
||||
|
||||
switch (extcon_event) {
|
||||
case EVT_DEVICE:
|
||||
val &= ~(DRD_HOST_MODE | DRD_DEVICE_MODE);
|
||||
writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL);
|
||||
|
||||
val = (val & ~DRD_HOST_MODE) | DRD_DEVICE_MODE;
|
||||
writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL);
|
||||
|
||||
val = readl(driver->icfgdrd_regs + ICFG_DRD_P0CTL);
|
||||
val |= ICFG_DEV_BIT;
|
||||
writel(val, driver->icfgdrd_regs + ICFG_DRD_P0CTL);
|
||||
break;
|
||||
|
||||
case EVT_HOST:
|
||||
val &= ~(DRD_HOST_MODE | DRD_DEVICE_MODE);
|
||||
writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL);
|
||||
|
||||
val = (val & ~DRD_DEVICE_MODE) | DRD_HOST_MODE;
|
||||
writel(val, driver->icfgdrd_regs + ICFG_FSM_CTRL);
|
||||
|
||||
val = readl(driver->usb2h_strap_reg);
|
||||
val |= OHCI_OVRCUR_POL;
|
||||
writel(val, driver->usb2h_strap_reg);
|
||||
|
||||
val = readl(driver->icfgdrd_regs + ICFG_DRD_P0CTL);
|
||||
val &= ~ICFG_DEV_BIT;
|
||||
writel(val, driver->icfgdrd_regs + ICFG_DRD_P0CTL);
|
||||
break;
|
||||
|
||||
default:
|
||||
pr_err("Invalid extcon event\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void extcon_work(struct work_struct *work)
|
||||
{
|
||||
struct ns2_phy_driver *driver;
|
||||
int vbus;
|
||||
int id;
|
||||
|
||||
driver = container_of(to_delayed_work(work),
|
||||
struct ns2_phy_driver, wq_extcon);
|
||||
|
||||
id = gpiod_get_value_cansleep(driver->id_gpiod);
|
||||
vbus = gpiod_get_value_cansleep(driver->vbus_gpiod);
|
||||
|
||||
if (!id && vbus) { /* Host connected */
|
||||
extcon_set_cable_state_(driver->edev, EXTCON_USB_HOST, true);
|
||||
pr_debug("Host cable connected\n");
|
||||
driver->data->new_state = EVT_HOST;
|
||||
connect_change(driver);
|
||||
} else if (id && !vbus) { /* Disconnected */
|
||||
extcon_set_cable_state_(driver->edev, EXTCON_USB_HOST, false);
|
||||
extcon_set_cable_state_(driver->edev, EXTCON_USB, false);
|
||||
pr_debug("Cable disconnected\n");
|
||||
} else if (id && vbus) { /* Device connected */
|
||||
extcon_set_cable_state_(driver->edev, EXTCON_USB, true);
|
||||
pr_debug("Device cable connected\n");
|
||||
driver->data->new_state = EVT_DEVICE;
|
||||
connect_change(driver);
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct ns2_phy_driver *driver = dev_id;
|
||||
|
||||
queue_delayed_work(system_power_efficient_wq, &driver->wq_extcon,
|
||||
driver->debounce_jiffies);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct phy_ops ops = {
|
||||
.init = ns2_drd_phy_init,
|
||||
.power_on = ns2_drd_phy_poweron,
|
||||
.power_off = ns2_drd_phy_poweroff,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct of_device_id ns2_drd_phy_dt_ids[] = {
|
||||
{ .compatible = "brcm,ns2-drd-phy", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ns2_drd_phy_dt_ids);
|
||||
|
||||
static int ns2_drd_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct phy_provider *phy_provider;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct ns2_phy_driver *driver;
|
||||
struct ns2_phy_data *data;
|
||||
struct resource *res;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
driver = devm_kzalloc(dev, sizeof(struct ns2_phy_driver),
|
||||
GFP_KERNEL);
|
||||
if (!driver)
|
||||
return -ENOMEM;
|
||||
|
||||
driver->data = devm_kzalloc(dev, sizeof(struct ns2_phy_data),
|
||||
GFP_KERNEL);
|
||||
if (!driver->data)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "icfg");
|
||||
driver->icfgdrd_regs = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(driver->icfgdrd_regs))
|
||||
return PTR_ERR(driver->icfgdrd_regs);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rst-ctrl");
|
||||
driver->idmdrd_rst_ctrl = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(driver->idmdrd_rst_ctrl))
|
||||
return PTR_ERR(driver->idmdrd_rst_ctrl);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "crmu-ctrl");
|
||||
driver->crmu_usb2_ctrl = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(driver->crmu_usb2_ctrl))
|
||||
return PTR_ERR(driver->crmu_usb2_ctrl);
|
||||
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "usb2-strap");
|
||||
driver->usb2h_strap_reg = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(driver->usb2h_strap_reg))
|
||||
return PTR_ERR(driver->usb2h_strap_reg);
|
||||
|
||||
/* create extcon */
|
||||
driver->id_gpiod = devm_gpiod_get(&pdev->dev, "id", GPIOD_IN);
|
||||
if (IS_ERR(driver->id_gpiod)) {
|
||||
dev_err(dev, "failed to get ID GPIO\n");
|
||||
return PTR_ERR(driver->id_gpiod);
|
||||
}
|
||||
driver->vbus_gpiod = devm_gpiod_get(&pdev->dev, "vbus", GPIOD_IN);
|
||||
if (IS_ERR(driver->vbus_gpiod)) {
|
||||
dev_err(dev, "failed to get VBUS GPIO\n");
|
||||
return PTR_ERR(driver->vbus_gpiod);
|
||||
}
|
||||
|
||||
driver->edev = devm_extcon_dev_allocate(dev, usb_extcon_cable);
|
||||
if (IS_ERR(driver->edev)) {
|
||||
dev_err(dev, "failed to allocate extcon device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = devm_extcon_dev_register(dev, driver->edev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to register extcon device\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = gpiod_set_debounce(driver->id_gpiod, GPIO_DELAY * 1000);
|
||||
if (ret < 0)
|
||||
driver->debounce_jiffies = msecs_to_jiffies(GPIO_DELAY);
|
||||
|
||||
INIT_DELAYED_WORK(&driver->wq_extcon, extcon_work);
|
||||
|
||||
driver->id_irq = gpiod_to_irq(driver->id_gpiod);
|
||||
if (driver->id_irq < 0) {
|
||||
dev_err(dev, "failed to get ID IRQ\n");
|
||||
return driver->id_irq;
|
||||
}
|
||||
|
||||
driver->vbus_irq = gpiod_to_irq(driver->vbus_gpiod);
|
||||
if (driver->vbus_irq < 0) {
|
||||
dev_err(dev, "failed to get ID IRQ\n");
|
||||
return driver->vbus_irq;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(dev, driver->id_irq, gpio_irq_handler,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||
"usb_id", driver);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to request handler for ID IRQ\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_request_irq(dev, driver->vbus_irq, gpio_irq_handler,
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||
"usb_vbus", driver);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to request handler for VBUS IRQ\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_set_drvdata(dev, driver);
|
||||
|
||||
/* Shutdown all ports. They can be powered up as required */
|
||||
val = readl(driver->crmu_usb2_ctrl);
|
||||
val &= ~(AFE_CORERDY_VDDC | PHY_RESETB);
|
||||
writel(val, driver->crmu_usb2_ctrl);
|
||||
|
||||
data = driver->data;
|
||||
data->phy = devm_phy_create(dev, dev->of_node, &ops);
|
||||
if (IS_ERR(data->phy)) {
|
||||
dev_err(dev, "Failed to create usb drd phy\n");
|
||||
return PTR_ERR(data->phy);
|
||||
}
|
||||
|
||||
data->driver = driver;
|
||||
phy_set_drvdata(data->phy, data);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider)) {
|
||||
dev_err(dev, "Failed to register as phy provider\n");
|
||||
return PTR_ERR(phy_provider);
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, driver);
|
||||
|
||||
dev_info(dev, "Registered NS2 DRD Phy device\n");
|
||||
queue_delayed_work(system_power_efficient_wq, &driver->wq_extcon,
|
||||
driver->debounce_jiffies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver ns2_drd_phy_driver = {
|
||||
.probe = ns2_drd_phy_probe,
|
||||
.driver = {
|
||||
.name = "bcm-ns2-usbphy",
|
||||
.of_match_table = of_match_ptr(ns2_drd_phy_dt_ids),
|
||||
},
|
||||
};
|
||||
module_platform_driver(ns2_drd_phy_driver);
|
||||
|
||||
MODULE_ALIAS("platform:bcm-ns2-drd-phy");
|
||||
MODULE_AUTHOR("Broadcom");
|
||||
MODULE_DESCRIPTION("Broadcom NS2 USB2 PHY driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -46,6 +46,7 @@ enum brcm_sata_phy_version {
|
||||
BRCM_SATA_PHY_STB_40NM,
|
||||
BRCM_SATA_PHY_IPROC_NS2,
|
||||
BRCM_SATA_PHY_IPROC_NSP,
|
||||
BRCM_SATA_PHY_IPROC_SR,
|
||||
};
|
||||
|
||||
struct brcm_sata_port {
|
||||
@ -81,12 +82,17 @@ enum sata_phy_regs {
|
||||
PLL_ACTRL2 = 0x8b,
|
||||
PLL_ACTRL2_SELDIV_MASK = 0x1f,
|
||||
PLL_ACTRL2_SELDIV_SHIFT = 9,
|
||||
PLL_ACTRL6 = 0x86,
|
||||
|
||||
PLL1_REG_BANK = 0x060,
|
||||
PLL1_ACTRL2 = 0x82,
|
||||
PLL1_ACTRL3 = 0x83,
|
||||
PLL1_ACTRL4 = 0x84,
|
||||
|
||||
TX_REG_BANK = 0x070,
|
||||
TX_ACTRL0 = 0x80,
|
||||
TX_ACTRL0_TXPOL_FLIP = BIT(6),
|
||||
|
||||
OOB_REG_BANK = 0x150,
|
||||
OOB1_REG_BANK = 0x160,
|
||||
OOB_CTRL1 = 0x80,
|
||||
@ -347,6 +353,68 @@ static int brcm_nsp_sata_init(struct brcm_sata_port *port)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SR PHY PLL0 registers */
|
||||
#define SR_PLL0_ACTRL6_MAGIC 0xa
|
||||
|
||||
/* SR PHY PLL1 registers */
|
||||
#define SR_PLL1_ACTRL2_MAGIC 0x32
|
||||
#define SR_PLL1_ACTRL3_MAGIC 0x2
|
||||
#define SR_PLL1_ACTRL4_MAGIC 0x3e8
|
||||
|
||||
static int brcm_sr_sata_init(struct brcm_sata_port *port)
|
||||
{
|
||||
struct brcm_sata_phy *priv = port->phy_priv;
|
||||
struct device *dev = port->phy_priv->dev;
|
||||
void __iomem *base = priv->phy_base;
|
||||
unsigned int val, try;
|
||||
|
||||
/* Configure PHY PLL register bank 1 */
|
||||
val = SR_PLL1_ACTRL2_MAGIC;
|
||||
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL2, 0x0, val);
|
||||
val = SR_PLL1_ACTRL3_MAGIC;
|
||||
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL3, 0x0, val);
|
||||
val = SR_PLL1_ACTRL4_MAGIC;
|
||||
brcm_sata_phy_wr(base, PLL1_REG_BANK, PLL1_ACTRL4, 0x0, val);
|
||||
|
||||
/* Configure PHY PLL register bank 0 */
|
||||
val = SR_PLL0_ACTRL6_MAGIC;
|
||||
brcm_sata_phy_wr(base, PLL_REG_BANK_0, PLL_ACTRL6, 0x0, val);
|
||||
|
||||
/* Wait for PHY PLL lock by polling pll_lock bit */
|
||||
try = 50;
|
||||
do {
|
||||
val = brcm_sata_phy_rd(base, BLOCK0_REG_BANK,
|
||||
BLOCK0_XGXSSTATUS);
|
||||
if (val & BLOCK0_XGXSSTATUS_PLL_LOCK)
|
||||
break;
|
||||
msleep(20);
|
||||
try--;
|
||||
} while (try);
|
||||
|
||||
if ((val & BLOCK0_XGXSSTATUS_PLL_LOCK) == 0) {
|
||||
/* PLL did not lock; give up */
|
||||
dev_err(dev, "port%d PLL did not lock\n", port->portnum);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
/* Invert Tx polarity */
|
||||
brcm_sata_phy_wr(base, TX_REG_BANK, TX_ACTRL0,
|
||||
~TX_ACTRL0_TXPOL_FLIP, TX_ACTRL0_TXPOL_FLIP);
|
||||
|
||||
/* Configure OOB control to handle 100MHz reference clock */
|
||||
val = ((0xc << OOB_CTRL1_BURST_MAX_SHIFT) |
|
||||
(0x4 << OOB_CTRL1_BURST_MIN_SHIFT) |
|
||||
(0x8 << OOB_CTRL1_WAKE_IDLE_MAX_SHIFT) |
|
||||
(0x3 << OOB_CTRL1_WAKE_IDLE_MIN_SHIFT));
|
||||
brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL1, 0x0, val);
|
||||
val = ((0x1b << OOB_CTRL2_RESET_IDLE_MAX_SHIFT) |
|
||||
(0x2 << OOB_CTRL2_BURST_CNT_SHIFT) |
|
||||
(0x9 << OOB_CTRL2_RESET_IDLE_MIN_SHIFT));
|
||||
brcm_sata_phy_wr(base, OOB_REG_BANK, OOB_CTRL2, 0x0, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int brcm_sata_phy_init(struct phy *phy)
|
||||
{
|
||||
int rc;
|
||||
@ -363,6 +431,9 @@ static int brcm_sata_phy_init(struct phy *phy)
|
||||
case BRCM_SATA_PHY_IPROC_NSP:
|
||||
rc = brcm_nsp_sata_init(port);
|
||||
break;
|
||||
case BRCM_SATA_PHY_IPROC_SR:
|
||||
rc = brcm_sr_sata_init(port);
|
||||
break;
|
||||
default:
|
||||
rc = -ENODEV;
|
||||
}
|
||||
@ -384,6 +455,8 @@ static const struct of_device_id brcm_sata_phy_of_match[] = {
|
||||
.data = (void *)BRCM_SATA_PHY_IPROC_NS2 },
|
||||
{ .compatible = "brcm,iproc-nsp-sata-phy",
|
||||
.data = (void *)BRCM_SATA_PHY_IPROC_NSP },
|
||||
{ .compatible = "brcm,iproc-sr-sata-phy",
|
||||
.data = (void *)BRCM_SATA_PHY_IPROC_SR },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, brcm_sata_phy_of_match);
|
20
drivers/phy/hisilicon/Kconfig
Normal file
20
drivers/phy/hisilicon/Kconfig
Normal file
@ -0,0 +1,20 @@
|
||||
#
|
||||
# Phy drivers for Hisilicon platforms
|
||||
#
|
||||
config PHY_HI6220_USB
|
||||
tristate "hi6220 USB PHY support"
|
||||
depends on (ARCH_HISI && ARM64) || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Enable this to support the HISILICON HI6220 USB PHY.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
||||
config PHY_HIX5HD2_SATA
|
||||
tristate "HIX5HD2 SATA PHY Driver"
|
||||
depends on ARCH_HIX5HD2 && OF && HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Support for SATA PHY on Hisilicon hix5hd2 Soc.
|
2
drivers/phy/hisilicon/Makefile
Normal file
2
drivers/phy/hisilicon/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
obj-$(CONFIG_PHY_HI6220_USB) += phy-hi6220-usb.o
|
||||
obj-$(CONFIG_PHY_HIX5HD2_SATA) += phy-hix5hd2-sata.o
|
50
drivers/phy/marvell/Kconfig
Normal file
50
drivers/phy/marvell/Kconfig
Normal file
@ -0,0 +1,50 @@
|
||||
#
|
||||
# Phy drivers for Marvell platforms
|
||||
#
|
||||
config ARMADA375_USBCLUSTER_PHY
|
||||
def_bool y
|
||||
depends on MACH_ARMADA_375 || COMPILE_TEST
|
||||
depends on OF && HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
|
||||
config PHY_BERLIN_SATA
|
||||
tristate "Marvell Berlin SATA PHY driver"
|
||||
depends on ARCH_BERLIN && HAS_IOMEM && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the SATA PHY on Marvell Berlin SoCs.
|
||||
|
||||
config PHY_BERLIN_USB
|
||||
tristate "Marvell Berlin USB PHY Driver"
|
||||
depends on ARCH_BERLIN && RESET_CONTROLLER && HAS_IOMEM && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the USB PHY on Marvell Berlin SoCs.
|
||||
|
||||
config PHY_MVEBU_SATA
|
||||
def_bool y
|
||||
depends on ARCH_DOVE || MACH_DOVE || MACH_KIRKWOOD
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
|
||||
config PHY_PXA_28NM_HSIC
|
||||
tristate "Marvell USB HSIC 28nm PHY Driver"
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support Marvell USB HSIC PHY driver for Marvell
|
||||
SoC. This driver will do the PHY initialization and shutdown.
|
||||
The PHY driver will be used by Marvell ehci driver.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
||||
|
||||
config PHY_PXA_28NM_USB2
|
||||
tristate "Marvell USB 2.0 28nm PHY Driver"
|
||||
depends on HAS_IOMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support Marvell USB 2.0 PHY driver for Marvell
|
||||
SoC. This driver will do the PHY initialization and shutdown.
|
||||
The PHY driver will be used by Marvell udc/ehci/otg driver.
|
||||
|
||||
To compile this driver as a module, choose M here.
|
6
drivers/phy/marvell/Makefile
Normal file
6
drivers/phy/marvell/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
obj-$(CONFIG_ARMADA375_USBCLUSTER_PHY) += phy-armada375-usb2.o
|
||||
obj-$(CONFIG_PHY_BERLIN_SATA) += phy-berlin-sata.o
|
||||
obj-$(CONFIG_PHY_BERLIN_USB) += phy-berlin-usb.o
|
||||
obj-$(CONFIG_PHY_MVEBU_SATA) += phy-mvebu-sata.o
|
||||
obj-$(CONFIG_PHY_PXA_28NM_HSIC) += phy-pxa-28nm-hsic.o
|
||||
obj-$(CONFIG_PHY_PXA_28NM_USB2) += phy-pxa-28nm-usb2.o
|
12
drivers/phy/motorola/Kconfig
Normal file
12
drivers/phy/motorola/Kconfig
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# Phy drivers for Motorola devices
|
||||
#
|
||||
config PHY_CPCAP_USB
|
||||
tristate "CPCAP PMIC USB PHY driver"
|
||||
depends on USB_SUPPORT && IIO
|
||||
depends on USB_MUSB_HDRC || USB_MUSB_HDRC=n
|
||||
select GENERIC_PHY
|
||||
select USB_PHY
|
||||
help
|
||||
Enable this for USB to work on Motorola phones and tablets
|
||||
such as Droid 4.
|
5
drivers/phy/motorola/Makefile
Normal file
5
drivers/phy/motorola/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# Makefile for the phy drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_PHY_CPCAP_USB) += phy-cpcap-usb.o
|
676
drivers/phy/motorola/phy-cpcap-usb.c
Normal file
676
drivers/phy/motorola/phy-cpcap-usb.c
Normal file
@ -0,0 +1,676 @@
|
||||
/*
|
||||
* Motorola CPCAP PMIC USB PHY driver
|
||||
* Copyright (C) 2017 Tony Lindgren <tony@atomide.com>
|
||||
*
|
||||
* Some parts based on earlier Motorola Linux kernel tree code in
|
||||
* board-mapphone-usb.c and cpcap-usb-det.c:
|
||||
* Copyright (C) 2007 - 2011 Motorola, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/iio/consumer.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/mfd/motorola-cpcap.h>
|
||||
#include <linux/phy/omap_usb.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/usb/musb.h>
|
||||
|
||||
/* CPCAP_REG_USBC1 register bits */
|
||||
#define CPCAP_BIT_IDPULSE BIT(15)
|
||||
#define CPCAP_BIT_ID100KPU BIT(14)
|
||||
#define CPCAP_BIT_IDPUCNTRL BIT(13)
|
||||
#define CPCAP_BIT_IDPU BIT(12)
|
||||
#define CPCAP_BIT_IDPD BIT(11)
|
||||
#define CPCAP_BIT_VBUSCHRGTMR3 BIT(10)
|
||||
#define CPCAP_BIT_VBUSCHRGTMR2 BIT(9)
|
||||
#define CPCAP_BIT_VBUSCHRGTMR1 BIT(8)
|
||||
#define CPCAP_BIT_VBUSCHRGTMR0 BIT(7)
|
||||
#define CPCAP_BIT_VBUSPU BIT(6)
|
||||
#define CPCAP_BIT_VBUSPD BIT(5)
|
||||
#define CPCAP_BIT_DMPD BIT(4)
|
||||
#define CPCAP_BIT_DPPD BIT(3)
|
||||
#define CPCAP_BIT_DM1K5PU BIT(2)
|
||||
#define CPCAP_BIT_DP1K5PU BIT(1)
|
||||
#define CPCAP_BIT_DP150KPU BIT(0)
|
||||
|
||||
/* CPCAP_REG_USBC2 register bits */
|
||||
#define CPCAP_BIT_ZHSDRV1 BIT(15)
|
||||
#define CPCAP_BIT_ZHSDRV0 BIT(14)
|
||||
#define CPCAP_BIT_DPLLCLKREQ BIT(13)
|
||||
#define CPCAP_BIT_SE0CONN BIT(12)
|
||||
#define CPCAP_BIT_UARTTXTRI BIT(11)
|
||||
#define CPCAP_BIT_UARTSWAP BIT(10)
|
||||
#define CPCAP_BIT_UARTMUX1 BIT(9)
|
||||
#define CPCAP_BIT_UARTMUX0 BIT(8)
|
||||
#define CPCAP_BIT_ULPISTPLOW BIT(7)
|
||||
#define CPCAP_BIT_TXENPOL BIT(6)
|
||||
#define CPCAP_BIT_USBXCVREN BIT(5)
|
||||
#define CPCAP_BIT_USBCNTRL BIT(4)
|
||||
#define CPCAP_BIT_USBSUSPEND BIT(3)
|
||||
#define CPCAP_BIT_EMUMODE2 BIT(2)
|
||||
#define CPCAP_BIT_EMUMODE1 BIT(1)
|
||||
#define CPCAP_BIT_EMUMODE0 BIT(0)
|
||||
|
||||
/* CPCAP_REG_USBC3 register bits */
|
||||
#define CPCAP_BIT_SPARE_898_15 BIT(15)
|
||||
#define CPCAP_BIT_IHSTX03 BIT(14)
|
||||
#define CPCAP_BIT_IHSTX02 BIT(13)
|
||||
#define CPCAP_BIT_IHSTX01 BIT(12)
|
||||
#define CPCAP_BIT_IHSTX0 BIT(11)
|
||||
#define CPCAP_BIT_IDPU_SPI BIT(10)
|
||||
#define CPCAP_BIT_UNUSED_898_9 BIT(9)
|
||||
#define CPCAP_BIT_VBUSSTBY_EN BIT(8)
|
||||
#define CPCAP_BIT_VBUSEN_SPI BIT(7)
|
||||
#define CPCAP_BIT_VBUSPU_SPI BIT(6)
|
||||
#define CPCAP_BIT_VBUSPD_SPI BIT(5)
|
||||
#define CPCAP_BIT_DMPD_SPI BIT(4)
|
||||
#define CPCAP_BIT_DPPD_SPI BIT(3)
|
||||
#define CPCAP_BIT_SUSPEND_SPI BIT(2)
|
||||
#define CPCAP_BIT_PU_SPI BIT(1)
|
||||
#define CPCAP_BIT_ULPI_SPI_SEL BIT(0)
|
||||
|
||||
struct cpcap_usb_ints_state {
|
||||
bool id_ground;
|
||||
bool id_float;
|
||||
bool chrg_det;
|
||||
bool rvrs_chrg;
|
||||
bool vbusov;
|
||||
|
||||
bool chrg_se1b;
|
||||
bool se0conn;
|
||||
bool rvrs_mode;
|
||||
bool chrgcurr1;
|
||||
bool vbusvld;
|
||||
bool sessvld;
|
||||
bool sessend;
|
||||
bool se1;
|
||||
|
||||
bool battdetb;
|
||||
bool dm;
|
||||
bool dp;
|
||||
};
|
||||
|
||||
enum cpcap_gpio_mode {
|
||||
CPCAP_DM_DP,
|
||||
CPCAP_MDM_RX_TX,
|
||||
CPCAP_UNKNOWN,
|
||||
CPCAP_OTG_DM_DP,
|
||||
};
|
||||
|
||||
struct cpcap_phy_ddata {
|
||||
struct regmap *reg;
|
||||
struct device *dev;
|
||||
struct clk *refclk;
|
||||
struct usb_phy phy;
|
||||
struct delayed_work detect_work;
|
||||
struct pinctrl *pins;
|
||||
struct pinctrl_state *pins_ulpi;
|
||||
struct pinctrl_state *pins_utmi;
|
||||
struct pinctrl_state *pins_uart;
|
||||
struct gpio_desc *gpio[2];
|
||||
struct iio_channel *vbus;
|
||||
struct iio_channel *id;
|
||||
struct regulator *vusb;
|
||||
atomic_t active;
|
||||
};
|
||||
|
||||
static bool cpcap_usb_vbus_valid(struct cpcap_phy_ddata *ddata)
|
||||
{
|
||||
int error, value = 0;
|
||||
|
||||
error = iio_read_channel_processed(ddata->vbus, &value);
|
||||
if (error >= 0)
|
||||
return value > 3900 ? true : false;
|
||||
|
||||
dev_err(ddata->dev, "error reading VBUS: %i\n", error);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int cpcap_usb_phy_set_host(struct usb_otg *otg, struct usb_bus *host)
|
||||
{
|
||||
otg->host = host;
|
||||
if (!host)
|
||||
otg->state = OTG_STATE_UNDEFINED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpcap_usb_phy_set_peripheral(struct usb_otg *otg,
|
||||
struct usb_gadget *gadget)
|
||||
{
|
||||
otg->gadget = gadget;
|
||||
if (!gadget)
|
||||
otg->state = OTG_STATE_UNDEFINED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops ops = {
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int cpcap_phy_get_ints_state(struct cpcap_phy_ddata *ddata,
|
||||
struct cpcap_usb_ints_state *s)
|
||||
{
|
||||
int val, error;
|
||||
|
||||
error = regmap_read(ddata->reg, CPCAP_REG_INTS1, &val);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
s->id_ground = val & BIT(15);
|
||||
s->id_float = val & BIT(14);
|
||||
s->vbusov = val & BIT(11);
|
||||
|
||||
error = regmap_read(ddata->reg, CPCAP_REG_INTS2, &val);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
s->vbusvld = val & BIT(3);
|
||||
s->sessvld = val & BIT(2);
|
||||
s->sessend = val & BIT(1);
|
||||
s->se1 = val & BIT(0);
|
||||
|
||||
error = regmap_read(ddata->reg, CPCAP_REG_INTS4, &val);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
s->dm = val & BIT(1);
|
||||
s->dp = val & BIT(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata);
|
||||
static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata);
|
||||
|
||||
static void cpcap_usb_detect(struct work_struct *work)
|
||||
{
|
||||
struct cpcap_phy_ddata *ddata;
|
||||
struct cpcap_usb_ints_state s;
|
||||
bool vbus = false;
|
||||
int error;
|
||||
|
||||
ddata = container_of(work, struct cpcap_phy_ddata, detect_work.work);
|
||||
|
||||
error = cpcap_phy_get_ints_state(ddata, &s);
|
||||
if (error)
|
||||
return;
|
||||
|
||||
if (s.id_ground) {
|
||||
dev_dbg(ddata->dev, "id ground, USB host mode\n");
|
||||
error = cpcap_usb_set_usb_mode(ddata);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
error = musb_mailbox(MUSB_ID_GROUND);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
|
||||
CPCAP_BIT_VBUSSTBY_EN,
|
||||
CPCAP_BIT_VBUSSTBY_EN);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
|
||||
CPCAP_BIT_VBUSSTBY_EN, 0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
vbus = cpcap_usb_vbus_valid(ddata);
|
||||
|
||||
if (vbus) {
|
||||
/* Are we connected to a docking station with vbus? */
|
||||
if (s.id_ground) {
|
||||
dev_dbg(ddata->dev, "connected to a dock\n");
|
||||
|
||||
/* No VBUS needed with docks */
|
||||
error = cpcap_usb_set_usb_mode(ddata);
|
||||
if (error)
|
||||
goto out_err;
|
||||
error = musb_mailbox(MUSB_ID_GROUND);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise assume we're connected to a USB host */
|
||||
dev_dbg(ddata->dev, "connected to USB host\n");
|
||||
error = cpcap_usb_set_usb_mode(ddata);
|
||||
if (error)
|
||||
goto out_err;
|
||||
error = musb_mailbox(MUSB_VBUS_VALID);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Default to debug UART mode */
|
||||
error = cpcap_usb_set_uart_mode(ddata);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
error = musb_mailbox(MUSB_VBUS_OFF);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
dev_dbg(ddata->dev, "set UART mode\n");
|
||||
|
||||
return;
|
||||
|
||||
out_err:
|
||||
dev_err(ddata->dev, "error setting cable state: %i\n", error);
|
||||
}
|
||||
|
||||
static irqreturn_t cpcap_phy_irq_thread(int irq, void *data)
|
||||
{
|
||||
struct cpcap_phy_ddata *ddata = data;
|
||||
|
||||
if (!atomic_read(&ddata->active))
|
||||
return IRQ_NONE;
|
||||
|
||||
schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int cpcap_usb_init_irq(struct platform_device *pdev,
|
||||
struct cpcap_phy_ddata *ddata,
|
||||
const char *name)
|
||||
{
|
||||
int irq, error;
|
||||
|
||||
irq = platform_get_irq_byname(pdev, name);
|
||||
if (!irq)
|
||||
return -ENODEV;
|
||||
|
||||
error = devm_request_threaded_irq(ddata->dev, irq, NULL,
|
||||
cpcap_phy_irq_thread,
|
||||
IRQF_SHARED,
|
||||
name, ddata);
|
||||
if (error) {
|
||||
dev_err(ddata->dev, "could not get irq %s: %i\n",
|
||||
name, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char * const cpcap_phy_irqs[] = {
|
||||
/* REG_INT_0 */
|
||||
"id_ground", "id_float",
|
||||
|
||||
/* REG_INT1 */
|
||||
"se0conn", "vbusvld", "sessvld", "sessend", "se1",
|
||||
|
||||
/* REG_INT_3 */
|
||||
"dm", "dp",
|
||||
};
|
||||
|
||||
static int cpcap_usb_init_interrupts(struct platform_device *pdev,
|
||||
struct cpcap_phy_ddata *ddata)
|
||||
{
|
||||
int i, error;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cpcap_phy_irqs); i++) {
|
||||
error = cpcap_usb_init_irq(pdev, ddata, cpcap_phy_irqs[i]);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Optional pins and modes. At least Motorola mapphone devices
|
||||
* are using two GPIOs and dynamic pinctrl to multiplex PHY pins
|
||||
* to UART, ULPI or UTMI mode.
|
||||
*/
|
||||
|
||||
static int cpcap_usb_gpio_set_mode(struct cpcap_phy_ddata *ddata,
|
||||
enum cpcap_gpio_mode mode)
|
||||
{
|
||||
if (!ddata->gpio[0] || !ddata->gpio[1])
|
||||
return 0;
|
||||
|
||||
gpiod_set_value(ddata->gpio[0], mode & 1);
|
||||
gpiod_set_value(ddata->gpio[1], mode >> 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpcap_usb_set_uart_mode(struct cpcap_phy_ddata *ddata)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_DM_DP);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
if (ddata->pins_uart) {
|
||||
error = pinctrl_select_state(ddata->pins, ddata->pins_uart);
|
||||
if (error)
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
|
||||
CPCAP_BIT_VBUSPD,
|
||||
CPCAP_BIT_VBUSPD);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
|
||||
0xffff, CPCAP_BIT_UARTMUX0 |
|
||||
CPCAP_BIT_EMUMODE0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3, 0x7fff,
|
||||
CPCAP_BIT_IDPU_SPI);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int cpcap_usb_set_usb_mode(struct cpcap_phy_ddata *ddata)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = cpcap_usb_gpio_set_mode(ddata, CPCAP_OTG_DM_DP);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (ddata->pins_utmi) {
|
||||
error = pinctrl_select_state(ddata->pins, ddata->pins_utmi);
|
||||
if (error) {
|
||||
dev_err(ddata->dev, "could not set usb mode: %i\n",
|
||||
error);
|
||||
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC1,
|
||||
CPCAP_BIT_VBUSPD, 0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
|
||||
CPCAP_BIT_USBXCVREN,
|
||||
CPCAP_BIT_USBXCVREN);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC3,
|
||||
CPCAP_BIT_PU_SPI |
|
||||
CPCAP_BIT_DMPD_SPI |
|
||||
CPCAP_BIT_DPPD_SPI |
|
||||
CPCAP_BIT_SUSPEND_SPI |
|
||||
CPCAP_BIT_ULPI_SPI_SEL, 0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
error = regmap_update_bits(ddata->reg, CPCAP_REG_USBC2,
|
||||
CPCAP_BIT_USBXCVREN,
|
||||
CPCAP_BIT_USBXCVREN);
|
||||
if (error)
|
||||
goto out_err;
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
dev_err(ddata->dev, "%s failed with %i\n", __func__, error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int cpcap_usb_init_optional_pins(struct cpcap_phy_ddata *ddata)
|
||||
{
|
||||
ddata->pins = devm_pinctrl_get(ddata->dev);
|
||||
if (IS_ERR(ddata->pins)) {
|
||||
dev_info(ddata->dev, "default pins not configured: %ld\n",
|
||||
PTR_ERR(ddata->pins));
|
||||
ddata->pins = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ddata->pins_ulpi = pinctrl_lookup_state(ddata->pins, "ulpi");
|
||||
if (IS_ERR(ddata->pins_ulpi)) {
|
||||
dev_info(ddata->dev, "ulpi pins not configured\n");
|
||||
ddata->pins_ulpi = NULL;
|
||||
}
|
||||
|
||||
ddata->pins_utmi = pinctrl_lookup_state(ddata->pins, "utmi");
|
||||
if (IS_ERR(ddata->pins_utmi)) {
|
||||
dev_info(ddata->dev, "utmi pins not configured\n");
|
||||
ddata->pins_utmi = NULL;
|
||||
}
|
||||
|
||||
ddata->pins_uart = pinctrl_lookup_state(ddata->pins, "uart");
|
||||
if (IS_ERR(ddata->pins_uart)) {
|
||||
dev_info(ddata->dev, "uart pins not configured\n");
|
||||
ddata->pins_uart = NULL;
|
||||
}
|
||||
|
||||
if (ddata->pins_uart)
|
||||
return pinctrl_select_state(ddata->pins, ddata->pins_uart);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpcap_usb_init_optional_gpios(struct cpcap_phy_ddata *ddata)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
ddata->gpio[i] = devm_gpiod_get_index(ddata->dev, "mode",
|
||||
i, GPIOD_OUT_HIGH);
|
||||
if (IS_ERR(ddata->gpio[i])) {
|
||||
dev_info(ddata->dev, "no mode change GPIO%i: %li\n",
|
||||
i, PTR_ERR(ddata->gpio[i]));
|
||||
ddata->gpio[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int cpcap_usb_init_iio(struct cpcap_phy_ddata *ddata)
|
||||
{
|
||||
enum iio_chan_type type;
|
||||
int error;
|
||||
|
||||
ddata->vbus = devm_iio_channel_get(ddata->dev, "vbus");
|
||||
if (IS_ERR(ddata->vbus)) {
|
||||
error = PTR_ERR(ddata->vbus);
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
if (!ddata->vbus->indio_dev) {
|
||||
error = -ENXIO;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
error = iio_get_channel_type(ddata->vbus, &type);
|
||||
if (error < 0)
|
||||
goto out_err;
|
||||
|
||||
if (type != IIO_VOLTAGE) {
|
||||
error = -EINVAL;
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n",
|
||||
error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id cpcap_usb_phy_id_table[] = {
|
||||
{
|
||||
.compatible = "motorola,cpcap-usb-phy",
|
||||
},
|
||||
{
|
||||
.compatible = "motorola,mapphone-cpcap-usb-phy",
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cpcap_usb_phy_id_table);
|
||||
#endif
|
||||
|
||||
static int cpcap_usb_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct cpcap_phy_ddata *ddata;
|
||||
struct phy *generic_phy;
|
||||
struct phy_provider *phy_provider;
|
||||
struct usb_otg *otg;
|
||||
const struct of_device_id *of_id;
|
||||
int error;
|
||||
|
||||
of_id = of_match_device(of_match_ptr(cpcap_usb_phy_id_table),
|
||||
&pdev->dev);
|
||||
if (!of_id)
|
||||
return -EINVAL;
|
||||
|
||||
ddata = devm_kzalloc(&pdev->dev, sizeof(*ddata), GFP_KERNEL);
|
||||
if (!ddata)
|
||||
return -ENOMEM;
|
||||
|
||||
ddata->reg = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
if (!ddata->reg)
|
||||
return -ENODEV;
|
||||
|
||||
otg = devm_kzalloc(&pdev->dev, sizeof(*otg), GFP_KERNEL);
|
||||
if (!otg)
|
||||
return -ENOMEM;
|
||||
|
||||
ddata->dev = &pdev->dev;
|
||||
ddata->phy.dev = ddata->dev;
|
||||
ddata->phy.label = "cpcap_usb_phy";
|
||||
ddata->phy.otg = otg;
|
||||
ddata->phy.type = USB_PHY_TYPE_USB2;
|
||||
otg->set_host = cpcap_usb_phy_set_host;
|
||||
otg->set_peripheral = cpcap_usb_phy_set_peripheral;
|
||||
otg->usb_phy = &ddata->phy;
|
||||
INIT_DELAYED_WORK(&ddata->detect_work, cpcap_usb_detect);
|
||||
platform_set_drvdata(pdev, ddata);
|
||||
|
||||
ddata->vusb = devm_regulator_get(&pdev->dev, "vusb");
|
||||
if (IS_ERR(ddata->vusb))
|
||||
return PTR_ERR(ddata->vusb);
|
||||
|
||||
error = regulator_enable(ddata->vusb);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
generic_phy = devm_phy_create(ddata->dev, NULL, &ops);
|
||||
if (IS_ERR(generic_phy)) {
|
||||
error = PTR_ERR(generic_phy);
|
||||
return PTR_ERR(generic_phy);
|
||||
}
|
||||
|
||||
phy_set_drvdata(generic_phy, ddata);
|
||||
|
||||
phy_provider = devm_of_phy_provider_register(ddata->dev,
|
||||
of_phy_simple_xlate);
|
||||
if (IS_ERR(phy_provider))
|
||||
return PTR_ERR(phy_provider);
|
||||
|
||||
error = cpcap_usb_init_optional_pins(ddata);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
cpcap_usb_init_optional_gpios(ddata);
|
||||
|
||||
error = cpcap_usb_init_iio(ddata);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = cpcap_usb_init_interrupts(pdev, ddata);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
usb_add_phy_dev(&ddata->phy);
|
||||
atomic_set(&ddata->active, 1);
|
||||
schedule_delayed_work(&ddata->detect_work, msecs_to_jiffies(1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpcap_usb_phy_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct cpcap_phy_ddata *ddata = platform_get_drvdata(pdev);
|
||||
int error;
|
||||
|
||||
atomic_set(&ddata->active, 0);
|
||||
error = cpcap_usb_set_uart_mode(ddata);
|
||||
if (error)
|
||||
dev_err(ddata->dev, "could not set UART mode\n");
|
||||
|
||||
error = musb_mailbox(MUSB_VBUS_OFF);
|
||||
if (error)
|
||||
dev_err(ddata->dev, "could not set mailbox\n");
|
||||
|
||||
usb_remove_phy(&ddata->phy);
|
||||
cancel_delayed_work_sync(&ddata->detect_work);
|
||||
clk_unprepare(ddata->refclk);
|
||||
regulator_disable(ddata->vusb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver cpcap_usb_phy_driver = {
|
||||
.probe = cpcap_usb_phy_probe,
|
||||
.remove = cpcap_usb_phy_remove,
|
||||
.driver = {
|
||||
.name = "cpcap-usb-phy",
|
||||
.of_match_table = of_match_ptr(cpcap_usb_phy_id_table),
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(cpcap_usb_phy_driver);
|
||||
|
||||
MODULE_ALIAS("platform:cpcap_usb");
|
||||
MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
|
||||
MODULE_DESCRIPTION("CPCAP usb phy driver");
|
||||
MODULE_LICENSE("GPL v2");
|
58
drivers/phy/qualcomm/Kconfig
Normal file
58
drivers/phy/qualcomm/Kconfig
Normal file
@ -0,0 +1,58 @@
|
||||
#
|
||||
# Phy drivers for Qualcomm platforms
|
||||
#
|
||||
config PHY_QCOM_APQ8064_SATA
|
||||
tristate "Qualcomm APQ8064 SATA SerDes/PHY driver"
|
||||
depends on ARCH_QCOM
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
|
||||
config PHY_QCOM_IPQ806X_SATA
|
||||
tristate "Qualcomm IPQ806x SATA SerDes/PHY driver"
|
||||
depends on ARCH_QCOM
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
|
||||
config PHY_QCOM_QMP
|
||||
tristate "Qualcomm QMP PHY Driver"
|
||||
depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the QMP PHY transceiver that is used
|
||||
with controllers such as PCIe, UFS, and USB on Qualcomm chips.
|
||||
|
||||
config PHY_QCOM_QUSB2
|
||||
tristate "Qualcomm QUSB2 PHY Driver"
|
||||
depends on OF && (ARCH_QCOM || COMPILE_TEST)
|
||||
depends on NVMEM || !NVMEM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the HighSpeed QUSB2 PHY transceiver for USB
|
||||
controllers on Qualcomm chips. This driver supports the high-speed
|
||||
PHY which is usually paired with either the ChipIdea or Synopsys DWC3
|
||||
USB IPs on MSM SOCs.
|
||||
|
||||
config PHY_QCOM_UFS
|
||||
tristate "Qualcomm UFS PHY driver"
|
||||
depends on OF && ARCH_QCOM
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for UFS PHY on QCOM chipsets.
|
||||
|
||||
config PHY_QCOM_USB_HS
|
||||
tristate "Qualcomm USB HS PHY module"
|
||||
depends on USB_ULPI_BUS
|
||||
depends on EXTCON || !EXTCON # if EXTCON=m, this cannot be built-in
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for the USB high-speed ULPI compliant phy on Qualcomm
|
||||
chipsets.
|
||||
|
||||
config PHY_QCOM_USB_HSIC
|
||||
tristate "Qualcomm USB HSIC ULPI PHY module"
|
||||
depends on USB_ULPI_BUS
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for the USB HSIC ULPI compliant PHY on QCOM chipsets.
|
9
drivers/phy/qualcomm/Makefile
Normal file
9
drivers/phy/qualcomm/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o
|
||||
obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o
|
||||
obj-$(CONFIG_PHY_QCOM_QMP) += phy-qcom-qmp.o
|
||||
obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o
|
||||
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs.o
|
||||
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-14nm.o
|
||||
obj-$(CONFIG_PHY_QCOM_UFS) += phy-qcom-ufs-qmp-20nm.o
|
||||
obj-$(CONFIG_PHY_QCOM_USB_HS) += phy-qcom-usb-hs.o
|
||||
obj-$(CONFIG_PHY_QCOM_USB_HSIC) += phy-qcom-usb-hsic.o
|
@ -11,12 +11,11 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/reset.h>
|
||||
#include <linux/extcon.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
#include "ulpi_phy.h"
|
||||
|
||||
#define ULPI_PWR_CLK_MNG_REG 0x88
|
||||
# define ULPI_PWR_OTG_COMP_DISABLE BIT(0)
|
||||
|
@ -8,13 +8,12 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/ulpi/driver.h>
|
||||
#include <linux/ulpi/regs.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/pinctrl/pinctrl-state.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include "ulpi_phy.h"
|
||||
|
||||
#define ULPI_HSIC_CFG 0x30
|
||||
#define ULPI_HSIC_IO_CAL 0x33
|
||||
|
24
drivers/phy/renesas/Kconfig
Normal file
24
drivers/phy/renesas/Kconfig
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Phy drivers for Renesas platforms
|
||||
#
|
||||
config PHY_RCAR_GEN2
|
||||
tristate "Renesas R-Car generation 2 USB PHY driver"
|
||||
depends on ARCH_RENESAS
|
||||
depends on GENERIC_PHY
|
||||
help
|
||||
Support for USB PHY found on Renesas R-Car generation 2 SoCs.
|
||||
|
||||
config PHY_RCAR_GEN3_USB2
|
||||
tristate "Renesas R-Car generation 3 USB 2.0 PHY driver"
|
||||
depends on ARCH_RENESAS
|
||||
depends on EXTCON
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for USB 2.0 PHY found on Renesas R-Car generation 3 SoCs.
|
||||
|
||||
config PHY_RCAR_GEN3_USB3
|
||||
tristate "Renesas R-Car generation 3 USB 3.0 PHY driver"
|
||||
depends on ARCH_RENESAS || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for USB 3.0 PHY found on Renesas R-Car generation 3 SoCs.
|
3
drivers/phy/renesas/Makefile
Normal file
3
drivers/phy/renesas/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
obj-$(CONFIG_PHY_RCAR_GEN2) += phy-rcar-gen2.o
|
||||
obj-$(CONFIG_PHY_RCAR_GEN3_USB2) += phy-rcar-gen3-usb2.o
|
||||
obj-$(CONFIG_PHY_RCAR_GEN3_USB3) += phy-rcar-gen3-usb3.o
|
226
drivers/phy/renesas/phy-rcar-gen3-usb3.c
Normal file
226
drivers/phy/renesas/phy-rcar-gen3-usb3.c
Normal file
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Renesas R-Car Gen3 for USB3.0 PHY driver
|
||||
*
|
||||
* Copyright (C) 2017 Renesas Electronics Corporation
|
||||
*
|
||||
* 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/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/phy/phy.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#define USB30_CLKSET0 0x034
|
||||
#define USB30_CLKSET1 0x036
|
||||
#define USB30_SSC_SET 0x038
|
||||
#define USB30_PHY_ENABLE 0x060
|
||||
#define USB30_VBUS_EN 0x064
|
||||
|
||||
/* USB30_CLKSET0 */
|
||||
#define CLKSET0_PRIVATE 0x05c0
|
||||
#define CLKSET0_USB30_FSEL_USB_EXTAL 0x0002
|
||||
|
||||
/* USB30_CLKSET1 */
|
||||
#define CLKSET1_USB30_PLL_MULTI_SHIFT 6
|
||||
#define CLKSET1_USB30_PLL_MULTI_USB_EXTAL (0x64 << \
|
||||
CLKSET1_USB30_PLL_MULTI_SHIFT)
|
||||
#define CLKSET1_PHYRESET BIT(4) /* 1: reset */
|
||||
#define CLKSET1_REF_CLKDIV BIT(3) /* 1: USB_EXTAL */
|
||||
#define CLKSET1_PRIVATE_2_1 BIT(1) /* Write B'01 */
|
||||
#define CLKSET1_REF_CLK_SEL BIT(0) /* 1: USB3S0_CLK_P */
|
||||
|
||||
/* USB30_SSC_SET */
|
||||
#define SSC_SET_SSC_EN BIT(12)
|
||||
#define SSC_SET_RANGE_SHIFT 9
|
||||
#define SSC_SET_RANGE_4980 (0x0 << SSC_SET_RANGE_SHIFT)
|
||||
#define SSC_SET_RANGE_4492 (0x1 << SSC_SET_RANGE_SHIFT)
|
||||
#define SSC_SET_RANGE_4003 (0x2 << SSC_SET_RANGE_SHIFT)
|
||||
|
||||
/* USB30_PHY_ENABLE */
|
||||
#define PHY_ENABLE_RESET_EN BIT(4)
|
||||
|
||||
/* USB30_VBUS_EN */
|
||||
#define VBUS_EN_VBUS_EN BIT(1)
|
||||
|
||||
struct rcar_gen3_usb3 {
|
||||
void __iomem *base;
|
||||
struct phy *phy;
|
||||
u32 ssc_range;
|
||||
bool usb3s_clk;
|
||||
bool usb_extal;
|
||||
};
|
||||
|
||||
static void write_clkset1_for_usb_extal(struct rcar_gen3_usb3 *r, bool reset)
|
||||
{
|
||||
u16 val = CLKSET1_USB30_PLL_MULTI_USB_EXTAL |
|
||||
CLKSET1_REF_CLKDIV | CLKSET1_PRIVATE_2_1;
|
||||
|
||||
if (reset)
|
||||
val |= CLKSET1_PHYRESET;
|
||||
|
||||
writew(val, r->base + USB30_CLKSET1);
|
||||
}
|
||||
|
||||
static void rcar_gen3_phy_usb3_enable_ssc(struct rcar_gen3_usb3 *r)
|
||||
{
|
||||
u16 val = SSC_SET_SSC_EN;
|
||||
|
||||
switch (r->ssc_range) {
|
||||
case 4980:
|
||||
val |= SSC_SET_RANGE_4980;
|
||||
break;
|
||||
case 4492:
|
||||
val |= SSC_SET_RANGE_4492;
|
||||
break;
|
||||
case 4003:
|
||||
val |= SSC_SET_RANGE_4003;
|
||||
break;
|
||||
default:
|
||||
dev_err(&r->phy->dev, "%s: unsupported range (%x)\n", __func__,
|
||||
r->ssc_range);
|
||||
return;
|
||||
}
|
||||
|
||||
writew(val, r->base + USB30_SSC_SET);
|
||||
}
|
||||
|
||||
static void rcar_gen3_phy_usb3_select_usb_extal(struct rcar_gen3_usb3 *r)
|
||||
{
|
||||
write_clkset1_for_usb_extal(r, false);
|
||||
if (r->ssc_range)
|
||||
rcar_gen3_phy_usb3_enable_ssc(r);
|
||||
writew(CLKSET0_PRIVATE | CLKSET0_USB30_FSEL_USB_EXTAL,
|
||||
r->base + USB30_CLKSET0);
|
||||
writew(PHY_ENABLE_RESET_EN, r->base + USB30_PHY_ENABLE);
|
||||
write_clkset1_for_usb_extal(r, true);
|
||||
usleep_range(10, 20);
|
||||
write_clkset1_for_usb_extal(r, false);
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb3_init(struct phy *p)
|
||||
{
|
||||
struct rcar_gen3_usb3 *r = phy_get_drvdata(p);
|
||||
|
||||
dev_vdbg(&r->phy->dev, "%s: enter (%d, %d, %d)\n", __func__,
|
||||
r->usb3s_clk, r->usb_extal, r->ssc_range);
|
||||
|
||||
if (!r->usb3s_clk && r->usb_extal)
|
||||
rcar_gen3_phy_usb3_select_usb_extal(r);
|
||||
|
||||
/* Enables VBUS detection anyway */
|
||||
writew(VBUS_EN_VBUS_EN, r->base + USB30_VBUS_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct phy_ops rcar_gen3_phy_usb3_ops = {
|
||||
.init = rcar_gen3_phy_usb3_init,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct of_device_id rcar_gen3_phy_usb3_match_table[] = {
|
||||
{ .compatible = "renesas,rcar-gen3-usb3-phy" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rcar_gen3_phy_usb3_match_table);
|
||||
|
||||
static int rcar_gen3_phy_usb3_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct rcar_gen3_usb3 *r;
|
||||
struct phy_provider *provider;
|
||||
struct resource *res;
|
||||
int ret = 0;
|
||||
struct clk *clk;
|
||||
|
||||
if (!dev->of_node) {
|
||||
dev_err(dev, "This driver needs device tree\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = devm_kzalloc(dev, sizeof(*r), GFP_KERNEL);
|
||||
if (!r)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
r->base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(r->base))
|
||||
return PTR_ERR(r->base);
|
||||
|
||||
clk = devm_clk_get(dev, "usb3s_clk");
|
||||
if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
|
||||
r->usb3s_clk = !!clk_get_rate(clk);
|
||||
clk_disable_unprepare(clk);
|
||||
}
|
||||
clk = devm_clk_get(dev, "usb_extal");
|
||||
if (!IS_ERR(clk) && !clk_prepare_enable(clk)) {
|
||||
r->usb_extal = !!clk_get_rate(clk);
|
||||
clk_disable_unprepare(clk);
|
||||
}
|
||||
|
||||
if (!r->usb3s_clk && !r->usb_extal) {
|
||||
dev_err(dev, "This driver needs usb3s_clk and/or usb_extal\n");
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* devm_phy_create() will call pm_runtime_enable(&phy->dev);
|
||||
* And then, phy-core will manage runtime pm for this device.
|
||||
*/
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
r->phy = devm_phy_create(dev, NULL, &rcar_gen3_phy_usb3_ops);
|
||||
if (IS_ERR(r->phy)) {
|
||||
dev_err(dev, "Failed to create USB3 PHY\n");
|
||||
ret = PTR_ERR(r->phy);
|
||||
goto error;
|
||||
}
|
||||
|
||||
of_property_read_u32(dev->of_node, "renesas,ssc-range", &r->ssc_range);
|
||||
|
||||
platform_set_drvdata(pdev, r);
|
||||
phy_set_drvdata(r->phy, r);
|
||||
|
||||
provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
|
||||
if (IS_ERR(provider)) {
|
||||
dev_err(dev, "Failed to register PHY provider\n");
|
||||
ret = PTR_ERR(provider);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
pm_runtime_disable(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rcar_gen3_phy_usb3_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
static struct platform_driver rcar_gen3_phy_usb3_driver = {
|
||||
.driver = {
|
||||
.name = "phy_rcar_gen3_usb3",
|
||||
.of_match_table = rcar_gen3_phy_usb3_match_table,
|
||||
},
|
||||
.probe = rcar_gen3_phy_usb3_probe,
|
||||
.remove = rcar_gen3_phy_usb3_remove,
|
||||
};
|
||||
module_platform_driver(rcar_gen3_phy_usb3_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Renesas R-Car Gen3 USB 3.0 PHY");
|
||||
MODULE_AUTHOR("Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>");
|
51
drivers/phy/rockchip/Kconfig
Normal file
51
drivers/phy/rockchip/Kconfig
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# Phy drivers for Rockchip platforms
|
||||
#
|
||||
config PHY_ROCKCHIP_DP
|
||||
tristate "Rockchip Display Port PHY Driver"
|
||||
depends on ARCH_ROCKCHIP && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Rockchip Display Port PHY.
|
||||
|
||||
config PHY_ROCKCHIP_EMMC
|
||||
tristate "Rockchip EMMC PHY Driver"
|
||||
depends on ARCH_ROCKCHIP && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Rockchip EMMC PHY.
|
||||
|
||||
config PHY_ROCKCHIP_INNO_USB2
|
||||
tristate "Rockchip INNO USB2PHY Driver"
|
||||
depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF
|
||||
depends on COMMON_CLK
|
||||
depends on EXTCON
|
||||
depends on USB_SUPPORT
|
||||
select GENERIC_PHY
|
||||
select USB_COMMON
|
||||
help
|
||||
Support for Rockchip USB2.0 PHY with Innosilicon IP block.
|
||||
|
||||
config PHY_ROCKCHIP_PCIE
|
||||
tristate "Rockchip PCIe PHY Driver"
|
||||
depends on (ARCH_ROCKCHIP && OF) || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Enable this to support the Rockchip PCIe PHY.
|
||||
|
||||
config PHY_ROCKCHIP_TYPEC
|
||||
tristate "Rockchip TYPEC PHY Driver"
|
||||
depends on OF && (ARCH_ROCKCHIP || COMPILE_TEST)
|
||||
select EXTCON
|
||||
select GENERIC_PHY
|
||||
select RESET_CONTROLLER
|
||||
help
|
||||
Enable this to support the Rockchip USB TYPEC PHY.
|
||||
|
||||
config PHY_ROCKCHIP_USB
|
||||
tristate "Rockchip USB2 PHY Driver"
|
||||
depends on ARCH_ROCKCHIP && OF
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable this to support the Rockchip USB 2.0 PHY.
|
6
drivers/phy/rockchip/Makefile
Normal file
6
drivers/phy/rockchip/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_DP) += phy-rockchip-dp.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_EMMC) += phy-rockchip-emmc.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_INNO_USB2) += phy-rockchip-inno-usb2.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_PCIE) += phy-rockchip-pcie.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_TYPEC) += phy-rockchip-typec.o
|
||||
obj-$(CONFIG_PHY_ROCKCHIP_USB) += phy-rockchip-usb.o
|
@ -406,7 +406,8 @@ static int rockchip_usb2phy_init(struct phy *phy)
|
||||
mutex_lock(&rport->mutex);
|
||||
|
||||
if (rport->port_id == USB2PHY_PORT_OTG) {
|
||||
if (rport->mode != USB_DR_MODE_HOST) {
|
||||
if (rport->mode != USB_DR_MODE_HOST &&
|
||||
rport->mode != USB_DR_MODE_UNKNOWN) {
|
||||
/* clear bvalid status and enable bvalid detect irq */
|
||||
ret = property_enable(rphy,
|
||||
&rport->port_cfg->bvalid_det_clr,
|
||||
@ -421,7 +422,7 @@ static int rockchip_usb2phy_init(struct phy *phy)
|
||||
goto out;
|
||||
|
||||
schedule_delayed_work(&rport->otg_sm_work,
|
||||
OTG_SCHEDULE_DELAY);
|
||||
OTG_SCHEDULE_DELAY * 3);
|
||||
} else {
|
||||
/* If OTG works in host only mode, do nothing. */
|
||||
dev_dbg(&rport->phy->dev, "mode %d\n", rport->mode);
|
||||
@ -463,6 +464,9 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* waiting for the utmi_clk to become stable */
|
||||
usleep_range(1500, 2000);
|
||||
|
||||
rport->suspended = false;
|
||||
return 0;
|
||||
}
|
||||
@ -493,7 +497,8 @@ static int rockchip_usb2phy_exit(struct phy *phy)
|
||||
struct rockchip_usb2phy_port *rport = phy_get_drvdata(phy);
|
||||
|
||||
if (rport->port_id == USB2PHY_PORT_OTG &&
|
||||
rport->mode != USB_DR_MODE_HOST) {
|
||||
rport->mode != USB_DR_MODE_HOST &&
|
||||
rport->mode != USB_DR_MODE_UNKNOWN) {
|
||||
cancel_delayed_work_sync(&rport->otg_sm_work);
|
||||
cancel_delayed_work_sync(&rport->chg_work);
|
||||
} else if (rport->port_id == USB2PHY_PORT_HOST)
|
||||
@ -970,7 +975,8 @@ static int rockchip_usb2phy_otg_port_init(struct rockchip_usb2phy *rphy,
|
||||
mutex_init(&rport->mutex);
|
||||
|
||||
rport->mode = of_usb_get_dr_mode_by_phy(child_np, -1);
|
||||
if (rport->mode == USB_DR_MODE_HOST) {
|
||||
if (rport->mode == USB_DR_MODE_HOST ||
|
||||
rport->mode == USB_DR_MODE_UNKNOWN) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
@ -1138,6 +1144,65 @@ disable_clks:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct rockchip_usb2phy_cfg rk3228_phy_cfgs[] = {
|
||||
{
|
||||
.reg = 0x760,
|
||||
.num_ports = 2,
|
||||
.clkout_ctl = { 0x0768, 4, 4, 1, 0 },
|
||||
.port_cfgs = {
|
||||
[USB2PHY_PORT_OTG] = {
|
||||
.phy_sus = { 0x0760, 15, 0, 0, 0x1d1 },
|
||||
.bvalid_det_en = { 0x0680, 3, 3, 0, 1 },
|
||||
.bvalid_det_st = { 0x0690, 3, 3, 0, 1 },
|
||||
.bvalid_det_clr = { 0x06a0, 3, 3, 0, 1 },
|
||||
.ls_det_en = { 0x0680, 2, 2, 0, 1 },
|
||||
.ls_det_st = { 0x0690, 2, 2, 0, 1 },
|
||||
.ls_det_clr = { 0x06a0, 2, 2, 0, 1 },
|
||||
.utmi_bvalid = { 0x0480, 4, 4, 0, 1 },
|
||||
.utmi_ls = { 0x0480, 3, 2, 0, 1 },
|
||||
},
|
||||
[USB2PHY_PORT_HOST] = {
|
||||
.phy_sus = { 0x0764, 15, 0, 0, 0x1d1 },
|
||||
.ls_det_en = { 0x0680, 4, 4, 0, 1 },
|
||||
.ls_det_st = { 0x0690, 4, 4, 0, 1 },
|
||||
.ls_det_clr = { 0x06a0, 4, 4, 0, 1 }
|
||||
}
|
||||
},
|
||||
.chg_det = {
|
||||
.opmode = { 0x0760, 3, 0, 5, 1 },
|
||||
.cp_det = { 0x0884, 4, 4, 0, 1 },
|
||||
.dcp_det = { 0x0884, 3, 3, 0, 1 },
|
||||
.dp_det = { 0x0884, 5, 5, 0, 1 },
|
||||
.idm_sink_en = { 0x0768, 8, 8, 0, 1 },
|
||||
.idp_sink_en = { 0x0768, 7, 7, 0, 1 },
|
||||
.idp_src_en = { 0x0768, 9, 9, 0, 1 },
|
||||
.rdm_pdwn_en = { 0x0768, 10, 10, 0, 1 },
|
||||
.vdm_src_en = { 0x0768, 12, 12, 0, 1 },
|
||||
.vdp_src_en = { 0x0768, 11, 11, 0, 1 },
|
||||
},
|
||||
},
|
||||
{
|
||||
.reg = 0x800,
|
||||
.num_ports = 2,
|
||||
.clkout_ctl = { 0x0808, 4, 4, 1, 0 },
|
||||
.port_cfgs = {
|
||||
[USB2PHY_PORT_OTG] = {
|
||||
.phy_sus = { 0x800, 15, 0, 0, 0x1d1 },
|
||||
.ls_det_en = { 0x0684, 0, 0, 0, 1 },
|
||||
.ls_det_st = { 0x0694, 0, 0, 0, 1 },
|
||||
.ls_det_clr = { 0x06a4, 0, 0, 0, 1 }
|
||||
},
|
||||
[USB2PHY_PORT_HOST] = {
|
||||
.phy_sus = { 0x804, 15, 0, 0, 0x1d1 },
|
||||
.ls_det_en = { 0x0684, 1, 1, 0, 1 },
|
||||
.ls_det_st = { 0x0694, 1, 1, 0, 1 },
|
||||
.ls_det_clr = { 0x06a4, 1, 1, 0, 1 }
|
||||
}
|
||||
},
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static const struct rockchip_usb2phy_cfg rk3328_phy_cfgs[] = {
|
||||
{
|
||||
.reg = 0x100,
|
||||
@ -1263,6 +1328,7 @@ static const struct rockchip_usb2phy_cfg rk3399_phy_cfgs[] = {
|
||||
};
|
||||
|
||||
static const struct of_device_id rockchip_usb2phy_dt_match[] = {
|
||||
{ .compatible = "rockchip,rk3228-usb2phy", .data = &rk3228_phy_cfgs },
|
||||
{ .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs },
|
||||
{ .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs },
|
||||
{ .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs },
|
95
drivers/phy/samsung/Kconfig
Normal file
95
drivers/phy/samsung/Kconfig
Normal file
@ -0,0 +1,95 @@
|
||||
#
|
||||
# Phy drivers for Samsung platforms
|
||||
#
|
||||
config PHY_EXYNOS_DP_VIDEO
|
||||
tristate "EXYNOS SoC series Display Port PHY driver"
|
||||
depends on OF
|
||||
depends on ARCH_EXYNOS || COMPILE_TEST
|
||||
default ARCH_EXYNOS
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Support for Display Port PHY found on Samsung EXYNOS SoCs.
|
||||
|
||||
config PHY_EXYNOS_MIPI_VIDEO
|
||||
tristate "S5P/EXYNOS SoC series MIPI CSI-2/DSI PHY driver"
|
||||
depends on HAS_IOMEM
|
||||
depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST
|
||||
select GENERIC_PHY
|
||||
default y if ARCH_S5PV210 || ARCH_EXYNOS
|
||||
help
|
||||
Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P
|
||||
and EXYNOS SoCs.
|
||||
|
||||
config PHY_EXYNOS_PCIE
|
||||
bool "Exynos PCIe PHY driver"
|
||||
depends on OF && (ARCH_EXYNOS || COMPILE_TEST)
|
||||
select GENERIC_PHY
|
||||
help
|
||||
Enable PCIe PHY support for Exynos SoC series.
|
||||
This driver provides PHY interface for Exynos PCIe controller.
|
||||
|
||||
config PHY_SAMSUNG_USB2
|
||||
tristate "Samsung USB 2.0 PHY driver"
|
||||
depends on HAS_IOMEM
|
||||
depends on USB_EHCI_EXYNOS || USB_OHCI_EXYNOS || USB_DWC2
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
default ARCH_EXYNOS
|
||||
help
|
||||
Enable this to support the Samsung USB 2.0 PHY driver for Samsung
|
||||
SoCs. This driver provides the interface for USB 2.0 PHY. Support
|
||||
for particular PHYs will be enabled based on the SoC type in addition
|
||||
to this driver.
|
||||
|
||||
config PHY_EXYNOS4210_USB2
|
||||
bool
|
||||
depends on PHY_SAMSUNG_USB2
|
||||
default CPU_EXYNOS4210
|
||||
|
||||
config PHY_EXYNOS4X12_USB2
|
||||
bool
|
||||
depends on PHY_SAMSUNG_USB2
|
||||
default SOC_EXYNOS3250 || SOC_EXYNOS4212 || SOC_EXYNOS4412
|
||||
|
||||
config PHY_EXYNOS5250_USB2
|
||||
bool
|
||||
depends on PHY_SAMSUNG_USB2
|
||||
default SOC_EXYNOS5250 || SOC_EXYNOS5420
|
||||
|
||||
config PHY_S5PV210_USB2
|
||||
bool "Support for S5PV210"
|
||||
depends on PHY_SAMSUNG_USB2
|
||||
depends on ARCH_S5PV210
|
||||
help
|
||||
Enable USB PHY support for S5PV210. This option requires that Samsung
|
||||
USB 2.0 PHY driver is enabled and means that support for this
|
||||
particular SoC is compiled in the driver. In case of S5PV210 two phys
|
||||
are available - device and host.
|
||||
|
||||
config PHY_EXYNOS5_USBDRD
|
||||
tristate "Exynos5 SoC series USB DRD PHY driver"
|
||||
depends on ARCH_EXYNOS && OF
|
||||
depends on HAS_IOMEM
|
||||
depends on USB_DWC3_EXYNOS
|
||||
select GENERIC_PHY
|
||||
select MFD_SYSCON
|
||||
default y
|
||||
help
|
||||
Enable USB DRD PHY support for Exynos 5 SoC series.
|
||||
This driver provides PHY interface for USB 3.0 DRD controller
|
||||
present on Exynos5 SoC series.
|
||||
|
||||
config PHY_EXYNOS5250_SATA
|
||||
tristate "Exynos5250 Sata SerDes/PHY driver"
|
||||
depends on SOC_EXYNOS5250
|
||||
depends on HAS_IOMEM
|
||||
depends on OF
|
||||
select GENERIC_PHY
|
||||
select I2C
|
||||
select I2C_S3C2410
|
||||
select MFD_SYSCON
|
||||
help
|
||||
Enable this to support SATA SerDes/Phy found on Samsung's
|
||||
Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s,
|
||||
SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host
|
||||
port to accept one SATA device.
|
11
drivers/phy/samsung/Makefile
Normal file
11
drivers/phy/samsung/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO) += phy-exynos-dp-video.o
|
||||
obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO) += phy-exynos-mipi-video.o
|
||||
obj-$(CONFIG_PHY_EXYNOS_PCIE) += phy-exynos-pcie.o
|
||||
obj-$(CONFIG_PHY_SAMSUNG_USB2) += phy-exynos-usb2.o
|
||||
phy-exynos-usb2-y += phy-samsung-usb2.o
|
||||
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4210_USB2) += phy-exynos4210-usb2.o
|
||||
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS4X12_USB2) += phy-exynos4x12-usb2.o
|
||||
phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o
|
||||
phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o
|
||||
obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o
|
||||
obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user