1 /* 2 * Emuxki BeOS Driver for Creative Labs SBLive!/Audigy series 3 * 4 * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) 5 * 6 * All rights reserved. 7 * Redistribution and use in source and binary forms, with or without modification, 8 * are permitted provided that the following conditions are met: 9 * 10 * - Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * - Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 25 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * 27 * 28 * Original code : Copyright 1999, Be Incorporated. All Rights Reserved. 29 * This file may be used under the terms of the Be Sample Code License. 30 */ 31 32 #include <string.h> 33 #include <stdlib.h> 34 #include <signal.h> 35 36 #include "emuxki.h" 37 #include "io.h" 38 #include "debug.h" 39 #include "midi_driver.h" 40 #include "util.h" 41 42 extern generic_mpu401_module * mpu401; 43 44 void 45 midi_interrupt_op( 46 int32 op, 47 void * data) 48 { 49 // dprint seems to be disabled here, will have to enable it to trace 50 51 midi_dev * port = (midi_dev *)data; 52 TRACE(("port = %p\n", port)); 53 if (op == B_MPU_401_ENABLE_CARD_INT) { 54 // sample code 55 /*cpu_status cp; 56 ddprintf(("sonic_vibes: B_MPU_401_ENABLE_CARD_INT\n")); 57 cp = disable_interrupts(); 58 acquire_spinlock(&port->card->hardware); 59 increment_interrupt_handler(port->card); 60 set_direct(port->card, 0x01, 0x00, 0x80); 61 set_indirect(port->card, 0x2A, 0x04, 0xff); 62 release_spinlock(&port->card->hardware); 63 restore_interrupts(cp);*/ 64 65 //real code 66 cpu_status status; 67 status = lock(); 68 emuxki_reg_write_32(&(port->card->config), EMU_INTE, 69 emuxki_reg_read_32(&(port->card->config), EMU_INTE) | 70 EMU_INTE_MIDITXENABLE | EMU_INTE_MIDIRXENABLE ); 71 unlock(status); 72 } 73 else if (op == B_MPU_401_DISABLE_CARD_INT) { 74 // sample code 75 /* turn off MPU interrupts */ 76 /*cpu_status cp; 77 ddprintf(("sonic_vibes: B_MPU_401_DISABLE_CARD_INT\n")); 78 cp = disable_interrupts(); 79 acquire_spinlock(&port->card->hardware); 80 set_direct(port->card, 0x01, 0x80, 0x80);*/ 81 /* remove interrupt handler if necessary */ 82 /*decrement_interrupt_handler(port->card); 83 release_spinlock(&port->card->hardware); 84 restore_interrupts(cp);*/ 85 86 //real code 87 cpu_status status; 88 status = lock(); 89 emuxki_reg_write_32(&port->card->config, EMU_INTE, 90 emuxki_reg_read_32(&port->card->config, EMU_INTE) & 91 ~ (EMU_INTE_MIDITXENABLE | EMU_INTE_MIDIRXENABLE ) ); 92 unlock(status); 93 } 94 TRACE(("midi_interrupt_op() done\n")); 95 } 96 97 static status_t midi_open(const char *name, uint32 flags, void **cookie); 98 static status_t midi_close(void *cookie); 99 static status_t midi_free(void *cookie); 100 static status_t midi_control(void *cookie, uint32 op, void *data, size_t len); 101 static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len); 102 static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len); 103 104 105 device_hooks midi_hooks = { 106 &midi_open, 107 &midi_close, 108 &midi_free, 109 &midi_control, 110 &midi_read, 111 &midi_write, 112 NULL, /* select */ 113 NULL, /* deselect */ 114 NULL, /* readv */ 115 NULL /* writev */ 116 }; 117 118 static status_t 119 midi_open( 120 const char * name, 121 uint32 flags, 122 void ** cookie) 123 { 124 int ix; 125 int ret; 126 127 LOG(("midi_open()\n")); 128 129 *cookie = NULL; 130 for (ix=0; ix<num_cards; ix++) { 131 if (!strcmp(name, cards[ix].midi.name)) { 132 break; 133 } 134 } 135 if (ix >= num_cards) { 136 LOG(("bad device\n")); 137 return ENODEV; 138 } 139 140 LOG(("mpu401: %p open(): %p driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi.driver)); 141 ret = (*mpu401->open_hook)(cards[ix].midi.driver, flags, cookie); 142 if (ret >= B_OK) { 143 cards[ix].midi.cookie = *cookie; 144 atomic_add(&cards[ix].midi.count, 1); 145 } 146 LOG(("mpu401: open returns %x / %p\n", ret, *cookie)); 147 return ret; 148 } 149 150 151 static status_t 152 midi_close( 153 void * cookie) 154 { 155 LOG(("midi_close()\n")); 156 return (*mpu401->close_hook)(cookie); 157 } 158 159 160 static status_t 161 midi_free( 162 void * cookie) 163 { 164 int ix; 165 status_t f; 166 LOG(("midi_free()\n")); 167 f = (*mpu401->free_hook)(cookie); 168 for (ix=0; ix<num_cards; ix++) { 169 if (cards[ix].midi.cookie == cookie) { 170 if (atomic_add(&cards[ix].midi.count, -1) == 1) { 171 cards[ix].midi.cookie = NULL; 172 LOG(("cleared %p card %d\n", cookie, ix)); 173 } 174 break; 175 } 176 } 177 LOG(("midi_free() done\n")); 178 return f; 179 } 180 181 182 static status_t 183 midi_control( 184 void * cookie, 185 uint32 iop, 186 void * data, 187 size_t len) 188 { 189 return (*mpu401->control_hook)(cookie, iop, data, len); 190 } 191 192 193 static status_t 194 midi_read( 195 void * cookie, 196 off_t pos, 197 void * ptr, 198 size_t * nread) 199 { 200 return (*mpu401->read_hook)(cookie, pos, ptr, nread); 201 } 202 203 204 static status_t 205 midi_write( 206 void * cookie, 207 off_t pos, 208 const void * ptr, 209 size_t * nwritten) 210 { 211 return (*mpu401->write_hook)(cookie, pos, ptr, nwritten); 212 } 213 214 215 bool 216 midi_interrupt(emuxki_dev *card) 217 { 218 TRACE(("midi_interrupt\n")); 219 if (!card->midi.driver) { 220 // kprintf("aiigh\n"); 221 return false; 222 } 223 224 return (*mpu401->interrupt_hook)(card->midi.driver); 225 } 226 227