Commit 7763481a authored by Frank Schaefer's avatar Frank Schaefer Committed by Mauro Carvalho Chehab

[media] em28xx: add debouncing mechanism for GPI-connected buttons

So far, the driver only supports a snapshot button which is assigned to
register 0x0c bit 5. This special port has a built-in debouncing mechanism.
For buttons connected to ordinary GPI ports, this patch implements a software
debouncing mechanism.
Signed-off-by: default avatarFrank Schäfer <fschaefer.oss@googlemail.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent f5222609
...@@ -479,7 +479,7 @@ static void em28xx_query_buttons(struct work_struct *work) ...@@ -479,7 +479,7 @@ static void em28xx_query_buttons(struct work_struct *work)
container_of(work, struct em28xx, buttons_query_work.work); container_of(work, struct em28xx, buttons_query_work.work);
u8 i, j; u8 i, j;
int regval; int regval;
bool pressed; bool is_pressed, was_pressed;
/* Poll and evaluate all addresses */ /* Poll and evaluate all addresses */
for (i = 0; i < dev->num_button_polling_addresses; i++) { for (i = 0; i < dev->num_button_polling_addresses; i++) {
...@@ -497,12 +497,21 @@ static void em28xx_query_buttons(struct work_struct *work) ...@@ -497,12 +497,21 @@ static void em28xx_query_buttons(struct work_struct *work)
j++; j++;
continue; continue;
} }
/* Determine if button is pressed */ /* Determine if button is and was pressed last time */
pressed = regval & button->mask; is_pressed = regval & button->mask;
if (button->inverted) was_pressed = dev->button_polling_last_values[i]
pressed = !pressed; & button->mask;
if (button->inverted) {
is_pressed = !is_pressed;
was_pressed = !was_pressed;
}
/* Clear button state (if needed) */
if (is_pressed && button->reg_clearing)
em28xx_write_reg(dev, button->reg_clearing,
(~regval & button->mask)
| (regval & ~button->mask));
/* Handle button state */ /* Handle button state */
if (!pressed) { if (!is_pressed || was_pressed) {
j++; j++;
continue; continue;
} }
...@@ -518,14 +527,11 @@ static void em28xx_query_buttons(struct work_struct *work) ...@@ -518,14 +527,11 @@ static void em28xx_query_buttons(struct work_struct *work)
default: default:
WARN_ONCE(1, "BUG: unhandled button role."); WARN_ONCE(1, "BUG: unhandled button role.");
} }
/* Clear button state (if needed) */
if (button->reg_clearing)
em28xx_write_reg(dev, button->reg_clearing,
(~regval & button->mask)
| (regval & ~button->mask));
/* Next button */ /* Next button */
j++; j++;
} }
/* Save current value for comparison during the next polling */
dev->button_polling_last_values[i] = regval;
} }
/* Schedule next poll */ /* Schedule next poll */
schedule_delayed_work(&dev->buttons_query_work, schedule_delayed_work(&dev->buttons_query_work,
...@@ -611,6 +617,8 @@ static void em28xx_init_buttons(struct em28xx *dev) ...@@ -611,6 +617,8 @@ static void em28xx_init_buttons(struct em28xx *dev)
/* Start polling */ /* Start polling */
if (dev->num_button_polling_addresses) { if (dev->num_button_polling_addresses) {
memset(dev->button_polling_last_values, 0,
EM28XX_NUM_BUTTON_ADDRESSES_MAX);
INIT_DELAYED_WORK(&dev->buttons_query_work, INIT_DELAYED_WORK(&dev->buttons_query_work,
em28xx_query_buttons); em28xx_query_buttons);
schedule_delayed_work(&dev->buttons_query_work, schedule_delayed_work(&dev->buttons_query_work,
......
...@@ -669,6 +669,7 @@ struct em28xx { ...@@ -669,6 +669,7 @@ struct em28xx {
/* Button state polling */ /* Button state polling */
struct delayed_work buttons_query_work; struct delayed_work buttons_query_work;
u8 button_polling_addresses[EM28XX_NUM_BUTTON_ADDRESSES_MAX]; u8 button_polling_addresses[EM28XX_NUM_BUTTON_ADDRESSES_MAX];
u8 button_polling_last_values[EM28XX_NUM_BUTTON_ADDRESSES_MAX];
u8 num_button_polling_addresses; u8 num_button_polling_addresses;
/* Snapshot button input device */ /* Snapshot button input device */
char snapshot_button_path[30]; /* path of the input dev */ char snapshot_button_path[30]; /* path of the input dev */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment