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 cpu_status status; 50 // dprint seems to be disabled here, will have to enable it to trace 51 52 midi_dev * port = (midi_dev *)data; 53 54 LOG(("mpu401:midi_interrupt_op %x\n",op)); 55 LOG(("port = %p\n", port)); 56 if (op == B_MPU_401_ENABLE_CARD_INT) { 57 /* turn on MPU interrupts */ 58 LOG(("emuxki: B_MPU_401_ENABLE_CARD_INT\n")); 59 status = lock(); 60 emuxki_reg_write_32(&(port->card->config), EMU_INTE, 61 emuxki_reg_read_32(&(port->card->config), EMU_INTE) | EMU_INTE_MIDIRXENABLE ); 62 unlock(status); 63 LOG(("INTE address: %x\n",&port->card->config)); 64 } 65 else if (op == B_MPU_401_DISABLE_CARD_INT) { 66 /* turn off MPU interrupts */ 67 LOG(("emuxki: B_MPU_401_DISABLE_CARD_INT\n")); 68 status = lock(); 69 emuxki_reg_write_32(&port->card->config, EMU_INTE, 70 emuxki_reg_read_32(&port->card->config, EMU_INTE) & ~ EMU_INTE_MIDIRXENABLE); 71 unlock(status); 72 } 73 74 LOG(("midi_interrupt_op() done\n")); 75 } 76 77 static status_t midi_open(const char *name, uint32 flags, void **cookie); 78 static status_t midi_close(void *cookie); 79 static status_t midi_free(void *cookie); 80 static status_t midi_control(void *cookie, uint32 op, void *data, size_t len); 81 static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len); 82 static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len); 83 84 85 device_hooks midi_hooks = { 86 &midi_open, 87 &midi_close, 88 &midi_free, 89 &midi_control, 90 &midi_read, 91 &midi_write, 92 NULL, /* select */ 93 NULL, /* deselect */ 94 NULL, /* readv */ 95 NULL /* writev */ 96 }; 97 98 static status_t 99 midi_open( 100 const char * name, 101 uint32 flags, 102 void ** cookie) 103 { 104 int ix; 105 int ret; 106 107 LOG(("midi_open()\n")); 108 109 *cookie = NULL; 110 for (ix=0; ix<num_cards; ix++) { 111 if (!strcmp(name, cards[ix].midi.name)) { 112 break; 113 } 114 } 115 if (ix >= num_cards) { 116 LOG(("bad device\n")); 117 return ENODEV; 118 } 119 120 LOG(("mpu401: %p open(): %p driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi.driver)); 121 ret = (*mpu401->open_hook)(cards[ix].midi.driver, flags, cookie); 122 if (ret >= B_OK) { 123 cards[ix].midi.cookie = *cookie; 124 atomic_add(&cards[ix].midi.count, 1); 125 } 126 LOG(("mpu401: open returns %x / %p\n", ret, *cookie)); 127 return ret; 128 } 129 130 131 static status_t 132 midi_close( 133 void * cookie) 134 { 135 LOG(("midi_close()\n")); 136 return (*mpu401->close_hook)(cookie); 137 } 138 139 140 static status_t 141 midi_free( 142 void * cookie) 143 { 144 int ix; 145 status_t f; 146 LOG(("midi_free()\n")); 147 f = (*mpu401->free_hook)(cookie); 148 for (ix=0; ix<num_cards; ix++) { 149 if (cards[ix].midi.cookie == cookie) { 150 if (atomic_add(&cards[ix].midi.count, -1) == 1) { 151 cards[ix].midi.cookie = NULL; 152 LOG(("cleared %p card %d\n", cookie, ix)); 153 } 154 break; 155 } 156 } 157 LOG(("midi_free() done\n")); 158 return f; 159 } 160 161 162 static status_t 163 midi_control( 164 void * cookie, 165 uint32 iop, 166 void * data, 167 size_t len) 168 { 169 return (*mpu401->control_hook)(cookie, iop, data, len); 170 } 171 172 173 static status_t 174 midi_read( 175 void * cookie, 176 off_t pos, 177 void * ptr, 178 size_t * nread) 179 { 180 return (*mpu401->read_hook)(cookie, pos, ptr, nread); 181 } 182 183 184 static status_t 185 midi_write( 186 void * cookie, 187 off_t pos, 188 const void * ptr, 189 size_t * nwritten) 190 { 191 return (*mpu401->write_hook)(cookie, pos, ptr, nwritten); 192 } 193 194 195 bool 196 midi_interrupt(emuxki_dev *card) 197 { 198 TRACE(("midi_interrupt\n")); 199 if (!card->midi.driver) { 200 dprintf("aiigh\n"); 201 return false; 202 } 203 204 return (*mpu401->interrupt_hook)(card->midi.driver); 205 } 206 207