mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 12:57:06 +09:00
UPSTREAM: media: cec: move cec autorepeat handling to rc-core
CEC autorepeat is different than other protocols. Autorepeat is triggered by the first repeated user control pressed CEC message, rather than a fixed REP_DELAY. This change also does away with the KEY_UP event directly after the first KEY_DOWN event, which was used to stop autorepeat from starting. See commita9a249a2c9("media: cec: fix remote control passthrough") for the original change. Acked-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com> (cherry picked from commit57c642cb45) Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com> Conflicts: drivers/media/cec/cec-adap.c
This commit is contained in:
@@ -598,6 +598,7 @@ static void ir_do_keyup(struct rc_dev *dev, bool sync)
|
||||
return;
|
||||
|
||||
IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
|
||||
del_timer_sync(&dev->timer_repeat);
|
||||
input_report_key(dev->input_dev, dev->last_keycode, 0);
|
||||
led_trigger_event(led_feedback, LED_OFF);
|
||||
if (sync)
|
||||
@@ -650,6 +651,31 @@ static void ir_timer_keyup(struct timer_list *t)
|
||||
spin_unlock_irqrestore(&dev->keylock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* ir_timer_repeat() - generates a repeat event after a timeout
|
||||
*
|
||||
* @t: a pointer to the struct timer_list
|
||||
*
|
||||
* This routine will generate a soft repeat event every REP_PERIOD
|
||||
* milliseconds.
|
||||
*/
|
||||
static void ir_timer_repeat(struct timer_list *t)
|
||||
{
|
||||
struct rc_dev *dev = from_timer(dev, t, timer_repeat);
|
||||
struct input_dev *input = dev->input_dev;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&dev->keylock, flags);
|
||||
if (dev->keypressed) {
|
||||
input_event(input, EV_KEY, dev->last_keycode, 2);
|
||||
input_sync(input);
|
||||
if (input->rep[REP_PERIOD])
|
||||
mod_timer(&dev->timer_repeat, jiffies +
|
||||
msecs_to_jiffies(input->rep[REP_PERIOD]));
|
||||
}
|
||||
spin_unlock_irqrestore(&dev->keylock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* rc_repeat() - signals that a key is still pressed
|
||||
* @dev: the struct rc_dev descriptor of the device
|
||||
@@ -732,6 +758,22 @@ static void ir_do_keydown(struct rc_dev *dev, enum rc_proto protocol,
|
||||
led_trigger_event(led_feedback, LED_FULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* For CEC, start sending repeat messages as soon as the first
|
||||
* repeated message is sent, as long as REP_DELAY = 0 and REP_PERIOD
|
||||
* is non-zero. Otherwise, the input layer will generate repeat
|
||||
* messages.
|
||||
*/
|
||||
if (!new_event && keycode != KEY_RESERVED &&
|
||||
dev->allowed_protocols == RC_PROTO_BIT_CEC &&
|
||||
!timer_pending(&dev->timer_repeat) &&
|
||||
dev->input_dev->rep[REP_PERIOD] &&
|
||||
!dev->input_dev->rep[REP_DELAY]) {
|
||||
input_event(dev->input_dev, EV_KEY, keycode, 2);
|
||||
mod_timer(&dev->timer_repeat, jiffies +
|
||||
msecs_to_jiffies(dev->input_dev->rep[REP_PERIOD]));
|
||||
}
|
||||
|
||||
input_sync(dev->input_dev);
|
||||
}
|
||||
|
||||
@@ -1598,6 +1640,7 @@ struct rc_dev *rc_allocate_device(enum rc_driver_type type)
|
||||
input_set_drvdata(dev->input_dev, dev);
|
||||
|
||||
timer_setup(&dev->timer_keyup, ir_timer_keyup, 0);
|
||||
timer_setup(&dev->timer_repeat, ir_timer_repeat, 0);
|
||||
|
||||
spin_lock_init(&dev->rc_map.lock);
|
||||
spin_lock_init(&dev->keylock);
|
||||
@@ -1731,7 +1774,10 @@ static int rc_setup_rx_device(struct rc_dev *dev)
|
||||
* to avoid wrong repetition of the keycodes. Note that this must be
|
||||
* set after the call to input_register_device().
|
||||
*/
|
||||
dev->input_dev->rep[REP_DELAY] = 500;
|
||||
if (dev->allowed_protocols == RC_PROTO_BIT_CEC)
|
||||
dev->input_dev->rep[REP_DELAY] = 0;
|
||||
else
|
||||
dev->input_dev->rep[REP_DELAY] = 500;
|
||||
|
||||
/*
|
||||
* As a repeat event on protocols like RC-5 and NEC take as long as
|
||||
@@ -1883,6 +1929,7 @@ void rc_unregister_device(struct rc_dev *dev)
|
||||
return;
|
||||
|
||||
del_timer_sync(&dev->timer_keyup);
|
||||
del_timer_sync(&dev->timer_repeat);
|
||||
|
||||
if (dev->driver_type == RC_DRIVER_IR_RAW)
|
||||
ir_raw_event_unregister(dev);
|
||||
|
||||
@@ -134,6 +134,8 @@ struct lirc_fh {
|
||||
* @keypressed: whether a key is currently pressed
|
||||
* @keyup_jiffies: time (in jiffies) when the current keypress should be released
|
||||
* @timer_keyup: timer for releasing a keypress
|
||||
* @timer_repeat: timer for autorepeat events. This is needed for CEC, which
|
||||
* has non-standard repeats.
|
||||
* @last_keycode: keycode of last keypress
|
||||
* @last_protocol: protocol of last keypress
|
||||
* @last_scancode: scancode of last keypress
|
||||
@@ -202,6 +204,7 @@ struct rc_dev {
|
||||
bool keypressed;
|
||||
unsigned long keyup_jiffies;
|
||||
struct timer_list timer_keyup;
|
||||
struct timer_list timer_repeat;
|
||||
u32 last_keycode;
|
||||
enum rc_proto last_protocol;
|
||||
u32 last_scancode;
|
||||
|
||||
Reference in New Issue
Block a user