All of lore.kernel.org
 help / color / mirror / Atom feed
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


  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.