Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / media / rc / img-ir / img-ir-sanyo.c
1 /*
2  * ImgTec IR Decoder setup for Sanyo 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  * From ir-sanyo-decoder.c:
12  *
13  * This protocol uses the NEC protocol timings. However, data is formatted as:
14  *      13 bits Custom Code
15  *      13 bits NOT(Custom Code)
16  *      8 bits Key data
17  *      8 bits NOT(Key data)
18  *
19  * According with LIRC, this protocol is used on Sanyo, Aiwa and Chinon
20  * Information for this protocol is available at the Sanyo LC7461 datasheet.
21  */
22
23 #include "img-ir-hw.h"
24
25 /* Convert Sanyo data to a scancode */
26 static int img_ir_sanyo_scancode(int len, u64 raw, u64 enabled_protocols,
27                                  struct img_ir_scancode_req *request)
28 {
29         unsigned int addr, addr_inv, data, data_inv;
30         /* a repeat code has no data */
31         if (!len)
32                 return IMG_IR_REPEATCODE;
33         if (len != 42)
34                 return -EINVAL;
35         addr     = (raw >>  0) & 0x1fff;
36         addr_inv = (raw >> 13) & 0x1fff;
37         data     = (raw >> 26) & 0xff;
38         data_inv = (raw >> 34) & 0xff;
39         /* Validate data */
40         if ((data_inv ^ data) != 0xff)
41                 return -EINVAL;
42         /* Validate address */
43         if ((addr_inv ^ addr) != 0x1fff)
44                 return -EINVAL;
45
46         /* Normal Sanyo */
47         request->protocol = RC_TYPE_SANYO;
48         request->scancode = addr << 8 | data;
49         return IMG_IR_SCANCODE;
50 }
51
52 /* Convert Sanyo scancode to Sanyo data filter */
53 static int img_ir_sanyo_filter(const struct rc_scancode_filter *in,
54                                struct img_ir_filter *out, u64 protocols)
55 {
56         unsigned int addr, addr_inv, data, data_inv;
57         unsigned int addr_m, data_m;
58
59         data = in->data & 0xff;
60         data_m = in->mask & 0xff;
61         data_inv = data ^ 0xff;
62
63         if (in->data & 0xff700000)
64                 return -EINVAL;
65
66         addr       = (in->data >> 8) & 0x1fff;
67         addr_m     = (in->mask >> 8) & 0x1fff;
68         addr_inv   = addr ^ 0x1fff;
69
70         out->data = (u64)data_inv << 34 |
71                     (u64)data     << 26 |
72                          addr_inv << 13 |
73                          addr;
74         out->mask = (u64)data_m << 34 |
75                     (u64)data_m << 26 |
76                          addr_m << 13 |
77                          addr_m;
78         return 0;
79 }
80
81 /* Sanyo decoder */
82 struct img_ir_decoder img_ir_sanyo = {
83         .type = RC_BIT_SANYO,
84         .control = {
85                 .decoden = 1,
86                 .code_type = IMG_IR_CODETYPE_PULSEDIST,
87         },
88         /* main timings */
89         .unit = 562500, /* 562.5 us */
90         .timings = {
91                 /* leader symbol */
92                 .ldr = {
93                         .pulse = { 16   /* 9ms */ },
94                         .space = { 8    /* 4.5ms */ },
95                 },
96                 /* 0 symbol */
97                 .s00 = {
98                         .pulse = { 1    /* 562.5 us */ },
99                         .space = { 1    /* 562.5 us */ },
100                 },
101                 /* 1 symbol */
102                 .s01 = {
103                         .pulse = { 1    /* 562.5 us */ },
104                         .space = { 3    /* 1687.5 us */ },
105                 },
106                 /* free time */
107                 .ft = {
108                         .minlen = 42,
109                         .maxlen = 42,
110                         .ft_min = 10,   /* 5.625 ms */
111                 },
112         },
113         /* repeat codes */
114         .repeat = 108,                  /* 108 ms */
115         .rtimings = {
116                 /* leader symbol */
117                 .ldr = {
118                         .space = { 4    /* 2.25 ms */ },
119                 },
120                 /* free time */
121                 .ft = {
122                         .minlen = 0,    /* repeat code has no data */
123                         .maxlen = 0,
124                 },
125         },
126         /* scancode logic */
127         .scancode = img_ir_sanyo_scancode,
128         .filter = img_ir_sanyo_filter,
129 };