diff options
Diffstat (limited to 'app-misc/lirc/files/lirc_wb677_mouse_kbd.c')
-rwxr-xr-x | app-misc/lirc/files/lirc_wb677_mouse_kbd.c | 881 |
1 files changed, 881 insertions, 0 deletions
diff --git a/app-misc/lirc/files/lirc_wb677_mouse_kbd.c b/app-misc/lirc/files/lirc_wb677_mouse_kbd.c new file mode 100755 index 0000000..bb1bef6 --- /dev/null +++ b/app-misc/lirc/files/lirc_wb677_mouse_kbd.c @@ -0,0 +1,881 @@ +/* Notice: + Do NOT merge this file with other file. + According to lirc group's suggestion, they hope that + we should put keyboard/mouse decoding into a separate file if we want to preserve it. +*/ + +#include <linux/input.h> +#include "lirc_wb677_common_extern.h" +#include "lirc_wb677_mouse_kbd.h" + + +void w83667hg_set_key(u8 *set_frame, u8 val, u8 *keycode, u8 *shiftmask) +{ +#ifdef ALLOW_DEBUG_DECODE + printk("%s set key: %d\n", DRVNAME, val); +#endif + + if (*set_frame <= KEY_SUBMIT_KEYCODE_FRAME_NUM + 1) { + *keycode <<= 1; + *keycode |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set key keycode:0x%x\n", DRVNAME, *keycode); + printk("set frame: %d\n", *set_frame); +#endif + } else { + *shiftmask <<= 1; + *shiftmask |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set key mask:0x%x\n", DRVNAME, *shiftmask); + printk("set frame: %d\n", *set_frame); +#endif + } + (*set_frame)++; +} + + +int w83667hg_jump_frame(struct irctl *ir, u8 frame_num, unsigned int *buf_num, u8 *out_bit, u8 *decode_status) +{ + unsigned int rlc = 0, cur_buf_num = *buf_num; + u8 bit = *out_bit, buf; + u8 cur_decode_status = *decode_status; + u8 cur_frame_num; + + cur_frame_num = 1; + for (; cur_frame_num <= frame_num; cur_buf_num++) { + buf = ir->buf[cur_buf_num]; + if (cur_buf_num > ir->buf_count) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: jump frame error\n", DRVNAME); + printk("current buf num: %d\n", cur_buf_num); + printk("current jumped frame: %d\n", cur_frame_num); + printk("current frame length: %d\n", rlc); + printk("total cir signal:\n"); + for (cur_buf_num = 0; cur_buf_num < ir->buf_count; cur_buf_num++) { + printk("0x%x ", ir->buf[cur_buf_num]); + if (cur_buf_num % 6 == 5) { + printk("\n"); + } + } +#endif + return -1; + } + if (bit == (buf & BIT_PULSE_MASK)) { + rlc += buf & BIT_LEN; + } else { + + /* decode*/ + switch (cur_decode_status) { + case ST_DECODE_NEW: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + cur_decode_status = ST_DECODE_ONE; + } else { + cur_decode_status = ST_DECODE_ZERO; + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + /* error occur, just ignore */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } + break; + case ST_DECODE_ZERO: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } else { + /* error */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + cur_decode_status = ST_DECODE_ONE; + cur_frame_num++; + } else { + /* error */ + cur_decode_status = ST_DECODE_ZERO; + cur_frame_num++; + } + } + break; + case ST_DECODE_ONE: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } else { + /* "10" => 1 */ + cur_decode_status = ST_DECODE_NEW; + cur_frame_num++; + } + } else if (rlc > TWO_PULSE_LEN_LOW) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + cur_decode_status = ST_DECODE_ONE; + cur_frame_num++; + } else { + /* "10" => 1 */ + cur_decode_status = ST_DECODE_ZERO; + cur_frame_num++; + } + } + break; + } /* switch*/ + + bit = buf & BIT_PULSE_MASK; + rlc = buf & BIT_LEN; + } + } /* for decode*/ + +/* + bit = ir->buf[cur_buf_num] & BIT_PULSE_MASK; + if (cur_decode_status & ST_DECODE_NEW) { + if (bit) { + *decode_status = ST_DECODE_ONE; + } else { + *decode_status = ST_DECODE_ZERO; + } + } else { + *decode_status = ST_DECODE_NEW; + } + *out_bit = bit; +*/ + + /* Fix problem 1 */ + if ((ir->buf[cur_buf_num] & BIT_LEN) > TWO_PULSE_LEN_LOW) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: fix problem 1 in jump_frame()\n", DRVNAME); +#endif +#ifdef ALLOW_DEBUG_DECODE + if (cur_frame_num > frame_num + 1) { + printk("%s error: jump_frame() get a too long frame\n", DRVNAME); + } +#endif + cur_buf_num--; + } + + /* copy from jump_iden */ + if (cur_decode_status & ST_DECODE_NEW) { +#ifdef ALLOW_DEBUG_DECODE + printk("hey man, it's NEW in jump_frame\n"); +printk("cur buf: 0x%x\n", ir->buf[cur_buf_num]); +printk("cur state: 0x%x\n", cur_decode_status); +#endif + *buf_num = --cur_buf_num; + /*//cur_buf_num--;*/ + *out_bit = ir->buf[cur_buf_num] & BIT_PULSE_MASK; + if (*out_bit) { + *decode_status = ST_DECODE_ONE; + } else { + *decode_status = ST_DECODE_ZERO; + } + } else { +#ifdef ALLOW_DEBUG_DECODE +printk("cur buf: 0x%x\n", ir->buf[cur_buf_num]); +printk("cur state: 0x%x\n", cur_decode_status); +#endif + *buf_num = cur_buf_num; + *out_bit = ir->buf[cur_buf_num] & BIT_PULSE_MASK; + *decode_status = ST_DECODE_NEW; +/* + if (*out_bit) { + *decode_status = ST_DECODE_ONE; + } else { + *decode_status = ST_DECODE_ZERO; + } +*/ + } + + return 0; +} + +int w83667hg_jump_head(struct irctl *ir, unsigned int *buf_num) +{ + unsigned int i, rlc = 0, max_buf_count = ir->buf_count; + u8 bit = BIT_PULSE_MASK, buf; + + for (i = 0; i < max_buf_count; i++) { + buf = ir->buf[i]; + if (bit == (buf & BIT_PULSE_MASK)) { + rlc += buf & BIT_LEN; + } else { + if ((rlc > HEAD_SYNC_LEN_LOW) && + (rlc < HEAD_SYNC_LEN_HIGH) && + (bit & BIT_PULSE_MASK)) { + break; + } + bit = buf & BIT_PULSE_MASK; + rlc = buf & BIT_LEN; + } + } /* for decode*/ + + if (i >= max_buf_count) { +/*//#ifdef ALLOW_DEBUG_DECODE*/ +#if 0 + printk("%s jump pulse error\n", DRVNAME); + printk("current buf num: %d\n", *buf_num); + printk("current jumped pulse: %d\n", i); + printk("current pulse length: %d\n", rlc); + printk("total cir signal:\n"); + for (i = 0; i < max_buf_count; i++) { + printk("0x%x ", ir->buf[i]); + if (i % 6 == 5) { + printk("\n"); + } + } +#endif + return -1; + } + + *buf_num = i; + + return 0; +} + + +int w83667hg_check_identification(u8 val, u8 identification, u8 *cur_iden) +{ + *cur_iden <<= 1; + *cur_iden |= val ; +#ifdef ALLOW_DEBUG_DECODE + printk("%s current check iden recv: %d\n", DRVNAME, val); + printk("%s current iden value: 0x%x\n", DRVNAME, *cur_iden); +#endif + + if (identification == (*cur_iden & IDENTIFICATION_CHECK_BIT)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s find identification\n\n", DRVNAME); +#endif + return 0; + } else { + return -1; + } +} + +int w83667hg_jump_identification(struct irctl *ir, u8 identification, unsigned int *buf_num, u8 *out_bit, u8 *decode_status) +{ + unsigned int rlc = 0, i = 1; + u8 bit = *out_bit, buf; + u8 cur_iden = 0; + u8 cur_decode_status = *decode_status; + + bit = BIT_PULSE_MASK; + cur_decode_status = ST_DECODE_NEW; + + for (; i < ir->buf_count; i++) { + buf = ir->buf[i]; +#ifdef ALLOW_DEBUG_DECODE +printk("buf: 0x%x\n", buf); +#endif + if (bit == (buf & BIT_PULSE_MASK)) { + rlc += buf & BIT_LEN; + } else { + /* decode*/ + switch (cur_decode_status) { + case ST_DECODE_NEW: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + cur_decode_status = ST_DECODE_ONE; + } else { + cur_decode_status = ST_DECODE_ZERO; + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + /* error occur, just ignore */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } + break; + case ST_DECODE_ZERO: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } else { + /* error */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + cur_decode_status = ST_DECODE_ONE; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } else { + /* error */ + cur_decode_status = ST_DECODE_ZERO; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } + } + break; + case ST_DECODE_ONE: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } else { + /* "10" => 1 */ + cur_decode_status = ST_DECODE_NEW; + if (!w83667hg_check_identification(1, identification, &cur_iden)) { + goto find_iden; + } + } + } else if (rlc > TWO_PULSE_LEN_LOW) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + cur_decode_status = ST_DECODE_ONE; + if (!w83667hg_check_identification(0, identification, &cur_iden)) { + goto find_iden; + } + } else { + /* "10" => 1 */ + cur_decode_status = ST_DECODE_ZERO; + if (!w83667hg_check_identification(1, identification, &cur_iden)) { + goto find_iden; + } + } + } + break; + } /* switch*/ + bit = buf & BIT_PULSE_MASK; + rlc = buf & BIT_LEN; + } + } + + if (i >= ir->buf_count) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s jump iden error\n", DRVNAME); + printk("current buf num: %d\n", i); + printk("current pulse length: %d\n", rlc); + printk("total cir signal:\n"); + for (i = 0; i < ir->buf_count; i++) { + printk("0x%x ", ir->buf[i]); + if (i % 6 == 5) { + printk("\n"); + } + } +#endif + return -1; + } + + find_iden: +#ifdef ALLOW_DEBUG_DECODE + printk("current buf num after iden: %d\n", i); + printk("current pulse length: %d\n", rlc); +#endif + /* try fix problem 1 */ + if ((rlc & BIT_LEN) >= TWO_PULSE_LEN_LOW) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s fix problem 1 in jump iden\n", DRVNAME); + printk("cur pulse len: %d\n", ir->buf[i] & BIT_LEN); +#endif + *buf_num = i + 1; + *out_bit = ir->buf[i] & BIT_PULSE_MASK; + if (*out_bit) { + *decode_status = ST_DECODE_ZERO; + } else { + *decode_status = ST_DECODE_ONE; + } + + return 0; + } + + /* now find identification successful! */ + { + *buf_num = i; + i--; + *out_bit = ir->buf[i] & BIT_PULSE_MASK; + if (bit) { + *decode_status = ST_DECODE_ONE; + } else { + *decode_status = ST_DECODE_ZERO; + } + } +#ifdef ALLOW_DEBUG_DECODE + printk("total cir signal:\n"); + for (i = 0; i < ir->buf_count; i++) { + printk("0x%x ", ir->buf[i]); + if (i % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif + + return 0; +} + +void w83667hg_submit_key(struct irctl *ir) +{ + unsigned int rlc = 0, buf_num = 0, i; + /* current usb keyboard key code setting, usb_kbd_keycode[keycode] */ + unsigned int input_code; + u8 bit, buf; + /* keycode and shiftmask parts in mce keyboard protocol*/ + u8 keycode = 0, shiftmask = 0; + u8 decode_status; + u8 frame_num, set_frame; + + /* 1) jump head */ + if (w83667hg_jump_head(ir, &buf_num)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode key jump head error\n", DRVNAME); +#endif + return; + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s buf_num after jump head: %d\n", DRVNAME, buf_num); +#endif + + /* 2) jump identification */ + if (w83667hg_jump_identification(ir, KEY_IDENTIFICATION, &buf_num, &bit, &decode_status)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode key jump identification error\n", DRVNAME); +#endif + return; + } + +#ifdef ALLOW_DEBUG_DECODE + printk("%s jump iden success\n\n", DRVNAME); + printk("%s buf_num after jump iden: %d\n", DRVNAME, buf_num); + printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); +#endif + + /* 3) jump "unknown", "C" and "CodeSet" parts in mce keyboard signal */ + if (w83667hg_jump_frame(ir, KEY_KEYCODE_FRAME_AFTER_I_START, &buf_num, &bit, &decode_status)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode key jump pulse error\n", DRVNAME); +#endif + return; + } + +#ifdef ALLOW_DEBUG_DECODE + printk("%s buf_num after jump pulse: %d\n", DRVNAME, buf_num); + printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); + frame_num = buf_num; + for (; frame_num < ir->buf_count; frame_num++) { + printk("0x%x\t", ir->buf[frame_num]); + if (frame_num % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode status before check key: %x\n", DRVNAME, decode_status); +#endif + + + /* 4) deocde "KeyCode" and "ShiftMask" parts in mce key signal */ + frame_num = 1, set_frame = 1; + for (; frame_num < KEY_FRAME_AFTER_JUMP + 2; buf_num++) { + if (bit != (ir->buf[buf_num] & BIT_PULSE_MASK)) { + /* decode*/ + if (rlc > PULSE_SILENT_LEN_LOW) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s error: cir signal end before received all key pulses\n", DRVNAME); + printk("bit: %d ", bit); + printk("rlc: %d\n", rlc); + printk("current pulse number: %d\n", frame_num); +#endif + if (decode_status == ST_DECODE_ONE) { + /* must set the last one */ + w83667hg_set_key(&set_frame, 1, &keycode, &shiftmask); + } + break; + } + switch (decode_status) { + case ST_DECODE_NEW: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + decode_status = ST_DECODE_ONE; + } else { + decode_status = ST_DECODE_ZERO; + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + /* error occur, just ignore */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + frame_num += 1; + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s cur state: %x\n", DRVNAME, decode_status); +#endif + break; + case ST_DECODE_ZERO: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + frame_num += 1; + } else { + /* error */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + decode_status = ST_DECODE_ONE; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + frame_num += 1; + } else { + /* error */ + decode_status = ST_DECODE_ZERO; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + } + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s cur state: %x\n", DRVNAME, decode_status); +#endif + break; + case ST_DECODE_ONE: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + } else { + /* "10" => 1 */ + decode_status = ST_DECODE_NEW; + w83667hg_set_key(&set_frame, 1, &keycode, &shiftmask); + frame_num += 1; + } + } else if (rlc > TWO_PULSE_LEN_LOW) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + decode_status = ST_DECODE_ONE; + w83667hg_set_key(&set_frame, 0, &keycode, &shiftmask); + } else { + /* "10" => 1 */ + decode_status = ST_DECODE_ZERO; + w83667hg_set_key(&set_frame, 1, &keycode, &shiftmask); + frame_num += 1; + } + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s cur state %x\n", DRVNAME, decode_status); +#endif + break; + } /* switch*/ + bit = ir->buf[buf_num] & BIT_PULSE_MASK; + rlc = ir->buf[buf_num] & BIT_LEN; +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode keyboard buf: 0x%x\n", DRVNAME, ir->buf[buf_num]); +#endif + + } else { + /* continue last pulse*/ + rlc += ir->buf[buf_num] & BIT_LEN; + } + + } /* for*/ + +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after decode keyboard:\n", DRVNAME); + printk("keycode: 0x%x ", keycode); + printk("shiftmask: 0x%x\n\n", shiftmask); +#endif + + /* 5) submit keycode to input */ + if (keycode != ir->pressed_keycode) { + if (ir->pressed_keycode) { + input_code = (unsigned int)usb_kbd_keycode[ir->pressed_keycode]; + input_report_key(ir->input_dev, input_code, 0); + } + ir->pressed_keycode = keycode; + if (keycode) { + input_code = (unsigned int)usb_kbd_keycode[keycode]; + input_report_key(ir->input_dev, input_code, 1); + } + } + + /* 6) submit shiftmask to input */ + + if (shiftmask != ir->pressed_shiftmask) { + for (i = 0; i < 7; i++) { + buf = 1<<i; + if ((buf & ir->pressed_shiftmask) && (!(buf & shiftmask))) { + input_code = (unsigned int)usb_kbd_keycode[0xE0 + i]; + input_report_key(ir->input_dev, input_code, 0); + } else if (!(buf & ir->pressed_shiftmask) && (buf & shiftmask)) { + input_code = (unsigned int)usb_kbd_keycode[0xE0 + i]; + input_report_key(ir->input_dev, input_code, 1); + } + } /* for*/ + ir->pressed_shiftmask = shiftmask; + } +} + +void w83667hg_set_mouse(u8 *set_frame, u8 val, u8 *deltay, u8 *deltax, u8 *clickrl) +{ +#ifdef ALLOW_DEBUG_DECODE + printk("%s set mouse val:%d\n", DRVNAME, val); +#endif + if (*set_frame <= MOUSE_SUBMIT_DELTAY_FRAME_NUM + 1) { + *deltay <<= 1; + *deltay |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set mouse delta y:0x%x\n", DRVNAME, *deltay); +#endif + } else if (*set_frame <= MOUSE_SUBMIT_DELTAX_FRAME_NUM) { + *deltax <<= 1; + *deltax |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set mouse delta x:0x%x\n", DRVNAME, *deltax); +#endif + } else if (*set_frame <= MOUSE_SUBMIT_L_FRAME_NUM) { + /* move right key, then set left key */ + *clickrl <<= 1; + *clickrl |= val; +#ifdef ALLOW_DEBUG_DECODE + printk("%s set mouse l:0x%x\n", DRVNAME, *clickrl); + printk("set pulse: %d\n", *set_frame); +#endif + } + (*set_frame)++; +} + +void w83667hg_submit_mouse(struct irctl *ir) +{ + unsigned int rlc = 0, buf_num = 0; + u8 bit; + /* deltax, deltay and clickrl parts in mce mouse protocol*/ + u8 deltax = 0, deltay = 0, clickrl = 0; + signed char x, y; + u8 decode_status; + u8 frame_num, set_frame; + + /* 1) jump head */ + if (w83667hg_jump_head(ir, &buf_num)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode mouse jump head error\n", DRVNAME); +#endif + return; + } + + /* 2) jump identification */ + if (w83667hg_jump_identification(ir, MOUSE_IDENTIFICATION, &buf_num, &bit, &decode_status)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode mouse jump identification error\n", DRVNAME); +#endif + return; + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after iden mouse:\n", DRVNAME); + printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); + frame_num = buf_num; + for (; frame_num < ir->buf_count; frame_num++) { + printk("0x%x ", ir->buf[frame_num]); + if (frame_num % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif + + /* 3) jump "unknown" part in mce mouse signal */ + if (w83667hg_jump_frame(ir, MOUSE_DELTAY_PULSE_AFTER_I_START, &buf_num, &bit, &decode_status)) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: decode mouse jump pulse error\n", DRVNAME); +#endif + return; + } +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after jump pulse buf num: %d\n", DRVNAME, buf_num); + printk("decode status: 0x%x, bit: 0x%x\n", decode_status, bit); + frame_num = buf_num; + for (; frame_num < ir->buf_count; frame_num++) { + printk("0x%x ", ir->buf[frame_num]); + if (frame_num % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif + + /* 4) deocde "deltay", "deltax", "r" and "l" parts in mce mouse signal */ + frame_num = 1, set_frame = 1; + for (; frame_num < MOUSE_CHECKSUM_FRAME_AFTER_JUMP + 1; buf_num++) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s: cur buf: 0x%x, pulse num: %d\n", DRVNAME, ir->buf[buf_num], frame_num); + printk("decode status: 0x%x\n", decode_status); +#endif + if (bit != (ir->buf[buf_num] & BIT_PULSE_MASK)) { + /* decode*/ + if (rlc > PULSE_SILENT_LEN_LOW) { +#ifdef ALLOW_DEBUG_DECODE + printk("%s error: cir signal end before received all mouse pulses\n", DRVNAME); + printk("bit: %d ", bit); + printk("rlc: %d\n", rlc); +#endif + break; + } + switch (decode_status) { + case ST_DECODE_NEW: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + decode_status = ST_DECODE_ONE; + } else { + decode_status = ST_DECODE_ZERO; + } + } else + if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + /* error occur, just ignore */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + frame_num += 1; + } + break; + case ST_DECODE_ZERO: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + frame_num += 1; + } else { + /* error */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + } + } else if ((rlc > TWO_PULSE_LEN_LOW) && + (rlc < TWO_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "01" => 0 */ + decode_status = ST_DECODE_ONE; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + frame_num += 1; + } else { + /* error */ + decode_status = ST_DECODE_ZERO; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + } + } + break; + case ST_DECODE_ONE: + if ((rlc > ONE_PULSE_LEN_LOW) && + (rlc < ONE_PULSE_LEN_HIGH)) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + } else { + /* "10" => 1 */ + decode_status = ST_DECODE_NEW; + w83667hg_set_mouse(&set_frame, 1, &deltay, &deltax, &clickrl); + frame_num += 1; + } + } else if (rlc > TWO_PULSE_LEN_LOW) { + if (bit & BIT_PULSE_MASK) { + /* "11" => error */ + decode_status = ST_DECODE_ONE; + w83667hg_set_mouse(&set_frame, 0, &deltay, &deltax, &clickrl); + frame_num += 1; + } else { + /* "10" => 1 */ + decode_status = ST_DECODE_ZERO; + w83667hg_set_mouse(&set_frame, 1, &deltay, &deltax, &clickrl); + frame_num += 1; + } + } + break; + } /* switch*/ + bit = ir->buf[buf_num] & BIT_PULSE_MASK; + rlc = ir->buf[buf_num] & BIT_LEN; + } else { + /* continue last pulse*/ + rlc += ir->buf[buf_num] & BIT_LEN; + } + + } /* for*/ + +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after decode mouse:\n", DRVNAME); + frame_num = buf_num; + for (; frame_num < ir->buf_count; frame_num++) { + printk("0x%x ", ir->buf[frame_num]); + if (frame_num % 7 == 6) { + printk("\n"); + } + } + printk("\n"); +#endif + + /* fix deltax lost problem */ + if (deltax) { + deltax <<= 1; + deltax |= 1; + } + +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after decode mouse:\n", DRVNAME); + printk("deltay: 0x%x ", deltay); + printk("deltax: 0x%x ", deltax); + printk("click rl: 0x%x \n\n", clickrl); +#endif + if (deltay & 0x40) { + y = -((~deltay & 0x7f) + 1); + } else { + y = deltay; + } + if (deltax & 0x40) { + x = -((~deltax & 0x7f) + 1); + } else { + x = deltax; + } + + /* 5) send to input */ + +#ifdef ALLOW_DEBUG_DECODE + printk("%s: after decode mouse and rebuild:\n", DRVNAME); + printk("y: %d ", y); + printk("x: %d ", x); + printk("click rl: 0x%x \n\n", clickrl); +#endif + + input_report_rel(ir->input_dev, REL_X, x); + input_report_rel(ir->input_dev, REL_Y, y); + + input_report_key(ir->input_dev, BTN_LEFT, clickrl & 1); + input_report_key(ir->input_dev, BTN_RIGHT, (clickrl >> 1) & 1); +} + + |