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
23extern generic_mpu401_module * mpu401;
24extern int32 num_cards;
25extern ice1712 cards[NUM_CARDS];
26
27void ice1712Midi_interrupt(int32 op, void *data);
28
29
30void
31ice1712Midi_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
63static status_t
64ice1712Midi_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
89static status_t
90ice1712Midi_close(void* cookie)
91{
92	ITRACE("**midi_close()\n");
93	return (*mpu401->close_hook)(cookie);
94}
95
96
97static status_t
98ice1712Midi_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
121static status_t
122ice1712Midi_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
130static status_t
131ice1712Midi_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
142static status_t
143ice1712Midi_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
155device_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