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