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