* [PATCH v3 0/2] usb: typec: fsa4480: Support reporting hotplug events to a codec
@ 2026-10-20 16:20 Val Packett
2026-10-20 16:20 ` [PATCH v3 1/2] dt-bindings: usb: fsa4480: Add an optional audio port/endpoint Val Packett
2026-10-20 16:20 ` [PATCH v3 2/2] usb: typec: fsa4480: Report switch & mux events to codec Val Packett
0 siblings, 2 replies; 4+ messages in thread
From: Val Packett @ 2026-10-20 16:20 UTC (permalink / raw)
Cc: Val Packett, Greg Kroah-Hartman, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Heikki Krogerus,
Bjorn Andersson, Neil Armstrong, Luca Weiss,
~postmarketos/upstreaming, phone-devel, linux-usb, linux-kernel,
devicetree
Currently the fsa4480 USB-C SBU MUX is not actually used with audio
codecs in mainline. I have gotten it to work with the wcd937x codec
on sm7325-motorola-dubai (copying the Type-C notification handler
code from wcd939x to wcd937x, will be sent after this).
v3:
* Put the codec mux/switch refs after unregistering our mux/switch
in fsa4480_remove (sashiko-bot)
v2: https://lore.kernel.org/all/20261020081343.1507986-1-val@packett.cool/
v1: https://lore.kernel.org/all/20261018225906.1265299-1-val@packett.cool/
Thanks,
~val
---
Luca Weiss (1):
usb: typec: fsa4480: Report switch & mux events to codec
Val Packett (1):
dt-bindings: usb: fsa4480: Add an optional audio port/endpoint
.../devicetree/bindings/usb/fcs,fsa4480.yaml | 94 +++++++++++++------
drivers/usb/typec/mux/fsa4480.c | 57 +++++++++--
2 files changed, 116 insertions(+), 35 deletions(-)
--
2.55.0
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH v3 1/2] dt-bindings: usb: fsa4480: Add an optional audio port/endpoint 2026-10-20 16:20 [PATCH v3 0/2] usb: typec: fsa4480: Support reporting hotplug events to a codec Val Packett @ 2026-10-20 16:20 ` Val Packett 2026-10-20 16:20 ` [PATCH v3 2/2] usb: typec: fsa4480: Report switch & mux events to codec Val Packett 1 sibling, 0 replies; 4+ messages in thread From: Val Packett @ 2026-10-20 16:20 UTC (permalink / raw) To: Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson Cc: Val Packett, Heikki Krogerus, Neil Armstrong, Luca Weiss, ~postmarketos/upstreaming, phone-devel, linux-usb, linux-kernel, devicetree The fsa4480 mux is physically connected not only to a Type-C port controller, but also to an audio codec which has to be notified when an analog audio accessory has been plugged in. Describe a second port intended for the codec. Keep it optional to make sure existing device trees do still validate. Signed-off-by: Val Packett <val@packett.cool> --- .../devicetree/bindings/usb/fcs,fsa4480.yaml | 94 +++++++++++++------ 1 file changed, 66 insertions(+), 28 deletions(-) diff --git a/Documentation/devicetree/bindings/usb/fcs,fsa4480.yaml b/Documentation/devicetree/bindings/usb/fcs,fsa4480.yaml index 89b1fb90aeeb..ee00c7ce0c50 100644 --- a/Documentation/devicetree/bindings/usb/fcs,fsa4480.yaml +++ b/Documentation/devicetree/bindings/usb/fcs,fsa4480.yaml @@ -9,31 +9,11 @@ title: ON Semiconductor Analog Audio Switch maintainers: - Bjorn Andersson <bjorn.andersson@linaro.org> -properties: - compatible: - oneOf: - - const: fcs,fsa4480 - - items: - - enum: - - ocs,ocp96011 - - const: fcs,fsa4480 - - reg: - maxItems: 1 - - interrupts: - maxItems: 1 - - vcc-supply: - description: power supply (2.7V-5.5V) - - mode-switch: true - orientation-switch: true - - port: +$defs: + controller-port: $ref: /schemas/graph.yaml#/$defs/port-base description: - A port node to link the FSA4480 to a TypeC controller for the purpose of + A port node to link the FSA4480 to a Type-C controller for the purpose of handling altmode muxing and orientation switching. unevaluatedProperties: false @@ -69,14 +49,57 @@ properties: - AUX+ connected to SBU2 - AUX- connected to SBU1 +properties: + compatible: + oneOf: + - const: fcs,fsa4480 + - items: + - enum: + - ocs,ocp96011 + - const: fcs,fsa4480 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + vcc-supply: + description: power supply (2.7V-5.5V) + + mode-switch: true + orientation-switch: true + + port: + $ref: "#/$defs/controller-port" + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: "#/$defs/controller-port" + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: + A port node to link the FSA4480 to an audio codec for the purpose of + handling Audio Accessory Mode muxing and orientation switching. + + required: + - port@0 + required: - compatible - reg - - port allOf: - $ref: usb-switch.yaml# - - $ref: usb-switch-ports.yaml# + +oneOf: + - required: + - port + - required: + - ports additionalProperties: false @@ -98,9 +121,24 @@ examples: mode-switch; orientation-switch; - port { - fsa4480_ept: endpoint { - remote-endpoint = <&typec_controller>; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + fsa4480_sbu_mux: endpoint { + remote-endpoint = <&typec_controller>; + }; + }; + + port@1 { + reg = <1>; + + fsa4480_audio: endpoint { + remote-endpoint = <&audio_codec>; + }; }; }; }; -- 2.55.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v3 2/2] usb: typec: fsa4480: Report switch & mux events to codec 2026-10-20 16:20 [PATCH v3 0/2] usb: typec: fsa4480: Support reporting hotplug events to a codec Val Packett 2026-10-20 16:20 ` [PATCH v3 1/2] dt-bindings: usb: fsa4480: Add an optional audio port/endpoint Val Packett @ 2026-10-20 16:20 ` Val Packett 2026-10-26 13:15 ` Heikki Krogerus 1 sibling, 1 reply; 4+ messages in thread From: Val Packett @ 2026-10-20 16:20 UTC (permalink / raw) To: Heikki Krogerus, Greg Kroah-Hartman Cc: Luca Weiss, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Neil Armstrong, ~postmarketos/upstreaming, phone-devel, linux-usb, linux-kernel, devicetree, Val Packett From: Luca Weiss <luca.weiss@fairphone.com> In the Type-C graph, the FSA4480 switch is in between the USB-C connector and the audio codec, but the audio codec also needs to receive the switch and mux events from the FSA4480. Update the driver to get an Type-C mux on the next endpoint and broadcast the recevied mux & switch state to it. Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> [val: enable the SENSE/MIC bits; put the refs in fsa4480_remove] Signed-off-by: Val Packett <val@packett.cool> --- drivers/usb/typec/mux/fsa4480.c | 57 +++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/drivers/usb/typec/mux/fsa4480.c b/drivers/usb/typec/mux/fsa4480.c index bea0c1deec94..3c12d17a25a2 100644 --- a/drivers/usb/typec/mux/fsa4480.c +++ b/drivers/usb/typec/mux/fsa4480.c @@ -60,6 +60,9 @@ struct fsa4480 { struct regmap *regmap; + struct typec_mux *codec; + struct typec_switch *codec_switch; + enum typec_orientation orientation; unsigned long mode; unsigned int svid; @@ -115,7 +118,8 @@ static int fsa4480_set(struct fsa4480 *fsa) } } else if (fsa->mode == TYPEC_MODE_AUDIO) { /* Audio Accessory Mode, setup to auto Jack Detection */ - enable |= FSA4480_ENABLE_USB | FSA4480_ENABLE_AGND; + enable |= FSA4480_ENABLE_USB | FSA4480_ENABLE_AGND | + FSA4480_ENABLE_SENSE | FSA4480_ENABLE_MIC; } else return -EOPNOTSUPP; @@ -162,7 +166,11 @@ static int fsa4480_switch_set(struct typec_switch_dev *sw, mutex_unlock(&fsa->lock); - return ret; + if (ret) + return ret; + + /* Report orientation to codec after switch has been done */ + return typec_switch_set(fsa->codec_switch, orientation); } static int fsa4480_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) @@ -185,7 +193,11 @@ static int fsa4480_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *st mutex_unlock(&fsa->lock); - return ret; + if (ret) + return ret; + + /* Report event to codec after switch has been done */ + return typec_mux_set(fsa->codec, state); } enum { @@ -287,6 +299,19 @@ static int fsa4480_probe(struct i2c_client *client) FIELD_GET(FSA4480_DEVICE_ID_REV_ID, val), FIELD_GET(FSA4480_DEVICE_ID_VENDOR_ID, val)); + /* Get Codec's MUX & Switch devices */ + fsa->codec = fwnode_typec_mux_get(dev->fwnode); + if (IS_ERR(fsa->codec)) + return dev_err_probe(dev, PTR_ERR(fsa->codec), + "failed to acquire codec mode-switch\n"); + + fsa->codec_switch = fwnode_typec_switch_get(dev->fwnode); + if (IS_ERR(fsa->codec_switch)) { + ret = dev_err_probe(dev, PTR_ERR(fsa->codec_switch), + "failed to acquire codec orientation-switch\n"); + goto err_put_mux; + } + /* Safe mode */ fsa->cur_enable = FSA4480_ENABLE_DEVICE | FSA4480_ENABLE_USB; fsa->mode = TYPEC_STATE_SAFE; @@ -310,8 +335,11 @@ static int fsa4480_probe(struct i2c_client *client) sw_desc.set = fsa4480_switch_set; fsa->sw = typec_switch_register(dev, &sw_desc); - if (IS_ERR(fsa->sw)) - return dev_err_probe(dev, PTR_ERR(fsa->sw), "failed to register typec switch\n"); + if (IS_ERR(fsa->sw)) { + ret = dev_err_probe(dev, PTR_ERR(fsa->sw), + "failed to register typec switch\n"); + goto err_put_switch; + } mux_desc.drvdata = fsa; mux_desc.fwnode = dev_fwnode(dev); @@ -319,12 +347,24 @@ static int fsa4480_probe(struct i2c_client *client) fsa->mux = typec_mux_register(dev, &mux_desc); if (IS_ERR(fsa->mux)) { - typec_switch_unregister(fsa->sw); - return dev_err_probe(dev, PTR_ERR(fsa->mux), "failed to register typec mux\n"); + ret = dev_err_probe(dev, PTR_ERR(fsa->mux), + "failed to register typec mux\n"); + goto err_unregister_switch; } i2c_set_clientdata(client, fsa); return 0; + +err_unregister_switch: + typec_switch_unregister(fsa->sw); + +err_put_switch: + typec_switch_put(fsa->codec_switch); + +err_put_mux: + typec_mux_put(fsa->codec); + + return ret; } static void fsa4480_remove(struct i2c_client *client) @@ -333,6 +373,9 @@ static void fsa4480_remove(struct i2c_client *client) typec_mux_unregister(fsa->mux); typec_switch_unregister(fsa->sw); + + typec_mux_put(fsa->codec); + typec_switch_put(fsa->codec_switch); } static const struct i2c_device_id fsa4480_table[] = { -- 2.55.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH v3 2/2] usb: typec: fsa4480: Report switch & mux events to codec 2026-10-20 16:20 ` [PATCH v3 2/2] usb: typec: fsa4480: Report switch & mux events to codec Val Packett @ 2026-10-26 13:15 ` Heikki Krogerus 0 siblings, 0 replies; 4+ messages in thread From: Heikki Krogerus @ 2026-10-26 13:15 UTC (permalink / raw) To: Val Packett Cc: Greg Kroah-Hartman, Luca Weiss, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Bjorn Andersson, Neil Armstrong, ~postmarketos/upstreaming, phone-devel, linux-usb, linux-kernel, devicetree On Tue, Oct 20, 2026 at 01:20:31PM -0300, Val Packett wrote: > From: Luca Weiss <luca.weiss@fairphone.com> > > In the Type-C graph, the FSA4480 switch is in between the USB-C connector > and the audio codec, but the audio codec also needs to receive the > switch and mux events from the FSA4480. > > Update the driver to get an Type-C mux on the next endpoint and > broadcast the recevied mux & switch state to it. > > Signed-off-by: Luca Weiss <luca.weiss@fairphone.com> > [val: enable the SENSE/MIC bits; put the refs in fsa4480_remove] > Signed-off-by: Val Packett <val@packett.cool> Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com> > --- > drivers/usb/typec/mux/fsa4480.c | 57 +++++++++++++++++++++++++++++---- > 1 file changed, 50 insertions(+), 7 deletions(-) > > diff --git a/drivers/usb/typec/mux/fsa4480.c b/drivers/usb/typec/mux/fsa4480.c > index bea0c1deec94..3c12d17a25a2 100644 > --- a/drivers/usb/typec/mux/fsa4480.c > +++ b/drivers/usb/typec/mux/fsa4480.c > @@ -60,6 +60,9 @@ struct fsa4480 { > > struct regmap *regmap; > > + struct typec_mux *codec; > + struct typec_switch *codec_switch; > + > enum typec_orientation orientation; > unsigned long mode; > unsigned int svid; > @@ -115,7 +118,8 @@ static int fsa4480_set(struct fsa4480 *fsa) > } > } else if (fsa->mode == TYPEC_MODE_AUDIO) { > /* Audio Accessory Mode, setup to auto Jack Detection */ > - enable |= FSA4480_ENABLE_USB | FSA4480_ENABLE_AGND; > + enable |= FSA4480_ENABLE_USB | FSA4480_ENABLE_AGND | > + FSA4480_ENABLE_SENSE | FSA4480_ENABLE_MIC; > } else > return -EOPNOTSUPP; > > @@ -162,7 +166,11 @@ static int fsa4480_switch_set(struct typec_switch_dev *sw, > > mutex_unlock(&fsa->lock); > > - return ret; > + if (ret) > + return ret; > + > + /* Report orientation to codec after switch has been done */ > + return typec_switch_set(fsa->codec_switch, orientation); > } > > static int fsa4480_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) > @@ -185,7 +193,11 @@ static int fsa4480_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *st > > mutex_unlock(&fsa->lock); > > - return ret; > + if (ret) > + return ret; > + > + /* Report event to codec after switch has been done */ > + return typec_mux_set(fsa->codec, state); > } > > enum { > @@ -287,6 +299,19 @@ static int fsa4480_probe(struct i2c_client *client) > FIELD_GET(FSA4480_DEVICE_ID_REV_ID, val), > FIELD_GET(FSA4480_DEVICE_ID_VENDOR_ID, val)); > > + /* Get Codec's MUX & Switch devices */ > + fsa->codec = fwnode_typec_mux_get(dev->fwnode); > + if (IS_ERR(fsa->codec)) > + return dev_err_probe(dev, PTR_ERR(fsa->codec), > + "failed to acquire codec mode-switch\n"); > + > + fsa->codec_switch = fwnode_typec_switch_get(dev->fwnode); > + if (IS_ERR(fsa->codec_switch)) { > + ret = dev_err_probe(dev, PTR_ERR(fsa->codec_switch), > + "failed to acquire codec orientation-switch\n"); > + goto err_put_mux; > + } > + > /* Safe mode */ > fsa->cur_enable = FSA4480_ENABLE_DEVICE | FSA4480_ENABLE_USB; > fsa->mode = TYPEC_STATE_SAFE; > @@ -310,8 +335,11 @@ static int fsa4480_probe(struct i2c_client *client) > sw_desc.set = fsa4480_switch_set; > > fsa->sw = typec_switch_register(dev, &sw_desc); > - if (IS_ERR(fsa->sw)) > - return dev_err_probe(dev, PTR_ERR(fsa->sw), "failed to register typec switch\n"); > + if (IS_ERR(fsa->sw)) { > + ret = dev_err_probe(dev, PTR_ERR(fsa->sw), > + "failed to register typec switch\n"); > + goto err_put_switch; > + } > > mux_desc.drvdata = fsa; > mux_desc.fwnode = dev_fwnode(dev); > @@ -319,12 +347,24 @@ static int fsa4480_probe(struct i2c_client *client) > > fsa->mux = typec_mux_register(dev, &mux_desc); > if (IS_ERR(fsa->mux)) { > - typec_switch_unregister(fsa->sw); > - return dev_err_probe(dev, PTR_ERR(fsa->mux), "failed to register typec mux\n"); > + ret = dev_err_probe(dev, PTR_ERR(fsa->mux), > + "failed to register typec mux\n"); > + goto err_unregister_switch; > } > > i2c_set_clientdata(client, fsa); > return 0; > + > +err_unregister_switch: > + typec_switch_unregister(fsa->sw); > + > +err_put_switch: > + typec_switch_put(fsa->codec_switch); > + > +err_put_mux: > + typec_mux_put(fsa->codec); > + > + return ret; > } > > static void fsa4480_remove(struct i2c_client *client) > @@ -333,6 +373,9 @@ static void fsa4480_remove(struct i2c_client *client) > > typec_mux_unregister(fsa->mux); > typec_switch_unregister(fsa->sw); > + > + typec_mux_put(fsa->codec); > + typec_switch_put(fsa->codec_switch); > } > > static const struct i2c_device_id fsa4480_table[] = { > -- > 2.55.0 -- heikki ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-26 13:15 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-10-20 16:20 [PATCH v3 0/2] usb: typec: fsa4480: Support reporting hotplug events to a codec Val Packett 2026-10-20 16:20 ` [PATCH v3 1/2] dt-bindings: usb: fsa4480: Add an optional audio port/endpoint Val Packett 2026-10-20 16:20 ` [PATCH v3 2/2] usb: typec: fsa4480: Report switch & mux events to codec Val Packett 2026-10-26 13:15 ` Heikki Krogerus
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®