OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [usb/] [brlvger.c] - Blame information for rev 1780

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 *      Tieman Voyager braille display USB driver.
3
 *
4
 *      Copyright 2001-2002 Stephane Dalton <sdalton@videotron.ca>
5
 *                      and Stéphane Doyon  <s.doyon@videotron.ca>
6
 *            Maintained by Stéphane Doyon  <s.doyon@videotron.ca>.
7
 */
8
/*
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program; if not, write to the Free Software
21
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 */
23
/* History:
24
 * 0.8 April 2002: Integration into the kernel tree.
25
 * 0.7 October 2001: First public release as a module, distributed with
26
 *     the BRLTTY package (beta versions around 2.99y).
27
 */
28
 
29
#define DRIVER_VERSION "v0.8"
30
#define DATE "April 2002"
31
#define DRIVER_AUTHOR \
32
        "Stephane Dalton <sdalton@videotron.ca> " \
33
        "and Stéphane Doyon <s.doyon@videotron.ca>"
34
#define DRIVER_DESC "Tieman Voyager braille display USB driver for Linux 2.4"
35
#define DRIVER_SHORTDESC "Voyager"
36
 
37
#define BANNER \
38
        KERN_INFO DRIVER_SHORTDESC " " DRIVER_VERSION " (" DATE ")\n" \
39
        KERN_INFO "   by " DRIVER_AUTHOR "\n"
40
 
41
static const char longbanner[] = {
42
        DRIVER_DESC ", " DRIVER_VERSION " (" DATE "), by " DRIVER_AUTHOR
43
};
44
 
45
#include <linux/module.h>
46
#include <linux/usb.h>
47
#include <linux/init.h>
48
#include <linux/slab.h>
49
#include <linux/sched.h>
50
#include <asm/uaccess.h>
51
#include <asm/atomic.h>
52
#include <linux/poll.h>
53
#include <linux/devfs_fs_kernel.h>
54
#include <linux/brlvger.h>
55
 
56
MODULE_AUTHOR( DRIVER_AUTHOR );
57
MODULE_DESCRIPTION( DRIVER_DESC );
58
MODULE_LICENSE("GPL");
59
 
60
/* Module parameters */
61
 
62
static int debug = 1;
63
MODULE_PARM(debug, "i");
64
MODULE_PARM_DESC(debug, "Debug level, 0-3");
65
 
66
static int write_repeats = 2;
67
MODULE_PARM(write_repeats, "i");
68
MODULE_PARM_DESC(write_repeats, "Hack: repetitions for command to "
69
                 "display braille pattern");
70
                 /* to get rid of weird extra dots (perhaps only on
71
                    early hardware versions?) */
72
 
73
static int stall_tries = 3;
74
MODULE_PARM(stall_tries, "i");
75
MODULE_PARM_DESC(stall_tries, "Hack: retransmits of stalled USB "
76
                 "control messages");
77
                 /* broken early hardware versions? */
78
 
79
#define BRLVGER_RAW_VOLTAGE 89
80
/* from 0->300V to 255->200V, we are told 265V is normal operating voltage,
81
   but we don't know the scale. Assuming it is linear. */
82
static int raw_voltage = BRLVGER_RAW_VOLTAGE;
83
MODULE_PARM(raw_voltage, "i");
84
MODULE_PARM_DESC(raw_voltage, "Parameter for the call to SET_DISPLAY_VOLTAGE");
85
 
86
 
87
/* protocol and display type defines */
88
#define MAX_BRLVGER_CELLS 72
89
#define MAX_INTERRUPT_DATA 8
90
/* control message request types */
91
#define BRLVGER_READ_REQ 0xC2
92
#define BRLVGER_WRITE_REQ 0x42
93
/* control message request codes */
94
#define BRLVGER_SET_DISPLAY_ON 0
95
#define BRLVGER_SET_DISPLAY_VOLTAGE 1
96
#define BRLVGER_GET_SERIAL 3
97
#define BRLVGER_GET_HWVERSION 4
98
#define BRLVGER_GET_FWVERSION 5
99
#define BRLVGER_GET_LENGTH 6
100
#define BRLVGER_SEND_BRAILLE 7
101
#define BRLVGER_BEEP 9
102
#if 0 /* not used and not sure they're working */
103
#define BRLVGER_GET_DISPLAY_VOLTAGE 2
104
#define BRLVGER_GET_CURRENT 8
105
#endif
106
 
107
/* Prototypes */
108
static void *brlvger_probe (struct usb_device *dev, unsigned ifnum,
109
                            const struct usb_device_id *id);
110
static void brlvger_disconnect(struct usb_device *dev, void *ptr);
111
static int brlvger_open(struct inode *inode, struct file *file);
112
static int brlvger_release(struct inode *inode, struct file *file);
113
static ssize_t brlvger_write(struct file *file, const char *buffer,
114
                             size_t count, loff_t *pos);
115
static ssize_t brlvger_read(struct file *file, char *buffer,
116
                            size_t count, loff_t *unused_pos);
117
static int brlvger_ioctl(struct inode *inode, struct file *file,
118
                         unsigned cmd, unsigned long arg);
119
static unsigned brlvger_poll(struct file *file, poll_table *wait);
120
static loff_t brlvger_llseek(struct file * file, loff_t offset, int orig);
121
static void intr_callback(struct urb *urb);
122
struct brlvger_priv;
123
static int brlvger_get_hw_version(struct brlvger_priv *priv,
124
                                  unsigned char *verbuf);
125
static int brlvger_get_fw_version(struct brlvger_priv *priv,
126
                                  unsigned char *buf);
127
static int brlvger_get_serial(struct brlvger_priv *priv,
128
                              unsigned char *buf);
129
static int brlvger_get_display_length(struct brlvger_priv *priv);
130
static int brlvger_set_display_on_off(struct brlvger_priv *priv, __u16 on);
131
static int brlvger_beep(struct brlvger_priv *priv, __u16 duration);
132
static int brlvger_set_display_voltage(struct brlvger_priv *priv,
133
                                       __u16 voltage);
134
static int mycontrolmsg(const char *funcname,
135
                        struct brlvger_priv *priv, unsigned pipe_dir,
136
                        __u8 request, __u8 requesttype, __u16 value,
137
                        __u16 index, void *data, __u16 size);
138
 
139
#define controlmsg(priv,pipe_dir,a,b,c,d,e,f) \
140
     mycontrolmsg(__FUNCTION__, priv, pipe_dir, \
141
                  a,b,c,d,e,f)
142
#define sndcontrolmsg(priv,a,b,c,d,e,f) \
143
    controlmsg(priv, 0, a,b,c,d,e,f)
144
#define rcvcontrolmsg(priv,a,b,c,d,e,f) \
145
    controlmsg(priv, USB_DIR_IN, a,b,c,d,e,f)
146
 
147
extern devfs_handle_t usb_devfs_handle; /* /dev/usb dir. */
148
 
149
/* ----------------------------------------------------------------------- */
150
 
151
/* Data */
152
 
153
/* key event queue size */
154
#define MAX_INTERRUPT_BUFFER 10
155
 
156
/* private state */
157
struct brlvger_priv {
158
        struct usb_device   *dev; /* USB device handle */
159
        struct usb_endpoint_descriptor *in_interrupt;
160
        struct urb *intr_urb;
161
        devfs_handle_t devfs;
162
 
163
        int subminor; /* which minor dev #? */
164
 
165
        unsigned char hwver[BRLVGER_HWVER_SIZE]; /* hardware version */
166
        unsigned char fwver[BRLVGER_FWVER_SIZE]; /* firmware version */
167
        unsigned char serialnum[BRLVGER_SERIAL_SIZE];
168
 
169
        int llength; /* logical length */
170
        int plength; /* physical length */
171
 
172
        __u8 obuf[MAX_BRLVGER_CELLS];
173
        __u8 intr_buff[MAX_INTERRUPT_DATA];
174
        __u8 event_queue[MAX_INTERRUPT_BUFFER][MAX_INTERRUPT_DATA];
175
        atomic_t intr_idx, read_idx;
176
        spinlock_t intr_idx_lock; /* protects intr_idx */
177
        wait_queue_head_t read_wait;
178
 
179
        int opened;
180
        struct semaphore open_sem; /* protects ->opened */
181
        struct semaphore dev_sem; /* protects ->dev */
182
};
183
 
184
/* Globals */
185
 
186
/* Table of connected devices, a different minor for each. */
187
static struct brlvger_priv *display_table[ MAX_NR_BRLVGER_DEVS ];
188
 
189
/* Mutex for the operation of removing a device from display_table */
190
static DECLARE_MUTEX(disconnect_sem);
191
 
192
/* For blocking open */
193
static DECLARE_WAIT_QUEUE_HEAD(open_wait);
194
 
195
/* Some print macros */
196
#ifdef dbg
197
#undef dbg
198
#endif
199
#ifdef info
200
#undef info
201
#endif
202
#ifdef err
203
#undef err
204
#endif
205
#define info(args...) \
206
    ({ printk(KERN_INFO "Voyager: " args); \
207
       printk("\n"); })
208
#define err(args...) \
209
    ({ printk(KERN_ERR "Voyager: " args); \
210
       printk("\n"); })
211
#define dbgprint(fmt, args...) \
212
    ({ printk(KERN_DEBUG "Voyager: %s: " fmt, __FUNCTION__ , ##args); \
213
       printk("\n"); })
214
#define dbg(args...) \
215
    ({ if(debug >= 1) dbgprint(args); })
216
#define dbg2(args...) \
217
    ({ if(debug >= 2) dbgprint(args); })
218
#define dbg3(args...) \
219
    ({ if(debug >= 3) dbgprint(args); })
220
 
221
/* ----------------------------------------------------------------------- */
222
 
223
/* Driver registration */
224
 
225
static struct usb_device_id brlvger_ids [] = {
226
        { USB_DEVICE(0x0798, 0x0001) },
227
        { }                     /* Terminating entry */
228
};
229
MODULE_DEVICE_TABLE (usb, brlvger_ids);
230
 
231
static struct file_operations brlvger_fops =
232
{
233
        owner:          THIS_MODULE,
234
        llseek:         brlvger_llseek,
235
        read:           brlvger_read,
236
        write:          brlvger_write,
237
        ioctl:          brlvger_ioctl,
238
        open:           brlvger_open,
239
        release:        brlvger_release,
240
        poll:           brlvger_poll,
241
};
242
 
243
static struct usb_driver brlvger_driver =
244
{
245
        name:           "brlvger",
246
        probe:          brlvger_probe,
247
        disconnect:     brlvger_disconnect,
248
        fops:           &brlvger_fops,
249
        minor:          BRLVGER_MINOR,
250
        id_table:       brlvger_ids,
251
};
252
 
253
static int
254
__init brlvger_init (void)
255
{
256
        printk(BANNER);
257
 
258
        if(stall_tries < 1 || write_repeats < 1)
259
          return -EINVAL;
260
 
261
        memset(display_table, 0, sizeof(display_table));
262
 
263
        if (usb_register(&brlvger_driver)) {
264
                err("USB registration failed");
265
                return -ENOSYS;
266
        }
267
 
268
        return 0;
269
}
270
 
271
static void
272
__exit brlvger_cleanup (void)
273
{
274
        usb_deregister (&brlvger_driver);
275
        dbg("Driver unregistered");
276
}
277
 
278
module_init (brlvger_init);
279
module_exit (brlvger_cleanup);
280
 
281
/* ----------------------------------------------------------------------- */
282
 
283
/* Probe and disconnect functions */
284
 
285
static void *
286
brlvger_probe (struct usb_device *dev, unsigned ifnum,
287
               const struct usb_device_id *id)
288
{
289
        struct brlvger_priv *priv = NULL;
290
        int i;
291
        struct usb_endpoint_descriptor *endpoint;
292
        struct usb_interface_descriptor *actifsettings;
293
        /* protects against reentrance: once we've found a free slot
294
           we reserve it.*/
295
        static DECLARE_MUTEX(reserve_sem);
296
        char devfs_name[16];
297
 
298
        actifsettings = dev->actconfig->interface->altsetting;
299
 
300
        if( dev->descriptor.bNumConfigurations != 1
301
                        || dev->config->bNumInterfaces != 1
302
                        || actifsettings->bNumEndpoints != 1 ) {
303
                err ("Bogus braille display config info");
304
                return NULL;
305
        }
306
 
307
        endpoint = actifsettings->endpoint;
308
        if (!(endpoint->bEndpointAddress & 0x80) ||
309
                ((endpoint->bmAttributes & 3) != 0x03)) {
310
                err ("Bogus braille display config info, wrong endpoints");
311
                return NULL;
312
        }
313
 
314
        down(&reserve_sem);
315
 
316
        for( i = 0; i < MAX_NR_BRLVGER_DEVS; i++ )
317
                if( display_table[i] == NULL )
318
                        break;
319
 
320
        if( i == MAX_NR_BRLVGER_DEVS ) {
321
                err( "This driver cannot handle more than %d "
322
                                "braille displays", MAX_NR_BRLVGER_DEVS);
323
                goto error;
324
        }
325
 
326
        if( !(priv = kmalloc (sizeof *priv, GFP_KERNEL)) ){
327
                err("No more memory");
328
                goto error;
329
        }
330
 
331
        memset(priv, 0, sizeof(*priv));
332
        atomic_set(&priv->intr_idx, 0);
333
        atomic_set(&priv->read_idx, MAX_INTERRUPT_BUFFER-1);
334
        spin_lock_init(&priv->intr_idx_lock);
335
        init_waitqueue_head(&priv->read_wait);
336
        /* opened is memset'ed to 0 */
337
        init_MUTEX(&priv->open_sem);
338
        init_MUTEX(&priv->dev_sem);
339
 
340
        priv->subminor = i;
341
 
342
        /* we found a interrupt in endpoint */
343
        priv->in_interrupt = endpoint;
344
 
345
        priv->dev = dev;
346
 
347
        if(brlvger_get_hw_version(priv, priv->hwver) <0) {
348
                err("Unable to get hardware version");
349
                goto error;
350
        }
351
        dbg("Hw ver %d.%d", priv->hwver[0], priv->hwver[1]);
352
        if(brlvger_get_fw_version(priv, priv->fwver) <0) {
353
                err("Unable to get firmware version");
354
                goto error;
355
        }
356
        dbg("Fw ver: %s", priv->fwver);
357
 
358
        if(brlvger_get_serial(priv, priv->serialnum) <0) {
359
                err("Unable to get serial number");
360
                goto error;
361
        }
362
        dbg("Serial number: %s", priv->serialnum);
363
 
364
        if( (priv->llength = brlvger_get_display_length(priv)) <0 ){
365
                err("Unable to get display length");
366
                goto error;
367
        }
368
        switch(priv->llength) {
369
        case 48:
370
                priv->plength = 44;
371
                break;
372
        case 72:
373
                priv->plength = 70;
374
                break;
375
        default:
376
                err("Unsupported display length: %d", priv->llength);
377
                goto error;
378
        };
379
        dbg("Display length: %d", priv->plength);
380
 
381
        sprintf(devfs_name, "brlvger%d", priv->subminor);
382
        priv->devfs = devfs_register(usb_devfs_handle, devfs_name,
383
                                     DEVFS_FL_DEFAULT, USB_MAJOR,
384
                                     BRLVGER_MINOR+priv->subminor,
385
                                     S_IFCHR |S_IRUSR|S_IWUSR |S_IRGRP|S_IWGRP,
386
                                     &brlvger_fops, NULL);
387
        if (!priv->devfs) {
388
#ifdef CONFIG_DEVFS_FS
389
                err("devfs node registration failed");
390
#endif
391
        }
392
 
393
        display_table[i] = priv;
394
 
395
        info( "Braille display %d is device major %d minor %d",
396
                                i, USB_MAJOR, BRLVGER_MINOR + i);
397
 
398
        /* Tell anyone waiting on a blocking open */
399
        wake_up_interruptible(&open_wait);
400
 
401
        goto out;
402
 
403
 error:
404
        if(priv) {
405
                kfree( priv );
406
                priv = NULL;
407
        }
408
 
409
 out:
410
        up(&reserve_sem);
411
        return priv;
412
}
413
 
414
static void
415
brlvger_disconnect(struct usb_device *dev, void *ptr)
416
{
417
        struct brlvger_priv *priv = (struct brlvger_priv *)ptr;
418
        int r;
419
 
420
        if(priv){
421
                info("Display %d disconnecting", priv->subminor);
422
 
423
                devfs_unregister(priv->devfs);
424
 
425
                down(&disconnect_sem);
426
                display_table[priv->subminor] = NULL;
427
                up(&disconnect_sem);
428
 
429
                down(&priv->open_sem);
430
                down(&priv->dev_sem);
431
                if(priv->opened) {
432
                        /* Disable interrupts */
433
                        if((r = usb_unlink_urb(priv->intr_urb)) <0)
434
                                err("usb_unlink_urb returns %d", r);
435
                        usb_free_urb(priv->intr_urb);
436
                        /* mark device as dead and prevent control
437
                           messages to it */
438
                        priv->dev = NULL;
439
                        /* Tell anyone hung up on a read that it
440
                           won't be coming */
441
                        wake_up_interruptible(&priv->read_wait);
442
                        up(&priv->dev_sem);
443
                        up(&priv->open_sem);
444
                }else
445
                        /* no corresponding up()s */
446
                        kfree(priv);
447
        }
448
}
449
 
450
/* ----------------------------------------------------------------------- */
451
 
452
/* fops implementation */
453
 
454
static int
455
brlvger_open(struct inode *inode, struct file *file)
456
{
457
        int devnum = MINOR (inode->i_rdev);
458
        struct brlvger_priv *priv;
459
        int n, ret;
460
 
461
        if (devnum < BRLVGER_MINOR
462
            || devnum >= (BRLVGER_MINOR + MAX_NR_BRLVGER_DEVS))
463
                return -ENXIO;
464
 
465
        n = devnum - BRLVGER_MINOR;
466
 
467
        MOD_INC_USE_COUNT;
468
 
469
        do {
470
                down(&disconnect_sem);
471
                priv = display_table[n];
472
 
473
                if(!priv) {
474
                        up(&disconnect_sem);
475
                        if (file->f_flags & O_NONBLOCK) {
476
                                dbg3("Failing non-blocking open: "
477
                                     "device %d not connected", n);
478
                                MOD_DEC_USE_COUNT;
479
                                return -EAGAIN;
480
                        }
481
                        /* Blocking open. One global wait queue will
482
                           suffice. We wait until a device for the selected
483
                           minor is connected. */
484
                        dbg2("Waiting for device %d to be connected", n);
485
                        ret = wait_event_interruptible(open_wait,
486
                                                       display_table[n]
487
                                                       != NULL);
488
                        if(ret) {
489
                                dbg2("Interrupted wait for device %d", n);
490
                                MOD_DEC_USE_COUNT;
491
                                return ret;
492
                        }
493
                }
494
        } while(!priv);
495
        /* We grabbed an existing device. */
496
 
497
        if(down_interruptible(&priv->open_sem))
498
                return -ERESTARTSYS;
499
        up(&disconnect_sem);
500
 
501
        /* Only one process can open each device, no sharing. */
502
        ret = -EBUSY;
503
        if(priv->opened)
504
                goto error;
505
 
506
        dbg("Opening display %d", priv->subminor);
507
 
508
        /* Setup interrupt handler for receiving key input */
509
        priv->intr_urb = usb_alloc_urb(0);
510
        if(!priv->intr_urb) {
511
                err("Unable to allocate URB");
512
                goto error;
513
        }
514
        FILL_INT_URB( priv->intr_urb, priv->dev,
515
                        usb_rcvintpipe(priv->dev,
516
                                       priv->in_interrupt->bEndpointAddress),
517
                        priv->intr_buff, sizeof(priv->intr_buff),
518
                        intr_callback, priv, priv->in_interrupt->bInterval);
519
        if((ret = usb_submit_urb(priv->intr_urb)) <0){
520
                err("Error %d while submitting URB", ret);
521
                goto error;
522
        }
523
 
524
        /* Set voltage */
525
        if(brlvger_set_display_voltage(priv, raw_voltage) <0) {
526
                err("Unable to set voltage");
527
                goto error;
528
        }
529
 
530
        /* Turn display on */
531
        if((ret = brlvger_set_display_on_off(priv, 1)) <0) {
532
                err("Error %d while turning display on", ret);
533
                goto error;
534
        }
535
 
536
        /* Mark as opened, so disconnect cannot free priv. */
537
        priv->opened = 1;
538
 
539
        file->private_data = priv;
540
 
541
        ret = 0;
542
        goto out;
543
 
544
 error:
545
        MOD_DEC_USE_COUNT;
546
 out:
547
        up(&priv->open_sem);
548
        return ret;
549
}
550
 
551
static int
552
brlvger_release(struct inode *inode, struct file *file)
553
{
554
        struct brlvger_priv *priv = file->private_data;
555
        int r;
556
 
557
        /* Turn display off. Safe even if disconnected. */
558
        brlvger_set_display_on_off(priv, 0);
559
 
560
        /* mutex with disconnect and with open */
561
        down(&priv->open_sem);
562
 
563
        if(!priv->dev) {
564
                dbg("Releasing disconnected device %d", priv->subminor);
565
                /* no up(&priv->open_sem) */
566
                kfree(priv);
567
        }else{
568
                dbg("Closing display %d", priv->subminor);
569
                /* Disable interrupts */
570
                if((r = usb_unlink_urb(priv->intr_urb)) <0)
571
                        err("usb_unlink_urb returns %d", r);
572
                usb_free_urb(priv->intr_urb);
573
                priv->opened = 0;
574
                up(&priv->open_sem);
575
        }
576
 
577
        MOD_DEC_USE_COUNT;
578
 
579
        return 0;
580
}
581
 
582
static ssize_t
583
brlvger_write(struct file *file, const char *buffer,
584
              size_t count, loff_t *pos)
585
{
586
        struct brlvger_priv *priv = file->private_data;
587
        char buf[MAX_BRLVGER_CELLS];
588
        int ret;
589
        size_t rs;
590
        loff_t off;
591
 
592
        __u16 written;
593
 
594
        if(!priv->dev)
595
                return -ENOLINK;
596
 
597
        off = *pos;
598
 
599
        if(off > priv->plength)
600
                return -ESPIPE;;
601
 
602
        rs = priv->plength - off;
603
 
604
        if(count > rs)
605
                count = rs;
606
        written = count;
607
 
608
        if (copy_from_user (buf, buffer, count ) )
609
                return -EFAULT;
610
 
611
        memset(priv->obuf, 0xaa, sizeof(priv->obuf));
612
 
613
        /* Firmware supports multiples of 8cells, so some cells are absent
614
           and for some reason there actually are holes! euurkkk! */
615
 
616
        if( priv->plength == 44 ) {
617
                /* Two ghost cells at the beginning of the display, plus
618
                   two more after the sixth physical cell. */
619
                if(off > 5) {
620
                        off +=4;
621
                        memcpy(priv->obuf, buf, count);
622
                }else{
623
                        int firstpart = 6 - off;
624
 
625
#ifdef WRITE_DEBUG
626
                        dbg3("off: %lld, rs: %d, count: %d, firstpart: %d",
627
                             off, rs, count, firstpart);
628
#endif
629
 
630
                        firstpart = (firstpart < count) ? firstpart : count;
631
 
632
#ifdef WRITE_DEBUG
633
                        dbg3("off: %lld", off);
634
                        dbg3("firstpart: %d", firstpart);
635
#endif
636
 
637
                        memcpy(priv->obuf, buf, firstpart);
638
 
639
                        if(firstpart != count) {
640
                                int secondpart = count - firstpart;
641
#ifdef WRITE_DEBUG
642
                                dbg3("secondpart: %d", secondpart);
643
#endif
644
 
645
                                memcpy(priv->obuf+(firstpart+2),
646
                                       buf+firstpart, secondpart);
647
                                written +=2;
648
                        }
649
 
650
                        off +=2;
651
 
652
#ifdef WRITE_DEBUG
653
                        dbg3("off: %lld, rs: %d, count: %d, firstpart: %d, "
654
                                "written: %d",  off, rs, count, firstpart, written);
655
#endif
656
                }
657
        }else{
658
                /* Two ghost cells at the beginningg of the display. */
659
                memcpy(priv->obuf, buf, count);
660
                off += 2;
661
        }
662
 
663
        {
664
                int repeat = write_repeats;
665
                /* Dirty hack: sometimes some of the dots are wrong and somehow
666
                   right themselves if the command is repeated. */
667
                while(repeat--) {
668
                        ret = sndcontrolmsg(priv,
669
                                BRLVGER_SEND_BRAILLE, BRLVGER_WRITE_REQ, 0,
670
                                off, priv->obuf, written);
671
                        if(ret <0)
672
                                return ret;
673
                }
674
        }
675
 
676
        return count;
677
}
678
 
679
static int
680
read_index(struct brlvger_priv *priv)
681
{
682
        int intr_idx, read_idx;
683
 
684
        read_idx = atomic_read(&priv->read_idx);
685
        read_idx = ++read_idx == MAX_INTERRUPT_BUFFER ? 0 : read_idx;
686
 
687
        intr_idx = atomic_read(&priv->intr_idx);
688
 
689
        return(read_idx == intr_idx ? -1 : read_idx);
690
}
691
 
692
static ssize_t
693
brlvger_read(struct file *file, char *buffer,
694
             size_t count, loff_t *unused_pos)
695
{
696
        struct brlvger_priv *priv = file->private_data;
697
        int read_idx;
698
 
699
        if(count != MAX_INTERRUPT_DATA)
700
                return -EINVAL;
701
 
702
        if(!priv->dev)
703
                return -ENOLINK;
704
 
705
        if((read_idx = read_index(priv)) == -1) {
706
                /* queue empty */
707
                if (file->f_flags & O_NONBLOCK)
708
                        return -EAGAIN;
709
                else{
710
                        int r = wait_event_interruptible(priv->read_wait,
711
                                                         (!priv->dev || (read_idx = read_index(priv)) != -1));
712
                        if(!priv->dev)
713
                                return -ENOLINK;
714
                        if(r)
715
                                return r;
716
                        if(read_idx == -1)
717
                                /* should not happen */
718
                                return 0;
719
                }
720
        }
721
 
722
        if (copy_to_user (buffer, priv->event_queue[read_idx], count) )
723
                return( -EFAULT);
724
 
725
        atomic_set(&priv->read_idx, read_idx);
726
        /* Multiple opens are not allowed. Yet on SMP, two processes could
727
           read at the same time (on a shared file descriptor); then it is not
728
           deterministic whether or not they will get duplicates of a key
729
           event. */
730
        return MAX_INTERRUPT_DATA;
731
}
732
 
733
static int
734
brlvger_ioctl(struct inode *inode, struct file *file,
735
              unsigned cmd, unsigned long arg)
736
{
737
        struct brlvger_priv *priv = file->private_data;
738
 
739
        if(!priv->dev)
740
                return -ENOLINK;
741
 
742
        switch(cmd) {
743
        case BRLVGER_GET_INFO: {
744
                struct brlvger_info vi;
745
 
746
                strncpy(vi.driver_version, DRIVER_VERSION,
747
                        sizeof(vi.driver_version));
748
                vi.driver_version[sizeof(vi.driver_version)-1] = 0;
749
                strncpy(vi.driver_banner, longbanner,
750
                        sizeof(vi.driver_banner));
751
                vi.driver_banner[sizeof(vi.driver_banner)-1] = 0;
752
 
753
                vi.display_length = priv->plength;
754
 
755
                memcpy(&vi.hwver, priv->hwver, BRLVGER_HWVER_SIZE);
756
                memcpy(&vi.fwver, priv->fwver, BRLVGER_FWVER_SIZE);
757
                memcpy(&vi.serialnum, priv->serialnum, BRLVGER_SERIAL_SIZE);
758
 
759
                if(copy_to_user((void *)arg, &vi, sizeof(vi)))
760
                        return -EFAULT;
761
                return 0;
762
        }
763
        case BRLVGER_DISPLAY_ON:
764
                return brlvger_set_display_on_off(priv, 1);
765
        case BRLVGER_DISPLAY_OFF:
766
                return brlvger_set_display_on_off(priv, 0);
767
        case BRLVGER_BUZZ: {
768
                __u16 duration;
769
                if(get_user(duration, (__u16 *)arg))
770
                        return -EFAULT;
771
                return brlvger_beep(priv, duration);
772
        }
773
 
774
#if 0 /* Underlying commands don't seem to work for some reason; not clear if
775
         we'd want to export these anyway. */
776
        case BRLVGER_SET_VOLTAGE: {
777
                __u16 voltage;
778
                if(get_user(voltage, (__u16 *)arg))
779
                        return -EFAULT;
780
                return brlvger_set_display_voltage(priv, voltage);
781
        }
782
        case BRLVGER_GET_VOLTAGE: {
783
                __u8 voltage;
784
                int r = brlvger_get_display_voltage(priv);
785
                if(r <0)
786
                        return r;
787
                voltage = r;
788
                if(put_user(voltage, (__u8 *)arg))
789
                        return -EFAULT;
790
                return 0;
791
        }
792
#endif
793
        default:
794
                return -EINVAL;
795
        };
796
}
797
 
798
static loff_t
799
brlvger_llseek(struct file *file, loff_t offset, int orig)
800
{
801
        struct brlvger_priv *priv = file->private_data;
802
 
803
        if(!priv->dev)
804
                return -ENOLINK;
805
 
806
        switch (orig) {
807
                case 0:
808
                        /*  nothing to do */
809
                        break;
810
                case 1:
811
                        offset +=file->f_pos;
812
                        break;
813
                case 2:
814
                        offset += priv->plength;
815
                default:
816
                        return -EINVAL;
817
        }
818
 
819
        if((offset >= priv->plength) || (offset < 0))
820
                return -EINVAL;
821
 
822
        return (file->f_pos = offset);
823
}
824
 
825
static unsigned
826
brlvger_poll(struct file *file, poll_table *wait)
827
{
828
        struct brlvger_priv *priv = file->private_data;
829
 
830
        if(!priv->dev)
831
                return POLLERR | POLLHUP;
832
 
833
        poll_wait(file, &priv->read_wait, wait);
834
 
835
        if(!priv->dev)
836
                return POLLERR | POLLHUP;
837
        if(read_index(priv) != -1)
838
                return POLLIN | POLLRDNORM;
839
 
840
        return 0;
841
}
842
 
843
static void
844
intr_callback(struct urb *urb)
845
{
846
        struct brlvger_priv *priv = urb->context;
847
        int intr_idx, read_idx;
848
 
849
        if( urb->status ) {
850
                if(urb->status == -ETIMEDOUT)
851
                        dbg2("Status -ETIMEDOUT, "
852
                             "probably disconnected");
853
                else if(urb->status != -ENOENT)
854
                        err("Status: %d", urb->status);
855
                return;
856
        }
857
 
858
        read_idx = atomic_read(&priv->read_idx);
859
        spin_lock(&priv->intr_idx_lock);
860
        intr_idx = atomic_read(&priv->intr_idx);
861
        if(read_idx == intr_idx) {
862
                dbg2("Queue full, dropping braille display input");
863
                spin_unlock(&priv->intr_idx_lock);
864
                return; /* queue full */
865
        }
866
 
867
        memcpy(priv->event_queue[intr_idx], urb->transfer_buffer,
868
               MAX_INTERRUPT_DATA);
869
 
870
        intr_idx = (++intr_idx == MAX_INTERRUPT_BUFFER)? 0 : intr_idx;
871
        atomic_set(&priv->intr_idx, intr_idx);
872
        spin_unlock(&priv->intr_idx_lock);
873
 
874
        wake_up_interruptible(&priv->read_wait);
875
}
876
 
877
/* ----------------------------------------------------------------------- */
878
 
879
/* Hardware access functions */
880
 
881
static int
882
mycontrolmsg(const char *funcname,
883
             struct brlvger_priv *priv, unsigned pipe_dir,
884
             __u8 request, __u8 requesttype, __u16 value,
885
             __u16 index, void *data, __u16 size)
886
{
887
        int ret=0, tries = stall_tries;
888
 
889
        /* Make sure the device was not disconnected */
890
        if(down_interruptible(&priv->dev_sem))
891
                return -ERESTARTSYS;
892
        if(!priv->dev) {
893
                up(&priv->dev_sem);
894
                return -ENOLINK;
895
        }
896
 
897
        /* Dirty hack for retransmission: stalls and fails all the time
898
           without this on the hardware we tested. */
899
        while(tries--) {
900
                ret = usb_control_msg(priv->dev,
901
                    usb_sndctrlpipe(priv->dev,0) |pipe_dir,
902
                    request, requesttype, value,
903
                    index, data, size,
904
                    HZ);
905
                if(ret != -EPIPE)
906
                        break;
907
                dbg2("Stalled, remaining %d tries", tries);
908
        }
909
        up(&priv->dev_sem);
910
        if(ret <0) {
911
                err("%s: usb_control_msg returns %d",
912
                                funcname, ret);
913
                return -EIO;
914
        }
915
        return 0;
916
}
917
 
918
static int
919
brlvger_get_hw_version(struct brlvger_priv *priv, unsigned char *verbuf)
920
{
921
        return rcvcontrolmsg(priv,
922
            BRLVGER_GET_HWVERSION, BRLVGER_READ_REQ, 0,
923
            0, verbuf, BRLVGER_HWVER_SIZE);
924
        /* verbuf should be 2 bytes */
925
}
926
 
927
static int
928
brlvger_get_fw_version(struct brlvger_priv *priv, unsigned char *buf)
929
{
930
        unsigned char rawbuf[(BRLVGER_FWVER_SIZE-1)*2+2];
931
        int i, len;
932
        int r = rcvcontrolmsg(priv,
933
                              BRLVGER_GET_FWVERSION, BRLVGER_READ_REQ, 0,
934
                              0, rawbuf, sizeof(rawbuf));
935
        if(r<0)
936
                return r;
937
 
938
        /* If I guess correctly: succession of 16bit words, the string is
939
           formed of the first byte of each of these words. First byte in
940
           buffer indicates total length of data; not sure what second byte is
941
           for. */
942
        len = rawbuf[0]-2;
943
        if(len<0)
944
                len = 0;
945
        else if(len+1 > BRLVGER_FWVER_SIZE)
946
                len = BRLVGER_FWVER_SIZE-1;
947
        for(i=0; i<len; i++)
948
                buf[i] = rawbuf[2+2*i];
949
        buf[i] = 0;
950
        return 0;
951
}
952
 
953
static int
954
brlvger_get_serial(struct brlvger_priv *priv, unsigned char *buf)
955
{
956
        unsigned char rawserial[BRLVGER_SERIAL_BIN_SIZE];
957
        int i;
958
        int r = rcvcontrolmsg(priv,
959
                              BRLVGER_GET_SERIAL, BRLVGER_READ_REQ, 0,
960
                              0, rawserial, sizeof(rawserial));
961
        if(r<0)
962
                return r;
963
 
964
        for(i=0; i<BRLVGER_SERIAL_BIN_SIZE; i++) {
965
#define NUM_TO_HEX(n) (((n)>9) ? (n)+'A' : (n)+'0')
966
                buf[2*i] = NUM_TO_HEX(rawserial[i] >>4);
967
                buf[2*i+1] = NUM_TO_HEX(rawserial[i] &0xf);
968
        }
969
        buf[2*i] = 0;
970
        return 0;
971
}
972
 
973
static int
974
brlvger_get_display_length(struct brlvger_priv *priv)
975
{
976
        unsigned char data[2];
977
        int ret = rcvcontrolmsg(priv,
978
            BRLVGER_GET_LENGTH, BRLVGER_READ_REQ, 0,
979
            0, data, 2);
980
        if(ret<0)
981
                return ret;
982
        return data[1];
983
}
984
 
985
static int
986
brlvger_beep(struct brlvger_priv *priv, __u16 duration)
987
{
988
        return sndcontrolmsg(priv,
989
            BRLVGER_BEEP, BRLVGER_WRITE_REQ, duration,
990
            0, NULL, 0);
991
}
992
 
993
static int
994
brlvger_set_display_on_off(struct brlvger_priv *priv, __u16 on)
995
{
996
        dbg2("Turning display %s", ((on) ? "on" : "off"));
997
        return sndcontrolmsg(priv,
998
            BRLVGER_SET_DISPLAY_ON,     BRLVGER_WRITE_REQ, on,
999
            0, NULL, 0);
1000
}
1001
 
1002
static int
1003
brlvger_set_display_voltage(struct brlvger_priv *priv, __u16 voltage)
1004
{
1005
        dbg("SET_DISPLAY_VOLTAGE to %u", voltage);
1006
        return sndcontrolmsg(priv,
1007
             BRLVGER_SET_DISPLAY_VOLTAGE, BRLVGER_WRITE_REQ, voltage,
1008
             0, NULL, 0);
1009
}
1010
 
1011
#if 0 /* Had problems testing these commands. Not particularly useful anyway.*/
1012
 
1013
static int
1014
brlvger_get_display_voltage(struct brlvger_priv *priv)
1015
{
1016
        __u8 voltage = 0;
1017
        int ret = rcvcontrolmsg(priv,
1018
            BRLVGER_GET_DISPLAY_VOLTAGE, BRLVGER_READ_REQ, 0,
1019
            0, &voltage, 1);
1020
        if(ret<0)
1021
                return ret;
1022
        return voltage;
1023
}
1024
 
1025
static int
1026
brlvger_get_current(struct brlvger_priv *priv)
1027
{
1028
        unsigned char data;
1029
        int ret = rcvcontrolmsg(priv,
1030
            BRLVGER_GET_CURRENT,        BRLVGER_READ_REQ,       0,
1031
            0, &data, 1);
1032
        if(ret<0)
1033
                return ret;
1034
        return data;
1035
}
1036
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.