From: Amit Sunil Dhamne <amitsd@google.com>
To: "André Draszik" <andre.draszik@linaro.org>,
"Sebastian Reichel" <sre@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Lee Jones" <lee@kernel.org>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Badhri Jagan Sridharan" <badhri@google.com>,
"Heikki Krogerus" <heikki.krogerus@linux.intel.com>,
"Peter Griffin" <peter.griffin@linaro.org>,
"Tudor Ambarus" <tudor.ambarus@linaro.org>,
"Alim Akhtar" <alim.akhtar@samsung.com>
Cc: linux-kernel@vger.kernel.org, linux-pm@vger.kernel.org,
devicetree@vger.kernel.org, linux-usb@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-samsung-soc@vger.kernel.org,
RD Babiera <rdbabiera@google.com>, Kyle Tso <kyletso@google.com>
Subject: Re: [PATCH 6/6] usb: typec: tcpm/tcpci_maxim: deprecate WAR for setting charger mode
Date: Tue, 25 Nov 2025 18:32:43 -0800 [thread overview]
Message-ID: <0a43b5a2-dc2f-402a-8ec7-1d5c88602ffc@google.com> (raw)
In-Reply-To: <9cad7b42dbfea351fb3b708736bf6f6715bcf694.camel@linaro.org>
On 11/24/25 1:09 AM, André Draszik wrote:
> Hi Amit,
>
> On Sun, 2025-11-23 at 08:35 +0000, Amit Sunil Dhamne via B4 Relay wrote:
>> From: Amit Sunil Dhamne <amitsd@google.com>
>>
>> TCPCI maxim driver directly writes to the charger's register space to
>> set charger mode depending on the power role. As MAX77759 chg driver
>> exists, this WAR is not required.
>>
>> Instead, use a regulator interface to set OTG Boost mode.
>>
>> Signed-off-by: Amit Sunil Dhamne <amitsd@google.com>
>> ---
>> drivers/usb/typec/tcpm/tcpci_maxim.h | 1 +
>> drivers/usb/typec/tcpm/tcpci_maxim_core.c | 48 +++++++++++++++++++++----------
>> 2 files changed, 34 insertions(+), 15 deletions(-)
>>
>> diff --git a/drivers/usb/typec/tcpm/tcpci_maxim.h b/drivers/usb/typec/tcpm/tcpci_maxim.h
>> index b33540a42a95..6c82a61efe46 100644
>> --- a/drivers/usb/typec/tcpm/tcpci_maxim.h
>> +++ b/drivers/usb/typec/tcpm/tcpci_maxim.h
>> @@ -60,6 +60,7 @@ struct max_tcpci_chip {
>> struct tcpm_port *port;
>> enum contamiant_state contaminant_state;
>> bool veto_vconn_swap;
>> + struct regulator *otg_reg;
>> };
>>
>> static inline int max_tcpci_read16(struct max_tcpci_chip *chip, unsigned int reg, u16 *val)
>> diff --git a/drivers/usb/typec/tcpm/tcpci_maxim_core.c b/drivers/usb/typec/tcpm/tcpci_maxim_core.c
>> index 19f638650796..6d819a762fa1 100644
>> --- a/drivers/usb/typec/tcpm/tcpci_maxim_core.c
>> +++ b/drivers/usb/typec/tcpm/tcpci_maxim_core.c
>> @@ -10,6 +10,7 @@
>> #include <linux/kernel.h>
>> #include <linux/module.h>
>> #include <linux/regmap.h>
>> +#include <linux/regulator/consumer.h>
>> #include <linux/usb/pd.h>
>> #include <linux/usb/tcpci.h>
>> #include <linux/usb/tcpm.h>
>> @@ -202,32 +203,49 @@ static void process_rx(struct max_tcpci_chip *chip, u16 status)
>> tcpm_pd_receive(chip->port, &msg, rx_type);
>> }
>>
>> +static int get_otg_regulator_handle(struct max_tcpci_chip *chip)
>> +{
>> + if (IS_ERR_OR_NULL(chip->otg_reg)) {
>> + chip->otg_reg = devm_regulator_get_exclusive(chip->dev,
>> + "otg-vbus");
>> + if (IS_ERR_OR_NULL(chip->otg_reg)) {
>> + dev_err(chip->dev,
>> + "Failed to get otg regulator handle");
>> + return -ENODEV;
>> + }
>> + }
>> +
>> + return 0;
>> +}
>> +
>> static int max_tcpci_set_vbus(struct tcpci *tcpci, struct tcpci_data *tdata, bool source, bool sink)
>> {
>> struct max_tcpci_chip *chip = tdata_to_max_tcpci(tdata);
>> - u8 buffer_source[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SOURCE};
>> - u8 buffer_sink[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_SINK};
>> - u8 buffer_none[2] = {MAX_BUCK_BOOST_OP, MAX_BUCK_BOOST_OFF};
> You should also remove the corresponding #defines at the top of this file.
Ack!
>
>> - struct i2c_client *i2c = chip->client;
>> int ret;
>>
>> - struct i2c_msg msgs[] = {
>> - {
>> - .addr = MAX_BUCK_BOOST_SID,
>> - .flags = i2c->flags & I2C_M_TEN,
>> - .len = 2,
>> - .buf = source ? buffer_source : sink ? buffer_sink : buffer_none,
>> - },
>> - };
>> -
>> if (source && sink) {
>> dev_err(chip->dev, "Both source and sink set\n");
>> return -EINVAL;
>> }
>>
>> - ret = i2c_transfer(i2c->adapter, msgs, 1);
>> + ret = get_otg_regulator_handle(chip);
>> + if (ret) {
>> + /*
>> + * Regulator is not necessary for sink only applications. Return
>> + * success in cases where sink mode is being modified.
>> + */
>> + return source ? ret : 1;
>> + }
>> +
>> + if (source) {
>> + if (!regulator_is_enabled(chip->otg_reg))
>> + ret = regulator_enable(chip->otg_reg);
>> + } else {
>> + if (regulator_is_enabled(chip->otg_reg))
>> + ret = regulator_disable(chip->otg_reg);
>> + }
> Given otg_reg is the fake regulator created by a previous patch in this
> series, this means that the regulator API is really used to configure two
> out of 16 possible charger modes here. That doesn't look right.
I understand the concern, but I believe the regulator framework is the
correct interface here for three reasons:
1. The TCPCI driver's responsibility is only to signal the intent to
source VBUS (OTG) or not. It should not be aware of the specific
register values or mode bits of the companion charger chip. The charger
driver (via the regulator enable op) is responsible for translating that
intent into the correct hardware-specific register value (e.g.,
selecting the correct OTG mode).
2. While the charger supports multiple modes, sourcing VBUS via OTG and
sinking VBUS (charging) are mutually exclusive states on Type-C and
there are no modes to support both. If complex scenarios arise (like
wireless charging + USB OTG), the logic to select the specific register
mode belongs in the charger driver (the regulator provider), not the
TCPCI consumer. Now say theoretically, we support wireless charging and
want to turn it on (sink) while USB OTG mode (source) is on. The charger
driver would set an appropriate mode based on this info (wireless
power-supply on, USB otg regulator on, so select XX mode). We can game
this for any 10 of the *valid* modes (refer [1]) supported by the chip
and this would work. Using a regulator framework here will not pose a
restriction on the number of charger modes now or in the future.
3. This design pattern is standard in the kernel from my study. Drivers
such as bq24190_charger and rt9471 expose USB OTG functionality via the
regulator framework.
[1]
https://android.googlesource.com/kernel/google-modules/bms/+/refs/heads/android-gs-raviole-mainline/max77759_regs.h#52
BR,
Amit
>
> Cheers,
> Andre'
prev parent reply other threads:[~2025-11-26 2:32 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-23 8:35 [PATCH 0/6] Introduce MAX77759 charger driver Amit Sunil Dhamne via B4 Relay
2025-11-23 8:35 ` [PATCH 1/6] dt-bindings: power: supply: Add Maxim MAX77759 charger Amit Sunil Dhamne via B4 Relay
2025-11-23 9:28 ` Krzysztof Kozlowski
2025-11-24 2:34 ` Amit Sunil Dhamne
2025-11-25 9:56 ` Krzysztof Kozlowski
2025-11-25 23:48 ` Amit Sunil Dhamne
2025-12-02 13:00 ` Krzysztof Kozlowski
2025-12-04 21:06 ` Amit Sunil Dhamne
2025-11-23 8:35 ` [PATCH 2/6] dt-bindings: mfd: maxim,max77759: add charger child node Amit Sunil Dhamne via B4 Relay
2025-11-23 9:30 ` Krzysztof Kozlowski
2025-11-26 0:02 ` Amit Sunil Dhamne
2025-11-23 8:35 ` [PATCH 3/6] dt-bindings: usb: maxim,max33359: Add supply property for VBUS in OTG mode Amit Sunil Dhamne via B4 Relay
2025-11-24 7:53 ` Krzysztof Kozlowski
2025-11-25 20:13 ` Amit Sunil Dhamne
2025-11-26 16:18 ` André Draszik
2025-11-26 20:27 ` Amit Sunil Dhamne
2025-11-26 10:01 ` Heikki Krogerus
2025-11-26 20:50 ` Amit Sunil Dhamne
2025-11-23 8:35 ` [PATCH 4/6] mfd: max77759: modify irq configs Amit Sunil Dhamne via B4 Relay
2025-11-24 6:21 ` André Draszik
2025-11-24 7:39 ` Krzysztof Kozlowski
2025-11-26 1:19 ` Amit Sunil Dhamne
2025-11-26 1:10 ` Amit Sunil Dhamne
2025-11-26 6:44 ` André Draszik
2025-11-26 7:36 ` André Draszik
2025-11-27 4:15 ` Amit Sunil Dhamne
2025-11-24 7:38 ` Krzysztof Kozlowski
2025-11-23 8:35 ` [PATCH 5/6] power: supply: max77759: add charger driver Amit Sunil Dhamne via B4 Relay
2025-11-26 7:36 ` André Draszik
2025-11-26 7:38 ` kernel test robot
2025-11-26 22:04 ` Amit Sunil Dhamne
2025-11-23 8:35 ` [PATCH 6/6] usb: typec: tcpm/tcpci_maxim: deprecate WAR for setting charger mode Amit Sunil Dhamne via B4 Relay
2025-11-24 9:09 ` André Draszik
2025-11-26 2:32 ` Amit Sunil Dhamne [this message]
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=0a43b5a2-dc2f-402a-8ec7-1d5c88602ffc@google.com \
--to=amitsd@google.com \
--cc=alim.akhtar@samsung.com \
--cc=andre.draszik@linaro.org \
--cc=badhri@google.com \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=krzk+dt@kernel.org \
--cc=kyletso@google.com \
--cc=lee@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=peter.griffin@linaro.org \
--cc=rdbabiera@google.com \
--cc=robh@kernel.org \
--cc=sre@kernel.org \
--cc=tudor.ambarus@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
all inboxes | Powered by JetHome®