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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [sound/] [uart6850.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * sound/uart6850.c
3
 *
4
 *
5
 * Copyright (C) by Hannu Savolainen 1993-1997
6
 *
7
 * OSS/Free for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL)
8
 * Version 2 (June 1991). See the "COPYING" file distributed with this software
9
 * for more info.
10
 * Extended by Alan Cox for Red Hat Software. Now a loadable MIDI driver.
11
 * 28/4/97 - (C) Copyright Alan Cox. Released under the GPL version 2.
12
 *
13
 * Alan Cox:            Updated for new modular code. Removed snd_* irq handling. Now
14
 *                      uses native linux resources
15
 * Christoph Hellwig:   Adapted to module_init/module_exit
16
 * Jeff Garzik:         Made it work again, in theory
17
 *                      FIXME: If the request_irq() succeeds, the probe succeeds. Ug.
18
 *
19
 *      Status: Testing required (no shit -jgarzik)
20
 *
21
 *
22
 */
23
 
24
#include <linux/init.h>
25
#include <linux/module.h>
26
 
27
/* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
28
 *      added 6850 support, used with COVOX SoundMaster II and custom cards.
29
 */
30
 
31
#include "sound_config.h"
32
 
33
static int uart6850_base = 0x330;
34
 
35
static int *uart6850_osp;
36
 
37
#define DATAPORT   (uart6850_base)
38
#define COMDPORT   (uart6850_base+1)
39
#define STATPORT   (uart6850_base+1)
40
 
41
static int uart6850_status(void)
42
{
43
        return inb(STATPORT);
44
}
45
 
46
#define input_avail()           (uart6850_status()&INPUT_AVAIL)
47
#define output_ready()          (uart6850_status()&OUTPUT_READY)
48
 
49
static void uart6850_cmd(unsigned char cmd)
50
{
51
        outb(cmd, COMDPORT);
52
}
53
 
54
static int uart6850_read(void)
55
{
56
        return inb(DATAPORT);
57
}
58
 
59
static void uart6850_write(unsigned char byte)
60
{
61
        outb(byte, DATAPORT);
62
}
63
 
64
#define OUTPUT_READY    0x02    /* Mask for data ready Bit */
65
#define INPUT_AVAIL     0x01    /* Mask for Data Send Ready Bit */
66
 
67
#define UART_RESET      0x95
68
#define UART_MODE_ON    0x03
69
 
70
static int uart6850_opened;
71
static int uart6850_irq;
72
static int uart6850_detected;
73
static int my_dev;
74
 
75
static void (*midi_input_intr) (int dev, unsigned char data);
76
static void poll_uart6850(unsigned long dummy);
77
 
78
 
79
static struct timer_list uart6850_timer = {
80
        function: poll_uart6850
81
};
82
 
83
static void uart6850_input_loop(void)
84
{
85
        int count = 10;
86
 
87
        while (count)
88
        {
89
                /*
90
                 * Not timed out
91
                 */
92
                if (input_avail())
93
                {
94
                        unsigned char c = uart6850_read();
95
                        count = 100;
96
                        if (uart6850_opened & OPEN_READ)
97
                                midi_input_intr(my_dev, c);
98
                }
99
                else
100
                {
101
                        while (!input_avail() && count)
102
                                count--;
103
                }
104
        }
105
}
106
 
107
void m6850intr(int irq, void *dev_id, struct pt_regs *dummy)
108
{
109
        if (input_avail())
110
                uart6850_input_loop();
111
}
112
 
113
/*
114
 *      It looks like there is no input interrupts in the UART mode. Let's try
115
 *      polling.
116
 */
117
 
118
static void poll_uart6850(unsigned long dummy)
119
{
120
        unsigned long flags;
121
 
122
        if (!(uart6850_opened & OPEN_READ))
123
                return;         /* Device has been closed */
124
 
125
        save_flags(flags);
126
        cli();
127
 
128
        if (input_avail())
129
                uart6850_input_loop();
130
 
131
        uart6850_timer.expires = 1 + jiffies;
132
        add_timer(&uart6850_timer);
133
 
134
        /*
135
         *      Come back later
136
         */
137
 
138
        restore_flags(flags);
139
}
140
 
141
static int uart6850_open(int dev, int mode,
142
              void            (*input) (int dev, unsigned char data),
143
              void            (*output) (int dev)
144
)
145
{
146
        if (uart6850_opened)
147
        {
148
/*                printk("Midi6850: Midi busy\n");*/
149
                  return -EBUSY;
150
        };
151
 
152
        uart6850_cmd(UART_RESET);
153
        uart6850_input_loop();
154
        midi_input_intr = input;
155
        uart6850_opened = mode;
156
        poll_uart6850(0);        /*
157
                                 * Enable input polling
158
                                 */
159
 
160
        return 0;
161
}
162
 
163
static void uart6850_close(int dev)
164
{
165
        uart6850_cmd(UART_MODE_ON);
166
        del_timer(&uart6850_timer);
167
        uart6850_opened = 0;
168
}
169
 
170
static int uart6850_out(int dev, unsigned char midi_byte)
171
{
172
        int timeout;
173
        unsigned long flags;
174
 
175
        /*
176
         * Test for input since pending input seems to block the output.
177
         */
178
 
179
        save_flags(flags);
180
        cli();
181
 
182
        if (input_avail())
183
                uart6850_input_loop();
184
 
185
        restore_flags(flags);
186
 
187
        /*
188
         * Sometimes it takes about 13000 loops before the output becomes ready
189
         * (After reset). Normally it takes just about 10 loops.
190
         */
191
 
192
        for (timeout = 30000; timeout > 0 && !output_ready(); timeout--);        /*
193
                                                                                 * Wait
194
                                                                                 */
195
        if (!output_ready())
196
        {
197
                printk(KERN_WARNING "Midi6850: Timeout\n");
198
                return 0;
199
        }
200
        uart6850_write(midi_byte);
201
        return 1;
202
}
203
 
204
static inline int uart6850_command(int dev, unsigned char *midi_byte)
205
{
206
        return 1;
207
}
208
 
209
static inline int uart6850_start_read(int dev)
210
{
211
        return 0;
212
}
213
 
214
static inline int uart6850_end_read(int dev)
215
{
216
        return 0;
217
}
218
 
219
static inline void uart6850_kick(int dev)
220
{
221
}
222
 
223
static inline int uart6850_buffer_status(int dev)
224
{
225
        return 0;                /*
226
                                 * No data in buffers
227
                                 */
228
}
229
 
230
#define MIDI_SYNTH_NAME "6850 UART Midi"
231
#define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
232
#include "midi_synth.h"
233
 
234
static struct midi_operations uart6850_operations =
235
{
236
        owner:          THIS_MODULE,
237
        info:           {"6850 UART", 0, 0, SNDCARD_UART6850},
238
        converter:      &std_midi_synth,
239
        in_info:        {0},
240
        open:           uart6850_open,
241
        close:          uart6850_close,
242
        outputc:        uart6850_out,
243
        start_read:     uart6850_start_read,
244
        end_read:       uart6850_end_read,
245
        kick:           uart6850_kick,
246
        command:        uart6850_command,
247
        buffer_status:  uart6850_buffer_status
248
};
249
 
250
 
251
static void __init attach_uart6850(struct address_info *hw_config)
252
{
253
        int ok, timeout;
254
        unsigned long   flags;
255
 
256
        if (!uart6850_detected)
257
                return;
258
 
259
        if ((my_dev = sound_alloc_mididev()) == -1)
260
        {
261
                printk(KERN_INFO "uart6850: Too many midi devices detected\n");
262
                return;
263
        }
264
        uart6850_base = hw_config->io_base;
265
        uart6850_osp = hw_config->osp;
266
        uart6850_irq = hw_config->irq;
267
 
268
        save_flags(flags);
269
        cli();
270
 
271
        for (timeout = 30000; timeout > 0 && !output_ready(); timeout--);        /*
272
                                                                                 * Wait
273
                                                                                 */
274
        uart6850_cmd(UART_MODE_ON);
275
        ok = 1;
276
        restore_flags(flags);
277
 
278
        conf_printf("6850 Midi Interface", hw_config);
279
 
280
        std_midi_synth.midi_dev = my_dev;
281
        hw_config->slots[4] = my_dev;
282
        midi_devs[my_dev] = &uart6850_operations;
283
        sequencer_init();
284
}
285
 
286
static inline int reset_uart6850(void)
287
{
288
        uart6850_read();
289
        return 1;               /*
290
                                 * OK
291
                                 */
292
}
293
 
294
static int __init probe_uart6850(struct address_info *hw_config)
295
{
296
        int ok;
297
 
298
        uart6850_osp = hw_config->osp;
299
        uart6850_base = hw_config->io_base;
300
        uart6850_irq = hw_config->irq;
301
 
302
        if (request_irq(uart6850_irq, m6850intr, 0, "MIDI6850", NULL) < 0)
303
                return 0;
304
 
305
        ok = reset_uart6850();
306
        uart6850_detected = ok;
307
        return ok;
308
}
309
 
310
static void __exit unload_uart6850(struct address_info *hw_config)
311
{
312
        free_irq(hw_config->irq, NULL);
313
        sound_unload_mididev(hw_config->slots[4]);
314
}
315
 
316
static struct address_info cfg_mpu;
317
 
318
static int __initdata io = -1;
319
static int __initdata irq = -1;
320
 
321
MODULE_PARM(io,"i");
322
MODULE_PARM(irq,"i");
323
 
324
static int __init init_uart6850(void)
325
{
326
        cfg_mpu.io_base = io;
327
        cfg_mpu.irq = irq;
328
 
329
        if (cfg_mpu.io_base == -1 || cfg_mpu.irq == -1) {
330
                printk(KERN_INFO "uart6850: irq and io must be set.\n");
331
                return -EINVAL;
332
        }
333
 
334
        if (probe_uart6850(&cfg_mpu))
335
                return -ENODEV;
336
        attach_uart6850(&cfg_mpu);
337
 
338
        return 0;
339
}
340
 
341
static void __exit cleanup_uart6850(void)
342
{
343
        unload_uart6850(&cfg_mpu);
344
}
345
 
346
module_init(init_uart6850);
347
module_exit(cleanup_uart6850);
348
 
349
#ifndef MODULE
350
static int __init setup_uart6850(char *str)
351
{
352
        /* io, irq */
353
        int ints[3];
354
 
355
        str = get_options(str, ARRAY_SIZE(ints), ints);
356
 
357
        io = ints[1];
358
        irq = ints[2];
359
 
360
        return 1;
361
}
362
__setup("uart6850=", setup_uart6850);
363
#endif
364
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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