Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
a60885b6
Commit
a60885b6
authored
Aug 02, 2022
by
Jiri Kosina
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'for-5.20/uclogic' into for-linus
- XP-PEN Deco L support (José Expósito)
parents
db244339
0cb1fc09
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
581 additions
and
14 deletions
+581
-14
drivers/hid/.kunitconfig
drivers/hid/.kunitconfig
+5
-0
drivers/hid/Kconfig
drivers/hid/Kconfig
+16
-0
drivers/hid/Makefile
drivers/hid/Makefile
+3
-0
drivers/hid/hid-ids.h
drivers/hid/hid-ids.h
+1
-0
drivers/hid/hid-uclogic-core.c
drivers/hid/hid-uclogic-core.c
+2
-0
drivers/hid/hid-uclogic-params.c
drivers/hid/hid-uclogic-params.c
+199
-2
drivers/hid/hid-uclogic-rdesc-test.c
drivers/hid/hid-uclogic-rdesc-test.c
+219
-0
drivers/hid/hid-uclogic-rdesc.c
drivers/hid/hid-uclogic-rdesc.c
+117
-7
drivers/hid/hid-uclogic-rdesc.h
drivers/hid/hid-uclogic-rdesc.h
+19
-5
No files found.
drivers/hid/.kunitconfig
0 → 100644
View file @
a60885b6
CONFIG_KUNIT=y
CONFIG_USB=y
CONFIG_USB_HID=y
CONFIG_HID_UCLOGIC=y
CONFIG_HID_KUNIT_TEST=y
drivers/hid/Kconfig
View file @
a60885b6
...
...
@@ -1306,6 +1306,22 @@ config HID_MCP2221
To compile this driver as a module, choose M here: the module
will be called hid-mcp2221.ko.
config HID_KUNIT_TEST
bool "KUnit tests for HID" if !KUNIT_ALL_TESTS
depends on KUNIT=y
depends on HID_UCLOGIC
default KUNIT_ALL_TESTS
help
This builds unit tests for HID. This option is not useful for
distributions or general kernels, but only for kernel
developers working on HID and associated drivers.
For more information on KUnit and unit tests in general,
please refer to the KUnit documentation in
Documentation/dev-tools/kunit/.
If in doubt, say "N".
endmenu
endif # HID
...
...
drivers/hid/Makefile
View file @
a60885b6
...
...
@@ -144,6 +144,9 @@ obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
obj-$(CONFIG_HID_SENSOR_HUB)
+=
hid-sensor-hub.o
obj-$(CONFIG_HID_SENSOR_CUSTOM_SENSOR)
+=
hid-sensor-custom.o
obj-$(CONFIG_HID_KUNIT_TEST)
+=
hid-uclogic-rdesc.o
\
hid-uclogic-rdesc-test.o
obj-$(CONFIG_USB_HID)
+=
usbhid/
obj-$(CONFIG_USB_MOUSE)
+=
usbhid/
obj-$(CONFIG_USB_KBD)
+=
usbhid/
...
...
drivers/hid/hid-ids.h
View file @
a60885b6
...
...
@@ -1279,6 +1279,7 @@
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540 0x0075
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640 0x0094
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01 0x0042
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L 0x0935
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078
#define USB_DEVICE_ID_UGEE_TABLET_G5 0x0074
#define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071
...
...
drivers/hid/hid-uclogic-core.c
View file @
a60885b6
...
...
@@ -521,6 +521,8 @@ static const struct hid_device_id uclogic_devices[] = {
USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_UGEE
,
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_UGEE
,
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L
)
},
{
HID_USB_DEVICE
(
USB_VENDOR_ID_UGEE
,
USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06
)
},
{
}
...
...
drivers/hid/hid-uclogic-params.c
View file @
a60885b6
...
...
@@ -238,7 +238,7 @@ static int uclogic_params_pen_init_v1(struct uclogic_params_pen *pen,
const
int
len
=
12
;
s32
resolution
;
/* Pen report descriptor template parameters */
s32
desc_params
[
UCLOGIC_RDESC_P
EN_P
H_ID_NUM
];
s32
desc_params
[
UCLOGIC_RDESC_PH_ID_NUM
];
__u8
*
desc_ptr
=
NULL
;
/* Check arguments */
...
...
@@ -383,7 +383,7 @@ static int uclogic_params_pen_init_v2(struct uclogic_params_pen *pen,
size_t
i
;
s32
resolution
;
/* Pen report descriptor template parameters */
s32
desc_params
[
UCLOGIC_RDESC_P
EN_P
H_ID_NUM
];
s32
desc_params
[
UCLOGIC_RDESC_PH_ID_NUM
];
__u8
*
desc_ptr
=
NULL
;
/* Check arguments */
...
...
@@ -1006,6 +1006,197 @@ static int uclogic_params_huion_init(struct uclogic_params *params,
return
rc
;
}
/**
* uclogic_probe_interface() - some tablets, like the Parblo A610 PLUS V2 or
* the XP-PEN Deco Mini 7, need to be initialized by sending them magic data.
*
* @hdev: The HID device of the tablet interface to initialize and get
* parameters from. Cannot be NULL.
* @magic_arr: The magic data that should be sent to probe the interface.
* Cannot be NULL.
* @magic_size: Size of the magic data.
* @endpoint: Endpoint where the magic data should be sent.
*
* Returns:
* Zero, if successful. A negative errno code on error.
*/
static
int
uclogic_probe_interface
(
struct
hid_device
*
hdev
,
u8
*
magic_arr
,
int
magic_size
,
int
endpoint
)
{
struct
usb_device
*
udev
;
unsigned
int
pipe
=
0
;
int
sent
;
u8
*
buf
=
NULL
;
int
rc
=
0
;
if
(
!
hdev
||
!
magic_arr
)
{
rc
=
-
EINVAL
;
goto
cleanup
;
}
buf
=
kmemdup
(
magic_arr
,
magic_size
,
GFP_KERNEL
);
if
(
!
buf
)
{
rc
=
-
ENOMEM
;
goto
cleanup
;
}
udev
=
hid_to_usb_dev
(
hdev
);
pipe
=
usb_sndintpipe
(
udev
,
endpoint
);
rc
=
usb_interrupt_msg
(
udev
,
pipe
,
buf
,
magic_size
,
&
sent
,
1000
);
if
(
rc
||
sent
!=
magic_size
)
{
hid_err
(
hdev
,
"Interface probing failed: %d
\n
"
,
rc
);
rc
=
-
1
;
goto
cleanup
;
}
rc
=
0
;
cleanup:
kfree
(
buf
);
return
rc
;
}
/**
* uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
* discovering their parameters.
*
* These tables, internally designed as v2 to differentiate them from older
* models, expect a payload of magic data in orther to be switched to the fully
* functional mode and expose their parameters in a similar way to the
* information present in uclogic_params_pen_init_v1() but with some
* differences.
*
* @params: Parameters to fill in (to be cleaned with
* uclogic_params_cleanup()). Not modified in case of error.
* Cannot be NULL.
* @hdev: The HID device of the tablet interface to initialize and get
* parameters from. Cannot be NULL.
*
* Returns:
* Zero, if successful. A negative errno code on error.
*/
static
int
uclogic_params_ugee_v2_init
(
struct
uclogic_params
*
params
,
struct
hid_device
*
hdev
)
{
int
rc
=
0
;
struct
usb_interface
*
iface
;
__u8
bInterfaceNumber
;
const
int
str_desc_len
=
12
;
__u8
*
str_desc
=
NULL
;
__u8
*
rdesc_pen
=
NULL
;
__u8
*
rdesc_frame
=
NULL
;
s32
desc_params
[
UCLOGIC_RDESC_PH_ID_NUM
];
s32
resolution
;
__u8
magic_arr
[]
=
{
0x02
,
0xb0
,
0x04
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
};
/* The resulting parameters (noop) */
struct
uclogic_params
p
=
{
0
,
};
if
(
!
params
||
!
hdev
)
{
rc
=
-
EINVAL
;
goto
cleanup
;
}
iface
=
to_usb_interface
(
hdev
->
dev
.
parent
);
bInterfaceNumber
=
iface
->
cur_altsetting
->
desc
.
bInterfaceNumber
;
if
(
bInterfaceNumber
!=
2
)
{
uclogic_params_init_invalid
(
&
p
);
goto
output
;
}
/*
* Initialize the interface by sending magic data.
* The specific data was discovered by sniffing the Windows driver
* traffic.
*/
rc
=
uclogic_probe_interface
(
hdev
,
magic_arr
,
sizeof
(
magic_arr
),
0x03
);
if
(
rc
)
{
uclogic_params_init_invalid
(
&
p
);
goto
output
;
}
/*
* Read the string descriptor containing pen and frame parameters.
* The specific string descriptor and data were discovered by sniffing
* the Windows driver traffic.
*/
rc
=
uclogic_params_get_str_desc
(
&
str_desc
,
hdev
,
100
,
str_desc_len
);
if
(
rc
!=
str_desc_len
)
{
hid_err
(
hdev
,
"failed retrieving pen and frame parameters: %d
\n
"
,
rc
);
uclogic_params_init_invalid
(
&
p
);
goto
output
;
}
desc_params
[
UCLOGIC_RDESC_PEN_PH_ID_X_LM
]
=
get_unaligned_le16
(
str_desc
+
2
);
desc_params
[
UCLOGIC_RDESC_PEN_PH_ID_Y_LM
]
=
get_unaligned_le16
(
str_desc
+
4
);
desc_params
[
UCLOGIC_RDESC_FRAME_PH_ID_UM
]
=
str_desc
[
6
];
desc_params
[
UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM
]
=
get_unaligned_le16
(
str_desc
+
8
);
resolution
=
get_unaligned_le16
(
str_desc
+
10
);
if
(
resolution
==
0
)
{
desc_params
[
UCLOGIC_RDESC_PEN_PH_ID_X_PM
]
=
0
;
desc_params
[
UCLOGIC_RDESC_PEN_PH_ID_Y_PM
]
=
0
;
}
else
{
desc_params
[
UCLOGIC_RDESC_PEN_PH_ID_X_PM
]
=
desc_params
[
UCLOGIC_RDESC_PEN_PH_ID_X_LM
]
*
1000
/
resolution
;
desc_params
[
UCLOGIC_RDESC_PEN_PH_ID_Y_PM
]
=
desc_params
[
UCLOGIC_RDESC_PEN_PH_ID_Y_LM
]
*
1000
/
resolution
;
}
kfree
(
str_desc
);
str_desc
=
NULL
;
/* Initialize the pen interface */
rdesc_pen
=
uclogic_rdesc_template_apply
(
uclogic_rdesc_ugee_v2_pen_template_arr
,
uclogic_rdesc_ugee_v2_pen_template_size
,
desc_params
,
ARRAY_SIZE
(
desc_params
));
if
(
!
rdesc_pen
)
{
rc
=
-
ENOMEM
;
goto
cleanup
;
}
p
.
pen
.
desc_ptr
=
rdesc_pen
;
p
.
pen
.
desc_size
=
uclogic_rdesc_ugee_v2_pen_template_size
;
p
.
pen
.
id
=
0x02
;
p
.
pen
.
subreport_list
[
0
].
value
=
0xf0
;
p
.
pen
.
subreport_list
[
0
].
id
=
UCLOGIC_RDESC_V1_FRAME_ID
;
/* Initialize the frame interface */
rdesc_frame
=
uclogic_rdesc_template_apply
(
uclogic_rdesc_ugee_v2_frame_btn_template_arr
,
uclogic_rdesc_ugee_v2_frame_btn_template_size
,
desc_params
,
ARRAY_SIZE
(
desc_params
));
if
(
!
rdesc_frame
)
{
rc
=
-
ENOMEM
;
goto
cleanup
;
}
rc
=
uclogic_params_frame_init_with_desc
(
&
p
.
frame_list
[
0
],
rdesc_frame
,
uclogic_rdesc_ugee_v2_frame_btn_template_size
,
UCLOGIC_RDESC_V1_FRAME_ID
);
kfree
(
rdesc_frame
);
if
(
rc
)
{
uclogic_params_init_invalid
(
&
p
);
goto
output
;
}
output:
/* Output parameters */
memcpy
(
params
,
&
p
,
sizeof
(
*
params
));
memset
(
&
p
,
0
,
sizeof
(
p
));
rc
=
0
;
cleanup:
kfree
(
str_desc
);
uclogic_params_cleanup
(
&
p
);
return
rc
;
}
/**
* uclogic_params_init() - initialize a tablet interface and discover its
* parameters.
...
...
@@ -1241,6 +1432,12 @@ int uclogic_params_init(struct uclogic_params *params,
uclogic_params_init_invalid
(
&
p
);
}
break
;
case
VID_PID
(
USB_VENDOR_ID_UGEE
,
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L
):
rc
=
uclogic_params_ugee_v2_init
(
&
p
,
hdev
);
if
(
rc
!=
0
)
goto
cleanup
;
break
;
case
VID_PID
(
USB_VENDOR_ID_TRUST
,
USB_DEVICE_ID_TRUST_PANORA_TABLET
):
case
VID_PID
(
USB_VENDOR_ID_UGEE
,
...
...
drivers/hid/hid-uclogic-rdesc-test.c
0 → 100644
View file @
a60885b6
// SPDX-License-Identifier: GPL-2.0+
/*
* HID driver for UC-Logic devices not fully compliant with HID standard
*
* Copyright (c) 2022 José Expósito <jose.exposito89@gmail.com>
*/
#include <kunit/test.h>
#include "./hid-uclogic-rdesc.h"
struct
uclogic_template_case
{
const
char
*
name
;
const
__u8
*
template
;
size_t
template_size
;
const
s32
*
param_list
;
size_t
param_num
;
const
__u8
*
expected
;
};
static
const
s32
params_pen_all
[
UCLOGIC_RDESC_PH_ID_NUM
]
=
{
[
UCLOGIC_RDESC_PEN_PH_ID_X_LM
]
=
0xAA
,
[
UCLOGIC_RDESC_PEN_PH_ID_X_PM
]
=
0xBB
,
[
UCLOGIC_RDESC_PEN_PH_ID_Y_LM
]
=
0xCC
,
[
UCLOGIC_RDESC_PEN_PH_ID_Y_PM
]
=
0xDD
,
[
UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM
]
=
0xEE
,
};
static
const
s32
params_pen_some
[]
=
{
[
UCLOGIC_RDESC_PEN_PH_ID_X_LM
]
=
0xAA
,
[
UCLOGIC_RDESC_PEN_PH_ID_X_PM
]
=
0xBB
,
};
static
const
s32
params_frame_all
[
UCLOGIC_RDESC_PH_ID_NUM
]
=
{
[
UCLOGIC_RDESC_FRAME_PH_ID_UM
]
=
0xFF
,
};
static
const
__u8
template_empty
[]
=
{
};
static
const
__u8
template_small
[]
=
{
0x00
};
static
const
__u8
template_no_ph
[]
=
{
0xAA
,
0xFE
,
0xAA
,
0xED
,
0x1D
};
static
const
__u8
template_pen_ph_end
[]
=
{
0xAA
,
0xBB
,
UCLOGIC_RDESC_PEN_PH_HEAD
};
static
const
__u8
template_btn_ph_end
[]
=
{
0xAA
,
0xBB
,
UCLOGIC_RDESC_FRAME_PH_BTN_HEAD
};
static
const
__u8
template_pen_all_params
[]
=
{
UCLOGIC_RDESC_PEN_PH
(
X_LM
),
0x47
,
UCLOGIC_RDESC_PEN_PH
(
X_PM
),
0x27
,
UCLOGIC_RDESC_PEN_PH
(
Y_LM
),
UCLOGIC_RDESC_PEN_PH
(
Y_PM
),
0x00
,
UCLOGIC_RDESC_PEN_PH
(
PRESSURE_LM
),
};
static
const
__u8
expected_pen_all_params
[]
=
{
0xAA
,
0x00
,
0x00
,
0x00
,
0x47
,
0xBB
,
0x00
,
0x00
,
0x00
,
0x27
,
0xCC
,
0x00
,
0x00
,
0x00
,
0xDD
,
0x00
,
0x00
,
0x00
,
0x00
,
0xEE
,
0x00
,
0x00
,
0x00
,
};
static
const
__u8
template_frame_all_params
[]
=
{
0x01
,
0x02
,
UCLOGIC_RDESC_FRAME_PH_BTN
,
0x99
,
};
static
const
__u8
expected_frame_all_params
[]
=
{
0x01
,
0x02
,
0x2A
,
0xFF
,
0x00
,
0x99
,
};
static
const
__u8
template_pen_some_params
[]
=
{
0x01
,
0x02
,
UCLOGIC_RDESC_PEN_PH
(
X_LM
),
0x03
,
UCLOGIC_RDESC_PEN_PH
(
X_PM
),
0x04
,
0x05
,
};
static
const
__u8
expected_pen_some_params
[]
=
{
0x01
,
0x02
,
0xAA
,
0x00
,
0x00
,
0x00
,
0x03
,
0xBB
,
0x00
,
0x00
,
0x00
,
0x04
,
0x05
,
};
static
const
__u8
template_params_none
[]
=
{
0x27
,
UCLOGIC_RDESC_PEN_PH
(
Y_LM
),
UCLOGIC_RDESC_PEN_PH
(
Y_PM
),
0x00
,
UCLOGIC_RDESC_PEN_PH
(
PRESSURE_LM
),
};
static
struct
uclogic_template_case
uclogic_template_cases
[]
=
{
{
.
name
=
"Empty template"
,
.
template
=
template_empty
,
.
template_size
=
sizeof
(
template_empty
),
.
param_list
=
params_pen_all
,
.
param_num
=
ARRAY_SIZE
(
params_pen_all
),
.
expected
=
template_empty
,
},
{
.
name
=
"Template smaller than the placeholder"
,
.
template
=
template_small
,
.
template_size
=
sizeof
(
template_small
),
.
param_list
=
params_pen_all
,
.
param_num
=
ARRAY_SIZE
(
params_pen_all
),
.
expected
=
template_small
,
},
{
.
name
=
"No placeholder"
,
.
template
=
template_no_ph
,
.
template_size
=
sizeof
(
template_no_ph
),
.
param_list
=
params_pen_all
,
.
param_num
=
ARRAY_SIZE
(
params_pen_all
),
.
expected
=
template_no_ph
,
},
{
.
name
=
"Pen placeholder at the end, without ID"
,
.
template
=
template_pen_ph_end
,
.
template_size
=
sizeof
(
template_pen_ph_end
),
.
param_list
=
params_pen_all
,
.
param_num
=
ARRAY_SIZE
(
params_pen_all
),
.
expected
=
template_pen_ph_end
,
},
{
.
name
=
"Frame button placeholder at the end, without ID"
,
.
template
=
template_btn_ph_end
,
.
template_size
=
sizeof
(
template_btn_ph_end
),
.
param_list
=
params_frame_all
,
.
param_num
=
ARRAY_SIZE
(
params_frame_all
),
.
expected
=
template_btn_ph_end
,
},
{
.
name
=
"All params present in the pen template"
,
.
template
=
template_pen_all_params
,
.
template_size
=
sizeof
(
template_pen_all_params
),
.
param_list
=
params_pen_all
,
.
param_num
=
ARRAY_SIZE
(
params_pen_all
),
.
expected
=
expected_pen_all_params
,
},
{
.
name
=
"All params present in the frame template"
,
.
template
=
template_frame_all_params
,
.
template_size
=
sizeof
(
template_frame_all_params
),
.
param_list
=
params_frame_all
,
.
param_num
=
ARRAY_SIZE
(
params_frame_all
),
.
expected
=
expected_frame_all_params
,
},
{
.
name
=
"Some params present in the pen template (complete param list)"
,
.
template
=
template_pen_some_params
,
.
template_size
=
sizeof
(
template_pen_some_params
),
.
param_list
=
params_pen_all
,
.
param_num
=
ARRAY_SIZE
(
params_pen_all
),
.
expected
=
expected_pen_some_params
,
},
{
.
name
=
"Some params present in the pen template (incomplete param list)"
,
.
template
=
template_pen_some_params
,
.
template_size
=
sizeof
(
template_pen_some_params
),
.
param_list
=
params_pen_some
,
.
param_num
=
ARRAY_SIZE
(
params_pen_some
),
.
expected
=
expected_pen_some_params
,
},
{
.
name
=
"No params present in the template"
,
.
template
=
template_params_none
,
.
template_size
=
sizeof
(
template_params_none
),
.
param_list
=
params_pen_some
,
.
param_num
=
ARRAY_SIZE
(
params_pen_some
),
.
expected
=
template_params_none
,
},
};
static
void
uclogic_template_case_desc
(
struct
uclogic_template_case
*
t
,
char
*
desc
)
{
strscpy
(
desc
,
t
->
name
,
KUNIT_PARAM_DESC_SIZE
);
}
KUNIT_ARRAY_PARAM
(
uclogic_template
,
uclogic_template_cases
,
uclogic_template_case_desc
);
static
void
uclogic_template_test
(
struct
kunit
*
test
)
{
__u8
*
res
;
const
struct
uclogic_template_case
*
params
=
test
->
param_value
;
res
=
uclogic_rdesc_template_apply
(
params
->
template
,
params
->
template_size
,
params
->
param_list
,
params
->
param_num
);
KUNIT_ASSERT_NOT_ERR_OR_NULL
(
test
,
res
);
KUNIT_EXPECT_EQ
(
test
,
0
,
memcmp
(
res
,
params
->
expected
,
params
->
template_size
));
kfree
(
res
);
}
static
struct
kunit_case
hid_uclogic_rdesc_test_cases
[]
=
{
KUNIT_CASE_PARAM
(
uclogic_template_test
,
uclogic_template_gen_params
),
{}
};
static
struct
kunit_suite
hid_uclogic_rdesc_test_suite
=
{
.
name
=
"hid-uclogic-rdesc-test"
,
.
test_cases
=
hid_uclogic_rdesc_test_cases
,
};
kunit_test_suite
(
hid_uclogic_rdesc_test_suite
);
MODULE_DESCRIPTION
(
"KUnit tests for the UC-Logic driver"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"José Expósito <jose.exposito89@gmail.com>"
);
drivers/hid/hid-uclogic-rdesc.c
View file @
a60885b6
...
...
@@ -859,6 +859,108 @@ const __u8 uclogic_rdesc_v2_frame_dial_arr[] = {
const
size_t
uclogic_rdesc_v2_frame_dial_size
=
sizeof
(
uclogic_rdesc_v2_frame_dial_arr
);
/* Fixed report descriptor template for UGEE v2 pen reports */
const
__u8
uclogic_rdesc_ugee_v2_pen_template_arr
[]
=
{
0x05
,
0x0d
,
/* Usage Page (Digitizers), */
0x09
,
0x01
,
/* Usage (Digitizer), */
0xa1
,
0x01
,
/* Collection (Application), */
0x85
,
0x02
,
/* Report ID (2), */
0x09
,
0x20
,
/* Usage (Stylus), */
0xa1
,
0x00
,
/* Collection (Physical), */
0x09
,
0x42
,
/* Usage (Tip Switch), */
0x09
,
0x44
,
/* Usage (Barrel Switch), */
0x09
,
0x46
,
/* Usage (Tablet Pick), */
0x75
,
0x01
,
/* Report Size (1), */
0x95
,
0x03
,
/* Report Count (3), */
0x14
,
/* Logical Minimum (0), */
0x25
,
0x01
,
/* Logical Maximum (1), */
0x81
,
0x02
,
/* Input (Variable), */
0x95
,
0x02
,
/* Report Count (2), */
0x81
,
0x03
,
/* Input (Constant, Variable), */
0x09
,
0x32
,
/* Usage (In Range), */
0x95
,
0x01
,
/* Report Count (1), */
0x81
,
0x02
,
/* Input (Variable), */
0x95
,
0x02
,
/* Report Count (2), */
0x81
,
0x03
,
/* Input (Constant, Variable), */
0x75
,
0x10
,
/* Report Size (16), */
0x95
,
0x01
,
/* Report Count (1), */
0x35
,
0x00
,
/* Physical Minimum (0), */
0xa4
,
/* Push, */
0x05
,
0x01
,
/* Usage Page (Desktop), */
0x09
,
0x30
,
/* Usage (X), */
0x65
,
0x13
,
/* Unit (Inch), */
0x55
,
0x0d
,
/* Unit Exponent (-3), */
0x27
,
UCLOGIC_RDESC_PEN_PH
(
X_LM
),
/* Logical Maximum (PLACEHOLDER), */
0x47
,
UCLOGIC_RDESC_PEN_PH
(
X_PM
),
/* Physical Maximum (PLACEHOLDER), */
0x81
,
0x02
,
/* Input (Variable), */
0x09
,
0x31
,
/* Usage (Y), */
0x27
,
UCLOGIC_RDESC_PEN_PH
(
Y_LM
),
/* Logical Maximum (PLACEHOLDER), */
0x47
,
UCLOGIC_RDESC_PEN_PH
(
Y_PM
),
/* Physical Maximum (PLACEHOLDER), */
0x81
,
0x02
,
/* Input (Variable), */
0xb4
,
/* Pop, */
0x09
,
0x30
,
/* Usage (Tip Pressure), */
0x45
,
0x00
,
/* Physical Maximum (0), */
0x27
,
UCLOGIC_RDESC_PEN_PH
(
PRESSURE_LM
),
/* Logical Maximum (PLACEHOLDER), */
0x75
,
0x0D
,
/* Report Size (13), */
0x95
,
0x01
,
/* Report Count (1), */
0x81
,
0x02
,
/* Input (Variable), */
0x75
,
0x01
,
/* Report Size (1), */
0x95
,
0x03
,
/* Report Count (3), */
0x81
,
0x01
,
/* Input (Constant), */
0x09
,
0x3d
,
/* Usage (X Tilt), */
0x35
,
0xC3
,
/* Physical Minimum (-61), */
0x45
,
0x3C
,
/* Physical Maximum (60), */
0x15
,
0xC3
,
/* Logical Minimum (-61), */
0x25
,
0x3C
,
/* Logical Maximum (60), */
0x75
,
0x08
,
/* Report Size (8), */
0x95
,
0x01
,
/* Report Count (1), */
0x81
,
0x02
,
/* Input (Variable), */
0x09
,
0x3e
,
/* Usage (Y Tilt), */
0x35
,
0xC3
,
/* Physical Minimum (-61), */
0x45
,
0x3C
,
/* Physical Maximum (60), */
0x15
,
0xC3
,
/* Logical Minimum (-61), */
0x25
,
0x3C
,
/* Logical Maximum (60), */
0x81
,
0x02
,
/* Input (Variable), */
0xc0
,
/* End Collection, */
0xc0
,
/* End Collection */
};
const
size_t
uclogic_rdesc_ugee_v2_pen_template_size
=
sizeof
(
uclogic_rdesc_ugee_v2_pen_template_arr
);
/* Fixed report descriptor template for UGEE v2 frame reports (buttons only) */
const
__u8
uclogic_rdesc_ugee_v2_frame_btn_template_arr
[]
=
{
0x05
,
0x01
,
/* Usage Page (Desktop), */
0x09
,
0x07
,
/* Usage (Keypad), */
0xA1
,
0x01
,
/* Collection (Application), */
0x85
,
UCLOGIC_RDESC_V1_FRAME_ID
,
/* Report ID, */
0x05
,
0x0D
,
/* Usage Page (Digitizer), */
0x09
,
0x39
,
/* Usage (Tablet Function Keys), */
0xA0
,
/* Collection (Physical), */
0x75
,
0x01
,
/* Report Size (1), */
0x95
,
0x08
,
/* Report Count (8), */
0x81
,
0x01
,
/* Input (Constant), */
0x05
,
0x09
,
/* Usage Page (Button), */
0x19
,
0x01
,
/* Usage Minimum (01h), */
UCLOGIC_RDESC_FRAME_PH_BTN
,
/* Usage Maximum (PLACEHOLDER), */
0x95
,
0x0A
,
/* Report Count (10), */
0x14
,
/* Logical Minimum (0), */
0x25
,
0x01
,
/* Logical Maximum (1), */
0x81
,
0x02
,
/* Input (Variable), */
0x95
,
0x46
,
/* Report Count (70), */
0x81
,
0x01
,
/* Input (Constant), */
0xC0
,
/* End Collection, */
0xC0
/* End Collection */
};
const
size_t
uclogic_rdesc_ugee_v2_frame_btn_template_size
=
sizeof
(
uclogic_rdesc_ugee_v2_frame_btn_template_arr
);
/* Fixed report descriptor for Ugee EX07 frame */
const
__u8
uclogic_rdesc_ugee_ex07_frame_arr
[]
=
{
0x05
,
0x01
,
/* Usage Page (Desktop), */
...
...
@@ -979,7 +1081,7 @@ const size_t uclogic_rdesc_xppen_deco01_frame_size =
* uclogic_rdesc_template_apply() - apply report descriptor parameters to a
* report descriptor template, creating a report descriptor. Copies the
* template over to the new report descriptor and replaces every occurrence of
*
UCLOGIC_RDESC_PH_HEAD
, followed by an index byte, with the value from the
*
the template placeholders
, followed by an index byte, with the value from the
* parameter list at that index.
*
* @template_ptr: Pointer to the template buffer.
...
...
@@ -996,7 +1098,8 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
const
s32
*
param_list
,
size_t
param_num
)
{
static
const
__u8
head
[]
=
{
UCLOGIC_RDESC_PH_HEAD
};
static
const
__u8
btn_head
[]
=
{
UCLOGIC_RDESC_FRAME_PH_BTN_HEAD
};
static
const
__u8
pen_head
[]
=
{
UCLOGIC_RDESC_PEN_PH_HEAD
};
__u8
*
rdesc_ptr
;
__u8
*
p
;
s32
v
;
...
...
@@ -1005,12 +1108,19 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
if
(
rdesc_ptr
==
NULL
)
return
NULL
;
for
(
p
=
rdesc_ptr
;
p
+
sizeof
(
head
)
<
rdesc_ptr
+
template_size
;)
{
if
(
memcmp
(
p
,
head
,
sizeof
(
head
))
==
0
&&
p
[
sizeof
(
head
)]
<
param_num
)
{
v
=
param_list
[
p
[
sizeof
(
head
)]];
for
(
p
=
rdesc_ptr
;
p
+
sizeof
(
btn_head
)
<
rdesc_ptr
+
template_size
;)
{
if
(
p
+
sizeof
(
pen_head
)
<
rdesc_ptr
+
template_size
&&
memcmp
(
p
,
pen_head
,
sizeof
(
pen_head
))
==
0
&&
p
[
sizeof
(
pen_head
)]
<
param_num
)
{
v
=
param_list
[
p
[
sizeof
(
pen_head
)]];
put_unaligned
(
cpu_to_le32
(
v
),
(
s32
*
)
p
);
p
+=
sizeof
(
head
)
+
1
;
p
+=
sizeof
(
pen_head
)
+
1
;
}
else
if
(
memcmp
(
p
,
btn_head
,
sizeof
(
btn_head
))
==
0
&&
p
[
sizeof
(
btn_head
)]
<
param_num
)
{
v
=
param_list
[
p
[
sizeof
(
btn_head
)]];
put_unaligned
((
__u8
)
0x2A
,
p
);
/* Usage Maximum */
put_unaligned_le16
((
__force
u16
)
cpu_to_le16
(
v
),
p
+
1
);
p
+=
sizeof
(
btn_head
)
+
1
;
}
else
{
p
++
;
}
...
...
drivers/hid/hid-uclogic-rdesc.h
View file @
a60885b6
...
...
@@ -81,7 +81,8 @@ extern __u8 uclogic_rdesc_twha60_fixed1_arr[];
extern
const
size_t
uclogic_rdesc_twha60_fixed1_size
;
/* Report descriptor template placeholder head */
#define UCLOGIC_RDESC_PH_HEAD 0xFE, 0xED, 0x1D
#define UCLOGIC_RDESC_PEN_PH_HEAD 0xFE, 0xED, 0x1D
#define UCLOGIC_RDESC_FRAME_PH_BTN_HEAD 0xFE, 0xED
/* Apply report descriptor parameters to a report descriptor template */
extern
__u8
*
uclogic_rdesc_template_apply
(
const
__u8
*
template_ptr
,
...
...
@@ -89,19 +90,24 @@ extern __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
const
s32
*
param_list
,
size_t
param_num
);
/*
Pen r
eport descriptor template placeholder IDs */
enum
uclogic_rdesc_p
en_p
h_id
{
/*
R
eport descriptor template placeholder IDs */
enum
uclogic_rdesc_ph_id
{
UCLOGIC_RDESC_PEN_PH_ID_X_LM
,
UCLOGIC_RDESC_PEN_PH_ID_X_PM
,
UCLOGIC_RDESC_PEN_PH_ID_Y_LM
,
UCLOGIC_RDESC_PEN_PH_ID_Y_PM
,
UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM
,
UCLOGIC_RDESC_PEN_PH_ID_NUM
UCLOGIC_RDESC_FRAME_PH_ID_UM
,
UCLOGIC_RDESC_PH_ID_NUM
};
/* Report descriptor pen template placeholder */
#define UCLOGIC_RDESC_PEN_PH(_ID) \
UCLOGIC_RDESC_PH_HEAD, UCLOGIC_RDESC_PEN_PH_ID_##_ID
UCLOGIC_RDESC_PEN_PH_HEAD, UCLOGIC_RDESC_PEN_PH_ID_##_ID
/* Report descriptor frame buttons template placeholder */
#define UCLOGIC_RDESC_FRAME_PH_BTN \
UCLOGIC_RDESC_FRAME_PH_BTN_HEAD, UCLOGIC_RDESC_FRAME_PH_ID_UM
/* Report ID for v1 pen reports */
#define UCLOGIC_RDESC_V1_PEN_ID 0x07
...
...
@@ -155,6 +161,14 @@ extern const size_t uclogic_rdesc_v2_frame_dial_size;
/* Device ID byte offset in v2 frame dial reports */
#define UCLOGIC_RDESC_V2_FRAME_DIAL_DEV_ID_BYTE 0x4
/* Fixed report descriptor template for UGEE v2 pen reports */
extern
const
__u8
uclogic_rdesc_ugee_v2_pen_template_arr
[];
extern
const
size_t
uclogic_rdesc_ugee_v2_pen_template_size
;
/* Fixed report descriptor template for UGEE v2 frame reports (buttons only) */
extern
const
__u8
uclogic_rdesc_ugee_v2_frame_btn_template_arr
[];
extern
const
size_t
uclogic_rdesc_ugee_v2_frame_btn_template_size
;
/* Fixed report descriptor for Ugee EX07 frame */
extern
const
__u8
uclogic_rdesc_ugee_ex07_frame_arr
[];
extern
const
size_t
uclogic_rdesc_ugee_ex07_frame_size
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment