Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

extcon: add Realtek DHC RTD SoC Type-C driver

This patch adds the extcon driver for Realtek DHC (digital home center)
RTD SoCs type-c module. This can be used to detect whether the port is
configured as a downstream or upstream facing port. And notify the status
of extcon to listeners.

Link: https://lore.kernel.org/lkml/20230904051253.23208-2-stanley_chang@realtek.com/
Signed-off-by: Stanley Chang <stanley_chang@realtek.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>

authored by

Stanley Chang and committed by
Chanwoo Choi
8a590d73 8a749fd1

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