xref: /haiku/src/add-ons/kernel/drivers/audio/cmedia/midi.c (revision 93a78ecaa45114d68952d08c4778f073515102f2)
1 /*
2 	Copyright 1999, Be Incorporated.   All Rights Reserved.
3 	This file may be used under the terms of the Be Sample Code License.
4 */
5 
6 #include <string.h>
7 #include <stdlib.h>
8 #include <signal.h>
9 
10 #include "cm_private.h"
11 
12 
13 extern void dump_card(cmedia_pci_dev * card);
14 
15 #if !defined(_KERNEL_EXPORT_H)
16 #include <KernelExport.h>
17 #endif /* _KERNEL_EXPORT_H */
18 
19 #define MIDI_ACTIVE_SENSE 0xfe
20 #define SNOOZE_GRANULARITY 500
21 
22 extern generic_mpu401_module * mpu401;
23 
24 void
25 midi_interrupt_op(
26 	int32 op,
27 	void * data)
28 {
29 	midi_dev * port = (midi_dev *)data;
30 	ddprintf(("port = %p\n", port));
31 	if (op == B_MPU_401_ENABLE_CARD_INT) {
32 		cpu_status cp;
33 		ddprintf(("cmedia_pci: B_MPU_401_ENABLE_CARD_INT\n"));
34 		cp = disable_interrupts();
35 		acquire_spinlock(&port->card->hardware);
36 		increment_interrupt_handler(port->card);
37 		set_direct(port->card, 0x01, 0x00, 0x80);
38 		set_indirect(port->card, 0x2A, 0x04, 0xff);
39 		release_spinlock(&port->card->hardware);
40 		restore_interrupts(cp);
41 	}
42 	else if (op == B_MPU_401_DISABLE_CARD_INT) {
43 		/* turn off MPU interrupts */
44 		cpu_status cp;
45 		ddprintf(("cmedia_pci: B_MPU_401_DISABLE_CARD_INT\n"));
46 		cp = disable_interrupts();
47 		acquire_spinlock(&port->card->hardware);
48 		set_direct(port->card, 0x01, 0x80, 0x80);
49 		/* remove interrupt handler if necessary */
50 		decrement_interrupt_handler(port->card);
51 		release_spinlock(&port->card->hardware);
52 		restore_interrupts(cp);
53 	}
54 	ddprintf(("cmedia_pci: midi_interrupt_op() done\n"));
55 }
56 
57 static status_t midi_open(const char *name, uint32 flags, void **cookie);
58 static status_t midi_close(void *cookie);
59 static status_t midi_free(void *cookie);
60 static status_t midi_control(void *cookie, uint32 op, void *data, size_t len);
61 static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len);
62 static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len);
63 
64 
65 device_hooks midi_hooks = {
66     &midi_open,
67     &midi_close,
68     &midi_free,
69     &midi_control,
70     &midi_read,
71     &midi_write,
72     NULL,		/* select */
73     NULL,		/* deselect */
74     NULL,		/* readv */
75     NULL		/* writev */
76 };
77 
78 static status_t
79 midi_open(
80 	const char * name,
81 	uint32 flags,
82 	void ** cookie)
83 {
84 	int ix;
85 	int ret;
86 
87 	ddprintf(("cmedia_pci: midi_open()\n"));
88 
89 	*cookie = NULL;
90 	for (ix=0; ix<num_cards; ix++) {
91 		if (!strcmp(name, cards[ix].midi.name)) {
92 			break;
93 		}
94 	}
95 	if (ix >= num_cards) {
96 		ddprintf(("bad device\n"));
97 		return ENODEV;
98 	}
99 
100 	ddprintf(("cmedia_pci: mpu401: %p  open(): %p  driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi.driver));
101 	ret = (*mpu401->open_hook)(cards[ix].midi.driver, flags, cookie);
102 	if (ret >= B_OK) {
103 		cards[ix].midi.cookie = *cookie;
104 		atomic_add(&cards[ix].midi.count, 1);
105 	}
106 	ddprintf(("cmedia_pci: mpu401: open returns %x / %p\n", ret, *cookie));
107 	return ret;
108 }
109 
110 
111 static status_t
112 midi_close(
113 	void * cookie)
114 {
115 	ddprintf(("cmedia_pci: midi_close()\n"));
116 	return (*mpu401->close_hook)(cookie);
117 }
118 
119 
120 static status_t
121 midi_free(
122 	void * cookie)
123 {
124 	int ix;
125 	status_t f;
126 	ddprintf(("cmedia_pci: midi_free()\n"));
127 	f = (*mpu401->free_hook)(cookie);
128 	for (ix=0; ix<num_cards; ix++) {
129 		if (cards[ix].midi.cookie == cookie) {
130 			if (atomic_add(&cards[ix].midi.count, -1) == 1) {
131 				cards[ix].midi.cookie = NULL;
132 				ddprintf(("cleared %p card %d\n", cookie, ix));
133 			}
134 			break;
135 		}
136 	}
137 	ddprintf(("cmedia_pci: midi_free() done\n"));
138 	return f;
139 }
140 
141 
142 static status_t
143 midi_control(
144 	void * cookie,
145 	uint32 iop,
146 	void * data,
147 	size_t len)
148 {
149 	return (*mpu401->control_hook)(cookie, iop, data, len);
150 }
151 
152 
153 static status_t
154 midi_read(
155 	void * cookie,
156 	off_t pos,
157 	void * ptr,
158 	size_t * nread)
159 {
160 	return (*mpu401->read_hook)(cookie, pos, ptr, nread);
161 }
162 
163 
164 static status_t
165 midi_write(
166 	void * cookie,
167 	off_t pos,
168 	const void * ptr,
169 	size_t * nwritten)
170 {
171 	return (*mpu401->write_hook)(cookie, pos, ptr, nwritten);
172 }
173 
174 
175 bool
176 midi_interrupt(
177 	cmedia_pci_dev * dev)
178 {
179 	if (!dev->midi.driver)  {
180 //		kprintf("aiigh\n");
181 		return false;
182 	}
183 
184 	return (*mpu401->interrupt_hook)(dev->midi.driver);
185 }
186 
187