X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fmedia%2FIR%2Fir-nec-decoder.c;h=ba79233112efa526b04f2cfbc65acd4a16f70b00;hb=e40b1127f994a427568319d1be9b9e5ab1f58dd1;hp=14609d9580a8818c7dad7b28bf774017acfd40c3;hpb=25bb10c11e6cca461f09df8f59c2eb501a9e4d52;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c index 14609d9..ba79233 100644 --- a/drivers/media/IR/ir-nec-decoder.c +++ b/drivers/media/IR/ir-nec-decoder.c @@ -17,13 +17,15 @@ #define NEC_NBITS 32 #define NEC_UNIT 562500 /* ns */ -#define NEC_HEADER_PULSE PULSE(16) -#define NECX_HEADER_PULSE PULSE(8) /* Less common NEC variant */ -#define NEC_HEADER_SPACE SPACE(8) -#define NEC_REPEAT_SPACE SPACE(4) -#define NEC_BIT_PULSE PULSE(1) -#define NEC_BIT_0_SPACE SPACE(1) -#define NEC_BIT_1_SPACE SPACE(3) +#define NEC_HEADER_PULSE (16 * NEC_UNIT) +#define NECX_HEADER_PULSE (8 * NEC_UNIT) /* Less common NEC variant */ +#define NEC_HEADER_SPACE (8 * NEC_UNIT) +#define NEC_REPEAT_SPACE (8 * NEC_UNIT) +#define NEC_BIT_PULSE (1 * NEC_UNIT) +#define NEC_BIT_0_SPACE (1 * NEC_UNIT) +#define NEC_BIT_1_SPACE (3 * NEC_UNIT) +#define NEC_TRAILER_PULSE (1 * NEC_UNIT) +#define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */ /* Used to register nec_decoder clients */ static LIST_HEAD(decoder_list); @@ -119,15 +121,14 @@ static struct attribute_group decoder_attribute_group = { /** * ir_nec_decode() - Decode one NEC pulse or space * @input_dev: the struct input_dev descriptor of the device - * @duration: duration in ns of pulse/space + * @duration: the struct ir_raw_event descriptor of the pulse/space * * This function returns -EINVAL if the pulse violates the state machine */ -static int ir_nec_decode(struct input_dev *input_dev, s64 duration) +static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev) { struct decoder_data *data; struct ir_input_dev *ir_dev = input_get_drvdata(input_dev); - int u; u32 scancode; u8 address, not_address, command, not_command; @@ -138,59 +139,88 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration) if (!data->enabled) return 0; - if (IS_RESET(duration)) { + if (IS_RESET(ev)) { data->state = STATE_INACTIVE; return 0; } - u = TO_UNITS(duration, NEC_UNIT); - if (DURATION(u) == 0) - goto out; - - IR_dprintk(2, "NEC decode started at state %d (%i units, %ius)\n", - data->state, u, TO_US(duration)); + IR_dprintk(2, "NEC decode started at state %d (%uus %s)\n", + data->state, TO_US(ev.duration), TO_STR(ev.pulse)); switch (data->state) { case STATE_INACTIVE: - if (u == NEC_HEADER_PULSE || u == NECX_HEADER_PULSE) { - data->count = 0; - data->state = STATE_HEADER_SPACE; - } + if (!ev.pulse) + break; + + if (!eq_margin(ev.duration, NEC_HEADER_PULSE, NEC_UNIT / 2) && + !eq_margin(ev.duration, NECX_HEADER_PULSE, NEC_UNIT / 2)) + break; + + data->count = 0; + data->state = STATE_HEADER_SPACE; return 0; case STATE_HEADER_SPACE: - if (u == NEC_HEADER_SPACE) { + if (ev.pulse) + break; + + if (eq_margin(ev.duration, NEC_HEADER_SPACE, NEC_UNIT / 2)) { data->state = STATE_BIT_PULSE; return 0; - } else if (u == NEC_REPEAT_SPACE) { + } else if (eq_margin(ev.duration, NEC_REPEAT_SPACE, NEC_UNIT / 2)) { ir_repeat(input_dev); IR_dprintk(1, "Repeat last key\n"); data->state = STATE_TRAILER_PULSE; return 0; } + break; case STATE_BIT_PULSE: - if (u == NEC_BIT_PULSE) { - data->state = STATE_BIT_SPACE; - return 0; - } - break; + if (!ev.pulse) + break; + + if (!eq_margin(ev.duration, NEC_BIT_PULSE, NEC_UNIT / 2)) + break; + + data->state = STATE_BIT_SPACE; + return 0; case STATE_BIT_SPACE: - if (u != NEC_BIT_0_SPACE && u != NEC_BIT_1_SPACE) + if (ev.pulse) break; data->nec_bits <<= 1; - if (u == NEC_BIT_1_SPACE) + if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2)) data->nec_bits |= 1; + else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2)) + break; data->count++; - if (data->count != NEC_NBITS) { + if (data->count == NEC_NBITS) + data->state = STATE_TRAILER_PULSE; + else data->state = STATE_BIT_PULSE; - return 0; - } + + return 0; + + case STATE_TRAILER_PULSE: + if (!ev.pulse) + break; + + if (!eq_margin(ev.duration, NEC_TRAILER_PULSE, NEC_UNIT / 2)) + break; + + data->state = STATE_TRAILER_SPACE; + return 0; + + case STATE_TRAILER_SPACE: + if (ev.pulse) + break; + + if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2)) + break; address = bitrev8((data->nec_bits >> 24) & 0xff); not_address = bitrev8((data->nec_bits >> 16) & 0xff); @@ -210,34 +240,18 @@ static int ir_nec_decode(struct input_dev *input_dev, s64 duration) command; IR_dprintk(1, "NEC (Ext) scancode 0x%06x\n", scancode); } else { - /* normal NEC */ + /* Normal NEC */ scancode = address << 8 | command; IR_dprintk(1, "NEC scancode 0x%04x\n", scancode); } ir_keydown(input_dev, scancode, 0); - data->state = STATE_TRAILER_PULSE; + data->state = STATE_INACTIVE; return 0; - - case STATE_TRAILER_PULSE: - if (u > 0) { - data->state = STATE_TRAILER_SPACE; - return 0; - } - break; - - case STATE_TRAILER_SPACE: - if (u < 0) { - data->state = STATE_INACTIVE; - return 0; - } - - break; } -out: - IR_dprintk(1, "NEC decode failed at state %d (%i units, %ius)\n", - data->state, u, TO_US(duration)); + IR_dprintk(1, "NEC decode failed at state %d (%uus %s)\n", + data->state, TO_US(ev.duration), TO_STR(ev.pulse)); data->state = STATE_INACTIVE; return -EINVAL; }