Ice1712 drivers: Add Midi drivers

This commit is contained in:
Jerome Leveque 2012-01-27 20:10:35 +00:00 committed by Jérôme Duval
parent f40e4a90b7
commit fc480b13f4
4 changed files with 189 additions and 172 deletions

View File

@ -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...) ;

View File

@ -75,7 +75,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;
@ -102,7 +102,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++;
@ -114,14 +114,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
@ -137,7 +156,6 @@ static status_t
ice1712_setup(ice1712 *ice)
{
int result, i;
status_t status = B_OK;
uint8 reg8 = 0;
uint16 mute;
@ -225,10 +243,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]);
@ -279,11 +321,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,
@ -353,7 +391,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);
@ -374,7 +412,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;
@ -430,15 +468,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);
@ -455,7 +487,7 @@ uninit_driver(void)
{
int ix, cnt = num_cards;
TRACE("===uninit_driver()===\n");
TRACE("@@uninit_driver()\n");
num_cards = 0;
@ -476,7 +508,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]);
@ -490,7 +522,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)) {
@ -513,7 +545,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;
}
@ -521,7 +553,7 @@ ice_1712_close(void *cookie)
static status_t
ice_1712_free(void *cookie)
{
TRACE("===free()===\n");
TRACE("**free()\n");
return B_OK;
}
@ -631,7 +663,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;
}
@ -641,7 +673,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;
}
@ -661,40 +693,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;
}

View File

@ -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 applySettings(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

View File

@ -9,175 +9,140 @@
* Distributed under the terms of the MIT license.
*/
#include <midi_driver.h>
#include <string.h>
#include <stdlib.h>
#include <signal.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);
cpu_status status;
uint8 int_status = 0;
midi_dev *midi = (midi_dev *)data;
//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);
if (op == B_MPU_401_ENABLE_CARD_INT) {
status = lock();
//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);
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)
status_t
ice_1712_midi_open(const char *name, uint32 flags, void **cookie)
{
int i, ix, used_midi = -1;
int ret;
TRACE("midi_open()\n");
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;
}