rtk_phy
struct rtk_phy *rtk_phy;
rtk_phy = devm_kzalloc(dev, sizeof(*rtk_phy), GFP_KERNEL);
if (!rtk_phy)
rtk_phy->dev = &pdev->dev;
rtk_phy->phy_cfg = devm_kzalloc(dev, sizeof(*phy_cfg), GFP_KERNEL);
if (!rtk_phy->phy_cfg)
memcpy(rtk_phy->phy_cfg, phy_cfg, sizeof(*phy_cfg));
rtk_phy->num_phy = phy_cfg->num_phy;
ret = parse_phy_data(rtk_phy);
platform_set_drvdata(pdev, rtk_phy);
generic_phy = devm_phy_create(rtk_phy->dev, NULL, &ops);
phy_set_drvdata(generic_phy, rtk_phy);
phy_provider = devm_of_phy_provider_register(rtk_phy->dev,
create_debug_files(rtk_phy);
struct rtk_phy *rtk_phy = platform_get_drvdata(pdev);
remove_debug_files(rtk_phy);
static void update_dc_disconnect_level_at_page0(struct rtk_phy *rtk_phy,
phy_cfg = rtk_phy->phy_cfg;
dev_err(rtk_phy->dev,
static void update_dc_disconnect_level_at_page1(struct rtk_phy *rtk_phy,
phy_cfg = rtk_phy->phy_cfg;
dev_err(rtk_phy->dev,
static void update_dc_disconnect_level(struct rtk_phy *rtk_phy,
struct phy_cfg *phy_cfg = rtk_phy->phy_cfg;
update_dc_disconnect_level_at_page0(rtk_phy, phy_parameter, update);
update_dc_disconnect_level_at_page1(rtk_phy, phy_parameter, update);
static void update_dc_driving_level(struct rtk_phy *rtk_phy,
phy_cfg = rtk_phy->phy_cfg;
dev_dbg(rtk_phy->dev, "%s driving_level=%d => dts driving_level=%d\n",
static void update_hs_clk_select(struct rtk_phy *rtk_phy,
phy_cfg = rtk_phy->phy_cfg;
static void do_rtk_phy_toggle(struct rtk_phy *rtk_phy,
phy_cfg = rtk_phy->phy_cfg;
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
update_dc_disconnect_level(rtk_phy, phy_parameter, false);
update_dc_disconnect_level(rtk_phy, phy_parameter, true);
static int do_rtk_phy_init(struct rtk_phy *rtk_phy, int index)
phy_cfg = rtk_phy->phy_cfg;
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
dev_dbg(rtk_phy->dev, "%s phy#%d use default parameter\n",
dev_err(rtk_phy->dev,
dev_err(rtk_phy->dev,
dev_err(rtk_phy->dev,
do_rtk_phy_toggle(rtk_phy, index, false);
struct rtk_phy *rtk_phy = phy_get_drvdata(phy);
if (!rtk_phy)
for (i = 0; i < rtk_phy->num_phy; i++)
ret = do_rtk_phy_init(rtk_phy, i);
dev_dbg(rtk_phy->dev, "Initialized RTK USB 2.0 PHY (take %dms)\n",
static void rtk_phy_toggle(struct rtk_phy *rtk_phy, bool connect, int port)
if (index > rtk_phy->num_phy) {
dev_err(rtk_phy->dev, "%s: The port=%d is not in usb phy (num_phy=%d)\n",
__func__, index, rtk_phy->num_phy);
do_rtk_phy_toggle(rtk_phy, index, connect);
struct rtk_phy *rtk_phy = phy_get_drvdata(phy);
dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port);
rtk_phy_toggle(rtk_phy, true, port);
struct rtk_phy *rtk_phy = phy_get_drvdata(phy);
dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port);
rtk_phy_toggle(rtk_phy, false, port);
struct rtk_phy *rtk_phy = s->private;
phy_cfg = rtk_phy->phy_cfg;
for (index = 0; index < rtk_phy->num_phy; index++) {
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
static inline void create_debug_files(struct rtk_phy *rtk_phy)
rtk_phy->debug_dir = debugfs_create_dir(dev_name(rtk_phy->dev),
debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy,
static inline void remove_debug_files(struct rtk_phy *rtk_phy)
debugfs_remove_recursive(rtk_phy->debug_dir);
static inline void create_debug_files(struct rtk_phy *rtk_phy) { }
static inline void remove_debug_files(struct rtk_phy *rtk_phy) { }
static int get_phy_data_by_efuse(struct rtk_phy *rtk_phy,
struct phy_cfg *phy_cfg = rtk_phy->phy_cfg;
cell = nvmem_cell_get(rtk_phy->dev, "usb-dc-cal");
dev_dbg(rtk_phy->dev, "%s no usb-dc-cal: %ld\n",
dev_dbg(rtk_phy->dev, "For groot IC we need a workaround to adjust efuse_usb_dc_cal\n");
cell = nvmem_cell_get(rtk_phy->dev, "usb-dc-dis");
dev_dbg(rtk_phy->dev, "%s no usb-dc-dis: %ld\n",
static int parse_phy_data(struct rtk_phy *rtk_phy)
struct device *dev = rtk_phy->dev;
rtk_phy->phy_parameter = devm_kzalloc(dev, sizeof(struct phy_parameter) *
rtk_phy->num_phy, GFP_KERNEL);
if (!rtk_phy->phy_parameter)
for (index = 0; index < rtk_phy->num_phy; index++) {
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
get_phy_data_by_efuse(rtk_phy, phy_parameter, index);
update_dc_driving_level(rtk_phy, phy_parameter);
update_hs_clk_select(rtk_phy, phy_parameter);
static void do_rtk_usb3_phy_toggle(struct rtk_phy *rtk_phy, int index, bool connect)
struct phy_cfg *phy_cfg = rtk_phy->phy_cfg;
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
static int do_rtk_phy_init(struct rtk_phy *rtk_phy, int index)
phy_cfg = rtk_phy->phy_cfg;
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
do_rtk_usb3_phy_toggle(rtk_phy, index, false);
dev_info(rtk_phy->dev, "toggle fail addr=0x%02x, data=0x%04x\n",
dev_warn(rtk_phy->dev, "Don't update rx_offset_range (rx_offset_code=0x%x, rx_offset_range=0x%x)\n",
struct rtk_phy *rtk_phy = phy_get_drvdata(phy);
for (i = 0; i < rtk_phy->num_phy; i++)
ret = do_rtk_phy_init(rtk_phy, i);
dev_dbg(rtk_phy->dev, "Initialized RTK USB 3.0 PHY (take %dms)\n",
static void rtk_phy_toggle(struct rtk_phy *rtk_phy, bool connect, int port)
if (index > rtk_phy->num_phy) {
dev_err(rtk_phy->dev, "%s: The port=%d is not in usb phy (num_phy=%d)\n",
__func__, index, rtk_phy->num_phy);
do_rtk_usb3_phy_toggle(rtk_phy, index, connect);
struct rtk_phy *rtk_phy = phy_get_drvdata(phy);
dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port);
rtk_phy_toggle(rtk_phy, true, port);
struct rtk_phy *rtk_phy = phy_get_drvdata(phy);
dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port);
rtk_phy_toggle(rtk_phy, false, port);
struct rtk_phy *rtk_phy = s->private;
phy_cfg = rtk_phy->phy_cfg;
for (index = 0; index < rtk_phy->num_phy; index++) {
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
static inline void create_debug_files(struct rtk_phy *rtk_phy)
rtk_phy->debug_dir = debugfs_create_dir(dev_name(rtk_phy->dev), phy_debug_root);
debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy,
static inline void remove_debug_files(struct rtk_phy *rtk_phy)
debugfs_remove_recursive(rtk_phy->debug_dir);
static inline void create_debug_files(struct rtk_phy *rtk_phy) { }
static inline void remove_debug_files(struct rtk_phy *rtk_phy) { }
static int get_phy_data_by_efuse(struct rtk_phy *rtk_phy,
struct phy_cfg *phy_cfg = rtk_phy->phy_cfg;
cell = nvmem_cell_get(rtk_phy->dev, "usb_u3_tx_lfps_swing_trim");
dev_dbg(rtk_phy->dev, "%s no usb_u3_tx_lfps_swing_trim: %ld\n",
static void update_amplitude_control_value(struct rtk_phy *rtk_phy,
phy_cfg = rtk_phy->phy_cfg;
static int parse_phy_data(struct rtk_phy *rtk_phy)
struct device *dev = rtk_phy->dev;
rtk_phy->phy_parameter = devm_kzalloc(dev, sizeof(struct phy_parameter) *
rtk_phy->num_phy, GFP_KERNEL);
if (!rtk_phy->phy_parameter)
for (index = 0; index < rtk_phy->num_phy; index++) {
phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];
get_phy_data_by_efuse(rtk_phy, phy_parameter, index);
update_amplitude_control_value(rtk_phy, phy_parameter);
struct rtk_phy *rtk_phy;
rtk_phy = devm_kzalloc(dev, sizeof(*rtk_phy), GFP_KERNEL);
if (!rtk_phy)
rtk_phy->dev = &pdev->dev;
rtk_phy->phy_cfg = devm_kzalloc(dev, sizeof(*phy_cfg), GFP_KERNEL);
if (!rtk_phy->phy_cfg)
memcpy(rtk_phy->phy_cfg, phy_cfg, sizeof(*phy_cfg));
rtk_phy->num_phy = 1;
ret = parse_phy_data(rtk_phy);
platform_set_drvdata(pdev, rtk_phy);
generic_phy = devm_phy_create(rtk_phy->dev, NULL, &ops);
phy_set_drvdata(generic_phy, rtk_phy);
phy_provider = devm_of_phy_provider_register(rtk_phy->dev, of_phy_simple_xlate);
create_debug_files(rtk_phy);
struct rtk_phy *rtk_phy = platform_get_drvdata(pdev);
remove_debug_files(rtk_phy);