1794 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * * extcon-rtk-type-c.c - Realtek Extcon Type C driver4 *5 * Copyright (C) 2023 Realtek Semiconductor Corporation6 *7 */8 9#include <linux/module.h>10#include <linux/kernel.h>11#include <linux/slab.h>12#include <linux/platform_device.h>13#include <linux/of.h>14#include <linux/of_address.h>15#include <linux/of_irq.h>16#include <linux/io.h>17#include <linux/interrupt.h>18#include <linux/syscalls.h>19#include <linux/suspend.h>20#include <linux/debugfs.h>21#include <linux/extcon.h>22#include <linux/extcon-provider.h>23#include <linux/sys_soc.h>24#include <linux/nvmem-consumer.h>25#include <linux/gpio/consumer.h>26#include <linux/usb/otg.h>27#include <linux/usb/typec.h>28 29struct cc_param {30 u32 rp_4p7k_code;31 u32 rp_36k_code;32 u32 rp_12k_code;33 u32 rd_code;34 u32 ra_code;35 u32 vref_2p6v;36 u32 vref_1p23v;37 u32 vref_0p8v;38 u32 vref_0p66v;39 u32 vref_0p4v;40 u32 vref_0p2v;41 u32 vref_1_1p6v;42 u32 vref_0_1p6v;43};44 45struct type_c_cfg {46 int parameter_ver; /* Parameter version */47 int cc_dfp_mode;48 struct cc_param cc1_param;49 struct cc_param cc2_param;50 51 u32 debounce_val;52 bool use_defalut_parameter;53};54 55struct type_c_data {56 void __iomem *reg_base;57 struct device *dev;58 struct extcon_dev *edev;59 60 u32 irq;61 62 /* rd control GPIO only for rtd1295 */63 struct gpio_desc *rd_ctrl_gpio_desc;64 65 /* Parameters */66 struct type_c_cfg *type_c_cfg;67 u32 dfp_mode_rp_en;68 u32 ufp_mode_rd_en;69 u32 cc1_code;70 u32 cc2_code;71 u32 cc1_vref;72 u32 cc2_vref;73 u32 debounce; /* 1b,1us 7f,4.7us */74 75 /* type_c state */76 int connect_change;77#define CONNECT_CHANGE 178#define CONNECT_NO_CHANGE 079 int cc_mode; /* cc is host or device */80#define IN_HOST_MODE 0x1081#define IN_DEVICE_MODE 0x2082 int is_attach;83#define IN_ATTACH 184#define TO_ATTACH 185#define IN_DETACH 086#define TO_DETACH 087 int at_cc1;88#define AT_CC1 189#define AT_CC2 090 91 u32 int_status;92 u32 cc_status;93 /* protect the data member */94 spinlock_t lock;95 struct delayed_work delayed_work;96 97 bool rd_en_at_first;98 99 struct dentry *debug_dir;100 101 struct typec_port *port;102};103 104/* Type C register offset */105#define USB_TYPEC_CTRL_CC1_0 0x0106#define USB_TYPEC_CTRL_CC1_1 0x4107#define USB_TYPEC_CTRL_CC2_0 0x8108#define USB_TYPEC_CTRL_CC2_1 0xC109#define USB_TYPEC_STS 0x10110#define USB_TYPEC_CTRL 0x14111#define USB_DBUS_PWR_CTRL 0x18112 113#define ENABLE_CC1 0x1114#define ENABLE_CC2 0x2115#define DISABLE_CC 0x0116 117/* Bit mapping USB_TYPEC_CTRL_CC1_0 and USB_TYPEC_CTRL_CC2_0 */118#define PLR_EN BIT(29)119#define CC_SWITCH_MASK (BIT(29) | BIT(28) | BIT(27))120#define CC_CODE_MASK (0xfffff << 7)121#define rp4pk_code(val) ((0x1f & (val)) << 22)122#define code_rp4pk(val) (((val) >> 22) & 0x1f)123#define rp36k_code(val) ((0x1f & (val)) << 17)124#define code_rp36k(val) (((val) >> 17) & 0x1f)125#define rp12k_code(val) ((0x1f & (val)) << 12)126#define code_rp12k(val) (((val) >> 12) & 0x1f)127#define rd_code(val) ((0x1f & (val)) << 7)128#define code_rd(val) (((val) >> 7) & 0x1f)129#define dfp_mode(val) ((0x3 & (val)) << 5)130#define EN_RP4P7K BIT(4)131#define EN_RP36K BIT(3)132#define EN_RP12K BIT(2)133#define EN_RD BIT(1)134#define EN_CC_DET BIT(0)135 136#define CC_MODE_UFP 0x0137#define CC_MODE_DFP_USB 0x1138#define CC_MODE_DFP_1_5 0x2139#define CC_MODE_DFP_3_0 0x3140 141/*142 * PARAMETER_V0:143 * Realtek Kylin rtd1295144 * Realtek Hercules rtd1395145 * Realtek Thor rtd1619146 * Realtek Hank rtd1319147 * Realtek Groot rtd1312c148 * PARAMETER_V1:149 * Realtek Stark rtd1619b150 * Realtek Parker rtd1319d151 * Realtek Danvers rtd1315e152 */153enum parameter_version {154 PARAMETER_V0 = 0,155 PARAMETER_V1 = 1,156};157 158/* Bit mapping USB_TYPEC_CTRL_CC1_1 and USB_TYPEC_CTRL_CC2_1 */159#define V0_vref_2p6v(val) ((0xf & (val)) << 26) /* Bit 29 for groot */160#define V0_vref_1p23v(val) ((0xf & (val)) << 22)161#define V0_vref_0p8v(val) ((0xf & (val)) << 18)162#define V0_vref_0p66v(val) ((0xf & (val)) << 14)163#define V0_vref_0p4v(val) ((0x7 & (val)) << 11)164#define V0_vref_0p2v(val) ((0x7 & (val)) << 8)165#define V0_vref_1_1p6v(val) ((0xf & (val)) << 4)166#define V0_vref_0_1p6v(val) ((0xf & (val)) << 0)167 168#define V0_decode_2p6v(val) (((val) >> 26) & 0xf) /* Bit 29 for groot */169#define V0_decode_1p23v(val) (((val) >> 22) & 0xf)170#define V0_decode_0p8v(val) (((val) >> 18) & 0xf)171#define V0_decode_0p66v(val) (((val) >> 14) & 0xf)172#define V0_decode_0p4v(val) (((val) >> 11) & 0x7)173#define V0_decode_0p2v(val) (((val) >> 8) & 0x7)174#define V0_decode_1_1p6v(val) (((val) >> 4) & 0xf)175#define V0_decode_0_1p6v(val) (((val) >> 0) & 0xf)176 177/* new Bit mapping USB_TYPEC_CTRL_CC1_1 and USB_TYPEC_CTRL_CC2_1 */178#define V1_vref_2p6v(val) ((0xf & (val)) << 28)179#define V1_vref_1p23v(val) ((0xf & (val)) << 24)180#define V1_vref_0p8v(val) ((0xf & (val)) << 20)181#define V1_vref_0p66v(val) ((0xf & (val)) << 16)182#define V1_vref_0p4v(val) ((0xf & (val)) << 12)183#define V1_vref_0p2v(val) ((0xf & (val)) << 8)184#define V1_vref_1_1p6v(val) ((0xf & (val)) << 4)185#define V1_vref_0_1p6v(val) ((0xf & (val)) << 0)186 187#define V1_decode_2p6v(val) (((val) >> 28) & 0xf)188#define V1_decode_1p23v(val) (((val) >> 24) & 0xf)189#define V1_decode_0p8v(val) (((val) >> 20) & 0xf)190#define V1_decode_0p66v(val) (((val) >> 16) & 0xf)191#define V1_decode_0p4v(val) (((val) >> 12) & 0xf)192#define V1_decode_0p2v(val) (((val) >> 8) & 0xf)193#define V1_decode_1_1p6v(val) (((val) >> 4) & 0xf)194#define V1_decode_0_1p6v(val) (((val) >> 0) & 0xf)195 196/* Bit mapping USB_TYPEC_STS */197#define DET_STS 0x7198#define CC1_DET_STS (DET_STS)199#define CC2_DET_STS (DET_STS << 3)200#define DET_STS_RA 0x1201#define DET_STS_RD 0x3202#define DET_STS_RP 0x1203#define CC1_DET_STS_RA (DET_STS_RA)204#define CC1_DET_STS_RD (DET_STS_RD)205#define CC1_DET_STS_RP (DET_STS_RP)206#define CC2_DET_STS_RA (DET_STS_RA << 3)207#define CC2_DET_STS_RD (DET_STS_RD << 3)208#define CC2_DET_STS_RP (DET_STS_RP << 3)209 210/* Bit mapping USB_TYPEC_CTRL */211#define CC2_INT_EN BIT(11)212#define CC1_INT_EN BIT(10)213#define CC2_INT_STS BIT(9)214#define CC1_INT_STS BIT(8)215#define DEBOUNCE_TIME_MASK 0xff216#define DEBOUNCE_EN BIT(0)217#define ENABLE_TYPE_C_DETECT (CC1_INT_EN | CC2_INT_EN)218#define ALL_CC_INT_STS (CC1_INT_STS | CC2_INT_STS)219 220/* Parameter */221#define DETECT_TIME 50 /* ms */222 223static const unsigned int usb_type_c_cable[] = {224 EXTCON_USB,225 EXTCON_USB_HOST,226 EXTCON_NONE,227};228 229enum usb_data_roles {230 DR_NONE,231 DR_HOST,232 DR_DEVICE,233};234 235static const struct soc_device_attribute rtk_soc_kylin[] = {236 { .family = "Realtek Kylin", },237 { /* empty */ }238};239 240static int rtd129x_switch_type_c_plug_config(struct type_c_data *type_c,241 int dr_mode, int cc)242{243 void __iomem *reg = type_c->reg_base + USB_TYPEC_CTRL_CC1_0;244 int val_cc;245 246#define TYPE_C_EN_SWITCH BIT(29)247#define TYPE_C_TXRX_SEL (BIT(28) | BIT(27))248#define TYPE_C_SWITCH_MASK (TYPE_C_EN_SWITCH | TYPE_C_TXRX_SEL)249#define TYPE_C_ENABLE_CC1 TYPE_C_EN_SWITCH250#define TYPE_C_ENABLE_CC2 (TYPE_C_EN_SWITCH | TYPE_C_TXRX_SEL)251#define TYPE_C_DISABLE_CC ~TYPE_C_SWITCH_MASK252 253 val_cc = readl(reg);254 val_cc &= ~TYPE_C_SWITCH_MASK;255 256 if (cc == DISABLE_CC) {257 val_cc &= TYPE_C_DISABLE_CC;258 } else if (cc == ENABLE_CC1) {259 val_cc |= TYPE_C_ENABLE_CC1;260 } else if (cc == ENABLE_CC2) {261 val_cc |= TYPE_C_ENABLE_CC2;262 } else {263 dev_err(type_c->dev, "%s: Error cc setting cc=0x%x\n", __func__, cc);264 return -EINVAL;265 }266 writel(val_cc, reg);267 268 /* waiting cc stable for enable/disable */269 mdelay(1);270 271 dev_dbg(type_c->dev, "%s: cc=0x%x val_cc=0x%x usb_typec_ctrl_cc1_0=0x%x\n",272 __func__, cc, val_cc, readl(reg));273 274 return 0;275}276 277static inline void switch_type_c_plug_config(struct type_c_data *type_c,278 int dr_mode, int cc)279{280 int ret = 0;281 282 if (soc_device_match(rtk_soc_kylin))283 ret = rtd129x_switch_type_c_plug_config(type_c, dr_mode, cc);284 285 if (ret < 0)286 dev_err(type_c->dev, "%s: Error set type c plug config\n",287 __func__);288}289 290static void switch_type_c_dr_mode(struct type_c_data *type_c, int dr_mode, int cc)291{292 bool is_host = false;293 bool is_device = false;294 bool polarity = false;295 bool vbus = false;296 bool ss = true;297 298 switch_type_c_plug_config(type_c, dr_mode, cc);299 if (cc == ENABLE_CC2)300 polarity = true;301 302 switch (dr_mode) {303 case USB_DR_MODE_HOST:304 is_host = true;305 break;306 case USB_DR_MODE_PERIPHERAL:307 is_device = true;308 vbus = true;309 break;310 default:311 dev_dbg(type_c->dev, "%s dr_mode=%d ==> no host or device\n",312 __func__, dr_mode);313 break;314 }315 316 dev_dbg(type_c->dev, "%s is_host=%d is_device=%d vbus=%d polarity=%d\n",317 __func__, is_host, is_device, vbus, polarity);318 319 /* for EXTCON_USB device mode */320 extcon_set_state(type_c->edev, EXTCON_USB, is_device);321 extcon_set_property(type_c->edev, EXTCON_USB,322 EXTCON_PROP_USB_VBUS,323 (union extcon_property_value)(int)vbus);324 extcon_set_property(type_c->edev, EXTCON_USB,325 EXTCON_PROP_USB_TYPEC_POLARITY,326 (union extcon_property_value)(int)polarity);327 extcon_set_property(type_c->edev, EXTCON_USB,328 EXTCON_PROP_USB_SS,329 (union extcon_property_value)(int)ss);330 331 /* for EXTCON_USB_HOST host mode */332 extcon_set_state(type_c->edev, EXTCON_USB_HOST, is_host);333 extcon_set_property(type_c->edev, EXTCON_USB_HOST,334 EXTCON_PROP_USB_VBUS,335 (union extcon_property_value)(int)vbus);336 extcon_set_property(type_c->edev, EXTCON_USB_HOST,337 EXTCON_PROP_USB_TYPEC_POLARITY,338 (union extcon_property_value)(int)polarity);339 extcon_set_property(type_c->edev, EXTCON_USB_HOST,340 EXTCON_PROP_USB_SS,341 (union extcon_property_value)(int)ss);342 343 /* sync EXTCON_USB and EXTCON_USB_HOST */344 extcon_sync(type_c->edev, EXTCON_USB);345 extcon_sync(type_c->edev, EXTCON_USB_HOST);346 347 if (type_c->port) {348 switch (dr_mode) {349 case USB_DR_MODE_HOST:350 typec_set_data_role(type_c->port, TYPEC_HOST);351 typec_set_pwr_role(type_c->port, TYPEC_SOURCE);352 break;353 case USB_DR_MODE_PERIPHERAL:354 typec_set_data_role(type_c->port, TYPEC_DEVICE);355 typec_set_pwr_role(type_c->port, TYPEC_SINK);356 break;357 default:358 dev_dbg(type_c->dev, "%s unknown dr_mode=%d\n",359 __func__, dr_mode);360 break;361 }362 }363}364 365/* connector attached/detached */366static int connector_attached(struct type_c_data *type_c, u32 cc, int dr_mode)367{368 void __iomem *reg = type_c->reg_base + USB_TYPEC_CTRL;369 370 cancel_delayed_work(&type_c->delayed_work);371 372 switch_type_c_dr_mode(type_c, dr_mode, cc);373 374 writel(ENABLE_TYPE_C_DETECT | readl(reg), reg);375 376 return 0;377}378 379static int connector_detached(struct type_c_data *type_c, u32 cc, int dr_mode)380{381 void __iomem *reg = type_c->reg_base + USB_TYPEC_CTRL;382 383 writel(~ENABLE_TYPE_C_DETECT & readl(reg), reg);384 385 switch_type_c_dr_mode(type_c, 0, cc);386 387 schedule_delayed_work(&type_c->delayed_work, msecs_to_jiffies(DETECT_TIME));388 389 return 0;390}391 392/* detect host device switch */393static int __detect_host_device(struct type_c_data *type_c, u32 rp_or_rd_en)394{395 struct device *dev = type_c->dev;396 void __iomem *reg_base = type_c->reg_base;397 u32 cc1_config, cc2_config, default_ctrl;398 u32 cc1_switch = 0;399 400 default_ctrl = readl(reg_base + USB_TYPEC_CTRL) & DEBOUNCE_TIME_MASK;401 writel(default_ctrl, reg_base + USB_TYPEC_CTRL);402 403 cc1_config = readl(reg_base + USB_TYPEC_CTRL_CC1_0);404 cc2_config = readl(reg_base + USB_TYPEC_CTRL_CC2_0);405 406 cc1_config &= ~EN_CC_DET;407 cc2_config &= ~EN_CC_DET;408 writel(cc1_config, reg_base + USB_TYPEC_CTRL_CC1_0);409 writel(cc2_config, reg_base + USB_TYPEC_CTRL_CC2_0);410 411 if (soc_device_match(rtk_soc_kylin))412 cc1_switch = cc1_config & CC_SWITCH_MASK;413 414 cc1_config &= CC_CODE_MASK;415 cc1_config |= rp_or_rd_en | cc1_switch;416 cc2_config &= CC_CODE_MASK;417 cc2_config |= rp_or_rd_en;418 writel(cc2_config, reg_base + USB_TYPEC_CTRL_CC2_0);419 writel(cc1_config, reg_base + USB_TYPEC_CTRL_CC1_0);420 421 /* For kylin to disable external rd control gpio */422 if (soc_device_match(rtk_soc_kylin)) {423 struct gpio_desc *gpio = type_c->rd_ctrl_gpio_desc;424 425 if (gpio && gpiod_direction_output(gpio, 1))426 dev_err(dev, "%s ERROR set rd_ctrl_gpio_desc fail\n", __func__);427 }428 429 cc1_config |= EN_CC_DET;430 cc2_config |= EN_CC_DET;431 writel(cc1_config, reg_base + USB_TYPEC_CTRL_CC1_0);432 writel(cc2_config, reg_base + USB_TYPEC_CTRL_CC2_0);433 434 return 0;435}436 437static int detect_device(struct type_c_data *type_c)438{439 return __detect_host_device(type_c, type_c->dfp_mode_rp_en);440}441 442static int detect_host(struct type_c_data *type_c)443{444 return __detect_host_device(type_c, type_c->ufp_mode_rd_en);445}446 447static int host_device_switch_detection(struct type_c_data *type_c)448{449 if (type_c->cc_mode == IN_HOST_MODE) {450 type_c->cc_mode = IN_DEVICE_MODE;451 detect_host(type_c);452 } else {453 type_c->cc_mode = IN_HOST_MODE;454 detect_device(type_c);455 }456 457 return 0;458}459 460static int detect_type_c_state(struct type_c_data *type_c)461{462 struct device *dev = type_c->dev;463 void __iomem *reg_base = type_c->reg_base;464 u32 int_status, cc_status, cc_status_check;465 unsigned long flags;466 467 spin_lock_irqsave(&type_c->lock, flags);468 469 int_status = readl(reg_base + USB_TYPEC_CTRL);470 cc_status = readl(reg_base + USB_TYPEC_STS);471 472 type_c->connect_change = CONNECT_NO_CHANGE;473 474 switch (type_c->cc_mode | type_c->is_attach) {475 case IN_HOST_MODE | IN_ATTACH:476 if (((cc_status & CC1_DET_STS) == CC1_DET_STS) && type_c->at_cc1 == AT_CC1) {477 dev_dbg(dev, "IN host mode and cc1 device detach (cc_status=0x%x)",478 cc_status);479 type_c->is_attach = TO_DETACH;480 type_c->connect_change = CONNECT_CHANGE;481 } else if (((cc_status & CC2_DET_STS) == CC2_DET_STS) &&482 type_c->at_cc1 == AT_CC2) {483 dev_dbg(dev, "IN host mode and cc2 device detach (cc_status=0x%x)",484 cc_status);485 type_c->is_attach = TO_DETACH;486 type_c->connect_change = CONNECT_CHANGE;487 }488 break;489 case IN_HOST_MODE | IN_DETACH:490 cc_status_check = readl(reg_base + USB_TYPEC_STS);491 if (cc_status_check != (CC1_DET_STS | CC2_DET_STS)) {492 if (in_interrupt()) {493 /* Add delay time to avoid capacitive effect of cable. */494 mdelay(300);495 } else {496 spin_unlock_irqrestore(&type_c->lock, flags);497 /* Add delay time to avoid capacitive effect of cable. */498 msleep(300);499 spin_lock_irqsave(&type_c->lock, flags);500 }501 cc_status_check = readl(reg_base + USB_TYPEC_STS);502 }503 if (cc_status != cc_status_check) {504 dev_warn(dev, "IN_HOST_MODE: cc_status (0x%x) != cc_status_check (0x%x)\n",505 cc_status, cc_status_check);506 cc_status = readl(reg_base + USB_TYPEC_STS);507 }508 509 if ((cc_status & CC1_DET_STS) == CC1_DET_STS_RD) {510 dev_dbg(dev, "IN host mode and cc1 device attach (cc_status=0x%x)",511 cc_status);512 type_c->is_attach = TO_ATTACH;513 type_c->at_cc1 = AT_CC1;514 type_c->connect_change = CONNECT_CHANGE;515 } else if ((cc_status & CC2_DET_STS) == CC2_DET_STS_RD) {516 dev_dbg(dev, "In host mode and cc2 device attach (cc_status=0x%x)",517 cc_status);518 type_c->is_attach = TO_ATTACH;519 type_c->at_cc1 = AT_CC2;520 type_c->connect_change = CONNECT_CHANGE;521 }522 break;523 case IN_DEVICE_MODE | IN_ATTACH:524 if ((cc_status & CC1_DET_STS) < CC1_DET_STS_RP ||525 (cc_status & CC2_DET_STS) < CC2_DET_STS_RP) {526 /* Add a sw debounce to filter cc signal sent from apple pd adapter */527 mdelay(5);528 cc_status_check = readl(reg_base + USB_TYPEC_STS);529 530 if (cc_status != cc_status_check) {531 dev_dbg(dev, "IN_DEVICE_MODE: cc_status (0x%x) != cc_status_check (0x%x) maybe use a pd adapter\n",532 cc_status, cc_status_check);533 cc_status = cc_status_check;534 }535 }536 537 if ((cc_status & CC1_DET_STS) < CC1_DET_STS_RP && type_c->at_cc1 == AT_CC1) {538 dev_dbg(dev, "IN device mode and cc1 host disconnect (cc_status=0x%x)",539 cc_status);540 type_c->is_attach = TO_DETACH;541 type_c->connect_change = CONNECT_CHANGE;542 } else if ((cc_status & CC2_DET_STS) < CC2_DET_STS_RP &&543 type_c->at_cc1 == AT_CC2) {544 dev_dbg(dev, "IN device mode and cc2 host disconnect (cc_status=0x%x)",545 cc_status);546 type_c->is_attach = TO_DETACH;547 type_c->connect_change = CONNECT_CHANGE;548 }549 break;550 case IN_DEVICE_MODE | IN_DETACH:551 cc_status_check = readl(reg_base + USB_TYPEC_STS);552 if (cc_status_check != 0x0) {553 if (in_interrupt()) {554 /* Add delay time to avoid capacitive effect of cable. */555 mdelay(300);556 } else {557 spin_unlock_irqrestore(&type_c->lock, flags);558 /* Add delay time to avoid capacitive effect of cable. */559 msleep(300);560 spin_lock_irqsave(&type_c->lock, flags);561 }562 cc_status_check = readl(reg_base + USB_TYPEC_STS);563 }564 565 if (cc_status != cc_status_check) {566 dev_warn(dev, "IN_DEVICE_MODE: cc_status (0x%x) != cc_status_check (0x%x)\n",567 cc_status, cc_status_check);568 cc_status = readl(reg_base + USB_TYPEC_STS);569 }570 571 if ((cc_status & CC1_DET_STS) >= CC1_DET_STS_RP) {572 dev_dbg(dev, "IN device mode and cc1 host connect (cc_status=0x%x)",573 cc_status);574 type_c->at_cc1 = AT_CC1;575 type_c->is_attach = TO_ATTACH;576 type_c->connect_change = CONNECT_CHANGE;577 } else if ((cc_status & CC2_DET_STS) >= CC2_DET_STS_RP) {578 dev_dbg(dev, "IN device mode and cc2 host connect (cc_status=0x%x)",579 cc_status);580 type_c->at_cc1 = AT_CC2;581 type_c->is_attach = TO_ATTACH;582 type_c->connect_change = CONNECT_CHANGE;583 }584 break;585 default:586 dev_err(dev, "error host or device mode (cc_mode=%d, is_attach=%d) ",587 type_c->cc_mode, type_c->is_attach);588 }589 590 type_c->int_status = int_status;591 type_c->cc_status = cc_status;592 593 spin_unlock_irqrestore(&type_c->lock, flags);594 return 0;595}596 597static void host_device_switch(struct work_struct *work)598{599 struct type_c_data *type_c = container_of(work, struct type_c_data,600 delayed_work.work);601 struct device *dev = type_c->dev;602 unsigned long flags;603 int connect_change = 0;604 int cc_mode = 0;605 int is_attach = 0;606 int at_cc1 = 0;607 608 spin_lock_irqsave(&type_c->lock, flags);609 if (type_c->connect_change)610 connect_change = type_c->connect_change;611 spin_unlock_irqrestore(&type_c->lock, flags);612 613 if (!connect_change)614 detect_type_c_state(type_c);615 616 spin_lock_irqsave(&type_c->lock, flags);617 if (type_c->connect_change) {618 connect_change = type_c->connect_change;619 cc_mode = type_c->cc_mode;620 is_attach = type_c->is_attach;621 at_cc1 = type_c->at_cc1;622 type_c->connect_change = CONNECT_NO_CHANGE;623 } else {624 host_device_switch_detection(type_c);625 626 schedule_delayed_work(&type_c->delayed_work, msecs_to_jiffies(DETECT_TIME));627 }628 spin_unlock_irqrestore(&type_c->lock, flags);629 630 if (!connect_change)631 return;632 633 dev_dbg(dev, "%s: usb cable connection change\n", __func__);634 if (cc_mode == IN_HOST_MODE) {635 if (is_attach && at_cc1)636 connector_attached(type_c, ENABLE_CC1, USB_DR_MODE_HOST);637 else if (is_attach && !at_cc1)638 connector_attached(type_c, ENABLE_CC2, USB_DR_MODE_HOST);639 else640 connector_detached(type_c, DISABLE_CC, USB_DR_MODE_HOST);641 } else if (cc_mode == IN_DEVICE_MODE) {642 if (is_attach && at_cc1)643 connector_attached(type_c, ENABLE_CC1, USB_DR_MODE_PERIPHERAL);644 else if (is_attach && !at_cc1)645 connector_attached(type_c, ENABLE_CC2, USB_DR_MODE_PERIPHERAL);646 else647 connector_detached(type_c, DISABLE_CC, USB_DR_MODE_PERIPHERAL);648 } else {649 dev_err(dev, "Error: IN unknown mode %d to %s at %s (cc_status=0x%x)\n",650 cc_mode, is_attach ? "attach" : "detach",651 at_cc1 ? "cc1" : "cc2", type_c->cc_status);652 }653 dev_info(dev, "Connection change OK: IN %s mode to %s at %s (cc_status=0x%x)\n",654 cc_mode == IN_HOST_MODE ? "host" : "device",655 is_attach ? "attach" : "detach",656 at_cc1 ? "cc1" : "cc2", type_c->cc_status);657}658 659static irqreturn_t type_c_detect_irq(int irq, void *__data)660{661 struct type_c_data *type_c = (struct type_c_data *)__data;662 struct device *dev = type_c->dev;663 void __iomem *reg = type_c->reg_base + USB_TYPEC_CTRL;664 unsigned long flags;665 666 detect_type_c_state(type_c);667 668 spin_lock_irqsave(&type_c->lock, flags);669 670 if (type_c->connect_change) {671 dev_dbg(dev, "%s: IN %s mode to %s (at %s interrupt) int_status=0x%x, cc_status=0x%x",672 __func__,673 type_c->cc_mode == IN_HOST_MODE ? "host" : "device",674 type_c->is_attach ? "attach" : "detach",675 type_c->at_cc1 ? "cc1" : "cc2",676 type_c->int_status, type_c->cc_status);677 678 /* clear interrupt status */679 writel(~ALL_CC_INT_STS & readl(reg), reg);680 681 cancel_delayed_work(&type_c->delayed_work);682 schedule_delayed_work(&type_c->delayed_work, msecs_to_jiffies(0));683 } else {684 static int local_count;685 686 /* if no connect_change, we keep the status to avoid status lose */687 if (local_count++ > 10) {688 /* clear interrupt status */689 writel(~ALL_CC_INT_STS & readl(reg), reg);690 local_count = 0;691 }692 }693 694 spin_unlock_irqrestore(&type_c->lock, flags);695 696 return IRQ_HANDLED;697}698 699static int type_c_port_dr_set(struct typec_port *port,700 enum typec_data_role role)701{702 struct type_c_data *type_c = typec_get_drvdata(port);703 u32 enable_cc;704 unsigned long flags;705 706 spin_lock_irqsave(&type_c->lock, flags);707 enable_cc = type_c->at_cc1 ? ENABLE_CC1 : ENABLE_CC2;708 spin_unlock_irqrestore(&type_c->lock, flags);709 710 if (role == TYPEC_HOST)711 switch_type_c_dr_mode(type_c, USB_DR_MODE_HOST, enable_cc);712 else if (role == TYPEC_DEVICE)713 switch_type_c_dr_mode(type_c, USB_DR_MODE_PERIPHERAL, enable_cc);714 else715 switch_type_c_dr_mode(type_c, 0, DISABLE_CC);716 717 return 0;718}719 720static const struct typec_operations type_c_port_ops = {721 .dr_set = type_c_port_dr_set,722};723 724#ifdef CONFIG_DEBUG_FS725static int type_c_parameter_show(struct seq_file *s, void *unused)726{727 struct type_c_data *type_c = s->private;728 struct type_c_cfg *type_c_cfg = type_c->type_c_cfg;729 struct cc_param *cc_param;730 unsigned long flags;731 732 spin_lock_irqsave(&type_c->lock, flags);733 734 seq_printf(s, "cc_dfp_mode %s\n",735 ({ char *tmp;736 switch (type_c_cfg->cc_dfp_mode) {737 case CC_MODE_DFP_USB:738 tmp = "CC_MODE_DFP_USB"; break;739 case CC_MODE_DFP_1_5:740 tmp = "CC_MODE_DFP_1_5"; break;741 case CC_MODE_DFP_3_0:742 tmp = "CC_MODE_DFP_3_0"; break;743 default:744 tmp = "?"; break;745 } tmp; }));746 747 seq_printf(s, "dfp_mode_rp_en 0x%x\n", type_c->dfp_mode_rp_en);748 seq_printf(s, "ufp_mode_rd_en 0x%x\n", type_c->ufp_mode_rd_en);749 seq_printf(s, "cc1_code 0x%x\n", type_c->cc1_code);750 seq_printf(s, "cc2_code 0x%x\n", type_c->cc2_code);751 seq_printf(s, "cc1_vref 0x%x\n", type_c->cc1_vref);752 seq_printf(s, "cc2_vref 0x%x\n", type_c->cc2_vref);753 seq_printf(s, "debounce 0x%x\n", type_c->debounce);754 seq_puts(s, "\n");755 756 cc_param = &type_c_cfg->cc1_param;757 seq_puts(s, "cc1_param:\n");758 seq_printf(s, " rp_4p7k_code 0x%x\n", cc_param->rp_4p7k_code);759 seq_printf(s, " rp_36k_code 0x%x\n", cc_param->rp_36k_code);760 seq_printf(s, " rp_12k_code 0x%x\n", cc_param->rp_12k_code);761 seq_printf(s, " rd_code 0x%x\n", cc_param->rd_code);762 seq_printf(s, " vref_2p6v 0x%x\n", cc_param->vref_2p6v);763 seq_printf(s, " vref_1p23v 0x%x\n", cc_param->vref_1p23v);764 seq_printf(s, " vref_0p8v 0x%x\n", cc_param->vref_0p8v);765 seq_printf(s, " vref_0p66v 0x%x\n", cc_param->vref_0p66v);766 seq_printf(s, " vref_0p4v 0x%x\n", cc_param->vref_0p4v);767 seq_printf(s, " vref_0p2v 0x%x\n", cc_param->vref_0p2v);768 seq_printf(s, " vref_1_1p6v 0x%x\n", cc_param->vref_1_1p6v);769 seq_printf(s, " vref_0_1p6v 0x%x\n", cc_param->vref_0_1p6v);770 771 cc_param = &type_c_cfg->cc2_param;772 seq_puts(s, "cc2_param:\n");773 seq_printf(s, " rp_4p7k_code 0x%x\n", cc_param->rp_4p7k_code);774 seq_printf(s, " rp_36k_code 0x%x\n", cc_param->rp_36k_code);775 seq_printf(s, " rp_12k_code 0x%x\n", cc_param->rp_12k_code);776 seq_printf(s, " rd_code 0x%x\n", cc_param->rd_code);777 seq_printf(s, " vref_2p6v 0x%x\n", cc_param->vref_2p6v);778 seq_printf(s, " vref_1p23v 0x%x\n", cc_param->vref_1p23v);779 seq_printf(s, " vref_0p8v 0x%x\n", cc_param->vref_0p8v);780 seq_printf(s, " vref_0p66v 0x%x\n", cc_param->vref_0p66v);781 seq_printf(s, " vref_0p4v 0x%x\n", cc_param->vref_0p4v);782 seq_printf(s, " vref_0p2v 0x%x\n", cc_param->vref_0p2v);783 seq_printf(s, " vref_1_1p6v 0x%x\n", cc_param->vref_1_1p6v);784 seq_printf(s, " vref_0_1p6v 0x%x\n", cc_param->vref_0_1p6v);785 786 spin_unlock_irqrestore(&type_c->lock, flags);787 788 return 0;789}790 791static int type_c_parameter_open(struct inode *inode, struct file *file)792{793 return single_open(file, type_c_parameter_show, inode->i_private);794}795 796static const struct file_operations type_c_parameter_fops = {797 .open = type_c_parameter_open,798 .read = seq_read,799 .llseek = seq_lseek,800 .release = single_release,801};802 803static int type_c_status_show(struct seq_file *s, void *unused)804{805 struct type_c_data *type_c = s->private;806 unsigned long flags;807 808 spin_lock_irqsave(&type_c->lock, flags);809 810 seq_printf(s, "In %s mode %s at %s (cc_status=0x%x)\n",811 type_c->cc_mode == IN_HOST_MODE ? "host" : "device",812 type_c->is_attach ? "attach" : "detach",813 type_c->at_cc1 ? "cc1" : "cc2", type_c->cc_status);814 815 seq_printf(s, "Read Register (type_c_ctrl_cc1_0=0x%x)\n",816 readl(type_c->reg_base + 0x0));817 seq_printf(s, "Read Register (type_c_ctrl_cc1_1=0x%x)\n",818 readl(type_c->reg_base + 0x4));819 seq_printf(s, "Read Register (type_c_ctrl_cc2_0=0x%x)\n",820 readl(type_c->reg_base + 0x8));821 seq_printf(s, "Read Register (type_c_ctrl_cc2_1=0x%x)\n",822 readl(type_c->reg_base + 0xc));823 seq_printf(s, "Read Register (type_c_status=0x%x)\n",824 readl(type_c->reg_base + 0x10));825 seq_printf(s, "Read Register (type_c_ctrl=0x%x)\n",826 readl(type_c->reg_base + 0x14));827 828 spin_unlock_irqrestore(&type_c->lock, flags);829 830 return 0;831}832 833static int type_c_status_open(struct inode *inode, struct file *file)834{835 return single_open(file, type_c_status_show, inode->i_private);836}837 838static const struct file_operations type_c_status_fops = {839 .open = type_c_status_open,840 .read = seq_read,841 .llseek = seq_lseek,842 .release = single_release,843};844 845static inline void create_debug_files(struct type_c_data *type_c)846{847 type_c->debug_dir = debugfs_create_dir("type_c", usb_debug_root);848 849 debugfs_create_file("parameter", 0444, type_c->debug_dir, type_c,850 &type_c_parameter_fops);851 852 debugfs_create_file("status", 0444, type_c->debug_dir, type_c,853 &type_c_status_fops);854}855 856static inline void remove_debug_files(struct type_c_data *type_c)857{858 debugfs_remove_recursive(type_c->debug_dir);859}860#else861static inline void create_debug_files(struct type_c_data *type_c) { }862static inline void remove_debug_files(struct type_c_data *type_c) { }863#endif /* CONFIG_DEBUG_FS */864 865/* Init and probe */866 867static inline s8 get_value(s8 value)868{869 return (((s8)value & 0x8) ? (-(s8)(0x7 & value)) : ((s8)(value)));870}871 872static int __updated_type_c_parameter_by_efuse(struct type_c_data *type_c)873{874 struct type_c_cfg *type_c_cfg = type_c->type_c_cfg;875 struct cc_param *cc_param;876 struct nvmem_cell *cell;877 s8 cc1_4p7k = 0;878 s8 cc1_12k = 0;879 s8 cc1_0p2v = 0;880 s8 cc1_0p8v = 0;881 s8 cc1_2p6v = 0;882 s8 cc1_0p66v = 0;883 s8 cc1_1p23v = 0;884 s8 cc2_4p7k = 0;885 s8 cc2_12k = 0;886 s8 cc2_0p2v = 0;887 s8 cc2_0p8v = 0;888 s8 cc2_2p6v = 0;889 s8 cc2_0p66v = 0;890 s8 cc2_1p23v = 0;891 892 cell = nvmem_cell_get(type_c->dev, "usb-cal");893 if (IS_ERR(cell)) {894 dev_warn(type_c->dev, "%s failed to get usb-cal: %ld\n",895 __func__, PTR_ERR(cell));896 } else {897 unsigned char *buf;898 size_t buf_size;899 int value_size = 4;900 int value_mask = (BIT(value_size) - 1);901 902 buf = nvmem_cell_read(cell, &buf_size);903 if (!IS_ERR(buf)) {904 cc1_0p2v = get_value((buf[0] >> value_size * 0) & value_mask);905 cc1_0p8v = get_value((buf[0] >> value_size * 1) & value_mask);906 cc1_2p6v = get_value((buf[1] >> value_size * 0) & value_mask);907 cc1_0p66v = get_value((buf[1] >> value_size * 1) & value_mask);908 cc1_1p23v = get_value((buf[2] >> value_size * 0) & value_mask);909 910 cc2_0p2v = get_value((buf[3] >> value_size * 0) & value_mask);911 cc2_0p8v = get_value((buf[3] >> value_size * 1) & value_mask);912 cc2_2p6v = get_value((buf[4] >> value_size * 0) & value_mask);913 cc2_0p66v = get_value((buf[4] >> value_size * 1) & value_mask);914 cc2_1p23v = get_value((buf[5] >> value_size * 0) & value_mask);915 916 cc1_4p7k = get_value((buf[6] >> value_size * 0) & value_mask);917 cc1_12k = get_value((buf[6] >> value_size * 1) & value_mask);918 cc2_4p7k = get_value((buf[7] >> value_size * 0) & value_mask);919 cc2_12k = get_value((buf[7] >> value_size * 1) & value_mask);920 921 kfree(buf);922 }923 nvmem_cell_put(cell);924 }925 926 dev_dbg(type_c->dev, "check efuse cc1_4p7k=%d cc1_12k=%d cc2_4p7k=%d cc2_12k=%d\n",927 cc1_4p7k, cc1_12k, cc2_4p7k, cc2_12k);928 dev_dbg(type_c->dev, "check efuse cc1_0p2v=%d cc1_0p8v=%d cc1_2p6v=%d cc1_0p66v=%d cc1_1p23v=%d\n",929 cc1_0p2v, cc1_0p8v, cc1_2p6v, cc1_0p66v, cc1_1p23v);930 dev_dbg(type_c->dev, "check efuse cc2_0p2v=%d cc2_0p8v=%d cc2_2p6v=%d cc2_0p66v=%d cc2_1p23v=%d\n",931 cc2_0p2v, cc2_0p8v, cc2_2p6v, cc2_0p66v, cc2_1p23v);932 933 cc_param = &type_c_cfg->cc1_param;934 cc_param->rp_4p7k_code = cc_param->rp_4p7k_code + cc1_4p7k;935 cc_param->rp_12k_code = cc_param->rp_12k_code + cc1_12k;936 937 cc_param->vref_1p23v = cc_param->vref_1p23v + cc1_1p23v;938 cc_param->vref_0p66v = cc_param->vref_0p66v + cc1_0p66v;939 cc_param->vref_2p6v = cc_param->vref_2p6v + cc1_2p6v;940 cc_param->vref_0p8v = cc_param->vref_0p8v + cc1_0p8v;941 cc_param->vref_0p2v = cc_param->vref_0p2v + cc1_0p2v;942 943 cc_param = &type_c_cfg->cc2_param;944 cc_param->rp_4p7k_code = cc_param->rp_4p7k_code + cc2_4p7k;945 cc_param->rp_12k_code = cc_param->rp_12k_code + cc2_12k;946 947 cc_param->vref_1p23v = cc_param->vref_1p23v + cc2_1p23v;948 cc_param->vref_0p66v = cc_param->vref_0p66v + cc2_0p66v;949 cc_param->vref_2p6v = cc_param->vref_2p6v + cc2_2p6v;950 cc_param->vref_0p8v = cc_param->vref_0p8v + cc2_0p8v;951 cc_param->vref_0p2v = cc_param->vref_0p2v + cc2_0p2v;952 953 return 0;954}955 956static int __updated_type_c_parameter_by_efuse_v2(struct type_c_data *type_c)957{958 struct type_c_cfg *type_c_cfg = type_c->type_c_cfg;959 struct cc_param *cc_param;960 struct nvmem_cell *cell;961 s8 cc1_4p7k = 0;962 s8 cc1_12k = 0;963 s8 cc1_0p2v = 0;964 s8 cc1_0p8v = 0;965 s8 cc1_2p6v = 0;966 s8 cc1_0p66v = 0;967 s8 cc1_1p23v = 0;968 s8 cc2_4p7k = 0;969 s8 cc2_12k = 0;970 s8 cc2_0p2v = 0;971 s8 cc2_0p8v = 0;972 s8 cc2_2p6v = 0;973 s8 cc2_0p66v = 0;974 s8 cc2_1p23v = 0;975 976 cell = nvmem_cell_get(type_c->dev, "usb-type-c-cal");977 if (IS_ERR(cell)) {978 dev_warn(type_c->dev, "%s failed to get usb-type-c-cal: %ld\n",979 __func__, PTR_ERR(cell));980 } else {981 unsigned char *buf;982 size_t buf_size;983 int value_size = 0;984 int value_mask = (BIT(value_size) - 1);985 986 buf = nvmem_cell_read(cell, &buf_size);987 if (!IS_ERR(buf)) {988 value_size = 5;989 value_mask = (BIT(value_size) - 1);990 cc1_4p7k = buf[0] & value_mask;991 cc1_12k = buf[1] & value_mask;992 cc2_4p7k = buf[2] & value_mask;993 cc2_12k = buf[3] & value_mask;994 995 value_size = 4;996 value_mask = (BIT(value_size) - 1);997 cc1_0p2v = (buf[4] >> value_size * 0) & value_mask;998 cc1_0p66v = (buf[4] >> value_size * 1) & value_mask;999 cc1_0p8v = (buf[5] >> value_size * 0) & value_mask;1000 cc1_1p23v = (buf[5] >> value_size * 1) & value_mask;1001 cc1_2p6v = (buf[6] >> value_size * 0) & value_mask;1002 1003 cc2_0p2v = (buf[6] >> value_size * 1) & value_mask;1004 cc2_0p66v = (buf[7] >> value_size * 0) & value_mask;1005 cc2_0p8v = (buf[7] >> value_size * 1) & value_mask;1006 cc2_1p23v = (buf[8] >> value_size * 0) & value_mask;1007 cc2_2p6v = (buf[8] >> value_size * 1) & value_mask;1008 1009 kfree(buf);1010 }1011 nvmem_cell_put(cell);1012 }1013 1014 dev_dbg(type_c->dev, "check efuse v2 cc1_4p7k=%d cc1_12k=%d cc2_4p7k=%d cc2_12k=%d\n",1015 cc1_4p7k, cc1_12k, cc2_4p7k, cc2_12k);1016 dev_dbg(type_c->dev, "check efuse v2 cc1_0p2v=%d cc1_0p8v=%d cc1_2p6v=%d cc1_0p66v=%d cc1_1p23v=%d\n",1017 cc1_0p2v, cc1_0p8v, cc1_2p6v, cc1_0p66v, cc1_1p23v);1018 dev_dbg(type_c->dev, "check efuse v2 cc2_0p2v=%d cc2_0p8v=%d cc2_2p6v=%d cc2_0p66v=%d cc2_1p23v=%d\n",1019 cc2_0p2v, cc2_0p8v, cc2_2p6v, cc2_0p66v, cc2_1p23v);1020 1021 cc_param = &type_c_cfg->cc1_param;1022 if (cc1_4p7k)1023 cc_param->rp_4p7k_code = cc1_4p7k;1024 if (cc1_12k)1025 cc_param->rp_12k_code = cc1_12k;1026 1027 if (cc1_1p23v)1028 cc_param->vref_1p23v = cc1_1p23v;1029 if (cc1_0p66v)1030 cc_param->vref_0p66v = cc1_0p66v;1031 if (cc1_2p6v)1032 cc_param->vref_2p6v = cc1_2p6v;1033 if (cc1_0p8v)1034 cc_param->vref_0p8v = cc1_0p8v;1035 if (cc1_0p2v)1036 cc_param->vref_0p2v = cc1_0p2v;1037 1038 cc_param = &type_c_cfg->cc2_param;1039 if (cc2_4p7k)1040 cc_param->rp_4p7k_code = cc2_4p7k;1041 if (cc2_12k)1042 cc_param->rp_12k_code = cc2_12k;1043 1044 if (cc2_1p23v)1045 cc_param->vref_1p23v = cc2_1p23v;1046 if (cc2_0p66v)1047 cc_param->vref_0p66v = cc2_0p66v;1048 if (cc2_2p6v)1049 cc_param->vref_2p6v = cc2_2p6v;1050 if (cc2_0p8v)1051 cc_param->vref_0p8v = cc2_0p8v;1052 if (cc2_0p2v)1053 cc_param->vref_0p2v = cc2_0p2v;1054 1055 return 0;1056}1057 1058static void get_default_type_c_parameter(struct type_c_data *type_c)1059{1060 void __iomem *reg;1061 int val;1062 1063 type_c->dfp_mode_rp_en = dfp_mode(CC_MODE_DFP_3_0) | EN_RP4P7K;1064 type_c->ufp_mode_rd_en = EN_RD;1065 1066 reg = type_c->reg_base + USB_TYPEC_CTRL_CC1_0;1067 val = readl(reg);1068 type_c->cc1_code = CC_CODE_MASK & val;1069 1070 reg = type_c->reg_base + USB_TYPEC_CTRL_CC2_0;1071 val = readl(reg);1072 type_c->cc2_code = CC_CODE_MASK & val;1073 1074 reg = type_c->reg_base + USB_TYPEC_CTRL_CC1_1;1075 val = readl(reg);1076 type_c->cc1_vref = val;1077 1078 reg = type_c->reg_base + USB_TYPEC_CTRL_CC2_1;1079 val = readl(reg);1080 type_c->cc2_vref = val;1081 1082 reg = type_c->reg_base + USB_TYPEC_CTRL;1083 val = readl(reg);1084 type_c->debounce = DEBOUNCE_TIME_MASK & val;1085}1086 1087static int setup_type_c_parameter(struct type_c_data *type_c)1088{1089 struct type_c_cfg *type_c_cfg = type_c->type_c_cfg;1090 struct cc_param *cc_param;1091 struct soc_device_attribute rtk_soc_efuse_v1[] = {1092 { .family = "Realtek Phoenix",},1093 { .family = "Realtek Kylin",},1094 { .family = "Realtek Hercules",},1095 { .family = "Realtek Thor",},1096 { .family = "Realtek Hank",},1097 { .family = "Realtek Groot",},1098 { .family = "Realtek Stark",},1099 { .family = "Realtek Parker",},1100 { /* empty */ }1101 };1102 1103 if (type_c_cfg->use_defalut_parameter) {1104 get_default_type_c_parameter(type_c);1105 return 0;1106 }1107 1108 if (soc_device_match(rtk_soc_efuse_v1))1109 __updated_type_c_parameter_by_efuse(type_c);1110 else1111 __updated_type_c_parameter_by_efuse_v2(type_c);1112 1113 /*1114 * UFP rd vref_ufp : 1p23v, 0p66v, 0p2v1115 * DFP_USB rp36k vref_dfp_usb: 0_1p6v, 0p2v, unused1116 * DFP_1.5 rp12k vref_dfp_1_5: 1_1p6v, 0p4v, 0p2v1117 * DFP_3.0 rp4p7k vref_dfp_3_0: 2p6v, 0p8v, 0p2v1118 */1119 1120 switch (type_c_cfg->cc_dfp_mode) {1121 case CC_MODE_DFP_USB:1122 type_c->dfp_mode_rp_en = dfp_mode(CC_MODE_DFP_USB) | EN_RP36K;1123 break;1124 case CC_MODE_DFP_1_5:1125 type_c->dfp_mode_rp_en = dfp_mode(CC_MODE_DFP_1_5) | EN_RP12K;1126 break;1127 case CC_MODE_DFP_3_0:1128 type_c->dfp_mode_rp_en = dfp_mode(CC_MODE_DFP_3_0) | EN_RP4P7K;1129 break;1130 default:1131 dev_err(type_c->dev, "%s: unknown cc_dfp_mode %d\n",1132 __func__, type_c_cfg->cc_dfp_mode);1133 }1134 1135 type_c->ufp_mode_rd_en = EN_RD;1136 1137 cc_param = &type_c_cfg->cc1_param;1138 type_c->cc1_code = rp4pk_code(cc_param->rp_4p7k_code) |1139 rp36k_code(cc_param->rp_36k_code) |1140 rp12k_code(cc_param->rp_12k_code) |1141 rd_code(cc_param->rd_code);1142 1143 if (type_c_cfg->parameter_ver == PARAMETER_V0)1144 type_c->cc1_vref = V0_vref_2p6v(cc_param->vref_2p6v) |1145 V0_vref_1p23v(cc_param->vref_1p23v) |1146 V0_vref_0p8v(cc_param->vref_0p8v) |1147 V0_vref_0p66v(cc_param->vref_0p66v) |1148 V0_vref_0p4v(cc_param->vref_0p4v) |1149 V0_vref_0p2v(cc_param->vref_0p2v) |1150 V0_vref_1_1p6v(cc_param->vref_1_1p6v) |1151 V0_vref_0_1p6v(cc_param->vref_0_1p6v);1152 else if (type_c_cfg->parameter_ver == PARAMETER_V1)1153 type_c->cc1_vref = V1_vref_2p6v(cc_param->vref_2p6v) |1154 V1_vref_1p23v(cc_param->vref_1p23v) |1155 V1_vref_0p8v(cc_param->vref_0p8v) |1156 V1_vref_0p66v(cc_param->vref_0p66v) |1157 V1_vref_0p4v(cc_param->vref_0p4v) |1158 V1_vref_0p2v(cc_param->vref_0p2v) |1159 V1_vref_1_1p6v(cc_param->vref_1_1p6v) |1160 V1_vref_0_1p6v(cc_param->vref_0_1p6v);1161 else1162 dev_err(type_c->dev, "%s: unknown parameter_ver %d\n",1163 __func__, type_c_cfg->parameter_ver);1164 1165 cc_param = &type_c_cfg->cc2_param;1166 type_c->cc2_code = rp4pk_code(cc_param->rp_4p7k_code)1167 | rp36k_code(cc_param->rp_36k_code)1168 | rp12k_code(cc_param->rp_12k_code)1169 | rd_code(cc_param->rd_code);1170 1171 if (type_c_cfg->parameter_ver == PARAMETER_V0)1172 type_c->cc2_vref = V0_vref_2p6v(cc_param->vref_2p6v) |1173 V0_vref_1p23v(cc_param->vref_1p23v) |1174 V0_vref_0p8v(cc_param->vref_0p8v) |1175 V0_vref_0p66v(cc_param->vref_0p66v) |1176 V0_vref_0p4v(cc_param->vref_0p4v) |1177 V0_vref_0p2v(cc_param->vref_0p2v) |1178 V0_vref_1_1p6v(cc_param->vref_1_1p6v) |1179 V0_vref_0_1p6v(cc_param->vref_0_1p6v);1180 else if (type_c_cfg->parameter_ver == PARAMETER_V1)1181 type_c->cc2_vref = V1_vref_2p6v(cc_param->vref_2p6v) |1182 V1_vref_1p23v(cc_param->vref_1p23v) |1183 V1_vref_0p8v(cc_param->vref_0p8v) |1184 V1_vref_0p66v(cc_param->vref_0p66v) |1185 V1_vref_0p4v(cc_param->vref_0p4v) |1186 V1_vref_0p2v(cc_param->vref_0p2v) |1187 V1_vref_1_1p6v(cc_param->vref_1_1p6v) |1188 V1_vref_0_1p6v(cc_param->vref_0_1p6v);1189 else1190 dev_err(type_c->dev, "%s: unknown parameter_ver %d\n",1191 __func__, type_c_cfg->parameter_ver);1192 1193 type_c->debounce = (type_c_cfg->debounce_val << 1) | DEBOUNCE_EN;1194 1195 return 0;1196}1197 1198static int extcon_rtk_type_c_init(struct type_c_data *type_c)1199{1200 struct device *dev = type_c->dev;1201 unsigned long flags;1202 void __iomem *reg;1203 int val;1204 1205 spin_lock_irqsave(&type_c->lock, flags);1206 1207 /* set parameter */1208 reg = type_c->reg_base + USB_TYPEC_CTRL_CC1_0;1209 val = readl(reg);1210 val = (~CC_CODE_MASK & val) | (type_c->cc1_code & CC_CODE_MASK);1211 writel(val, reg);1212 1213 reg = type_c->reg_base + USB_TYPEC_CTRL_CC2_0;1214 val = readl(reg);1215 val = (~CC_CODE_MASK & val) | (type_c->cc2_code & CC_CODE_MASK);1216 1217 reg = type_c->reg_base + USB_TYPEC_CTRL_CC1_1;1218 writel(type_c->cc1_vref, reg);1219 1220 reg = type_c->reg_base + USB_TYPEC_CTRL_CC2_1;1221 writel(type_c->cc2_vref, reg);1222 1223 reg = type_c->reg_base + USB_TYPEC_CTRL;1224 val = readl(reg);1225 val = (~DEBOUNCE_TIME_MASK & val) | (type_c->debounce & DEBOUNCE_TIME_MASK);1226 1227 dev_info(dev, "First check USB_DR_MODE_PERIPHERAL");1228 type_c->cc_mode = IN_DEVICE_MODE;1229 type_c->is_attach = IN_DETACH;1230 type_c->connect_change = CONNECT_NO_CHANGE;1231 1232 detect_host(type_c);1233 1234 spin_unlock_irqrestore(&type_c->lock, flags);1235 1236 schedule_delayed_work(&type_c->delayed_work, msecs_to_jiffies(0));1237 1238 if (!type_c->port) {1239 struct typec_capability typec_cap = { };1240 struct fwnode_handle *fwnode;1241 const char *buf;1242 int ret;1243 1244 typec_cap.revision = USB_TYPEC_REV_1_0;1245 typec_cap.prefer_role = TYPEC_NO_PREFERRED_ROLE;1246 typec_cap.driver_data = type_c;1247 typec_cap.ops = &type_c_port_ops;1248 1249 fwnode = device_get_named_child_node(dev, "connector");1250 if (!fwnode)1251 return -EINVAL;1252 1253 ret = fwnode_property_read_string(fwnode, "power-role", &buf);1254 if (ret) {1255 dev_err(dev, "power-role not found: %d\n", ret);1256 return ret;1257 }1258 1259 ret = typec_find_port_power_role(buf);1260 if (ret < 0)1261 return ret;1262 typec_cap.type = ret;1263 1264 ret = fwnode_property_read_string(fwnode, "data-role", &buf);1265 if (ret) {1266 dev_err(dev, "data-role not found: %d\n", ret);1267 return ret;1268 }1269 1270 ret = typec_find_port_data_role(buf);1271 if (ret < 0)1272 return ret;1273 typec_cap.data = ret;1274 1275 type_c->port = typec_register_port(type_c->dev, &typec_cap);1276 if (IS_ERR(type_c->port))1277 return PTR_ERR(type_c->port);1278 }1279 1280 return 0;1281}1282 1283static int extcon_rtk_type_c_edev_register(struct type_c_data *type_c)1284{1285 struct device *dev = type_c->dev;1286 int ret = 0;1287 1288 type_c->edev = devm_extcon_dev_allocate(dev, usb_type_c_cable);1289 if (IS_ERR(type_c->edev)) {1290 dev_err(dev, "failed to allocate extcon device\n");1291 return -ENOMEM;1292 }1293 1294 ret = devm_extcon_dev_register(dev, type_c->edev);1295 if (ret < 0) {1296 dev_err(dev, "failed to register extcon device\n");1297 return ret;1298 }1299 1300 extcon_set_property_capability(type_c->edev, EXTCON_USB,1301 EXTCON_PROP_USB_VBUS);1302 extcon_set_property_capability(type_c->edev, EXTCON_USB,1303 EXTCON_PROP_USB_TYPEC_POLARITY);1304 extcon_set_property_capability(type_c->edev, EXTCON_USB,1305 EXTCON_PROP_USB_SS);1306 1307 extcon_set_property_capability(type_c->edev, EXTCON_USB_HOST,1308 EXTCON_PROP_USB_VBUS);1309 extcon_set_property_capability(type_c->edev, EXTCON_USB_HOST,1310 EXTCON_PROP_USB_TYPEC_POLARITY);1311 extcon_set_property_capability(type_c->edev, EXTCON_USB_HOST,1312 EXTCON_PROP_USB_SS);1313 1314 return ret;1315}1316 1317static int extcon_rtk_type_c_probe(struct platform_device *pdev)1318{1319 struct device *dev = &pdev->dev;1320 struct type_c_data *type_c;1321 const struct type_c_cfg *type_c_cfg;1322 int ret = 0;1323 1324 type_c = devm_kzalloc(dev, sizeof(*type_c), GFP_KERNEL);1325 if (!type_c)1326 return -ENOMEM;1327 1328 type_c->reg_base = devm_platform_ioremap_resource(pdev, 0);1329 if (IS_ERR(type_c->reg_base))1330 return PTR_ERR(type_c->reg_base);1331 1332 type_c->dev = dev;1333 1334 type_c->irq = irq_of_parse_and_map(pdev->dev.of_node, 0);1335 if (type_c->irq <= 0) {1336 dev_err(&pdev->dev, "Type C driver with no IRQ. Check %s setup!\n",1337 dev_name(&pdev->dev));1338 ret = -ENODEV;1339 goto err;1340 }1341 1342 ret = devm_request_irq(dev, type_c->irq, type_c_detect_irq,1343 IRQF_SHARED, "type_c_detect", type_c);1344 1345 spin_lock_init(&type_c->lock);1346 1347 type_c->rd_ctrl_gpio_desc = NULL;1348 if (soc_device_match(rtk_soc_kylin)) {1349 struct gpio_desc *gpio;1350 1351 gpio = fwnode_gpiod_get_index(of_fwnode_handle(dev->of_node),1352 "realtek,rd-ctrl-gpios",1353 0, GPIOD_OUT_HIGH, "rd-ctrl-gpio");1354 if (IS_ERR(gpio)) {1355 dev_err(dev, "Error rd_ctrl-gpios no found (err=%d)\n",1356 (int)PTR_ERR(gpio));1357 } else {1358 type_c->rd_ctrl_gpio_desc = gpio;1359 dev_dbg(dev, "%s get rd-ctrl-gpios (id=%d) OK\n",1360 __func__, desc_to_gpio(gpio));1361 }1362 }1363 1364 type_c_cfg = of_device_get_match_data(dev);1365 if (!type_c_cfg) {1366 dev_err(dev, "type_c config are not assigned!\n");1367 ret = -EINVAL;1368 goto err;1369 }1370 1371 type_c->type_c_cfg = devm_kzalloc(dev, sizeof(*type_c_cfg), GFP_KERNEL);1372 1373 memcpy(type_c->type_c_cfg, type_c_cfg, sizeof(*type_c_cfg));1374 1375 if (setup_type_c_parameter(type_c)) {1376 dev_err(dev, "ERROR: %s to setup type c parameter!!", __func__);1377 ret = -EINVAL;1378 goto err;1379 }1380 1381 INIT_DELAYED_WORK(&type_c->delayed_work, host_device_switch);1382 1383 ret = extcon_rtk_type_c_init(type_c);1384 if (ret) {1385 dev_err(dev, "%s failed to init type_c\n", __func__);1386 goto err;1387 }1388 1389 platform_set_drvdata(pdev, type_c);1390 1391 ret = extcon_rtk_type_c_edev_register(type_c);1392 1393 create_debug_files(type_c);1394 1395 return 0;1396 1397err:1398 dev_err(&pdev->dev, "%s: Probe fail, %d\n", __func__, ret);1399 1400 return ret;1401}1402 1403static void extcon_rtk_type_c_remove(struct platform_device *pdev)1404{1405 struct device *dev = &pdev->dev;1406 struct type_c_data *type_c = dev_get_drvdata(dev);1407 u32 default_ctrl;1408 unsigned long flags;1409 1410 remove_debug_files(type_c);1411 1412 if (type_c->port) {1413 typec_unregister_port(type_c->port);1414 type_c->port = NULL;1415 }1416 1417 cancel_delayed_work_sync(&type_c->delayed_work);1418 flush_delayed_work(&type_c->delayed_work);1419 WARN_ON_ONCE(delayed_work_pending(&type_c->delayed_work));1420 1421 spin_lock_irqsave(&type_c->lock, flags);1422 /* disable interrupt */1423 default_ctrl = readl(type_c->reg_base + USB_TYPEC_CTRL) &1424 DEBOUNCE_TIME_MASK;1425 writel(default_ctrl, type_c->reg_base + USB_TYPEC_CTRL);1426 1427 /* disable cc detect, rp, rd */1428 writel(PLR_EN, type_c->reg_base + USB_TYPEC_CTRL_CC1_0);1429 writel(0, type_c->reg_base + USB_TYPEC_CTRL_CC2_0);1430 1431 spin_unlock_irqrestore(&type_c->lock, flags);1432 1433 if (type_c->rd_ctrl_gpio_desc)1434 gpiod_put(type_c->rd_ctrl_gpio_desc);1435 type_c->rd_ctrl_gpio_desc = NULL;1436 1437 free_irq(type_c->irq, type_c);1438}1439 1440static const struct type_c_cfg rtd1295_type_c_cfg = {1441 .parameter_ver = PARAMETER_V0,1442 .cc_dfp_mode = CC_MODE_DFP_3_0,1443 .cc1_param = { .rp_4p7k_code = 0xb,1444 .rp_36k_code = 0x17,1445 .rp_12k_code = 0x10,1446 .rd_code = 0,1447 .ra_code = 0,1448 .vref_2p6v = 0x0,1449 .vref_1p23v = 0x0,1450 .vref_0p8v = 0x3,1451 .vref_0p66v = 0x0,1452 .vref_0p4v = 0x0,1453 .vref_0p2v = 0x4,1454 .vref_1_1p6v = 0,1455 .vref_0_1p6v = 0 },1456 .cc2_param = { .rp_4p7k_code = 0xc,1457 .rp_36k_code = 0x17,1458 .rp_12k_code = 0x12,1459 .rd_code = 0,1460 .ra_code = 0,1461 .vref_2p6v = 0x2,1462 .vref_1p23v = 0x0,1463 .vref_0p8v = 0x3,1464 .vref_0p66v = 0x0,1465 .vref_0p4v = 0x0,1466 .vref_0p2v = 0x5,1467 .vref_1_1p6v = 0,1468 .vref_0_1p6v = 0 },1469 .debounce_val = 0x7f, /* 1b,1us 7f,4.7us */1470 .use_defalut_parameter = false,1471};1472 1473static const struct type_c_cfg rtd1395_type_c_cfg = {1474 .parameter_ver = PARAMETER_V0,1475 .cc_dfp_mode = CC_MODE_DFP_3_0,1476 .cc1_param = { .rp_4p7k_code = 0xc,1477 .rp_36k_code = 0xb,1478 .rp_12k_code = 0xe,1479 .rd_code = 0x10,1480 .ra_code = 0x0,1481 .vref_2p6v = 0x0,1482 .vref_1p23v = 0x1,1483 .vref_0p8v = 0x0,1484 .vref_0p66v = 0x0,1485 .vref_0p4v = 0x3,1486 .vref_0p2v = 0x0,1487 .vref_1_1p6v = 0x7,1488 .vref_0_1p6v = 0x7 },1489 .cc2_param = { .rp_4p7k_code = 0xb,1490 .rp_36k_code = 0x9,1491 .rp_12k_code = 0xe,1492 .rd_code = 0xf,1493 .ra_code = 0x0,1494 .vref_2p6v = 0x1,1495 .vref_1p23v = 0x3,1496 .vref_0p8v = 0x3,1497 .vref_0p66v = 0x2,1498 .vref_0p4v = 0x3,1499 .vref_0p2v = 0x2,1500 .vref_1_1p6v = 0x7,1501 .vref_0_1p6v = 0x7 },1502 .debounce_val = 0x7f, /* 1b,1us 7f,4.7us */1503 .use_defalut_parameter = false,1504};1505 1506static const struct type_c_cfg rtd1619_type_c_cfg = {1507 .parameter_ver = PARAMETER_V0,1508 .cc_dfp_mode = CC_MODE_DFP_3_0,1509 .cc1_param = { .rp_4p7k_code = 0xc,1510 .rp_36k_code = 0xf,1511 .rp_12k_code = 0xe,1512 .rd_code = 0x11,1513 .ra_code = 0x0,1514 .vref_2p6v = 0x5,1515 .vref_1p23v = 0x7,1516 .vref_0p8v = 0xa,1517 .vref_0p66v = 0xa,1518 .vref_0p4v = 0x3,1519 .vref_0p2v = 0x2,1520 .vref_1_1p6v = 0x7,1521 .vref_0_1p6v = 0x7 },1522 .cc2_param = { .rp_4p7k_code = 0xc,1523 .rp_36k_code = 0xf,1524 .rp_12k_code = 0xe,1525 .rd_code = 0xf,1526 .ra_code = 0x0,1527 .vref_2p6v = 0x5,1528 .vref_1p23v = 0x8,1529 .vref_0p8v = 0xa,1530 .vref_0p66v = 0xa,1531 .vref_0p4v = 0x3,1532 .vref_0p2v = 0x2,1533 .vref_1_1p6v = 0x7,1534 .vref_0_1p6v = 0x7 },1535 .debounce_val = 0x7f, /* 1b,1us 7f,4.7us */1536 .use_defalut_parameter = false,1537};1538 1539static const struct type_c_cfg rtd1319_type_c_cfg = {1540 .parameter_ver = PARAMETER_V0,1541 .cc_dfp_mode = CC_MODE_DFP_1_5,1542 .cc1_param = { .rp_4p7k_code = 0x9,1543 .rp_36k_code = 0xe,1544 .rp_12k_code = 0x9,1545 .rd_code = 0x9,1546 .ra_code = 0x7,1547 .vref_2p6v = 0x3,1548 .vref_1p23v = 0x7,1549 .vref_0p8v = 0x7,1550 .vref_0p66v = 0x6,1551 .vref_0p4v = 0x2,1552 .vref_0p2v = 0x3,1553 .vref_1_1p6v = 0x4,1554 .vref_0_1p6v = 0x7 },1555 .cc2_param = { .rp_4p7k_code = 0x8,1556 .rp_36k_code = 0xe,1557 .rp_12k_code = 0x9,1558 .rd_code = 0x9,1559 .ra_code = 0x7,1560 .vref_2p6v = 0x3,1561 .vref_1p23v = 0x7,1562 .vref_0p8v = 0x7,1563 .vref_0p66v = 0x6,1564 .vref_0p4v = 0x3,1565 .vref_0p2v = 0x3,1566 .vref_1_1p6v = 0x6,1567 .vref_0_1p6v = 0x7 },1568 .debounce_val = 0x7f, /* 1b,1us 7f,4.7us */1569 .use_defalut_parameter = false,1570};1571 1572static const struct type_c_cfg rtd1312c_type_c_cfg = {1573 .parameter_ver = PARAMETER_V0,1574 .cc_dfp_mode = CC_MODE_DFP_1_5,1575 .cc1_param = { .rp_4p7k_code = 0xe,1576 .rp_36k_code = 0xc,1577 .rp_12k_code = 0xc,1578 .rd_code = 0xa,1579 .ra_code = 0x3,1580 .vref_2p6v = 0xa,1581 .vref_1p23v = 0x7,1582 .vref_0p8v = 0x7,1583 .vref_0p66v = 0x7,1584 .vref_0p4v = 0x4,1585 .vref_0p2v = 0x4,1586 .vref_1_1p6v = 0x7,1587 .vref_0_1p6v = 0x7 },1588 .cc2_param = { .rp_4p7k_code = 0xe,1589 .rp_36k_code = 0xc,1590 .rp_12k_code = 0xc,1591 .rd_code = 0xa,1592 .ra_code = 0x3,1593 .vref_2p6v = 0xa,1594 .vref_1p23v = 0x7,1595 .vref_0p8v = 0x7,1596 .vref_0p66v = 0x7,1597 .vref_0p4v = 0x4,1598 .vref_0p2v = 0x4,1599 .vref_1_1p6v = 0x7,1600 .vref_0_1p6v = 0x7 },1601 .debounce_val = 0x7f, /* 1b,1us 7f,4.7us */1602 .use_defalut_parameter = false,1603};1604 1605static const struct type_c_cfg rtd1619b_type_c_cfg = {1606 .parameter_ver = PARAMETER_V1,1607 .cc_dfp_mode = CC_MODE_DFP_1_5,1608 .cc1_param = { .rp_4p7k_code = 0xf,1609 .rp_36k_code = 0xf,1610 .rp_12k_code = 0xf,1611 .rd_code = 0xf,1612 .ra_code = 0x7,1613 .vref_2p6v = 0x9,1614 .vref_1p23v = 0x7,1615 .vref_0p8v = 0x9,1616 .vref_0p66v = 0x8,1617 .vref_0p4v = 0x7,1618 .vref_0p2v = 0x9,1619 .vref_1_1p6v = 0x7,1620 .vref_0_1p6v = 0x7 },1621 .cc2_param = { .rp_4p7k_code = 0xf,1622 .rp_36k_code = 0xf,1623 .rp_12k_code = 0xf,1624 .rd_code = 0xf,1625 .ra_code = 0x7,1626 .vref_1p23v = 0x7,1627 .vref_0p8v = 0x9,1628 .vref_0p66v = 0x8,1629 .vref_0p4v = 0x7,1630 .vref_0p2v = 0x8,1631 .vref_1_1p6v = 0x7,1632 .vref_0_1p6v = 0x7 },1633 .debounce_val = 0x7f, /* 1b,1us 7f,4.7us */1634 .use_defalut_parameter = false,1635};1636 1637static const struct type_c_cfg rtd1319d_type_c_cfg = {1638 .parameter_ver = PARAMETER_V1,1639 .cc_dfp_mode = CC_MODE_DFP_1_5,1640 .cc1_param = { .rp_4p7k_code = 0xe,1641 .rp_36k_code = 0x3,1642 .rp_12k_code = 0xe,1643 .rd_code = 0xf,1644 .ra_code = 0x6,1645 .vref_2p6v = 0x7,1646 .vref_1p23v = 0x7,1647 .vref_0p8v = 0x8,1648 .vref_0p66v = 0x7,1649 .vref_0p4v = 0x7,1650 .vref_0p2v = 0x7,1651 .vref_1_1p6v = 0x7,1652 .vref_0_1p6v = 0x7 },1653 .cc2_param = { .rp_4p7k_code = 0xe,1654 .rp_36k_code = 0x3,1655 .rp_12k_code = 0xe,1656 .rd_code = 0xf,1657 .ra_code = 0x6,1658 .vref_2p6v = 0x7,1659 .vref_1p23v = 0x7,1660 .vref_0p8v = 0x8,1661 .vref_0p66v = 0x7,1662 .vref_0p4v = 0x7,1663 .vref_0p2v = 0x8,1664 .vref_1_1p6v = 0x7,1665 .vref_0_1p6v = 0x7 },1666 .debounce_val = 0x7f, /* 1b,1us 7f,4.7us */1667 .use_defalut_parameter = false,1668};1669 1670static const struct type_c_cfg rtd1315e_type_c_cfg = {1671 .parameter_ver = PARAMETER_V1,1672 .cc_dfp_mode = CC_MODE_DFP_1_5,1673 .cc1_param = { .rp_4p7k_code = 0xe,1674 .rp_36k_code = 0x3,1675 .rp_12k_code = 0xe,1676 .rd_code = 0xf,1677 .ra_code = 0x6,1678 .vref_2p6v = 0x7,1679 .vref_1p23v = 0x7,1680 .vref_0p8v = 0x8,1681 .vref_0p66v = 0x7,1682 .vref_0p4v = 0x7,1683 .vref_0p2v = 0x7,1684 .vref_1_1p6v = 0x7,1685 .vref_0_1p6v = 0x7 },1686 .cc2_param = { .rp_4p7k_code = 0xe,1687 .rp_36k_code = 0x3,1688 .rp_12k_code = 0xe,1689 .rd_code = 0xf,1690 .ra_code = 0x6,1691 .vref_2p6v = 0x7,1692 .vref_1p23v = 0x7,1693 .vref_0p8v = 0x8,1694 .vref_0p66v = 0x7,1695 .vref_0p4v = 0x7,1696 .vref_0p2v = 0x8,1697 .vref_1_1p6v = 0x7,1698 .vref_0_1p6v = 0x7 },1699 .debounce_val = 0x7f, /* 1b,1us 7f,4.7us */1700 .use_defalut_parameter = false,1701};1702 1703static const struct of_device_id extcon_rtk_type_c_match[] = {1704 { .compatible = "realtek,rtd1295-type-c", .data = &rtd1295_type_c_cfg },1705 { .compatible = "realtek,rtd1312c-type-c", .data = &rtd1312c_type_c_cfg },1706 { .compatible = "realtek,rtd1315e-type-c", .data = &rtd1315e_type_c_cfg },1707 { .compatible = "realtek,rtd1319-type-c", .data = &rtd1319_type_c_cfg },1708 { .compatible = "realtek,rtd1319d-type-c", .data = &rtd1319d_type_c_cfg },1709 { .compatible = "realtek,rtd1395-type-c", .data = &rtd1395_type_c_cfg },1710 { .compatible = "realtek,rtd1619-type-c", .data = &rtd1619_type_c_cfg },1711 { .compatible = "realtek,rtd1619b-type-c", .data = &rtd1619b_type_c_cfg },1712 {},1713};1714MODULE_DEVICE_TABLE(of, extcon_rtk_type_c_match);1715 1716#ifdef CONFIG_PM_SLEEP1717static int extcon_rtk_type_c_prepare(struct device *dev)1718{1719 struct type_c_data *type_c = dev_get_drvdata(dev);1720 u32 default_ctrl;1721 unsigned long flags;1722 1723 cancel_delayed_work_sync(&type_c->delayed_work);1724 flush_delayed_work(&type_c->delayed_work);1725 WARN_ON_ONCE(delayed_work_pending(&type_c->delayed_work));1726 1727 spin_lock_irqsave(&type_c->lock, flags);1728 /* disable interrupt */1729 default_ctrl = readl(type_c->reg_base + USB_TYPEC_CTRL) &1730 DEBOUNCE_TIME_MASK;1731 writel(default_ctrl, type_c->reg_base + USB_TYPEC_CTRL);1732 1733 /* disable cc detect, rp, rd */1734 writel(PLR_EN, type_c->reg_base + USB_TYPEC_CTRL_CC1_0);1735 writel(0, type_c->reg_base + USB_TYPEC_CTRL_CC2_0);1736 1737 spin_unlock_irqrestore(&type_c->lock, flags);1738 1739 return 0;1740}1741 1742static void extcon_rtk_type_c_complete(struct device *dev)1743{1744 /* nothing */1745}1746 1747static int extcon_rtk_type_c_suspend(struct device *dev)1748{1749 /* nothing */1750 1751 return 0;1752}1753 1754static int extcon_rtk_type_c_resume(struct device *dev)1755{1756 struct type_c_data *type_c = dev_get_drvdata(dev);1757 int ret;1758 1759 ret = extcon_rtk_type_c_init(type_c);1760 if (ret) {1761 dev_err(dev, "%s failed to init type_c\n", __func__);1762 return ret;1763 }1764 1765 return 0;1766}1767 1768static const struct dev_pm_ops extcon_rtk_type_c_pm_ops = {1769 SET_LATE_SYSTEM_SLEEP_PM_OPS(extcon_rtk_type_c_suspend, extcon_rtk_type_c_resume)1770 .prepare = extcon_rtk_type_c_prepare,1771 .complete = extcon_rtk_type_c_complete,1772};1773 1774#define DEV_PM_OPS (&extcon_rtk_type_c_pm_ops)1775#else1776#define DEV_PM_OPS NULL1777#endif /* CONFIG_PM_SLEEP */1778 1779static struct platform_driver extcon_rtk_type_c_driver = {1780 .probe = extcon_rtk_type_c_probe,1781 .remove_new = extcon_rtk_type_c_remove,1782 .driver = {1783 .name = "extcon-rtk-type_c",1784 .of_match_table = extcon_rtk_type_c_match,1785 .pm = DEV_PM_OPS,1786 },1787};1788 1789module_platform_driver(extcon_rtk_type_c_driver);1790 1791MODULE_DESCRIPTION("Realtek Extcon Type C driver");1792MODULE_AUTHOR("Stanley Chang <stanley_chang@realtek.com>");1793MODULE_LICENSE("GPL");1794