All of lore.kernel.org
 help / color / mirror / Atom feed
From: Abdel Alkuor <alkuor@gmail.com>
To: heikki.krogerus@linux.intel.com,
	krzysztof.kozlowski+dt@linaro.org, bryan.odonoghue@linaro.org
Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org,
	linux-kernel@vger.kernel.org, ryan.eleceng@gmail.com,
	robh+dt@kernel.org, conor+dt@kernel.org,
	devicetree@vger.kernel.org, Abdel Alkuor <abdelalkuor@geotab.com>
Subject: [PATCH v7 08/14] USB: typec: tps6598x: Add interrupt support for TPS25750
Date: Wed, 27 Sep 2023 13:53:42 -0400	[thread overview]
Message-ID: <20230927175348.18041-9-alkuor@gmail.com> (raw)
In-Reply-To: <20230927175348.18041-1-alkuor@gmail.com>

From: Abdel Alkuor <abdelalkuor@geotab.com>

tps25750 event registers structure is different than tps6598x's,
tps25750 has 11 bytes of events which are read at once where
tps6598x has two event registers of 8 bytes each which are read
separately. Likewise MASK event registers. Also, not all events
are supported in both devices.

Create a new handler to accommodate tps25750 interrupt

Signed-off-by: Abdel Alkuor <abdelalkuor@geotab.com>
---
Changes in v7:
  - Add driver name to commit subject
  - Create tps25750 interrupt handler
Changes in v6:
  - Create tipd callbacks factory 
Changes in v5:
  - Incorporating tps25750 into tps6598x driver

 drivers/usb/typec/tipd/core.c | 90 ++++++++++++++++++++++++++++++++---
 1 file changed, 84 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c
index 56ffffe225f2..40a76826a44e 100644
--- a/drivers/usb/typec/tipd/core.c
+++ b/drivers/usb/typec/tipd/core.c
@@ -101,6 +101,10 @@ static const char *const modes[] = {
 /* Unrecognized commands will be replaced with "!CMD" */
 #define INVALID_CMD(_cmd_)		(_cmd_ == 0x444d4321)
 
+struct tipd_data {
+	irq_handler_t irq_handler;
+};
+
 struct tps6598x {
 	struct device *dev;
 	struct regmap *regmap;
@@ -118,9 +122,11 @@ struct tps6598x {
 	enum power_supply_usb_type usb_type;
 
 	int wakeup;
+	u32 status; /* status reg */
 	u16 pwr_status;
 	struct delayed_work	wq_poll;
-	irq_handler_t irq_handler;
+
+	struct tipd_data cb;
 };
 
 static enum power_supply_property tps6598x_psy_props[] = {
@@ -545,6 +551,64 @@ static irqreturn_t cd321x_interrupt(int irq, void *data)
 	return IRQ_NONE;
 }
 
+static bool tps6598x_has_role_changed(struct tps6598x *tps, u32 status)
+{
+	status ^= tps->status;
+
+	return status & (TPS_STATUS_PORTROLE | TPS_STATUS_DATAROLE);
+}
+
+static irqreturn_t tps25750_interrupt(int irq, void *data)
+{
+	struct tps6598x *tps = data;
+	u64 event[2] = { };
+	u32 status;
+	int ret;
+
+	mutex_lock(&tps->lock);
+
+	ret = tps6598x_block_read(tps, TPS_REG_INT_EVENT1, event, 11);
+	if (ret) {
+		dev_err(tps->dev, "%s: failed to read events\n", __func__);
+		goto err_unlock;
+	}
+
+	if (!(event[0] | event[1]))
+		goto err_unlock;
+
+	if (!tps6598x_read_status(tps, &status))
+		goto err_clear_ints;
+
+	if ((event[0] | event[1]) & TPS_REG_INT_POWER_STATUS_UPDATE)
+		if (!tps6598x_read_power_status(tps))
+			goto err_clear_ints;
+
+	if ((event[0] | event[1]) & TPS_REG_INT_DATA_STATUS_UPDATE)
+		if (!tps6598x_read_data_status(tps))
+			goto err_clear_ints;
+
+	/*
+	 * data/port roles could be updated independently after
+	 * a plug event. Therefore, we need to check
+	 * for pr/dr status change to set TypeC dr/pr accordingly.
+	 */
+	if ((event[0] | event[1]) & TPS_REG_INT_PLUG_EVENT ||
+	    tps6598x_has_role_changed(tps, status))
+		tps6598x_handle_plug_event(tps, status);
+
+	tps->status = status;
+
+err_clear_ints:
+	tps6598x_block_write(tps, TPS_REG_INT_CLEAR1, event, 11);
+
+err_unlock:
+	mutex_unlock(&tps->lock);
+
+	if (event[0] | event[1])
+		return IRQ_HANDLED;
+	return IRQ_NONE;
+}
+
 static irqreturn_t tps6598x_interrupt(int irq, void *data)
 {
 	struct tps6598x *tps = data;
@@ -600,7 +664,7 @@ static void tps6598x_poll_work(struct work_struct *work)
 	struct tps6598x *tps = container_of(to_delayed_work(work),
 					    struct tps6598x, wq_poll);
 
-	tps->irq_handler(0, tps);
+	tps->cb.irq_handler(0, tps);
 	queue_delayed_work(system_power_efficient_wq,
 			   &tps->wq_poll, msecs_to_jiffies(POLL_INTERVAL));
 }
@@ -967,9 +1031,20 @@ static int tps25750_apply_patch(struct tps6598x *tps)
 	return 0;
 };
 
+static const struct tipd_data cd321x_data = {
+	.irq_handler = cd321x_interrupt,
+};
+
+static const struct tipd_data tps6598x_data = {
+	.irq_handler = tps6598x_interrupt,
+};
+
+static const struct tipd_data tps25750_data = {
+	.irq_handler = tps25750_interrupt,
+};
+
 static int tps6598x_probe(struct i2c_client *client)
 {
-	irq_handler_t irq_handler = tps6598x_interrupt;
 	struct device_node *np = client->dev.of_node;
 	struct typec_capability typec_cap = { };
 	struct tps6598x *tps;
@@ -1017,15 +1092,18 @@ static int tps6598x_probe(struct i2c_client *client)
 			APPLE_CD_REG_INT_DATA_STATUS_UPDATE |
 			APPLE_CD_REG_INT_PLUG_EVENT;
 
-		irq_handler = cd321x_interrupt;
+		tps->cb = cd321x_data;
 	} else {
+		if (is_tps25750)
+			tps->cb = tps25750_data;
+		else
+			tps->cb = tps6598x_data;
 		/* Enable power status, data status and plug event interrupts */
 		mask1 = TPS_REG_INT_POWER_STATUS_UPDATE |
 			TPS_REG_INT_DATA_STATUS_UPDATE |
 			TPS_REG_INT_PLUG_EVENT;
 	}
 
-	tps->irq_handler = irq_handler;
 	/* Make sure the controller has application firmware running */
 	ret = tps6598x_check_mode(tps);
 	if (ret < 0)
@@ -1125,7 +1203,7 @@ static int tps6598x_probe(struct i2c_client *client)
 
 	if (client->irq) {
 		ret = devm_request_threaded_irq(&client->dev, client->irq, NULL,
-						irq_handler,
+						tps->cb.irq_handler,
 						IRQF_SHARED | IRQF_ONESHOT,
 						dev_name(&client->dev), tps);
 	} else {
-- 
2.34.1


  parent reply	other threads:[~2023-09-27 17:57 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-27 17:53 [PATCH v7 00/14] Add TPS25750 USB type-C PD controller support Abdel Alkuor
2023-09-27 17:53 ` [PATCH v7 01/14] dt-bindings: usb: tps6598x: Add tps25750 Abdel Alkuor
2023-09-28  5:37   ` Krzysztof Kozlowski
2023-09-28  8:06     ` Abdel Alkuor
2023-09-27 17:53 ` [PATCH v7 02/14] USB: typec: tsp6598x: Add cmd timeout and response delay Abdel Alkuor
2023-09-29  8:52   ` Heikki Krogerus
2023-09-27 17:53 ` [PATCH v7 03/14] USB: typec: tps6598x: Add patch mode to tps6598x Abdel Alkuor
2023-09-29 10:11   ` Heikki Krogerus
2023-09-27 17:53 ` [PATCH v7 04/14] USB: typec: tps6598x: Load TPS25750 patch bundle Abdel Alkuor
2023-09-29 10:29   ` Heikki Krogerus
2023-09-27 17:53 ` [PATCH v7 05/14] USB: typec: tps6598x: Check for EEPROM present Abdel Alkuor
2023-09-27 17:53 ` [PATCH v7 06/14] USB: typec: tps6598x: Clear dead battery flag Abdel Alkuor
2023-09-27 17:53 ` [PATCH v7 07/14] USB: typec: tps6598x: Apply patch again after power resume Abdel Alkuor
2023-09-27 17:53 ` Abdel Alkuor [this message]
2023-09-29 10:43   ` [PATCH v7 08/14] USB: typec: tps6598x: Add interrupt support for TPS25750 Heikki Krogerus
2023-09-27 17:53 ` [PATCH v7 09/14] USB: typec: tps6598x: Refactor tps6598x port registration Abdel Alkuor
2023-09-27 17:53 ` [PATCH v7 10/14] USB: typec: tps6598x: Add port registration for tps25750 Abdel Alkuor
2023-09-27 17:53 ` [PATCH v7 11/14] USB: typec: tps6598x: Enable sleep mode " Abdel Alkuor
2023-09-27 17:53 ` [PATCH v7 12/14] USB: typec: tps6598x: Add trace for tps25750 irq Abdel Alkuor
2023-09-27 17:53 ` [PATCH v7 13/14] USB: typec: tps6598x: Add power status trace for tps25750 Abdel Alkuor
2023-09-27 17:53 ` [PATCH v7 14/14] USB: typec: tps6598x: Add " Abdel Alkuor

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=20230927175348.18041-9-alkuor@gmail.com \
    --to=alkuor@gmail.com \
    --cc=abdelalkuor@geotab.com \
    --cc=bryan.odonoghue@linaro.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=heikki.krogerus@linux.intel.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=ryan.eleceng@gmail.com \
    /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.