Hello, more patchs for adding Midi feature. On 2/8/12, SMC.Collins@xxxxxxxxxxx <SMC.Collins@xxxxxxxxxxx> wrote: > Are these patchs suitable for testing ? I can build and report back if you > like. Yes they are, You can send any feedback. Jerome
From f9507ed95003fb22f5d12c49c4a78efd352d1fce Mon Sep 17 00:00:00 2001 From: Jerome Leveque <leveque.jerome@xxxxxxxxx> Date: Fri, 27 Jan 2012 20:09:35 +0000 Subject: [PATCH] Generic MPU401 driver: Add Ice1712 card, Fix line size > 80 --- src/add-ons/kernel/generic/mpu401/mpu401.c | 303 +++++++++++++++++----------- 1 files changed, 180 insertions(+), 123 deletions(-) diff --git a/src/add-ons/kernel/generic/mpu401/mpu401.c b/src/add-ons/kernel/generic/mpu401/mpu401.c index d7c03a0..953c33d 100644 --- a/src/add-ons/kernel/generic/mpu401/mpu401.c +++ b/src/add-ons/kernel/generic/mpu401/mpu401.c @@ -21,14 +21,15 @@ #include "mpu401_priv.h" /* ---------- - midi_create_device - + midi_create_device - ----- */ /*-----------------------------*/ /* Version 1 of mpu401 module */ /*-----------------------------*/ -static status_t -create_device(int port, void ** out_storage, uint32 workarounds, void (*interrupt_op)(int32 op, void * card), void * card) +static status_t +create_device(int port, void ** out_storage, uint32 workarounds, + void (*interrupt_op)(int32 op, void * card), void * card) { mpu401device mpu_device; mpu401device *mpuptr; @@ -39,50 +40,52 @@ create_device(int port, void ** out_storage, uint32 workarounds, void (*interrup mpu_device.V2 = FALSE; mpu_device.count = 1; mpu_device.interrupt_op = interrupt_op; - mpu_device.card = card; + mpu_device.card = card; - LOG(("create_device count= %ld, addrport 0x%x, workarounds: %d",mpu_device.count, mpu_device.addrport, mpu_device.workarounds)); + LOG(("create_device count= %ld, addrport 0x%x, workarounds: %d", + mpu_device.count, mpu_device.addrport, mpu_device.workarounds)); - // basically, each call to create device allocates memory for - //a structure with the specific device info. The pointer to this is + // basically, each call to create device allocates memory for + //a structure with the specific device info. The pointer to this is // returned back to calling driver mpuptr = (mpu401device*)malloc (sizeof(mpu401device)); memcpy(mpuptr, &mpu_device, sizeof(mpu_device)); *out_storage = (void *)mpuptr; - + return B_OK; } /*-----------------------------*/ /* Version 2 of mpu401 module */ /*-----------------------------*/ -static status_t -create_device_v2(int port, void ** out_storage, uint32 workarounds, void (*interrupt_op)(int32 op, void * card), void * card) +static status_t +create_device_v2(int port, void ** out_storage, uint32 workarounds, + void (*interrupt_op)(int32 op, void * card), void * card) { mpu401device *mpuptr; mpu401device mpu_device; - LOG(("v2: create_device, **out_storage %p ,workarounds %ld ,void *card %p\n",out_storage, workarounds, card)); - - // not sure exactly how v2 of the module works. I think that two ports are - // created. One for midi in data, and another for midi out data. + // not sure exactly how v2 of the module works. I think that two ports + // are created. One for midi in data, and another for midi out data. // Instead of transfering data using a buffer and pointer, the midi // data is transfered via the global ports. - // If the ports are created in the midi server, then the port id's + // If the ports are created in the midi server, then the port id's // should be known in this hook call. - // If the ports are created in this hook call, the the port id's + // If the ports are created in this hook call, the the port id's // should be returned to the midi server. - // One version of read/write hook functions are used for both v1, v2. Therefore, in - // those calls, it needs to be known whether the mididata is to be read/written - // to a buffer, or to the port. + // One version of read/write hook functions are used for both v1, v2. + // Therefore, in those calls, it needs to be known whether the mididata + // is to be read/written to a buffer, or to the port. mpu_device.addrport = port; mpu_device.workarounds = workarounds; - mpu_device.V2 = TRUE; - mpu_device.count =1; - mpu_device.card = card; + mpu_device.V2 = TRUE; + mpu_device.count =1; + mpu_device.card = card; + LOG(("create_device count= %ld, addrport 0x%x, workarounds: %d", + mpu_device.count, mpu_device.addrport, mpu_device.workarounds)); mpuptr = (mpu401device*)malloc(sizeof(mpu401device)); memcpy(mpuptr, &mpu_device, sizeof(mpu_device)); @@ -93,18 +96,19 @@ create_device_v2(int port, void ** out_storage, uint32 workarounds, void (*inter /* ---------- - midi_delete_device + midi_delete_device ----- */ -static status_t +static status_t delete_device(void * storage) -{ +{ mpu401device * mpu_device = (mpu401device *)storage; - LOG(("device->addrport= 0x%x count= %ld\n",mpu_device->addrport, mpu_device->count)); - LOG(("delete_device: *storage:%p\n",storage)); + LOG(("device->addrport= 0x%x count= %ld\n", + mpu_device->addrport, mpu_device->count)); + LOG(("delete_device: *storage:%p\n", storage)); + + free(mpu_device); // free the memory allocated in create_device - free(mpu_device); // free the memory allocated in create_device - return B_OK; } @@ -112,78 +116,106 @@ delete_device(void * storage) midi_open - handle open() calls ----- */ -static status_t +static status_t midi_open(void * storage, uint32 flags, void ** out_cookie) { char semname[25]; - int ack_byte; + int ack_byte; mpu401device * mpu_device = (mpu401device *)storage; - LOG(("open() flags: %ld, * storage: %p, **out_cookie: %p\n",flags, storage,out_cookie)); - LOG(("open: device->addrport 0x%x ,workarounds 0x%x\n",mpu_device->addrport, mpu_device->workarounds)); + LOG(("open() flags: %ld, *storage: %p, **out_cookie: %p\n", flags, + storage, out_cookie)); + LOG(("open: device->addrport 0x%x ,workarounds 0x%x\n", + mpu_device->addrport, mpu_device->workarounds)); // the undocumented V2 module is not complete // we will allow the device to be created since some drivers depend on it // but will return an error if the actual midi device is opened: if ( mpu_device->V2 == TRUE) return B_ERROR; - + switch (mpu_device->workarounds){ - case 0x11020004: // This is still required for Creative Audigy, Audidy2 + case 0x11020004: // Still required for Creative Audigy, Audigy2 case 0x11020005: case 0: // don't know the current mpu state PRINT(("reset MPU401\n")); - Write_MPU401(mpu_device->addrport, UARTCMD, mpu_device->workarounds, MPU401_RESET); + Write_MPU401(mpu_device->addrport, UARTCMD, + mpu_device->workarounds, MPU401_RESET); snooze(30000); - Write_MPU401(mpu_device->addrport, UARTCMD, mpu_device->workarounds, MPU401_RESET); + Write_MPU401(mpu_device->addrport, UARTCMD, + mpu_device->workarounds, MPU401_RESET); snooze(30000); - ack_byte = Read_MPU401(mpu_device->addrport, UARTDATA, mpu_device->workarounds); + ack_byte = Read_MPU401(mpu_device->addrport, UARTDATA, + mpu_device->workarounds); PRINT(("enable UART mode\n")); - Write_MPU401(mpu_device->addrport, UARTCMD, mpu_device->workarounds, MPU401_UART); + Write_MPU401(mpu_device->addrport, UARTCMD, + mpu_device->workarounds, MPU401_UART); snooze(30000); - ack_byte = Read_MPU401(mpu_device->addrport, UARTDATA, mpu_device->workarounds ); + ack_byte = Read_MPU401(mpu_device->addrport, UARTDATA, + mpu_device->workarounds ); PRINT(("port cmd ack is 0x%x\n", ack_byte)); *out_cookie = mpu_device; break; + case 0x14121712: + PRINT(("reset MPU401\n")); + Write_MPU401(mpu_device->addrport, UARTDATA, + mpu_device->workarounds, 0x00); + snooze(30000); + Write_MPU401(mpu_device->addrport, UARTCMD, + mpu_device->workarounds, MPU401_RESET); + snooze(30000); + ack_byte = Read_MPU401(mpu_device->addrport, UARTDATA, + mpu_device->workarounds); + PRINT(("enable UART mode\n")); + Write_MPU401(mpu_device->addrport, UARTDATA, + mpu_device->workarounds, 0x00); + snooze(30000); + Write_MPU401(mpu_device->addrport, UARTCMD, + mpu_device->workarounds, MPU401_UART); + snooze(30000); + ack_byte = Read_MPU401(mpu_device->addrport, UARTDATA, + mpu_device->workarounds ); + PRINT(("port cmd ack is 0x%x\n", ack_byte)); + break; case 1: - // Some devices are always in UART mode + // Some devices are always in UART mode PRINT(("already in UART mode\n")); break; default: - PRINT(("Unknown workaround value: %d\n", mpu_device->workarounds)); + PRINT(("Unknown workaround: %d\n", mpu_device->workarounds)); break; } //end switch // Create Read semaphore for midi-in data sprintf(semname, "mpu401:%04x:read_sem", mpu_device->addrport); mpu_device->readsemaphore = create_sem(0, semname); - + // Create Write semaphore for midi-out data sprintf(semname,"mpu401:%04x:write_sem", mpu_device->addrport); mpu_device->writesemaphore = create_sem(1, semname); - + // clear midi-in buffer - mbuf_bytes=0; + mbuf_bytes=0; mbuf_current=0; mbuf_start=0; //Enable midi interrupts - mpu_device->interrupt_op(B_MPU_401_ENABLE_CARD_INT, mpu_device->card ); - + mpu_device->interrupt_op(B_MPU_401_ENABLE_CARD_INT, mpu_device->card); + if ((mpu_device->readsemaphore > B_OK) && (mpu_device->writesemaphore > B_OK)) { atomic_add(&mpu_device->count, 1); PRINT(("midi_open() done (count = %x)\n", open_count)); return B_OK; - } + } return B_ERROR; } /* ---------- midi_close - handle close() calls ----- */ -static status_t +static status_t midi_close(void * cookie) { mpu401device * mpu_device = (mpu401device *)cookie; @@ -192,13 +224,13 @@ midi_close(void * cookie) return B_ERROR; //Disable soundcard midi interrupts - mpu_device->interrupt_op(B_MPU_401_DISABLE_CARD_INT, mpu_device->card ); + mpu_device->interrupt_op(B_MPU_401_DISABLE_CARD_INT, mpu_device->card); // Delete the semaphores delete_sem(mpu_device->readsemaphore); delete_sem(mpu_device->writesemaphore); - atomic_add(&mpu_device->count, -1); + atomic_add(&mpu_device->count, -1); PRINT(("midi_close() done (count = %lu)\n", mpu_device->count)); return B_OK; @@ -207,7 +239,7 @@ midi_close(void * cookie) /* ---------- midi_free - free up allocated memory ----- */ -static status_t +static status_t midi_free(void * cookie) { LOG(("midi_free()\n")); @@ -217,7 +249,7 @@ midi_free(void * cookie) /* ---------- midi_control - handle control() calls ----- */ -static status_t +static status_t midi_control(void * cookie, uint32 op, void * data, size_t len) { //mpu401device *mpu_device = (mpu401device *)cookie; @@ -231,13 +263,13 @@ midi_control(void * cookie, uint32 op, void * data, size_t len) /* ---------- midi_read - handle read() calls ----- */ -static status_t +static status_t midi_read(void *cookie, off_t pos, void *buffer, size_t *num_bytes) { /* The actual midi data is read from the device in the interrupt handler; this reads and returns the data from a buffer */ - unsigned char *data; + unsigned char *data; unsigned int i; size_t count; cpu_status status; @@ -249,29 +281,29 @@ midi_read(void *cookie, off_t pos, void *buffer, size_t *num_bytes) i=0; *num_bytes=0; - bestat = acquire_sem_etc ( mpu_device->readsemaphore, 1, B_CAN_INTERRUPT, 0); + bestat = acquire_sem_etc(mpu_device->readsemaphore, 1, + B_CAN_INTERRUPT, 0); if (bestat == B_INTERRUPTED) { //PRINT(("acquire_sem B_INTERRUPTED!\n")); - return B_INTERRUPTED; + return B_INTERRUPTED; } if (bestat != B_OK) { TRACE(("acquire_sem not B_OK %d\n",(int)bestat)); *num_bytes = 1; - return B_INTERRUPTED; - } - if (bestat == B_OK) { + return B_INTERRUPTED; + } else { status = lock(); *(data+i) = mpubuffer[mbuf_start]; i++; - mbuf_start++; // pointer to data in ringbuffer + mbuf_start++; // pointer to data in ringbuffer if (mbuf_start >= (MBUF_ELEMENTS-1)) - mbuf_start = 0; //wraparound of ringbuffer - *num_bytes =1; // tell caller how many bytes are being returned in buffer + mbuf_start = 0; //wraparound of ringbuffer + *num_bytes =1; // How many bytes are being returned in buffer if (mbuf_bytes>0) - mbuf_bytes--; // bytes read from buffer, so decrement buffer count + mbuf_bytes--; // bytes read from buffer, so decrement buffer count unlock(status); //PRINT(("bytes in buffer: %d\n",mbuf_bytes)); - } + } return B_OK; } @@ -279,7 +311,7 @@ midi_read(void *cookie, off_t pos, void *buffer, size_t *num_bytes) /* ---------- midi_write - handle write() calls ----- */ -static status_t +static status_t midi_write(void * cookie, off_t pos, const void * data, size_t * num_bytes) { unsigned char *bufdata; @@ -287,71 +319,83 @@ midi_write(void * cookie, off_t pos, const void * data, size_t * num_bytes) size_t count; mpu401device *mpu_device = (mpu401device *)cookie; - bufdata = (unsigned char*)data; /* Pointer to midi data buffer */ + bufdata = (unsigned char*)data; /* Pointer to midi data buffer */ count = *num_bytes; - + /* Only for deep debugging..will slow things down */ - //PRINT(("write %d bytes, addrport 0x%x, workarounds 0x%x\n",(int)count,mpu_device->addrport, mpu_device->workarounds)); + /*PRINT(("write %d bytes, addrport 0x%x, workarounds 0x%x\n", + (int)count, mpu_device->addrport, mpu_device->workarounds));*/ acquire_sem(mpu_device->writesemaphore); for (i=0; i<count; i++) { // wait until device is ready - while ((Read_MPU401(mpu_device->addrport, UARTCMD, mpu_device->workarounds) & MPU401_OK2WR)); - Write_MPU401(mpu_device->addrport, UARTDATA, mpu_device->workarounds, *(bufdata+i)); - } + while ((Read_MPU401(mpu_device->addrport, UARTCMD, + mpu_device->workarounds) & MPU401_OK2WR)); - *num_bytes = 0; + Write_MPU401(mpu_device->addrport, UARTDATA, + mpu_device->workarounds, *(bufdata+i)); + } + + *num_bytes = 0; release_sem(mpu_device->writesemaphore); return B_OK; } /* ---------- - interrupt_hook - handle interrupts for mpu401 data + interrupt_hook - handle interrupts for mpu401 data ----- */ -static bool +static bool interrupt_hook(void * cookie) { status_t bestat; mpu401device *mpu_device = (mpu401device *)cookie; - - //PRINT(("irq! port: 0x%x\n",mpu_device->addrport)); /* Only for deep debugging..will slow things down */ - - /* Input data is available when bit 7 of the Status port is zero. Conversely, when bit 7 is - is a one, no MIDI data is available. Reading from the data port will often clear the - interrupt signal depending on the sound card. */ - - if ((Read_MPU401(mpu_device->addrport, UARTCMD, mpu_device->workarounds) & MPU401_OK2RD) == 0) { + + /* Only for deep debugging..will slow things down */ + //PRINT(("irq! port: 0x%x\n",mpu_device->addrport)); + + /* Input data is available when bit 7 of the Status port is zero. + Conversely, when bit 7 is is a one, no MIDI data is available. + Reading from the data port will often clear the interrupt signal + depending on the sound card. */ + + if ((Read_MPU401(mpu_device->addrport, UARTCMD, + mpu_device->workarounds) & MPU401_OK2RD) == 0) { /* Okay, midi data waiting to be read from device */ if (mbuf_current >= (MBUF_ELEMENTS-1)) mbuf_current = 0; - - mpubuffer[mbuf_current] = Read_MPU401(mpu_device->addrport, - UARTDATA, mpu_device->workarounds); /* store midi data byte into buffer */ - mbuf_current++; /* pointer to next blank byte */ - mbuf_bytes++; /* increment count of midi data bytes */ - - bestat = release_sem_etc(mpu_device->readsemaphore, 1, B_DO_NOT_RESCHEDULE); - - return TRUE; //B_INVOKE_SCHEDULER - } + + /* store midi data byte into buffer */ + mpubuffer[mbuf_current] = Read_MPU401(mpu_device->addrport, + UARTDATA, mpu_device->workarounds); + mbuf_current++; /* pointer to next blank byte */ + mbuf_bytes++; /* increment count of midi data bytes */ + + bestat = release_sem_etc(mpu_device->readsemaphore, 1, + B_DO_NOT_RESCHEDULE); + + return TRUE; //B_INVOKE_SCHEDULER + } + /* No midi data from this interrupt */ - return FALSE; //B_UNHANDLED_INTERRUPT + return FALSE; //B_UNHANDLED_INTERRUPT } /*-----------------------------------------------------------------*/ -uchar -Read_MPU401(unsigned int addrport, const char cmdtype, unsigned int workarounds) +uchar +Read_MPU401(unsigned int addrport, const char cmdtype, + unsigned int workarounds) { uchar mpudatabyte; cpu_status status; unsigned int regptr; - - //PRINT(("read workaround 0x%x\n",workarounds)); /* Only for deep debugging..will slow things down */ + + /* Only for deep debugging..will slow things down */ + //PRINT(("read workaround 0x%x\n",workarounds)); switch (workarounds) { case 0x11020004: /* Creative Audigy Gameport */ regptr = (((I_MPU1 + cmdtype) << 16) & PTR_ADDRESS_MASK); - status = lock(); + status = lock(); gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA or CMD */ mpudatabyte = gPCI->read_io_32(addrport + D_DATA); unlock(status); @@ -359,42 +403,55 @@ Read_MPU401(unsigned int addrport, const char cmdtype, unsigned int workarounds) case 0x11020005: /* Creative Audigy LiveDrive */ regptr = (((I_MPU2 + cmdtype) << 16) & PTR_ADDRESS_MASK); - status = lock(); + status = lock(); gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA2 or CMD2 */ mpudatabyte = gPCI->read_io_32(addrport + D_DATA); unlock(status); break; + case 0x14121712: + status = lock(); + mpudatabyte = gPCI->read_io_8(addrport + cmdtype); + unlock(status); + break; + default: - mpudatabyte = gISA->read_io_8(addrport + cmdtype ); + mpudatabyte = gISA->read_io_8(addrport + cmdtype); break; } - return mpudatabyte; + return mpudatabyte; } -status_t -Write_MPU401(unsigned int addrport, const char cmdtype, unsigned int workarounds, uchar mpudatabyte ) +status_t +Write_MPU401(unsigned int addrport, const char cmdtype, + unsigned int workarounds, uchar mpudatabyte) { cpu_status status; unsigned int regptr; - + /* Only for deep debugging..will slow things down */ - //PRINT(("write workaround 0x%x at addr: 0x%x\n",workarounds,addrport)); + //PRINT(("write workaround 0x%x at addr: 0x%x\n",workarounds,addrport)); switch (workarounds) { - case 0x11020004: /* Creative Audigy Gameport */ + case 0x11020004: /* Creative Audigy Gameport */ regptr = (((I_MPU1 + cmdtype ) << 16) & PTR_ADDRESS_MASK); - status = lock(); - gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA or CMD */ - gPCI->write_io_32(addrport + D_DATA, mpudatabyte ); + status = lock(); + gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA or CMD */ + gPCI->write_io_32(addrport + D_DATA, mpudatabyte ); unlock(status); break; - case 0x11020005: /* Creative Audigy LiveDrive */ + case 0x11020005: /* Creative Audigy LiveDrive */ regptr = (((I_MPU2 + cmdtype ) << 16) & PTR_ADDRESS_MASK); - status = lock(); - gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA2 or CMD2 */ - gPCI->write_io_32(addrport + D_DATA, mpudatabyte ); + status = lock(); + gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA2 or CMD2 */ + gPCI->write_io_32(addrport + D_DATA, mpudatabyte ); + unlock(status); + break; + + case 0x14121712: + status = lock(); + gPCI->write_io_8(addrport + cmdtype, mpudatabyte); unlock(status); break; @@ -402,7 +459,7 @@ Write_MPU401(unsigned int addrport, const char cmdtype, unsigned int workarounds gISA->write_io_8(addrport + cmdtype, mpudatabyte); break; } - return B_OK; + return B_OK; } @@ -412,7 +469,7 @@ static status_t std_ops(int32 op, ...) { switch(op) { - + case B_MODULE_INIT: LOG_CREATE(); @@ -423,19 +480,19 @@ std_ops(int32 op, ...) if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI) < B_OK) return B_ERROR; return B_OK; - + case B_MODULE_UNINIT: put_module(B_ISA_MODULE_NAME); put_module(B_PCI_MODULE_NAME); PRINT(("B_MODULE_UNINIT\n")); return B_OK; - + default: return B_ERROR; } } -static generic_mpu401_module mpu401_module = +static generic_mpu401_module mpu401_module = { { B_MPU_401_MODULE_NAME, @@ -453,8 +510,8 @@ static generic_mpu401_module mpu401_module = interrupt_hook }; -// Module v2 seems to be undocumented -static generic_mpu401_module mpu401_module2 = +// Module v2 seems to be undocumented +static generic_mpu401_module mpu401_module2 = { { "generic/mpu401/v2", @@ -480,7 +537,7 @@ _EXPORT generic_mpu401_module *modules[] = }; spinlock locked = B_SPINLOCK_INITIALIZER; -cpu_status +cpu_status lock(void) { cpu_status status = disable_interrupts(); @@ -488,7 +545,7 @@ lock(void) return status; } -void +void unlock(cpu_status status) { release_spinlock(&locked); -- 1.7.7.2
From 5ee61a3a8205e622d5a94f2c4a2c90dac4ea030f Mon Sep 17 00:00:00 2001 From: Jerome Leveque <leveque.jerome@xxxxxxxxx> Date: Fri, 27 Jan 2012 20:10:35 +0000 Subject: [PATCH] Ice1712 drivers: Add Midi drivers --- src/add-ons/kernel/drivers/audio/ice1712/debug.h | 4 +- src/add-ons/kernel/drivers/audio/ice1712/ice1712.c | 128 ++++++++----- src/add-ons/kernel/drivers/audio/ice1712/ice1712.h | 30 +++- src/add-ons/kernel/drivers/audio/ice1712/midi.c | 205 ++++++++------------ 4 files changed, 192 insertions(+), 175 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/ice1712/debug.h b/src/add-ons/kernel/drivers/audio/ice1712/debug.h index a856466..ed98501 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/debug.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/debug.h @@ -15,8 +15,8 @@ # undef TRACE #endif -#define TRACE_MULTI_AUDIO -#ifdef TRACE_MULTI_AUDIO +//#define ICE1712_VERBOSE +#ifdef ICE1712_VERBOSE # define TRACE(a...) dprintf("\33[34mice1712:\33[0m " a) #else # define TRACE(a...) ; diff --git a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c index b628d74..d1f057e 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c @@ -55,7 +55,7 @@ init_hardware(void) pci_info info; memset(cards, 0, sizeof(ice1712) * NUM_CARDS); - TRACE("ice1712: init_hardware()\n"); + TRACE("@@init_hardware()\n"); if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci)) return ENOSYS; @@ -82,7 +82,7 @@ ice_1712_int(void *arg) uint16 reg16 = 0; uint32 status = B_UNHANDLED_INTERRUPT; -// interrupt from DMA PATH + // interrupt from DMA PATH reg8 = read_mt_uint8(ice, MT_DMA_INT_MASK_STATUS); if (reg8 != 0) { ice->buffer++; @@ -94,14 +94,33 @@ ice_1712_int(void *arg) status = B_HANDLED_INTERRUPT; } -// interrupt from Controller Registers + // interrupt from Controller Registers reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_STATUS); if (reg8 != 0) { - write_ccs_uint8(ice, CCS_INTERRUPT_STATUS, reg8); - status = B_HANDLED_INTERRUPT; + bool ret; + if (reg8 & CCS_INTERRUPT_MIDI_1) { + ret = (*mpu401->interrupt_hook)(ice->midi_interf[0].mpu401device); + if (ret) { + //Do not ack, cause more datas are available + reg8 &= ~CCS_INTERRUPT_MIDI_1; + } + } + + if (reg8 & CCS_INTERRUPT_MIDI_2) { + ret = (*mpu401->interrupt_hook)(ice->midi_interf[1].mpu401device); + if (ret) { + //Do not ack, cause more datas are available + reg8 &= ~CCS_INTERRUPT_MIDI_2; + } + } + + if (reg8 != 0) { + write_ccs_uint8(ice, CCS_INTERRUPT_STATUS, reg8); + status = B_HANDLED_INTERRUPT; + } } -// interrupt from DS PATH + // interrupt from DS PATH reg16 = read_ds_uint16(ice, DS_DMA_INT_STATUS); if (reg16 != 0) { //Ack interrupt @@ -117,7 +136,6 @@ static status_t ice1712_setup(ice1712 *ice) { int result, i; - status_t status = B_OK; uint8 reg8 = 0; uint16 mute; @@ -205,10 +223,34 @@ ice1712_setup(ice1712 *ice) reg8 >>= 1; ice->config.nb_MPU401 = (reg8 & 0x1) + 1; - for (i = 0; i < ice->config.nb_MPU401; i++) { - sprintf(ice->midi_interf[i].name, "midi/ice1712/%ld/%d", - ice - cards + 1, i + 1); - names[num_names++] = ice->midi_interf[i].name; + if (ice->config.nb_MPU401 > 0) { + sprintf(ice->midi_interf[0].name, "midi/ice1712/%ld/1", + ice - cards + 1); + + (*mpu401->create_device)(ice->Controller + CCS_MIDI_1_DATA, + &ice->midi_interf[0].mpu401device, + 0x14121712, + ice_1712_midi_interrupt_op, + &ice->midi_interf[0]); + + names[num_names++] = ice->midi_interf[0].name; + ice->midi_interf[0].card = ice; + ice->midi_interf[0].int_mask = CCS_INTERRUPT_MIDI_1; + } + + if (ice->config.nb_MPU401 > 1) { + sprintf(ice->midi_interf[1].name, "midi/ice1712/%ld/2", + ice - cards + 1); + + (*mpu401->create_device)(ice->Controller + CCS_MIDI_2_DATA, + &ice->midi_interf[1].mpu401device, + 0x14121712, + ice_1712_midi_interrupt_op, + &ice->midi_interf[1]); + + names[num_names++] = ice->midi_interf[1].name; + ice->midi_interf[1].card = ice; + ice->midi_interf[1].int_mask = CCS_INTERRUPT_MIDI_2; } TRACE("E2PROM_MAP_SPDIF : 0x%x\n", ice->eeprom_data[E2PROM_MAP_SPDIF]); @@ -259,11 +301,7 @@ ice1712_setup(ice1712 *ice) } // TRACE("installing interrupt : %0x\n", ice->irq); - status = install_io_interrupt_handler(ice->irq, ice_1712_int, ice, 0); - if (status == B_OK) - TRACE("Install Interrupt Handler == B_OK\n"); - else - TRACE("Install Interrupt Handler != B_OK\n"); + install_io_interrupt_handler(ice->irq, ice_1712_int, ice, 0); ice->mem_id_pb = alloc_mem(&ice->phys_addr_pb, &ice->log_addr_pb, PLAYBACK_BUFFER_TOTAL_SIZE, @@ -333,7 +371,7 @@ ice1712_setup(ice1712 *ice) reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_MASK); TRACE("-----CCS----- = %x\n", reg8); - write_ccs_uint8(ice, CCS_INTERRUPT_MASK, 0x6F); + write_ccs_uint8(ice, CCS_INTERRUPT_MASK, 0xEF); /* reg16 = read_ds_uint16(ice, DS_DMA_INT_MASK); TRACE("-----DS_DMA----- = %x\n", reg16); @@ -354,7 +392,7 @@ init_driver(void) status_t err; num_cards = 0; - TRACE("ice1712: init_driver()\n"); + TRACE("@@init_driver()\n"); if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci)) return ENOSYS; @@ -413,15 +451,9 @@ init_driver(void) static void ice_1712_shutdown(ice1712 *ice) { - status_t result; - delete_sem(ice->buffer_ready_sem); - result = remove_io_interrupt_handler(ice->irq, ice_1712_int, ice); - if (result == B_OK) - TRACE("remove Interrupt result == B_OK\n"); - else - TRACE("remove Interrupt result != B_OK\n"); + remove_io_interrupt_handler(ice->irq, ice_1712_int, ice); if (ice->mem_id_pb != B_ERROR) delete_area(ice->mem_id_pb); @@ -438,7 +470,7 @@ uninit_driver(void) { int ix, cnt = num_cards; - TRACE("===uninit_driver()===\n"); + TRACE("@@uninit_driver()\n"); num_cards = 0; @@ -458,7 +490,7 @@ const char ** publish_devices(void) { int ix = 0; - TRACE("===publish_devices()===\n"); + TRACE("@@publish_devices()\n"); for (ix=0; names[ix]; ix++) { TRACE("publish %s\n", names[ix]); @@ -472,7 +504,7 @@ ice_1712_open(const char *name, uint32 flags, void **cookie) { int ix; ice1712 *card = NULL; - TRACE("===open()===\n"); + TRACE("**open()\n"); for (ix=0; ix<num_cards; ix++) { if (!strcmp(cards[ix].name, name)) { @@ -495,7 +527,7 @@ ice_1712_open(const char *name, uint32 flags, void **cookie) static status_t ice_1712_close(void *cookie) { - TRACE("===close()===\n"); + TRACE("**close()\n"); return B_OK; } @@ -503,7 +535,7 @@ ice_1712_close(void *cookie) static status_t ice_1712_free(void *cookie) { - TRACE("===free()===\n"); + TRACE("**free()\n"); return B_OK; } @@ -613,7 +645,7 @@ ice_1712_control(void *cookie, uint32 op, void *arg, size_t len) static status_t ice_1712_read(void *cookie, off_t position, void *buf, size_t *num_bytes) { - TRACE("===read()===\n"); + TRACE("**read()\n"); *num_bytes = 0; return B_IO_ERROR; } @@ -623,7 +655,7 @@ static status_t ice_1712_write(void *cookie, off_t position, const void *buffer, size_t *num_bytes) { - TRACE("===write()===\n"); + TRACE("**write()\n"); *num_bytes = 0; return B_IO_ERROR; } @@ -643,40 +675,42 @@ device_hooks ice1712_hooks = NULL }; -/* -device_hooks ice1712Midi_hooks = + +device_hooks ice1712_midi_hooks = { - ice1712Midi_open, - ice1712Midi_close, - ice1712Midi_free, - ice1712Midi_control, - ice1712Midi_read, - ice1712Midi_write, + ice_1712_midi_open, + ice_1712_midi_close, + ice_1712_midi_free, + ice_1712_midi_control, + ice_1712_midi_read, + ice_1712_midi_write, NULL, NULL, NULL, NULL }; -*/ + device_hooks * find_device(const char * name) { - int ix; + int ix, midi; - TRACE("ice1712: find_device(%s)\n", name); + TRACE("**find_device(%s)\n", name); for (ix=0; ix < num_cards; ix++) { -/* if (!strcmp(cards[ix].midi.name, name)) { - return &midi_hooks; - }*/ + for (midi = 0; midi < MAX_MIDI_INTERFACE; midi++) { + if (!strcmp(cards[ix].midi_interf[midi].name, name)) { + return &ice1712_midi_hooks; + } + } if (!strcmp(cards[ix].name, name)) { return &ice1712_hooks; } } - TRACE("ice1712: find_device(%s) failed\n", name); + TRACE("!!! failed !!!\n"); return NULL; } diff --git a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h index e29c5e3..7212255 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h @@ -35,6 +35,7 @@ typedef enum product_t { #define NUM_CARDS 4 #define MAX_ADC 12 // + the output of the Digital mixer #define MAX_DAC 10 +#define MAX_MIDI_INTERFACE 2 #define SWAPPING_BUFFERS 2 #define SAMPLE_SIZE 4 #define MIN_BUFFER_FRAMES 64 @@ -62,14 +63,27 @@ typedef enum product_t { #define ICE1712_SAMPLERATE_88K2 0xB #define ICE1712_SAMPLERATE_44K1 0x8 +struct ice1712; + typedef struct _midi_dev { - struct _ice1712_ *card; - void *driver; - void *cookie; - int32 count; - char name[64]; + struct ice1712 *card; + void *mpu401device; + uint8 int_mask; + char name[64]; } midi_dev; +void ice_1712_midi_interrupt_op(int32 op, void *data); +status_t ice_1712_midi_open(const char *name, + uint32 flags, void **cookie); +status_t ice_1712_midi_close(void *cookie); +status_t ice_1712_midi_free(void *cookie); +status_t ice_1712_midi_control(void *cookie, + uint32 op, void *data, size_t len); +status_t ice_1712_midi_read(void *cookie, + off_t pos, void *data, size_t *len); +status_t ice_1712_midi_write(void *cookie, + off_t pos, const void *data, size_t *len); + typedef struct _codecCommLines { uint8 clock; @@ -120,7 +134,7 @@ typedef struct ice1712 pci_info info; char name[128]; - midi_dev midi_interf[2]; + midi_dev midi_interf[MAX_MIDI_INTERFACE]; uint32 Controller; //PCI_10 uint32 DDMA; //PCI_14 @@ -165,6 +179,10 @@ status_t apply_settings(ice1712 *card); extern int32 num_cards; extern ice1712 cards[NUM_CARDS]; +//CSS_INTERRUPT_MASK +#define CCS_INTERRUPT_MIDI_1 0x80 +#define CCS_INTERRUPT_MIDI_2 0x20 + //??????? #define GPIO_SPDIF_STATUS 0x02 //Status #define GPIO_SPDIF_CCLK 0x04 //data Clock diff --git a/src/add-ons/kernel/drivers/audio/ice1712/midi.c b/src/add-ons/kernel/drivers/audio/ice1712/midi.c index ac8cd7b..ddc1ec7 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/midi.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/midi.c @@ -12,172 +12,137 @@ #include <string.h> #include <stdlib.h> #include <signal.h> +#include <midi_driver.h> #include "ice1712.h" +#include "ice1712_reg.h" #include "io.h" -#include "midi_driver.h" #include "util.h" - #include "debug.h" extern generic_mpu401_module * mpu401; -void midi_interrupt_op(int32 op, void * data) + +void +ice_1712_midi_interrupt_op(int32 op, void *data) { -// midi_dev * port = (midi_dev *)data; - if (op == B_MPU_401_ENABLE_CARD_INT) - { - // sample code - cpu_status cp; -// ddprintf(("sonic_vibes: B_MPU_401_ENABLE_CARD_INT\n")); - cp = disable_interrupts(); -// acquire_spinlock(&port->card->hardware); -// increment_interrupt_handler(port->card); -// set_direct(port->card, 0x01, 0x00, 0x80); -// set_indirect(port->card, 0x2A, 0x04, 0xff); -// release_spinlock(&port->card->hardware); - restore_interrupts(cp); - - //real code - cp = lock(); -// emuxki_reg_write_32(&(port->card->config), EMU_INTE, -// emuxki_reg_read_32(&(port->card->config), EMU_INTE) | -// EMU_INTE_MIDITXENABLE | EMU_INTE_MIDIRXENABLE ); - unlock(cp); - } - else if (op == B_MPU_401_DISABLE_CARD_INT) - { - // sample code - /* turn off MPU interrupts */ - cpu_status cp; -// ddprintf(("sonic_vibes: B_MPU_401_DISABLE_CARD_INT\n")); - cp = disable_interrupts(); -// acquire_spinlock(&port->card->hardware); -// set_direct(port->card, 0x01, 0x80, 0x80);*/ - /* remove interrupt handler if necessary */ -// decrement_interrupt_handler(port->card); -// release_spinlock(&port->card->hardware); - restore_interrupts(cp); - - //real code -// cpu_status status; - cp = lock(); -// emuxki_reg_write_32(&port->card->config, EMU_INTE, -// emuxki_reg_read_32(&port->card->config, EMU_INTE) & -// ~ (EMU_INTE_MIDITXENABLE | EMU_INTE_MIDIRXENABLE ) ); - unlock(cp); + cpu_status status; + uint8 int_status = 0; + midi_dev *midi = (midi_dev *)data; + + if (op == B_MPU_401_ENABLE_CARD_INT) { + status = lock(); + + int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK); + int_status &= ~(midi->int_mask); + write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status); + + TRACE("B_MPU_401_ENABLE_CARD_INT: %s\n", midi->name); + + unlock(status); + } else if (op == B_MPU_401_DISABLE_CARD_INT) { + status = lock(); + + int_status = read_ccs_uint8(midi->card, CCS_INTERRUPT_MASK); + int_status |= midi->int_mask; + write_ccs_uint8(midi->card, CCS_INTERRUPT_MASK, int_status); + + TRACE("B_MPU_401_DISABLE_CARD_INT: %s\n", midi->name); + + unlock(status); } + + TRACE("New mask status 0x%x\n", int_status); } -static status_t midi_open(const char *name, uint32 flags, void **cookie); -static status_t midi_close(void *cookie); -static status_t midi_free(void *cookie); -static status_t midi_control(void *cookie, uint32 op, void *data, size_t len); -static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len); -static status_t midi_write(void *cookie, off_t pos, const void *data, - size_t *len); - -device_hooks midi_hooks = { - &midi_open, - &midi_close, - &midi_free, - &midi_control, - &midi_read, - &midi_write, - NULL, /* select */ - NULL, /* deselect */ - NULL, /* readv */ - NULL /* writev */ -}; - -static status_t midi_open(const char * name, uint32 flags, void ** cookie) -{ - int i, ix, used_midi = -1; - int ret; - TRACE("midi_open()\n"); +status_t +ice_1712_midi_open(const char *name, uint32 flags, void **cookie) +{ + int midi, card; + status_t ret = ENODEV; + TRACE("**midi_open()\n"); *cookie = NULL; - for (ix = 0; ix < num_cards; ix++) { - for (i = 0; i < cards[ix].config.nb_MPU401; i++) - if (!strcmp(name, cards[ix].midi_interf[i].name)) { - used_midi = i; + + for (card = 0; card < num_cards; card++) { + for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) { + if (!strcmp(name, cards[card].midi_interf[midi].name)) { + midi_dev *dev = &(cards[card].midi_interf[midi]); + ret = (*mpu401->open_hook)(dev->mpu401device, flags, cookie); + if (ret >= B_OK) { + *cookie = dev->mpu401device; + } break; } + } } - if (ix >= num_cards) { - TRACE("bad device\n"); - return ENODEV; - } - - TRACE("mpu401: %p open(): %p driver: %p\n", mpu401, - mpu401->open_hook, cards[ix].midi_interf[used_midi].driver); - ret = (*mpu401->open_hook)(cards[ix].midi_interf[used_midi].driver, - flags, cookie); - if (ret >= B_OK) { - cards[ix].midi_interf[used_midi].cookie = *cookie; - atomic_add(&cards[ix].midi_interf[used_midi].count, 1); - } - TRACE("mpu401: open returns %x / %p\n", ret, *cookie); return ret; - } -static status_t midi_close(void * cookie) +status_t +ice_1712_midi_close(void* cookie) { - TRACE("midi_close()\n"); + TRACE("**midi_close()\n"); return (*mpu401->close_hook)(cookie); } -static status_t midi_free(void * cookie) +status_t +ice_1712_midi_free(void* cookie) { - int i, ix; - status_t f; - TRACE("midi_free()\n"); - f = (*mpu401->free_hook)(cookie); - for (ix = 0; ix < num_cards; ix++) { - for (i = 0; i < cards[ix].config.nb_MPU401; i++) - if (cards[ix].midi_interf[i].cookie == cookie) { - if (atomic_add(&cards[ix].midi_interf[i].count, -1) == 1) { - cards[ix].midi_interf[i].cookie = NULL; - TRACE("cleared %p card %d\n", cookie, ix); - } + int midi, card; + status_t ret; + + TRACE("**midi_free()\n"); + + ret = (*mpu401->free_hook)(cookie); + + for (card = 0; card < num_cards; card++) { + for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) { + if (cookie == cards[card].midi_interf[midi].mpu401device) { + cards[card].midi_interf[midi].mpu401device = NULL; + TRACE("Cleared %p card %d, midi %d\n", cookie, card, midi); break; } + } } - TRACE("midi_free() done\n"); - return f; + + return ret; } -static status_t midi_control(void * cookie, uint32 iop, void * data, size_t len) +status_t +ice_1712_midi_control(void* cookie, + uint32 iop, void* data, size_t len) { + TRACE("**midi_control()\n"); return (*mpu401->control_hook)(cookie, iop, data, len); } -static status_t midi_read(void * cookie, off_t pos, void * ptr, size_t * nread) +status_t +ice_1712_midi_read(void * cookie, off_t pos, void * ptr, size_t * nread) { - return (*mpu401->read_hook)(cookie, pos, ptr, nread); + status_t ret = B_ERROR; + + ret = (*mpu401->read_hook)(cookie, pos, ptr, nread); + //TRACE("**midi_read(%ld)\n", ret); + + return ret; } -static status_t midi_write(void * cookie, off_t pos, const void * ptr, +status_t +ice_1712_midi_write(void * cookie, off_t pos, const void * ptr, size_t * nwritten) { - return (*mpu401->write_hook)(cookie, pos, ptr, nwritten); -} + status_t ret = B_ERROR; + ret = (*mpu401->write_hook)(cookie, pos, ptr, nwritten); + //TRACE("**midi_write(%ld)\n", ret); -bool midi_interrupt(ice1712 *card) -{ - TRACE("midi_interrupt\n"); - if (!card->midi_interf[0].driver) { -// kprintf("aiigh\n"); - return false; - } - return (*mpu401->interrupt_hook)(card->midi_interf[0].driver); + return ret; } -- 1.7.7.2