From: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
To: sre@kernel.org, linux-pm@vger.kernel.org
Cc: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
Subject: [PATCH 6/7] power: supply: sbs-battery: add ability to disable charger broadcasts
Date: Fri, 1 Nov 2019 15:07:04 -0400 [thread overview]
Message-ID: <20191101190705.13393-6-jeff.dagenais@gmail.com> (raw)
In-Reply-To: <20191101190705.13393-1-jeff.dagenais@gmail.com>
In certain designs, it is possible to add a battery on a populated i2c
bus without an sbs compliant charger. In that case, the battery will
un-necessarily and sometimes un-desirably master the bus trying to write
info in the charger.
It is observed in many occasion that these battery "broadcasts" are even
corrupting other ongoing master to slave communication. I.e. the
multi-master support in the battery is inadequate.
Thankfully, the CHARGER_MODE bit allows designers to disable that SBS
battery behaviour.
This needs to be done once when the battery is first seen on the bus.
Signed-off-by: Jean-Francois Dagenais <jeff.dagenais@gmail.com>
---
drivers/power/supply/sbs-battery.c | 39 +++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/drivers/power/supply/sbs-battery.c b/drivers/power/supply/sbs-battery.c
index 46c89dd05f46..fb116ab7752d 100644
--- a/drivers/power/supply/sbs-battery.c
+++ b/drivers/power/supply/sbs-battery.c
@@ -51,6 +51,7 @@ enum sbs_capacity_mode {
CAPACITY_MODE_AMPS = 0,
CAPACITY_MODE_WATTS = BATTERY_MODE_CAPACITY_MASK
};
+#define BATTERY_MODE_CHARGER_MASK (1<<14)
/* manufacturer access defines */
#define MANUFACTURER_ACCESS_STATUS 0x0006
@@ -157,6 +158,7 @@ struct sbs_info {
bool is_present;
struct gpio_desc *gpio_detect;
bool enable_detection;
+ bool charger_broadcasts;
int last_state;
int poll_time;
u32 i2c_retry_count;
@@ -596,6 +598,34 @@ static int sbs_get_property_index(struct i2c_client *client,
return -EINVAL;
}
+static void sbs_disable_charger_broadcasts(struct sbs_info *chip)
+{
+ int val = sbs_read_word_data(chip->client, BATTERY_MODE_OFFSET);
+ if (val < 0)
+ goto exit;
+
+ val |= BATTERY_MODE_CHARGER_MASK;
+
+ val = sbs_write_word_data(chip->client, BATTERY_MODE_OFFSET, val);
+
+exit:
+ if (val < 0)
+ dev_err(&chip->client->dev,
+ "Failed to disable charger broadcasting: %d\n", val);
+ else
+ dev_dbg(&chip->client->dev, "%s\n", __func__);
+}
+
+static void sbs_set_is_present(struct sbs_info *chip, bool is_present)
+{
+ dev_dbg(&chip->client->dev, "%s %d\n", __func__, is_present);
+
+ if (!chip->is_present && is_present && !chip->charger_broadcasts)
+ sbs_disable_charger_broadcasts(chip);
+
+ chip->is_present = is_present;
+}
+
static int sbs_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
@@ -610,7 +640,7 @@ static int sbs_get_property(struct power_supply *psy,
return ret;
if (psp == POWER_SUPPLY_PROP_PRESENT) {
val->intval = ret;
- chip->is_present = val->intval;
+ sbs_set_is_present(chip, val->intval);
return 0;
}
if (ret == 0)
@@ -706,7 +736,7 @@ static int sbs_get_property(struct power_supply *psy,
if (!chip->gpio_detect &&
chip->is_present != (ret >= 0)) {
- chip->is_present = (ret >= 0);
+ sbs_set_is_present(chip, ret >= 0);
power_supply_changed(chip->power_supply);
}
@@ -737,7 +767,7 @@ static void sbs_supply_changed(struct sbs_info *chip)
ret = gpiod_get_value_cansleep(chip->gpio_detect);
if (ret < 0)
return;
- chip->is_present = ret;
+ sbs_set_is_present(chip, ret);
power_supply_changed(battery);
}
@@ -862,6 +892,9 @@ static int sbs_probe(struct i2c_client *client,
force_load = of_property_read_bool(client->dev.of_node,
"sbs,force-load");
+ chip->charger_broadcasts = !of_property_read_bool(client->dev.of_node,
+ "sbs,disable-charger-broadcasts");
+
chip->gpio_detect = devm_gpiod_get_optional(&client->dev,
"sbs,battery-detect", GPIOD_IN);
if (IS_ERR(chip->gpio_detect)) {
--
2.23.0
next prev parent reply other threads:[~2019-11-01 19:07 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-01 19:06 [PATCH 1/7] power: supply: sbs-battery: use octal permissions on module param Jean-Francois Dagenais
2019-11-01 19:07 ` [PATCH 2/7] power: supply: sbs-battery: prefix module param variable Jean-Francois Dagenais
2019-11-01 19:07 ` [PATCH 3/7] power: supply: sbs-battery: add force_load as a dts property Jean-Francois Dagenais
2019-12-19 1:19 ` Sebastian Reichel
2019-11-01 19:07 ` [PATCH 4/7] devicetree: bindings: sbs-battery: add sbs,force-load property Jean-Francois Dagenais
2019-12-19 1:23 ` Sebastian Reichel
2019-11-01 19:07 ` [PATCH 5/7] power: supply: sbs-battery: fix CAPACITY_MODE bit naming Jean-Francois Dagenais
2019-12-19 1:22 ` Sebastian Reichel
2019-11-01 19:07 ` Jean-Francois Dagenais [this message]
2019-11-01 19:07 ` [PATCH 7/7] dt-bindings: power: sbs-battery: add disable-charger-broadcasts doc Jean-Francois Dagenais
2019-12-19 1:22 ` Sebastian Reichel
2019-12-19 1:13 ` [PATCH 1/7] power: supply: sbs-battery: use octal permissions on module param Sebastian Reichel
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=20191101190705.13393-6-jeff.dagenais@gmail.com \
--to=jeff.dagenais@gmail.com \
--cc=linux-pm@vger.kernel.org \
--cc=sre@kernel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.