HID: intel-thc-hid: Intel-thc: Add more frequency support for SPI

The Nova Lake platform enhances THC with half divider capability for
clock division, allowing more granular frequency control for the THC
SPI port.

Supported frequencies include 50MHz (125MHz/2.5), 35MHz (125MHz/3.5),
and 10MHz (125MHz/8/1.5).

Signed-off-by: Even Xu <even.xu@intel.com>
Tested-by: Rui Zhang <rui1.zhang@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
This commit is contained in:
Even Xu
2026-03-18 11:22:04 +08:00
committed by Jiri Kosina
parent 4ba38ee380
commit 88919bedab
2 changed files with 51 additions and 0 deletions

View File

@@ -1112,12 +1112,15 @@ int thc_port_select(struct thc_device *dev, enum thc_port_type port_type)
EXPORT_SYMBOL_NS_GPL(thc_port_select, "INTEL_THC");
#define THC_SPI_FREQUENCY_7M 7812500
#define THC_SPI_FREQUENCY_10M 10416700
#define THC_SPI_FREQUENCY_15M 15625000
#define THC_SPI_FREQUENCY_17M 17857100
#define THC_SPI_FREQUENCY_20M 20833000
#define THC_SPI_FREQUENCY_25M 25000000
#define THC_SPI_FREQUENCY_31M 31250000
#define THC_SPI_FREQUENCY_35M 35714200
#define THC_SPI_FREQUENCY_41M 41666700
#define THC_SPI_FREQUENCY_50M 50000000
#define THC_SPI_LOW_FREQUENCY THC_SPI_FREQUENCY_17M
@@ -1125,21 +1128,27 @@ static u8 thc_get_spi_freq_div_val(struct thc_device *dev, u32 spi_freq_val)
{
static const int frequency[] = {
THC_SPI_FREQUENCY_7M,
THC_SPI_FREQUENCY_10M,
THC_SPI_FREQUENCY_15M,
THC_SPI_FREQUENCY_17M,
THC_SPI_FREQUENCY_20M,
THC_SPI_FREQUENCY_25M,
THC_SPI_FREQUENCY_31M,
THC_SPI_FREQUENCY_35M,
THC_SPI_FREQUENCY_41M,
THC_SPI_FREQUENCY_50M,
};
static const u8 frequency_div[] = {
THC_SPI_FRQ_DIV_2,
THC_SPI_FRQ_DIV_1,
THC_SPI_FRQ_DIV_1,
THC_SPI_FRQ_DIV_7,
THC_SPI_FRQ_DIV_6,
THC_SPI_FRQ_DIV_5,
THC_SPI_FRQ_DIV_4,
THC_SPI_FRQ_DIV_3,
THC_SPI_FRQ_DIV_3,
THC_SPI_FRQ_DIV_2,
};
int size = ARRAY_SIZE(frequency);
u32 closest_freq;
@@ -1190,6 +1199,25 @@ int thc_spi_read_config(struct thc_device *dev, u32 spi_freq_val,
if (spi_freq_val < THC_SPI_LOW_FREQUENCY)
is_low_freq = true;
/* 10M, 35M and 50M CLK need 1.5, 3.5 and 2.5 half divider */
if ((freq_div == THC_SPI_FRQ_DIV_2 && spi_freq_val >= THC_SPI_FREQUENCY_50M) ||
(freq_div == THC_SPI_FRQ_DIV_3 && spi_freq_val < THC_SPI_FREQUENCY_41M) ||
(freq_div == THC_SPI_FRQ_DIV_1 && spi_freq_val < THC_SPI_FREQUENCY_15M)) {
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_DUTYC_CFG_OFFSET,
THC_M_PRT_SPI_DUTYC_CFG_SPI_TCRF_HALF_DIV_EN,
THC_M_PRT_SPI_DUTYC_CFG_SPI_TCRF_HALF_DIV_EN);
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPARE_REG_OFFSET,
THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE,
THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE);
} else {
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_DUTYC_CFG_OFFSET,
THC_M_PRT_SPI_DUTYC_CFG_SPI_TCRF_HALF_DIV_EN, 0);
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPARE_REG_OFFSET,
THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE, 0);
}
cfg = FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TCRF, freq_div) |
FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TRMODE, io_mode) |
(is_low_freq ? THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN : 0) |
@@ -1243,6 +1271,25 @@ int thc_spi_write_config(struct thc_device *dev, u32 spi_freq_val,
if (spi_freq_val < THC_SPI_LOW_FREQUENCY)
is_low_freq = true;
/* 10M, 35M and 50M CLK need 1.5, 3.5 and 2.5 half divider */
if ((freq_div == THC_SPI_FRQ_DIV_2 && spi_freq_val >= THC_SPI_FREQUENCY_50M) ||
(freq_div == THC_SPI_FRQ_DIV_3 && spi_freq_val < THC_SPI_FREQUENCY_41M) ||
(freq_div == THC_SPI_FRQ_DIV_1 && spi_freq_val < THC_SPI_FREQUENCY_15M)) {
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_DUTYC_CFG_OFFSET,
THC_M_PRT_SPI_DUTYC_CFG_SPI_TCWF_HALF_DIV_EN,
THC_M_PRT_SPI_DUTYC_CFG_SPI_TCWF_HALF_DIV_EN);
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPARE_REG_OFFSET,
THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE,
THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE);
} else {
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_DUTYC_CFG_OFFSET,
THC_M_PRT_SPI_DUTYC_CFG_SPI_TCWF_HALF_DIV_EN, 0);
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPARE_REG_OFFSET,
THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE, 0);
}
cfg = FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TCWF, freq_div) |
FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TWMODE, io_mode) |
(is_low_freq ? THC_M_PRT_SPI_CFG_SPI_LOW_FREQ_EN : 0) |

View File

@@ -643,6 +643,10 @@
#define THC_M_PRT_SPI_DUTYC_CFG_SPI_CSA_CK_DELAY_VAL GENMASK(3, 0)
#define THC_M_PRT_SPI_DUTYC_CFG_SPI_CSA_CK_DELAY_EN BIT(25)
#define THC_M_PRT_SPI_DUTYC_CFG_SPI_TCRF_HALF_DIV_EN BIT(30)
#define THC_M_PRT_SPI_DUTYC_CFG_SPI_TCWF_HALF_DIV_EN BIT(31)
#define THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE BIT(2)
/* CS Assertion delay default value */
#define THC_CSA_CK_DELAY_VAL_DEFAULT 4