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