From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
To: Neil Armstrong <neil.armstrong@linaro.org>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>,
linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-arm-msm@vger.kernel.org
Subject: Re: [PATCH 2/3] usb: typec: fsa4480: rework mux & switch setup to handle more states
Date: Mon, 26 Jun 2023 11:30:39 +0300 [thread overview]
Message-ID: <ZJlMr6vad6kPor1k@kuha.fi.intel.com> (raw)
In-Reply-To: <20230614-topic-sm8550-upstream-type-c-audio-v1-2-15a92565146b@linaro.org>
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
next prev parent reply other threads:[~2023-06-26 8:30 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZJlMr6vad6kPor1k@kuha.fi.intel.com \
--to=heikki.krogerus@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=krzysztof.kozlowski@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=neil.armstrong@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox