1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. 4 * Copyright (c) 2022, Linaro Ltd 5 */ 6 #include <linux/auxiliary_bus.h> 7 #include <linux/bitfield.h> 8 #include <linux/module.h> 9 #include <linux/of.h> 10 #include <linux/of_device.h> 11 #include <linux/mutex.h> 12 #include <linux/property.h> 13 #include <linux/soc/qcom/pdr.h> 14 #include <drm/drm_bridge.h> 15 16 #include <linux/usb/typec_altmode.h> 17 #include <linux/usb/typec_dp.h> 18 #include <linux/usb/typec_mux.h> 19 20 #include <linux/soc/qcom/pmic_glink.h> 21 22 #define PMIC_GLINK_MAX_PORTS 2 23 24 #define USBC_SC8180X_NOTIFY_IND 0x13 25 #define USBC_CMD_WRITE_REQ 0x15 26 #define USBC_NOTIFY_IND 0x16 27 28 #define ALTMODE_PAN_EN 0x10 29 #define ALTMODE_PAN_ACK 0x11 30 31 struct usbc_write_req { 32 struct pmic_glink_hdr hdr; 33 __le32 cmd; 34 __le32 arg; 35 __le32 reserved; 36 }; 37 38 #define NOTIFY_PAYLOAD_SIZE 16 39 struct usbc_notify { 40 struct pmic_glink_hdr hdr; 41 char payload[NOTIFY_PAYLOAD_SIZE]; 42 u32 reserved; 43 }; 44 45 struct usbc_sc8180x_notify { 46 struct pmic_glink_hdr hdr; 47 __le32 notification; 48 __le32 reserved[2]; 49 }; 50 51 enum pmic_glink_altmode_pin_assignment { 52 DPAM_HPD_OUT, 53 DPAM_HPD_A, 54 DPAM_HPD_B, 55 DPAM_HPD_C, 56 DPAM_HPD_D, 57 DPAM_HPD_E, 58 DPAM_HPD_F, 59 }; 60 61 struct pmic_glink_altmode; 62 63 #define work_to_altmode_port(w) container_of((w), struct pmic_glink_altmode_port, work) 64 65 struct pmic_glink_altmode_port { 66 struct pmic_glink_altmode *altmode; 67 unsigned int index; 68 69 struct typec_switch *typec_switch; 70 struct typec_mux *typec_mux; 71 struct typec_mux_state state; 72 struct typec_altmode dp_alt; 73 74 struct work_struct work; 75 76 struct drm_bridge bridge; 77 78 enum typec_orientation orientation; 79 u16 svid; 80 u8 dp_data; 81 u8 mode; 82 u8 hpd_state; 83 u8 hpd_irq; 84 }; 85 86 #define work_to_altmode(w) container_of((w), struct pmic_glink_altmode, enable_work) 87 88 struct pmic_glink_altmode { 89 struct device *dev; 90 91 unsigned int owner_id; 92 93 /* To synchronize WRITE_REQ acks */ 94 struct mutex lock; 95 96 struct completion pan_ack; 97 struct pmic_glink_client *client; 98 99 struct work_struct enable_work; 100 101 struct pmic_glink_altmode_port ports[PMIC_GLINK_MAX_PORTS]; 102 }; 103 104 static int pmic_glink_altmode_request(struct pmic_glink_altmode *altmode, u32 cmd, u32 arg) 105 { 106 struct usbc_write_req req = {}; 107 unsigned long left; 108 int ret; 109 110 /* 111 * The USBC_CMD_WRITE_REQ ack doesn't identify the request, so wait for 112 * one ack at a time. 113 */ 114 mutex_lock(&altmode->lock); 115 116 req.hdr.owner = cpu_to_le32(altmode->owner_id); 117 req.hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP); 118 req.hdr.opcode = cpu_to_le32(USBC_CMD_WRITE_REQ); 119 req.cmd = cpu_to_le32(cmd); 120 req.arg = cpu_to_le32(arg); 121 122 ret = pmic_glink_send(altmode->client, &req, sizeof(req)); 123 if (ret) { 124 dev_err(altmode->dev, "failed to send altmode request: %#x (%d)\n", cmd, ret); 125 goto out_unlock; 126 } 127 128 left = wait_for_completion_timeout(&altmode->pan_ack, 5 * HZ); 129 if (!left) { 130 dev_err(altmode->dev, "timeout waiting for altmode request ack for: %#x\n", cmd); 131 ret = -ETIMEDOUT; 132 } 133 134 out_unlock: 135 mutex_unlock(&altmode->lock); 136 return ret; 137 } 138 139 static void pmic_glink_altmode_enable_dp(struct pmic_glink_altmode *altmode, 140 struct pmic_glink_altmode_port *port, 141 u8 mode, bool hpd_state, 142 bool hpd_irq) 143 { 144 struct typec_displayport_data dp_data = {}; 145 int ret; 146 147 dp_data.status = DP_STATUS_ENABLED; 148 if (hpd_state) 149 dp_data.status |= DP_STATUS_HPD_STATE; 150 if (hpd_irq) 151 dp_data.status |= DP_STATUS_IRQ_HPD; 152 dp_data.conf = DP_CONF_SET_PIN_ASSIGN(mode); 153 154 port->state.alt = &port->dp_alt; 155 port->state.data = &dp_data; 156 port->state.mode = TYPEC_MODAL_STATE(mode); 157 158 ret = typec_mux_set(port->typec_mux, &port->state); 159 if (ret) 160 dev_err(altmode->dev, "failed to switch mux to DP\n"); 161 } 162 163 static void pmic_glink_altmode_enable_usb(struct pmic_glink_altmode *altmode, 164 struct pmic_glink_altmode_port *port) 165 { 166 int ret; 167 168 port->state.alt = NULL; 169 port->state.data = NULL; 170 port->state.mode = TYPEC_STATE_USB; 171 172 ret = typec_mux_set(port->typec_mux, &port->state); 173 if (ret) 174 dev_err(altmode->dev, "failed to switch mux to USB\n"); 175 } 176 177 static void pmic_glink_altmode_safe(struct pmic_glink_altmode *altmode, 178 struct pmic_glink_altmode_port *port) 179 { 180 int ret; 181 182 port->state.alt = NULL; 183 port->state.data = NULL; 184 port->state.mode = TYPEC_STATE_SAFE; 185 186 ret = typec_mux_set(port->typec_mux, &port->state); 187 if (ret) 188 dev_err(altmode->dev, "failed to switch mux to safe mode\n"); 189 } 190 191 static void pmic_glink_altmode_worker(struct work_struct *work) 192 { 193 struct pmic_glink_altmode_port *alt_port = work_to_altmode_port(work); 194 struct pmic_glink_altmode *altmode = alt_port->altmode; 195 196 typec_switch_set(alt_port->typec_switch, alt_port->orientation); 197 198 if (alt_port->svid == USB_TYPEC_DP_SID && alt_port->mode == 0xff) 199 pmic_glink_altmode_safe(altmode, alt_port); 200 else if (alt_port->svid == USB_TYPEC_DP_SID) 201 pmic_glink_altmode_enable_dp(altmode, alt_port, alt_port->mode, 202 alt_port->hpd_state, alt_port->hpd_irq); 203 else 204 pmic_glink_altmode_enable_usb(altmode, alt_port); 205 206 if (alt_port->hpd_state) 207 drm_bridge_hpd_notify(&alt_port->bridge, connector_status_connected); 208 else 209 drm_bridge_hpd_notify(&alt_port->bridge, connector_status_disconnected); 210 211 pmic_glink_altmode_request(altmode, ALTMODE_PAN_ACK, alt_port->index); 212 }; 213 214 static enum typec_orientation pmic_glink_altmode_orientation(unsigned int orientation) 215 { 216 if (orientation == 0) 217 return TYPEC_ORIENTATION_NORMAL; 218 else if (orientation == 1) 219 return TYPEC_ORIENTATION_REVERSE; 220 else 221 return TYPEC_ORIENTATION_NONE; 222 } 223 224 #define SC8180X_PORT_MASK 0x000000ff 225 #define SC8180X_ORIENTATION_MASK 0x0000ff00 226 #define SC8180X_MUX_MASK 0x00ff0000 227 #define SC8180X_MODE_MASK 0x3f000000 228 #define SC8180X_HPD_STATE_MASK 0x40000000 229 #define SC8180X_HPD_IRQ_MASK 0x80000000 230 231 static void pmic_glink_altmode_sc8180xp_notify(struct pmic_glink_altmode *altmode, 232 const void *data, size_t len) 233 { 234 struct pmic_glink_altmode_port *alt_port; 235 const struct usbc_sc8180x_notify *msg; 236 u32 notification; 237 u8 orientation; 238 u8 hpd_state; 239 u8 hpd_irq; 240 u16 svid; 241 u8 port; 242 u8 mode; 243 u8 mux; 244 245 if (len != sizeof(*msg)) { 246 dev_warn(altmode->dev, "invalid length of USBC_NOTIFY indication: %zd\n", len); 247 return; 248 } 249 250 msg = data; 251 notification = le32_to_cpu(msg->notification); 252 port = FIELD_GET(SC8180X_PORT_MASK, notification); 253 orientation = FIELD_GET(SC8180X_ORIENTATION_MASK, notification); 254 mux = FIELD_GET(SC8180X_MUX_MASK, notification); 255 mode = FIELD_GET(SC8180X_MODE_MASK, notification); 256 hpd_state = FIELD_GET(SC8180X_HPD_STATE_MASK, notification); 257 hpd_irq = FIELD_GET(SC8180X_HPD_IRQ_MASK, notification); 258 259 svid = mux == 2 ? USB_TYPEC_DP_SID : 0; 260 261 if (!altmode->ports[port].altmode) { 262 dev_dbg(altmode->dev, "notification on undefined port %d\n", port); 263 return; 264 } 265 266 alt_port = &altmode->ports[port]; 267 alt_port->orientation = pmic_glink_altmode_orientation(orientation); 268 alt_port->svid = svid; 269 alt_port->mode = mode; 270 alt_port->hpd_state = hpd_state; 271 alt_port->hpd_irq = hpd_irq; 272 schedule_work(&alt_port->work); 273 } 274 275 #define SC8280XP_DPAM_MASK 0x3f 276 #define SC8280XP_HPD_STATE_MASK BIT(6) 277 #define SC8280XP_HPD_IRQ_MASK BIT(7) 278 279 static void pmic_glink_altmode_sc8280xp_notify(struct pmic_glink_altmode *altmode, 280 u16 svid, const void *data, size_t len) 281 { 282 struct pmic_glink_altmode_port *alt_port; 283 const struct usbc_notify *notify; 284 u8 orientation; 285 u8 hpd_state; 286 u8 hpd_irq; 287 u8 mode; 288 u8 port; 289 290 if (len != sizeof(*notify)) { 291 dev_warn(altmode->dev, "invalid length USBC_NOTIFY_IND: %zd\n", 292 len); 293 return; 294 } 295 296 notify = data; 297 298 port = notify->payload[0]; 299 orientation = notify->payload[1]; 300 mode = FIELD_GET(SC8280XP_DPAM_MASK, notify->payload[8]) - DPAM_HPD_A; 301 hpd_state = FIELD_GET(SC8280XP_HPD_STATE_MASK, notify->payload[8]); 302 hpd_irq = FIELD_GET(SC8280XP_HPD_IRQ_MASK, notify->payload[8]); 303 304 if (!altmode->ports[port].altmode) { 305 dev_dbg(altmode->dev, "notification on undefined port %d\n", port); 306 return; 307 } 308 309 alt_port = &altmode->ports[port]; 310 alt_port->orientation = pmic_glink_altmode_orientation(orientation); 311 alt_port->svid = svid; 312 alt_port->mode = mode; 313 alt_port->hpd_state = hpd_state; 314 alt_port->hpd_irq = hpd_irq; 315 schedule_work(&alt_port->work); 316 } 317 318 static void pmic_glink_altmode_callback(const void *data, size_t len, void *priv) 319 { 320 struct pmic_glink_altmode *altmode = priv; 321 const struct pmic_glink_hdr *hdr = data; 322 u16 opcode; 323 u16 svid; 324 325 opcode = le32_to_cpu(hdr->opcode) & 0xff; 326 svid = le32_to_cpu(hdr->opcode) >> 16; 327 328 switch (opcode) { 329 case USBC_CMD_WRITE_REQ: 330 complete(&altmode->pan_ack); 331 break; 332 case USBC_NOTIFY_IND: 333 pmic_glink_altmode_sc8280xp_notify(altmode, svid, data, len); 334 break; 335 case USBC_SC8180X_NOTIFY_IND: 336 pmic_glink_altmode_sc8180xp_notify(altmode, data, len); 337 break; 338 } 339 } 340 341 static int pmic_glink_altmode_attach(struct drm_bridge *bridge, 342 enum drm_bridge_attach_flags flags) 343 { 344 return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL; 345 } 346 347 static const struct drm_bridge_funcs pmic_glink_altmode_bridge_funcs = { 348 .attach = pmic_glink_altmode_attach, 349 }; 350 351 static void pmic_glink_altmode_put_mux(void *data) 352 { 353 typec_mux_put(data); 354 } 355 356 static void pmic_glink_altmode_put_switch(void *data) 357 { 358 typec_switch_put(data); 359 } 360 361 static void pmic_glink_altmode_enable_worker(struct work_struct *work) 362 { 363 struct pmic_glink_altmode *altmode = work_to_altmode(work); 364 int ret; 365 366 ret = pmic_glink_altmode_request(altmode, ALTMODE_PAN_EN, 0); 367 if (ret) 368 dev_err(altmode->dev, "failed to request altmode notifications\n"); 369 } 370 371 static void pmic_glink_altmode_pdr_notify(void *priv, int state) 372 { 373 struct pmic_glink_altmode *altmode = priv; 374 375 if (state == SERVREG_SERVICE_STATE_UP) 376 schedule_work(&altmode->enable_work); 377 } 378 379 static const struct of_device_id pmic_glink_altmode_of_quirks[] = { 380 { .compatible = "qcom,sc8180x-pmic-glink", .data = (void *)PMIC_GLINK_OWNER_USBC }, 381 {} 382 }; 383 384 static int pmic_glink_altmode_probe(struct auxiliary_device *adev, 385 const struct auxiliary_device_id *id) 386 { 387 struct pmic_glink_altmode_port *alt_port; 388 struct pmic_glink_altmode *altmode; 389 const struct of_device_id *match; 390 struct fwnode_handle *fwnode; 391 struct device *dev = &adev->dev; 392 u32 port; 393 int ret; 394 395 altmode = devm_kzalloc(dev, sizeof(*altmode), GFP_KERNEL); 396 if (!altmode) 397 return -ENOMEM; 398 399 altmode->dev = dev; 400 401 match = of_match_device(pmic_glink_altmode_of_quirks, dev->parent); 402 if (match) 403 altmode->owner_id = (unsigned long)match->data; 404 else 405 altmode->owner_id = PMIC_GLINK_OWNER_USBC_PAN; 406 407 INIT_WORK(&altmode->enable_work, pmic_glink_altmode_enable_worker); 408 init_completion(&altmode->pan_ack); 409 mutex_init(&altmode->lock); 410 411 device_for_each_child_node(dev, fwnode) { 412 ret = fwnode_property_read_u32(fwnode, "reg", &port); 413 if (ret < 0) { 414 dev_err(dev, "missing reg property of %pOFn\n", fwnode); 415 return ret; 416 } 417 418 if (port >= ARRAY_SIZE(altmode->ports)) { 419 dev_warn(dev, "invalid connector number, ignoring\n"); 420 continue; 421 } 422 423 if (altmode->ports[port].altmode) { 424 dev_err(dev, "multiple connector definition for port %u\n", port); 425 return -EINVAL; 426 } 427 428 alt_port = &altmode->ports[port]; 429 alt_port->altmode = altmode; 430 alt_port->index = port; 431 INIT_WORK(&alt_port->work, pmic_glink_altmode_worker); 432 433 alt_port->bridge.funcs = &pmic_glink_altmode_bridge_funcs; 434 alt_port->bridge.of_node = to_of_node(fwnode); 435 alt_port->bridge.ops = DRM_BRIDGE_OP_HPD; 436 alt_port->bridge.type = DRM_MODE_CONNECTOR_USB; 437 438 ret = devm_drm_bridge_add(dev, &alt_port->bridge); 439 if (ret) 440 return ret; 441 442 alt_port->dp_alt.svid = USB_TYPEC_DP_SID; 443 alt_port->dp_alt.mode = USB_TYPEC_DP_MODE; 444 alt_port->dp_alt.active = 1; 445 446 alt_port->typec_mux = fwnode_typec_mux_get(fwnode); 447 if (IS_ERR(alt_port->typec_mux)) 448 return dev_err_probe(dev, PTR_ERR(alt_port->typec_mux), 449 "failed to acquire mode-switch for port: %d\n", 450 port); 451 452 ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_mux, 453 alt_port->typec_mux); 454 if (ret) 455 return ret; 456 457 alt_port->typec_switch = fwnode_typec_switch_get(fwnode); 458 if (IS_ERR(alt_port->typec_switch)) 459 return dev_err_probe(dev, PTR_ERR(alt_port->typec_switch), 460 "failed to acquire orientation-switch for port: %d\n", 461 port); 462 463 ret = devm_add_action_or_reset(dev, pmic_glink_altmode_put_switch, 464 alt_port->typec_switch); 465 if (ret) 466 return ret; 467 } 468 469 altmode->client = devm_pmic_glink_register_client(dev, 470 altmode->owner_id, 471 pmic_glink_altmode_callback, 472 pmic_glink_altmode_pdr_notify, 473 altmode); 474 return PTR_ERR_OR_ZERO(altmode->client); 475 } 476 477 static const struct auxiliary_device_id pmic_glink_altmode_id_table[] = { 478 { .name = "pmic_glink.altmode", }, 479 {}, 480 }; 481 MODULE_DEVICE_TABLE(auxiliary, pmic_glink_altmode_id_table); 482 483 static struct auxiliary_driver pmic_glink_altmode_driver = { 484 .name = "pmic_glink_altmode", 485 .probe = pmic_glink_altmode_probe, 486 .id_table = pmic_glink_altmode_id_table, 487 }; 488 489 module_auxiliary_driver(pmic_glink_altmode_driver); 490 491 MODULE_DESCRIPTION("Qualcomm PMIC GLINK Altmode driver"); 492 MODULE_LICENSE("GPL"); 493