Generic MPU401 driver: Add Ice1712 card, Fix line size > 80

This commit is contained in:
Jerome Leveque
2012-02-09 23:15:55 +01:00
committed by Jérôme Duval
parent 1684be5e39
commit 6ffb178a00
+191 -134
View File
@@ -21,14 +21,15 @@
#include "mpu401_priv.h" #include "mpu401_priv.h"
/* ---------- /* ----------
midi_create_device - midi_create_device -
----- */ ----- */
/*-----------------------------*/ /*-----------------------------*/
/* Version 1 of mpu401 module */ /* Version 1 of mpu401 module */
/*-----------------------------*/ /*-----------------------------*/
static status_t static status_t
create_device(int port, void ** out_storage, uint32 workarounds, void (*interrupt_op)(int32 op, void * card), void * card) create_device(int port, void ** out_storage, uint32 workarounds,
void (*interrupt_op)(int32 op, void * card), void * card)
{ {
mpu401device mpu_device; mpu401device mpu_device;
mpu401device *mpuptr; mpu401device *mpuptr;
@@ -39,50 +40,52 @@ create_device(int port, void ** out_storage, uint32 workarounds, void (*interrup
mpu_device.V2 = FALSE; mpu_device.V2 = FALSE;
mpu_device.count = 1; mpu_device.count = 1;
mpu_device.interrupt_op = interrupt_op; 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 // basically, each call to create device allocates memory for
//a structure with the specific device info. The pointer to this is //a structure with the specific device info. The pointer to this is
// returned back to calling driver // returned back to calling driver
mpuptr = (mpu401device*)malloc (sizeof(mpu401device)); mpuptr = (mpu401device*)malloc (sizeof(mpu401device));
memcpy(mpuptr, &mpu_device, sizeof(mpu_device)); memcpy(mpuptr, &mpu_device, sizeof(mpu_device));
*out_storage = (void *)mpuptr; *out_storage = (void *)mpuptr;
return B_OK; return B_OK;
} }
/*-----------------------------*/ /*-----------------------------*/
/* Version 2 of mpu401 module */ /* Version 2 of mpu401 module */
/*-----------------------------*/ /*-----------------------------*/
static status_t static status_t
create_device_v2(int port, void ** out_storage, uint32 workarounds, void (*interrupt_op)(int32 op, void * card), void * card) create_device_v2(int port, void ** out_storage, uint32 workarounds,
void (*interrupt_op)(int32 op, void * card), void * card)
{ {
mpu401device *mpuptr; mpu401device *mpuptr;
mpu401device mpu_device; 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 // Instead of transfering data using a buffer and pointer, the midi
// data is transfered via the global ports. // 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. // 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. // should be returned to the midi server.
// One version of read/write hook functions are used for both v1, v2. Therefore, in // One version of read/write hook functions are used for both v1, v2.
// those calls, it needs to be known whether the mididata is to be read/written // Therefore, in those calls, it needs to be known whether the mididata
// to a buffer, or to the port. // is to be read/written to a buffer, or to the port.
mpu_device.addrport = port; mpu_device.addrport = port;
mpu_device.workarounds = workarounds; mpu_device.workarounds = workarounds;
mpu_device.V2 = TRUE; mpu_device.V2 = TRUE;
mpu_device.count =1; mpu_device.count = 1;
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));
mpuptr = (mpu401device*)malloc(sizeof(mpu401device)); mpuptr = (mpu401device*)malloc(sizeof(mpu401device));
memcpy(mpuptr, &mpu_device, sizeof(mpu_device)); 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) delete_device(void * storage)
{ {
mpu401device * mpu_device = (mpu401device *)storage; mpu401device * mpu_device = (mpu401device *)storage;
LOG(("device->addrport= 0x%x count= %ld\n",mpu_device->addrport, mpu_device->count)); LOG(("device->addrport= 0x%x count= %ld\n",
LOG(("delete_device: *storage:%p\n",storage)); 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; return B_OK;
} }
@@ -112,78 +116,106 @@ delete_device(void * storage)
midi_open - handle open() calls midi_open - handle open() calls
----- */ ----- */
static status_t static status_t
midi_open(void * storage, uint32 flags, void ** out_cookie) midi_open(void * storage, uint32 flags, void ** out_cookie)
{ {
char semname[25]; char semname[25];
int ack_byte; int ack_byte;
mpu401device * mpu_device = (mpu401device *)storage; mpu401device * mpu_device = (mpu401device *)storage;
LOG(("open() flags: %ld, * storage: %p, **out_cookie: %p\n",flags, storage,out_cookie)); LOG(("open() flags: %ld, *storage: %p, **out_cookie: %p\n", flags,
LOG(("open: device->addrport 0x%x ,workarounds 0x%x\n",mpu_device->addrport, mpu_device->workarounds)); 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 // the undocumented V2 module is not complete
// we will allow the device to be created since some drivers depend on it // 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: // but will return an error if the actual midi device is opened:
if ( mpu_device->V2 == TRUE) if ( mpu_device->V2 == TRUE)
return B_ERROR; return B_ERROR;
switch (mpu_device->workarounds){ 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 0x11020005:
case 0: case 0:
// don't know the current mpu state // don't know the current mpu state
PRINT(("reset MPU401\n")); 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); 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); 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")); 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); 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)); PRINT(("port cmd ack is 0x%x\n", ack_byte));
*out_cookie = mpu_device; *out_cookie = mpu_device;
break; 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: case 1:
// Some devices are always in UART mode // Some devices are always in UART mode
PRINT(("already in UART mode\n")); PRINT(("already in UART mode\n"));
break; break;
default: default:
PRINT(("Unknown workaround value: %d\n", mpu_device->workarounds)); PRINT(("Unknown workaround: %d\n", mpu_device->workarounds));
break; break;
} //end switch } //end switch
// Create Read semaphore for midi-in data // Create Read semaphore for midi-in data
sprintf(semname, "mpu401:%04x:read_sem", mpu_device->addrport); sprintf(semname, "mpu401:%04x:read_sem", mpu_device->addrport);
mpu_device->readsemaphore = create_sem(0, semname); mpu_device->readsemaphore = create_sem(0, semname);
// Create Write semaphore for midi-out data // Create Write semaphore for midi-out data
sprintf(semname,"mpu401:%04x:write_sem", mpu_device->addrport); sprintf(semname,"mpu401:%04x:write_sem", mpu_device->addrport);
mpu_device->writesemaphore = create_sem(1, semname); mpu_device->writesemaphore = create_sem(1, semname);
// clear midi-in buffer // clear midi-in buffer
mbuf_bytes=0; mbuf_bytes = 0;
mbuf_current=0; mbuf_current=0;
mbuf_start=0; mbuf_start=0;
//Enable midi interrupts //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) if ((mpu_device->readsemaphore > B_OK)
&& (mpu_device->writesemaphore > B_OK)) { && (mpu_device->writesemaphore > B_OK)) {
atomic_add(&mpu_device->count, 1); atomic_add(&mpu_device->count, 1);
PRINT(("midi_open() done (count = %x)\n", open_count)); PRINT(("midi_open() done (count = %x)\n", open_count));
return B_OK; return B_OK;
} }
return B_ERROR; return B_ERROR;
} }
/* ---------- /* ----------
midi_close - handle close() calls midi_close - handle close() calls
----- */ ----- */
static status_t static status_t
midi_close(void * cookie) midi_close(void * cookie)
{ {
mpu401device * mpu_device = (mpu401device *)cookie; mpu401device * mpu_device = (mpu401device *)cookie;
@@ -192,13 +224,13 @@ midi_close(void * cookie)
return B_ERROR; return B_ERROR;
//Disable soundcard midi interrupts //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 the semaphores
delete_sem(mpu_device->readsemaphore); delete_sem(mpu_device->readsemaphore);
delete_sem(mpu_device->writesemaphore); 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)); PRINT(("midi_close() done (count = %lu)\n", mpu_device->count));
return B_OK; return B_OK;
@@ -207,7 +239,7 @@ midi_close(void * cookie)
/* ---------- /* ----------
midi_free - free up allocated memory midi_free - free up allocated memory
----- */ ----- */
static status_t static status_t
midi_free(void * cookie) midi_free(void * cookie)
{ {
LOG(("midi_free()\n")); LOG(("midi_free()\n"));
@@ -217,7 +249,7 @@ midi_free(void * cookie)
/* ---------- /* ----------
midi_control - handle control() calls midi_control - handle control() calls
----- */ ----- */
static status_t static status_t
midi_control(void * cookie, uint32 op, void * data, size_t len) midi_control(void * cookie, uint32 op, void * data, size_t len)
{ {
//mpu401device *mpu_device = (mpu401device *)cookie; //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 midi_read - handle read() calls
----- */ ----- */
static status_t static status_t
midi_read(void *cookie, off_t pos, void *buffer, size_t *num_bytes) 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; /* The actual midi data is read from the device in the interrupt handler;
this reads and returns the data from a buffer */ this reads and returns the data from a buffer */
unsigned char *data; unsigned char *data;
unsigned int i; unsigned int i;
size_t count; size_t count;
cpu_status status; cpu_status status;
@@ -249,29 +281,29 @@ midi_read(void *cookie, off_t pos, void *buffer, size_t *num_bytes)
i=0; i=0;
*num_bytes=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) { if (bestat == B_INTERRUPTED) {
//PRINT(("acquire_sem B_INTERRUPTED!\n")); //PRINT(("acquire_sem B_INTERRUPTED!\n"));
return B_INTERRUPTED; return B_INTERRUPTED;
} }
if (bestat != B_OK) { if (bestat != B_OK) {
TRACE(("acquire_sem not B_OK %d\n",(int)bestat)); TRACE(("acquire_sem not B_OK %d\n",(int)bestat));
*num_bytes = 1; *num_bytes = 1;
return B_INTERRUPTED; return B_INTERRUPTED;
} } else {
if (bestat == B_OK) {
status = lock(); status = lock();
*(data+i) = mpubuffer[mbuf_start]; *(data+i) = mpubuffer[mbuf_start];
i++; i++;
mbuf_start++; // pointer to data in ringbuffer mbuf_start++; // pointer to data in ringbuffer
if (mbuf_start >= (MBUF_ELEMENTS-1)) if (mbuf_start >= (MBUF_ELEMENTS-1))
mbuf_start = 0; //wraparound of ringbuffer mbuf_start = 0; //wraparound of ringbuffer
*num_bytes =1; // tell caller how many bytes are being returned in buffer *num_bytes = 1; // How many bytes are being returned in buffer
if (mbuf_bytes>0) 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); unlock(status);
//PRINT(("bytes in buffer: %d\n",mbuf_bytes)); //PRINT(("bytes in buffer: %d\n",mbuf_bytes));
} }
return B_OK; 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 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) midi_write(void * cookie, off_t pos, const void * data, size_t * num_bytes)
{ {
unsigned char *bufdata; unsigned char *bufdata;
@@ -287,71 +319,83 @@ midi_write(void * cookie, off_t pos, const void * data, size_t * num_bytes)
size_t count; size_t count;
mpu401device *mpu_device = (mpu401device *)cookie; 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; count = *num_bytes;
/* Only for deep debugging..will slow things down */ /* 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); acquire_sem(mpu_device->writesemaphore);
for (i=0; i<count; i++) { for (i=0; i<count; i++) {
// wait until device is ready // wait until device is ready
while ((Read_MPU401(mpu_device->addrport, UARTCMD, mpu_device->workarounds) & MPU401_OK2WR)); while ((Read_MPU401(mpu_device->addrport, UARTCMD,
Write_MPU401(mpu_device->addrport, UARTDATA, mpu_device->workarounds, *(bufdata+i)); 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); release_sem(mpu_device->writesemaphore);
return B_OK; 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) interrupt_hook(void * cookie)
{ {
status_t bestat; status_t bestat;
mpu401device *mpu_device = (mpu401device *)cookie; 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 /* Only for deep debugging..will slow things down */
is a one, no MIDI data is available. Reading from the data port will often clear the //PRINT(("irq! port: 0x%x\n",mpu_device->addrport));
interrupt signal depending on the sound card. */
/* Input data is available when bit 7 of the Status port is zero.
if ((Read_MPU401(mpu_device->addrport, UARTCMD, mpu_device->workarounds) & MPU401_OK2RD) == 0) { 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 */ /* Okay, midi data waiting to be read from device */
if (mbuf_current >= (MBUF_ELEMENTS-1)) if (mbuf_current >= (MBUF_ELEMENTS-1))
mbuf_current = 0; mbuf_current = 0;
mpubuffer[mbuf_current] = Read_MPU401(mpu_device->addrport, /* store midi data byte into buffer */
UARTDATA, mpu_device->workarounds); /* store midi data byte into buffer */ mpubuffer[mbuf_current] = Read_MPU401(mpu_device->addrport,
mbuf_current++; /* pointer to next blank byte */ UARTDATA, mpu_device->workarounds);
mbuf_bytes++; /* increment count of midi data bytes */ 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);
bestat = release_sem_etc(mpu_device->readsemaphore, 1,
return TRUE; //B_INVOKE_SCHEDULER B_DO_NOT_RESCHEDULE);
}
return TRUE; //B_INVOKE_SCHEDULER
}
/* No midi data from this interrupt */ /* No midi data from this interrupt */
return FALSE; //B_UNHANDLED_INTERRUPT return FALSE; //B_UNHANDLED_INTERRUPT
} }
/*-----------------------------------------------------------------*/ /*-----------------------------------------------------------------*/
uchar uchar
Read_MPU401(unsigned int addrport, const char cmdtype, unsigned int workarounds) Read_MPU401(unsigned int addrport, const char cmdtype,
unsigned int workarounds)
{ {
uchar mpudatabyte; uchar mpudatabyte;
cpu_status status; cpu_status status;
unsigned int regptr; 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) { switch (workarounds) {
case 0x11020004: /* Creative Audigy Gameport */ case 0x11020004: /* Creative Audigy Gameport */
regptr = (((I_MPU1 + cmdtype) << 16) & PTR_ADDRESS_MASK); regptr = (((I_MPU1 + cmdtype) << 16) & PTR_ADDRESS_MASK);
status = lock(); status = lock();
gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA or CMD */ gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA or CMD */
mpudatabyte = gPCI->read_io_32(addrport + D_DATA); mpudatabyte = gPCI->read_io_32(addrport + D_DATA);
unlock(status); unlock(status);
@@ -359,42 +403,55 @@ Read_MPU401(unsigned int addrport, const char cmdtype, unsigned int workarounds)
case 0x11020005: /* Creative Audigy LiveDrive */ case 0x11020005: /* Creative Audigy LiveDrive */
regptr = (((I_MPU2 + cmdtype) << 16) & PTR_ADDRESS_MASK); regptr = (((I_MPU2 + cmdtype) << 16) & PTR_ADDRESS_MASK);
status = lock(); status = lock();
gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA2 or CMD2 */ gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA2 or CMD2 */
mpudatabyte = gPCI->read_io_32(addrport + D_DATA); mpudatabyte = gPCI->read_io_32(addrport + D_DATA);
unlock(status); unlock(status);
break; break;
default: case 0x14121712:
mpudatabyte = gISA->read_io_8(addrport + cmdtype ); status = lock();
break; mpudatabyte = gPCI->read_io_8(addrport + cmdtype);
}
return 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));
switch (workarounds) {
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 );
unlock(status); unlock(status);
break; break;
case 0x11020005: /* Creative Audigy LiveDrive */ default:
mpudatabyte = gISA->read_io_8(addrport + cmdtype);
break;
}
return 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));
switch (workarounds) {
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 );
unlock(status);
break;
case 0x11020005: /* Creative Audigy LiveDrive */
regptr = (((I_MPU2 + cmdtype ) << 16) & PTR_ADDRESS_MASK); regptr = (((I_MPU2 + cmdtype ) << 16) & PTR_ADDRESS_MASK);
status = lock(); status = lock();
gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA2 or CMD2 */ gPCI->write_io_32(addrport + D_PTR, regptr); /*DATA2 or CMD2 */
gPCI->write_io_32(addrport + D_DATA, mpudatabyte ); gPCI->write_io_32(addrport + D_DATA, mpudatabyte );
unlock(status);
break;
case 0x14121712:
status = lock();
gPCI->write_io_8(addrport + cmdtype, mpudatabyte);
unlock(status); unlock(status);
break; break;
@@ -402,7 +459,7 @@ Write_MPU401(unsigned int addrport, const char cmdtype, unsigned int workarounds
gISA->write_io_8(addrport + cmdtype, mpudatabyte); gISA->write_io_8(addrport + cmdtype, mpudatabyte);
break; break;
} }
return B_OK; return B_OK;
} }
@@ -412,7 +469,7 @@ static status_t
std_ops(int32 op, ...) std_ops(int32 op, ...)
{ {
switch(op) { switch(op) {
case B_MODULE_INIT: case B_MODULE_INIT:
LOG_CREATE(); LOG_CREATE();
@@ -423,19 +480,19 @@ std_ops(int32 op, ...)
if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI) < B_OK) if (get_module(B_PCI_MODULE_NAME, (module_info **)&gPCI) < B_OK)
return B_ERROR; return B_ERROR;
return B_OK; return B_OK;
case B_MODULE_UNINIT: case B_MODULE_UNINIT:
put_module(B_ISA_MODULE_NAME); put_module(B_ISA_MODULE_NAME);
put_module(B_PCI_MODULE_NAME); put_module(B_PCI_MODULE_NAME);
PRINT(("B_MODULE_UNINIT\n")); PRINT(("B_MODULE_UNINIT\n"));
return B_OK; return B_OK;
default: default:
return B_ERROR; return B_ERROR;
} }
} }
static generic_mpu401_module mpu401_module = static generic_mpu401_module mpu401_module =
{ {
{ {
B_MPU_401_MODULE_NAME, B_MPU_401_MODULE_NAME,
@@ -453,8 +510,8 @@ static generic_mpu401_module mpu401_module =
interrupt_hook interrupt_hook
}; };
// Module v2 seems to be undocumented // Module v2 seems to be undocumented
static generic_mpu401_module mpu401_module2 = static generic_mpu401_module mpu401_module2 =
{ {
{ {
"generic/mpu401/v2", "generic/mpu401/v2",
@@ -480,7 +537,7 @@ _EXPORT generic_mpu401_module *modules[] =
}; };
spinlock locked = B_SPINLOCK_INITIALIZER; spinlock locked = B_SPINLOCK_INITIALIZER;
cpu_status cpu_status
lock(void) lock(void)
{ {
cpu_status status = disable_interrupts(); cpu_status status = disable_interrupts();
@@ -488,7 +545,7 @@ lock(void)
return status; return status;
} }
void void
unlock(cpu_status status) unlock(cpu_status status)
{ {
release_spinlock(&locked); release_spinlock(&locked);