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