@@ -246,6 +246,123 @@ static int uclogic_resume(struct hid_device *hdev)
246246}
247247#endif
248248
249+ /**
250+ * uclogic_raw_event_pen - handle raw pen events (pen HID reports).
251+ *
252+ * @drvdata: Driver data.
253+ * @data: Report data buffer, can be modified.
254+ * @size: Report data size, bytes.
255+ *
256+ * Returns:
257+ * Negative value on error (stops event delivery), zero for success.
258+ */
259+ static int uclogic_raw_event_pen (struct uclogic_drvdata * drvdata ,
260+ u8 * data , int size )
261+ {
262+ struct uclogic_params * params = & drvdata -> params ;
263+
264+ WARN_ON (drvdata == NULL );
265+ WARN_ON (data == NULL && size != 0 );
266+
267+ /* If in-range reports are inverted */
268+ if (params -> pen .inrange ==
269+ UCLOGIC_PARAMS_PEN_INRANGE_INVERTED ) {
270+ /* Invert the in-range bit */
271+ data [1 ] ^= 0x40 ;
272+ }
273+ /*
274+ * If report contains fragmented high-resolution pen
275+ * coordinates
276+ */
277+ if (size >= 10 && params -> pen .fragmented_hires ) {
278+ u8 pressure_low_byte ;
279+ u8 pressure_high_byte ;
280+
281+ /* Lift pressure bytes */
282+ pressure_low_byte = data [6 ];
283+ pressure_high_byte = data [7 ];
284+ /*
285+ * Move Y coord to make space for high-order X
286+ * coord byte
287+ */
288+ data [6 ] = data [5 ];
289+ data [5 ] = data [4 ];
290+ /* Move high-order X coord byte */
291+ data [4 ] = data [8 ];
292+ /* Move high-order Y coord byte */
293+ data [7 ] = data [9 ];
294+ /* Place pressure bytes */
295+ data [8 ] = pressure_low_byte ;
296+ data [9 ] = pressure_high_byte ;
297+ }
298+ /* If we need to emulate in-range detection */
299+ if (params -> pen .inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE ) {
300+ /* Set in-range bit */
301+ data [1 ] |= 0x40 ;
302+ /* (Re-)start in-range timeout */
303+ mod_timer (& drvdata -> inrange_timer ,
304+ jiffies + msecs_to_jiffies (100 ));
305+ }
306+ /* If we report tilt and Y direction is flipped */
307+ if (size >= 12 && params -> pen .tilt_y_flipped )
308+ data [11 ] = - data [11 ];
309+
310+ return 0 ;
311+ }
312+
313+ /**
314+ * uclogic_raw_event_frame - handle raw frame events (frame HID reports).
315+ *
316+ * @drvdata: Driver data.
317+ * @data: Report data buffer, can be modified.
318+ * @size: Report data size, bytes.
319+ *
320+ * Returns:
321+ * Negative value on error (stops event delivery), zero for success.
322+ */
323+ static int uclogic_raw_event_frame (struct uclogic_drvdata * drvdata ,
324+ u8 * data , int size )
325+ {
326+ struct uclogic_params * params = & drvdata -> params ;
327+
328+ WARN_ON (drvdata == NULL );
329+ WARN_ON (data == NULL && size != 0 );
330+
331+ /* If need to, and can, set pad device ID for Wacom drivers */
332+ if (params -> frame .dev_id_byte > 0 &&
333+ params -> frame .dev_id_byte < size ) {
334+ data [params -> frame .dev_id_byte ] = 0xf ;
335+ }
336+ /* If need to, and can, read rotary encoder state change */
337+ if (params -> frame .re_lsb > 0 &&
338+ params -> frame .re_lsb / 8 < size ) {
339+ unsigned int byte = params -> frame .re_lsb / 8 ;
340+ unsigned int bit = params -> frame .re_lsb % 8 ;
341+
342+ u8 change ;
343+ u8 prev_state = drvdata -> re_state ;
344+ /* Read Gray-coded state */
345+ u8 state = (data [byte ] >> bit ) & 0x3 ;
346+ /* Encode state change into 2-bit signed integer */
347+ if ((prev_state == 1 && state == 0 ) ||
348+ (prev_state == 2 && state == 3 )) {
349+ change = 1 ;
350+ } else if ((prev_state == 2 && state == 0 ) ||
351+ (prev_state == 1 && state == 3 )) {
352+ change = 3 ;
353+ } else {
354+ change = 0 ;
355+ }
356+ /* Write change */
357+ data [byte ] = (data [byte ] & ~((u8 )3 << bit )) |
358+ (change << bit );
359+ /* Remember state */
360+ drvdata -> re_state = state ;
361+ }
362+
363+ return 0 ;
364+ }
365+
249366static int uclogic_raw_event (struct hid_device * hdev ,
250367 struct hid_report * report ,
251368 u8 * data , int size )
@@ -265,85 +382,13 @@ static int uclogic_raw_event(struct hid_device *hdev,
265382 data [0 ] = params -> frame .id ;
266383 return 0 ;
267384 }
268- /* If in-range reports are inverted */
269- if (params -> pen .inrange ==
270- UCLOGIC_PARAMS_PEN_INRANGE_INVERTED ) {
271- /* Invert the in-range bit */
272- data [1 ] ^= 0x40 ;
273- }
274- /*
275- * If report contains fragmented high-resolution pen
276- * coordinates
277- */
278- if (size >= 10 && params -> pen .fragmented_hires ) {
279- u8 pressure_low_byte ;
280- u8 pressure_high_byte ;
281-
282- /* Lift pressure bytes */
283- pressure_low_byte = data [6 ];
284- pressure_high_byte = data [7 ];
285- /*
286- * Move Y coord to make space for high-order X
287- * coord byte
288- */
289- data [6 ] = data [5 ];
290- data [5 ] = data [4 ];
291- /* Move high-order X coord byte */
292- data [4 ] = data [8 ];
293- /* Move high-order Y coord byte */
294- data [7 ] = data [9 ];
295- /* Place pressure bytes */
296- data [8 ] = pressure_low_byte ;
297- data [9 ] = pressure_high_byte ;
298- }
299- /* If we need to emulate in-range detection */
300- if (params -> pen .inrange == UCLOGIC_PARAMS_PEN_INRANGE_NONE ) {
301- /* Set in-range bit */
302- data [1 ] |= 0x40 ;
303- /* (Re-)start in-range timeout */
304- mod_timer (& drvdata -> inrange_timer ,
305- jiffies + msecs_to_jiffies (100 ));
306- }
307- /* If we report tilt and Y direction is flipped */
308- if (size >= 12 && params -> pen .tilt_y_flipped )
309- data [11 ] = - data [11 ];
385+ return uclogic_raw_event_pen (drvdata , data , size );
310386 }
311387
312388 /* Tweak frame control reports, if necessary */
313389 if ((report -> type == HID_INPUT_REPORT ) &&
314- (report -> id == params -> frame .id )) {
315- /* If need to, and can, set pad device ID for Wacom drivers */
316- if (params -> frame .dev_id_byte > 0 &&
317- params -> frame .dev_id_byte < size ) {
318- data [params -> frame .dev_id_byte ] = 0xf ;
319- }
320- /* If need to, and can, read rotary encoder state change */
321- if (params -> frame .re_lsb > 0 &&
322- params -> frame .re_lsb / 8 < size ) {
323- unsigned int byte = params -> frame .re_lsb / 8 ;
324- unsigned int bit = params -> frame .re_lsb % 8 ;
325-
326- u8 change ;
327- u8 prev_state = drvdata -> re_state ;
328- /* Read Gray-coded state */
329- u8 state = (data [byte ] >> bit ) & 0x3 ;
330- /* Encode state change into 2-bit signed integer */
331- if ((prev_state == 1 && state == 0 ) ||
332- (prev_state == 2 && state == 3 )) {
333- change = 1 ;
334- } else if ((prev_state == 2 && state == 0 ) ||
335- (prev_state == 1 && state == 3 )) {
336- change = 3 ;
337- } else {
338- change = 0 ;
339- }
340- /* Write change */
341- data [byte ] = (data [byte ] & ~((u8 )3 << bit )) |
342- (change << bit );
343- /* Remember state */
344- drvdata -> re_state = state ;
345- }
346- }
390+ (report -> id == params -> frame .id ))
391+ return uclogic_raw_event_frame (drvdata , data , size );
347392
348393 return 0 ;
349394}
0 commit comments