All of lore.kernel.org
 help / color / mirror / Atom feed
From: Even Xu <even.xu@intel.com>
To: bentiss@kernel.org, jikos@kernel.org
Cc: srinivas.pandruvada@linux.intel.com, linux-input@vger.kernel.org,
	linux-kernel@vger.kernel.org, Even Xu <even.xu@intel.com>
Subject: [PATCH 1/2] HID: Intel-thc-hid: Intel-thc: Refactor I2C bus configuration with unified config structure
Date: Mon, 27 Jul 2026 11:03:09 +0800	[thread overview]
Message-ID: <20260727030310.3850984-2-even.xu@intel.com> (raw)
In-Reply-To: <20260727030310.3850984-1-even.xu@intel.com>

Introduce a new struct thc_i2c_config to consolidate all configurable
I2C bus parameters into a single structure for better maintainability
and extensibility.

Changes include:
- Add struct thc_i2c_config to encapsulate I2C bus parameters
- Rename thc_i2c_subip_set_speed() to thc_i2c_subip_bus_config() to
  better reflect its expanded functionality
- Update thc_i2c_subip_bus_config() to accept struct thc_i2c_config
  parameter for comprehensive I2C parameter configuration
- Modify thc_i2c_subip_init() to use struct thc_i2c_config and call
  thc_i2c_subip_bus_config() for complete bus initialization

This refactoring improves code organization and unifies I2C configuration
parameters.

Signed-off-by: Even Xu <even.xu@intel.com>
---
 .../intel-thc-hid/intel-thc/intel-thc-dev.c   | 69 ++++++++++++-------
 .../intel-thc-hid/intel-thc/intel-thc-dev.h   | 23 ++++++-
 .../intel-thc-hid/intel-thc/intel-thc-hw.h    |  3 +
 3 files changed, 68 insertions(+), 27 deletions(-)

diff --git a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
index 9a8449428170..7b4a58e1416d 100644
--- a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
+++ b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
@@ -1422,14 +1422,25 @@ static int thc_i2c_subip_pio_write(struct thc_device *dev, const u32 address,
 #define I2C_SUBIP_DMA_TDLR_DEFAULT	7
 #define I2C_SUBIP_DMA_RDLR_DEFAULT	7
 
-static int thc_i2c_subip_set_speed(struct thc_device *dev, const u32 speed,
-				   const u32 hcnt, const u32 lcnt)
+static int thc_i2c_subip_bus_config(struct thc_device *dev, const struct thc_i2c_config *i2c_config)
 {
 	u32 hcnt_offset, lcnt_offset;
-	u32 val;
+	u32 read_size = sizeof(u32);
+	u32 val = 0;
 	int ret;
 
-	switch (speed) {
+	ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_TAR_OFFSET, &read_size, &val);
+	if (ret < 0)
+		return ret;
+
+	val &= ~(THC_I2C_IC_TAR_IC_TAR | THC_I2C_IC_TAR_IC_10BITADDR_MASTER);
+	val |= FIELD_PREP(THC_I2C_IC_TAR_IC_10BITADDR_MASTER, i2c_config->addr_mode);
+	val |= FIELD_PREP(THC_I2C_IC_TAR_IC_TAR, i2c_config->target_addr);
+	ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_TAR_OFFSET, sizeof(u32), &val);
+	if (ret < 0)
+		return ret;
+
+	switch (i2c_config->speed) {
 	case THC_I2C_STANDARD:
 		hcnt_offset = THC_I2C_IC_SS_SCL_HCNT_OFFSET;
 		lcnt_offset = THC_I2C_IC_SS_SCL_LCNT_OFFSET;
@@ -1446,25 +1457,43 @@ static int thc_i2c_subip_set_speed(struct thc_device *dev, const u32 speed,
 		break;
 
 	default:
-		dev_err_once(dev->dev, "Unsupported i2c speed %d\n", speed);
+		dev_err_once(dev->dev, "Unsupported i2c speed %d\n", i2c_config->speed);
 		ret = -EINVAL;
 		return ret;
 	}
 
-	ret = thc_i2c_subip_pio_write(dev, hcnt_offset, sizeof(u32), &hcnt);
+	ret = thc_i2c_subip_pio_write(dev, hcnt_offset, sizeof(u32), &i2c_config->scl_hcnt);
 	if (ret < 0)
 		return ret;
 
-	ret = thc_i2c_subip_pio_write(dev, lcnt_offset, sizeof(u32), &lcnt);
+	ret = thc_i2c_subip_pio_write(dev, lcnt_offset, sizeof(u32), &i2c_config->scl_lcnt);
 	if (ret < 0)
 		return ret;
 
 	val = I2C_SUBIP_CON_DEFAULT & ~THC_I2C_IC_CON_SPEED;
-	val |= FIELD_PREP(THC_I2C_IC_CON_SPEED, speed);
+	val |= FIELD_PREP(THC_I2C_IC_CON_SPEED, i2c_config->speed);
 	ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_CON_OFFSET, sizeof(u32), &val);
 	if (ret < 0)
 		return ret;
 
+	ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_SDA_HOLD_OFFSET, &read_size, &val);
+	if (ret < 0)
+		return ret;
+
+	if (i2c_config->sda_tx_hold) {
+		val &= ~THC_I2C_IC_SDA_HOLD_IC_SDA_TX_HOLD;
+		val |= FIELD_PREP(THC_I2C_IC_SDA_HOLD_IC_SDA_TX_HOLD, i2c_config->sda_tx_hold);
+	}
+
+	if (i2c_config->sda_rx_hold) {
+		val &= ~THC_I2C_IC_SDA_HOLD_IC_SDA_RX_HOLD;
+		val |= FIELD_PREP(THC_I2C_IC_SDA_HOLD_IC_SDA_RX_HOLD, i2c_config->sda_rx_hold);
+	}
+
+	ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_SDA_HOLD_OFFSET, sizeof(u32), &val);
+	if (ret < 0)
+		return ret;
+
 	return 0;
 }
 
@@ -1474,6 +1503,7 @@ static u32 i2c_subip_regs[] = {
 	THC_I2C_IC_INTR_MASK_OFFSET,
 	THC_I2C_IC_RX_TL_OFFSET,
 	THC_I2C_IC_TX_TL_OFFSET,
+	THC_I2C_IC_SDA_HOLD_OFFSET,
 	THC_I2C_IC_DMA_CR_OFFSET,
 	THC_I2C_IC_DMA_TDLR_OFFSET,
 	THC_I2C_IC_DMA_RDLR_OFFSET,
@@ -1490,20 +1520,19 @@ static u32 i2c_subip_regs[] = {
  * thc_i2c_subip_init - Initialize and configure THC I2C subsystem
  *
  * @dev: The pointer of THC private device context
- * @target_address: Slave address of touch device (TIC)
- * @speed: I2C bus frequency speed mode
- * @hcnt: I2C clock SCL high count
- * @lcnt: I2C clock SCL low count
+ * @i2c_config: The pointer of THC I2C bus configure structure
  *
  * Return: 0 on success, other error codes on failed.
  */
-int thc_i2c_subip_init(struct thc_device *dev, const u32 target_address,
-		       const u32 speed, const u32 hcnt, const u32 lcnt)
+int thc_i2c_subip_init(struct thc_device *dev, const struct thc_i2c_config *i2c_config)
 {
 	u32 read_size = sizeof(u32);
 	u32 val;
 	int ret;
 
+	if (!dev || !i2c_config)
+		return -EINVAL;
+
 	ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_ENABLE_OFFSET, &read_size, &val);
 	if (ret < 0)
 		return ret;
@@ -1513,17 +1542,7 @@ int thc_i2c_subip_init(struct thc_device *dev, const u32 target_address,
 	if (ret < 0)
 		return ret;
 
-	ret = thc_i2c_subip_pio_read(dev, THC_I2C_IC_TAR_OFFSET, &read_size, &val);
-	if (ret < 0)
-		return ret;
-
-	val &= ~THC_I2C_IC_TAR_IC_TAR;
-	val |= FIELD_PREP(THC_I2C_IC_TAR_IC_TAR, target_address);
-	ret = thc_i2c_subip_pio_write(dev, THC_I2C_IC_TAR_OFFSET, sizeof(u32), &val);
-	if (ret < 0)
-		return ret;
-
-	ret = thc_i2c_subip_set_speed(dev, speed, hcnt, lcnt);
+	ret = thc_i2c_subip_bus_config(dev, i2c_config);
 	if (ret < 0)
 		return ret;
 
diff --git a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.h b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.h
index 0db435335e24..be8a9605d02f 100644
--- a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.h
+++ b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.h
@@ -49,6 +49,26 @@ enum thc_int_type {
 	THC_UNKNOWN_INT
 };
 
+/**
+ * struct thc_i2c_config - THC I2C bus configuration
+ * @target_addr: Slave address of touch device (TIC)
+ * @addr_mode: Slave address mode of touch device (TIC), 7bit or 10bit
+ * @speed: I2C bus frequency speed mode
+ * @scl_hcnt: I2C clock SCL high count
+ * @scl_lcnt: I2C clock SCL low count
+ * @sda_tx_hold: I2C Data SDA transmit hold period
+ * @sda_rx_hold: I2C Data SDA receive hold period
+ */
+struct thc_i2c_config {
+	u16 target_addr;
+	u8  addr_mode;
+	u32 speed;
+	u32 scl_hcnt;
+	u32 scl_lcnt;
+	u32 sda_tx_hold;
+	u32 sda_rx_hold;
+};
+
 /**
  * struct thc_device - THC private device struct
  * @thc_regmap: MMIO regmap structure for accessing THC registers
@@ -121,8 +141,7 @@ int thc_spi_write_config(struct thc_device *dev, u32 spi_freq_val,
 			 u32 io_mode, u32 opcode, u32 spi_wr_mps, u32 perf_limit);
 void thc_spi_input_output_address_config(struct thc_device *dev, u32 input_hdr_addr,
 					 u32 input_bdy_addr, u32 output_addr);
-int thc_i2c_subip_init(struct thc_device *dev, const u32 target_address,
-		       const u32 speed, const u32 hcnt, const u32 lcnt);
+int thc_i2c_subip_init(struct thc_device *dev, const struct thc_i2c_config *i2c_config);
 int thc_i2c_subip_regs_save(struct thc_device *dev);
 int thc_i2c_subip_regs_restore(struct thc_device *dev);
 int thc_i2c_set_rx_max_size(struct thc_device *dev, u32 max_rx_size);
diff --git a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-hw.h b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-hw.h
index c6d026686b7a..a21222543ce4 100644
--- a/drivers/hid/intel-thc-hid/intel-thc/intel-thc-hw.h
+++ b/drivers/hid/intel-thc-hid/intel-thc/intel-thc-hw.h
@@ -887,4 +887,7 @@ enum THC_I2C_SPEED_MODE {
 #define THC_I2C_IC_DMA_CR_RDMAE				BIT(0)
 #define THC_I2C_IC_DMA_CR_TDMAE				BIT(1)
 
+#define THC_I2C_IC_SDA_HOLD_IC_SDA_TX_HOLD		GENMASK(15, 0)
+#define THC_I2C_IC_SDA_HOLD_IC_SDA_RX_HOLD		GENMASK(23, 16)
+
 #endif /* _INTEL_THC_HW_H_  */
-- 
2.43.0


  reply	other threads:[~2026-07-27  3:02 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-27  3:03 [PATCH 0/2] HID: Intel-thc-hid: Support complete I2C bus configuration Even Xu
2026-07-27  3:03 ` Even Xu [this message]
2026-07-27  3:15   ` [PATCH 1/2] HID: Intel-thc-hid: Intel-thc: Refactor I2C bus configuration with unified config structure sashiko-bot
2026-07-27  3:03 ` [PATCH 2/2] HID: Intel-thc-hid: Intel-quicki2c: Support full I2C BUS config parameters Even Xu
2026-07-27  3:11   ` sashiko-bot

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=20260727030310.3850984-2-even.xu@intel.com \
    --to=even.xu@intel.com \
    --cc=bentiss@kernel.org \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=srinivas.pandruvada@linux.intel.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.