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

usb: typec-mux: ptn36502: broadcast typec state to next mux

In the Type-C graph, the ptn36502 retimer is in between the USB-C
connector and the USB3/DP combo PHY, and this PHY also requires the
USB-C mode events to properly set-up the SuperSpeed Lanes functions
to setup USB3-only, USB3 + DP Altmode or DP Altmode only on the 4 lanes.

Update the ptn36502 retimer to get an optional type-c mux on the next
endpoint, and broadcast the received mode to it.

Tested-by: Luca Weiss <luca.weiss@fairphone.com>
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://lore.kernel.org/r/20240606-topic-sm8x50-upstream-retimer-broadcast-mode-v2-3-c6f6eae479c3@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Neil Armstrong and committed by
Greg Kroah-Hartman
a96abf3b 74b64e76

+22 -2
+22 -2
drivers/usb/typec/mux/ptn36502.c
··· 67 67 struct typec_retimer *retimer; 68 68 69 69 struct typec_switch *typec_switch; 70 + struct typec_mux *typec_mux; 70 71 71 72 struct mutex lock; /* protect non-concurrent retimer & switch */ 72 73 ··· 236 235 static int ptn36502_retimer_set(struct typec_retimer *retimer, struct typec_retimer_state *state) 237 236 { 238 237 struct ptn36502 *ptn = typec_retimer_get_drvdata(retimer); 238 + struct typec_mux_state mux_state; 239 239 int ret = 0; 240 240 241 241 mutex_lock(&ptn->lock); ··· 254 252 255 253 mutex_unlock(&ptn->lock); 256 254 257 - return ret; 255 + if (ret) 256 + return ret; 257 + 258 + mux_state.alt = state->alt; 259 + mux_state.data = state->data; 260 + mux_state.mode = state->mode; 261 + 262 + return typec_mux_set(ptn->typec_mux, &mux_state); 258 263 } 259 264 260 265 static int ptn36502_detect(struct ptn36502 *ptn) ··· 330 321 return dev_err_probe(dev, PTR_ERR(ptn->typec_switch), 331 322 "Failed to acquire orientation-switch\n"); 332 323 324 + ptn->typec_mux = fwnode_typec_mux_get(dev->fwnode); 325 + if (IS_ERR(ptn->typec_mux)) { 326 + ret = dev_err_probe(dev, PTR_ERR(ptn->typec_mux), 327 + "Failed to acquire mode-switch\n"); 328 + goto err_switch_put; 329 + } 330 + 333 331 ret = regulator_enable(ptn->vdd18_supply); 334 332 if (ret) { 335 333 ret = dev_err_probe(dev, ret, "Failed to enable vdd18\n"); 336 - goto err_switch_put; 334 + goto err_mux_put; 337 335 } 338 336 339 337 ret = ptn36502_detect(ptn); ··· 381 365 err_disable_regulator: 382 366 regulator_disable(ptn->vdd18_supply); 383 367 368 + err_mux_put: 369 + typec_mux_put(ptn->typec_mux); 370 + 384 371 err_switch_put: 385 372 typec_switch_put(ptn->typec_switch); 386 373 ··· 399 380 400 381 regulator_disable(ptn->vdd18_supply); 401 382 383 + typec_mux_put(ptn->typec_mux); 402 384 typec_switch_put(ptn->typec_switch); 403 385 } 404 386