diff options
| author | Even Xu <even.xu@intel.com> | 2025-05-14 14:19:41 +0800 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.com> | 2025-06-10 21:15:59 +0200 |
| commit | 22da60f0304b6bfd2c7cba8ee88086f344ef5206 (patch) | |
| tree | 6c5d1f11763a78d18a0bec272b33f4c305b9c268 /drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c | |
| parent | 45e92a093099eaf71ff2915a5f6ab5c04c8385e6 (diff) | |
| download | linux-next-22da60f0304b6bfd2c7cba8ee88086f344ef5206.tar.gz linux-next-22da60f0304b6bfd2c7cba8ee88086f344ef5206.zip | |
HID: Intel-thc-hid: Intel-thc: Introduce interrupt delay control
This patch adds support for a new feature, named "Interrupt Delay",
allowing driver to set a specific delay time for next interrupt
detection. It gives driver a capability to control THC waiting time for
the next interrupt, to reduce the likelihood of spurious readings.
APIs added:
- thc_i2c_set_rx_int_delay(): Set I2C Rx input interrupt delay value
- thc_i2c_rx_int_delay_enable(): Enable or disable I2C Rx interrupt delay
As this interrupt delay feature is only applicable to RxDMA and must
remain disabled during SWDMA operations, it also involves a change
in SWDMA code to record the max input size control feature state
before SWDMA and restore the state after SWDMA.
Signed-off-by: Even Xu <even.xu@intel.com>
Tested-by: Chong Han <chong.han@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Diffstat (limited to 'drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c')
| -rw-r--r-- | drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c | 71 |
1 files changed, 71 insertions, 0 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 8fc6e8484cd8..6f2263869b20 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 @@ -2,6 +2,7 @@ /* Copyright (c) 2024 Intel Corporation */ #include <linux/bitfield.h> +#include <linux/math.h> #include <linux/regmap.h> #include "intel-thc-dev.h" @@ -1640,6 +1641,76 @@ int thc_i2c_rx_max_size_enable(struct thc_device *dev, bool enable) } EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_max_size_enable, "INTEL_THC"); +/** + * thc_i2c_set_rx_int_delay - Set I2C Rx input interrupt delay value + * @dev: The pointer of THC private device context + * @delay_us: Interrupt delay value, unit is us + * + * Set @delay_us for I2C RxDMA input interrupt delay feature. + * + * Return: 0 on success, other error codes on failure. + */ +int thc_i2c_set_rx_int_delay(struct thc_device *dev, u32 delay_us) +{ + u32 val; + int ret; + + if (!dev) + return -EINVAL; + + if (!delay_us) + return -EOPNOTSUPP; + + ret = regmap_read(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, &val); + if (ret) + return ret; + + /* THC hardware counts at 10us unit */ + val |= FIELD_PREP(THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL, DIV_ROUND_UP(delay_us, 10)); + + ret = regmap_write(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, val); + if (ret) + return ret; + + dev->i2c_int_delay_us = delay_us; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(thc_i2c_set_rx_int_delay, "INTEL_THC"); + +/** + * thc_i2c_rx_int_delay_enable - Enable I2C Rx interrupt delay + * @dev: The pointer of THC private device context + * @enable: Enable interrupt delay or not + * + * Enable or disable I2C RxDMA input interrupt delay feature. + * Input interrupt delay can only be enabled after interrupt delay value + * was set by thc_i2c_set_rx_int_delay(). + * + * Return: 0 on success, other error codes on failure. + */ +int thc_i2c_rx_int_delay_enable(struct thc_device *dev, bool enable) +{ + u32 mask = THC_M_PRT_SPI_ICRRD_OPCODE_I2C_INTERVAL_EN; + u32 val = enable ? mask : 0; + int ret; + + if (!dev) + return -EINVAL; + + if (!dev->i2c_int_delay_us) + return -EOPNOTSUPP; + + ret = regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_ICRRD_OPCODE_OFFSET, mask, val); + if (ret) + return ret; + + dev->i2c_int_delay_en = enable; + + return 0; +} +EXPORT_SYMBOL_NS_GPL(thc_i2c_rx_int_delay_enable, "INTEL_THC"); + MODULE_AUTHOR("Xinpeng Sun <xinpeng.sun@intel.com>"); MODULE_AUTHOR("Even Xu <even.xu@intel.com>"); |
