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

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

In the Type-C graph, the nb7vpq904m 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 nb7vpq904m retimer to get an optional type-c mux on the next
endpoint, and broadcast the received mode to it.

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

authored by

Neil Armstrong and committed by
Greg Kroah-Hartman
90c478ee a96abf3b

+22 -2
+22 -2
drivers/usb/typec/mux/nb7vpq904m.c
··· 69 69 70 70 bool swap_data_lanes; 71 71 struct typec_switch *typec_switch; 72 + struct typec_mux *typec_mux; 72 73 73 74 struct mutex lock; /* protect non-concurrent retimer & switch */ 74 75 ··· 276 275 static int nb7vpq904m_retimer_set(struct typec_retimer *retimer, struct typec_retimer_state *state) 277 276 { 278 277 struct nb7vpq904m *nb7 = typec_retimer_get_drvdata(retimer); 278 + struct typec_mux_state mux_state; 279 279 int ret = 0; 280 280 281 281 mutex_lock(&nb7->lock); ··· 294 292 295 293 mutex_unlock(&nb7->lock); 296 294 297 - return ret; 295 + if (ret) 296 + return ret; 297 + 298 + mux_state.alt = state->alt; 299 + mux_state.data = state->data; 300 + mux_state.mode = state->mode; 301 + 302 + return typec_mux_set(nb7->typec_mux, &mux_state); 298 303 } 299 304 300 305 static const struct regmap_config nb7_regmap = { ··· 422 413 return dev_err_probe(dev, PTR_ERR(nb7->typec_switch), 423 414 "failed to acquire orientation-switch\n"); 424 415 416 + nb7->typec_mux = fwnode_typec_mux_get(dev->fwnode); 417 + if (IS_ERR(nb7->typec_mux)) { 418 + ret = dev_err_probe(dev, PTR_ERR(nb7->typec_mux), 419 + "Failed to acquire mode-switch\n"); 420 + goto err_switch_put; 421 + } 422 + 425 423 ret = nb7vpq904m_parse_data_lanes_mapping(nb7); 426 424 if (ret) 427 - goto err_switch_put; 425 + goto err_mux_put; 428 426 429 427 ret = regulator_enable(nb7->vcc_supply); 430 428 if (ret) ··· 474 458 gpiod_set_value(nb7->enable_gpio, 0); 475 459 regulator_disable(nb7->vcc_supply); 476 460 461 + err_mux_put: 462 + typec_mux_put(nb7->typec_mux); 463 + 477 464 err_switch_put: 478 465 typec_switch_put(nb7->typec_switch); 479 466 ··· 494 475 495 476 regulator_disable(nb7->vcc_supply); 496 477 478 + typec_mux_put(nb7->typec_mux); 497 479 typec_switch_put(nb7->typec_switch); 498 480 } 499 481