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

platform/chrome: cros_ec_typec: Get retimer handle

Where available, obtain the handle to retimer switch specified via
firmware, and update the mux configuration callsites to add retimer
support for supported modes.

Signed-off-by: Prashant Malani <pmalani@chromium.org>
Link: https://lore.kernel.org/r/20220711072333.2064341-10-pmalani@chromium.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Prashant Malani and committed by
Greg Kroah-Hartman
c76d09da 66fe238a

+41 -3
+41 -3
drivers/platform/chrome/cros_ec_typec.c
··· 20 20 #include <linux/usb/typec_altmode.h> 21 21 #include <linux/usb/typec_dp.h> 22 22 #include <linux/usb/typec_mux.h> 23 + #include <linux/usb/typec_retimer.h> 23 24 #include <linux/usb/typec_tbt.h> 24 25 #include <linux/usb/role.h> 25 26 ··· 54 53 struct usb_pd_identity c_identity; 55 54 struct typec_switch *ori_sw; 56 55 struct typec_mux *mux; 56 + struct typec_retimer *retimer; 57 57 struct usb_role_switch *role_sw; 58 58 59 59 /* Variables keeping track of switch state. */ ··· 144 142 goto mux_err; 145 143 } 146 144 145 + port->retimer = fwnode_typec_retimer_get(fwnode); 146 + if (IS_ERR(port->retimer)) { 147 + dev_dbg(dev, "Retimer handle not found.\n"); 148 + goto retimer_sw_err; 149 + } 150 + 147 151 port->ori_sw = fwnode_typec_switch_get(fwnode); 148 152 if (IS_ERR(port->ori_sw)) { 149 153 dev_dbg(dev, "Orientation switch handle not found.\n"); ··· 167 159 role_sw_err: 168 160 typec_switch_put(port->ori_sw); 169 161 ori_sw_err: 162 + typec_retimer_put(port->retimer); 163 + retimer_sw_err: 170 164 typec_mux_put(port->mux); 171 165 mux_err: 172 166 return -ENODEV; ··· 213 203 } 214 204 } 215 205 206 + /* 207 + * Map the Type-C Mux state to retimer state and call the retimer set function. We need this 208 + * because we re-use the Type-C mux state for retimers. 209 + */ 210 + static int cros_typec_retimer_set(struct typec_retimer *retimer, struct typec_mux_state state) 211 + { 212 + struct typec_retimer_state rstate = { 213 + .alt = state.alt, 214 + .mode = state.mode, 215 + .data = state.data, 216 + }; 217 + 218 + return typec_retimer_set(retimer, &rstate); 219 + } 220 + 216 221 static int cros_typec_usb_disconnect_state(struct cros_typec_port *port) 217 222 { 218 223 port->state.alt = NULL; ··· 236 211 237 212 usb_role_switch_set_role(port->role_sw, USB_ROLE_NONE); 238 213 typec_switch_set(port->ori_sw, TYPEC_ORIENTATION_NONE); 214 + cros_typec_retimer_set(port->retimer, port->state); 239 215 240 216 return typec_mux_set(port->mux, &port->state); 241 217 } ··· 407 381 408 382 static int cros_typec_usb_safe_state(struct cros_typec_port *port) 409 383 { 384 + int ret; 410 385 port->state.mode = TYPEC_STATE_SAFE; 411 386 412 - return typec_mux_set(port->mux, &port->state); 387 + ret = cros_typec_retimer_set(port->retimer, port->state); 388 + if (!ret) 389 + ret = typec_mux_set(port->mux, &port->state); 390 + 391 + return ret; 413 392 } 414 393 415 394 /* ··· 511 480 port->state.data = &dp_data; 512 481 port->state.mode = TYPEC_MODAL_STATE(ffs(pd_ctrl->dp_mode)); 513 482 514 - return typec_mux_set(port->mux, &port->state); 483 + ret = cros_typec_retimer_set(port->retimer, port->state); 484 + if (!ret) 485 + ret = typec_mux_set(port->mux, &port->state); 486 + 487 + return ret; 515 488 } 516 489 517 490 static int cros_typec_enable_usb4(struct cros_typec_data *typec, ··· 604 569 } else if (port->mux_flags & USB_PD_MUX_USB_ENABLED) { 605 570 port->state.alt = NULL; 606 571 port->state.mode = TYPEC_STATE_USB; 607 - ret = typec_mux_set(port->mux, &port->state); 572 + 573 + ret = cros_typec_retimer_set(port->retimer, port->state); 574 + if (!ret) 575 + ret = typec_mux_set(port->mux, &port->state); 608 576 } else { 609 577 dev_dbg(typec->dev, 610 578 "Unrecognized mode requested, mux flags: %x\n",