* [PATCH 0/3] typec: support Audio Accessory mode on FSA4480
@ 2023-06-14 13:10 Neil Armstrong
2023-06-14 13:10 ` [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change Neil Armstrong
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Neil Armstrong @ 2023-06-14 13:10 UTC (permalink / raw)
To: Heikki Krogerus, Greg Kroah-Hartman
Cc: Krzysztof Kozlowski, linux-usb, linux-kernel, linux-arm-msm,
Neil Armstrong
This serie enables Audio Accessory mode support on the FSA4480
USB Type-C Analog Audio Switch.
In order to get the proper MUX state, also let's make UCSI
call type_set_mode() on partner changes to propagate the
Accessory and USB modes.
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
Neil Armstrong (3):
usb: typec: ucsi: call typec_set_mode on non-altmode partner change
usb: typec: fsa4480: rework mux & switch setup to handle more states
usb: typec: fsa4480: add support for Audio Accessory Mode
drivers/usb/typec/mux/fsa4480.c | 126 +++++++++++++++++++++++++++++-----------
drivers/usb/typec/ucsi/ucsi.c | 17 ++++++
2 files changed, 108 insertions(+), 35 deletions(-)
---
base-commit: 858fd168a95c5b9669aac8db6c14a9aeab446375
change-id: 20230614-topic-sm8550-upstream-type-c-audio-2ccdf6d18896
Best regards,
--
Neil Armstrong <neil.armstrong@linaro.org>
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change 2023-06-14 13:10 [PATCH 0/3] typec: support Audio Accessory mode on FSA4480 Neil Armstrong @ 2023-06-14 13:10 ` Neil Armstrong 2023-06-14 13:11 ` Krzysztof Kozlowski 2023-06-26 8:12 ` Heikki Krogerus 2023-06-14 13:10 ` [PATCH 2/3] usb: typec: fsa4480: rework mux & switch setup to handle more states Neil Armstrong 2023-06-14 13:10 ` [PATCH 3/3] usb: typec: fsa4480: add support for Audio Accessory Mode Neil Armstrong 2 siblings, 2 replies; 12+ messages in thread From: Neil Armstrong @ 2023-06-14 13:10 UTC (permalink / raw) To: Heikki Krogerus, Greg Kroah-Hartman Cc: Krzysztof Kozlowski, linux-usb, linux-kernel, linux-arm-msm, Neil Armstrong Add support for calling typec_set_mode() for the DEBUG, AUDIO accessory modes. Let's also call typec_set_mode() for USB as default and SAFE when partner is disconnected. The USB state is only called when ALT mode is specifically not specified by the partner status flags in order to leave the altmode handlers setup the proper mode to switches, muxes and retimers. Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> --- drivers/usb/typec/ucsi/ucsi.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 2b472ec01dc4..44f43cdea5c1 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -809,6 +809,23 @@ static void ucsi_partner_change(struct ucsi_connector *con) break; } + if (con->status.flags & UCSI_CONSTAT_CONNECTED) { + switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { + case UCSI_CONSTAT_PARTNER_TYPE_DEBUG: + typec_set_mode(con->port, TYPEC_MODE_DEBUG); + break; + case UCSI_CONSTAT_PARTNER_TYPE_AUDIO: + typec_set_mode(con->port, TYPEC_MODE_AUDIO); + break; + default: + if (UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) == + UCSI_CONSTAT_PARTNER_FLAG_USB) + typec_set_mode(con->port, TYPEC_STATE_USB); + } + } else { + typec_set_mode(con->port, TYPEC_STATE_SAFE); + } + /* Only notify USB controller if partner supports USB data */ if (!(UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) & UCSI_CONSTAT_PARTNER_FLAG_USB)) u_role = USB_ROLE_NONE; -- 2.34.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change 2023-06-14 13:10 ` [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change Neil Armstrong @ 2023-06-14 13:11 ` Krzysztof Kozlowski 2023-06-26 8:12 ` Heikki Krogerus 1 sibling, 0 replies; 12+ messages in thread From: Krzysztof Kozlowski @ 2023-06-14 13:11 UTC (permalink / raw) To: Neil Armstrong, Heikki Krogerus, Greg Kroah-Hartman Cc: linux-usb, linux-kernel, linux-arm-msm On 14/06/2023 15:10, Neil Armstrong wrote: > Add support for calling typec_set_mode() for the DEBUG, AUDIO > accessory modes. > > Let's also call typec_set_mode() for USB as default and SAFE > when partner is disconnected. > > The USB state is only called when ALT mode is specifically > not specified by the partner status flags in order > to leave the altmode handlers setup the proper mode to > switches, muxes and retimers. > Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Best regards, Krzysztof ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change 2023-06-14 13:10 ` [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change Neil Armstrong 2023-06-14 13:11 ` Krzysztof Kozlowski @ 2023-06-26 8:12 ` Heikki Krogerus 2023-06-26 13:23 ` Neil Armstrong 1 sibling, 1 reply; 12+ messages in thread From: Heikki Krogerus @ 2023-06-26 8:12 UTC (permalink / raw) To: Neil Armstrong Cc: Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb, linux-kernel, linux-arm-msm Hi Neil, Sorry to keep you waiting. On Wed, Jun 14, 2023 at 03:10:39PM +0200, Neil Armstrong wrote: > Add support for calling typec_set_mode() for the DEBUG, AUDIO > accessory modes. > > Let's also call typec_set_mode() for USB as default and SAFE > when partner is disconnected. > > The USB state is only called when ALT mode is specifically > not specified by the partner status flags in order > to leave the altmode handlers setup the proper mode to > switches, muxes and retimers. > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> > --- > drivers/usb/typec/ucsi/ucsi.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c > index 2b472ec01dc4..44f43cdea5c1 100644 > --- a/drivers/usb/typec/ucsi/ucsi.c > +++ b/drivers/usb/typec/ucsi/ucsi.c > @@ -809,6 +809,23 @@ static void ucsi_partner_change(struct ucsi_connector *con) > break; > } > > + if (con->status.flags & UCSI_CONSTAT_CONNECTED) { > + switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { > + case UCSI_CONSTAT_PARTNER_TYPE_DEBUG: > + typec_set_mode(con->port, TYPEC_MODE_DEBUG); > + break; > + case UCSI_CONSTAT_PARTNER_TYPE_AUDIO: > + typec_set_mode(con->port, TYPEC_MODE_AUDIO); > + break; > + default: > + if (UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) == > + UCSI_CONSTAT_PARTNER_FLAG_USB) > + typec_set_mode(con->port, TYPEC_STATE_USB); > + } > + } else { > + typec_set_mode(con->port, TYPEC_STATE_SAFE); > + } Can you do that (set safe mode) in ucsi_unregister_partner() instead? thanks, -- heikki ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change 2023-06-26 8:12 ` Heikki Krogerus @ 2023-06-26 13:23 ` Neil Armstrong 2023-06-26 14:43 ` Greg Kroah-Hartman 0 siblings, 1 reply; 12+ messages in thread From: Neil Armstrong @ 2023-06-26 13:23 UTC (permalink / raw) To: Heikki Krogerus Cc: Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb, linux-kernel, linux-arm-msm Hi, On 26/06/2023 10:12, Heikki Krogerus wrote: > Hi Neil, > > Sorry to keep you waiting. No problem, thanks for reviewing my patches! > > On Wed, Jun 14, 2023 at 03:10:39PM +0200, Neil Armstrong wrote: >> Add support for calling typec_set_mode() for the DEBUG, AUDIO >> accessory modes. >> >> Let's also call typec_set_mode() for USB as default and SAFE >> when partner is disconnected. >> >> The USB state is only called when ALT mode is specifically >> not specified by the partner status flags in order >> to leave the altmode handlers setup the proper mode to >> switches, muxes and retimers. >> >> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> >> --- >> drivers/usb/typec/ucsi/ucsi.c | 17 +++++++++++++++++ >> 1 file changed, 17 insertions(+) >> >> diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c >> index 2b472ec01dc4..44f43cdea5c1 100644 >> --- a/drivers/usb/typec/ucsi/ucsi.c >> +++ b/drivers/usb/typec/ucsi/ucsi.c >> @@ -809,6 +809,23 @@ static void ucsi_partner_change(struct ucsi_connector *con) >> break; >> } >> >> + if (con->status.flags & UCSI_CONSTAT_CONNECTED) { >> + switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { >> + case UCSI_CONSTAT_PARTNER_TYPE_DEBUG: >> + typec_set_mode(con->port, TYPEC_MODE_DEBUG); >> + break; >> + case UCSI_CONSTAT_PARTNER_TYPE_AUDIO: >> + typec_set_mode(con->port, TYPEC_MODE_AUDIO); >> + break; >> + default: >> + if (UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) == >> + UCSI_CONSTAT_PARTNER_FLAG_USB) >> + typec_set_mode(con->port, TYPEC_STATE_USB); >> + } >> + } else { >> + typec_set_mode(con->port, TYPEC_STATE_SAFE); >> + } > > Can you do that (set safe mode) in ucsi_unregister_partner() instead? It seems greg already landed the patch into usb-next, but I can send a fix to move it to unregister Neil > > thanks, > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change 2023-06-26 13:23 ` Neil Armstrong @ 2023-06-26 14:43 ` Greg Kroah-Hartman 0 siblings, 0 replies; 12+ messages in thread From: Greg Kroah-Hartman @ 2023-06-26 14:43 UTC (permalink / raw) To: Neil Armstrong Cc: Heikki Krogerus, Krzysztof Kozlowski, linux-usb, linux-kernel, linux-arm-msm On Mon, Jun 26, 2023 at 03:23:11PM +0200, Neil Armstrong wrote: > Hi, > > On 26/06/2023 10:12, Heikki Krogerus wrote: > > Hi Neil, > > > > Sorry to keep you waiting. > > No problem, thanks for reviewing my patches! > > > > > On Wed, Jun 14, 2023 at 03:10:39PM +0200, Neil Armstrong wrote: > > > Add support for calling typec_set_mode() for the DEBUG, AUDIO > > > accessory modes. > > > > > > Let's also call typec_set_mode() for USB as default and SAFE > > > when partner is disconnected. > > > > > > The USB state is only called when ALT mode is specifically > > > not specified by the partner status flags in order > > > to leave the altmode handlers setup the proper mode to > > > switches, muxes and retimers. > > > > > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> > > > --- > > > drivers/usb/typec/ucsi/ucsi.c | 17 +++++++++++++++++ > > > 1 file changed, 17 insertions(+) > > > > > > diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c > > > index 2b472ec01dc4..44f43cdea5c1 100644 > > > --- a/drivers/usb/typec/ucsi/ucsi.c > > > +++ b/drivers/usb/typec/ucsi/ucsi.c > > > @@ -809,6 +809,23 @@ static void ucsi_partner_change(struct ucsi_connector *con) > > > break; > > > } > > > + if (con->status.flags & UCSI_CONSTAT_CONNECTED) { > > > + switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) { > > > + case UCSI_CONSTAT_PARTNER_TYPE_DEBUG: > > > + typec_set_mode(con->port, TYPEC_MODE_DEBUG); > > > + break; > > > + case UCSI_CONSTAT_PARTNER_TYPE_AUDIO: > > > + typec_set_mode(con->port, TYPEC_MODE_AUDIO); > > > + break; > > > + default: > > > + if (UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) == > > > + UCSI_CONSTAT_PARTNER_FLAG_USB) > > > + typec_set_mode(con->port, TYPEC_STATE_USB); > > > + } > > > + } else { > > > + typec_set_mode(con->port, TYPEC_STATE_SAFE); > > > + } > > > > Can you do that (set safe mode) in ucsi_unregister_partner() instead? > > It seems greg already landed the patch into usb-next, but I can send a fix to > move it to unregister Yes please. ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/3] usb: typec: fsa4480: rework mux & switch setup to handle more states 2023-06-14 13:10 [PATCH 0/3] typec: support Audio Accessory mode on FSA4480 Neil Armstrong 2023-06-14 13:10 ` [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change Neil Armstrong @ 2023-06-14 13:10 ` Neil Armstrong 2023-06-14 13:12 ` Krzysztof Kozlowski 2023-06-26 8:30 ` Heikki Krogerus 2023-06-14 13:10 ` [PATCH 3/3] usb: typec: fsa4480: add support for Audio Accessory Mode Neil Armstrong 2 siblings, 2 replies; 12+ messages in thread From: Neil Armstrong @ 2023-06-14 13:10 UTC (permalink / raw) To: Heikki Krogerus, Greg Kroah-Hartman Cc: Krzysztof Kozlowski, linux-usb, linux-kernel, linux-arm-msm, Neil Armstrong In order to handle the Audio Accessory mode, refactor the mux and switch setup in a single function. The refactor will help add new states and make the process simpler to understand. Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> --- drivers/usb/typec/mux/fsa4480.c | 111 +++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 36 deletions(-) diff --git a/drivers/usb/typec/mux/fsa4480.c b/drivers/usb/typec/mux/fsa4480.c index d6495e533e58..b2913594a58f 100644 --- a/drivers/usb/typec/mux/fsa4480.c +++ b/drivers/usb/typec/mux/fsa4480.c @@ -46,8 +46,11 @@ struct fsa4480 { struct regmap *regmap; + enum typec_orientation orientation; + unsigned long mode; + unsigned int svid; + u8 cur_enable; - u8 cur_select; }; static const struct regmap_config fsa4480_regmap_config = { @@ -58,19 +61,42 @@ static const struct regmap_config fsa4480_regmap_config = { .disable_locking = true, }; -static int fsa4480_switch_set(struct typec_switch_dev *sw, - enum typec_orientation orientation) +static int fsa4480_set(struct fsa4480 *fsa) { - struct fsa4480 *fsa = typec_switch_get_drvdata(sw); - u8 new_sel; - - mutex_lock(&fsa->lock); - new_sel = FSA4480_SEL_USB; - if (orientation == TYPEC_ORIENTATION_REVERSE) - new_sel |= FSA4480_SEL_SBU_REVERSE; - - if (new_sel == fsa->cur_select) - goto out_unlock; + bool reverse = (fsa->orientation == TYPEC_ORIENTATION_REVERSE); + u8 enable = FSA4480_ENABLE_DEVICE; + u8 sel = 0; + + /* USB Mode */ + if (fsa->mode < TYPEC_STATE_MODAL || + (!fsa->svid && (fsa->mode == TYPEC_MODE_USB2 || + fsa->mode == TYPEC_MODE_USB3))) { + enable |= FSA4480_ENABLE_USB; + sel = FSA4480_SEL_USB; + } else if (fsa->svid) { + switch (fsa->mode) { + /* DP Only */ + case TYPEC_DP_STATE_C: + case TYPEC_DP_STATE_E: + enable |= FSA4480_ENABLE_SBU; + if (reverse) + sel = FSA4480_SEL_SBU_REVERSE; + break; + + /* DP + USB */ + case TYPEC_DP_STATE_D: + case TYPEC_DP_STATE_F: + enable |= FSA4480_ENABLE_USB | FSA4480_ENABLE_SBU; + sel = FSA4480_SEL_USB; + if (reverse) + sel |= FSA4480_SEL_SBU_REVERSE; + break; + + default: + return -EOPNOTSUPP; + } + } else + return -EOPNOTSUPP; if (fsa->cur_enable & FSA4480_ENABLE_SBU) { /* Disable SBU output while re-configuring the switch */ @@ -81,48 +107,59 @@ static int fsa4480_switch_set(struct typec_switch_dev *sw, usleep_range(35, 1000); } - regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, new_sel); - fsa->cur_select = new_sel; - - if (fsa->cur_enable & FSA4480_ENABLE_SBU) { - regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, fsa->cur_enable); + regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, sel); + regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, enable); + if (enable & FSA4480_ENABLE_SBU) { /* 15us to allow the SBU switch to turn on again */ usleep_range(15, 1000); } -out_unlock: - mutex_unlock(&fsa->lock); + fsa->cur_enable = enable; return 0; } +static int fsa4480_switch_set(struct typec_switch_dev *sw, + enum typec_orientation orientation) +{ + struct fsa4480 *fsa = typec_switch_get_drvdata(sw); + int ret = 0; + + mutex_lock(&fsa->lock); + + if (fsa->orientation != orientation) { + fsa->orientation = orientation; + + ret = fsa4480_set(fsa); + } + + mutex_unlock(&fsa->lock); + + return ret; +} + static int fsa4480_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) { struct fsa4480 *fsa = typec_mux_get_drvdata(mux); - u8 new_enable; + int ret = 0; mutex_lock(&fsa->lock); - new_enable = FSA4480_ENABLE_DEVICE | FSA4480_ENABLE_USB; - if (state->mode >= TYPEC_DP_STATE_A) - new_enable |= FSA4480_ENABLE_SBU; + if (fsa->mode != state->mode) { + fsa->mode = state->mode; - if (new_enable == fsa->cur_enable) - goto out_unlock; + if (state->alt) + fsa->svid = state->alt->svid; + else + fsa->svid = 0; // No SVID - regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, new_enable); - fsa->cur_enable = new_enable; - - if (new_enable & FSA4480_ENABLE_SBU) { - /* 15us to allow the SBU switch to turn off */ - usleep_range(15, 1000); + ret = fsa4480_set(fsa); } -out_unlock: mutex_unlock(&fsa->lock); - return 0; + return ret; } static int fsa4480_probe(struct i2c_client *client) @@ -143,8 +180,10 @@ static int fsa4480_probe(struct i2c_client *client) if (IS_ERR(fsa->regmap)) return dev_err_probe(dev, PTR_ERR(fsa->regmap), "failed to initialize regmap\n"); + /* Safe mode */ fsa->cur_enable = FSA4480_ENABLE_DEVICE | FSA4480_ENABLE_USB; - fsa->cur_select = FSA4480_SEL_USB; + fsa->mode = TYPEC_STATE_SAFE; + fsa->orientation = TYPEC_ORIENTATION_NONE; /* set default settings */ regmap_write(fsa->regmap, FSA4480_SLOW_L, 0x00); @@ -156,7 +195,7 @@ static int fsa4480_probe(struct i2c_client *client) regmap_write(fsa->regmap, FSA4480_DELAY_L_MIC, 0x00); regmap_write(fsa->regmap, FSA4480_DELAY_L_SENSE, 0x00); regmap_write(fsa->regmap, FSA4480_DELAY_L_AGND, 0x09); - regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, fsa->cur_select); + regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, FSA4480_SEL_USB); regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, fsa->cur_enable); sw_desc.drvdata = fsa; -- 2.34.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 2/3] usb: typec: fsa4480: rework mux & switch setup to handle more states 2023-06-14 13:10 ` [PATCH 2/3] usb: typec: fsa4480: rework mux & switch setup to handle more states Neil Armstrong @ 2023-06-14 13:12 ` Krzysztof Kozlowski 2023-06-26 8:30 ` Heikki Krogerus 1 sibling, 0 replies; 12+ messages in thread From: Krzysztof Kozlowski @ 2023-06-14 13:12 UTC (permalink / raw) To: Neil Armstrong, Heikki Krogerus, Greg Kroah-Hartman Cc: linux-usb, linux-kernel, linux-arm-msm On 14/06/2023 15:10, Neil Armstrong wrote: > In order to handle the Audio Accessory mode, refactor the mux > and switch setup in a single function. > > The refactor will help add new states and make the process > simpler to understand. > Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Best regards, Krzysztof ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/3] usb: typec: fsa4480: rework mux & switch setup to handle more states 2023-06-14 13:10 ` [PATCH 2/3] usb: typec: fsa4480: rework mux & switch setup to handle more states Neil Armstrong 2023-06-14 13:12 ` Krzysztof Kozlowski @ 2023-06-26 8:30 ` Heikki Krogerus 1 sibling, 0 replies; 12+ messages in thread From: Heikki Krogerus @ 2023-06-26 8:30 UTC (permalink / raw) To: Neil Armstrong Cc: Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb, linux-kernel, linux-arm-msm On Wed, Jun 14, 2023 at 03:10:40PM +0200, Neil Armstrong wrote: > In order to handle the Audio Accessory mode, refactor the mux > and switch setup in a single function. > > The refactor will help add new states and make the process > simpler to understand. > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > drivers/usb/typec/mux/fsa4480.c | 111 +++++++++++++++++++++++++++------------- > 1 file changed, 75 insertions(+), 36 deletions(-) > > diff --git a/drivers/usb/typec/mux/fsa4480.c b/drivers/usb/typec/mux/fsa4480.c > index d6495e533e58..b2913594a58f 100644 > --- a/drivers/usb/typec/mux/fsa4480.c > +++ b/drivers/usb/typec/mux/fsa4480.c > @@ -46,8 +46,11 @@ struct fsa4480 { > > struct regmap *regmap; > > + enum typec_orientation orientation; > + unsigned long mode; > + unsigned int svid; > + > u8 cur_enable; > - u8 cur_select; > }; > > static const struct regmap_config fsa4480_regmap_config = { > @@ -58,19 +61,42 @@ static const struct regmap_config fsa4480_regmap_config = { > .disable_locking = true, > }; > > -static int fsa4480_switch_set(struct typec_switch_dev *sw, > - enum typec_orientation orientation) > +static int fsa4480_set(struct fsa4480 *fsa) > { > - struct fsa4480 *fsa = typec_switch_get_drvdata(sw); > - u8 new_sel; > - > - mutex_lock(&fsa->lock); > - new_sel = FSA4480_SEL_USB; > - if (orientation == TYPEC_ORIENTATION_REVERSE) > - new_sel |= FSA4480_SEL_SBU_REVERSE; > - > - if (new_sel == fsa->cur_select) > - goto out_unlock; > + bool reverse = (fsa->orientation == TYPEC_ORIENTATION_REVERSE); > + u8 enable = FSA4480_ENABLE_DEVICE; > + u8 sel = 0; > + > + /* USB Mode */ > + if (fsa->mode < TYPEC_STATE_MODAL || > + (!fsa->svid && (fsa->mode == TYPEC_MODE_USB2 || > + fsa->mode == TYPEC_MODE_USB3))) { > + enable |= FSA4480_ENABLE_USB; > + sel = FSA4480_SEL_USB; > + } else if (fsa->svid) { > + switch (fsa->mode) { > + /* DP Only */ > + case TYPEC_DP_STATE_C: > + case TYPEC_DP_STATE_E: > + enable |= FSA4480_ENABLE_SBU; > + if (reverse) > + sel = FSA4480_SEL_SBU_REVERSE; > + break; > + > + /* DP + USB */ > + case TYPEC_DP_STATE_D: > + case TYPEC_DP_STATE_F: > + enable |= FSA4480_ENABLE_USB | FSA4480_ENABLE_SBU; > + sel = FSA4480_SEL_USB; > + if (reverse) > + sel |= FSA4480_SEL_SBU_REVERSE; > + break; > + > + default: > + return -EOPNOTSUPP; > + } > + } else > + return -EOPNOTSUPP; > > if (fsa->cur_enable & FSA4480_ENABLE_SBU) { > /* Disable SBU output while re-configuring the switch */ > @@ -81,48 +107,59 @@ static int fsa4480_switch_set(struct typec_switch_dev *sw, > usleep_range(35, 1000); > } > > - regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, new_sel); > - fsa->cur_select = new_sel; > - > - if (fsa->cur_enable & FSA4480_ENABLE_SBU) { > - regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, fsa->cur_enable); > + regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, sel); > + regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, enable); > > + if (enable & FSA4480_ENABLE_SBU) { > /* 15us to allow the SBU switch to turn on again */ > usleep_range(15, 1000); > } > > -out_unlock: > - mutex_unlock(&fsa->lock); > + fsa->cur_enable = enable; > > return 0; > } > > +static int fsa4480_switch_set(struct typec_switch_dev *sw, > + enum typec_orientation orientation) > +{ > + struct fsa4480 *fsa = typec_switch_get_drvdata(sw); > + int ret = 0; > + > + mutex_lock(&fsa->lock); > + > + if (fsa->orientation != orientation) { > + fsa->orientation = orientation; > + > + ret = fsa4480_set(fsa); > + } > + > + mutex_unlock(&fsa->lock); > + > + return ret; > +} > + > static int fsa4480_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) > { > struct fsa4480 *fsa = typec_mux_get_drvdata(mux); > - u8 new_enable; > + int ret = 0; > > mutex_lock(&fsa->lock); > > - new_enable = FSA4480_ENABLE_DEVICE | FSA4480_ENABLE_USB; > - if (state->mode >= TYPEC_DP_STATE_A) > - new_enable |= FSA4480_ENABLE_SBU; > + if (fsa->mode != state->mode) { > + fsa->mode = state->mode; > > - if (new_enable == fsa->cur_enable) > - goto out_unlock; > + if (state->alt) > + fsa->svid = state->alt->svid; > + else > + fsa->svid = 0; // No SVID > > - regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, new_enable); > - fsa->cur_enable = new_enable; > - > - if (new_enable & FSA4480_ENABLE_SBU) { > - /* 15us to allow the SBU switch to turn off */ > - usleep_range(15, 1000); > + ret = fsa4480_set(fsa); > } > > -out_unlock: > mutex_unlock(&fsa->lock); > > - return 0; > + return ret; > } > > static int fsa4480_probe(struct i2c_client *client) > @@ -143,8 +180,10 @@ static int fsa4480_probe(struct i2c_client *client) > if (IS_ERR(fsa->regmap)) > return dev_err_probe(dev, PTR_ERR(fsa->regmap), "failed to initialize regmap\n"); > > + /* Safe mode */ > fsa->cur_enable = FSA4480_ENABLE_DEVICE | FSA4480_ENABLE_USB; > - fsa->cur_select = FSA4480_SEL_USB; > + fsa->mode = TYPEC_STATE_SAFE; > + fsa->orientation = TYPEC_ORIENTATION_NONE; > > /* set default settings */ > regmap_write(fsa->regmap, FSA4480_SLOW_L, 0x00); > @@ -156,7 +195,7 @@ static int fsa4480_probe(struct i2c_client *client) > regmap_write(fsa->regmap, FSA4480_DELAY_L_MIC, 0x00); > regmap_write(fsa->regmap, FSA4480_DELAY_L_SENSE, 0x00); > regmap_write(fsa->regmap, FSA4480_DELAY_L_AGND, 0x09); > - regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, fsa->cur_select); > + regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, FSA4480_SEL_USB); > regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, fsa->cur_enable); > > sw_desc.drvdata = fsa; > > -- > 2.34.1 -- heikki ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 3/3] usb: typec: fsa4480: add support for Audio Accessory Mode 2023-06-14 13:10 [PATCH 0/3] typec: support Audio Accessory mode on FSA4480 Neil Armstrong 2023-06-14 13:10 ` [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change Neil Armstrong 2023-06-14 13:10 ` [PATCH 2/3] usb: typec: fsa4480: rework mux & switch setup to handle more states Neil Armstrong @ 2023-06-14 13:10 ` Neil Armstrong 2023-06-14 13:12 ` Krzysztof Kozlowski 2023-06-26 8:32 ` Heikki Krogerus 2 siblings, 2 replies; 12+ messages in thread From: Neil Armstrong @ 2023-06-14 13:10 UTC (permalink / raw) To: Heikki Krogerus, Greg Kroah-Hartman Cc: Krzysztof Kozlowski, linux-usb, linux-kernel, linux-arm-msm, Neil Armstrong The FSA4480 Type-C switch supports switching the Audio R/L, AGND and MIC signals to the USB-C DP/DM and SBU1/2 to support the Audio Accessory Mode. The FSA4480 has an integrated Audio jack detection mechanism to automatically mux the AGND, MIX and Sense to the correct SBU lines to support 3 pole and both 4 pole TRRS pinouts. Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> --- drivers/usb/typec/mux/fsa4480.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/usb/typec/mux/fsa4480.c b/drivers/usb/typec/mux/fsa4480.c index b2913594a58f..45f5683b7d81 100644 --- a/drivers/usb/typec/mux/fsa4480.c +++ b/drivers/usb/typec/mux/fsa4480.c @@ -25,15 +25,24 @@ #define FSA4480_DELAY_L_MIC 0x0e #define FSA4480_DELAY_L_SENSE 0x0f #define FSA4480_DELAY_L_AGND 0x10 +#define FSA4480_FUNCTION_ENABLE 0x12 #define FSA4480_RESET 0x1e #define FSA4480_MAX_REGISTER 0x1f #define FSA4480_ENABLE_DEVICE BIT(7) #define FSA4480_ENABLE_SBU GENMASK(6, 5) #define FSA4480_ENABLE_USB GENMASK(4, 3) +#define FSA4480_ENABLE_SENSE BIT(2) +#define FSA4480_ENABLE_MIC BIT(1) +#define FSA4480_ENABLE_AGND BIT(0) #define FSA4480_SEL_SBU_REVERSE GENMASK(6, 5) #define FSA4480_SEL_USB GENMASK(4, 3) +#define FSA4480_SEL_SENSE BIT(2) +#define FSA4480_SEL_MIC BIT(1) +#define FSA4480_SEL_AGND BIT(0) + +#define FSA4480_ENABLE_AUTO_JACK_DETECT BIT(0) struct fsa4480 { struct i2c_client *client; @@ -95,6 +104,9 @@ static int fsa4480_set(struct fsa4480 *fsa) default: return -EOPNOTSUPP; } + } else if (fsa->mode == TYPEC_MODE_AUDIO) { + /* Audio Accessory Mode, setup to auto Jack Detection */ + enable |= FSA4480_ENABLE_USB | FSA4480_ENABLE_AGND; } else return -EOPNOTSUPP; @@ -110,6 +122,11 @@ static int fsa4480_set(struct fsa4480 *fsa) regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, sel); regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, enable); + /* Start AUDIO JACK DETECTION to setup MIC, AGND & Sense muxes */ + if (enable & FSA4480_ENABLE_AGND) + regmap_write(fsa->regmap, FSA4480_FUNCTION_ENABLE, + FSA4480_ENABLE_AUTO_JACK_DETECT); + if (enable & FSA4480_ENABLE_SBU) { /* 15us to allow the SBU switch to turn on again */ usleep_range(15, 1000); -- 2.34.1 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] usb: typec: fsa4480: add support for Audio Accessory Mode 2023-06-14 13:10 ` [PATCH 3/3] usb: typec: fsa4480: add support for Audio Accessory Mode Neil Armstrong @ 2023-06-14 13:12 ` Krzysztof Kozlowski 2023-06-26 8:32 ` Heikki Krogerus 1 sibling, 0 replies; 12+ messages in thread From: Krzysztof Kozlowski @ 2023-06-14 13:12 UTC (permalink / raw) To: Neil Armstrong, Heikki Krogerus, Greg Kroah-Hartman Cc: linux-usb, linux-kernel, linux-arm-msm On 14/06/2023 15:10, Neil Armstrong wrote: > The FSA4480 Type-C switch supports switching the Audio R/L, > AGND and MIC signals to the USB-C DP/DM and SBU1/2 to support > the Audio Accessory Mode. > > The FSA4480 has an integrated Audio jack detection mechanism > to automatically mux the AGND, MIX and Sense to the correct > SBU lines to support 3 pole and both 4 pole TRRS pinouts. > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> > --- Tested-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org> Best regards, Krzysztof ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/3] usb: typec: fsa4480: add support for Audio Accessory Mode 2023-06-14 13:10 ` [PATCH 3/3] usb: typec: fsa4480: add support for Audio Accessory Mode Neil Armstrong 2023-06-14 13:12 ` Krzysztof Kozlowski @ 2023-06-26 8:32 ` Heikki Krogerus 1 sibling, 0 replies; 12+ messages in thread From: Heikki Krogerus @ 2023-06-26 8:32 UTC (permalink / raw) To: Neil Armstrong Cc: Greg Kroah-Hartman, Krzysztof Kozlowski, linux-usb, linux-kernel, linux-arm-msm On Wed, Jun 14, 2023 at 03:10:41PM +0200, Neil Armstrong wrote: > The FSA4480 Type-C switch supports switching the Audio R/L, > AGND and MIC signals to the USB-C DP/DM and SBU1/2 to support > the Audio Accessory Mode. > > The FSA4480 has an integrated Audio jack detection mechanism > to automatically mux the AGND, MIX and Sense to the correct > SBU lines to support 3 pole and both 4 pole TRRS pinouts. > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > drivers/usb/typec/mux/fsa4480.c | 17 +++++++++++++++++ > 1 file changed, 17 insertions(+) > > diff --git a/drivers/usb/typec/mux/fsa4480.c b/drivers/usb/typec/mux/fsa4480.c > index b2913594a58f..45f5683b7d81 100644 > --- a/drivers/usb/typec/mux/fsa4480.c > +++ b/drivers/usb/typec/mux/fsa4480.c > @@ -25,15 +25,24 @@ > #define FSA4480_DELAY_L_MIC 0x0e > #define FSA4480_DELAY_L_SENSE 0x0f > #define FSA4480_DELAY_L_AGND 0x10 > +#define FSA4480_FUNCTION_ENABLE 0x12 > #define FSA4480_RESET 0x1e > #define FSA4480_MAX_REGISTER 0x1f > > #define FSA4480_ENABLE_DEVICE BIT(7) > #define FSA4480_ENABLE_SBU GENMASK(6, 5) > #define FSA4480_ENABLE_USB GENMASK(4, 3) > +#define FSA4480_ENABLE_SENSE BIT(2) > +#define FSA4480_ENABLE_MIC BIT(1) > +#define FSA4480_ENABLE_AGND BIT(0) > > #define FSA4480_SEL_SBU_REVERSE GENMASK(6, 5) > #define FSA4480_SEL_USB GENMASK(4, 3) > +#define FSA4480_SEL_SENSE BIT(2) > +#define FSA4480_SEL_MIC BIT(1) > +#define FSA4480_SEL_AGND BIT(0) > + > +#define FSA4480_ENABLE_AUTO_JACK_DETECT BIT(0) > > struct fsa4480 { > struct i2c_client *client; > @@ -95,6 +104,9 @@ static int fsa4480_set(struct fsa4480 *fsa) > default: > return -EOPNOTSUPP; > } > + } else if (fsa->mode == TYPEC_MODE_AUDIO) { > + /* Audio Accessory Mode, setup to auto Jack Detection */ > + enable |= FSA4480_ENABLE_USB | FSA4480_ENABLE_AGND; > } else > return -EOPNOTSUPP; > > @@ -110,6 +122,11 @@ static int fsa4480_set(struct fsa4480 *fsa) > regmap_write(fsa->regmap, FSA4480_SWITCH_SELECT, sel); > regmap_write(fsa->regmap, FSA4480_SWITCH_ENABLE, enable); > > + /* Start AUDIO JACK DETECTION to setup MIC, AGND & Sense muxes */ > + if (enable & FSA4480_ENABLE_AGND) > + regmap_write(fsa->regmap, FSA4480_FUNCTION_ENABLE, > + FSA4480_ENABLE_AUTO_JACK_DETECT); > + > if (enable & FSA4480_ENABLE_SBU) { > /* 15us to allow the SBU switch to turn on again */ > usleep_range(15, 1000); thanks, -- heikki ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2023-06-26 14:43 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-06-14 13:10 [PATCH 0/3] typec: support Audio Accessory mode on FSA4480 Neil Armstrong 2023-06-14 13:10 ` [PATCH 1/3] usb: typec: ucsi: call typec_set_mode on non-altmode partner change Neil Armstrong 2023-06-14 13:11 ` Krzysztof Kozlowski 2023-06-26 8:12 ` Heikki Krogerus 2023-06-26 13:23 ` Neil Armstrong 2023-06-26 14:43 ` Greg Kroah-Hartman 2023-06-14 13:10 ` [PATCH 2/3] usb: typec: fsa4480: rework mux & switch setup to handle more states Neil Armstrong 2023-06-14 13:12 ` Krzysztof Kozlowski 2023-06-26 8:30 ` Heikki Krogerus 2023-06-14 13:10 ` [PATCH 3/3] usb: typec: fsa4480: add support for Audio Accessory Mode Neil Armstrong 2023-06-14 13:12 ` Krzysztof Kozlowski 2023-06-26 8:32 ` Heikki Krogerus
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).