1313 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * phy-rtk-usb2.c RTK usb2.0 PHY driver4 *5 * Copyright (C) 2023 Realtek Semiconductor Corporation6 *7 */8 9#include <linux/module.h>10#include <linux/of.h>11#include <linux/of_address.h>12#include <linux/platform_device.h>13#include <linux/uaccess.h>14#include <linux/debugfs.h>15#include <linux/nvmem-consumer.h>16#include <linux/regmap.h>17#include <linux/sys_soc.h>18#include <linux/mfd/syscon.h>19#include <linux/phy/phy.h>20#include <linux/usb.h>21 22/* GUSB2PHYACCn register */23#define PHY_NEW_REG_REQ BIT(25)24#define PHY_VSTS_BUSY BIT(23)25#define PHY_VCTRL_SHIFT 826#define PHY_REG_DATA_MASK 0xff27 28#define GET_LOW_NIBBLE(addr) ((addr) & 0x0f)29#define GET_HIGH_NIBBLE(addr) (((addr) & 0xf0) >> 4)30 31#define EFUS_USB_DC_CAL_RATE 232#define EFUS_USB_DC_CAL_MAX 733 34#define EFUS_USB_DC_DIS_RATE 135#define EFUS_USB_DC_DIS_MAX 736 37#define MAX_PHY_DATA_SIZE 2038#define OFFEST_PHY_READ 0x2039 40#define MAX_USB_PHY_NUM 441#define MAX_USB_PHY_PAGE0_DATA_SIZE 1642#define MAX_USB_PHY_PAGE1_DATA_SIZE 1643#define MAX_USB_PHY_PAGE2_DATA_SIZE 844 45#define SET_PAGE_OFFSET 0xf446#define SET_PAGE_0 0x9b47#define SET_PAGE_1 0xbb48#define SET_PAGE_2 0xdb49 50#define PAGE_START 0xe051#define PAGE0_0XE4 0xe452#define PAGE0_0XE6 0xe653#define PAGE0_0XE7 0xe754#define PAGE1_0XE0 0xe055#define PAGE1_0XE2 0xe256 57#define SENSITIVITY_CTRL (BIT(4) | BIT(5) | BIT(6))58#define ENABLE_AUTO_SENSITIVITY_CALIBRATION BIT(2)59#define DEFAULT_DC_DRIVING_VALUE (0x8)60#define DEFAULT_DC_DISCONNECTION_VALUE (0x6)61#define HS_CLK_SELECT BIT(6)62 63struct phy_reg {64 void __iomem *reg_wrap_vstatus;65 void __iomem *reg_gusb2phyacc0;66 int vstatus_index;67};68 69struct phy_data {70 u8 addr;71 u8 data;72};73 74struct phy_cfg {75 int page0_size;76 struct phy_data page0[MAX_USB_PHY_PAGE0_DATA_SIZE];77 int page1_size;78 struct phy_data page1[MAX_USB_PHY_PAGE1_DATA_SIZE];79 int page2_size;80 struct phy_data page2[MAX_USB_PHY_PAGE2_DATA_SIZE];81 82 int num_phy;83 84 bool check_efuse;85 int check_efuse_version;86#define CHECK_EFUSE_V1 187#define CHECK_EFUSE_V2 288 int efuse_dc_driving_rate;89 int efuse_dc_disconnect_rate;90 int dc_driving_mask;91 int dc_disconnect_mask;92 bool usb_dc_disconnect_at_page0;93 int driving_updated_for_dev_dis;94 95 bool do_toggle;96 bool do_toggle_driving;97 bool use_default_parameter;98 bool is_double_sensitivity_mode;99};100 101struct phy_parameter {102 struct phy_reg phy_reg;103 104 /* Get from efuse */105 s8 efuse_usb_dc_cal;106 s8 efuse_usb_dc_dis;107 108 /* Get from dts */109 bool inverse_hstx_sync_clock;110 u32 driving_level;111 s32 driving_level_compensate;112 s32 disconnection_compensate;113};114 115struct rtk_phy {116 struct device *dev;117 118 struct phy_cfg *phy_cfg;119 int num_phy;120 struct phy_parameter *phy_parameter;121 122 struct dentry *debug_dir;123};124 125/* mapping 0xE0 to 0 ... 0xE7 to 7, 0xF0 to 8 ,,, 0xF7 to 15 */126static inline int page_addr_to_array_index(u8 addr)127{128 return (int)((((addr) - PAGE_START) & 0x7) +129 ((((addr) - PAGE_START) & 0x10) >> 1));130}131 132static inline u8 array_index_to_page_addr(int index)133{134 return ((((index) + PAGE_START) & 0x7) +135 ((((index) & 0x8) << 1) + PAGE_START));136}137 138#define PHY_IO_TIMEOUT_USEC (50000)139#define PHY_IO_DELAY_US (100)140 141static inline int utmi_wait_register(void __iomem *reg, u32 mask, u32 result)142{143 int ret;144 unsigned int val;145 146 ret = read_poll_timeout(readl, val, ((val & mask) == result),147 PHY_IO_DELAY_US, PHY_IO_TIMEOUT_USEC, false, reg);148 if (ret) {149 pr_err("%s can't program USB phy\n", __func__);150 return -ETIMEDOUT;151 }152 153 return 0;154}155 156static char rtk_phy_read(struct phy_reg *phy_reg, char addr)157{158 void __iomem *reg_gusb2phyacc0 = phy_reg->reg_gusb2phyacc0;159 unsigned int val;160 int ret = 0;161 162 addr -= OFFEST_PHY_READ;163 164 /* polling until VBusy == 0 */165 ret = utmi_wait_register(reg_gusb2phyacc0, PHY_VSTS_BUSY, 0);166 if (ret)167 return (char)ret;168 169 /* VCtrl = low nibble of addr, and set PHY_NEW_REG_REQ */170 val = PHY_NEW_REG_REQ | (GET_LOW_NIBBLE(addr) << PHY_VCTRL_SHIFT);171 writel(val, reg_gusb2phyacc0);172 ret = utmi_wait_register(reg_gusb2phyacc0, PHY_VSTS_BUSY, 0);173 if (ret)174 return (char)ret;175 176 /* VCtrl = high nibble of addr, and set PHY_NEW_REG_REQ */177 val = PHY_NEW_REG_REQ | (GET_HIGH_NIBBLE(addr) << PHY_VCTRL_SHIFT);178 writel(val, reg_gusb2phyacc0);179 ret = utmi_wait_register(reg_gusb2phyacc0, PHY_VSTS_BUSY, 0);180 if (ret)181 return (char)ret;182 183 val = readl(reg_gusb2phyacc0);184 185 return (char)(val & PHY_REG_DATA_MASK);186}187 188static int rtk_phy_write(struct phy_reg *phy_reg, char addr, char data)189{190 unsigned int val;191 void __iomem *reg_wrap_vstatus = phy_reg->reg_wrap_vstatus;192 void __iomem *reg_gusb2phyacc0 = phy_reg->reg_gusb2phyacc0;193 int shift_bits = phy_reg->vstatus_index * 8;194 int ret = 0;195 196 /* write data to VStatusOut2 (data output to phy) */197 writel((u32)data << shift_bits, reg_wrap_vstatus);198 199 ret = utmi_wait_register(reg_gusb2phyacc0, PHY_VSTS_BUSY, 0);200 if (ret)201 return ret;202 203 /* VCtrl = low nibble of addr, set PHY_NEW_REG_REQ */204 val = PHY_NEW_REG_REQ | (GET_LOW_NIBBLE(addr) << PHY_VCTRL_SHIFT);205 206 writel(val, reg_gusb2phyacc0);207 ret = utmi_wait_register(reg_gusb2phyacc0, PHY_VSTS_BUSY, 0);208 if (ret)209 return ret;210 211 /* VCtrl = high nibble of addr, set PHY_NEW_REG_REQ */212 val = PHY_NEW_REG_REQ | (GET_HIGH_NIBBLE(addr) << PHY_VCTRL_SHIFT);213 214 writel(val, reg_gusb2phyacc0);215 ret = utmi_wait_register(reg_gusb2phyacc0, PHY_VSTS_BUSY, 0);216 if (ret)217 return ret;218 219 return 0;220}221 222static int rtk_phy_set_page(struct phy_reg *phy_reg, int page)223{224 switch (page) {225 case 0:226 return rtk_phy_write(phy_reg, SET_PAGE_OFFSET, SET_PAGE_0);227 case 1:228 return rtk_phy_write(phy_reg, SET_PAGE_OFFSET, SET_PAGE_1);229 case 2:230 return rtk_phy_write(phy_reg, SET_PAGE_OFFSET, SET_PAGE_2);231 default:232 pr_err("%s error page=%d\n", __func__, page);233 }234 235 return -EINVAL;236}237 238static u8 __updated_dc_disconnect_level_page0_0xe4(struct phy_cfg *phy_cfg,239 struct phy_parameter *phy_parameter, u8 data)240{241 u8 ret;242 s32 val;243 s32 dc_disconnect_mask = phy_cfg->dc_disconnect_mask;244 int offset = 4;245 246 val = (s32)((data >> offset) & dc_disconnect_mask)247 + phy_parameter->efuse_usb_dc_dis248 + phy_parameter->disconnection_compensate;249 250 if (val > dc_disconnect_mask)251 val = dc_disconnect_mask;252 else if (val < 0)253 val = 0;254 255 ret = (data & (~(dc_disconnect_mask << offset))) |256 (val & dc_disconnect_mask) << offset;257 258 return ret;259}260 261/* updated disconnect level at page0 */262static void update_dc_disconnect_level_at_page0(struct rtk_phy *rtk_phy,263 struct phy_parameter *phy_parameter, bool update)264{265 struct phy_cfg *phy_cfg;266 struct phy_reg *phy_reg;267 struct phy_data *phy_data_page;268 struct phy_data *phy_data;269 u8 addr, data;270 int offset = 4;271 s32 dc_disconnect_mask;272 int i;273 274 phy_cfg = rtk_phy->phy_cfg;275 phy_reg = &phy_parameter->phy_reg;276 277 /* Set page 0 */278 phy_data_page = phy_cfg->page0;279 rtk_phy_set_page(phy_reg, 0);280 281 i = page_addr_to_array_index(PAGE0_0XE4);282 phy_data = phy_data_page + i;283 if (!phy_data->addr) {284 phy_data->addr = PAGE0_0XE4;285 phy_data->data = rtk_phy_read(phy_reg, PAGE0_0XE4);286 }287 288 addr = phy_data->addr;289 data = phy_data->data;290 dc_disconnect_mask = phy_cfg->dc_disconnect_mask;291 292 if (update)293 data = __updated_dc_disconnect_level_page0_0xe4(phy_cfg, phy_parameter, data);294 else295 data = (data & ~(dc_disconnect_mask << offset)) |296 (DEFAULT_DC_DISCONNECTION_VALUE << offset);297 298 if (rtk_phy_write(phy_reg, addr, data))299 dev_err(rtk_phy->dev,300 "%s: Error to set page1 parameter addr=0x%x value=0x%x\n",301 __func__, addr, data);302}303 304static u8 __updated_dc_disconnect_level_page1_0xe2(struct phy_cfg *phy_cfg,305 struct phy_parameter *phy_parameter, u8 data)306{307 u8 ret;308 s32 val;309 s32 dc_disconnect_mask = phy_cfg->dc_disconnect_mask;310 311 if (phy_cfg->check_efuse_version == CHECK_EFUSE_V1) {312 val = (s32)(data & dc_disconnect_mask)313 + phy_parameter->efuse_usb_dc_dis314 + phy_parameter->disconnection_compensate;315 } else { /* for CHECK_EFUSE_V2 or no efuse */316 if (phy_parameter->efuse_usb_dc_dis)317 val = (s32)(phy_parameter->efuse_usb_dc_dis +318 phy_parameter->disconnection_compensate);319 else320 val = (s32)((data & dc_disconnect_mask) +321 phy_parameter->disconnection_compensate);322 }323 324 if (val > dc_disconnect_mask)325 val = dc_disconnect_mask;326 else if (val < 0)327 val = 0;328 329 ret = (data & (~dc_disconnect_mask)) | (val & dc_disconnect_mask);330 331 return ret;332}333 334/* updated disconnect level at page1 */335static void update_dc_disconnect_level_at_page1(struct rtk_phy *rtk_phy,336 struct phy_parameter *phy_parameter, bool update)337{338 struct phy_cfg *phy_cfg;339 struct phy_data *phy_data_page;340 struct phy_data *phy_data;341 struct phy_reg *phy_reg;342 u8 addr, data;343 s32 dc_disconnect_mask;344 int i;345 346 phy_cfg = rtk_phy->phy_cfg;347 phy_reg = &phy_parameter->phy_reg;348 349 /* Set page 1 */350 phy_data_page = phy_cfg->page1;351 rtk_phy_set_page(phy_reg, 1);352 353 i = page_addr_to_array_index(PAGE1_0XE2);354 phy_data = phy_data_page + i;355 if (!phy_data->addr) {356 phy_data->addr = PAGE1_0XE2;357 phy_data->data = rtk_phy_read(phy_reg, PAGE1_0XE2);358 }359 360 addr = phy_data->addr;361 data = phy_data->data;362 dc_disconnect_mask = phy_cfg->dc_disconnect_mask;363 364 if (update)365 data = __updated_dc_disconnect_level_page1_0xe2(phy_cfg, phy_parameter, data);366 else367 data = (data & ~dc_disconnect_mask) | DEFAULT_DC_DISCONNECTION_VALUE;368 369 if (rtk_phy_write(phy_reg, addr, data))370 dev_err(rtk_phy->dev,371 "%s: Error to set page1 parameter addr=0x%x value=0x%x\n",372 __func__, addr, data);373}374 375static void update_dc_disconnect_level(struct rtk_phy *rtk_phy,376 struct phy_parameter *phy_parameter, bool update)377{378 struct phy_cfg *phy_cfg = rtk_phy->phy_cfg;379 380 if (phy_cfg->usb_dc_disconnect_at_page0)381 update_dc_disconnect_level_at_page0(rtk_phy, phy_parameter, update);382 else383 update_dc_disconnect_level_at_page1(rtk_phy, phy_parameter, update);384}385 386static u8 __update_dc_driving_page0_0xe4(struct phy_cfg *phy_cfg,387 struct phy_parameter *phy_parameter, u8 data)388{389 s32 driving_level_compensate = phy_parameter->driving_level_compensate;390 s32 dc_driving_mask = phy_cfg->dc_driving_mask;391 s32 val;392 u8 ret;393 394 if (phy_cfg->check_efuse_version == CHECK_EFUSE_V1) {395 val = (s32)(data & dc_driving_mask) + driving_level_compensate396 + phy_parameter->efuse_usb_dc_cal;397 } else { /* for CHECK_EFUSE_V2 or no efuse */398 if (phy_parameter->efuse_usb_dc_cal)399 val = (s32)((phy_parameter->efuse_usb_dc_cal & dc_driving_mask)400 + driving_level_compensate);401 else402 val = (s32)(data & dc_driving_mask);403 }404 405 if (val > dc_driving_mask)406 val = dc_driving_mask;407 else if (val < 0)408 val = 0;409 410 ret = (data & (~dc_driving_mask)) | (val & dc_driving_mask);411 412 return ret;413}414 415static void update_dc_driving_level(struct rtk_phy *rtk_phy,416 struct phy_parameter *phy_parameter)417{418 struct phy_cfg *phy_cfg;419 struct phy_reg *phy_reg;420 421 phy_reg = &phy_parameter->phy_reg;422 phy_cfg = rtk_phy->phy_cfg;423 if (!phy_cfg->page0[4].addr) {424 rtk_phy_set_page(phy_reg, 0);425 phy_cfg->page0[4].addr = PAGE0_0XE4;426 phy_cfg->page0[4].data = rtk_phy_read(phy_reg, PAGE0_0XE4);427 }428 429 if (phy_parameter->driving_level != DEFAULT_DC_DRIVING_VALUE) {430 u32 dc_driving_mask;431 u8 driving_level;432 u8 data;433 434 data = phy_cfg->page0[4].data;435 dc_driving_mask = phy_cfg->dc_driving_mask;436 driving_level = data & dc_driving_mask;437 438 dev_dbg(rtk_phy->dev, "%s driving_level=%d => dts driving_level=%d\n",439 __func__, driving_level, phy_parameter->driving_level);440 441 phy_cfg->page0[4].data = (data & (~dc_driving_mask)) |442 (phy_parameter->driving_level & dc_driving_mask);443 }444 445 phy_cfg->page0[4].data = __update_dc_driving_page0_0xe4(phy_cfg,446 phy_parameter,447 phy_cfg->page0[4].data);448}449 450static void update_hs_clk_select(struct rtk_phy *rtk_phy,451 struct phy_parameter *phy_parameter)452{453 struct phy_cfg *phy_cfg;454 struct phy_reg *phy_reg;455 456 phy_cfg = rtk_phy->phy_cfg;457 phy_reg = &phy_parameter->phy_reg;458 459 if (phy_parameter->inverse_hstx_sync_clock) {460 if (!phy_cfg->page0[6].addr) {461 rtk_phy_set_page(phy_reg, 0);462 phy_cfg->page0[6].addr = PAGE0_0XE6;463 phy_cfg->page0[6].data = rtk_phy_read(phy_reg, PAGE0_0XE6);464 }465 466 phy_cfg->page0[6].data = phy_cfg->page0[6].data | HS_CLK_SELECT;467 }468}469 470static void do_rtk_phy_toggle(struct rtk_phy *rtk_phy,471 int index, bool connect)472{473 struct phy_parameter *phy_parameter;474 struct phy_cfg *phy_cfg;475 struct phy_reg *phy_reg;476 struct phy_data *phy_data_page;477 u8 addr, data;478 int i;479 480 phy_cfg = rtk_phy->phy_cfg;481 phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];482 phy_reg = &phy_parameter->phy_reg;483 484 if (!phy_cfg->do_toggle)485 goto out;486 487 if (phy_cfg->is_double_sensitivity_mode)488 goto do_toggle_driving;489 490 /* Set page 0 */491 rtk_phy_set_page(phy_reg, 0);492 493 addr = PAGE0_0XE7;494 data = rtk_phy_read(phy_reg, addr);495 496 if (connect)497 rtk_phy_write(phy_reg, addr, data & (~SENSITIVITY_CTRL));498 else499 rtk_phy_write(phy_reg, addr, data | (SENSITIVITY_CTRL));500 501do_toggle_driving:502 503 if (!phy_cfg->do_toggle_driving)504 goto do_toggle;505 506 /* Page 0 addr 0xE4 driving capability */507 508 /* Set page 0 */509 phy_data_page = phy_cfg->page0;510 rtk_phy_set_page(phy_reg, 0);511 512 i = page_addr_to_array_index(PAGE0_0XE4);513 addr = phy_data_page[i].addr;514 data = phy_data_page[i].data;515 516 if (connect) {517 rtk_phy_write(phy_reg, addr, data);518 } else {519 u8 value;520 s32 tmp;521 s32 driving_updated =522 phy_cfg->driving_updated_for_dev_dis;523 s32 dc_driving_mask = phy_cfg->dc_driving_mask;524 525 tmp = (s32)(data & dc_driving_mask) + driving_updated;526 527 if (tmp > dc_driving_mask)528 tmp = dc_driving_mask;529 else if (tmp < 0)530 tmp = 0;531 532 value = (data & (~dc_driving_mask)) | (tmp & dc_driving_mask);533 534 rtk_phy_write(phy_reg, addr, value);535 }536 537do_toggle:538 /* restore dc disconnect level before toggle */539 update_dc_disconnect_level(rtk_phy, phy_parameter, false);540 541 /* Set page 1 */542 rtk_phy_set_page(phy_reg, 1);543 544 addr = PAGE1_0XE0;545 data = rtk_phy_read(phy_reg, addr);546 547 rtk_phy_write(phy_reg, addr, data &548 (~ENABLE_AUTO_SENSITIVITY_CALIBRATION));549 mdelay(1);550 rtk_phy_write(phy_reg, addr, data |551 (ENABLE_AUTO_SENSITIVITY_CALIBRATION));552 553 /* update dc disconnect level after toggle */554 update_dc_disconnect_level(rtk_phy, phy_parameter, true);555 556out:557 return;558}559 560static int do_rtk_phy_init(struct rtk_phy *rtk_phy, int index)561{562 struct phy_parameter *phy_parameter;563 struct phy_cfg *phy_cfg;564 struct phy_data *phy_data_page;565 struct phy_reg *phy_reg;566 int i;567 568 phy_cfg = rtk_phy->phy_cfg;569 phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];570 phy_reg = &phy_parameter->phy_reg;571 572 if (phy_cfg->use_default_parameter) {573 dev_dbg(rtk_phy->dev, "%s phy#%d use default parameter\n",574 __func__, index);575 goto do_toggle;576 }577 578 /* Set page 0 */579 phy_data_page = phy_cfg->page0;580 rtk_phy_set_page(phy_reg, 0);581 582 for (i = 0; i < phy_cfg->page0_size; i++) {583 struct phy_data *phy_data = phy_data_page + i;584 u8 addr = phy_data->addr;585 u8 data = phy_data->data;586 587 if (!addr)588 continue;589 590 if (rtk_phy_write(phy_reg, addr, data)) {591 dev_err(rtk_phy->dev,592 "%s: Error to set page0 parameter addr=0x%x value=0x%x\n",593 __func__, addr, data);594 return -EINVAL;595 }596 }597 598 /* Set page 1 */599 phy_data_page = phy_cfg->page1;600 rtk_phy_set_page(phy_reg, 1);601 602 for (i = 0; i < phy_cfg->page1_size; i++) {603 struct phy_data *phy_data = phy_data_page + i;604 u8 addr = phy_data->addr;605 u8 data = phy_data->data;606 607 if (!addr)608 continue;609 610 if (rtk_phy_write(phy_reg, addr, data)) {611 dev_err(rtk_phy->dev,612 "%s: Error to set page1 parameter addr=0x%x value=0x%x\n",613 __func__, addr, data);614 return -EINVAL;615 }616 }617 618 if (phy_cfg->page2_size == 0)619 goto do_toggle;620 621 /* Set page 2 */622 phy_data_page = phy_cfg->page2;623 rtk_phy_set_page(phy_reg, 2);624 625 for (i = 0; i < phy_cfg->page2_size; i++) {626 struct phy_data *phy_data = phy_data_page + i;627 u8 addr = phy_data->addr;628 u8 data = phy_data->data;629 630 if (!addr)631 continue;632 633 if (rtk_phy_write(phy_reg, addr, data)) {634 dev_err(rtk_phy->dev,635 "%s: Error to set page2 parameter addr=0x%x value=0x%x\n",636 __func__, addr, data);637 return -EINVAL;638 }639 }640 641do_toggle:642 do_rtk_phy_toggle(rtk_phy, index, false);643 644 return 0;645}646 647static int rtk_phy_init(struct phy *phy)648{649 struct rtk_phy *rtk_phy = phy_get_drvdata(phy);650 unsigned long phy_init_time = jiffies;651 int i, ret = 0;652 653 if (!rtk_phy)654 return -EINVAL;655 656 for (i = 0; i < rtk_phy->num_phy; i++)657 ret = do_rtk_phy_init(rtk_phy, i);658 659 dev_dbg(rtk_phy->dev, "Initialized RTK USB 2.0 PHY (take %dms)\n",660 jiffies_to_msecs(jiffies - phy_init_time));661 return ret;662}663 664static int rtk_phy_exit(struct phy *phy)665{666 return 0;667}668 669static void rtk_phy_toggle(struct rtk_phy *rtk_phy, bool connect, int port)670{671 int index = port;672 673 if (index > rtk_phy->num_phy) {674 dev_err(rtk_phy->dev, "%s: The port=%d is not in usb phy (num_phy=%d)\n",675 __func__, index, rtk_phy->num_phy);676 return;677 }678 679 do_rtk_phy_toggle(rtk_phy, index, connect);680}681 682static int rtk_phy_connect(struct phy *phy, int port)683{684 struct rtk_phy *rtk_phy = phy_get_drvdata(phy);685 686 dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port);687 rtk_phy_toggle(rtk_phy, true, port);688 689 return 0;690}691 692static int rtk_phy_disconnect(struct phy *phy, int port)693{694 struct rtk_phy *rtk_phy = phy_get_drvdata(phy);695 696 dev_dbg(rtk_phy->dev, "%s port=%d\n", __func__, port);697 rtk_phy_toggle(rtk_phy, false, port);698 699 return 0;700}701 702static const struct phy_ops ops = {703 .init = rtk_phy_init,704 .exit = rtk_phy_exit,705 .connect = rtk_phy_connect,706 .disconnect = rtk_phy_disconnect,707 .owner = THIS_MODULE,708};709 710#ifdef CONFIG_DEBUG_FS711static struct dentry *create_phy_debug_root(void)712{713 struct dentry *phy_debug_root;714 715 phy_debug_root = debugfs_lookup("phy", usb_debug_root);716 if (!phy_debug_root)717 phy_debug_root = debugfs_create_dir("phy", usb_debug_root);718 719 return phy_debug_root;720}721 722static int rtk_usb2_parameter_show(struct seq_file *s, void *unused)723{724 struct rtk_phy *rtk_phy = s->private;725 struct phy_cfg *phy_cfg;726 int i, index;727 728 phy_cfg = rtk_phy->phy_cfg;729 730 seq_puts(s, "Property:\n");731 seq_printf(s, " check_efuse: %s\n",732 phy_cfg->check_efuse ? "Enable" : "Disable");733 seq_printf(s, " check_efuse_version: %d\n",734 phy_cfg->check_efuse_version);735 seq_printf(s, " efuse_dc_driving_rate: %d\n",736 phy_cfg->efuse_dc_driving_rate);737 seq_printf(s, " dc_driving_mask: 0x%x\n",738 phy_cfg->dc_driving_mask);739 seq_printf(s, " efuse_dc_disconnect_rate: %d\n",740 phy_cfg->efuse_dc_disconnect_rate);741 seq_printf(s, " dc_disconnect_mask: 0x%x\n",742 phy_cfg->dc_disconnect_mask);743 seq_printf(s, " usb_dc_disconnect_at_page0: %s\n",744 phy_cfg->usb_dc_disconnect_at_page0 ? "true" : "false");745 seq_printf(s, " do_toggle: %s\n",746 phy_cfg->do_toggle ? "Enable" : "Disable");747 seq_printf(s, " do_toggle_driving: %s\n",748 phy_cfg->do_toggle_driving ? "Enable" : "Disable");749 seq_printf(s, " driving_updated_for_dev_dis: 0x%x\n",750 phy_cfg->driving_updated_for_dev_dis);751 seq_printf(s, " use_default_parameter: %s\n",752 phy_cfg->use_default_parameter ? "Enable" : "Disable");753 seq_printf(s, " is_double_sensitivity_mode: %s\n",754 phy_cfg->is_double_sensitivity_mode ? "Enable" : "Disable");755 756 for (index = 0; index < rtk_phy->num_phy; index++) {757 struct phy_parameter *phy_parameter;758 struct phy_reg *phy_reg;759 struct phy_data *phy_data_page;760 761 phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];762 phy_reg = &phy_parameter->phy_reg;763 764 seq_printf(s, "PHY %d:\n", index);765 766 seq_puts(s, "Page 0:\n");767 /* Set page 0 */768 phy_data_page = phy_cfg->page0;769 rtk_phy_set_page(phy_reg, 0);770 771 for (i = 0; i < phy_cfg->page0_size; i++) {772 struct phy_data *phy_data = phy_data_page + i;773 u8 addr = array_index_to_page_addr(i);774 u8 data = phy_data->data;775 u8 value = rtk_phy_read(phy_reg, addr);776 777 if (phy_data->addr)778 seq_printf(s, " Page 0: addr=0x%x data=0x%02x ==> read value=0x%02x\n",779 addr, data, value);780 else781 seq_printf(s, " Page 0: addr=0x%x data=none ==> read value=0x%02x\n",782 addr, value);783 }784 785 seq_puts(s, "Page 1:\n");786 /* Set page 1 */787 phy_data_page = phy_cfg->page1;788 rtk_phy_set_page(phy_reg, 1);789 790 for (i = 0; i < phy_cfg->page1_size; i++) {791 struct phy_data *phy_data = phy_data_page + i;792 u8 addr = array_index_to_page_addr(i);793 u8 data = phy_data->data;794 u8 value = rtk_phy_read(phy_reg, addr);795 796 if (phy_data->addr)797 seq_printf(s, " Page 1: addr=0x%x data=0x%02x ==> read value=0x%02x\n",798 addr, data, value);799 else800 seq_printf(s, " Page 1: addr=0x%x data=none ==> read value=0x%02x\n",801 addr, value);802 }803 804 if (phy_cfg->page2_size == 0)805 goto out;806 807 seq_puts(s, "Page 2:\n");808 /* Set page 2 */809 phy_data_page = phy_cfg->page2;810 rtk_phy_set_page(phy_reg, 2);811 812 for (i = 0; i < phy_cfg->page2_size; i++) {813 struct phy_data *phy_data = phy_data_page + i;814 u8 addr = array_index_to_page_addr(i);815 u8 data = phy_data->data;816 u8 value = rtk_phy_read(phy_reg, addr);817 818 if (phy_data->addr)819 seq_printf(s, " Page 2: addr=0x%x data=0x%02x ==> read value=0x%02x\n",820 addr, data, value);821 else822 seq_printf(s, " Page 2: addr=0x%x data=none ==> read value=0x%02x\n",823 addr, value);824 }825 826out:827 seq_puts(s, "PHY Property:\n");828 seq_printf(s, " efuse_usb_dc_cal: %d\n",829 (int)phy_parameter->efuse_usb_dc_cal);830 seq_printf(s, " efuse_usb_dc_dis: %d\n",831 (int)phy_parameter->efuse_usb_dc_dis);832 seq_printf(s, " inverse_hstx_sync_clock: %s\n",833 phy_parameter->inverse_hstx_sync_clock ? "Enable" : "Disable");834 seq_printf(s, " driving_level: %d\n",835 phy_parameter->driving_level);836 seq_printf(s, " driving_level_compensate: %d\n",837 phy_parameter->driving_level_compensate);838 seq_printf(s, " disconnection_compensate: %d\n",839 phy_parameter->disconnection_compensate);840 }841 842 return 0;843}844DEFINE_SHOW_ATTRIBUTE(rtk_usb2_parameter);845 846static inline void create_debug_files(struct rtk_phy *rtk_phy)847{848 struct dentry *phy_debug_root = NULL;849 850 phy_debug_root = create_phy_debug_root();851 if (!phy_debug_root)852 return;853 854 rtk_phy->debug_dir = debugfs_create_dir(dev_name(rtk_phy->dev),855 phy_debug_root);856 857 debugfs_create_file("parameter", 0444, rtk_phy->debug_dir, rtk_phy,858 &rtk_usb2_parameter_fops);859}860 861static inline void remove_debug_files(struct rtk_phy *rtk_phy)862{863 debugfs_remove_recursive(rtk_phy->debug_dir);864}865#else866static inline void create_debug_files(struct rtk_phy *rtk_phy) { }867static inline void remove_debug_files(struct rtk_phy *rtk_phy) { }868#endif /* CONFIG_DEBUG_FS */869 870static int get_phy_data_by_efuse(struct rtk_phy *rtk_phy,871 struct phy_parameter *phy_parameter, int index)872{873 struct phy_cfg *phy_cfg = rtk_phy->phy_cfg;874 u8 value = 0;875 struct nvmem_cell *cell;876 struct soc_device_attribute rtk_soc_groot[] = {877 { .family = "Realtek Groot",},878 { /* empty */ } };879 880 if (!phy_cfg->check_efuse)881 goto out;882 883 /* Read efuse for usb dc cal */884 cell = nvmem_cell_get(rtk_phy->dev, "usb-dc-cal");885 if (IS_ERR(cell)) {886 dev_dbg(rtk_phy->dev, "%s no usb-dc-cal: %ld\n",887 __func__, PTR_ERR(cell));888 } else {889 unsigned char *buf;890 size_t buf_size;891 892 buf = nvmem_cell_read(cell, &buf_size);893 if (!IS_ERR(buf)) {894 value = buf[0] & phy_cfg->dc_driving_mask;895 kfree(buf);896 }897 nvmem_cell_put(cell);898 }899 900 if (phy_cfg->check_efuse_version == CHECK_EFUSE_V1) {901 int rate = phy_cfg->efuse_dc_driving_rate;902 903 if (value <= EFUS_USB_DC_CAL_MAX)904 phy_parameter->efuse_usb_dc_cal = (int8_t)(value * rate);905 else906 phy_parameter->efuse_usb_dc_cal = -(int8_t)907 ((EFUS_USB_DC_CAL_MAX & value) * rate);908 909 if (soc_device_match(rtk_soc_groot)) {910 dev_dbg(rtk_phy->dev, "For groot IC we need a workaround to adjust efuse_usb_dc_cal\n");911 912 /* We don't multiple dc_cal_rate=2 for positive dc cal compensate */913 if (value <= EFUS_USB_DC_CAL_MAX)914 phy_parameter->efuse_usb_dc_cal = (int8_t)(value);915 916 /* We set max dc cal compensate is 0x8 if otp is 0x7 */917 if (value == 0x7)918 phy_parameter->efuse_usb_dc_cal = (int8_t)(value + 1);919 }920 } else { /* for CHECK_EFUSE_V2 */921 phy_parameter->efuse_usb_dc_cal = value & phy_cfg->dc_driving_mask;922 }923 924 /* Read efuse for usb dc disconnect level */925 value = 0;926 cell = nvmem_cell_get(rtk_phy->dev, "usb-dc-dis");927 if (IS_ERR(cell)) {928 dev_dbg(rtk_phy->dev, "%s no usb-dc-dis: %ld\n",929 __func__, PTR_ERR(cell));930 } else {931 unsigned char *buf;932 size_t buf_size;933 934 buf = nvmem_cell_read(cell, &buf_size);935 if (!IS_ERR(buf)) {936 value = buf[0] & phy_cfg->dc_disconnect_mask;937 kfree(buf);938 }939 nvmem_cell_put(cell);940 }941 942 if (phy_cfg->check_efuse_version == CHECK_EFUSE_V1) {943 int rate = phy_cfg->efuse_dc_disconnect_rate;944 945 if (value <= EFUS_USB_DC_DIS_MAX)946 phy_parameter->efuse_usb_dc_dis = (int8_t)(value * rate);947 else948 phy_parameter->efuse_usb_dc_dis = -(int8_t)949 ((EFUS_USB_DC_DIS_MAX & value) * rate);950 } else { /* for CHECK_EFUSE_V2 */951 phy_parameter->efuse_usb_dc_dis = value & phy_cfg->dc_disconnect_mask;952 }953 954out:955 return 0;956}957 958static int parse_phy_data(struct rtk_phy *rtk_phy)959{960 struct device *dev = rtk_phy->dev;961 struct device_node *np = dev->of_node;962 struct phy_parameter *phy_parameter;963 int ret = 0;964 int index;965 966 rtk_phy->phy_parameter = devm_kzalloc(dev, sizeof(struct phy_parameter) *967 rtk_phy->num_phy, GFP_KERNEL);968 if (!rtk_phy->phy_parameter)969 return -ENOMEM;970 971 for (index = 0; index < rtk_phy->num_phy; index++) {972 phy_parameter = &((struct phy_parameter *)rtk_phy->phy_parameter)[index];973 974 phy_parameter->phy_reg.reg_wrap_vstatus = of_iomap(np, 0);975 phy_parameter->phy_reg.reg_gusb2phyacc0 = of_iomap(np, 1) + index;976 phy_parameter->phy_reg.vstatus_index = index;977 978 if (of_property_read_bool(np, "realtek,inverse-hstx-sync-clock"))979 phy_parameter->inverse_hstx_sync_clock = true;980 else981 phy_parameter->inverse_hstx_sync_clock = false;982 983 if (of_property_read_u32_index(np, "realtek,driving-level",984 index, &phy_parameter->driving_level))985 phy_parameter->driving_level = DEFAULT_DC_DRIVING_VALUE;986 987 if (of_property_read_u32_index(np, "realtek,driving-level-compensate",988 index, &phy_parameter->driving_level_compensate))989 phy_parameter->driving_level_compensate = 0;990 991 if (of_property_read_u32_index(np, "realtek,disconnection-compensate",992 index, &phy_parameter->disconnection_compensate))993 phy_parameter->disconnection_compensate = 0;994 995 get_phy_data_by_efuse(rtk_phy, phy_parameter, index);996 997 update_dc_driving_level(rtk_phy, phy_parameter);998 999 update_hs_clk_select(rtk_phy, phy_parameter);1000 }1001 1002 return ret;1003}1004 1005static int rtk_usb2phy_probe(struct platform_device *pdev)1006{1007 struct rtk_phy *rtk_phy;1008 struct device *dev = &pdev->dev;1009 struct phy *generic_phy;1010 struct phy_provider *phy_provider;1011 const struct phy_cfg *phy_cfg;1012 int ret = 0;1013 1014 phy_cfg = of_device_get_match_data(dev);1015 if (!phy_cfg) {1016 dev_err(dev, "phy config are not assigned!\n");1017 return -EINVAL;1018 }1019 1020 rtk_phy = devm_kzalloc(dev, sizeof(*rtk_phy), GFP_KERNEL);1021 if (!rtk_phy)1022 return -ENOMEM;1023 1024 rtk_phy->dev = &pdev->dev;1025 rtk_phy->phy_cfg = devm_kzalloc(dev, sizeof(*phy_cfg), GFP_KERNEL);1026 1027 memcpy(rtk_phy->phy_cfg, phy_cfg, sizeof(*phy_cfg));1028 1029 rtk_phy->num_phy = phy_cfg->num_phy;1030 1031 ret = parse_phy_data(rtk_phy);1032 if (ret)1033 goto err;1034 1035 platform_set_drvdata(pdev, rtk_phy);1036 1037 generic_phy = devm_phy_create(rtk_phy->dev, NULL, &ops);1038 if (IS_ERR(generic_phy))1039 return PTR_ERR(generic_phy);1040 1041 phy_set_drvdata(generic_phy, rtk_phy);1042 1043 phy_provider = devm_of_phy_provider_register(rtk_phy->dev,1044 of_phy_simple_xlate);1045 if (IS_ERR(phy_provider))1046 return PTR_ERR(phy_provider);1047 1048 create_debug_files(rtk_phy);1049 1050err:1051 return ret;1052}1053 1054static void rtk_usb2phy_remove(struct platform_device *pdev)1055{1056 struct rtk_phy *rtk_phy = platform_get_drvdata(pdev);1057 1058 remove_debug_files(rtk_phy);1059}1060 1061static const struct phy_cfg rtd1295_phy_cfg = {1062 .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE,1063 .page0 = { [0] = {0xe0, 0x90},1064 [3] = {0xe3, 0x3a},1065 [4] = {0xe4, 0x68},1066 [6] = {0xe6, 0x91},1067 [13] = {0xf5, 0x81},1068 [15] = {0xf7, 0x02}, },1069 .page1_size = 8,1070 .page1 = { /* default parameter */ },1071 .page2_size = 0,1072 .page2 = { /* no parameter */ },1073 .num_phy = 1,1074 .check_efuse = false,1075 .check_efuse_version = CHECK_EFUSE_V1,1076 .efuse_dc_driving_rate = 1,1077 .dc_driving_mask = 0xf,1078 .efuse_dc_disconnect_rate = EFUS_USB_DC_DIS_RATE,1079 .dc_disconnect_mask = 0xf,1080 .usb_dc_disconnect_at_page0 = true,1081 .do_toggle = true,1082 .do_toggle_driving = false,1083 .driving_updated_for_dev_dis = 0xf,1084 .use_default_parameter = false,1085 .is_double_sensitivity_mode = false,1086};1087 1088static const struct phy_cfg rtd1395_phy_cfg = {1089 .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE,1090 .page0 = { [4] = {0xe4, 0xac},1091 [13] = {0xf5, 0x00},1092 [15] = {0xf7, 0x02}, },1093 .page1_size = 8,1094 .page1 = { /* default parameter */ },1095 .page2_size = 0,1096 .page2 = { /* no parameter */ },1097 .num_phy = 1,1098 .check_efuse = false,1099 .check_efuse_version = CHECK_EFUSE_V1,1100 .efuse_dc_driving_rate = 1,1101 .dc_driving_mask = 0xf,1102 .efuse_dc_disconnect_rate = EFUS_USB_DC_DIS_RATE,1103 .dc_disconnect_mask = 0xf,1104 .usb_dc_disconnect_at_page0 = true,1105 .do_toggle = true,1106 .do_toggle_driving = false,1107 .driving_updated_for_dev_dis = 0xf,1108 .use_default_parameter = false,1109 .is_double_sensitivity_mode = false,1110};1111 1112static const struct phy_cfg rtd1395_phy_cfg_2port = {1113 .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE,1114 .page0 = { [4] = {0xe4, 0xac},1115 [13] = {0xf5, 0x00},1116 [15] = {0xf7, 0x02}, },1117 .page1_size = 8,1118 .page1 = { /* default parameter */ },1119 .page2_size = 0,1120 .page2 = { /* no parameter */ },1121 .num_phy = 2,1122 .check_efuse = false,1123 .check_efuse_version = CHECK_EFUSE_V1,1124 .efuse_dc_driving_rate = 1,1125 .dc_driving_mask = 0xf,1126 .efuse_dc_disconnect_rate = EFUS_USB_DC_DIS_RATE,1127 .dc_disconnect_mask = 0xf,1128 .usb_dc_disconnect_at_page0 = true,1129 .do_toggle = true,1130 .do_toggle_driving = false,1131 .driving_updated_for_dev_dis = 0xf,1132 .use_default_parameter = false,1133 .is_double_sensitivity_mode = false,1134};1135 1136static const struct phy_cfg rtd1619_phy_cfg = {1137 .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE,1138 .page0 = { [4] = {0xe4, 0x68}, },1139 .page1_size = 8,1140 .page1 = { /* default parameter */ },1141 .page2_size = 0,1142 .page2 = { /* no parameter */ },1143 .num_phy = 1,1144 .check_efuse = true,1145 .check_efuse_version = CHECK_EFUSE_V1,1146 .efuse_dc_driving_rate = 1,1147 .dc_driving_mask = 0xf,1148 .efuse_dc_disconnect_rate = EFUS_USB_DC_DIS_RATE,1149 .dc_disconnect_mask = 0xf,1150 .usb_dc_disconnect_at_page0 = true,1151 .do_toggle = true,1152 .do_toggle_driving = false,1153 .driving_updated_for_dev_dis = 0xf,1154 .use_default_parameter = false,1155 .is_double_sensitivity_mode = false,1156};1157 1158static const struct phy_cfg rtd1319_phy_cfg = {1159 .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE,1160 .page0 = { [0] = {0xe0, 0x18},1161 [4] = {0xe4, 0x6a},1162 [7] = {0xe7, 0x71},1163 [13] = {0xf5, 0x15},1164 [15] = {0xf7, 0x32}, },1165 .page1_size = 8,1166 .page1 = { [3] = {0xe3, 0x44}, },1167 .page2_size = MAX_USB_PHY_PAGE2_DATA_SIZE,1168 .page2 = { [0] = {0xe0, 0x01}, },1169 .num_phy = 1,1170 .check_efuse = true,1171 .check_efuse_version = CHECK_EFUSE_V1,1172 .efuse_dc_driving_rate = 1,1173 .dc_driving_mask = 0xf,1174 .efuse_dc_disconnect_rate = EFUS_USB_DC_DIS_RATE,1175 .dc_disconnect_mask = 0xf,1176 .usb_dc_disconnect_at_page0 = true,1177 .do_toggle = true,1178 .do_toggle_driving = true,1179 .driving_updated_for_dev_dis = 0xf,1180 .use_default_parameter = false,1181 .is_double_sensitivity_mode = true,1182};1183 1184static const struct phy_cfg rtd1312c_phy_cfg = {1185 .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE,1186 .page0 = { [0] = {0xe0, 0x14},1187 [4] = {0xe4, 0x67},1188 [5] = {0xe5, 0x55}, },1189 .page1_size = 8,1190 .page1 = { [3] = {0xe3, 0x23},1191 [6] = {0xe6, 0x58}, },1192 .page2_size = MAX_USB_PHY_PAGE2_DATA_SIZE,1193 .page2 = { /* default parameter */ },1194 .num_phy = 1,1195 .check_efuse = true,1196 .check_efuse_version = CHECK_EFUSE_V1,1197 .efuse_dc_driving_rate = 1,1198 .dc_driving_mask = 0xf,1199 .efuse_dc_disconnect_rate = EFUS_USB_DC_DIS_RATE,1200 .dc_disconnect_mask = 0xf,1201 .usb_dc_disconnect_at_page0 = true,1202 .do_toggle = true,1203 .do_toggle_driving = true,1204 .driving_updated_for_dev_dis = 0xf,1205 .use_default_parameter = false,1206 .is_double_sensitivity_mode = true,1207};1208 1209static const struct phy_cfg rtd1619b_phy_cfg = {1210 .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE,1211 .page0 = { [0] = {0xe0, 0xa3},1212 [4] = {0xe4, 0xa8},1213 [5] = {0xe5, 0x4f},1214 [6] = {0xe6, 0x02}, },1215 .page1_size = 8,1216 .page1 = { [3] = {0xe3, 0x64}, },1217 .page2_size = MAX_USB_PHY_PAGE2_DATA_SIZE,1218 .page2 = { [7] = {0xe7, 0x45}, },1219 .num_phy = 1,1220 .check_efuse = true,1221 .check_efuse_version = CHECK_EFUSE_V1,1222 .efuse_dc_driving_rate = EFUS_USB_DC_CAL_RATE,1223 .dc_driving_mask = 0x1f,1224 .efuse_dc_disconnect_rate = EFUS_USB_DC_DIS_RATE,1225 .dc_disconnect_mask = 0xf,1226 .usb_dc_disconnect_at_page0 = false,1227 .do_toggle = true,1228 .do_toggle_driving = true,1229 .driving_updated_for_dev_dis = 0x8,1230 .use_default_parameter = false,1231 .is_double_sensitivity_mode = true,1232};1233 1234static const struct phy_cfg rtd1319d_phy_cfg = {1235 .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE,1236 .page0 = { [0] = {0xe0, 0xa3},1237 [4] = {0xe4, 0x8e},1238 [5] = {0xe5, 0x4f},1239 [6] = {0xe6, 0x02}, },1240 .page1_size = MAX_USB_PHY_PAGE1_DATA_SIZE,1241 .page1 = { [14] = {0xf5, 0x1}, },1242 .page2_size = MAX_USB_PHY_PAGE2_DATA_SIZE,1243 .page2 = { [7] = {0xe7, 0x44}, },1244 .check_efuse = true,1245 .num_phy = 1,1246 .check_efuse_version = CHECK_EFUSE_V1,1247 .efuse_dc_driving_rate = EFUS_USB_DC_CAL_RATE,1248 .dc_driving_mask = 0x1f,1249 .efuse_dc_disconnect_rate = EFUS_USB_DC_DIS_RATE,1250 .dc_disconnect_mask = 0xf,1251 .usb_dc_disconnect_at_page0 = false,1252 .do_toggle = true,1253 .do_toggle_driving = false,1254 .driving_updated_for_dev_dis = 0x8,1255 .use_default_parameter = false,1256 .is_double_sensitivity_mode = true,1257};1258 1259static const struct phy_cfg rtd1315e_phy_cfg = {1260 .page0_size = MAX_USB_PHY_PAGE0_DATA_SIZE,1261 .page0 = { [0] = {0xe0, 0xa3},1262 [4] = {0xe4, 0x8c},1263 [5] = {0xe5, 0x4f},1264 [6] = {0xe6, 0x02}, },1265 .page1_size = MAX_USB_PHY_PAGE1_DATA_SIZE,1266 .page1 = { [3] = {0xe3, 0x7f},1267 [14] = {0xf5, 0x01}, },1268 .page2_size = MAX_USB_PHY_PAGE2_DATA_SIZE,1269 .page2 = { [7] = {0xe7, 0x44}, },1270 .num_phy = 1,1271 .check_efuse = true,1272 .check_efuse_version = CHECK_EFUSE_V2,1273 .efuse_dc_driving_rate = EFUS_USB_DC_CAL_RATE,1274 .dc_driving_mask = 0x1f,1275 .efuse_dc_disconnect_rate = EFUS_USB_DC_DIS_RATE,1276 .dc_disconnect_mask = 0xf,1277 .usb_dc_disconnect_at_page0 = false,1278 .do_toggle = true,1279 .do_toggle_driving = false,1280 .driving_updated_for_dev_dis = 0x8,1281 .use_default_parameter = false,1282 .is_double_sensitivity_mode = true,1283};1284 1285static const struct of_device_id usbphy_rtk_dt_match[] = {1286 { .compatible = "realtek,rtd1295-usb2phy", .data = &rtd1295_phy_cfg },1287 { .compatible = "realtek,rtd1312c-usb2phy", .data = &rtd1312c_phy_cfg },1288 { .compatible = "realtek,rtd1315e-usb2phy", .data = &rtd1315e_phy_cfg },1289 { .compatible = "realtek,rtd1319-usb2phy", .data = &rtd1319_phy_cfg },1290 { .compatible = "realtek,rtd1319d-usb2phy", .data = &rtd1319d_phy_cfg },1291 { .compatible = "realtek,rtd1395-usb2phy", .data = &rtd1395_phy_cfg },1292 { .compatible = "realtek,rtd1395-usb2phy-2port", .data = &rtd1395_phy_cfg_2port },1293 { .compatible = "realtek,rtd1619-usb2phy", .data = &rtd1619_phy_cfg },1294 { .compatible = "realtek,rtd1619b-usb2phy", .data = &rtd1619b_phy_cfg },1295 {},1296};1297MODULE_DEVICE_TABLE(of, usbphy_rtk_dt_match);1298 1299static struct platform_driver rtk_usb2phy_driver = {1300 .probe = rtk_usb2phy_probe,1301 .remove_new = rtk_usb2phy_remove,1302 .driver = {1303 .name = "rtk-usb2phy",1304 .of_match_table = usbphy_rtk_dt_match,1305 },1306};1307 1308module_platform_driver(rtk_usb2phy_driver);1309 1310MODULE_LICENSE("GPL");1311MODULE_AUTHOR("Stanley Chang <stanley_chang@realtek.com>");1312MODULE_DESCRIPTION("Realtek usb 2.0 phy driver");1313