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