1 /* 2 * Copyright 2004-2015 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Jérôme Duval, jerome.duval@free.fr 7 * Marcus Overhagen, marcus@overhagen.de 8 * Jérôme Lévêque, leveque.jerome@gmail.com 9 */ 10 11 12 #include <midi_driver.h> 13 #include <string.h> 14 #include <stdlib.h> 15 #include <signal.h> 16 17 #include "ice1712.h" 18 #include "ice1712_reg.h" 19 #include "io.h" 20 #include "util.h" 21 #include "debug.h" 22 23 extern generic_mpu401_module * mpu401; 24 extern int32 num_cards; 25 extern ice1712 cards[NUM_CARDS]; 26 27 void ice1712Midi_interrupt(int32 op, void *data); 28 29 30 void 31 ice1712Midi_interrupt(int32 op, void *data) 32 { 33 cpu_status status; 34 uint8 int_status = 0; 35 ice1712Midi *midi = (ice1712Midi*)data; 36 37 if (op == B_MPU_401_ENABLE_CARD_INT) { 38 status = lock(); 39 40 int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK); 41 int_status &= ~(midi->int_mask); 42 write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status); 43 44 ITRACE("B_MPU_401_ENABLE_CARD_INT: %s\n", midi->name); 45 46 unlock(status); 47 } else if (op == B_MPU_401_DISABLE_CARD_INT) { 48 status = lock(); 49 50 int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK); 51 int_status |= midi->int_mask; 52 write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status); 53 54 ITRACE("B_MPU_401_DISABLE_CARD_INT: %s\n", midi->name); 55 56 unlock(status); 57 } 58 59 ITRACE("New mask status 0x%x\n", int_status); 60 } 61 62 63 static status_t 64 ice1712Midi_open(const char *name, uint32 flags, void **cookie) 65 { 66 int midi, card; 67 status_t ret = ENODEV; 68 69 ITRACE("**midi_open()\n"); 70 *cookie = NULL; 71 72 for (card = 0; card < num_cards; card++) { 73 for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) { 74 if (!strcmp(name, cards[card].midiItf[midi].name)) { 75 ice1712Midi *dev = &(cards[card].midiItf[midi]); 76 ret = (*mpu401->open_hook)(dev->mpu401device, flags, cookie); 77 if (ret >= B_OK) { 78 *cookie = dev->mpu401device; 79 } 80 break; 81 } 82 } 83 } 84 85 return ret; 86 } 87 88 89 static status_t 90 ice1712Midi_close(void* cookie) 91 { 92 ITRACE("**midi_close()\n"); 93 return (*mpu401->close_hook)(cookie); 94 } 95 96 97 static status_t 98 ice1712Midi_free(void* cookie) 99 { 100 int midi, card; 101 status_t ret; 102 103 ITRACE("**midi_free()\n"); 104 105 ret = (*mpu401->free_hook)(cookie); 106 107 for (card = 0; card < num_cards; card++) { 108 for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) { 109 if (cookie == cards[card].midiItf[midi].mpu401device) { 110 cards[card].midiItf[midi].mpu401device = NULL; 111 ITRACE("Cleared %p card %d, midi %d\n", cookie, card, midi); 112 break; 113 } 114 } 115 } 116 117 return ret; 118 } 119 120 121 static status_t 122 ice1712Midi_control(void* cookie, 123 uint32 iop, void* data, size_t len) 124 { 125 ITRACE("**midi_control()\n"); 126 return (*mpu401->control_hook)(cookie, iop, data, len); 127 } 128 129 130 static status_t 131 ice1712Midi_read(void * cookie, off_t pos, void * ptr, size_t * nread) 132 { 133 status_t ret = B_ERROR; 134 135 ret = (*mpu401->read_hook)(cookie, pos, ptr, nread); 136 ITRACE_VV("**midi_read: %" B_PRIi32 "\n", ret); 137 138 return ret; 139 } 140 141 142 static status_t 143 ice1712Midi_write(void * cookie, off_t pos, const void * ptr, 144 size_t * nwritten) 145 { 146 status_t ret = B_ERROR; 147 148 ret = (*mpu401->write_hook)(cookie, pos, ptr, nwritten); 149 ITRACE_VV("**midi_write: %" B_PRIi32 "\n", ret); 150 151 return ret; 152 } 153 154 155 device_hooks ice1712Midi_hooks = 156 { 157 ice1712Midi_open, 158 ice1712Midi_close, 159 ice1712Midi_free, 160 ice1712Midi_control, 161 ice1712Midi_read, 162 ice1712Midi_write, 163 NULL, 164 NULL, 165 NULL, 166 NULL 167 }; 168