0001
0002
0003
0004
0005
0006
0007
0008 #include "img-ir-hw.h"
0009 #include <linux/bitrev.h>
0010 #include <linux/log2.h>
0011
0012
0013 static int img_ir_nec_scancode(int len, u64 raw, u64 enabled_protocols,
0014 struct img_ir_scancode_req *request)
0015 {
0016 unsigned int addr, addr_inv, data, data_inv;
0017
0018 if (!len)
0019 return IMG_IR_REPEATCODE;
0020 if (len != 32)
0021 return -EINVAL;
0022
0023 addr = (raw >> 0) & 0xff;
0024 addr_inv = (raw >> 8) & 0xff;
0025 data = (raw >> 16) & 0xff;
0026 data_inv = (raw >> 24) & 0xff;
0027 if ((data_inv ^ data) != 0xff) {
0028
0029
0030 request->scancode = bitrev8(addr) << 24 |
0031 bitrev8(addr_inv) << 16 |
0032 bitrev8(data) << 8 |
0033 bitrev8(data_inv);
0034 request->protocol = RC_PROTO_NEC32;
0035 } else if ((addr_inv ^ addr) != 0xff) {
0036
0037
0038 request->scancode = addr << 16 |
0039 addr_inv << 8 |
0040 data;
0041 request->protocol = RC_PROTO_NECX;
0042 } else {
0043
0044
0045 request->scancode = addr << 8 |
0046 data;
0047 request->protocol = RC_PROTO_NEC;
0048 }
0049 return IMG_IR_SCANCODE;
0050 }
0051
0052
0053 static int img_ir_nec_filter(const struct rc_scancode_filter *in,
0054 struct img_ir_filter *out, u64 protocols)
0055 {
0056 unsigned int addr, addr_inv, data, data_inv;
0057 unsigned int addr_m, addr_inv_m, data_m, data_inv_m;
0058
0059 data = in->data & 0xff;
0060 data_m = in->mask & 0xff;
0061
0062 protocols &= RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32;
0063
0064
0065
0066
0067
0068
0069 if (!is_power_of_2(protocols)) {
0070 if ((in->data | in->mask) & 0xff000000)
0071 protocols = RC_PROTO_BIT_NEC32;
0072 else if ((in->data | in->mask) & 0x00ff0000)
0073 protocols = RC_PROTO_BIT_NECX;
0074 else
0075 protocols = RC_PROTO_BIT_NEC;
0076 }
0077
0078 if (protocols == RC_PROTO_BIT_NEC32) {
0079
0080
0081 addr = bitrev8(in->data >> 24);
0082 addr_m = bitrev8(in->mask >> 24);
0083 addr_inv = bitrev8(in->data >> 16);
0084 addr_inv_m = bitrev8(in->mask >> 16);
0085 data = bitrev8(in->data >> 8);
0086 data_m = bitrev8(in->mask >> 8);
0087 data_inv = bitrev8(in->data >> 0);
0088 data_inv_m = bitrev8(in->mask >> 0);
0089 } else if (protocols == RC_PROTO_BIT_NECX) {
0090
0091
0092 addr = (in->data >> 16) & 0xff;
0093 addr_m = (in->mask >> 16) & 0xff;
0094 addr_inv = (in->data >> 8) & 0xff;
0095 addr_inv_m = (in->mask >> 8) & 0xff;
0096 data_inv = data ^ 0xff;
0097 data_inv_m = data_m;
0098 } else {
0099
0100
0101 addr = (in->data >> 8) & 0xff;
0102 addr_m = (in->mask >> 8) & 0xff;
0103 addr_inv = addr ^ 0xff;
0104 addr_inv_m = addr_m;
0105 data_inv = data ^ 0xff;
0106 data_inv_m = data_m;
0107 }
0108
0109
0110 out->data = data_inv << 24 |
0111 data << 16 |
0112 addr_inv << 8 |
0113 addr;
0114 out->mask = data_inv_m << 24 |
0115 data_m << 16 |
0116 addr_inv_m << 8 |
0117 addr_m;
0118 return 0;
0119 }
0120
0121
0122
0123
0124
0125
0126 struct img_ir_decoder img_ir_nec = {
0127 .type = RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32,
0128 .control = {
0129 .decoden = 1,
0130 .code_type = IMG_IR_CODETYPE_PULSEDIST,
0131 },
0132
0133 .unit = 562500,
0134 .timings = {
0135
0136 .ldr = {
0137 .pulse = { 16 },
0138 .space = { 8 },
0139 },
0140
0141 .s00 = {
0142 .pulse = { 1 },
0143 .space = { 1 },
0144 },
0145
0146 .s01 = {
0147 .pulse = { 1 },
0148 .space = { 3 },
0149 },
0150
0151 .ft = {
0152 .minlen = 32,
0153 .maxlen = 32,
0154 .ft_min = 10,
0155 },
0156 },
0157
0158 .repeat = 108,
0159 .rtimings = {
0160
0161 .ldr = {
0162 .space = { 4 },
0163 },
0164
0165 .ft = {
0166 .minlen = 0,
0167 .maxlen = 0,
0168 },
0169 },
0170
0171 .scancode = img_ir_nec_scancode,
0172 .filter = img_ir_nec_filter,
0173 };