Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+19 −11
Original line number Diff line number Diff line
@@ -479,7 +479,7 @@ static void em28xx_query_buttons(struct work_struct *work)
		container_of(work, struct em28xx, buttons_query_work.work);
	u8 i, j;
	int regval;
	bool pressed;
	bool is_pressed, was_pressed;

	/* Poll and evaluate all addresses */
	for (i = 0; i < dev->num_button_polling_addresses; i++) {
@@ -497,12 +497,21 @@ static void em28xx_query_buttons(struct work_struct *work)
				j++;
				continue;
			}
			/* Determine if button is pressed */
			pressed = regval & button->mask;
			if (button->inverted)
				pressed = !pressed;
			/* Determine if button is and was pressed last time */
			is_pressed = regval & button->mask;
			was_pressed = dev->button_polling_last_values[i]
				       & 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 */
			if (!pressed) {
			if (!is_pressed || was_pressed) {
				j++;
				continue;
			}
@@ -518,14 +527,11 @@ static void em28xx_query_buttons(struct work_struct *work)
			default:
				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 */
			j++;
		}
		/* Save current value for comparison during the next polling */
		dev->button_polling_last_values[i] = regval;
	}
	/* Schedule next poll */
	schedule_delayed_work(&dev->buttons_query_work,
@@ -611,6 +617,8 @@ static void em28xx_init_buttons(struct em28xx *dev)

	/* Start polling */
	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,
							  em28xx_query_buttons);
		schedule_delayed_work(&dev->buttons_query_work,
+1 −0
Original line number Diff line number Diff line
@@ -669,6 +669,7 @@ struct em28xx {
	/* Button state polling */
	struct delayed_work buttons_query_work;
	u8 button_polling_addresses[EM28XX_NUM_BUTTON_ADDRESSES_MAX];
	u8 button_polling_last_values[EM28XX_NUM_BUTTON_ADDRESSES_MAX];
	u8 num_button_polling_addresses;
	/* Snapshot button input device */
	char snapshot_button_path[30];	/* path of the input dev */