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
13extern 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
22extern generic_mpu401_module * mpu401;
23
24void
25midi_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
57static status_t midi_open(const char *name, uint32 flags, void **cookie);
58static status_t midi_close(void *cookie);
59static status_t midi_free(void *cookie);
60static status_t midi_control(void *cookie, uint32 op, void *data, size_t len);
61static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len);
62static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len);
63
64
65device_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
78static status_t
79midi_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
111static status_t
112midi_close(
113	void * cookie)
114{
115	ddprintf(("cmedia_pci: midi_close()\n"));
116	return (*mpu401->close_hook)(cookie);
117}
118
119
120static status_t
121midi_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
142static status_t
143midi_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
153static status_t
154midi_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
164static status_t
165midi_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
175bool
176midi_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