Skip to content

Commit 4751113

Browse files
EvenxfJiri Kosina
authored andcommitted
HID: intel-thc-hid: intel-quickspi: Add THC QuickSPI driver hid layer
Add HID Low level driver callbacks and hid probe function to register QucikSPI as a HID driver, and external touch device as a HID device. Co-developed-by: Xinpeng Sun <[email protected]> Signed-off-by: Xinpeng Sun <[email protected]> Signed-off-by: Even Xu <[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 c8f3027 commit 4751113

File tree

5 files changed

+205
-0
lines changed

5 files changed

+205
-0
lines changed

drivers/hid/intel-thc-hid/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ intel-thc-objs += intel-thc/intel-thc-dma.o
1111

1212
obj-$(CONFIG_INTEL_QUICKSPI) += intel-quickspi.o
1313
intel-quickspi-objs += intel-quickspi/pci-quickspi.o
14+
intel-quickspi-objs += intel-quickspi/quickspi-hid.o
1415

1516
ccflags-y += -I $(src)/intel-thc

drivers/hid/intel-thc-hid/intel-quickspi/quickspi-dev.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#ifndef _QUICKSPI_DEV_H_
55
#define _QUICKSPI_DEV_H_
66

7+
#include <linux/hid-over-spi.h>
8+
79
#define PCI_DEVICE_ID_INTEL_THC_MTL_DEVICE_ID_SPI_PORT1 0x7E49
810
#define PCI_DEVICE_ID_INTEL_THC_MTL_DEVICE_ID_SPI_PORT2 0x7E4B
911
#define PCI_DEVICE_ID_INTEL_THC_LNL_DEVICE_ID_SPI_PORT1 0xA849
@@ -38,24 +40,33 @@ struct quickspi_driver_data {
3840
struct device;
3941
struct pci_dev;
4042
struct thc_device;
43+
struct hid_device;
4144

4245
/**
4346
* struct quickspi_device - THC QuickSpi device struct
4447
* @dev: point to kernel device
4548
* @pdev: point to PCI device
4649
* @thc_hw: point to THC device
50+
* @hid_dev: point to hid device
4751
* @driver_data: point to quickspi specific driver data
4852
* @state: THC SPI device state
4953
* @mem_addr: MMIO memory address
54+
* @dev_desc: device descriptor for HIDSPI protocol
55+
* @report_descriptor: store a copy of device report descriptor
5056
*/
5157
struct quickspi_device {
5258
struct device *dev;
5359
struct pci_dev *pdev;
5460
struct thc_device *thc_hw;
61+
struct hid_device *hid_dev;
5562
struct quickspi_driver_data *driver_data;
5663
enum quickspi_dev_state state;
5764

5865
void __iomem *mem_addr;
66+
67+
struct hidspi_dev_descriptor dev_desc;
68+
69+
u8 *report_descriptor;
5970
};
6071

6172
#endif /* _QUICKSPI_DEV_H_ */
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (c) 2024 Intel Corporation */
3+
4+
#include <linux/hid.h>
5+
#include <linux/input.h>
6+
7+
#include "quickspi-dev.h"
8+
#include "quickspi-hid.h"
9+
10+
/**
11+
* quickspi_hid_parse() - HID core parse() callback
12+
*
13+
* @hid: HID device instance
14+
*
15+
* This function gets called during call to hid_add_device
16+
*
17+
* Return: 0 on success and non zero on error.
18+
*/
19+
static int quickspi_hid_parse(struct hid_device *hid)
20+
{
21+
struct quickspi_device *qsdev = hid->driver_data;
22+
23+
if (qsdev->report_descriptor)
24+
return hid_parse_report(hid, qsdev->report_descriptor,
25+
le16_to_cpu(qsdev->dev_desc.rep_desc_len));
26+
27+
dev_err(qsdev->dev, "invalid report descriptor\n");
28+
return -EINVAL;
29+
}
30+
31+
static int quickspi_hid_start(struct hid_device *hid)
32+
{
33+
return 0;
34+
}
35+
36+
static void quickspi_hid_stop(struct hid_device *hid)
37+
{
38+
}
39+
40+
static int quickspi_hid_open(struct hid_device *hid)
41+
{
42+
return 0;
43+
}
44+
45+
static void quickspi_hid_close(struct hid_device *hid)
46+
{
47+
}
48+
49+
static int quickspi_hid_raw_request(struct hid_device *hid,
50+
unsigned char reportnum,
51+
__u8 *buf, size_t len,
52+
unsigned char rtype, int reqtype)
53+
{
54+
return 0;
55+
}
56+
57+
static int quickspi_hid_power(struct hid_device *hid, int lvl)
58+
{
59+
return 0;
60+
}
61+
62+
static struct hid_ll_driver quickspi_hid_ll_driver = {
63+
.parse = quickspi_hid_parse,
64+
.start = quickspi_hid_start,
65+
.stop = quickspi_hid_stop,
66+
.open = quickspi_hid_open,
67+
.close = quickspi_hid_close,
68+
.power = quickspi_hid_power,
69+
.raw_request = quickspi_hid_raw_request,
70+
};
71+
72+
/**
73+
* quickspi_hid_probe() - Register HID low level driver
74+
*
75+
* @qsdev: point to quickspi device
76+
*
77+
* This function is used to allocate and add HID device.
78+
*
79+
* Return: 0 on success, non zero on error.
80+
*/
81+
int quickspi_hid_probe(struct quickspi_device *qsdev)
82+
{
83+
struct hid_device *hid;
84+
int ret;
85+
86+
hid = hid_allocate_device();
87+
if (IS_ERR(hid))
88+
return PTR_ERR(hid);
89+
90+
hid->ll_driver = &quickspi_hid_ll_driver;
91+
hid->bus = BUS_PCI;
92+
hid->dev.parent = qsdev->dev;
93+
hid->driver_data = qsdev;
94+
hid->version = le16_to_cpu(qsdev->dev_desc.version_id);
95+
hid->vendor = le16_to_cpu(qsdev->dev_desc.vendor_id);
96+
hid->product = le16_to_cpu(qsdev->dev_desc.product_id);
97+
snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X", "quickspi-hid",
98+
hid->vendor, hid->product);
99+
100+
ret = hid_add_device(hid);
101+
if (ret) {
102+
hid_destroy_device(hid);
103+
return ret;
104+
}
105+
106+
qsdev->hid_dev = hid;
107+
108+
return 0;
109+
}
110+
111+
/**
112+
* quickspi_hid_remove() - Destroy HID device
113+
*
114+
* @qsdev: point to quickspi device
115+
*
116+
* Return: 0 on success, non zero on error.
117+
*/
118+
void quickspi_hid_remove(struct quickspi_device *qsdev)
119+
{
120+
hid_destroy_device(qsdev->hid_dev);
121+
}
122+
123+
/**
124+
* quickspi_hid_send_report() - Send HID input report data to HID core
125+
*
126+
* @qsdev: point to quickspi device
127+
* @data: point to input report data buffer
128+
* @data_len: the length of input report data
129+
*
130+
* Return: 0 on success, non zero on error.
131+
*/
132+
int quickspi_hid_send_report(struct quickspi_device *qsdev,
133+
void *data, size_t data_len)
134+
{
135+
int ret;
136+
137+
ret = hid_input_report(qsdev->hid_dev, HID_INPUT_REPORT, data, data_len, 1);
138+
if (ret)
139+
dev_err(qsdev->dev, "Failed to send HID input report, ret = %d.\n", ret);
140+
141+
return ret;
142+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright (c) 2024 Intel Corporation */
3+
4+
#ifndef _QUICKSPI_HID_H_
5+
#define _QUICKSPI_HID_H_
6+
7+
struct quickspi_device;
8+
9+
int quickspi_hid_send_report(struct quickspi_device *qsdev,
10+
void *data, size_t data_size);
11+
int quickspi_hid_probe(struct quickspi_device *qsdev);
12+
void quickspi_hid_remove(struct quickspi_device *qsdev);
13+
14+
#endif /* _QUICKSPI_HID_H_ */

include/linux/hid-over-spi.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/* Copyright 2024 Intel Corporation */
3+
4+
#ifndef _HID_OVER_SPI_H_
5+
#define _HID_OVER_SPI_H_
6+
7+
/**
8+
* struct hidspi_dev_descriptor - HIDSPI device descriptor definition
9+
* @dev_desc_len: The length of the complete device descriptor, fixed to 0x18 (24).
10+
* @bcd_ver: The version number of the HIDSPI protocol supported.
11+
* In binary coded decimal (BCD) format. Must be fixed to 0x0300.
12+
* @rep_desc_len: The length of the report descriptor
13+
* @max_input_len: The length of the largest possible HID input (or feature) report
14+
* @max_output_len: The length of the largest output (or feature) report
15+
* @max_frag_len: The length of the largest fragment, where a fragment represents
16+
* the body of an input report.
17+
* @vendor_id: Device manufacturers vendor ID
18+
* @product_id: Device unique model/product ID
19+
* @version_id: Device’s unique version
20+
* @flags: Specify flags for the device’s operation
21+
* @reserved: Reserved and should be 0
22+
*/
23+
struct hidspi_dev_descriptor {
24+
__le16 dev_desc_len;
25+
__le16 bcd_ver;
26+
__le16 rep_desc_len;
27+
__le16 max_input_len;
28+
__le16 max_output_len;
29+
__le16 max_frag_len;
30+
__le16 vendor_id;
31+
__le16 product_id;
32+
__le16 version_id;
33+
__le16 flags;
34+
__le32 reserved;
35+
};
36+
37+
#endif /* _HID_OVER_SPI_H_ */

0 commit comments

Comments
 (0)