xref: /haiku/src/add-ons/kernel/drivers/audio/cmedia/midi.c (revision 028e368c21a7d7221cd9c466afb9ac2c8462c052)
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