~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to drivers/staging/media/lirc/lirc_igorplugusb.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lirc_igorplugusb - USB remote support for LIRC
 
3
 *
 
4
 * Supports the standard homebrew IgorPlugUSB receiver with Igor's firmware.
 
5
 * See http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm
 
6
 *
 
7
 * The device can only record bursts of up to 36 pulses/spaces.
 
8
 * Works fine with RC5. Longer commands lead to device buffer overrun.
 
9
 * (Maybe a better firmware or a microcontroller with more ram can help?)
 
10
 *
 
11
 * Version 0.1  [beta status]
 
12
 *
 
13
 * Copyright (C) 2004 Jan M. Hochstein
 
14
 *      <hochstein@algo.informatik.tu-darmstadt.de>
 
15
 *
 
16
 * This driver was derived from:
 
17
 *   Paul Miller <pmiller9@users.sourceforge.net>
 
18
 *      "lirc_atiusb" module
 
19
 *   Vladimir Dergachev <volodya@minspring.com>'s 2002
 
20
 *      "USB ATI Remote support" (input device)
 
21
 *   Adrian Dewhurst <sailor-lk@sailorfrag.net>'s 2002
 
22
 *      "USB StreamZap remote driver" (LIRC)
 
23
 *   Artur Lipowski <alipowski@kki.net.pl>'s 2002
 
24
 *      "lirc_dev" and "lirc_gpio" LIRC modules
 
25
 */
 
26
 
 
27
/*
 
28
 * This program is free software; you can redistribute it and/or modify
 
29
 * it under the terms of the GNU General Public License as published by
 
30
 * the Free Software Foundation; either version 2 of the License, or
 
31
 * (at your option) any later version.
 
32
 *
 
33
 * This program is distributed in the hope that it will be useful,
 
34
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
35
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
36
 * GNU General Public License for more details.
 
37
 *
 
38
 * You should have received a copy of the GNU General Public License
 
39
 * along with this program; if not, write to the Free Software
 
40
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
41
 */
 
42
 
 
43
#include <linux/module.h>
 
44
#include <linux/kernel.h>
 
45
#include <linux/kmod.h>
 
46
#include <linux/sched.h>
 
47
#include <linux/errno.h>
 
48
#include <linux/fs.h>
 
49
#include <linux/usb.h>
 
50
#include <linux/time.h>
 
51
 
 
52
#include <media/lirc.h>
 
53
#include <media/lirc_dev.h>
 
54
 
 
55
 
 
56
/* module identification */
 
57
#define DRIVER_VERSION          "0.2"
 
58
#define DRIVER_AUTHOR           \
 
59
        "Jan M. Hochstein <hochstein@algo.informatik.tu-darmstadt.de>"
 
60
#define DRIVER_DESC             "Igorplug USB remote driver for LIRC"
 
61
#define DRIVER_NAME             "lirc_igorplugusb"
 
62
 
 
63
/* debugging support */
 
64
#ifdef CONFIG_USB_DEBUG
 
65
static int debug = 1;
 
66
#else
 
67
static int debug;
 
68
#endif
 
69
 
 
70
#define dprintk(fmt, args...)                                   \
 
71
        do {                                                    \
 
72
                if (debug)                                      \
 
73
                        printk(KERN_DEBUG fmt, ## args);        \
 
74
        } while (0)
 
75
 
 
76
/* One mode2 pulse/space has 4 bytes. */
 
77
#define CODE_LENGTH          sizeof(int)
 
78
 
 
79
/* Igor's firmware cannot record bursts longer than 36. */
 
80
#define DEVICE_BUFLEN      36
 
81
 
 
82
/*
 
83
 * Header at the beginning of the device's buffer:
 
84
 *      unsigned char data_length
 
85
 *      unsigned char data_start    (!=0 means ring-buffer overrun)
 
86
 *      unsigned char counter       (incremented by each burst)
 
87
 */
 
88
#define DEVICE_HEADERLEN        3
 
89
 
 
90
/* This is for the gap */
 
91
#define ADDITIONAL_LIRC_BYTES   2
 
92
 
 
93
/* times to poll per second */
 
94
#define SAMPLE_RATE          100
 
95
static int sample_rate = SAMPLE_RATE;
 
96
 
 
97
 
 
98
/**** Igor's USB Request Codes */
 
99
 
 
100
#define SET_INFRABUFFER_EMPTY   1
 
101
/**
 
102
 * Params: none
 
103
 * Answer: empty
 
104
 */
 
105
 
 
106
#define GET_INFRACODE      2
 
107
/**
 
108
 * Params:
 
109
 *   wValue: offset to begin reading infra buffer
 
110
 *
 
111
 * Answer: infra data
 
112
 */
 
113
 
 
114
#define SET_DATAPORT_DIRECTION  3
 
115
/**
 
116
 * Params:
 
117
 *   wValue: (byte) 1 bit for each data port pin (0=in, 1=out)
 
118
 *
 
119
 * Answer: empty
 
120
 */
 
121
 
 
122
#define GET_DATAPORT_DIRECTION  4
 
123
/**
 
124
 * Params: none
 
125
 *
 
126
 * Answer: (byte) 1 bit for each data port pin (0=in, 1=out)
 
127
 */
 
128
 
 
129
#define SET_OUT_DATAPORT        5
 
130
/**
 
131
 * Params:
 
132
 *   wValue: byte to write to output data port
 
133
 *
 
134
 * Answer: empty
 
135
 */
 
136
 
 
137
#define GET_OUT_DATAPORT        6
 
138
/**
 
139
 * Params: none
 
140
 *
 
141
 * Answer: least significant 3 bits read from output data port
 
142
 */
 
143
 
 
144
#define GET_IN_DATAPORT  7
 
145
/**
 
146
 * Params: none
 
147
 *
 
148
 * Answer: least significant 3 bits read from input data port
 
149
 */
 
150
 
 
151
#define READ_EEPROM          8
 
152
/**
 
153
 * Params:
 
154
 *   wValue: offset to begin reading EEPROM
 
155
 *
 
156
 * Answer: EEPROM bytes
 
157
 */
 
158
 
 
159
#define WRITE_EEPROM        9
 
160
/**
 
161
 * Params:
 
162
 *   wValue: offset to EEPROM byte
 
163
 *   wIndex: byte to write
 
164
 *
 
165
 * Answer: empty
 
166
 */
 
167
 
 
168
#define SEND_RS232            10
 
169
/**
 
170
 * Params:
 
171
 *   wValue: byte to send
 
172
 *
 
173
 * Answer: empty
 
174
 */
 
175
 
 
176
#define RECV_RS232            11
 
177
/**
 
178
 * Params: none
 
179
 *
 
180
 * Answer: byte received
 
181
 */
 
182
 
 
183
#define SET_RS232_BAUD    12
 
184
/**
 
185
 * Params:
 
186
 *   wValue: byte to write to UART bit rate register (UBRR)
 
187
 *
 
188
 * Answer: empty
 
189
 */
 
190
 
 
191
#define GET_RS232_BAUD    13
 
192
/**
 
193
 * Params: none
 
194
 *
 
195
 * Answer: byte read from UART bit rate register (UBRR)
 
196
 */
 
197
 
 
198
 
 
199
/* data structure for each usb remote */
 
200
struct igorplug {
 
201
 
 
202
        /* usb */
 
203
        struct usb_device *usbdev;
 
204
        int devnum;
 
205
 
 
206
        unsigned char *buf_in;
 
207
        unsigned int len_in;
 
208
        int in_space;
 
209
        struct timeval last_time;
 
210
 
 
211
        dma_addr_t dma_in;
 
212
 
 
213
        /* lirc */
 
214
        struct lirc_driver *d;
 
215
 
 
216
        /* handle sending (init strings) */
 
217
        int send_flags;
 
218
};
 
219
 
 
220
static int unregister_from_lirc(struct igorplug *ir)
 
221
{
 
222
        struct lirc_driver *d;
 
223
        int devnum;
 
224
 
 
225
        if (!ir) {
 
226
                printk(KERN_ERR "%s: called with NULL device struct!\n",
 
227
                       __func__);
 
228
                return -EINVAL;
 
229
        }
 
230
 
 
231
        devnum = ir->devnum;
 
232
        d = ir->d;
 
233
 
 
234
        if (!d) {
 
235
                printk(KERN_ERR "%s: called with NULL lirc driver struct!\n",
 
236
                       __func__);
 
237
                return -EINVAL;
 
238
        }
 
239
 
 
240
        dprintk(DRIVER_NAME "[%d]: calling lirc_unregister_driver\n", devnum);
 
241
        lirc_unregister_driver(d->minor);
 
242
 
 
243
        kfree(d);
 
244
        ir->d = NULL;
 
245
        kfree(ir);
 
246
 
 
247
        return devnum;
 
248
}
 
249
 
 
250
static int set_use_inc(void *data)
 
251
{
 
252
        struct igorplug *ir = data;
 
253
 
 
254
        if (!ir) {
 
255
                printk(DRIVER_NAME "[?]: set_use_inc called with no context\n");
 
256
                return -EIO;
 
257
        }
 
258
 
 
259
        dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum);
 
260
 
 
261
        if (!ir->usbdev)
 
262
                return -ENODEV;
 
263
 
 
264
        return 0;
 
265
}
 
266
 
 
267
static void set_use_dec(void *data)
 
268
{
 
269
        struct igorplug *ir = data;
 
270
 
 
271
        if (!ir) {
 
272
                printk(DRIVER_NAME "[?]: set_use_dec called with no context\n");
 
273
                return;
 
274
        }
 
275
 
 
276
        dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum);
 
277
}
 
278
 
 
279
static void send_fragment(struct igorplug *ir, struct lirc_buffer *buf,
 
280
                           int i, int max)
 
281
{
 
282
        int code;
 
283
 
 
284
        /* MODE2: pulse/space (PULSE_BIT) in 1us units */
 
285
        while (i < max) {
 
286
                /* 1 Igor-tick = 85.333333 us */
 
287
                code = (unsigned int)ir->buf_in[i] * 85 +
 
288
                        (unsigned int)ir->buf_in[i] / 3;
 
289
                ir->last_time.tv_usec += code;
 
290
                if (ir->in_space)
 
291
                        code |= PULSE_BIT;
 
292
                lirc_buffer_write(buf, (unsigned char *)&code);
 
293
                /* 1 chunk = CODE_LENGTH bytes */
 
294
                ir->in_space ^= 1;
 
295
                ++i;
 
296
        }
 
297
}
 
298
 
 
299
/**
 
300
 * Called in user context.
 
301
 * return 0 if data was added to the buffer and
 
302
 * -ENODATA if none was available. This should add some number of bits
 
303
 * evenly divisible by code_length to the buffer
 
304
 */
 
305
static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf)
 
306
{
 
307
        int ret;
 
308
        struct igorplug *ir = (struct igorplug *)data;
 
309
 
 
310
        if (!ir || !ir->usbdev)  /* Has the device been removed? */
 
311
                return -ENODEV;
 
312
 
 
313
        memset(ir->buf_in, 0, ir->len_in);
 
314
 
 
315
        ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
 
316
                              GET_INFRACODE, USB_TYPE_VENDOR | USB_DIR_IN,
 
317
                              0/* offset */, /*unused*/0,
 
318
                              ir->buf_in, ir->len_in,
 
319
                              /*timeout*/HZ * USB_CTRL_GET_TIMEOUT);
 
320
        if (ret > 0) {
 
321
                int code, timediff;
 
322
                struct timeval now;
 
323
 
 
324
                /* ACK packet has 1 byte --> ignore */
 
325
                if (ret < DEVICE_HEADERLEN)
 
326
                        return -ENODATA;
 
327
 
 
328
                dprintk(DRIVER_NAME ": Got %d bytes. Header: %02x %02x %02x\n",
 
329
                        ret, ir->buf_in[0], ir->buf_in[1], ir->buf_in[2]);
 
330
 
 
331
                do_gettimeofday(&now);
 
332
                timediff = now.tv_sec - ir->last_time.tv_sec;
 
333
                if (timediff + 1 > PULSE_MASK / 1000000)
 
334
                        timediff = PULSE_MASK;
 
335
                else {
 
336
                        timediff *= 1000000;
 
337
                        timediff += now.tv_usec - ir->last_time.tv_usec;
 
338
                }
 
339
                ir->last_time.tv_sec = now.tv_sec;
 
340
                ir->last_time.tv_usec = now.tv_usec;
 
341
 
 
342
                /* create leading gap  */
 
343
                code = timediff;
 
344
                lirc_buffer_write(buf, (unsigned char *)&code);
 
345
                ir->in_space = 1;   /* next comes a pulse */
 
346
 
 
347
                if (ir->buf_in[2] == 0)
 
348
                        send_fragment(ir, buf, DEVICE_HEADERLEN, ret);
 
349
                else {
 
350
                        printk(KERN_WARNING DRIVER_NAME
 
351
                               "[%d]: Device buffer overrun.\n", ir->devnum);
 
352
                        /* HHHNNNNNNNNNNNOOOOOOOO H = header
 
353
                              <---[2]--->         N = newer
 
354
                           <---------ret--------> O = older */
 
355
                        ir->buf_in[2] %= ret - DEVICE_HEADERLEN; /* sanitize */
 
356
                        /* keep even-ness to not desync pulse/pause */
 
357
                        send_fragment(ir, buf, DEVICE_HEADERLEN +
 
358
                                      ir->buf_in[2] - (ir->buf_in[2] & 1), ret);
 
359
                        send_fragment(ir, buf, DEVICE_HEADERLEN,
 
360
                                      DEVICE_HEADERLEN + ir->buf_in[2]);
 
361
                }
 
362
 
 
363
                ret = usb_control_msg(
 
364
                      ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
 
365
                      SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN,
 
366
                      /*unused*/0, /*unused*/0,
 
367
                      /*dummy*/ir->buf_in, /*dummy*/ir->len_in,
 
368
                      /*timeout*/HZ * USB_CTRL_GET_TIMEOUT);
 
369
                if (ret < 0)
 
370
                        printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: "
 
371
                               "error %d\n", ir->devnum, ret);
 
372
                return 0;
 
373
        } else if (ret < 0)
 
374
                printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n",
 
375
                        ir->devnum, ret);
 
376
 
 
377
        return -ENODATA;
 
378
}
 
379
 
 
380
 
 
381
 
 
382
static int igorplugusb_remote_probe(struct usb_interface *intf,
 
383
                                    const struct usb_device_id *id)
 
384
{
 
385
        struct usb_device *dev = NULL;
 
386
        struct usb_host_interface *idesc = NULL;
 
387
        struct usb_endpoint_descriptor *ep;
 
388
        struct igorplug *ir = NULL;
 
389
        struct lirc_driver *driver = NULL;
 
390
        int devnum, pipe, maxp;
 
391
        int minor = 0;
 
392
        char buf[63], name[128] = "";
 
393
        int mem_failure = 0;
 
394
        int ret;
 
395
 
 
396
        dprintk(DRIVER_NAME ": usb probe called.\n");
 
397
 
 
398
        dev = interface_to_usbdev(intf);
 
399
 
 
400
        idesc = intf->cur_altsetting;
 
401
 
 
402
        if (idesc->desc.bNumEndpoints != 1)
 
403
                return -ENODEV;
 
404
 
 
405
        ep = &idesc->endpoint->desc;
 
406
        if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
 
407
            != USB_DIR_IN)
 
408
            || (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
 
409
            != USB_ENDPOINT_XFER_CONTROL)
 
410
                return -ENODEV;
 
411
 
 
412
        pipe = usb_rcvctrlpipe(dev, ep->bEndpointAddress);
 
413
        devnum = dev->devnum;
 
414
        maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
 
415
 
 
416
        dprintk(DRIVER_NAME "[%d]: bytes_in_key=%zu maxp=%d\n",
 
417
                devnum, CODE_LENGTH, maxp);
 
418
 
 
419
        mem_failure = 0;
 
420
        ir = kzalloc(sizeof(struct igorplug), GFP_KERNEL);
 
421
        if (!ir) {
 
422
                mem_failure = 1;
 
423
                goto mem_failure_switch;
 
424
        }
 
425
        driver = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
 
426
        if (!driver) {
 
427
                mem_failure = 2;
 
428
                goto mem_failure_switch;
 
429
        }
 
430
 
 
431
        ir->buf_in = usb_alloc_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN,
 
432
                                        GFP_ATOMIC, &ir->dma_in);
 
433
        if (!ir->buf_in) {
 
434
                mem_failure = 3;
 
435
                goto mem_failure_switch;
 
436
        }
 
437
 
 
438
        strcpy(driver->name, DRIVER_NAME " ");
 
439
        driver->minor = -1;
 
440
        driver->code_length = CODE_LENGTH * 8; /* in bits */
 
441
        driver->features = LIRC_CAN_REC_MODE2;
 
442
        driver->data = ir;
 
443
        driver->chunk_size = CODE_LENGTH;
 
444
        driver->buffer_size = DEVICE_BUFLEN + ADDITIONAL_LIRC_BYTES;
 
445
        driver->set_use_inc = &set_use_inc;
 
446
        driver->set_use_dec = &set_use_dec;
 
447
        driver->sample_rate = sample_rate;    /* per second */
 
448
        driver->add_to_buf = &igorplugusb_remote_poll;
 
449
        driver->dev = &intf->dev;
 
450
        driver->owner = THIS_MODULE;
 
451
 
 
452
        minor = lirc_register_driver(driver);
 
453
        if (minor < 0)
 
454
                mem_failure = 9;
 
455
 
 
456
mem_failure_switch:
 
457
 
 
458
        switch (mem_failure) {
 
459
        case 9:
 
460
                usb_free_coherent(dev, DEVICE_BUFLEN + DEVICE_HEADERLEN,
 
461
                        ir->buf_in, ir->dma_in);
 
462
        case 3:
 
463
                kfree(driver);
 
464
        case 2:
 
465
                kfree(ir);
 
466
        case 1:
 
467
                printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n",
 
468
                        devnum, mem_failure);
 
469
                return -ENOMEM;
 
470
        }
 
471
 
 
472
        driver->minor = minor;
 
473
        ir->d = driver;
 
474
        ir->devnum = devnum;
 
475
        ir->usbdev = dev;
 
476
        ir->len_in = DEVICE_BUFLEN + DEVICE_HEADERLEN;
 
477
        ir->in_space = 1; /* First mode2 event is a space. */
 
478
        do_gettimeofday(&ir->last_time);
 
479
 
 
480
        if (dev->descriptor.iManufacturer
 
481
            && usb_string(dev, dev->descriptor.iManufacturer,
 
482
                          buf, sizeof(buf)) > 0)
 
483
                strlcpy(name, buf, sizeof(name));
 
484
        if (dev->descriptor.iProduct
 
485
            && usb_string(dev, dev->descriptor.iProduct, buf, sizeof(buf)) > 0)
 
486
                snprintf(name + strlen(name), sizeof(name) - strlen(name),
 
487
                         " %s", buf);
 
488
        printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name,
 
489
               dev->bus->busnum, devnum);
 
490
 
 
491
        /* clear device buffer */
 
492
        ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
 
493
                SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN,
 
494
                /*unused*/0, /*unused*/0,
 
495
                /*dummy*/ir->buf_in, /*dummy*/ir->len_in,
 
496
                /*timeout*/HZ * USB_CTRL_GET_TIMEOUT);
 
497
        if (ret < 0)
 
498
                printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n",
 
499
                        devnum, ret);
 
500
 
 
501
        usb_set_intfdata(intf, ir);
 
502
        return 0;
 
503
}
 
504
 
 
505
 
 
506
static void igorplugusb_remote_disconnect(struct usb_interface *intf)
 
507
{
 
508
        struct usb_device *usbdev = interface_to_usbdev(intf);
 
509
        struct igorplug *ir = usb_get_intfdata(intf);
 
510
        struct device *dev = &intf->dev;
 
511
        int devnum;
 
512
 
 
513
        usb_set_intfdata(intf, NULL);
 
514
 
 
515
        if (!ir || !ir->d)
 
516
                return;
 
517
 
 
518
        ir->usbdev = NULL;
 
519
 
 
520
        usb_free_coherent(usbdev, ir->len_in, ir->buf_in, ir->dma_in);
 
521
 
 
522
        devnum = unregister_from_lirc(ir);
 
523
 
 
524
        dev_info(dev, DRIVER_NAME "[%d]: %s done\n", devnum, __func__);
 
525
}
 
526
 
 
527
static struct usb_device_id igorplugusb_remote_id_table[] = {
 
528
        /* Igor Plug USB (Atmel's Manufact. ID) */
 
529
        { USB_DEVICE(0x03eb, 0x0002) },
 
530
        /* Fit PC2 Infrared Adapter */
 
531
        { USB_DEVICE(0x03eb, 0x21fe) },
 
532
 
 
533
        /* Terminating entry */
 
534
        { }
 
535
};
 
536
 
 
537
static struct usb_driver igorplugusb_remote_driver = {
 
538
        .name =         DRIVER_NAME,
 
539
        .probe =        igorplugusb_remote_probe,
 
540
        .disconnect =   igorplugusb_remote_disconnect,
 
541
        .id_table =     igorplugusb_remote_id_table
 
542
};
 
543
 
 
544
static int __init igorplugusb_remote_init(void)
 
545
{
 
546
        int ret = 0;
 
547
 
 
548
        dprintk(DRIVER_NAME ": loaded, debug mode enabled\n");
 
549
 
 
550
        ret = usb_register(&igorplugusb_remote_driver);
 
551
        if (ret)
 
552
                printk(KERN_ERR DRIVER_NAME ": usb register failed!\n");
 
553
 
 
554
        return ret;
 
555
}
 
556
 
 
557
static void __exit igorplugusb_remote_exit(void)
 
558
{
 
559
        usb_deregister(&igorplugusb_remote_driver);
 
560
}
 
561
 
 
562
module_init(igorplugusb_remote_init);
 
563
module_exit(igorplugusb_remote_exit);
 
564
 
 
565
#include <linux/vermagic.h>
 
566
MODULE_INFO(vermagic, VERMAGIC_STRING);
 
567
 
 
568
MODULE_DESCRIPTION(DRIVER_DESC);
 
569
MODULE_AUTHOR(DRIVER_AUTHOR);
 
570
MODULE_LICENSE("GPL");
 
571
MODULE_DEVICE_TABLE(usb, igorplugusb_remote_id_table);
 
572
 
 
573
module_param(sample_rate, int, S_IRUGO | S_IWUSR);
 
574
MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)");
 
575
 
 
576
module_param(debug, bool, S_IRUGO | S_IWUSR);
 
577
MODULE_PARM_DESC(debug, "Debug enabled or not");