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

« back to all changes in this revision

Viewing changes to sound/oss/uart401.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
 * sound/oss/uart401.c
 
3
 *
 
4
 * MPU-401 UART driver (formerly uart401_midi.c)
 
5
 *
 
6
 *
 
7
 * Copyright (C) by Hannu Savolainen 1993-1997
 
8
 *
 
9
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
 
10
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
 
11
 * for more info.
 
12
 *
 
13
 * Changes:
 
14
 *      Alan Cox                Reformatted, removed sound_mem usage, use normal Linux
 
15
 *                              interrupt allocation. Protect against bogus unload
 
16
 *                              Fixed to allow IRQ > 15
 
17
 *      Christoph Hellwig       Adapted to module_init/module_exit
 
18
 *      Arnaldo C. de Melo      got rid of check_region
 
19
 *
 
20
 * Status:
 
21
 *              Untested
 
22
 */
 
23
 
 
24
#include <linux/init.h>
 
25
#include <linux/interrupt.h>
 
26
#include <linux/module.h>
 
27
#include <linux/slab.h>
 
28
#include <linux/spinlock.h>
 
29
#include "sound_config.h"
 
30
 
 
31
#include "mpu401.h"
 
32
 
 
33
typedef struct uart401_devc
 
34
{
 
35
        int             base;
 
36
        int             irq;
 
37
        int            *osp;
 
38
        void            (*midi_input_intr) (int dev, unsigned char data);
 
39
        int             opened, disabled;
 
40
        volatile unsigned char input_byte;
 
41
        int             my_dev;
 
42
        int             share_irq;
 
43
        spinlock_t      lock;
 
44
}
 
45
uart401_devc;
 
46
 
 
47
#define DATAPORT   (devc->base)
 
48
#define COMDPORT   (devc->base+1)
 
49
#define STATPORT   (devc->base+1)
 
50
 
 
51
static int uart401_status(uart401_devc * devc)
 
52
{
 
53
        return inb(STATPORT);
 
54
}
 
55
 
 
56
#define input_avail(devc) (!(uart401_status(devc)&INPUT_AVAIL))
 
57
#define output_ready(devc)      (!(uart401_status(devc)&OUTPUT_READY))
 
58
 
 
59
static void uart401_cmd(uart401_devc * devc, unsigned char cmd)
 
60
{
 
61
        outb((cmd), COMDPORT);
 
62
}
 
63
 
 
64
static int uart401_read(uart401_devc * devc)
 
65
{
 
66
        return inb(DATAPORT);
 
67
}
 
68
 
 
69
static void uart401_write(uart401_devc * devc, unsigned char byte)
 
70
{
 
71
        outb((byte), DATAPORT);
 
72
}
 
73
 
 
74
#define OUTPUT_READY    0x40
 
75
#define INPUT_AVAIL     0x80
 
76
#define MPU_ACK         0xFE
 
77
#define MPU_RESET       0xFF
 
78
#define UART_MODE_ON    0x3F
 
79
 
 
80
static int      reset_uart401(uart401_devc * devc);
 
81
static void     enter_uart_mode(uart401_devc * devc);
 
82
 
 
83
static void uart401_input_loop(uart401_devc * devc)
 
84
{
 
85
        int work_limit=30000;
 
86
        
 
87
        while (input_avail(devc) && --work_limit)
 
88
        {
 
89
                unsigned char   c = uart401_read(devc);
 
90
 
 
91
                if (c == MPU_ACK)
 
92
                        devc->input_byte = c;
 
93
                else if (devc->opened & OPEN_READ && devc->midi_input_intr)
 
94
                        devc->midi_input_intr(devc->my_dev, c);
 
95
        }
 
96
        if(work_limit==0)
 
97
                printk(KERN_WARNING "Too much work in interrupt on uart401 (0x%X). UART jabbering ??\n", devc->base);
 
98
}
 
99
 
 
100
irqreturn_t uart401intr(int irq, void *dev_id)
 
101
{
 
102
        uart401_devc *devc = dev_id;
 
103
 
 
104
        if (devc == NULL)
 
105
        {
 
106
                printk(KERN_ERR "uart401: bad devc\n");
 
107
                return IRQ_NONE;
 
108
        }
 
109
 
 
110
        if (input_avail(devc))
 
111
                uart401_input_loop(devc);
 
112
        return IRQ_HANDLED;
 
113
}
 
114
 
 
115
static int
 
116
uart401_open(int dev, int mode,
 
117
             void            (*input) (int dev, unsigned char data),
 
118
             void            (*output) (int dev)
 
119
)
 
120
{
 
121
        uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
 
122
 
 
123
        if (devc->opened)
 
124
                return -EBUSY;
 
125
 
 
126
        /* Flush the UART */
 
127
        
 
128
        while (input_avail(devc))
 
129
                uart401_read(devc);
 
130
 
 
131
        devc->midi_input_intr = input;
 
132
        devc->opened = mode;
 
133
        enter_uart_mode(devc);
 
134
        devc->disabled = 0;
 
135
 
 
136
        return 0;
 
137
}
 
138
 
 
139
static void uart401_close(int dev)
 
140
{
 
141
        uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
 
142
 
 
143
        reset_uart401(devc);
 
144
        devc->opened = 0;
 
145
}
 
146
 
 
147
static int uart401_out(int dev, unsigned char midi_byte)
 
148
{
 
149
        int timeout;
 
150
        unsigned long flags;
 
151
        uart401_devc *devc = (uart401_devc *) midi_devs[dev]->devc;
 
152
 
 
153
        if (devc->disabled)
 
154
                return 1;
 
155
        /*
 
156
         * Test for input since pending input seems to block the output.
 
157
         */
 
158
 
 
159
        spin_lock_irqsave(&devc->lock,flags);   
 
160
        if (input_avail(devc))
 
161
                uart401_input_loop(devc);
 
162
 
 
163
        spin_unlock_irqrestore(&devc->lock,flags);
 
164
 
 
165
        /*
 
166
         * Sometimes it takes about 13000 loops before the output becomes ready
 
167
         * (After reset). Normally it takes just about 10 loops.
 
168
         */
 
169
 
 
170
        for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
 
171
 
 
172
        if (!output_ready(devc))
 
173
        {
 
174
                  printk(KERN_WARNING "uart401: Timeout - Device not responding\n");
 
175
                  devc->disabled = 1;
 
176
                  reset_uart401(devc);
 
177
                  enter_uart_mode(devc);
 
178
                  return 1;
 
179
        }
 
180
        uart401_write(devc, midi_byte);
 
181
        return 1;
 
182
}
 
183
 
 
184
static inline int uart401_start_read(int dev)
 
185
{
 
186
        return 0;
 
187
}
 
188
 
 
189
static inline int uart401_end_read(int dev)
 
190
{
 
191
        return 0;
 
192
}
 
193
 
 
194
static inline void uart401_kick(int dev)
 
195
{
 
196
}
 
197
 
 
198
static inline int uart401_buffer_status(int dev)
 
199
{
 
200
        return 0;
 
201
}
 
202
 
 
203
#define MIDI_SYNTH_NAME "MPU-401 UART"
 
204
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
 
205
#include "midi_synth.h"
 
206
 
 
207
static const struct midi_operations uart401_operations =
 
208
{
 
209
        .owner          = THIS_MODULE,
 
210
        .info           = {"MPU-401 (UART) MIDI", 0, 0, SNDCARD_MPU401},
 
211
        .converter      = &std_midi_synth,
 
212
        .in_info        = {0},
 
213
        .open           = uart401_open,
 
214
        .close          = uart401_close,
 
215
        .outputc        = uart401_out,
 
216
        .start_read     = uart401_start_read,
 
217
        .end_read       = uart401_end_read,
 
218
        .kick           = uart401_kick,
 
219
        .buffer_status  = uart401_buffer_status,
 
220
};
 
221
 
 
222
static void enter_uart_mode(uart401_devc * devc)
 
223
{
 
224
        int ok, timeout;
 
225
        unsigned long flags;
 
226
 
 
227
        spin_lock_irqsave(&devc->lock,flags);   
 
228
        for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
 
229
 
 
230
        devc->input_byte = 0;
 
231
        uart401_cmd(devc, UART_MODE_ON);
 
232
 
 
233
        ok = 0;
 
234
        for (timeout = 50000; timeout > 0 && !ok; timeout--)
 
235
                if (devc->input_byte == MPU_ACK)
 
236
                        ok = 1;
 
237
                else if (input_avail(devc))
 
238
                        if (uart401_read(devc) == MPU_ACK)
 
239
                                ok = 1;
 
240
 
 
241
        spin_unlock_irqrestore(&devc->lock,flags);
 
242
}
 
243
 
 
244
static int reset_uart401(uart401_devc * devc)
 
245
{
 
246
        int ok, timeout, n;
 
247
 
 
248
        /*
 
249
         * Send the RESET command. Try again if no success at the first time.
 
250
         */
 
251
 
 
252
        ok = 0;
 
253
 
 
254
        for (n = 0; n < 2 && !ok; n++)
 
255
        {
 
256
                for (timeout = 30000; timeout > 0 && !output_ready(devc); timeout--);
 
257
                devc->input_byte = 0;
 
258
                uart401_cmd(devc, MPU_RESET);
 
259
 
 
260
                /*
 
261
                 * Wait at least 25 msec. This method is not accurate so let's make the
 
262
                 * loop bit longer. Cannot sleep since this is called during boot.
 
263
                 */
 
264
 
 
265
                for (timeout = 50000; timeout > 0 && !ok; timeout--)
 
266
                {
 
267
                        if (devc->input_byte == MPU_ACK)        /* Interrupt */
 
268
                                ok = 1;
 
269
                        else if (input_avail(devc))
 
270
                        {
 
271
                                if (uart401_read(devc) == MPU_ACK)
 
272
                                        ok = 1;
 
273
                        }
 
274
                }
 
275
        }
 
276
 
 
277
 
 
278
        if (ok)
 
279
        {
 
280
                DEB(printk("Reset UART401 OK\n"));
 
281
        }
 
282
        else
 
283
                DDB(printk("Reset UART401 failed - No hardware detected.\n"));
 
284
 
 
285
        if (ok)
 
286
                uart401_input_loop(devc);       /*
 
287
                                                 * Flush input before enabling interrupts
 
288
                                                 */
 
289
 
 
290
        return ok;
 
291
}
 
292
 
 
293
int probe_uart401(struct address_info *hw_config, struct module *owner)
 
294
{
 
295
        uart401_devc *devc;
 
296
        char *name = "MPU-401 (UART) MIDI";
 
297
        int ok = 0;
 
298
        unsigned long flags;
 
299
 
 
300
        DDB(printk("Entered probe_uart401()\n"));
 
301
 
 
302
        /* Default to "not found" */
 
303
        hw_config->slots[4] = -1;
 
304
 
 
305
        if (!request_region(hw_config->io_base, 4, "MPU-401 UART")) {
 
306
                printk(KERN_INFO "uart401: could not request_region(%d, 4)\n", hw_config->io_base);
 
307
                return 0;
 
308
        }
 
309
 
 
310
        devc = kmalloc(sizeof(uart401_devc), GFP_KERNEL);
 
311
        if (!devc) {
 
312
                printk(KERN_WARNING "uart401: Can't allocate memory\n");
 
313
                goto cleanup_region;
 
314
        }
 
315
 
 
316
        devc->base = hw_config->io_base;
 
317
        devc->irq = hw_config->irq;
 
318
        devc->osp = hw_config->osp;
 
319
        devc->midi_input_intr = NULL;
 
320
        devc->opened = 0;
 
321
        devc->input_byte = 0;
 
322
        devc->my_dev = 0;
 
323
        devc->share_irq = 0;
 
324
        spin_lock_init(&devc->lock);
 
325
 
 
326
        spin_lock_irqsave(&devc->lock,flags);   
 
327
        ok = reset_uart401(devc);
 
328
        spin_unlock_irqrestore(&devc->lock,flags);
 
329
 
 
330
        if (!ok)
 
331
                goto cleanup_devc;
 
332
 
 
333
        if (hw_config->name)
 
334
                name = hw_config->name;
 
335
 
 
336
        if (devc->irq < 0) {
 
337
                devc->share_irq = 1;
 
338
                devc->irq *= -1;
 
339
        } else
 
340
                devc->share_irq = 0;
 
341
 
 
342
        if (!devc->share_irq)
 
343
                if (request_irq(devc->irq, uart401intr, 0, "MPU-401 UART", devc) < 0) {
 
344
                        printk(KERN_WARNING "uart401: Failed to allocate IRQ%d\n", devc->irq);
 
345
                        devc->share_irq = 1;
 
346
                }
 
347
        devc->my_dev = sound_alloc_mididev();
 
348
        enter_uart_mode(devc);
 
349
 
 
350
        if (devc->my_dev == -1) {
 
351
                printk(KERN_INFO "uart401: Too many midi devices detected\n");
 
352
                goto cleanup_irq;
 
353
        }
 
354
        conf_printf(name, hw_config);
 
355
        midi_devs[devc->my_dev] = kmalloc(sizeof(struct midi_operations), GFP_KERNEL);
 
356
        if (!midi_devs[devc->my_dev]) {
 
357
                printk(KERN_ERR "uart401: Failed to allocate memory\n");
 
358
                goto cleanup_unload_mididev;
 
359
        }
 
360
        memcpy(midi_devs[devc->my_dev], &uart401_operations, sizeof(struct midi_operations));
 
361
 
 
362
        if (owner)
 
363
                midi_devs[devc->my_dev]->owner = owner;
 
364
        
 
365
        midi_devs[devc->my_dev]->devc = devc;
 
366
        midi_devs[devc->my_dev]->converter = kmalloc(sizeof(struct synth_operations), GFP_KERNEL);
 
367
        if (!midi_devs[devc->my_dev]->converter) {
 
368
                printk(KERN_WARNING "uart401: Failed to allocate memory\n");
 
369
                goto cleanup_midi_devs;
 
370
        }
 
371
        memcpy(midi_devs[devc->my_dev]->converter, &std_midi_synth, sizeof(struct synth_operations));
 
372
        strcpy(midi_devs[devc->my_dev]->info.name, name);
 
373
        midi_devs[devc->my_dev]->converter->id = "UART401";
 
374
        midi_devs[devc->my_dev]->converter->midi_dev = devc->my_dev;
 
375
 
 
376
        if (owner)
 
377
                midi_devs[devc->my_dev]->converter->owner = owner;
 
378
 
 
379
        hw_config->slots[4] = devc->my_dev;
 
380
        sequencer_init();
 
381
        devc->opened = 0;
 
382
        return 1;
 
383
cleanup_midi_devs:
 
384
        kfree(midi_devs[devc->my_dev]);
 
385
cleanup_unload_mididev:
 
386
        sound_unload_mididev(devc->my_dev);
 
387
cleanup_irq:
 
388
        if (!devc->share_irq)
 
389
                free_irq(devc->irq, devc);
 
390
cleanup_devc:
 
391
        kfree(devc);
 
392
cleanup_region:
 
393
        release_region(hw_config->io_base, 4);
 
394
        return 0;
 
395
}
 
396
 
 
397
void unload_uart401(struct address_info *hw_config)
 
398
{
 
399
        uart401_devc *devc;
 
400
        int n=hw_config->slots[4];
 
401
        
 
402
        /* Not set up */
 
403
        if(n==-1 || midi_devs[n]==NULL)
 
404
                return;
 
405
                
 
406
        /* Not allocated (erm ??) */
 
407
        
 
408
        devc = midi_devs[hw_config->slots[4]]->devc;
 
409
        if (devc == NULL)
 
410
                return;
 
411
 
 
412
        reset_uart401(devc);
 
413
        release_region(hw_config->io_base, 4);
 
414
 
 
415
        if (!devc->share_irq)
 
416
                free_irq(devc->irq, devc);
 
417
        if (devc)
 
418
        {
 
419
                kfree(midi_devs[devc->my_dev]->converter);
 
420
                kfree(midi_devs[devc->my_dev]);
 
421
                kfree(devc);
 
422
                devc = NULL;
 
423
        }
 
424
        /* This kills midi_devs[x] */
 
425
        sound_unload_mididev(hw_config->slots[4]);
 
426
}
 
427
 
 
428
EXPORT_SYMBOL(probe_uart401);
 
429
EXPORT_SYMBOL(unload_uart401);
 
430
EXPORT_SYMBOL(uart401intr);
 
431
 
 
432
static struct address_info cfg_mpu;
 
433
 
 
434
static int io = -1;
 
435
static int irq = -1;
 
436
 
 
437
module_param(io, int, 0444);
 
438
module_param(irq, int, 0444);
 
439
 
 
440
 
 
441
static int __init init_uart401(void)
 
442
{
 
443
        cfg_mpu.irq = irq;
 
444
        cfg_mpu.io_base = io;
 
445
 
 
446
        /* Can be loaded either for module use or to provide functions
 
447
           to others */
 
448
        if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1) {
 
449
                printk(KERN_INFO "MPU-401 UART driver Copyright (C) Hannu Savolainen 1993-1997");
 
450
                if (!probe_uart401(&cfg_mpu, THIS_MODULE))
 
451
                        return -ENODEV;
 
452
        }
 
453
 
 
454
        return 0;
 
455
}
 
456
 
 
457
static void __exit cleanup_uart401(void)
 
458
{
 
459
        if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1)
 
460
                unload_uart401(&cfg_mpu);
 
461
}
 
462
 
 
463
module_init(init_uart401);
 
464
module_exit(cleanup_uart401);
 
465
 
 
466
#ifndef MODULE
 
467
static int __init setup_uart401(char *str)
 
468
{
 
469
        /* io, irq */
 
470
        int ints[3];
 
471
        
 
472
        str = get_options(str, ARRAY_SIZE(ints), ints);
 
473
 
 
474
        io = ints[1];
 
475
        irq = ints[2];
 
476
        
 
477
        return 1;
 
478
}
 
479
 
 
480
__setup("uart401=", setup_uart401);
 
481
#endif
 
482
MODULE_LICENSE("GPL");