phy: for 4.13
*) Group phy drivers into vendor specific directories *) Add USB3 PHY driver for Renesas R-Car Gen3 *) Add USB2 PHY driver for Meson GXL and GXM SoCs *) Add USB DRD PHY driver for Broadcom Northstar2 *) Add USB PHY driver for CPCAP PMIC USB *) Make phy-meson8b-usb2 driver support USB PHY on Meson8 *) Make phy-tusb1210 driver support TUSB1211 *) Make phy-rockchip-inno-usb2 driver support usb2-phy in rk3228 SoCs *) Make phy-brcm-sata driver support for stingray SATA phy *) Make bcm-ns-usb3 as a MDIO driver *) Make rockchip-inno-usb2 support two host ports *) Implement ->set_mode() callback in phy-tusb1210 *) Minor fixes in phy drivers Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJZQ8eDAAoJEA5ceFyATYLZkPQP/2rnRFd3aCuMboOCTvJXyC4v YWxxk7M/yaicvH4YHgyO+HAH69Byy5uZ7R5CWR1iG6rEuoKob47f1DwvM4HV00LE 0jx3bZKsxyDS1ezGFJqZJMx10STwMdrl3H6cMD7Ot9gZJ4H4EWu2VJxIFN78xRWD VrsPvMrZdW7raxr9addqoy+/r+Uu9y4idcPjhcQkUUGqlscnOcW2r7WomWQaOcq1 YXyOxeNzVLEQbIK/yd6NzLTfYvlgSf9rD7nucwyKF6oGbpFaEFsy7+Zha2xsWxsT IgfdvquYKFaD2Y1jfzszdn6yopV14V9zhbHz9e3uGbk0lak6E0+qOXA8Mw3L47PK 7eTFmIau221zuxutbEjz4edRJfYORjrlNy1JLSvyMrvQS5F0DstAka91BVeBS1CT kVdeO0gf1L7+dqDGCGt4byQwUiYD3zNfCb6JqZaIRGyLrc1OfHrUWQoS0kZxj4B0 E9sB2bem6sEKjWoc92EFJvA1d/BpZb4fBmgNu/rKHUfDMI1XWK+5coDd7w4xOGol 3M3/kmzetanZTpFQ/2XJnJQ3eiJCh6eY7LoDXAYbxeMsx1y9EwcX7rkbMVF1/Iap AEq+9oMZA0hk5QdX6L8Z+WKHm8AHswltVKpnVKD0+e/ysVuRscALl/Ip3nCalNzY 0kEYmF7KlVM/r3Cj1xlU =RzAi -----END PGP SIGNATURE----- Merge tag 'phy-for-4.13' of git://git.kernel.org/pub/scm/linux/kernel/git/kishon/linux-phy into usb-next Kishon writes: phy: for 4.13 *) Group phy drivers into vendor specific directories *) Add USB3 PHY driver for Renesas R-Car Gen3 *) Add USB2 PHY driver for Meson GXL and GXM SoCs *) Add USB DRD PHY driver for Broadcom Northstar2 *) Add USB PHY driver for CPCAP PMIC USB *) Make phy-meson8b-usb2 driver support USB PHY on Meson8 *) Make phy-tusb1210 driver support TUSB1211 *) Make phy-rockchip-inno-usb2 driver support usb2-phy in rk3228 SoCs *) Make phy-brcm-sata driver support for stingray SATA phy *) Make bcm-ns-usb3 as a MDIO driver *) Make rockchip-inno-usb2 support two host ports *) Implement ->set_mode() callback in phy-tusb1210 *) Minor fixes in phy drivers Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
This commit is contained in:
commit
21bdb3b071
@ -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 {
|
||||
compatible = "brcm,ns-ax-usb3-phy";
|
||||
reg = <0x18105000 0x1000>, <0x18003000 0x1000>;
|
||||
reg-names = "dmp", "ccb-mii";
|
||||
#phy-cells = <0>;
|
||||
mdio: mdio@0 {
|
||||
reg = <0x0>;
|
||||
#size-cells = <1>;
|
||||
#address-cells = <0>;
|
||||
|
||||
usb3-phy@10 {
|
||||
compatible = "brcm,ns-ax-usb3-phy";
|
||||
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";
|
||||
};
|
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
|
||||
@ -10831,11 +10831,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>
|
||||
@ -11237,12 +11237,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>
|
||||
|
@ -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_TEGRA) += tegra/
|
||||
obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
|
||||
obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.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-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
|
33
drivers/phy/st/Kconfig
Normal file
33
drivers/phy/st/Kconfig
Normal file
@ -0,0 +1,33 @@
|
||||
#
|
||||
# Phy drivers for STMicro platforms
|
||||
#
|
||||
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_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_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.
|
4
drivers/phy/st/Makefile
Normal file
4
drivers/phy/st/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
obj-$(CONFIG_PHY_MIPHY28LP) += phy-miphy28lp.o
|
||||
obj-$(CONFIG_PHY_ST_SPEAR1310_MIPHY) += phy-spear1310-miphy.o
|
||||
obj-$(CONFIG_PHY_ST_SPEAR1340_MIPHY) += phy-spear1340-miphy.o
|
||||
obj-$(CONFIG_PHY_STIH407_USB) += phy-stih407-usb.o
|
78
drivers/phy/ti/Kconfig
Normal file
78
drivers/phy/ti/Kconfig
Normal file
@ -0,0 +1,78 @@
|
||||
#
|
||||
# Phy drivers for TI platforms
|
||||
#
|
||||
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 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 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 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.
|
7
drivers/phy/ti/Makefile
Normal file
7
drivers/phy/ti/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o
|
||||
obj-$(CONFIG_PHY_DM816X_USB) += phy-dm816x-usb.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_PHY_TUSB1210) += phy-tusb1210.o
|
||||
obj-$(CONFIG_TWL4030_USB) += phy-twl4030-usb.o
|
@ -11,9 +11,9 @@
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/ulpi/driver.h>
|
||||
#include <linux/ulpi/regs.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
|
||||
#include "ulpi_phy.h"
|
||||
#include <linux/phy/ulpi_phy.h>
|
||||
|
||||
#define TUSB1210_VENDOR_SPECIFIC2 0x80
|
||||
#define TUSB1210_VENDOR_SPECIFIC2_IHSTX_SHIFT 0
|
||||
@ -53,9 +53,43 @@ static int tusb1210_power_off(struct phy *phy)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tusb1210_set_mode(struct phy *phy, enum phy_mode mode)
|
||||
{
|
||||
struct tusb1210 *tusb = phy_get_drvdata(phy);
|
||||
int ret;
|
||||
|
||||
ret = ulpi_read(tusb->ulpi, ULPI_OTG_CTRL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (mode) {
|
||||
case PHY_MODE_USB_HOST:
|
||||
ret |= (ULPI_OTG_CTRL_DRVVBUS_EXT
|
||||
| ULPI_OTG_CTRL_ID_PULLUP
|
||||
| ULPI_OTG_CTRL_DP_PULLDOWN
|
||||
| ULPI_OTG_CTRL_DM_PULLDOWN);
|
||||
ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
|
||||
ret |= ULPI_OTG_CTRL_DRVVBUS;
|
||||
break;
|
||||
case PHY_MODE_USB_DEVICE:
|
||||
ret &= ~(ULPI_OTG_CTRL_DRVVBUS
|
||||
| ULPI_OTG_CTRL_DP_PULLDOWN
|
||||
| ULPI_OTG_CTRL_DM_PULLDOWN);
|
||||
ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
|
||||
ret &= ~ULPI_OTG_CTRL_DRVVBUS_EXT;
|
||||
break;
|
||||
default:
|
||||
/* nothing */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ulpi_write(tusb->ulpi, ULPI_OTG_CTRL, ret);
|
||||
}
|
||||
|
||||
static const struct phy_ops phy_ops = {
|
||||
.power_on = tusb1210_power_on,
|
||||
.power_off = tusb1210_power_off,
|
||||
.set_mode = tusb1210_set_mode,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
@ -125,7 +159,8 @@ static void tusb1210_remove(struct ulpi *ulpi)
|
||||
#define TI_VENDOR_ID 0x0451
|
||||
|
||||
static const struct ulpi_device_id tusb1210_ulpi_id[] = {
|
||||
{ TI_VENDOR_ID, 0x1507, },
|
||||
{ TI_VENDOR_ID, 0x1507, }, /* TUSB1210 */
|
||||
{ TI_VENDOR_ID, 0x1508, }, /* TUSB1211 */
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(ulpi, tusb1210_ulpi_id);
|
Loading…
Reference in New Issue
Block a user