[media] em28xx: reduce the polling interval for GPI connected buttons
authorFrank Schaefer <fschaefer.oss@googlemail.com>
Sat, 14 Dec 2013 09:40:11 +0000 (06:40 -0300)
committerMauro Carvalho Chehab <m.chehab@samsung.com>
Fri, 20 Dec 2013 16:10:21 +0000 (14:10 -0200)
For GPI-connected buttons without (hardware) debouncing, the polling interval
needs to be reduced to detect button presses properly.

Signed-off-by: Frank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
drivers/media/usb/em28xx/em28xx-input.c
drivers/media/usb/em28xx/em28xx.h

index 5ec6a4e7f853cd76b91abce29e9dbeba3cbf2593..93a7d02b9cb498aa3eca31b17f2908bbb977c285 100644 (file)
@@ -30,8 +30,9 @@
 
 #include "em28xx.h"
 
-#define EM28XX_SNAPSHOT_KEY KEY_CAMERA
-#define EM28XX_BUTTONS_QUERY_INTERVAL 500
+#define EM28XX_SNAPSHOT_KEY                            KEY_CAMERA
+#define EM28XX_BUTTONS_DEBOUNCED_QUERY_INTERVAL                500 /* [ms] */
+#define EM28XX_BUTTONS_VOLATILE_QUERY_INTERVAL         100 /* [ms] */
 
 static unsigned int ir_debug;
 module_param(ir_debug, int, 0644);
@@ -546,7 +547,7 @@ static void em28xx_query_buttons(struct work_struct *work)
        }
        /* Schedule next poll */
        schedule_delayed_work(&dev->buttons_query_work,
-                             msecs_to_jiffies(EM28XX_BUTTONS_QUERY_INTERVAL));
+                             msecs_to_jiffies(dev->button_polling_interval));
 }
 
 static int em28xx_register_snapshot_button(struct em28xx *dev)
@@ -594,6 +595,7 @@ static void em28xx_init_buttons(struct em28xx *dev)
        u8  i = 0, j = 0;
        bool addr_new = 0;
 
+       dev->button_polling_interval = EM28XX_BUTTONS_DEBOUNCED_QUERY_INTERVAL;
        while (dev->board.buttons[i].role >= 0 &&
                         dev->board.buttons[i].role < EM28XX_NUM_BUTTON_ROLES) {
                struct em28xx_button *button = &dev->board.buttons[i];
@@ -609,18 +611,18 @@ static void em28xx_init_buttons(struct em28xx *dev)
                if (addr_new && dev->num_button_polling_addresses
                                           >= EM28XX_NUM_BUTTON_ADDRESSES_MAX) {
                        WARN_ONCE(1, "BUG: maximum number of button polling addresses exceeded.");
-                       addr_new = 0;
+                       goto next_button;
                }
                /* Button role specific checks and actions */
                if (button->role == EM28XX_BUTTON_SNAPSHOT) {
                        /* Register input device */
                        if (em28xx_register_snapshot_button(dev) < 0)
-                               addr_new = 0;
+                               goto next_button;
                } else if (button->role == EM28XX_BUTTON_ILLUMINATION) {
                        /* Check sanity */
                        if (!em28xx_find_led(dev, EM28XX_LED_ILLUMINATION)) {
                                em28xx_errdev("BUG: illumination button defined, but no illumination LED.\n");
-                               addr_new = 0;
+                               goto next_button;
                        }
                }
                /* Add read address to list of polling addresses */
@@ -629,6 +631,11 @@ static void em28xx_init_buttons(struct em28xx *dev)
                        dev->button_polling_addresses[index] = button->reg_r;
                        dev->num_button_polling_addresses++;
                }
+               /* Reduce polling interval if necessary */
+               if (!button->reg_clearing)
+                       dev->button_polling_interval =
+                                        EM28XX_BUTTONS_VOLATILE_QUERY_INTERVAL;
+next_button:
                /* Next button */
                i++;
        }
@@ -640,7 +647,7 @@ static void em28xx_init_buttons(struct em28xx *dev)
                INIT_DELAYED_WORK(&dev->buttons_query_work,
                                                          em28xx_query_buttons);
                schedule_delayed_work(&dev->buttons_query_work,
-                              msecs_to_jiffies(EM28XX_BUTTONS_QUERY_INTERVAL));
+                              msecs_to_jiffies(dev->button_polling_interval));
        }
 }
 
index aa35750d6e6606f83ab21d6a56ce16e977b0559f..191ef3593891663d43daa778eb21e1ac7a1b55aa 100644 (file)
@@ -681,6 +681,7 @@ struct em28xx {
        u8 button_polling_addresses[EM28XX_NUM_BUTTON_ADDRESSES_MAX];
        u8 button_polling_last_values[EM28XX_NUM_BUTTON_ADDRESSES_MAX];
        u8 num_button_polling_addresses;
+       u16 button_polling_interval; /* [ms] */
        /* Snapshot button input device */
        char snapshot_button_path[30];  /* path of the input dev */
        struct input_dev *sbutton_input_dev;