xref: /haiku/src/add-ons/kernel/drivers/audio/emuxki/midi.c (revision 17889a8c70dbb3d59c1412f6431968753c767bab)
1 /*
2  * Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series
3  *
4  * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr)
5  *
6  * All rights reserved.
7  * Redistribution and use in source and binary forms, with or without modification,
8  * are permitted provided that the following conditions are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * - Redistributions in binary form must reproduce the above copyright notice,
13  *   this list of conditions and the following disclaimer in the documentation
14  *   and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  *
28  * Original code : Copyright 1999, Be Incorporated.   All Rights Reserved.
29  * This file may be used under the terms of the Be Sample Code License.
30 */
31 
32 #include <string.h>
33 #include <stdlib.h>
34 #include <signal.h>
35 
36 #include "emuxki.h"
37 #include "io.h"
38 #include "debug.h"
39 #include "midi_driver.h"
40 #include "util.h"
41 
42 extern generic_mpu401_module * mpu401;
43 
44 void
45 midi_interrupt_op(
46 	int32 op,
47 	void * data)
48 {
49 	cpu_status status;
50 	// dprint seems to be disabled here, will have to enable it to trace
51 
52 	midi_dev * port = (midi_dev *)data;
53 
54 	LOG(("mpu401:midi_interrupt_op %x\n",op));
55 	LOG(("port = %p\n", port));
56 	if (op == B_MPU_401_ENABLE_CARD_INT) {
57 		/* turn on MPU interrupts */
58 		LOG(("emuxki: B_MPU_401_ENABLE_CARD_INT\n"));
59 		status = lock();
60 		emuxki_reg_write_32(&(port->card->config), EMU_INTE,
61 			  emuxki_reg_read_32(&(port->card->config), EMU_INTE) | EMU_INTE_MIDIRXENABLE );
62 		unlock(status);
63 		LOG(("INTE address: %x\n",&port->card->config));
64 	}
65 	else if (op == B_MPU_401_DISABLE_CARD_INT) {
66 		/* turn off MPU interrupts */
67 		LOG(("emuxki: B_MPU_401_DISABLE_CARD_INT\n"));
68 		status = lock();
69 		emuxki_reg_write_32(&port->card->config, EMU_INTE,
70 			  emuxki_reg_read_32(&port->card->config, EMU_INTE) &  ~ EMU_INTE_MIDIRXENABLE);
71 		unlock(status);
72 	}
73 
74 	LOG(("midi_interrupt_op() done\n"));
75 }
76 
77 static status_t midi_open(const char *name, uint32 flags, void **cookie);
78 static status_t midi_close(void *cookie);
79 static status_t midi_free(void *cookie);
80 static status_t midi_control(void *cookie, uint32 op, void *data, size_t len);
81 static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len);
82 static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len);
83 
84 
85 device_hooks midi_hooks = {
86     &midi_open,
87     &midi_close,
88     &midi_free,
89     &midi_control,
90     &midi_read,
91     &midi_write,
92     NULL,		/* select */
93     NULL,		/* deselect */
94     NULL,		/* readv */
95     NULL		/* writev */
96 };
97 
98 static status_t
99 midi_open(
100 	const char * name,
101 	uint32 flags,
102 	void ** cookie)
103 {
104 	int ix;
105 	int ret;
106 
107 	LOG(("midi_open()\n"));
108 
109 	*cookie = NULL;
110 	for (ix=0; ix<num_cards; ix++) {
111 		if (!strcmp(name, cards[ix].midi.name)) {
112 			break;
113 		}
114 	}
115 	if (ix >= num_cards) {
116 		LOG(("bad device\n"));
117 		return ENODEV;
118 	}
119 
120 	LOG(("mpu401: %p  open(): %p  driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi.driver));
121 	ret = (*mpu401->open_hook)(cards[ix].midi.driver, flags, cookie);
122 	if (ret >= B_OK) {
123 		cards[ix].midi.cookie = *cookie;
124 		atomic_add(&cards[ix].midi.count, 1);
125 	}
126 	LOG(("mpu401: open returns %x / %p\n", ret, *cookie));
127 	return ret;
128 }
129 
130 
131 static status_t
132 midi_close(
133 	void * cookie)
134 {
135 	LOG(("midi_close()\n"));
136 	return (*mpu401->close_hook)(cookie);
137 }
138 
139 
140 static status_t
141 midi_free(
142 	void * cookie)
143 {
144 	int ix;
145 	status_t f;
146 	LOG(("midi_free()\n"));
147 	f = (*mpu401->free_hook)(cookie);
148 	for (ix=0; ix<num_cards; ix++) {
149 		if (cards[ix].midi.cookie == cookie) {
150 			if (atomic_add(&cards[ix].midi.count, -1) == 1) {
151 				cards[ix].midi.cookie = NULL;
152 				LOG(("cleared %p card %d\n", cookie, ix));
153 			}
154 			break;
155 		}
156 	}
157 	LOG(("midi_free() done\n"));
158 	return f;
159 }
160 
161 
162 static status_t
163 midi_control(
164 	void * cookie,
165 	uint32 iop,
166 	void * data,
167 	size_t len)
168 {
169 	return (*mpu401->control_hook)(cookie, iop, data, len);
170 }
171 
172 
173 static status_t
174 midi_read(
175 	void * cookie,
176 	off_t pos,
177 	void * ptr,
178 	size_t * nread)
179 {
180 	return (*mpu401->read_hook)(cookie, pos, ptr, nread);
181 }
182 
183 
184 static status_t
185 midi_write(
186 	void * cookie,
187 	off_t pos,
188 	const void * ptr,
189 	size_t * nwritten)
190 {
191 	return (*mpu401->write_hook)(cookie, pos, ptr, nwritten);
192 }
193 
194 
195 bool
196 midi_interrupt(emuxki_dev *card)
197 {
198 	TRACE(("midi_interrupt\n"));
199 	if (!card->midi.driver)  {
200 		dprintf("aiigh\n");
201 		return false;
202 	}
203 
204 	return (*mpu401->interrupt_hook)(card->midi.driver);
205 }
206 
207