18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Meson8, Meson8b and GXBB USB2 PHY driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2016 Martin Blumenstingl <martin.blumenstingl@googlemail.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/clk.h> 98c2ecf20Sopenharmony_ci#include <linux/delay.h> 108c2ecf20Sopenharmony_ci#include <linux/io.h> 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/of_device.h> 138c2ecf20Sopenharmony_ci#include <linux/property.h> 148c2ecf20Sopenharmony_ci#include <linux/regmap.h> 158c2ecf20Sopenharmony_ci#include <linux/reset.h> 168c2ecf20Sopenharmony_ci#include <linux/phy/phy.h> 178c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 188c2ecf20Sopenharmony_ci#include <linux/usb/of.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci#define REG_CONFIG 0x00 218c2ecf20Sopenharmony_ci #define REG_CONFIG_CLK_EN BIT(0) 228c2ecf20Sopenharmony_ci #define REG_CONFIG_CLK_SEL_MASK GENMASK(3, 1) 238c2ecf20Sopenharmony_ci #define REG_CONFIG_CLK_DIV_MASK GENMASK(10, 4) 248c2ecf20Sopenharmony_ci #define REG_CONFIG_CLK_32k_ALTSEL BIT(15) 258c2ecf20Sopenharmony_ci #define REG_CONFIG_TEST_TRIG BIT(31) 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define REG_CTRL 0x04 288c2ecf20Sopenharmony_ci #define REG_CTRL_SOFT_PRST BIT(0) 298c2ecf20Sopenharmony_ci #define REG_CTRL_SOFT_HRESET BIT(1) 308c2ecf20Sopenharmony_ci #define REG_CTRL_SS_SCALEDOWN_MODE_MASK GENMASK(3, 2) 318c2ecf20Sopenharmony_ci #define REG_CTRL_CLK_DET_RST BIT(4) 328c2ecf20Sopenharmony_ci #define REG_CTRL_INTR_SEL BIT(5) 338c2ecf20Sopenharmony_ci #define REG_CTRL_CLK_DETECTED BIT(8) 348c2ecf20Sopenharmony_ci #define REG_CTRL_SOF_SENT_RCVD_TGL BIT(9) 358c2ecf20Sopenharmony_ci #define REG_CTRL_SOF_TOGGLE_OUT BIT(10) 368c2ecf20Sopenharmony_ci #define REG_CTRL_POWER_ON_RESET BIT(15) 378c2ecf20Sopenharmony_ci #define REG_CTRL_SLEEPM BIT(16) 388c2ecf20Sopenharmony_ci #define REG_CTRL_TX_BITSTUFF_ENN_H BIT(17) 398c2ecf20Sopenharmony_ci #define REG_CTRL_TX_BITSTUFF_ENN BIT(18) 408c2ecf20Sopenharmony_ci #define REG_CTRL_COMMON_ON BIT(19) 418c2ecf20Sopenharmony_ci #define REG_CTRL_REF_CLK_SEL_MASK GENMASK(21, 20) 428c2ecf20Sopenharmony_ci #define REG_CTRL_REF_CLK_SEL_SHIFT 20 438c2ecf20Sopenharmony_ci #define REG_CTRL_FSEL_MASK GENMASK(24, 22) 448c2ecf20Sopenharmony_ci #define REG_CTRL_FSEL_SHIFT 22 458c2ecf20Sopenharmony_ci #define REG_CTRL_PORT_RESET BIT(25) 468c2ecf20Sopenharmony_ci #define REG_CTRL_THREAD_ID_MASK GENMASK(31, 26) 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#define REG_ENDP_INTR 0x08 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci/* bits [31:26], [24:21] and [15:3] seem to be read-only */ 518c2ecf20Sopenharmony_ci#define REG_ADP_BC 0x0c 528c2ecf20Sopenharmony_ci #define REG_ADP_BC_VBUS_VLD_EXT_SEL BIT(0) 538c2ecf20Sopenharmony_ci #define REG_ADP_BC_VBUS_VLD_EXT BIT(1) 548c2ecf20Sopenharmony_ci #define REG_ADP_BC_OTG_DISABLE BIT(2) 558c2ecf20Sopenharmony_ci #define REG_ADP_BC_ID_PULLUP BIT(3) 568c2ecf20Sopenharmony_ci #define REG_ADP_BC_DRV_VBUS BIT(4) 578c2ecf20Sopenharmony_ci #define REG_ADP_BC_ADP_PRB_EN BIT(5) 588c2ecf20Sopenharmony_ci #define REG_ADP_BC_ADP_DISCHARGE BIT(6) 598c2ecf20Sopenharmony_ci #define REG_ADP_BC_ADP_CHARGE BIT(7) 608c2ecf20Sopenharmony_ci #define REG_ADP_BC_SESS_END BIT(8) 618c2ecf20Sopenharmony_ci #define REG_ADP_BC_DEVICE_SESS_VLD BIT(9) 628c2ecf20Sopenharmony_ci #define REG_ADP_BC_B_VALID BIT(10) 638c2ecf20Sopenharmony_ci #define REG_ADP_BC_A_VALID BIT(11) 648c2ecf20Sopenharmony_ci #define REG_ADP_BC_ID_DIG BIT(12) 658c2ecf20Sopenharmony_ci #define REG_ADP_BC_VBUS_VALID BIT(13) 668c2ecf20Sopenharmony_ci #define REG_ADP_BC_ADP_PROBE BIT(14) 678c2ecf20Sopenharmony_ci #define REG_ADP_BC_ADP_SENSE BIT(15) 688c2ecf20Sopenharmony_ci #define REG_ADP_BC_ACA_ENABLE BIT(16) 698c2ecf20Sopenharmony_ci #define REG_ADP_BC_DCD_ENABLE BIT(17) 708c2ecf20Sopenharmony_ci #define REG_ADP_BC_VDAT_DET_EN_B BIT(18) 718c2ecf20Sopenharmony_ci #define REG_ADP_BC_VDAT_SRC_EN_B BIT(19) 728c2ecf20Sopenharmony_ci #define REG_ADP_BC_CHARGE_SEL BIT(20) 738c2ecf20Sopenharmony_ci #define REG_ADP_BC_CHARGE_DETECT BIT(21) 748c2ecf20Sopenharmony_ci #define REG_ADP_BC_ACA_PIN_RANGE_C BIT(22) 758c2ecf20Sopenharmony_ci #define REG_ADP_BC_ACA_PIN_RANGE_B BIT(23) 768c2ecf20Sopenharmony_ci #define REG_ADP_BC_ACA_PIN_RANGE_A BIT(24) 778c2ecf20Sopenharmony_ci #define REG_ADP_BC_ACA_PIN_GND BIT(25) 788c2ecf20Sopenharmony_ci #define REG_ADP_BC_ACA_PIN_FLOAT BIT(26) 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci#define REG_DBG_UART 0x10 818c2ecf20Sopenharmony_ci #define REG_DBG_UART_BYPASS_SEL BIT(0) 828c2ecf20Sopenharmony_ci #define REG_DBG_UART_BYPASS_DM_EN BIT(1) 838c2ecf20Sopenharmony_ci #define REG_DBG_UART_BYPASS_DP_EN BIT(2) 848c2ecf20Sopenharmony_ci #define REG_DBG_UART_BYPASS_DM_DATA BIT(3) 858c2ecf20Sopenharmony_ci #define REG_DBG_UART_BYPASS_DP_DATA BIT(4) 868c2ecf20Sopenharmony_ci #define REG_DBG_UART_FSV_MINUS BIT(5) 878c2ecf20Sopenharmony_ci #define REG_DBG_UART_FSV_PLUS BIT(6) 888c2ecf20Sopenharmony_ci #define REG_DBG_UART_FSV_BURN_IN_TEST BIT(7) 898c2ecf20Sopenharmony_ci #define REG_DBG_UART_LOOPBACK_EN_B BIT(8) 908c2ecf20Sopenharmony_ci #define REG_DBG_UART_SET_IDDQ BIT(9) 918c2ecf20Sopenharmony_ci #define REG_DBG_UART_ATE_RESET BIT(10) 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci#define REG_TEST 0x14 948c2ecf20Sopenharmony_ci #define REG_TEST_DATA_IN_MASK GENMASK(3, 0) 958c2ecf20Sopenharmony_ci #define REG_TEST_EN_MASK GENMASK(7, 4) 968c2ecf20Sopenharmony_ci #define REG_TEST_ADDR_MASK GENMASK(11, 8) 978c2ecf20Sopenharmony_ci #define REG_TEST_DATA_OUT_SEL BIT(12) 988c2ecf20Sopenharmony_ci #define REG_TEST_CLK BIT(13) 998c2ecf20Sopenharmony_ci #define REG_TEST_VA_TEST_EN_B_MASK GENMASK(15, 14) 1008c2ecf20Sopenharmony_ci #define REG_TEST_DATA_OUT_MASK GENMASK(19, 16) 1018c2ecf20Sopenharmony_ci #define REG_TEST_DISABLE_ID_PULLUP BIT(20) 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci#define REG_TUNE 0x18 1048c2ecf20Sopenharmony_ci #define REG_TUNE_TX_RES_TUNE_MASK GENMASK(1, 0) 1058c2ecf20Sopenharmony_ci #define REG_TUNE_TX_HSXV_TUNE_MASK GENMASK(3, 2) 1068c2ecf20Sopenharmony_ci #define REG_TUNE_TX_VREF_TUNE_MASK GENMASK(7, 4) 1078c2ecf20Sopenharmony_ci #define REG_TUNE_TX_RISE_TUNE_MASK GENMASK(9, 8) 1088c2ecf20Sopenharmony_ci #define REG_TUNE_TX_PREEMP_PULSE_TUNE BIT(10) 1098c2ecf20Sopenharmony_ci #define REG_TUNE_TX_PREEMP_AMP_TUNE_MASK GENMASK(12, 11) 1108c2ecf20Sopenharmony_ci #define REG_TUNE_TX_FSLS_TUNE_MASK GENMASK(16, 13) 1118c2ecf20Sopenharmony_ci #define REG_TUNE_SQRX_TUNE_MASK GENMASK(19, 17) 1128c2ecf20Sopenharmony_ci #define REG_TUNE_OTG_TUNE GENMASK(22, 20) 1138c2ecf20Sopenharmony_ci #define REG_TUNE_COMP_DIS_TUNE GENMASK(25, 23) 1148c2ecf20Sopenharmony_ci #define REG_TUNE_HOST_DM_PULLDOWN BIT(26) 1158c2ecf20Sopenharmony_ci #define REG_TUNE_HOST_DP_PULLDOWN BIT(27) 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci#define RESET_COMPLETE_TIME 500 1188c2ecf20Sopenharmony_ci#define ACA_ENABLE_COMPLETE_TIME 50 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistruct phy_meson8b_usb2_match_data { 1218c2ecf20Sopenharmony_ci bool host_enable_aca; 1228c2ecf20Sopenharmony_ci}; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_cistruct phy_meson8b_usb2_priv { 1258c2ecf20Sopenharmony_ci struct regmap *regmap; 1268c2ecf20Sopenharmony_ci enum usb_dr_mode dr_mode; 1278c2ecf20Sopenharmony_ci struct clk *clk_usb_general; 1288c2ecf20Sopenharmony_ci struct clk *clk_usb; 1298c2ecf20Sopenharmony_ci struct reset_control *reset; 1308c2ecf20Sopenharmony_ci const struct phy_meson8b_usb2_match_data *match; 1318c2ecf20Sopenharmony_ci}; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_cistatic const struct regmap_config phy_meson8b_usb2_regmap_conf = { 1348c2ecf20Sopenharmony_ci .reg_bits = 8, 1358c2ecf20Sopenharmony_ci .val_bits = 32, 1368c2ecf20Sopenharmony_ci .reg_stride = 4, 1378c2ecf20Sopenharmony_ci .max_register = REG_TUNE, 1388c2ecf20Sopenharmony_ci}; 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistatic int phy_meson8b_usb2_power_on(struct phy *phy) 1418c2ecf20Sopenharmony_ci{ 1428c2ecf20Sopenharmony_ci struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy); 1438c2ecf20Sopenharmony_ci u32 reg; 1448c2ecf20Sopenharmony_ci int ret; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci if (!IS_ERR_OR_NULL(priv->reset)) { 1478c2ecf20Sopenharmony_ci ret = reset_control_reset(priv->reset); 1488c2ecf20Sopenharmony_ci if (ret) { 1498c2ecf20Sopenharmony_ci dev_err(&phy->dev, "Failed to trigger USB reset\n"); 1508c2ecf20Sopenharmony_ci return ret; 1518c2ecf20Sopenharmony_ci } 1528c2ecf20Sopenharmony_ci } 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci ret = clk_prepare_enable(priv->clk_usb_general); 1558c2ecf20Sopenharmony_ci if (ret) { 1568c2ecf20Sopenharmony_ci dev_err(&phy->dev, "Failed to enable USB general clock\n"); 1578c2ecf20Sopenharmony_ci return ret; 1588c2ecf20Sopenharmony_ci } 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci ret = clk_prepare_enable(priv->clk_usb); 1618c2ecf20Sopenharmony_ci if (ret) { 1628c2ecf20Sopenharmony_ci dev_err(&phy->dev, "Failed to enable USB DDR clock\n"); 1638c2ecf20Sopenharmony_ci clk_disable_unprepare(priv->clk_usb_general); 1648c2ecf20Sopenharmony_ci return ret; 1658c2ecf20Sopenharmony_ci } 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci regmap_update_bits(priv->regmap, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL, 1688c2ecf20Sopenharmony_ci REG_CONFIG_CLK_32k_ALTSEL); 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK, 1718c2ecf20Sopenharmony_ci 0x2 << REG_CTRL_REF_CLK_SEL_SHIFT); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_FSEL_MASK, 1748c2ecf20Sopenharmony_ci 0x5 << REG_CTRL_FSEL_SHIFT); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci /* reset the PHY */ 1778c2ecf20Sopenharmony_ci regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 1788c2ecf20Sopenharmony_ci REG_CTRL_POWER_ON_RESET); 1798c2ecf20Sopenharmony_ci udelay(RESET_COMPLETE_TIME); 1808c2ecf20Sopenharmony_ci regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 0); 1818c2ecf20Sopenharmony_ci udelay(RESET_COMPLETE_TIME); 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT, 1848c2ecf20Sopenharmony_ci REG_CTRL_SOF_TOGGLE_OUT); 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_ci if (priv->dr_mode == USB_DR_MODE_HOST) { 1878c2ecf20Sopenharmony_ci regmap_update_bits(priv->regmap, REG_DBG_UART, 1888c2ecf20Sopenharmony_ci REG_DBG_UART_SET_IDDQ, 0); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci if (priv->match->host_enable_aca) { 1918c2ecf20Sopenharmony_ci regmap_update_bits(priv->regmap, REG_ADP_BC, 1928c2ecf20Sopenharmony_ci REG_ADP_BC_ACA_ENABLE, 1938c2ecf20Sopenharmony_ci REG_ADP_BC_ACA_ENABLE); 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci udelay(ACA_ENABLE_COMPLETE_TIME); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci regmap_read(priv->regmap, REG_ADP_BC, ®); 1988c2ecf20Sopenharmony_ci if (reg & REG_ADP_BC_ACA_PIN_FLOAT) { 1998c2ecf20Sopenharmony_ci dev_warn(&phy->dev, "USB ID detect failed!\n"); 2008c2ecf20Sopenharmony_ci clk_disable_unprepare(priv->clk_usb); 2018c2ecf20Sopenharmony_ci clk_disable_unprepare(priv->clk_usb_general); 2028c2ecf20Sopenharmony_ci return -EINVAL; 2038c2ecf20Sopenharmony_ci } 2048c2ecf20Sopenharmony_ci } 2058c2ecf20Sopenharmony_ci } 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci return 0; 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistatic int phy_meson8b_usb2_power_off(struct phy *phy) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy); 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci if (priv->dr_mode == USB_DR_MODE_HOST) 2158c2ecf20Sopenharmony_ci regmap_update_bits(priv->regmap, REG_DBG_UART, 2168c2ecf20Sopenharmony_ci REG_DBG_UART_SET_IDDQ, 2178c2ecf20Sopenharmony_ci REG_DBG_UART_SET_IDDQ); 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci clk_disable_unprepare(priv->clk_usb); 2208c2ecf20Sopenharmony_ci clk_disable_unprepare(priv->clk_usb_general); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci return 0; 2238c2ecf20Sopenharmony_ci} 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic const struct phy_ops phy_meson8b_usb2_ops = { 2268c2ecf20Sopenharmony_ci .power_on = phy_meson8b_usb2_power_on, 2278c2ecf20Sopenharmony_ci .power_off = phy_meson8b_usb2_power_off, 2288c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 2298c2ecf20Sopenharmony_ci}; 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_cistatic int phy_meson8b_usb2_probe(struct platform_device *pdev) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci struct phy_meson8b_usb2_priv *priv; 2348c2ecf20Sopenharmony_ci struct phy *phy; 2358c2ecf20Sopenharmony_ci struct phy_provider *phy_provider; 2368c2ecf20Sopenharmony_ci void __iomem *base; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 2398c2ecf20Sopenharmony_ci if (!priv) 2408c2ecf20Sopenharmony_ci return -ENOMEM; 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_ci base = devm_platform_ioremap_resource(pdev, 0); 2438c2ecf20Sopenharmony_ci if (IS_ERR(base)) 2448c2ecf20Sopenharmony_ci return PTR_ERR(base); 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci priv->match = device_get_match_data(&pdev->dev); 2478c2ecf20Sopenharmony_ci if (!priv->match) 2488c2ecf20Sopenharmony_ci return -ENODEV; 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci priv->regmap = devm_regmap_init_mmio(&pdev->dev, base, 2518c2ecf20Sopenharmony_ci &phy_meson8b_usb2_regmap_conf); 2528c2ecf20Sopenharmony_ci if (IS_ERR(priv->regmap)) 2538c2ecf20Sopenharmony_ci return PTR_ERR(priv->regmap); 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ci priv->clk_usb_general = devm_clk_get(&pdev->dev, "usb_general"); 2568c2ecf20Sopenharmony_ci if (IS_ERR(priv->clk_usb_general)) 2578c2ecf20Sopenharmony_ci return PTR_ERR(priv->clk_usb_general); 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci priv->clk_usb = devm_clk_get(&pdev->dev, "usb"); 2608c2ecf20Sopenharmony_ci if (IS_ERR(priv->clk_usb)) 2618c2ecf20Sopenharmony_ci return PTR_ERR(priv->clk_usb); 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci priv->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL); 2648c2ecf20Sopenharmony_ci if (IS_ERR(priv->reset)) 2658c2ecf20Sopenharmony_ci return dev_err_probe(&pdev->dev, PTR_ERR(priv->reset), 2668c2ecf20Sopenharmony_ci "Failed to get the reset line"); 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci priv->dr_mode = of_usb_get_dr_mode_by_phy(pdev->dev.of_node, -1); 2698c2ecf20Sopenharmony_ci if (priv->dr_mode == USB_DR_MODE_UNKNOWN) { 2708c2ecf20Sopenharmony_ci dev_err(&pdev->dev, 2718c2ecf20Sopenharmony_ci "missing dual role configuration of the controller\n"); 2728c2ecf20Sopenharmony_ci return -EINVAL; 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops); 2768c2ecf20Sopenharmony_ci if (IS_ERR(phy)) { 2778c2ecf20Sopenharmony_ci dev_err(&pdev->dev, "failed to create PHY\n"); 2788c2ecf20Sopenharmony_ci return PTR_ERR(phy); 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci phy_set_drvdata(phy, priv); 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci phy_provider = 2848c2ecf20Sopenharmony_ci devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate); 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci return PTR_ERR_OR_ZERO(phy_provider); 2878c2ecf20Sopenharmony_ci} 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_cistatic const struct phy_meson8b_usb2_match_data phy_meson8_usb2_match_data = { 2908c2ecf20Sopenharmony_ci .host_enable_aca = false, 2918c2ecf20Sopenharmony_ci}; 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_cistatic const struct phy_meson8b_usb2_match_data phy_meson8b_usb2_match_data = { 2948c2ecf20Sopenharmony_ci .host_enable_aca = true, 2958c2ecf20Sopenharmony_ci}; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_cistatic const struct of_device_id phy_meson8b_usb2_of_match[] = { 2988c2ecf20Sopenharmony_ci { 2998c2ecf20Sopenharmony_ci .compatible = "amlogic,meson8-usb2-phy", 3008c2ecf20Sopenharmony_ci .data = &phy_meson8_usb2_match_data 3018c2ecf20Sopenharmony_ci }, 3028c2ecf20Sopenharmony_ci { 3038c2ecf20Sopenharmony_ci .compatible = "amlogic,meson8b-usb2-phy", 3048c2ecf20Sopenharmony_ci .data = &phy_meson8b_usb2_match_data 3058c2ecf20Sopenharmony_ci }, 3068c2ecf20Sopenharmony_ci { 3078c2ecf20Sopenharmony_ci .compatible = "amlogic,meson8m2-usb2-phy", 3088c2ecf20Sopenharmony_ci .data = &phy_meson8b_usb2_match_data 3098c2ecf20Sopenharmony_ci }, 3108c2ecf20Sopenharmony_ci { 3118c2ecf20Sopenharmony_ci .compatible = "amlogic,meson-gxbb-usb2-phy", 3128c2ecf20Sopenharmony_ci .data = &phy_meson8b_usb2_match_data 3138c2ecf20Sopenharmony_ci }, 3148c2ecf20Sopenharmony_ci { /* sentinel */ } 3158c2ecf20Sopenharmony_ci}; 3168c2ecf20Sopenharmony_ciMODULE_DEVICE_TABLE(of, phy_meson8b_usb2_of_match); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_cistatic struct platform_driver phy_meson8b_usb2_driver = { 3198c2ecf20Sopenharmony_ci .probe = phy_meson8b_usb2_probe, 3208c2ecf20Sopenharmony_ci .driver = { 3218c2ecf20Sopenharmony_ci .name = "phy-meson-usb2", 3228c2ecf20Sopenharmony_ci .of_match_table = phy_meson8b_usb2_of_match, 3238c2ecf20Sopenharmony_ci }, 3248c2ecf20Sopenharmony_ci}; 3258c2ecf20Sopenharmony_cimodule_platform_driver(phy_meson8b_usb2_driver); 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_ciMODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>"); 3288c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("Meson8, Meson8b, Meson8m2 and GXBB USB2 PHY driver"); 3298c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 330