~ubuntu-branches/ubuntu/vivid/linux-ti-omap/vivid

« back to all changes in this revision

Viewing changes to ubuntu/lirc/lirc_ttusbir/lirc_ttusbir.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader, Amit Kucheria
  • Date: 2010-03-23 18:05:12 UTC
  • Revision ID: james.westby@ubuntu.com-20100323180512-iavj906ocnphdubp
Tags: 2.6.33-500.3
[ Amit Kucheria ]

* [Config] Fix the debug package name to end in -dbgsym
* SAUCE: Add the ubuntu/ drivers to omap
* SAUCE: Re-export the symbols for aufs
* [Config] Enable AUFS and COMPCACHE

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lirc_ttusbir.c
 
3
 *
 
4
 * lirc_ttusbir - LIRC device driver for the TechnoTrend USB IR Receiver
 
5
 *
 
6
 * Copyright (C) 2007 Stefan Macher <st_maker-lirc@yahoo.de>
 
7
 *
 
8
 * This LIRC driver provides access to the TechnoTrend USB IR Receiver.
 
9
 * The receiver delivers the IR signal as raw sampled true/false data in
 
10
 * isochronous USB packets each of size 128 byte.
 
11
 * Currently the driver reduces the sampling rate by factor of 8 as this
 
12
 * is still more than enough to decode RC-5 - others should be analyzed.
 
13
 * But the driver does not rely on RC-5 it should be able to decode every
 
14
 * IR signal that is not too fast.
 
15
 */
 
16
 
 
17
/*
 
18
 *  This program is free software; you can redistribute it and/or modify
 
19
 *  it under the terms of the GNU General Public License as published by
 
20
 *  the Free Software Foundation; either version 2 of the License, or
 
21
 *  (at your option) any later version.
 
22
 *
 
23
 *  This program is distributed in the hope that it will be useful,
 
24
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
25
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
26
 *  GNU General Public License for more details.
 
27
 *
 
28
 *  You should have received a copy of the GNU General Public License
 
29
 *  along with this program; if not, write to the Free Software
 
30
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
31
 */
 
32
 
 
33
#include <linux/version.h>
 
34
#include <linux/kernel.h>
 
35
#include <linux/init.h>
 
36
#include <linux/module.h>
 
37
#include <linux/errno.h>
 
38
#include <linux/slab.h>
 
39
#include <linux/usb.h>
 
40
 
 
41
#include "../lirc.h"
 
42
#include "../kcompat.h"
 
43
#include "../lirc_dev/lirc_dev.h"
 
44
 
 
45
MODULE_DESCRIPTION("TechnoTrend USB IR device driver for LIRC");
 
46
MODULE_AUTHOR("Stefan Macher (st_maker-lirc@yahoo.de)");
 
47
MODULE_LICENSE("GPL");
 
48
 
 
49
/* #define DEBUG */
 
50
#ifdef DEBUG
 
51
#define DPRINTK printk
 
52
#else
 
53
#define DPRINTK(_x_, a...)
 
54
#endif
 
55
 
 
56
/* function declarations */
 
57
static int probe(struct usb_interface *intf, const struct usb_device_id *id);
 
58
static void disconnect(struct usb_interface *intf);
 
59
#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
 
60
static void urb_complete(struct urb *urb, struct pt_regs *pt_regs);
 
61
#else
 
62
static void urb_complete(struct urb *urb);
 
63
#endif
 
64
static int set_use_inc(void *data);
 
65
static void set_use_dec(void *data);
 
66
 
 
67
static int num_urbs = 2;
 
68
module_param(num_urbs, int, S_IRUGO);
 
69
MODULE_PARM_DESC(num_urbs,
 
70
                 "Number of URBs in queue. Try to increase to 4 in case "
 
71
                 "of problems (default: 2; minimum: 2)");
 
72
 
 
73
/* table of devices that work with this driver */
 
74
static struct usb_device_id device_id_table[] = {
 
75
        /* TechnoTrend USB IR Receiver */
 
76
        { USB_DEVICE(0x0B48, 0x2003) },
 
77
        /* Terminating entry */
 
78
        { }
 
79
};
 
80
MODULE_DEVICE_TABLE(usb, device_id_table);
 
81
 
 
82
/* USB driver definition */
 
83
static struct usb_driver usb_driver = {
 
84
        .name = "TTUSBIR",
 
85
        .id_table = &(device_id_table[0]),
 
86
        .probe = probe,
 
87
        .disconnect = disconnect,
 
88
};
 
89
 
 
90
/* USB device definition */
 
91
struct ttusbir_device {
 
92
        struct usb_driver *usb_driver;
 
93
        struct usb_device *udev;
 
94
        struct usb_interface *interf;
 
95
        struct usb_class_driver class_driver;
 
96
        unsigned int ifnum; /* Interface number to use */
 
97
        unsigned int alt_setting; /* alternate setting to use */
 
98
        unsigned int endpoint; /* Endpoint to use */
 
99
        struct urb **urb; /* num_urb URB pointers*/
 
100
        char **buffer; /* 128 byte buffer for each URB */
 
101
        struct lirc_buffer rbuf; /* Buffer towards LIRC */
 
102
        struct lirc_driver driver;
 
103
        int minor;
 
104
        int last_pulse; /* remembers if last received byte was pulse or space */
 
105
        int last_num; /* remembers how many last bytes appeared */
 
106
        int opened;
 
107
};
 
108
 
 
109
/*** LIRC specific functions ***/
 
110
static int set_use_inc(void *data)
 
111
{
 
112
        int i, retval;
 
113
        struct ttusbir_device *ttusbir = data;
 
114
 
 
115
        DPRINTK("Sending first URBs\n");
 
116
        /* @TODO Do I need to check if I am already opened */
 
117
        ttusbir->opened = 1;
 
118
 
 
119
        for (i = 0; i < num_urbs; i++) {
 
120
                retval = usb_submit_urb(ttusbir->urb[i], GFP_KERNEL);
 
121
                if (retval) {
 
122
                        err("%s: usb_submit_urb failed on urb %d",
 
123
                            __func__, i);
 
124
                        return retval;
 
125
                }
 
126
        }
 
127
        return 0;
 
128
}
 
129
 
 
130
static void set_use_dec(void *data)
 
131
{
 
132
        struct ttusbir_device *ttusbir = data;
 
133
 
 
134
        DPRINTK("Device closed\n");
 
135
 
 
136
        ttusbir->opened = 0;
 
137
}
 
138
 
 
139
/*** USB specific functions ***/
 
140
 
 
141
/*
 
142
 * This mapping table is used to do a very simple filtering of the
 
143
 * input signal.
 
144
 * For a value with at least 4 bits set it returns 0xFF otherwise
 
145
 * 0x00.  For faster IR signals this can not be used. But for RC-5 we
 
146
 * still have about 14 samples per pulse/space, i.e. we sample with 14
 
147
 * times higher frequency than the signal frequency
 
148
 */
 
149
const unsigned char map_table[] =
 
150
{
 
151
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
152
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
153
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
154
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
155
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
156
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
157
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
158
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
159
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
160
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
161
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
162
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
163
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
164
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
165
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
166
        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 
167
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
168
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
169
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
170
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
171
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
172
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
173
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
174
        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 
175
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 
176
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
177
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
178
        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 
179
        0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
 
180
        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 
181
        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 
182
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
 
183
};
 
184
 
 
185
#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
 
186
static void urb_complete(struct urb *urb, struct pt_regs *pt_regs)
 
187
#else
 
188
static void urb_complete(struct urb *urb)
 
189
#endif
 
190
{
 
191
        struct ttusbir_device *ttusbir;
 
192
        unsigned char *buf;
 
193
        int i;
 
194
        lirc_t l;
 
195
 
 
196
        ttusbir = urb->context;
 
197
 
 
198
        if (!ttusbir->opened)
 
199
                return;
 
200
 
 
201
        buf = (unsigned char *)urb->transfer_buffer;
 
202
 
 
203
        for (i = 0; i < 128; i++) {
 
204
                /* Here we do the filtering and some kind of down sampling */
 
205
                buf[i] = ~map_table[buf[i]];
 
206
                if (ttusbir->last_pulse == buf[i]) {
 
207
                        if (ttusbir->last_num < PULSE_MASK/63)
 
208
                                ttusbir->last_num++;
 
209
                /*
 
210
                 * else we are in a idle period and do not need to
 
211
                 * increment any longer
 
212
                 */
 
213
                } else {
 
214
                        l = ttusbir->last_num * 62; /* about 62 = us/byte */
 
215
                        if (ttusbir->last_pulse) /* pulse or space? */
 
216
                                l |= PULSE_BIT;
 
217
                        if (!lirc_buffer_full(&ttusbir->rbuf)) {
 
218
                                lirc_buffer_write(&ttusbir->rbuf, (void *)&l);
 
219
                                wake_up_interruptible(&ttusbir->rbuf.wait_poll);
 
220
                        }
 
221
                        ttusbir->last_num = 0;
 
222
                        ttusbir->last_pulse = buf[i];
 
223
                }
 
224
        }
 
225
        usb_submit_urb(urb, GFP_ATOMIC); /* keep data rolling :-) */
 
226
}
 
227
 
 
228
/*
 
229
 * Called whenever the USB subsystem thinks we could be the right driver
 
230
 * to handle this device
 
231
 */
 
232
static int probe(struct usb_interface *intf, const struct usb_device_id *id)
 
233
{
 
234
        int alt_set, endp;
 
235
        int found = 0;
 
236
        int i, j;
 
237
        int struct_size;
 
238
        struct usb_host_interface *host_interf;
 
239
        struct usb_interface_descriptor *interf_desc;
 
240
        struct usb_host_endpoint *host_endpoint;
 
241
        struct ttusbir_device *ttusbir;
 
242
 
 
243
        DPRINTK("Module ttusbir probe\n");
 
244
 
 
245
        /* To reduce memory fragmentation we use only one allocation */
 
246
        struct_size =  sizeof(struct ttusbir_device) +
 
247
                (sizeof(struct urb *) * num_urbs) +
 
248
                (sizeof(char *) * num_urbs) +
 
249
                (num_urbs * 128);
 
250
        ttusbir = kzalloc(struct_size, GFP_KERNEL);
 
251
        if (!ttusbir)
 
252
                return -ENOMEM;
 
253
 
 
254
        ttusbir->urb = (struct urb **)((char *)ttusbir +
 
255
                                      sizeof(struct ttusbir_device));
 
256
        ttusbir->buffer = (char **)((char *)ttusbir->urb +
 
257
                                   (sizeof(struct urb *) * num_urbs));
 
258
        for (i = 0; i < num_urbs; i++)
 
259
                ttusbir->buffer[i] = (char *)ttusbir->buffer +
 
260
                        (sizeof(char *)*num_urbs) + (i * 128);
 
261
 
 
262
        ttusbir->usb_driver = &usb_driver;
 
263
        ttusbir->alt_setting = -1;
 
264
        /* @TODO check if error can be returned */
 
265
        ttusbir->udev = usb_get_dev(interface_to_usbdev(intf));
 
266
        ttusbir->interf = intf;
 
267
        ttusbir->last_pulse = 0x00;
 
268
        ttusbir->last_num = 0;
 
269
 
 
270
        /*
 
271
         * Now look for interface setting we can handle
 
272
         * We are searching for the alt setting where end point
 
273
         * 0x82 has max packet size 16
 
274
         */
 
275
        for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) {
 
276
                host_interf = &intf->altsetting[alt_set];
 
277
                interf_desc = &host_interf->desc;
 
278
                for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) {
 
279
                        host_endpoint = &host_interf->endpoint[endp];
 
280
                        if ((host_endpoint->desc.bEndpointAddress == 0x82) &&
 
281
                            (host_endpoint->desc.wMaxPacketSize == 0x10)) {
 
282
                                ttusbir->alt_setting = alt_set;
 
283
                                ttusbir->endpoint = endp;
 
284
                                found = 1;
 
285
                                break;
 
286
                        }
 
287
                }
 
288
        }
 
289
        if (ttusbir->alt_setting != -1)
 
290
                DPRINTK("alt setting: %d\n", ttusbir->alt_setting);
 
291
        else {
 
292
                err("Could not find alternate setting\n");
 
293
                kfree(ttusbir);
 
294
                return -EINVAL;
 
295
        }
 
296
 
 
297
        /* OK lets setup this interface setting */
 
298
        usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting);
 
299
 
 
300
        /* Store device info in interface structure */
 
301
        usb_set_intfdata(intf, ttusbir);
 
302
 
 
303
        /* Register as a LIRC driver */
 
304
        if (lirc_buffer_init(&ttusbir->rbuf, sizeof(lirc_t), 256) < 0) {
 
305
                err("Could not get memory for LIRC data buffer\n");
 
306
                usb_set_intfdata(intf, NULL);
 
307
                kfree(ttusbir);
 
308
                return -ENOMEM;
 
309
        }
 
310
        strcpy(ttusbir->driver.name, "TTUSBIR");
 
311
        ttusbir->driver.minor = -1;
 
312
        ttusbir->driver.code_length = 1;
 
313
        ttusbir->driver.sample_rate = 0;
 
314
        ttusbir->driver.data = ttusbir;
 
315
        ttusbir->driver.add_to_buf = NULL;
 
316
#ifndef LIRC_REMOVE_DURING_EXPORT
 
317
        ttusbir->driver.get_queue = NULL;
 
318
#endif
 
319
        ttusbir->driver.rbuf = &ttusbir->rbuf;
 
320
        ttusbir->driver.set_use_inc = set_use_inc;
 
321
        ttusbir->driver.set_use_dec = set_use_dec;
 
322
        ttusbir->driver.fops = NULL;
 
323
        ttusbir->driver.dev = &intf->dev;
 
324
        ttusbir->driver.owner = THIS_MODULE;
 
325
        ttusbir->driver.features = LIRC_CAN_REC_MODE2;
 
326
        ttusbir->minor = lirc_register_driver(&ttusbir->driver);
 
327
        if (ttusbir->minor < 0) {
 
328
                err("Error registering as LIRC driver\n");
 
329
                usb_set_intfdata(intf, NULL);
 
330
                lirc_buffer_free(&ttusbir->rbuf);
 
331
                kfree(ttusbir);
 
332
                return -EIO;
 
333
        }
 
334
 
 
335
        /* Allocate and setup the URB that we will use to talk to the device */
 
336
        for (i = 0; i < num_urbs; i++) {
 
337
                ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL);
 
338
                if (!ttusbir->urb[i]) {
 
339
                        err("Could not allocate memory for the URB\n");
 
340
                        for (j = i - 1; j >= 0; j--)
 
341
                                kfree(ttusbir->urb[j]);
 
342
                        lirc_buffer_free(&ttusbir->rbuf);
 
343
                        lirc_unregister_driver(ttusbir->minor);
 
344
                        kfree(ttusbir);
 
345
                        usb_set_intfdata(intf, NULL);
 
346
                        return -ENOMEM;
 
347
                }
 
348
                ttusbir->urb[i]->dev = ttusbir->udev;
 
349
                ttusbir->urb[i]->context = ttusbir;
 
350
                ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev,
 
351
                                                        ttusbir->endpoint);
 
352
                ttusbir->urb[i]->interval = 1;
 
353
                ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP;
 
354
                ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0];
 
355
                ttusbir->urb[i]->complete = urb_complete;
 
356
                ttusbir->urb[i]->number_of_packets = 8;
 
357
                ttusbir->urb[i]->transfer_buffer_length = 128;
 
358
                for (j = 0; j < 8; j++) {
 
359
                        ttusbir->urb[i]->iso_frame_desc[j].offset = j*16;
 
360
                        ttusbir->urb[i]->iso_frame_desc[j].length = 16;
 
361
                }
 
362
        }
 
363
        return 0;
 
364
}
 
365
 
 
366
/**
 
367
 * Called when the driver is unloaded or the device is unplugged
 
368
 */
 
369
static void disconnect(struct usb_interface *intf)
 
370
{
 
371
        int i;
 
372
        struct ttusbir_device *ttusbir;
 
373
 
 
374
        DPRINTK("Module ttusbir disconnect\n");
 
375
 
 
376
        ttusbir = (struct ttusbir_device *) usb_get_intfdata(intf);
 
377
        usb_set_intfdata(intf, NULL);
 
378
        lirc_unregister_driver(ttusbir->minor);
 
379
        DPRINTK("unregistered\n");
 
380
 
 
381
        for (i = 0; i < num_urbs; i++) {
 
382
                usb_kill_urb(ttusbir->urb[i]);
 
383
                usb_free_urb(ttusbir->urb[i]);
 
384
        }
 
385
        DPRINTK("URBs killed\n");
 
386
        lirc_buffer_free(&ttusbir->rbuf);
 
387
        kfree(ttusbir);
 
388
}
 
389
 
 
390
static int ttusbir_init_module(void)
 
391
{
 
392
        int result;
 
393
 
 
394
        DPRINTK(KERN_DEBUG "Module ttusbir init\n");
 
395
 
 
396
        /* register this driver with the USB subsystem */
 
397
        result = usb_register(&usb_driver);
 
398
        if (result)
 
399
                err("usb_register failed. Error number %d", result);
 
400
        return result;
 
401
}
 
402
 
 
403
static void ttusbir_exit_module(void)
 
404
{
 
405
        printk(KERN_DEBUG "Module ttusbir exit\n");
 
406
        usb_deregister(&usb_driver);
 
407
}
 
408
 
 
409
module_init(ttusbir_init_module);
 
410
module_exit(ttusbir_exit_module);