[media] serial_ir: generate timeout

No timeout is generated by serial_ir since the port only generates
interrupts on edges. Some IR protocols like rc6 and rc5 need a trailing
space or timeout so they know there are no more bits coming.

Without it, the current key will only be reported once some more IR
occurs.

Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Sean Young 2016-12-02 15:16:11 -02:00 committed by Mauro Carvalho Chehab
parent 17809ed219
commit 2940c7e497

View file

@ -137,6 +137,7 @@ struct serial_ir {
ktime_t lastkt; ktime_t lastkt;
struct rc_dev *rcdev; struct rc_dev *rcdev;
struct platform_device *pdev; struct platform_device *pdev;
struct timer_list timeout_timer;
unsigned int freq; unsigned int freq;
unsigned int duty_cycle; unsigned int duty_cycle;
@ -395,9 +396,14 @@ static irqreturn_t serial_ir_irq_handler(int i, void *blah)
frbwrite(data, !(dcd ^ sense)); frbwrite(data, !(dcd ^ sense));
serial_ir.lastkt = kt; serial_ir.lastkt = kt;
last_dcd = dcd; last_dcd = dcd;
ir_raw_event_handle(serial_ir.rcdev);
} }
} while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */
mod_timer(&serial_ir.timeout_timer,
jiffies + nsecs_to_jiffies(serial_ir.rcdev->timeout));
ir_raw_event_handle(serial_ir.rcdev);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@ -471,6 +477,16 @@ static int hardware_init_port(void)
return 0; return 0;
} }
static void serial_ir_timeout(unsigned long arg)
{
DEFINE_IR_RAW_EVENT(ev);
ev.timeout = true;
ev.duration = serial_ir.rcdev->timeout;
ir_raw_event_store_with_filter(serial_ir.rcdev, &ev);
ir_raw_event_handle(serial_ir.rcdev);
}
static int serial_ir_probe(struct platform_device *dev) static int serial_ir_probe(struct platform_device *dev)
{ {
int i, nlow, nhigh, result; int i, nlow, nhigh, result;
@ -500,6 +516,9 @@ static int serial_ir_probe(struct platform_device *dev)
return -EBUSY; return -EBUSY;
} }
setup_timer(&serial_ir.timeout_timer, serial_ir_timeout,
(unsigned long)&serial_ir);
result = hardware_init_port(); result = hardware_init_port();
if (result < 0) if (result < 0)
return result; return result;
@ -781,7 +800,9 @@ static int __init serial_ir_init_module(void)
rcdev->allowed_protocols = RC_BIT_ALL; rcdev->allowed_protocols = RC_BIT_ALL;
rcdev->driver_name = KBUILD_MODNAME; rcdev->driver_name = KBUILD_MODNAME;
rcdev->map_name = RC_MAP_RC6_MCE; rcdev->map_name = RC_MAP_RC6_MCE;
rcdev->min_timeout = 1;
rcdev->timeout = IR_DEFAULT_TIMEOUT; rcdev->timeout = IR_DEFAULT_TIMEOUT;
rcdev->max_timeout = 10 * IR_DEFAULT_TIMEOUT;
rcdev->rx_resolution = 250000; rcdev->rx_resolution = 250000;
serial_ir.rcdev = rcdev; serial_ir.rcdev = rcdev;
@ -797,6 +818,7 @@ static int __init serial_ir_init_module(void)
static void __exit serial_ir_exit_module(void) static void __exit serial_ir_exit_module(void)
{ {
del_timer_sync(&serial_ir.timeout_timer);
rc_unregister_device(serial_ir.rcdev); rc_unregister_device(serial_ir.rcdev);
serial_ir_exit(); serial_ir_exit();
} }