1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Willsemi WUSB3801 Type-C port controller driver 4 * 5 * Copyright (C) 2022 Samuel Holland <samuel@sholland.org> 6 */ 7 8 #include <linux/i2c.h> 9 #include <linux/module.h> 10 #include <linux/regmap.h> 11 #include <linux/regulator/consumer.h> 12 #include <linux/usb/typec.h> 13 14 #define WUSB3801_REG_DEVICE_ID 0x01 15 #define WUSB3801_REG_CTRL0 0x02 16 #define WUSB3801_REG_INT 0x03 17 #define WUSB3801_REG_STAT 0x04 18 #define WUSB3801_REG_CTRL1 0x05 19 #define WUSB3801_REG_TEST00 0x06 20 #define WUSB3801_REG_TEST01 0x07 21 #define WUSB3801_REG_TEST02 0x08 22 #define WUSB3801_REG_TEST03 0x09 23 #define WUSB3801_REG_TEST04 0x0a 24 #define WUSB3801_REG_TEST05 0x0b 25 #define WUSB3801_REG_TEST06 0x0c 26 #define WUSB3801_REG_TEST07 0x0d 27 #define WUSB3801_REG_TEST08 0x0e 28 #define WUSB3801_REG_TEST09 0x0f 29 #define WUSB3801_REG_TEST0A 0x10 30 #define WUSB3801_REG_TEST0B 0x11 31 #define WUSB3801_REG_TEST0C 0x12 32 #define WUSB3801_REG_TEST0D 0x13 33 #define WUSB3801_REG_TEST0E 0x14 34 #define WUSB3801_REG_TEST0F 0x15 35 #define WUSB3801_REG_TEST10 0x16 36 #define WUSB3801_REG_TEST11 0x17 37 #define WUSB3801_REG_TEST12 0x18 38 39 #define WUSB3801_DEVICE_ID_VERSION_ID GENMASK(7, 3) 40 #define WUSB3801_DEVICE_ID_VENDOR_ID GENMASK(2, 0) 41 42 #define WUSB3801_CTRL0_DIS_ACC_SUPPORT BIT(7) 43 #define WUSB3801_CTRL0_TRY GENMASK(6, 5) 44 #define WUSB3801_CTRL0_TRY_NONE (0x0 << 5) 45 #define WUSB3801_CTRL0_TRY_SNK (0x1 << 5) 46 #define WUSB3801_CTRL0_TRY_SRC (0x2 << 5) 47 #define WUSB3801_CTRL0_CURRENT GENMASK(4, 3) /* SRC */ 48 #define WUSB3801_CTRL0_CURRENT_DEFAULT (0x0 << 3) 49 #define WUSB3801_CTRL0_CURRENT_1_5A (0x1 << 3) 50 #define WUSB3801_CTRL0_CURRENT_3_0A (0x2 << 3) 51 #define WUSB3801_CTRL0_ROLE GENMASK(2, 1) 52 #define WUSB3801_CTRL0_ROLE_SNK (0x0 << 1) 53 #define WUSB3801_CTRL0_ROLE_SRC (0x1 << 1) 54 #define WUSB3801_CTRL0_ROLE_DRP (0x2 << 1) 55 #define WUSB3801_CTRL0_INT_MASK BIT(0) 56 57 #define WUSB3801_INT_ATTACHED BIT(0) 58 #define WUSB3801_INT_DETACHED BIT(1) 59 60 #define WUSB3801_STAT_VBUS_DETECTED BIT(7) 61 #define WUSB3801_STAT_CURRENT GENMASK(6, 5) /* SNK */ 62 #define WUSB3801_STAT_CURRENT_STANDBY (0x0 << 5) 63 #define WUSB3801_STAT_CURRENT_DEFAULT (0x1 << 5) 64 #define WUSB3801_STAT_CURRENT_1_5A (0x2 << 5) 65 #define WUSB3801_STAT_CURRENT_3_0A (0x3 << 5) 66 #define WUSB3801_STAT_PARTNER GENMASK(4, 2) 67 #define WUSB3801_STAT_PARTNER_STANDBY (0x0 << 2) 68 #define WUSB3801_STAT_PARTNER_SNK (0x1 << 2) 69 #define WUSB3801_STAT_PARTNER_SRC (0x2 << 2) 70 #define WUSB3801_STAT_PARTNER_AUDIO (0x3 << 2) 71 #define WUSB3801_STAT_PARTNER_DEBUG (0x4 << 2) 72 #define WUSB3801_STAT_ORIENTATION GENMASK(1, 0) 73 #define WUSB3801_STAT_ORIENTATION_NONE (0x0 << 0) 74 #define WUSB3801_STAT_ORIENTATION_CC1 (0x1 << 0) 75 #define WUSB3801_STAT_ORIENTATION_CC2 (0x2 << 0) 76 #define WUSB3801_STAT_ORIENTATION_BOTH (0x3 << 0) 77 78 #define WUSB3801_CTRL1_SM_RESET BIT(0) 79 80 #define WUSB3801_TEST01_VENDOR_SUB_ID (BIT(8) | BIT(6)) 81 82 #define WUSB3801_TEST02_FORCE_ERR_RCY BIT(8) 83 84 #define WUSB3801_TEST0A_WAIT_VBUS BIT(5) 85 86 struct wusb3801 { 87 struct typec_capability cap; 88 struct device *dev; 89 struct typec_partner *partner; 90 struct typec_port *port; 91 struct regmap *regmap; 92 struct regulator *vbus_supply; 93 unsigned int partner_type; 94 enum typec_port_type port_type; 95 enum typec_pwr_opmode pwr_opmode; 96 bool vbus_on; 97 }; 98 99 static enum typec_role wusb3801_get_default_role(struct wusb3801 *wusb3801) 100 { 101 switch (wusb3801->port_type) { 102 case TYPEC_PORT_SRC: 103 return TYPEC_SOURCE; 104 case TYPEC_PORT_SNK: 105 return TYPEC_SINK; 106 case TYPEC_PORT_DRP: 107 default: 108 if (wusb3801->cap.prefer_role == TYPEC_SOURCE) 109 return TYPEC_SOURCE; 110 return TYPEC_SINK; 111 } 112 } 113 114 static int wusb3801_map_port_type(enum typec_port_type type) 115 { 116 switch (type) { 117 case TYPEC_PORT_SRC: 118 return WUSB3801_CTRL0_ROLE_SRC; 119 case TYPEC_PORT_SNK: 120 return WUSB3801_CTRL0_ROLE_SNK; 121 case TYPEC_PORT_DRP: 122 default: 123 return WUSB3801_CTRL0_ROLE_DRP; 124 } 125 } 126 127 static int wusb3801_map_pwr_opmode(enum typec_pwr_opmode mode) 128 { 129 switch (mode) { 130 case TYPEC_PWR_MODE_USB: 131 default: 132 return WUSB3801_CTRL0_CURRENT_DEFAULT; 133 case TYPEC_PWR_MODE_1_5A: 134 return WUSB3801_CTRL0_CURRENT_1_5A; 135 case TYPEC_PWR_MODE_3_0A: 136 return WUSB3801_CTRL0_CURRENT_3_0A; 137 } 138 } 139 140 static unsigned int wusb3801_map_try_role(int role) 141 { 142 switch (role) { 143 case TYPEC_NO_PREFERRED_ROLE: 144 default: 145 return WUSB3801_CTRL0_TRY_NONE; 146 case TYPEC_SINK: 147 return WUSB3801_CTRL0_TRY_SNK; 148 case TYPEC_SOURCE: 149 return WUSB3801_CTRL0_TRY_SRC; 150 } 151 } 152 153 static enum typec_orientation wusb3801_unmap_orientation(unsigned int status) 154 { 155 switch (status & WUSB3801_STAT_ORIENTATION) { 156 case WUSB3801_STAT_ORIENTATION_NONE: 157 case WUSB3801_STAT_ORIENTATION_BOTH: 158 default: 159 return TYPEC_ORIENTATION_NONE; 160 case WUSB3801_STAT_ORIENTATION_CC1: 161 return TYPEC_ORIENTATION_NORMAL; 162 case WUSB3801_STAT_ORIENTATION_CC2: 163 return TYPEC_ORIENTATION_REVERSE; 164 } 165 } 166 167 static enum typec_pwr_opmode wusb3801_unmap_pwr_opmode(unsigned int status) 168 { 169 switch (status & WUSB3801_STAT_CURRENT) { 170 case WUSB3801_STAT_CURRENT_STANDBY: 171 case WUSB3801_STAT_CURRENT_DEFAULT: 172 default: 173 return TYPEC_PWR_MODE_USB; 174 case WUSB3801_STAT_CURRENT_1_5A: 175 return TYPEC_PWR_MODE_1_5A; 176 case WUSB3801_STAT_CURRENT_3_0A: 177 return TYPEC_PWR_MODE_3_0A; 178 } 179 } 180 181 static int wusb3801_try_role(struct typec_port *port, int role) 182 { 183 struct wusb3801 *wusb3801 = typec_get_drvdata(port); 184 185 return regmap_update_bits(wusb3801->regmap, WUSB3801_REG_CTRL0, 186 WUSB3801_CTRL0_TRY, 187 wusb3801_map_try_role(role)); 188 } 189 190 static int wusb3801_port_type_set(struct typec_port *port, 191 enum typec_port_type type) 192 { 193 struct wusb3801 *wusb3801 = typec_get_drvdata(port); 194 int ret; 195 196 ret = regmap_update_bits(wusb3801->regmap, WUSB3801_REG_CTRL0, 197 WUSB3801_CTRL0_ROLE, 198 wusb3801_map_port_type(type)); 199 if (ret) 200 return ret; 201 202 wusb3801->port_type = type; 203 204 return 0; 205 } 206 207 static const struct typec_operations wusb3801_typec_ops = { 208 .try_role = wusb3801_try_role, 209 .port_type_set = wusb3801_port_type_set, 210 }; 211 212 static int wusb3801_hw_init(struct wusb3801 *wusb3801) 213 { 214 return regmap_write(wusb3801->regmap, WUSB3801_REG_CTRL0, 215 wusb3801_map_try_role(wusb3801->cap.prefer_role) | 216 wusb3801_map_pwr_opmode(wusb3801->pwr_opmode) | 217 wusb3801_map_port_type(wusb3801->port_type)); 218 } 219 220 static void wusb3801_hw_update(struct wusb3801 *wusb3801) 221 { 222 struct typec_port *port = wusb3801->port; 223 struct device *dev = wusb3801->dev; 224 unsigned int partner_type, status; 225 int ret; 226 227 ret = regmap_read(wusb3801->regmap, WUSB3801_REG_STAT, &status); 228 if (ret) { 229 dev_warn(dev, "Failed to read port status: %d\n", ret); 230 status = 0; 231 } 232 dev_dbg(dev, "status = 0x%02x\n", status); 233 234 partner_type = status & WUSB3801_STAT_PARTNER; 235 236 if (partner_type == WUSB3801_STAT_PARTNER_SNK) { 237 if (!wusb3801->vbus_on) { 238 ret = regulator_enable(wusb3801->vbus_supply); 239 if (ret) 240 dev_warn(dev, "Failed to enable VBUS: %d\n", ret); 241 wusb3801->vbus_on = true; 242 } 243 } else { 244 if (wusb3801->vbus_on) { 245 regulator_disable(wusb3801->vbus_supply); 246 wusb3801->vbus_on = false; 247 } 248 } 249 250 if (partner_type != wusb3801->partner_type) { 251 struct typec_partner_desc desc = {}; 252 enum typec_data_role data_role; 253 enum typec_role pwr_role = wusb3801_get_default_role(wusb3801); 254 255 switch (partner_type) { 256 case WUSB3801_STAT_PARTNER_STANDBY: 257 break; 258 case WUSB3801_STAT_PARTNER_SNK: 259 pwr_role = TYPEC_SOURCE; 260 break; 261 case WUSB3801_STAT_PARTNER_SRC: 262 pwr_role = TYPEC_SINK; 263 break; 264 case WUSB3801_STAT_PARTNER_AUDIO: 265 desc.accessory = TYPEC_ACCESSORY_AUDIO; 266 break; 267 case WUSB3801_STAT_PARTNER_DEBUG: 268 desc.accessory = TYPEC_ACCESSORY_DEBUG; 269 break; 270 } 271 272 if (wusb3801->partner) { 273 typec_unregister_partner(wusb3801->partner); 274 wusb3801->partner = NULL; 275 } 276 277 if (partner_type != WUSB3801_STAT_PARTNER_STANDBY) { 278 wusb3801->partner = typec_register_partner(port, &desc); 279 if (IS_ERR(wusb3801->partner)) 280 dev_err(dev, "Failed to register partner: %ld\n", 281 PTR_ERR(wusb3801->partner)); 282 } 283 284 data_role = pwr_role == TYPEC_SOURCE ? TYPEC_HOST : TYPEC_DEVICE; 285 typec_set_data_role(port, data_role); 286 typec_set_pwr_role(port, pwr_role); 287 typec_set_vconn_role(port, pwr_role); 288 } 289 290 typec_set_pwr_opmode(wusb3801->port, 291 partner_type == WUSB3801_STAT_PARTNER_SRC 292 ? wusb3801_unmap_pwr_opmode(status) 293 : wusb3801->pwr_opmode); 294 typec_set_orientation(wusb3801->port, 295 wusb3801_unmap_orientation(status)); 296 297 wusb3801->partner_type = partner_type; 298 } 299 300 static irqreturn_t wusb3801_irq(int irq, void *data) 301 { 302 struct wusb3801 *wusb3801 = data; 303 unsigned int dummy; 304 305 /* 306 * The interrupt register must be read in order to clear the IRQ, 307 * but all of the useful information is in the status register. 308 */ 309 regmap_read(wusb3801->regmap, WUSB3801_REG_INT, &dummy); 310 311 wusb3801_hw_update(wusb3801); 312 313 return IRQ_HANDLED; 314 } 315 316 static const struct regmap_config config = { 317 .reg_bits = 8, 318 .val_bits = 8, 319 .max_register = WUSB3801_REG_TEST12, 320 }; 321 322 static int wusb3801_probe(struct i2c_client *client) 323 { 324 struct device *dev = &client->dev; 325 struct fwnode_handle *connector; 326 struct wusb3801 *wusb3801; 327 const char *cap_str; 328 int ret; 329 330 wusb3801 = devm_kzalloc(dev, sizeof(*wusb3801), GFP_KERNEL); 331 if (!wusb3801) 332 return -ENOMEM; 333 334 i2c_set_clientdata(client, wusb3801); 335 336 wusb3801->dev = dev; 337 338 wusb3801->regmap = devm_regmap_init_i2c(client, &config); 339 if (IS_ERR(wusb3801->regmap)) 340 return PTR_ERR(wusb3801->regmap); 341 342 wusb3801->vbus_supply = devm_regulator_get(dev, "vbus"); 343 if (IS_ERR(wusb3801->vbus_supply)) 344 return PTR_ERR(wusb3801->vbus_supply); 345 346 connector = device_get_named_child_node(dev, "connector"); 347 if (!connector) 348 return -ENODEV; 349 350 ret = typec_get_fw_cap(&wusb3801->cap, connector); 351 if (ret) 352 goto err_put_connector; 353 wusb3801->port_type = wusb3801->cap.type; 354 355 ret = fwnode_property_read_string(connector, "typec-power-opmode", &cap_str); 356 if (ret) 357 goto err_put_connector; 358 359 ret = typec_find_pwr_opmode(cap_str); 360 if (ret < 0 || ret == TYPEC_PWR_MODE_PD) 361 goto err_put_connector; 362 wusb3801->pwr_opmode = ret; 363 364 /* Initialize the hardware with the devicetree settings. */ 365 ret = wusb3801_hw_init(wusb3801); 366 if (ret) 367 return ret; 368 369 wusb3801->cap.revision = USB_TYPEC_REV_1_2; 370 wusb3801->cap.accessory[0] = TYPEC_ACCESSORY_AUDIO; 371 wusb3801->cap.accessory[1] = TYPEC_ACCESSORY_DEBUG; 372 wusb3801->cap.orientation_aware = true; 373 wusb3801->cap.driver_data = wusb3801; 374 wusb3801->cap.ops = &wusb3801_typec_ops; 375 376 wusb3801->port = typec_register_port(dev, &wusb3801->cap); 377 if (IS_ERR(wusb3801->port)) { 378 ret = PTR_ERR(wusb3801->port); 379 goto err_put_connector; 380 } 381 382 /* Initialize the port attributes from the hardware state. */ 383 wusb3801_hw_update(wusb3801); 384 385 ret = request_threaded_irq(client->irq, NULL, wusb3801_irq, 386 IRQF_ONESHOT, dev_name(dev), wusb3801); 387 if (ret) 388 goto err_unregister_port; 389 390 fwnode_handle_put(connector); 391 392 return 0; 393 394 err_unregister_port: 395 typec_unregister_port(wusb3801->port); 396 err_put_connector: 397 fwnode_handle_put(connector); 398 399 return ret; 400 } 401 402 static int wusb3801_remove(struct i2c_client *client) 403 { 404 struct wusb3801 *wusb3801 = i2c_get_clientdata(client); 405 406 free_irq(client->irq, wusb3801); 407 408 if (wusb3801->partner) 409 typec_unregister_partner(wusb3801->partner); 410 typec_unregister_port(wusb3801->port); 411 412 if (wusb3801->vbus_on) 413 regulator_disable(wusb3801->vbus_supply); 414 415 return 0; 416 } 417 418 static const struct of_device_id wusb3801_of_match[] = { 419 { .compatible = "willsemi,wusb3801" }, 420 {} 421 }; 422 MODULE_DEVICE_TABLE(of, wusb3801_of_match); 423 424 static struct i2c_driver wusb3801_driver = { 425 .probe_new = wusb3801_probe, 426 .remove = wusb3801_remove, 427 .driver = { 428 .name = "wusb3801", 429 .of_match_table = wusb3801_of_match, 430 }, 431 }; 432 433 module_i2c_driver(wusb3801_driver); 434 435 MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>"); 436 MODULE_DESCRIPTION("Willsemi WUSB3801 Type-C port controller driver"); 437 MODULE_LICENSE("GPL"); 438