Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / media / rc / img-ir / img-ir-sony.c
1 /*
2  * ImgTec IR Decoder setup for Sony (SIRC) 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 Sony data to a scancode */
15 static int img_ir_sony_scancode(int len, u64 raw, u64 enabled_protocols,
16                                 struct img_ir_scancode_req *request)
17 {
18         unsigned int dev, subdev, func;
19
20         switch (len) {
21         case 12:
22                 if (!(enabled_protocols & RC_BIT_SONY12))
23                         return -EINVAL;
24                 func   = raw & 0x7f;    /* first 7 bits */
25                 raw    >>= 7;
26                 dev    = raw & 0x1f;    /* next 5 bits */
27                 subdev = 0;
28                 request->protocol = RC_TYPE_SONY12;
29                 break;
30         case 15:
31                 if (!(enabled_protocols & RC_BIT_SONY15))
32                         return -EINVAL;
33                 func   = raw & 0x7f;    /* first 7 bits */
34                 raw    >>= 7;
35                 dev    = raw & 0xff;    /* next 8 bits */
36                 subdev = 0;
37                 request->protocol = RC_TYPE_SONY15;
38                 break;
39         case 20:
40                 if (!(enabled_protocols & RC_BIT_SONY20))
41                         return -EINVAL;
42                 func   = raw & 0x7f;    /* first 7 bits */
43                 raw    >>= 7;
44                 dev    = raw & 0x1f;    /* next 5 bits */
45                 raw    >>= 5;
46                 subdev = raw & 0xff;    /* next 8 bits */
47                 request->protocol = RC_TYPE_SONY20;
48                 break;
49         default:
50                 return -EINVAL;
51         }
52         request->scancode = dev << 16 | subdev << 8 | func;
53         return IMG_IR_SCANCODE;
54 }
55
56 /* Convert NEC scancode to NEC data filter */
57 static int img_ir_sony_filter(const struct rc_scancode_filter *in,
58                               struct img_ir_filter *out, u64 protocols)
59 {
60         unsigned int dev, subdev, func;
61         unsigned int dev_m, subdev_m, func_m;
62         unsigned int len = 0;
63
64         dev      = (in->data >> 16) & 0xff;
65         dev_m    = (in->mask >> 16) & 0xff;
66         subdev   = (in->data >> 8)  & 0xff;
67         subdev_m = (in->mask >> 8)  & 0xff;
68         func     = (in->data >> 0)  & 0x7f;
69         func_m   = (in->mask >> 0)  & 0x7f;
70
71         if (subdev & subdev_m) {
72                 /* can't encode subdev and higher device bits */
73                 if (dev & dev_m & 0xe0)
74                         return -EINVAL;
75                 /* subdevice (extended) bits only in 20 bit encoding */
76                 if (!(protocols & RC_BIT_SONY20))
77                         return -EINVAL;
78                 len = 20;
79                 dev_m &= 0x1f;
80         } else if (dev & dev_m & 0xe0) {
81                 /* upper device bits only in 15 bit encoding */
82                 if (!(protocols & RC_BIT_SONY15))
83                         return -EINVAL;
84                 len = 15;
85                 subdev_m = 0;
86         } else {
87                 /*
88                  * The hardware mask cannot distinguish high device bits and low
89                  * extended bits, so logically AND those bits of the masks
90                  * together.
91                  */
92                 subdev_m &= (dev_m >> 5) | 0xf8;
93                 dev_m &= 0x1f;
94         }
95
96         /* ensure there aren't any bits straying between fields */
97         dev &= dev_m;
98         subdev &= subdev_m;
99
100         /* write the hardware filter */
101         out->data = func          |
102                     dev      << 7 |
103                     subdev   << 15;
104         out->mask = func_m        |
105                     dev_m    << 7 |
106                     subdev_m << 15;
107
108         if (len) {
109                 out->minlen = len;
110                 out->maxlen = len;
111         }
112         return 0;
113 }
114
115 /*
116  * Sony SIRC decoder
117  * See also http://www.sbprojects.com/knowledge/ir/sirc.php
118  *          http://picprojects.org.uk/projects/sirc/sonysirc.pdf
119  */
120 struct img_ir_decoder img_ir_sony = {
121         .type = RC_BIT_SONY12 | RC_BIT_SONY15 | RC_BIT_SONY20,
122         .control = {
123                 .decoden = 1,
124                 .code_type = IMG_IR_CODETYPE_PULSELEN,
125         },
126         /* main timings */
127         .unit = 600000, /* 600 us */
128         .timings = {
129                 /* leader symbol */
130                 .ldr = {
131                         .pulse = { 4    /* 2.4 ms */ },
132                         .space = { 1    /* 600 us */ },
133                 },
134                 /* 0 symbol */
135                 .s00 = {
136                         .pulse = { 1    /* 600 us */ },
137                         .space = { 1    /* 600 us */ },
138                 },
139                 /* 1 symbol */
140                 .s01 = {
141                         .pulse = { 2    /* 1.2 ms */ },
142                         .space = { 1    /* 600 us */ },
143                 },
144                 /* free time */
145                 .ft = {
146                         .minlen = 12,
147                         .maxlen = 20,
148                         .ft_min = 10,   /* 6 ms */
149                 },
150         },
151         /* scancode logic */
152         .scancode = img_ir_sony_scancode,
153         .filter = img_ir_sony_filter,
154 };