ir-nec-decoder.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* ir-raw-event.c - handle IR Pulse/Space event
  2. *
  3. * Copyright (C) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation version 2 of the License.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include <media/ir-core.h>
  15. /* Start time: 4.5 ms */
  16. #define MIN_START_TIME 3900000
  17. #define MAX_START_TIME 5100000
  18. /* Pulse time: 560 us */
  19. #define MIN_PULSE_TIME 460000
  20. #define MAX_PULSE_TIME 660000
  21. /* Bit 1 space time: 2.25ms-560 us */
  22. #define MIN_BIT1_TIME 1490000
  23. #define MAX_BIT1_TIME 1890000
  24. /* Bit 0 space time: 1.12ms-560 us */
  25. #define MIN_BIT0_TIME 360000
  26. #define MAX_BIT0_TIME 760000
  27. /**
  28. * __ir_nec_decode() - Decode one NEC pulsecode
  29. * @input_dev: the struct input_dev descriptor of the device
  30. * @evs: event array with type/duration of pulse/space
  31. * @len: length of the array
  32. * @pos: position to start seeking for a code
  33. * This function returns the decoded ircode or -EINVAL if no pulse got decoded
  34. */
  35. static int __ir_nec_decode(struct input_dev *input_dev,
  36. struct ir_raw_event *evs,
  37. int len, int *pos)
  38. {
  39. int count = -1;
  40. int ircode = 0, not_code = 0;
  41. /* Be sure that the first event is an start one and is a pulse */
  42. for (; *pos < len; (*pos)++) {
  43. if (evs[*pos].type & (IR_START_EVENT | IR_PULSE))
  44. break;
  45. }
  46. (*pos)++; /* First event doesn't contain data */
  47. if (*pos >= len)
  48. return 0;
  49. /* First space should have 4.5 ms otherwise is not NEC protocol */
  50. if ((evs[*pos].delta.tv_nsec < MIN_START_TIME) |
  51. (evs[*pos].delta.tv_nsec > MAX_START_TIME) |
  52. (evs[*pos].type != IR_SPACE))
  53. goto err;
  54. /*
  55. * FIXME: need to implement the repeat sequence
  56. */
  57. count = 0;
  58. for ((*pos)++; *pos < len; (*pos)++) {
  59. int bit;
  60. if ((evs[*pos].delta.tv_nsec < MIN_PULSE_TIME) |
  61. (evs[*pos].delta.tv_nsec > MAX_PULSE_TIME) |
  62. (evs[*pos].type != IR_PULSE))
  63. goto err;
  64. if (++*pos >= len)
  65. goto err;
  66. if (evs[*pos].type != IR_SPACE)
  67. goto err;
  68. if ((evs[*pos].delta.tv_nsec > MIN_BIT1_TIME) &&
  69. (evs[*pos].delta.tv_nsec < MAX_BIT1_TIME))
  70. bit = 1;
  71. else if ((evs[*pos].delta.tv_nsec > MIN_BIT0_TIME) &&
  72. (evs[*pos].delta.tv_nsec < MAX_BIT0_TIME))
  73. bit = 0;
  74. else
  75. goto err;
  76. if (bit) {
  77. int shift = count;
  78. /* Address first, then command */
  79. if (shift < 8) {
  80. shift += 8;
  81. ircode |= 1 << shift;
  82. } else if (shift < 16) {
  83. not_code |= 1 << shift;
  84. } else if (shift < 24) {
  85. shift -= 16;
  86. ircode |= 1 << shift;
  87. } else {
  88. shift -= 24;
  89. not_code |= 1 << shift;
  90. }
  91. }
  92. if (++count == 32)
  93. break;
  94. }
  95. /*
  96. * Fixme: may need to accept Extended NEC protocol?
  97. */
  98. if ((ircode & ~not_code) != ircode) {
  99. IR_dprintk(1, "NEC checksum error: code 0x%04x, not-code 0x%04x\n",
  100. ircode, not_code);
  101. return -EINVAL;
  102. }
  103. IR_dprintk(1, "NEC scancode 0x%04x\n", ircode);
  104. ir_keydown(input_dev, ircode);
  105. ir_keyup(input_dev);
  106. return ircode;
  107. err:
  108. IR_dprintk(1, "NEC decoded failed at bit %d while decoding %luus time\n",
  109. count, (evs[*pos].delta.tv_nsec + 500) / 1000);
  110. return -EINVAL;
  111. }
  112. /**
  113. * __ir_nec_decode() - Decodes all NEC pulsecodes on a given array
  114. * @input_dev: the struct input_dev descriptor of the device
  115. * @evs: event array with type/duration of pulse/space
  116. * @len: length of the array
  117. * This function returns the number of decoded pulses or -EINVAL if no
  118. * pulse got decoded
  119. */
  120. int ir_nec_decode(struct input_dev *input_dev,
  121. struct ir_raw_event *evs,
  122. int len)
  123. {
  124. int pos = 0;
  125. int rc = 0;
  126. while (pos < len) {
  127. if (__ir_nec_decode(input_dev, evs, len, &pos) >= 0)
  128. rc++;
  129. }
  130. if (!rc)
  131. return -EINVAL;
  132. return rc;
  133. }
  134. EXPORT_SYMBOL_GPL(ir_nec_decode);