xref: /haiku/src/add-ons/kernel/drivers/audio/ice1712/midi.cpp (revision 1e60bdeab63fa7a57bc9a55b032052e95a18bd2c)
1 /*
2  * Copyright 2004-2015 Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jérôme Duval, jerome.duval@free.fr
7  *		Marcus Overhagen, marcus@overhagen.de
8  *		Jérôme Lévêque, leveque.jerome@gmail.com
9  */
10 
11 
12 #include <midi_driver.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <signal.h>
16 
17 #include "ice1712.h"
18 #include "ice1712_reg.h"
19 #include "io.h"
20 #include "util.h"
21 #include "debug.h"
22 
23 extern generic_mpu401_module * mpu401;
24 extern int32 num_cards;
25 extern ice1712 cards[NUM_CARDS];
26 
27 void ice1712Midi_interrupt(int32 op, void *data);
28 
29 
30 void
31 ice1712Midi_interrupt(int32 op, void *data)
32 {
33 	cpu_status status;
34 	uint8 int_status = 0;
35 	ice1712Midi *midi = (ice1712Midi*)data;
36 
37 	if (op == B_MPU_401_ENABLE_CARD_INT) {
38 		status = lock();
39 
40 		int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK);
41 		int_status &= ~(midi->int_mask);
42 		write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status);
43 
44 		ITRACE("B_MPU_401_ENABLE_CARD_INT: %s\n", midi->name);
45 
46 		unlock(status);
47 	} else if (op == B_MPU_401_DISABLE_CARD_INT) {
48 		status = lock();
49 
50 		int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK);
51 		int_status |= midi->int_mask;
52 		write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status);
53 
54 		ITRACE("B_MPU_401_DISABLE_CARD_INT: %s\n", midi->name);
55 
56 		unlock(status);
57 	}
58 
59 	ITRACE("New mask status 0x%x\n", int_status);
60 }
61 
62 
63 static status_t
64 ice1712Midi_open(const char *name, uint32 flags, void **cookie)
65 {
66 	int midi, card;
67 	status_t ret = ENODEV;
68 
69 	ITRACE("**midi_open()\n");
70 	*cookie = NULL;
71 
72 	for (card = 0; card < num_cards; card++) {
73 		for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) {
74 			if (!strcmp(name, cards[card].midiItf[midi].name)) {
75 				ice1712Midi *dev = &(cards[card].midiItf[midi]);
76 				ret = (*mpu401->open_hook)(dev->mpu401device, flags, cookie);
77 				if (ret >= B_OK) {
78 					*cookie = dev->mpu401device;
79 				}
80 				break;
81 			}
82 		}
83 	}
84 
85 	return ret;
86 }
87 
88 
89 static status_t
90 ice1712Midi_close(void* cookie)
91 {
92 	ITRACE("**midi_close()\n");
93 	return (*mpu401->close_hook)(cookie);
94 }
95 
96 
97 static status_t
98 ice1712Midi_free(void* cookie)
99 {
100 	int midi, card;
101 	status_t ret;
102 
103 	ITRACE("**midi_free()\n");
104 
105 	ret = (*mpu401->free_hook)(cookie);
106 
107 	for (card = 0; card < num_cards; card++) {
108 		for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) {
109 			if (cookie == cards[card].midiItf[midi].mpu401device) {
110 				cards[card].midiItf[midi].mpu401device = NULL;
111 				ITRACE("Cleared %p card %d, midi %d\n", cookie, card, midi);
112 				break;
113 			}
114 		}
115 	}
116 
117 	return ret;
118 }
119 
120 
121 static status_t
122 ice1712Midi_control(void* cookie,
123 	uint32 iop, void* data, size_t len)
124 {
125 	ITRACE("**midi_control()\n");
126 	return (*mpu401->control_hook)(cookie, iop, data, len);
127 }
128 
129 
130 static status_t
131 ice1712Midi_read(void * cookie, off_t pos, void * ptr, size_t * nread)
132 {
133 	status_t ret = B_ERROR;
134 
135 	ret = (*mpu401->read_hook)(cookie, pos, ptr, nread);
136 	ITRACE_VV("**midi_read: %" B_PRIi32 "\n", ret);
137 
138 	return ret;
139 }
140 
141 
142 static status_t
143 ice1712Midi_write(void * cookie, off_t pos, const void * ptr,
144 		size_t * nwritten)
145 {
146 	status_t ret = B_ERROR;
147 
148 	ret = (*mpu401->write_hook)(cookie, pos, ptr, nwritten);
149 	ITRACE_VV("**midi_write: %" B_PRIi32 "\n", ret);
150 
151 	return ret;
152 }
153 
154 
155 device_hooks ice1712Midi_hooks =
156 {
157 	ice1712Midi_open,
158 	ice1712Midi_close,
159 	ice1712Midi_free,
160 	ice1712Midi_control,
161 	ice1712Midi_read,
162 	ice1712Midi_write,
163 	NULL,
164 	NULL,
165 	NULL,
166 	NULL
167 };
168