1a46c0ec8Sopenharmony_ci/*
2a46c0ec8Sopenharmony_ci * Copyright © 2018 Red Hat, Inc.
3a46c0ec8Sopenharmony_ci *
4a46c0ec8Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5a46c0ec8Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6a46c0ec8Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7a46c0ec8Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8a46c0ec8Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9a46c0ec8Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10a46c0ec8Sopenharmony_ci *
11a46c0ec8Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12a46c0ec8Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13a46c0ec8Sopenharmony_ci * Software.
14a46c0ec8Sopenharmony_ci *
15a46c0ec8Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16a46c0ec8Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17a46c0ec8Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18a46c0ec8Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19a46c0ec8Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20a46c0ec8Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21a46c0ec8Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
22a46c0ec8Sopenharmony_ci */
23a46c0ec8Sopenharmony_ci
24a46c0ec8Sopenharmony_ci#pragma once
25a46c0ec8Sopenharmony_ci
26a46c0ec8Sopenharmony_ci#include "config.h"
27a46c0ec8Sopenharmony_ci
28a46c0ec8Sopenharmony_ci#include <stdbool.h>
29a46c0ec8Sopenharmony_ci#include <stdint.h>
30a46c0ec8Sopenharmony_ci
31a46c0ec8Sopenharmony_ci#include <libudev.h>
32a46c0ec8Sopenharmony_ci
33a46c0ec8Sopenharmony_ci#include "libinput.h"
34a46c0ec8Sopenharmony_ci
35a46c0ec8Sopenharmony_ci/**
36a46c0ec8Sopenharmony_ci * Handle to the quirks context.
37a46c0ec8Sopenharmony_ci */
38a46c0ec8Sopenharmony_cistruct quirks_context;
39a46c0ec8Sopenharmony_ci
40a46c0ec8Sopenharmony_ci/**
41a46c0ec8Sopenharmony_ci * Contains all quirks set for a single device.
42a46c0ec8Sopenharmony_ci */
43a46c0ec8Sopenharmony_cistruct quirks;
44a46c0ec8Sopenharmony_ci
45a46c0ec8Sopenharmony_cistruct quirk_dimensions {
46a46c0ec8Sopenharmony_ci	size_t x, y;
47a46c0ec8Sopenharmony_ci};
48a46c0ec8Sopenharmony_ci
49a46c0ec8Sopenharmony_cistruct quirk_range {
50a46c0ec8Sopenharmony_ci	int lower, upper;
51a46c0ec8Sopenharmony_ci};
52a46c0ec8Sopenharmony_ci
53a46c0ec8Sopenharmony_cistruct quirk_tuples {
54a46c0ec8Sopenharmony_ci	struct {
55a46c0ec8Sopenharmony_ci		int first;
56a46c0ec8Sopenharmony_ci		int second;
57a46c0ec8Sopenharmony_ci		int third;
58a46c0ec8Sopenharmony_ci	} tuples[32];
59a46c0ec8Sopenharmony_ci	size_t ntuples;
60a46c0ec8Sopenharmony_ci};
61a46c0ec8Sopenharmony_ci
62a46c0ec8Sopenharmony_ci/**
63a46c0ec8Sopenharmony_ci * Quirks known to libinput
64a46c0ec8Sopenharmony_ci */
65a46c0ec8Sopenharmony_cienum quirk {
66a46c0ec8Sopenharmony_ci	QUIRK_MODEL_ALPS_SERIAL_TOUCHPAD = 100,
67a46c0ec8Sopenharmony_ci	QUIRK_MODEL_APPLE_TOUCHPAD,
68a46c0ec8Sopenharmony_ci	QUIRK_MODEL_APPLE_TOUCHPAD_ONEBUTTON,
69a46c0ec8Sopenharmony_ci	QUIRK_MODEL_BOUNCING_KEYS,
70a46c0ec8Sopenharmony_ci	QUIRK_MODEL_CHROMEBOOK,
71a46c0ec8Sopenharmony_ci	QUIRK_MODEL_CLEVO_W740SU,
72a46c0ec8Sopenharmony_ci	QUIRK_MODEL_DELL_CANVAS_TOTEM,
73a46c0ec8Sopenharmony_ci	QUIRK_MODEL_HP_PAVILION_DM4_TOUCHPAD,
74a46c0ec8Sopenharmony_ci	QUIRK_MODEL_HP_ZBOOK_STUDIO_G3,
75a46c0ec8Sopenharmony_ci	QUIRK_MODEL_INVERT_HORIZONTAL_SCROLLING,
76a46c0ec8Sopenharmony_ci	QUIRK_MODEL_LENOVO_SCROLLPOINT,
77a46c0ec8Sopenharmony_ci	QUIRK_MODEL_LENOVO_T450_TOUCHPAD,
78a46c0ec8Sopenharmony_ci	QUIRK_MODEL_LENOVO_X1GEN6_TOUCHPAD,
79a46c0ec8Sopenharmony_ci	QUIRK_MODEL_LENOVO_X230,
80a46c0ec8Sopenharmony_ci	QUIRK_MODEL_SYNAPTICS_SERIAL_TOUCHPAD,
81a46c0ec8Sopenharmony_ci	QUIRK_MODEL_SYSTEM76_BONOBO,
82a46c0ec8Sopenharmony_ci	QUIRK_MODEL_SYSTEM76_GALAGO,
83a46c0ec8Sopenharmony_ci	QUIRK_MODEL_SYSTEM76_KUDU,
84a46c0ec8Sopenharmony_ci	QUIRK_MODEL_TABLET_MODE_NO_SUSPEND,
85a46c0ec8Sopenharmony_ci	QUIRK_MODEL_TABLET_MODE_SWITCH_UNRELIABLE,
86a46c0ec8Sopenharmony_ci	QUIRK_MODEL_TOUCHPAD_VISIBLE_MARKER,
87a46c0ec8Sopenharmony_ci	QUIRK_MODEL_TRACKBALL,
88a46c0ec8Sopenharmony_ci	QUIRK_MODEL_WACOM_TOUCHPAD,
89a46c0ec8Sopenharmony_ci	QUIRK_MODEL_PRESSURE_PAD,
90a46c0ec8Sopenharmony_ci	QUIRK_MODEL_TOUCHPAD_PHANTOM_CLICKS,
91a46c0ec8Sopenharmony_ci
92a46c0ec8Sopenharmony_ci	_QUIRK_LAST_MODEL_QUIRK_, /* Guard: do not modify */
93a46c0ec8Sopenharmony_ci
94a46c0ec8Sopenharmony_ci	QUIRK_ATTR_SIZE_HINT = 300,
95a46c0ec8Sopenharmony_ci	QUIRK_ATTR_TOUCH_SIZE_RANGE,
96a46c0ec8Sopenharmony_ci	QUIRK_ATTR_PALM_SIZE_THRESHOLD,
97a46c0ec8Sopenharmony_ci	QUIRK_ATTR_LID_SWITCH_RELIABILITY,
98a46c0ec8Sopenharmony_ci	QUIRK_ATTR_KEYBOARD_INTEGRATION,
99a46c0ec8Sopenharmony_ci	QUIRK_ATTR_TRACKPOINT_INTEGRATION,
100a46c0ec8Sopenharmony_ci	QUIRK_ATTR_TPKBCOMBO_LAYOUT,
101a46c0ec8Sopenharmony_ci	QUIRK_ATTR_PRESSURE_RANGE,
102a46c0ec8Sopenharmony_ci	QUIRK_ATTR_PALM_PRESSURE_THRESHOLD,
103a46c0ec8Sopenharmony_ci	QUIRK_ATTR_RESOLUTION_HINT,
104a46c0ec8Sopenharmony_ci	QUIRK_ATTR_TRACKPOINT_MULTIPLIER,
105a46c0ec8Sopenharmony_ci	QUIRK_ATTR_THUMB_PRESSURE_THRESHOLD,
106a46c0ec8Sopenharmony_ci	QUIRK_ATTR_USE_VELOCITY_AVERAGING,
107a46c0ec8Sopenharmony_ci	QUIRK_ATTR_TABLET_SMOOTHING,
108a46c0ec8Sopenharmony_ci	QUIRK_ATTR_THUMB_SIZE_THRESHOLD,
109a46c0ec8Sopenharmony_ci	QUIRK_ATTR_MSC_TIMESTAMP,
110a46c0ec8Sopenharmony_ci	QUIRK_ATTR_EVENT_CODE,
111a46c0ec8Sopenharmony_ci	QUIRK_ATTR_INPUT_PROP,
112a46c0ec8Sopenharmony_ci
113a46c0ec8Sopenharmony_ci	_QUIRK_LAST_ATTR_QUIRK_, /* Guard: do not modify */
114a46c0ec8Sopenharmony_ci};
115a46c0ec8Sopenharmony_ci
116a46c0ec8Sopenharmony_ci/**
117a46c0ec8Sopenharmony_ci * Returns a printable name for the quirk. This name is for developer
118a46c0ec8Sopenharmony_ci * tools, not user consumption. Do not display this in a GUI.
119a46c0ec8Sopenharmony_ci */
120a46c0ec8Sopenharmony_ciconst char*
121a46c0ec8Sopenharmony_ciquirk_get_name(enum quirk q);
122a46c0ec8Sopenharmony_ci
123a46c0ec8Sopenharmony_ci/**
124a46c0ec8Sopenharmony_ci * Log priorities used if custom logging is enabled.
125a46c0ec8Sopenharmony_ci */
126a46c0ec8Sopenharmony_cienum quirks_log_priorities {
127a46c0ec8Sopenharmony_ci	QLOG_NOISE,
128a46c0ec8Sopenharmony_ci	QLOG_DEBUG = LIBINPUT_LOG_PRIORITY_DEBUG,
129a46c0ec8Sopenharmony_ci	QLOG_INFO = LIBINPUT_LOG_PRIORITY_INFO,
130a46c0ec8Sopenharmony_ci	QLOG_ERROR = LIBINPUT_LOG_PRIORITY_ERROR,
131a46c0ec8Sopenharmony_ci	QLOG_PARSER_ERROR,
132a46c0ec8Sopenharmony_ci};
133a46c0ec8Sopenharmony_ci
134a46c0ec8Sopenharmony_ci/**
135a46c0ec8Sopenharmony_ci * Log type to be used for logging. Use the libinput logging to hook up a
136a46c0ec8Sopenharmony_ci * libinput log handler. This will cause the quirks to reduce the noise and
137a46c0ec8Sopenharmony_ci * only provide useful messages.
138a46c0ec8Sopenharmony_ci *
139a46c0ec8Sopenharmony_ci * QLOG_CUSTOM_LOG_PRIORITIES enables more fine-grained and verbose logging,
140a46c0ec8Sopenharmony_ci * allowing debugging tools to be more useful.
141a46c0ec8Sopenharmony_ci */
142a46c0ec8Sopenharmony_cienum quirks_log_type {
143a46c0ec8Sopenharmony_ci	QLOG_LIBINPUT_LOGGING,
144a46c0ec8Sopenharmony_ci	QLOG_CUSTOM_LOG_PRIORITIES,
145a46c0ec8Sopenharmony_ci};
146a46c0ec8Sopenharmony_ci
147a46c0ec8Sopenharmony_ci/**
148a46c0ec8Sopenharmony_ci * Initialize the quirks subsystem. This function must be called
149a46c0ec8Sopenharmony_ci * before anything else.
150a46c0ec8Sopenharmony_ci *
151a46c0ec8Sopenharmony_ci * If log_type is QLOG_CUSTOM_LOG_PRIORITIES, the log handler is called with
152a46c0ec8Sopenharmony_ci * the custom QLOG_* log priorities. Otherwise, the log handler only uses
153a46c0ec8Sopenharmony_ci * the libinput log priorities.
154a46c0ec8Sopenharmony_ci *
155a46c0ec8Sopenharmony_ci * @param data_path The directory containing the various data files
156a46c0ec8Sopenharmony_ci * @param override_file A file path containing custom overrides
157a46c0ec8Sopenharmony_ci * @param log_handler The libinput log handler called for debugging output
158a46c0ec8Sopenharmony_ci * @param libinput The libinput struct passed to the log handler
159a46c0ec8Sopenharmony_ci *
160a46c0ec8Sopenharmony_ci * @return an opaque handle to the context
161a46c0ec8Sopenharmony_ci */
162a46c0ec8Sopenharmony_cistruct quirks_context *
163a46c0ec8Sopenharmony_ciquirks_init_subsystem(const char *data_path,
164a46c0ec8Sopenharmony_ci		      const char *override_file,
165a46c0ec8Sopenharmony_ci		      libinput_log_handler log_handler,
166a46c0ec8Sopenharmony_ci		      struct libinput *libinput,
167a46c0ec8Sopenharmony_ci		      enum quirks_log_type log_type);
168a46c0ec8Sopenharmony_ci
169a46c0ec8Sopenharmony_ci/**
170a46c0ec8Sopenharmony_ci * Clean up after ourselves. This function must be called
171a46c0ec8Sopenharmony_ci * as the last call to the quirks subsystem.
172a46c0ec8Sopenharmony_ci *
173a46c0ec8Sopenharmony_ci * All quirks returned to the caller in quirks_fetch_for_device() must be
174a46c0ec8Sopenharmony_ci * unref'd before this call.
175a46c0ec8Sopenharmony_ci *
176a46c0ec8Sopenharmony_ci * @return Always NULL
177a46c0ec8Sopenharmony_ci */
178a46c0ec8Sopenharmony_cistruct quirks_context *
179a46c0ec8Sopenharmony_ciquirks_context_unref(struct quirks_context *ctx);
180a46c0ec8Sopenharmony_ci
181a46c0ec8Sopenharmony_cistruct quirks_context *
182a46c0ec8Sopenharmony_ciquirks_context_ref(struct quirks_context *ctx);
183a46c0ec8Sopenharmony_ci
184a46c0ec8Sopenharmony_ci/**
185a46c0ec8Sopenharmony_ci * Fetch the quirks for a given device. If no quirks are defined, this
186a46c0ec8Sopenharmony_ci * function returns NULL.
187a46c0ec8Sopenharmony_ci *
188a46c0ec8Sopenharmony_ci * @return A new quirks struct, use quirks_unref() to release
189a46c0ec8Sopenharmony_ci */
190a46c0ec8Sopenharmony_cistruct quirks *
191a46c0ec8Sopenharmony_ciquirks_fetch_for_device(struct quirks_context *ctx,
192a46c0ec8Sopenharmony_ci			struct udev_device *device);
193a46c0ec8Sopenharmony_ci
194a46c0ec8Sopenharmony_ci/**
195a46c0ec8Sopenharmony_ci * Reduce the refcount by one. When the refcount reaches zero, the
196a46c0ec8Sopenharmony_ci * associated struct is released.
197a46c0ec8Sopenharmony_ci *
198a46c0ec8Sopenharmony_ci * @return Always NULL
199a46c0ec8Sopenharmony_ci */
200a46c0ec8Sopenharmony_cistruct quirks *
201a46c0ec8Sopenharmony_ciquirks_unref(struct quirks *q);
202a46c0ec8Sopenharmony_ci
203a46c0ec8Sopenharmony_ci/**
204a46c0ec8Sopenharmony_ci * Returns true if the given quirk applies is in this quirk list.
205a46c0ec8Sopenharmony_ci */
206a46c0ec8Sopenharmony_cibool
207a46c0ec8Sopenharmony_ciquirks_has_quirk(struct quirks *q, enum quirk which);
208a46c0ec8Sopenharmony_ci
209a46c0ec8Sopenharmony_ci/**
210a46c0ec8Sopenharmony_ci * Get the value of the given quirk, as unsigned integer.
211a46c0ec8Sopenharmony_ci * This function will assert if the quirk type does not match the
212a46c0ec8Sopenharmony_ci * requested type. If the quirk is not set for this device, val is
213a46c0ec8Sopenharmony_ci * unchanged.
214a46c0ec8Sopenharmony_ci *
215a46c0ec8Sopenharmony_ci * @return true if the quirk value is valid, false otherwise.
216a46c0ec8Sopenharmony_ci */
217a46c0ec8Sopenharmony_cibool
218a46c0ec8Sopenharmony_ciquirks_get_uint32(struct quirks *q,
219a46c0ec8Sopenharmony_ci		  enum quirk which,
220a46c0ec8Sopenharmony_ci		  uint32_t *val);
221a46c0ec8Sopenharmony_ci
222a46c0ec8Sopenharmony_ci/**
223a46c0ec8Sopenharmony_ci * Get the value of the given quirk, as signed integer.
224a46c0ec8Sopenharmony_ci * This function will assert if the quirk type does not match the
225a46c0ec8Sopenharmony_ci * requested type. If the quirk is not set for this device, val is
226a46c0ec8Sopenharmony_ci * unchanged.
227a46c0ec8Sopenharmony_ci *
228a46c0ec8Sopenharmony_ci * @return true if the quirk value is valid, false otherwise.
229a46c0ec8Sopenharmony_ci */
230a46c0ec8Sopenharmony_cibool
231a46c0ec8Sopenharmony_ciquirks_get_int32(struct quirks *q,
232a46c0ec8Sopenharmony_ci		 enum quirk which,
233a46c0ec8Sopenharmony_ci		 int32_t *val);
234a46c0ec8Sopenharmony_ci
235a46c0ec8Sopenharmony_ci/**
236a46c0ec8Sopenharmony_ci * Get the value of the given quirk, as double.
237a46c0ec8Sopenharmony_ci * This function will assert if the quirk type does not match the
238a46c0ec8Sopenharmony_ci * requested type. If the quirk is not set for this device, val is
239a46c0ec8Sopenharmony_ci * unchanged.
240a46c0ec8Sopenharmony_ci *
241a46c0ec8Sopenharmony_ci * @return true if the quirk value is valid, false otherwise.
242a46c0ec8Sopenharmony_ci */
243a46c0ec8Sopenharmony_cibool
244a46c0ec8Sopenharmony_ciquirks_get_double(struct quirks *q,
245a46c0ec8Sopenharmony_ci		  enum quirk which,
246a46c0ec8Sopenharmony_ci		  double *val);
247a46c0ec8Sopenharmony_ci
248a46c0ec8Sopenharmony_ci/**
249a46c0ec8Sopenharmony_ci * Get the value of the given quirk, as string.
250a46c0ec8Sopenharmony_ci * This function will assert if the quirk type does not match the
251a46c0ec8Sopenharmony_ci * requested type. If the quirk is not set for this device, val is
252a46c0ec8Sopenharmony_ci * unchanged.
253a46c0ec8Sopenharmony_ci *
254a46c0ec8Sopenharmony_ci * val is set to the string, do not modify or free it. The lifetime of the
255a46c0ec8Sopenharmony_ci * returned string is bound to the lifetime of the quirk.
256a46c0ec8Sopenharmony_ci *
257a46c0ec8Sopenharmony_ci * @return true if the quirk value is valid, false otherwise.
258a46c0ec8Sopenharmony_ci */
259a46c0ec8Sopenharmony_cibool
260a46c0ec8Sopenharmony_ciquirks_get_string(struct quirks *q,
261a46c0ec8Sopenharmony_ci		  enum quirk which,
262a46c0ec8Sopenharmony_ci		  char **val);
263a46c0ec8Sopenharmony_ci
264a46c0ec8Sopenharmony_ci/**
265a46c0ec8Sopenharmony_ci * Get the value of the given quirk, as bool.
266a46c0ec8Sopenharmony_ci * This function will assert if the quirk type does not match the
267a46c0ec8Sopenharmony_ci * requested type. If the quirk is not set for this device, val is
268a46c0ec8Sopenharmony_ci * unchanged.
269a46c0ec8Sopenharmony_ci *
270a46c0ec8Sopenharmony_ci * @return true if the quirk value is valid, false otherwise.
271a46c0ec8Sopenharmony_ci */
272a46c0ec8Sopenharmony_cibool
273a46c0ec8Sopenharmony_ciquirks_get_bool(struct quirks *q,
274a46c0ec8Sopenharmony_ci		enum quirk which,
275a46c0ec8Sopenharmony_ci		bool *val);
276a46c0ec8Sopenharmony_ci
277a46c0ec8Sopenharmony_ci/**
278a46c0ec8Sopenharmony_ci * Get the value of the given quirk, as dimension.
279a46c0ec8Sopenharmony_ci * This function will assert if the quirk type does not match the
280a46c0ec8Sopenharmony_ci * requested type. If the quirk is not set for this device, val is
281a46c0ec8Sopenharmony_ci * unchanged.
282a46c0ec8Sopenharmony_ci *
283a46c0ec8Sopenharmony_ci * @return true if the quirk value is valid, false otherwise.
284a46c0ec8Sopenharmony_ci */
285a46c0ec8Sopenharmony_cibool
286a46c0ec8Sopenharmony_ciquirks_get_dimensions(struct quirks *q,
287a46c0ec8Sopenharmony_ci		      enum quirk which,
288a46c0ec8Sopenharmony_ci		      struct quirk_dimensions *val);
289a46c0ec8Sopenharmony_ci
290a46c0ec8Sopenharmony_ci/**
291a46c0ec8Sopenharmony_ci * Get the value of the given quirk, as range.
292a46c0ec8Sopenharmony_ci * This function will assert if the quirk type does not match the
293a46c0ec8Sopenharmony_ci * requested type. If the quirk is not set for this device, val is
294a46c0ec8Sopenharmony_ci * unchanged.
295a46c0ec8Sopenharmony_ci *
296a46c0ec8Sopenharmony_ci * @return true if the quirk value is valid, false otherwise.
297a46c0ec8Sopenharmony_ci */
298a46c0ec8Sopenharmony_cibool
299a46c0ec8Sopenharmony_ciquirks_get_range(struct quirks *q,
300a46c0ec8Sopenharmony_ci		 enum quirk which,
301a46c0ec8Sopenharmony_ci		 struct quirk_range *val);
302a46c0ec8Sopenharmony_ci
303a46c0ec8Sopenharmony_ci/**
304a46c0ec8Sopenharmony_ci * Get the tuples of the given quirk.
305a46c0ec8Sopenharmony_ci * This function will assert if the quirk type does not match the
306a46c0ec8Sopenharmony_ci * requested type. If the quirk is not set for this device, tuples is
307a46c0ec8Sopenharmony_ci * unchanged.
308a46c0ec8Sopenharmony_ci *
309a46c0ec8Sopenharmony_ci * @return true if the quirk value is valid, false otherwise.
310a46c0ec8Sopenharmony_ci */
311a46c0ec8Sopenharmony_cibool
312a46c0ec8Sopenharmony_ciquirks_get_tuples(struct quirks *q,
313a46c0ec8Sopenharmony_ci		  enum quirk which,
314a46c0ec8Sopenharmony_ci		  const struct quirk_tuples **tuples);
315a46c0ec8Sopenharmony_ci
316a46c0ec8Sopenharmony_ci/**
317a46c0ec8Sopenharmony_ci * Get the uint32 array of the given quirk.
318a46c0ec8Sopenharmony_ci * This function will assert if the quirk type does not match the
319a46c0ec8Sopenharmony_ci * requested type. If the quirk is not set for this device, tuples is
320a46c0ec8Sopenharmony_ci * unchanged.
321a46c0ec8Sopenharmony_ci *
322a46c0ec8Sopenharmony_ci * @return true if the quirk value is valid, false otherwise.
323a46c0ec8Sopenharmony_ci */
324a46c0ec8Sopenharmony_cibool
325a46c0ec8Sopenharmony_ciquirks_get_uint32_array(struct quirks *q,
326a46c0ec8Sopenharmony_ci			enum quirk which,
327a46c0ec8Sopenharmony_ci			const uint32_t **array,
328a46c0ec8Sopenharmony_ci			size_t *nelements);
329