@@ -186,12 +186,14 @@ struct atmel_ptc {
186186 int irq ;
187187 u8 imr ;
188188 struct completion ppp_ack ;
189+ struct tasklet_struct tasklet ;
189190 unsigned int button_keycode [ATMEL_PTC_MAX_NODES ];
190191 bool buttons_registered ;
191192 bool scroller_registered [ATMEL_PTC_MAX_SCROLLERS ];
192193 u32 button_event [ATMEL_PTC_MAX_NODES / 32 ];
193194 u32 button_state [ATMEL_PTC_MAX_NODES / 32 ];
194195 u32 scroller_event ;
196+ bool scroller_tracking ;
195197 char fw_version [ATMEL_PPP_FW_FOOTER_SIZE ];
196198};
197199
@@ -403,29 +405,29 @@ static u32 atmel_qtm_get_touch_events_scroller_event_id(struct atmel_ptc *ptc)
403405
404406static void atmel_ptc_irq_scroller_event (struct atmel_ptc * ptc )
405407{
406- unsigned long i ;
408+ unsigned int status , i ;
407409
408- if (!ptc -> scroller_event )
410+ if (!ptc -> scroller_event || ptc -> scroller_tracking )
409411 return ;
410412
411- for_each_set_bit (i , (unsigned long * )& ptc -> scroller_event , ATMEL_PTC_MAX_SCROLLERS ) {
412- unsigned int scroller_type =
413- atmel_qtm_get_scroller_type (ptc , i );
414- unsigned int position =
415- atmel_qtm_get_scroller_position (ptc , i );
416- unsigned int status =
417- atmel_qtm_get_scroller_status (ptc , i );
418-
419- if (scroller_type == ATMEL_QTM_SCROLLER_TYPE_WHEEL )
420- input_report_abs (ptc -> scroller_input [i ],
421- ABS_WHEEL , position );
422- else
423- input_report_abs (ptc -> scroller_input [i ],
424- ABS_X , position );
413+ /*
414+ * Report the touch event and let the tasklet tracking the position
415+ * until the scrollers are no longer touched.
416+ */
417+ for (i = 0 ; i < ATMEL_PTC_MAX_SCROLLERS ; i ++ ) {
418+ if (!ptc -> scroller_input [i ])
419+ break ;
420+
421+ status = atmel_qtm_get_scroller_status (ptc , i );
425422
426423 input_report_key (ptc -> scroller_input [i ], BTN_TOUCH ,
427424 status & 0x1 );
428425 input_sync (ptc -> scroller_input [i ]);
426+
427+ if (status & 0x1 ) {
428+ ptc -> scroller_tracking = true;
429+ tasklet_schedule (& ptc -> tasklet );
430+ }
429431 }
430432}
431433
@@ -724,6 +726,37 @@ static int atmel_ptc_cmd_send(struct atmel_ptc *ptc, struct atmel_qtm_cmd *cmd)
724726 return 0 ;
725727}
726728
729+ static void atmel_ptc_tasklet (unsigned long priv )
730+ {
731+ struct atmel_ptc * ptc = (struct atmel_ptc * )priv ;
732+ unsigned int scroller_type , position , status , i ;
733+
734+ for (i = 0 ; i < ATMEL_PTC_MAX_SCROLLERS ; i ++ ) {
735+ if (!ptc -> scroller_input [i ])
736+ break ;
737+
738+ scroller_type = atmel_qtm_get_scroller_type (ptc , i );
739+ position = atmel_qtm_get_scroller_position (ptc , i );
740+ status = atmel_qtm_get_scroller_status (ptc , i );
741+
742+ if (status & 0x1 ) {
743+ if (scroller_type == ATMEL_QTM_SCROLLER_TYPE_WHEEL )
744+ input_report_abs (ptc -> scroller_input [i ],
745+ ABS_WHEEL , position );
746+ else
747+ input_report_abs (ptc -> scroller_input [i ],
748+ ABS_X , position );
749+ input_sync (ptc -> scroller_input [i ]);
750+ tasklet_schedule (& ptc -> tasklet );
751+ } else {
752+ input_report_key (ptc -> scroller_input [i ], BTN_TOUCH , 0 );
753+ input_sync (ptc -> scroller_input [i ]);
754+
755+ ptc -> scroller_tracking = false;
756+ }
757+ }
758+ }
759+
727760static int atmel_ptc_conf_load (struct atmel_ptc * ptc )
728761{
729762 const struct firmware * conf ;
@@ -1024,13 +1057,16 @@ static int atmel_ptc_probe(struct platform_device *pdev)
10241057 if (debug_mode )
10251058 ret = sysfs_create_group (& ptc -> dev -> kobj , & atmel_ptc_qtm_mb_attr_group );
10261059
1060+ tasklet_init (& ptc -> tasklet , atmel_ptc_tasklet , (unsigned long )ptc );
1061+
10271062 return ret ;
10281063}
10291064
10301065static int atmel_ptc_remove (struct platform_device * pdev )
10311066{
10321067 struct atmel_ptc * ptc = platform_get_drvdata (pdev );
10331068
1069+ tasklet_kill (& ptc -> tasklet );
10341070 atmel_ptc_unregister_input_devices (ptc );
10351071 atmel_ptc_free_pins (ptc );
10361072
0 commit comments