Merge branch 'for-linus' of git://oss.sgi.com:8090/xfs/xfs-pull
[linux-2.6] / drivers / media / dvb / dvb-usb / af9005-remote.c
1 /* DVB USB compliant Linux driver for the Afatech 9005
2  * USB1.1 DVB-T receiver.
3  *
4  * Standard remote decode function
5  *
6  * Copyright (C) 2007 Luca Olivetti (luca@ventoso.org)
7  *
8  * Thanks to Afatech who kindly provided information.
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  * see Documentation/dvb/REDME.dvb-usb for more information
25  */
26 #include "af9005.h"
27 /* debug */
28 int dvb_usb_af9005_remote_debug;
29 module_param_named(debug, dvb_usb_af9005_remote_debug, int, 0644);
30 MODULE_PARM_DESC(debug,
31                  "enable (1) or disable (0) debug messages."
32                  DVB_USB_DEBUG_STATUS);
33
34 #define deb_decode(args...)   dprintk(dvb_usb_af9005_remote_debug,0x01,args)
35
36 struct dvb_usb_rc_key af9005_rc_keys[] = {
37
38         {0x01, 0xb7, KEY_POWER},
39         {0x01, 0xa7, KEY_VOLUMEUP},
40         {0x01, 0x87, KEY_CHANNELUP},
41         {0x01, 0x7f, KEY_MUTE},
42         {0x01, 0xbf, KEY_VOLUMEDOWN},
43         {0x01, 0x3f, KEY_CHANNELDOWN},
44         {0x01, 0xdf, KEY_1},
45         {0x01, 0x5f, KEY_2},
46         {0x01, 0x9f, KEY_3},
47         {0x01, 0x1f, KEY_4},
48         {0x01, 0xef, KEY_5},
49         {0x01, 0x6f, KEY_6},
50         {0x01, 0xaf, KEY_7},
51         {0x01, 0x27, KEY_8},
52         {0x01, 0x07, KEY_9},
53         {0x01, 0xcf, KEY_ZOOM},
54         {0x01, 0x4f, KEY_0},
55         {0x01, 0x8f, KEY_GOTO}, /* marked jump on the remote */
56
57         {0x00, 0xbd, KEY_POWER},
58         {0x00, 0x7d, KEY_VOLUMEUP},
59         {0x00, 0xfd, KEY_CHANNELUP},
60         {0x00, 0x9d, KEY_MUTE},
61         {0x00, 0x5d, KEY_VOLUMEDOWN},
62         {0x00, 0xdd, KEY_CHANNELDOWN},
63         {0x00, 0xad, KEY_1},
64         {0x00, 0x6d, KEY_2},
65         {0x00, 0xed, KEY_3},
66         {0x00, 0x8d, KEY_4},
67         {0x00, 0x4d, KEY_5},
68         {0x00, 0xcd, KEY_6},
69         {0x00, 0xb5, KEY_7},
70         {0x00, 0x75, KEY_8},
71         {0x00, 0xf5, KEY_9},
72         {0x00, 0x95, KEY_ZOOM},
73         {0x00, 0x55, KEY_0},
74         {0x00, 0xd5, KEY_GOTO}, /* marked jump on the remote */
75 };
76
77 int af9005_rc_keys_size = ARRAY_SIZE(af9005_rc_keys);
78
79 static int repeatable_keys[] = {
80         KEY_VOLUMEUP,
81         KEY_VOLUMEDOWN,
82         KEY_CHANNELUP,
83         KEY_CHANNELDOWN
84 };
85
86 int af9005_rc_decode(struct dvb_usb_device *d, u8 * data, int len, u32 * event,
87                      int *state)
88 {
89         u16 mark, space;
90         u32 result;
91         u8 cust, dat, invdat;
92         int i;
93
94         if (len >= 6) {
95                 mark = (u16) (data[0] << 8) + data[1];
96                 space = (u16) (data[2] << 8) + data[3];
97                 if (space * 3 < mark) {
98                         for (i = 0; i < ARRAY_SIZE(repeatable_keys); i++) {
99                                 if (d->last_event == repeatable_keys[i]) {
100                                         *state = REMOTE_KEY_REPEAT;
101                                         *event = d->last_event;
102                                         deb_decode("repeat key, event %x\n",
103                                                    *event);
104                                         return 0;
105                                 }
106                         }
107                         deb_decode("repeated key ignored (non repeatable)\n");
108                         return 0;
109                 } else if (len >= 33 * 4) {     /*32 bits + start code */
110                         result = 0;
111                         for (i = 4; i < 4 + 32 * 4; i += 4) {
112                                 result <<= 1;
113                                 mark = (u16) (data[i] << 8) + data[i + 1];
114                                 mark >>= 1;
115                                 space = (u16) (data[i + 2] << 8) + data[i + 3];
116                                 space >>= 1;
117                                 if (mark * 2 > space)
118                                         result += 1;
119                         }
120                         deb_decode("key pressed, raw value %x\n", result);
121                         if ((result & 0xff000000) != 0xfe000000) {
122                                 deb_decode
123                                     ("doesn't start with 0xfe, ignored\n");
124                                 return 0;
125                         }
126                         cust = (result >> 16) & 0xff;
127                         dat = (result >> 8) & 0xff;
128                         invdat = (~result) & 0xff;
129                         if (dat != invdat) {
130                                 deb_decode("code != inverted code\n");
131                                 return 0;
132                         }
133                         for (i = 0; i < af9005_rc_keys_size; i++) {
134                                 if (af9005_rc_keys[i].custom == cust
135                                     && af9005_rc_keys[i].data == dat) {
136                                         *event = af9005_rc_keys[i].event;
137                                         *state = REMOTE_KEY_PRESSED;
138                                         deb_decode
139                                             ("key pressed, event %x\n", *event);
140                                         return 0;
141                                 }
142                         }
143                         deb_decode("not found in table\n");
144                 }
145         }
146         return 0;
147 }
148
149 EXPORT_SYMBOL(af9005_rc_keys);
150 EXPORT_SYMBOL(af9005_rc_keys_size);
151 EXPORT_SYMBOL(af9005_rc_decode);
152
153 MODULE_AUTHOR("Luca Olivetti <luca@ventoso.org>");
154 MODULE_DESCRIPTION
155     ("Standard remote control decoder for Afatech 9005 DVB-T USB1.1 stick");
156 MODULE_VERSION("1.0");
157 MODULE_LICENSE("GPL");