aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/IR/ir-nec-decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/IR/ir-nec-decoder.c')
-rw-r--r--drivers/media/IR/ir-nec-decoder.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index 52e0f378ae3d..d597421d6547 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -20,12 +20,13 @@
20#define NEC_HEADER_PULSE (16 * NEC_UNIT) 20#define NEC_HEADER_PULSE (16 * NEC_UNIT)
21#define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */ 21#define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */
22#define NEC_HEADER_SPACE (8 * NEC_UNIT) 22#define NEC_HEADER_SPACE (8 * NEC_UNIT)
23#define NEC_REPEAT_SPACE (8 * NEC_UNIT) 23#define NEC_REPEAT_SPACE (4 * NEC_UNIT)
24#define NEC_BIT_PULSE (1 * NEC_UNIT) 24#define NEC_BIT_PULSE (1 * NEC_UNIT)
25#define NEC_BIT_0_SPACE (1 * NEC_UNIT) 25#define NEC_BIT_0_SPACE (1 * NEC_UNIT)
26#define NEC_BIT_1_SPACE (3 * NEC_UNIT) 26#define NEC_BIT_1_SPACE (3 * NEC_UNIT)
27#define NEC_TRAILER_PULSE (1 * NEC_UNIT) 27#define NEC_TRAILER_PULSE (1 * NEC_UNIT)
28#define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */ 28#define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */
29#define NECX_REPEAT_BITS 1
29 30
30enum nec_state { 31enum nec_state {
31 STATE_INACTIVE, 32 STATE_INACTIVE,
@@ -67,8 +68,12 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
67 if (!ev.pulse) 68 if (!ev.pulse)
68 break; 69 break;
69 70
70 if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) && 71 if (eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2)) {
71 !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2)) 72 data->is_nec_x = false;
73 data->necx_repeat = false;
74 } else if (eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2))
75 data->is_nec_x = true;
76 else
72 break; 77 break;
73 78
74 data->count = 0; 79 data->count = 0;
@@ -105,6 +110,17 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
105 if (ev.pulse) 110 if (ev.pulse)
106 break; 111 break;
107 112
113 if (data->necx_repeat && data->count == NECX_REPEAT_BITS &&
114 geq_margin(ev.duration,
115 NEC_TRAILER_SPACE, NEC_UNIT / 2)) {
116 IR_dprintk(1, "Repeat last key\n");
117 ir_repeat(input_dev);
118 data->state = STATE_INACTIVE;
119 return 0;
120
121 } else if (data->count > NECX_REPEAT_BITS)
122 data->necx_repeat = false;
123
108 data->bits <<= 1; 124 data->bits <<= 1;
109 if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) 125 if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
110 data->bits |= 1; 126 data->bits |= 1;
@@ -159,6 +175,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
159 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); 175 IR_dprintk(1, "NEC scancode 0x%04x\n", scancode);
160 } 176 }
161 177
178 if (data->is_nec_x)
179 data->necx_repeat = true;
180
162 ir_keydown(input_dev, scancode, 0); 181 ir_keydown(input_dev, scancode, 0);
163 data->state = STATE_INACTIVE; 182 data->state = STATE_INACTIVE;
164 return 0; 183 return 0;