• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/sound/oss/
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
33typedef 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}
45uart401_devc;
46
47#define	DATAPORT   (devc->base)
48#define	COMDPORT   (devc->base+1)
49#define	STATPORT   (devc->base+1)
50
51static 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
59static void uart401_cmd(uart401_devc * devc, unsigned char cmd)
60{
61	outb((cmd), COMDPORT);
62}
63
64static int uart401_read(uart401_devc * devc)
65{
66	return inb(DATAPORT);
67}
68
69static 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
80static int      reset_uart401(uart401_devc * devc);
81static void     enter_uart_mode(uart401_devc * devc);
82
83static 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
100irqreturn_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
115static int
116uart401_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
139static 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
147static 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
184static inline int uart401_start_read(int dev)
185{
186	return 0;
187}
188
189static inline int uart401_end_read(int dev)
190{
191	return 0;
192}
193
194static inline void uart401_kick(int dev)
195{
196}
197
198static 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
207static 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
222static 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
244static 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
293int 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;
383cleanup_midi_devs:
384	kfree(midi_devs[devc->my_dev]);
385cleanup_unload_mididev:
386	sound_unload_mididev(devc->my_dev);
387cleanup_irq:
388	if (!devc->share_irq)
389		free_irq(devc->irq, devc);
390cleanup_devc:
391	kfree(devc);
392cleanup_region:
393	release_region(hw_config->io_base, 4);
394	return 0;
395}
396
397void 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
428EXPORT_SYMBOL(probe_uart401);
429EXPORT_SYMBOL(unload_uart401);
430EXPORT_SYMBOL(uart401intr);
431
432static struct address_info cfg_mpu;
433
434static int io = -1;
435static int irq = -1;
436
437module_param(io, int, 0444);
438module_param(irq, int, 0444);
439
440
441static 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
457static void __exit cleanup_uart401(void)
458{
459	if (cfg_mpu.io_base != -1 && cfg_mpu.irq != -1)
460		unload_uart401(&cfg_mpu);
461}
462
463module_init(init_uart401);
464module_exit(cleanup_uart401);
465
466#ifndef MODULE
467static 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
482MODULE_LICENSE("GPL");
483