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

Configure Feed

Select the types of activity you want to include in your feed.

usb: typec: ps883x: Cache register settings, not Type-C mode

Certain Type-C mode configurations may result in identical settings of
the PS8830. Check if the latter have changed instead of assuming
there's always a difference.

ps883x_set() is changed to accept a typec_retimer_state in preparation
for more work and the ps883x_sw_set() (which only handles orientation
switching) is changed to use regmap_assign_bits(), which itself does
not perform any writes if the desired value is already set.

Reviewed-by: Jack Pham <jack.pham@oss.qualcomm.com>
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20251014-topic-ps883x_usb4-v1-1-e6adb1a4296e@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Konrad Dybcio and committed by
Greg Kroah-Hartman
f83cb615 26c3af0c

+22 -19
+22 -19
drivers/usb/typec/mux/ps883x.c
··· 54 54 struct mutex lock; /* protect non-concurrent retimer & switch */ 55 55 56 56 enum typec_orientation orientation; 57 - unsigned long mode; 58 - unsigned int svid; 57 + u8 cfg0; 58 + u8 cfg1; 59 + u8 cfg2; 59 60 }; 60 61 61 62 static int ps883x_configure(struct ps883x_retimer *retimer, int cfg0, ··· 64 63 { 65 64 struct device *dev = &retimer->client->dev; 66 65 int ret; 66 + 67 + if (retimer->cfg0 == cfg0 && retimer->cfg1 == cfg1 && retimer->cfg2 == cfg2) 68 + return 0; 67 69 68 70 ret = regmap_write(retimer->regmap, REG_USB_PORT_CONN_STATUS_0, cfg0); 69 71 if (ret) { ··· 86 82 return ret; 87 83 } 88 84 85 + retimer->cfg0 = cfg0; 86 + retimer->cfg1 = cfg1; 87 + retimer->cfg2 = cfg2; 88 + 89 89 return 0; 90 90 } 91 91 92 - static int ps883x_set(struct ps883x_retimer *retimer) 92 + static int ps883x_set(struct ps883x_retimer *retimer, struct typec_retimer_state *state) 93 93 { 94 94 int cfg0 = CONN_STATUS_0_CONNECTION_PRESENT; 95 95 int cfg1 = 0x00; 96 96 int cfg2 = 0x00; 97 97 98 98 if (retimer->orientation == TYPEC_ORIENTATION_NONE || 99 - retimer->mode == TYPEC_STATE_SAFE) { 99 + state->mode == TYPEC_STATE_SAFE) { 100 100 return ps883x_configure(retimer, cfg0, cfg1, cfg2); 101 101 } 102 102 103 - if (retimer->mode != TYPEC_STATE_USB && retimer->svid != USB_TYPEC_DP_SID) 103 + if (state->alt && state->alt->svid != USB_TYPEC_DP_SID) 104 104 return -EINVAL; 105 105 106 106 if (retimer->orientation == TYPEC_ORIENTATION_REVERSE) 107 107 cfg0 |= CONN_STATUS_0_ORIENTATION_REVERSED; 108 108 109 - switch (retimer->mode) { 109 + switch (state->mode) { 110 110 case TYPEC_STATE_USB: 111 111 cfg0 |= CONN_STATUS_0_USB_3_1_CONNECTED; 112 112 break; ··· 157 149 if (retimer->orientation != orientation) { 158 150 retimer->orientation = orientation; 159 151 160 - ret = ps883x_set(retimer); 152 + ret = regmap_assign_bits(retimer->regmap, REG_USB_PORT_CONN_STATUS_0, 153 + CONN_STATUS_0_ORIENTATION_REVERSED, 154 + orientation == TYPEC_ORIENTATION_REVERSE); 155 + if (ret) { 156 + dev_err(&retimer->client->dev, "failed to set orientation: %d\n", ret); 157 + return ret; 158 + } 161 159 } 162 160 163 161 mutex_unlock(&retimer->lock); ··· 179 165 int ret = 0; 180 166 181 167 mutex_lock(&retimer->lock); 182 - 183 - if (state->mode != retimer->mode) { 184 - retimer->mode = state->mode; 185 - 186 - if (state->alt) 187 - retimer->svid = state->alt->svid; 188 - else 189 - retimer->svid = 0; 190 - 191 - ret = ps883x_set(retimer); 192 - } 193 - 168 + ret = ps883x_set(retimer, state); 194 169 mutex_unlock(&retimer->lock); 195 170 196 171 if (ret)