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 42extern generic_mpu401_module * mpu401; 43 44void 45midi_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 77static status_t midi_open(const char *name, uint32 flags, void **cookie); 78static status_t midi_close(void *cookie); 79static status_t midi_free(void *cookie); 80static status_t midi_control(void *cookie, uint32 op, void *data, size_t len); 81static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len); 82static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len); 83 84 85device_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 98static status_t 99midi_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 131static status_t 132midi_close( 133 void * cookie) 134{ 135 LOG(("midi_close()\n")); 136 return (*mpu401->close_hook)(cookie); 137} 138 139 140static status_t 141midi_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 162static status_t 163midi_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 173static status_t 174midi_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 184static status_t 185midi_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 195bool 196midi_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