2 **********************************************************************
3 * cardmo.c - MIDI UART output HAL for emu10k1 driver
4 * Copyright 1999, 2000 Creative Labs, Inc.
6 **********************************************************************
8 * Date Author Summary of changes
9 * ---- ------ ------------------
10 * October 20, 1999 Bertrand Lee base code release
11 * November 2, 1999 Alan Cox cleaned up
13 **********************************************************************
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public
26 * License along with this program; if not, write to the Free
27 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
30 **********************************************************************
33 #include <linux/slab.h>
40 /* Installs the IRQ handler for the MPU out port *
41 * and initialize parameters */
43 int emu10k1_mpuout_open(struct emu10k1_card
*card
, struct midi_openinfo
*openinfo
)
45 struct emu10k1_mpuout
*card_mpuout
= card
->mpuout
;
47 DPF(2, "emu10k1_mpuout_open()\n");
49 if (!(card_mpuout
->status
& FLAGS_AVAILABLE
))
52 /* Copy open info and mark channel as in use */
53 card_mpuout
->intr
= 0;
54 card_mpuout
->openinfo
= *openinfo
;
55 card_mpuout
->status
&= ~FLAGS_AVAILABLE
;
56 card_mpuout
->laststatus
= 0x80;
57 card_mpuout
->firstmidiq
= NULL
;
58 card_mpuout
->lastmidiq
= NULL
;
60 emu10k1_mpu_reset(card
);
61 emu10k1_mpu_acquire(card
);
66 int emu10k1_mpuout_close(struct emu10k1_card
*card
)
68 struct emu10k1_mpuout
*card_mpuout
= card
->mpuout
;
69 struct midi_queue
*midiq
;
70 struct midi_hdr
*midihdr
;
73 DPF(2, "emu10k1_mpuout_close()\n");
75 emu10k1_irq_disable(card
, card
->is_audigy
? A_INTE_MIDITXENABLE
: INTE_MIDITXENABLE
);
77 spin_lock_irqsave(&card_mpuout
->lock
, flags
);
79 while (card_mpuout
->firstmidiq
!= NULL
) {
80 midiq
= card_mpuout
->firstmidiq
;
81 midihdr
= (struct midi_hdr
*) midiq
->refdata
;
83 card_mpuout
->firstmidiq
= midiq
->next
;
90 card_mpuout
->lastmidiq
= NULL
;
92 emu10k1_mpu_release(card
);
94 card_mpuout
->status
|= FLAGS_AVAILABLE
;
96 spin_unlock_irqrestore(&card_mpuout
->lock
, flags
);
101 /* If there isn't enough buffer space, reject Midi Buffer. *
102 * Otherwise, disable TX, create object to hold Midi *
103 * uffer, update buffer flags and other parameters *
104 * before enabling TX again. */
106 int emu10k1_mpuout_add_buffer(struct emu10k1_card
*card
, struct midi_hdr
*midihdr
)
108 struct emu10k1_mpuout
*card_mpuout
= card
->mpuout
;
109 struct midi_queue
*midiq
;
112 DPF(2, "emu10k1_mpuout_add_buffer()\n");
114 if (card_mpuout
->state
== CARDMIDIOUT_STATE_SUSPEND
)
117 midihdr
->flags
|= MIDIBUF_INQUEUE
;
118 midihdr
->flags
&= ~MIDIBUF_DONE
;
120 if ((midiq
= (struct midi_queue
*) kmalloc(sizeof(struct midi_queue
), GFP_KERNEL
)) == NULL
) {
127 midiq
->length
= midihdr
->bufferlength
;
128 midiq
->sizeLeft
= midihdr
->bufferlength
;
129 midiq
->midibyte
= midihdr
->data
;
131 midiq
->refdata
= (unsigned long) midihdr
;
133 spin_lock_irqsave(&card_mpuout
->lock
, flags
);
135 if (card_mpuout
->firstmidiq
== NULL
) {
136 card_mpuout
->firstmidiq
= midiq
;
137 card_mpuout
->lastmidiq
= midiq
;
139 (card_mpuout
->lastmidiq
)->next
= midiq
;
140 card_mpuout
->lastmidiq
= midiq
;
143 card_mpuout
->intr
= 0;
145 emu10k1_irq_enable(card
, card
->is_audigy
? A_INTE_MIDITXENABLE
: INTE_MIDITXENABLE
);
147 spin_unlock_irqrestore(&card_mpuout
->lock
, flags
);
152 void emu10k1_mpuout_bh(unsigned long refdata
)
154 struct emu10k1_card
*card
= (struct emu10k1_card
*) refdata
;
155 struct emu10k1_mpuout
*card_mpuout
= card
->mpuout
;
157 struct midi_queue
*midiq
;
158 struct midi_queue
*doneq
= NULL
;
161 spin_lock_irqsave(&card_mpuout
->lock
, flags
);
163 while (card_mpuout
->firstmidiq
!= NULL
) {
164 midiq
= card_mpuout
->firstmidiq
;
166 while (cByteSent
< 4 && midiq
->sizeLeft
) {
167 if (emu10k1_mpu_write_data(card
, *midiq
->midibyte
) < 0) {
168 DPF(2, "emu10k1_mpuoutDpcCallback error!!\n");
176 if (midiq
->sizeLeft
== 0) {
179 card_mpuout
->firstmidiq
= midiq
->next
;
184 if (card_mpuout
->firstmidiq
== NULL
)
185 card_mpuout
->lastmidiq
= NULL
;
188 while (doneq
!= card_mpuout
->firstmidiq
) {
189 unsigned long callback_msg
[3];
196 callback_msg
[1] = midiq
->length
;
197 callback_msg
[2] = midiq
->refdata
;
199 emu10k1_midi_callback(ICARDMIDI_OUTLONGDATA
, card_mpuout
->openinfo
.refdata
, callback_msg
);
200 } else if (((u8
) midiq
->refdata
) < 0xF0 && ((u8
) midiq
->refdata
) > 0x7F)
201 card_mpuout
->laststatus
= (u8
) midiq
->refdata
;
207 if ((card_mpuout
->firstmidiq
!= NULL
) || cByteSent
) {
208 card_mpuout
->intr
= 0;
209 emu10k1_irq_enable(card
, card
->is_audigy
? A_INTE_MIDITXENABLE
: INTE_MIDITXENABLE
);
212 spin_unlock_irqrestore(&card_mpuout
->lock
, flags
);
217 int emu10k1_mpuout_irqhandler(struct emu10k1_card
*card
)
219 struct emu10k1_mpuout
*card_mpuout
= card
->mpuout
;
221 DPF(4, "emu10k1_mpuout_irqhandler\n");
223 card_mpuout
->intr
= 1;
224 emu10k1_irq_disable(card
, card
->is_audigy
? A_INTE_MIDITXENABLE
: INTE_MIDITXENABLE
);
226 tasklet_hi_schedule(&card_mpuout
->tasklet
);