Skip to content

Commit 1b2d053

Browse files
sunxinpengJiri Kosina
authored andcommitted
HID: intel-thc-hid: Add basic THC driver skeleton
Create intel-thc-hid folder and add Kconfig and Makefile for THC drivers. Add basic THC device context structure, definitions and related initialization APIs for THC Hardware layer driver. Also initialize regmap struct for future THC registers access. Co-developed-by: Even Xu <[email protected]> Signed-off-by: Even Xu <[email protected]> Signed-off-by: Xinpeng Sun <[email protected]> Tested-by: Rui Zhang <[email protected]> Tested-by: Mark Pearson <[email protected]> Reviewed-by: Srinivas Pandruvada <[email protected]> Reviewed-by: Mark Pearson <[email protected]> Tested-by: Aaron Ma <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent df3a78d commit 1b2d053

File tree

7 files changed

+285
-0
lines changed

7 files changed

+285
-0
lines changed

MAINTAINERS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11873,6 +11873,12 @@ S: Maintained
1187311873
F: arch/x86/include/asm/intel_telemetry.h
1187411874
F: drivers/platform/x86/intel/telemetry/
1187511875

11876+
INTEL TOUCH HOST CONTROLLER (THC) DRIVER
11877+
M: Even Xu <[email protected]>
11878+
M: Xinpeng Sun <[email protected]>
11879+
S: Maintained
11880+
F: drivers/hid/intel-thc-hid/
11881+
1187611882
INTEL TPMI DRIVER
1187711883
M: Srinivas Pandruvada <[email protected]>
1187811884

drivers/hid/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,4 +1386,6 @@ source "drivers/hid/amd-sfh-hid/Kconfig"
13861386

13871387
source "drivers/hid/surface-hid/Kconfig"
13881388

1389+
source "drivers/hid/intel-thc-hid/Kconfig"
1390+
13891391
endif # HID_SUPPORT

drivers/hid/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,5 @@ obj-$(INTEL_ISH_FIRMWARE_DOWNLOADER) += intel-ish-hid/
171171
obj-$(CONFIG_AMD_SFH_HID) += amd-sfh-hid/
172172

173173
obj-$(CONFIG_SURFACE_HID_CORE) += surface-hid/
174+
175+
obj-$(CONFIG_INTEL_THC_HID) += intel-thc-hid/

drivers/hid/intel-thc-hid/Kconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
# Copyright (c) 2024, Intel Corporation.
3+
4+
menu "Intel THC HID Support"
5+
depends on X86_64 && PCI
6+
7+
config INTEL_THC_HID
8+
tristate "Intel Touch Host Controller"
9+
select HID
10+
help
11+
THC (Touch Host Controller) is the name of the IP block in PCH that
12+
interfaces with Touch Devices (ex: touchscreen, touchpad etc.). It
13+
is comprised of 3 key functional blocks: A natively half-duplex
14+
Quad I/O capable SPI master; a low latency I2C interface to support
15+
HIDI2C compliant devices; a hardware sequencer with Read/Write DMA
16+
capability to system memory.
17+
18+
Say Y/M here if you want to support Intel THC. If unsure, say N.
19+
20+
endmenu

drivers/hid/intel-thc-hid/Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# SPDX-License-Identifier: GPL-2.0
2+
#
3+
# Makefile - Intel Touch Host Controller (THC) drivers
4+
# Copyright (c) 2024, Intel Corporation.
5+
#
6+
#
7+
8+
obj-$(CONFIG_INTEL_THC_HID) += intel-thc.o
9+
intel-thc-objs += intel-thc/intel-thc-dev.o
10+
11+
ccflags-y += -I $(src)/intel-thc
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (c) 2024 Intel Corporation */
3+
4+
#include <linux/regmap.h>
5+
6+
#include "intel-thc-dev.h"
7+
8+
static int thc_regmap_read(void *context, unsigned int reg,
9+
unsigned int *val)
10+
{
11+
struct thc_device *thc_ctx = context;
12+
void __iomem *base = thc_ctx->mmio_addr;
13+
14+
*val = ioread32(base + reg);
15+
return 0;
16+
}
17+
18+
static int thc_regmap_write(void *context, unsigned int reg,
19+
unsigned int val)
20+
{
21+
struct thc_device *thc_ctx = context;
22+
void __iomem *base = thc_ctx->mmio_addr;
23+
24+
iowrite32(val, base + reg);
25+
return 0;
26+
}
27+
28+
static const struct regmap_range thc_rw_ranges[] = {
29+
regmap_reg_range(0x10, 0x14),
30+
regmap_reg_range(0x1000, 0x1320),
31+
};
32+
33+
static const struct regmap_access_table thc_rw_table = {
34+
.yes_ranges = thc_rw_ranges,
35+
.n_yes_ranges = ARRAY_SIZE(thc_rw_ranges),
36+
};
37+
38+
static const struct regmap_config thc_regmap_cfg = {
39+
.name = "thc_regmap_common",
40+
.reg_bits = 32,
41+
.val_bits = 32,
42+
.reg_stride = 4,
43+
.max_register = 0x1320,
44+
.reg_read = thc_regmap_read,
45+
.reg_write = thc_regmap_write,
46+
.cache_type = REGCACHE_NONE,
47+
.fast_io = true,
48+
.rd_table = &thc_rw_table,
49+
.wr_table = &thc_rw_table,
50+
.volatile_table = &thc_rw_table,
51+
};
52+
53+
/**
54+
* thc_clear_state - Clear THC hardware state
55+
*
56+
* @dev: The pointer of THC device structure
57+
*/
58+
static void thc_clear_state(const struct thc_device *dev)
59+
{
60+
u32 val;
61+
62+
/* Clear interrupt cause register */
63+
val = THC_M_PRT_ERR_CAUSE_INVLD_DEV_ENTRY |
64+
THC_M_PRT_ERR_CAUSE_FRAME_BABBLE_ERR |
65+
THC_M_PRT_ERR_CAUSE_BUF_OVRRUN_ERR |
66+
THC_M_PRT_ERR_CAUSE_PRD_ENTRY_ERR;
67+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_ERR_CAUSE_OFFSET, val, val);
68+
69+
/* Clear interrupt error state */
70+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_1_OFFSET,
71+
THC_M_PRT_READ_DMA_CNTRL_IE_STALL,
72+
THC_M_PRT_READ_DMA_CNTRL_IE_STALL);
73+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_2_OFFSET,
74+
THC_M_PRT_READ_DMA_CNTRL_IE_STALL,
75+
THC_M_PRT_READ_DMA_CNTRL_IE_STALL);
76+
77+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
78+
THC_M_PRT_INT_STATUS_TXN_ERR_INT_STS,
79+
THC_M_PRT_INT_STATUS_TXN_ERR_INT_STS);
80+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_INT_STATUS_OFFSET,
81+
THC_M_PRT_INT_STATUS_FATAL_ERR_INT_STS,
82+
THC_M_PRT_INT_STATUS_FATAL_ERR_INT_STS);
83+
84+
val = THC_M_PRT_INT_EN_TXN_ERR_INT_EN |
85+
THC_M_PRT_INT_EN_FATAL_ERR_INT_EN |
86+
THC_M_PRT_INT_EN_BUF_OVRRUN_ERR_INT_EN;
87+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_INT_EN_OFFSET, val, val);
88+
89+
val = THC_M_PRT_SW_SEQ_STS_THC_SS_ERR |
90+
THC_M_PRT_SW_SEQ_STS_TSSDONE;
91+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SW_SEQ_STS_OFFSET, val, val);
92+
93+
/* Clear RxDMA state */
94+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_1_OFFSET,
95+
THC_M_PRT_READ_DMA_CNTRL_IE_EOF, 0);
96+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_2_OFFSET,
97+
THC_M_PRT_READ_DMA_CNTRL_IE_EOF, 0);
98+
99+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_INT_STS_1_OFFSET,
100+
THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS,
101+
THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS);
102+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_INT_STS_2_OFFSET,
103+
THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS,
104+
THC_M_PRT_READ_DMA_INT_STS_EOF_INT_STS);
105+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_INT_STS_1_OFFSET,
106+
THC_M_PRT_READ_DMA_INT_STS_NONDMA_INT_STS,
107+
THC_M_PRT_READ_DMA_INT_STS_NONDMA_INT_STS);
108+
109+
/* Clear TxDMA state */
110+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_WRITE_DMA_CNTRL_OFFSET,
111+
THC_M_PRT_WRITE_DMA_CNTRL_THC_WRDMA_IE_IOC_DMACPL,
112+
THC_M_PRT_WRITE_DMA_CNTRL_THC_WRDMA_IE_IOC_DMACPL);
113+
114+
val = THC_M_PRT_WRITE_INT_STS_THC_WRDMA_ERROR_STS |
115+
THC_M_PRT_WRITE_INT_STS_THC_WRDMA_IOC_STS |
116+
THC_M_PRT_WRITE_INT_STS_THC_WRDMA_CMPL_STATUS;
117+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_WRITE_INT_STS_OFFSET, val, val);
118+
119+
/* Reset all DMAs count */
120+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_DB_CNT_1_OFFSET,
121+
THC_M_PRT_DB_CNT_1_THC_M_PRT_DB_CNT_RST,
122+
THC_M_PRT_DB_CNT_1_THC_M_PRT_DB_CNT_RST);
123+
124+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_DEVINT_CNT_OFFSET,
125+
THC_M_PRT_DEVINT_CNT_THC_M_PRT_DEVINT_CNT_RST,
126+
THC_M_PRT_DEVINT_CNT_THC_M_PRT_DEVINT_CNT_RST);
127+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_READ_DMA_CNTRL_1_OFFSET,
128+
THC_M_PRT_READ_DMA_CNTRL_TPCPR,
129+
THC_M_PRT_READ_DMA_CNTRL_TPCPR);
130+
131+
/* Reset THC hardware sequence state */
132+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_FRAME_DROP_CNT_1_OFFSET,
133+
THC_M_PRT_FRAME_DROP_CNT_1_RFDC,
134+
THC_M_PRT_FRAME_DROP_CNT_1_RFDC);
135+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_FRAME_DROP_CNT_2_OFFSET,
136+
THC_M_PRT_FRAME_DROP_CNT_2_RFDC,
137+
THC_M_PRT_FRAME_DROP_CNT_2_RFDC);
138+
139+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_FRM_CNT_1_OFFSET,
140+
THC_M_PRT_FRM_CNT_1_THC_M_PRT_FRM_CNT_RST,
141+
THC_M_PRT_FRM_CNT_1_THC_M_PRT_FRM_CNT_RST);
142+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_FRM_CNT_2_OFFSET,
143+
THC_M_PRT_FRM_CNT_2_THC_M_PRT_FRM_CNT_RST,
144+
THC_M_PRT_FRM_CNT_2_THC_M_PRT_FRM_CNT_RST);
145+
146+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_RXDMA_PKT_CNT_1_OFFSET,
147+
THC_M_PRT_RXDMA_PKT_CNT_1_THC_M_PRT_RXDMA_PKT_CNT_RST,
148+
THC_M_PRT_RXDMA_PKT_CNT_1_THC_M_PRT_RXDMA_PKT_CNT_RST);
149+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_RXDMA_PKT_CNT_2_OFFSET,
150+
THC_M_PRT_RXDMA_PKT_CNT_2_THC_M_PRT_RXDMA_PKT_CNT_RST,
151+
THC_M_PRT_RXDMA_PKT_CNT_2_THC_M_PRT_RXDMA_PKT_CNT_RST);
152+
153+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SWINT_CNT_1_OFFSET,
154+
THC_M_PRT_SWINT_CNT_1_THC_M_PRT_SWINT_CNT_RST,
155+
THC_M_PRT_SWINT_CNT_1_THC_M_PRT_SWINT_CNT_RST);
156+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_SWINT_CNT_1_OFFSET,
157+
THC_M_PRT_SWINT_CNT_1_THC_M_PRT_SWINT_CNT_RST,
158+
THC_M_PRT_SWINT_CNT_1_THC_M_PRT_SWINT_CNT_RST);
159+
160+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_TX_FRM_CNT_OFFSET,
161+
THC_M_PRT_TX_FRM_CNT_THC_M_PRT_TX_FRM_CNT_RST,
162+
THC_M_PRT_TX_FRM_CNT_THC_M_PRT_TX_FRM_CNT_RST);
163+
164+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_TXDMA_PKT_CNT_OFFSET,
165+
THC_M_PRT_TXDMA_PKT_CNT_THC_M_PRT_TXDMA_PKT_CNT_RST,
166+
THC_M_PRT_TXDMA_PKT_CNT_THC_M_PRT_TXDMA_PKT_CNT_RST);
167+
168+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_UFRM_CNT_1_OFFSET,
169+
THC_M_PRT_UFRM_CNT_1_THC_M_PRT_UFRM_CNT_RST,
170+
THC_M_PRT_UFRM_CNT_1_THC_M_PRT_UFRM_CNT_RST);
171+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_UFRM_CNT_2_OFFSET,
172+
THC_M_PRT_UFRM_CNT_2_THC_M_PRT_UFRM_CNT_RST,
173+
THC_M_PRT_UFRM_CNT_2_THC_M_PRT_UFRM_CNT_RST);
174+
175+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_PRD_EMPTY_CNT_1_OFFSET,
176+
THC_M_PRT_PRD_EMPTY_CNT_1_RPTEC,
177+
THC_M_PRT_PRD_EMPTY_CNT_1_RPTEC);
178+
regmap_write_bits(dev->thc_regmap, THC_M_PRT_PRD_EMPTY_CNT_2_OFFSET,
179+
THC_M_PRT_PRD_EMPTY_CNT_2_RPTEC,
180+
THC_M_PRT_PRD_EMPTY_CNT_2_RPTEC);
181+
}
182+
183+
/**
184+
* thc_dev_init - Allocate and initialize the THC device structure
185+
*
186+
* @device: The pointer of device structure
187+
* @mem_addr: The pointer of MMIO memory address
188+
*
189+
* Return: The thc_device pointer on success, NULL on failed.
190+
*/
191+
struct thc_device *thc_dev_init(struct device *device, void __iomem *mem_addr)
192+
{
193+
struct thc_device *thc_dev;
194+
int ret;
195+
196+
thc_dev = devm_kzalloc(device, sizeof(*thc_dev), GFP_KERNEL);
197+
if (!thc_dev)
198+
return ERR_PTR(-ENOMEM);
199+
200+
thc_dev->dev = device;
201+
thc_dev->mmio_addr = mem_addr;
202+
thc_dev->thc_regmap = devm_regmap_init(device, NULL, thc_dev, &thc_regmap_cfg);
203+
if (IS_ERR(thc_dev->thc_regmap)) {
204+
ret = PTR_ERR(thc_dev->thc_regmap);
205+
dev_err_once(device, "Failed to init thc_regmap: %d\n", ret);
206+
return ERR_PTR(ret);
207+
}
208+
209+
thc_clear_state(thc_dev);
210+
211+
return thc_dev;
212+
}
213+
EXPORT_SYMBOL_NS_GPL(thc_dev_init, "INTEL_THC");
214+
215+
MODULE_AUTHOR("Xinpeng Sun <[email protected]>");
216+
MODULE_AUTHOR("Even Xu <[email protected]>");
217+
218+
MODULE_DESCRIPTION("Intel(R) Intel THC Hardware Driver");
219+
MODULE_LICENSE("GPL");
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (c) 2024 Intel Corporation */
3+
4+
#ifndef _INTEL_THC_DEV_H_
5+
#define _INTEL_THC_DEV_H_
6+
7+
#include <linux/cdev.h>
8+
9+
#define THC_REGMAP_COMMON_OFFSET 0x10
10+
#define THC_REGMAP_MMIO_OFFSET 0x1000
11+
12+
/**
13+
* struct thc_device - THC private device struct
14+
* @thc_regmap: MMIO regmap structure for accessing THC registers
15+
* @mmio_addr: MMIO registers address
16+
*/
17+
struct thc_device {
18+
struct device *dev;
19+
struct regmap *thc_regmap;
20+
void __iomem *mmio_addr;
21+
};
22+
23+
struct thc_device *thc_dev_init(struct device *device, void __iomem *mem_addr);
24+
25+
#endif /* _INTEL_THC_DEV_H_ */

0 commit comments

Comments
 (0)