summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app-misc/lirc/files/lirc_wb677_mouse_kbd.c')
-rwxr-xr-xapp-misc/lirc/files/lirc_wb677_mouse_kbd.c881
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);
+}
+
+