img-ir-rc6.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * ImgTec IR Decoder setup for Philips RC-6 protocol.
  3. *
  4. * Copyright 2012-2014 Imagination Technologies Ltd.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2 of the License, or (at your
  9. * option) any later version.
  10. */
  11. #include "img-ir-hw.h"
  12. /* Convert RC6 data to a scancode */
  13. static int img_ir_rc6_scancode(int len, u64 raw, u64 enabled_protocols,
  14. struct img_ir_scancode_req *request)
  15. {
  16. unsigned int addr, cmd, mode, trl1, trl2;
  17. /*
  18. * Due to a side effect of the decoder handling the double length
  19. * Trailer bit, the header information is a bit scrambled, and the
  20. * raw data is shifted incorrectly.
  21. * This workaround effectively recovers the header bits.
  22. *
  23. * The Header field should look like this:
  24. *
  25. * StartBit ModeBit2 ModeBit1 ModeBit0 TrailerBit
  26. *
  27. * But what we get is:
  28. *
  29. * ModeBit2 ModeBit1 ModeBit0 TrailerBit1 TrailerBit2
  30. *
  31. * The start bit is not important to recover the scancode.
  32. */
  33. raw >>= 27;
  34. trl1 = (raw >> 17) & 0x01;
  35. trl2 = (raw >> 16) & 0x01;
  36. mode = (raw >> 18) & 0x07;
  37. addr = (raw >> 8) & 0xff;
  38. cmd = raw & 0xff;
  39. /*
  40. * Due to the above explained irregularity the trailer bits cannot
  41. * have the same value.
  42. */
  43. if (trl1 == trl2)
  44. return -EINVAL;
  45. /* Only mode 0 supported for now */
  46. if (mode)
  47. return -EINVAL;
  48. request->protocol = RC_PROTO_RC6_0;
  49. request->scancode = addr << 8 | cmd;
  50. request->toggle = trl2;
  51. return IMG_IR_SCANCODE;
  52. }
  53. /* Convert RC6 scancode to RC6 data filter */
  54. static int img_ir_rc6_filter(const struct rc_scancode_filter *in,
  55. struct img_ir_filter *out, u64 protocols)
  56. {
  57. /* Not supported by the hw. */
  58. return -EINVAL;
  59. }
  60. /*
  61. * RC-6 decoder
  62. * see http://www.sbprojects.com/knowledge/ir/rc6.php
  63. */
  64. struct img_ir_decoder img_ir_rc6 = {
  65. .type = RC_PROTO_BIT_RC6_0,
  66. .control = {
  67. .bitorien = 1,
  68. .code_type = IMG_IR_CODETYPE_BIPHASE,
  69. .decoden = 1,
  70. .decodinpol = 1,
  71. },
  72. /* main timings */
  73. .tolerance = 20,
  74. /*
  75. * Due to a quirk in the img-ir decoder, default header values do
  76. * not work, the values described below were extracted from
  77. * successful RTL test cases.
  78. */
  79. .timings = {
  80. /* leader symbol */
  81. .ldr = {
  82. .pulse = { 650 },
  83. .space = { 660 },
  84. },
  85. /* 0 symbol */
  86. .s00 = {
  87. .pulse = { 370 },
  88. .space = { 370 },
  89. },
  90. /* 01 symbol */
  91. .s01 = {
  92. .pulse = { 370 },
  93. .space = { 370 },
  94. },
  95. /* free time */
  96. .ft = {
  97. .minlen = 21,
  98. .maxlen = 21,
  99. .ft_min = 2666, /* 2.666 ms */
  100. },
  101. },
  102. /* scancode logic */
  103. .scancode = img_ir_rc6_scancode,
  104. .filter = img_ir_rc6_filter,
  105. };