diff --git a/src/add-ons/kernel/drivers/audio/ice1712/Jamfile b/src/add-ons/kernel/drivers/audio/ice1712/Jamfile index 1e11dc0eba..d21536d088 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/Jamfile +++ b/src/add-ons/kernel/drivers/audio/ice1712/Jamfile @@ -5,10 +5,10 @@ SetSubDirSupportedPlatformsBeOSCompatible ; UsePrivateHeaders media ; KernelAddon ice1712 : - ice1712.c - io.c - midi.c - multi.c - util.c + ice1712.cpp + io.cpp + midi.cpp + multi.cpp + util.cpp ; diff --git a/src/add-ons/kernel/drivers/audio/ice1712/debug.h b/src/add-ons/kernel/drivers/audio/ice1712/debug.h index c684bc038e..f75da2c15b 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/debug.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/debug.h @@ -1,36 +1,29 @@ /* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com */ + + #ifndef _DEBUG_ICE1712_H_ #define _DEBUG_ICE1712_H_ -#ifdef TRACE -# undef TRACE -#endif - //#define ICE1712_VERBOSE #ifdef ICE1712_VERBOSE -# define TRACE(a...) dprintf("\33[34mice1712:\33[0m " a) +# define ITRACE(a...) dprintf("ice1712: " a) #else -# define TRACE(a...) ; +# define ITRACE(a...) (void)0 #endif //#define ICE1712_VERY_VERBOSE #ifdef ICE1712_VERY_VERBOSE -# define TRACE_VV(a...) dprintf("\33[34mice1712:\33[0m " a) +# define ITRACE_VV(a...) ITRACE(a) #else -# define TRACE_VV(a...) ; +# define ITRACE_VV(a...) (void)0 #endif -#define ASSERT(a) if (a) {} else TRACE("ASSERT failed! file = %s, line = %d\n",\ - __FILE__,__LINE__) - - #endif // _DEBUG_ICE1712_H_ diff --git a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.cpp similarity index 64% rename from src/add-ons/kernel/drivers/audio/ice1712/ice1712.c rename to src/add-ons/kernel/drivers/audio/ice1712/ice1712.cpp index 1a6dd4d3aa..94d182f8b4 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.cpp @@ -1,12 +1,11 @@ /* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com */ @@ -26,43 +25,49 @@ #include #include +static status_t ice1712Settings_load(ice1712 *card); +status_t ice1712Settings_apply(ice1712 *card); +static int32 ice1712HW_interrupt(void *arg); +static status_t ice1712HW_setup(ice1712 *ice); +static void ice1712HW_shutdown(ice1712 *ice); -status_t init_hardware(void); -status_t init_driver(void); -void uninit_driver(void); -const char **publish_devices(void); -device_hooks *find_device(const char *); -status_t load_settings(ice1712 *card); -int32 ice_1712_int(void *arg); +extern device_hooks ice1712Midi_hooks; +extern device_hooks ice1712Audio_hooks; +void ice1712Midi_interrupt(int32 op, void *data); pci_module_info *pci; generic_mpu401_module *mpu401; int32 num_cards = 0; ice1712 cards[NUM_CARDS]; -int32 num_names = 0; -char *names[NUM_CARDS*20+1]; -int32 api_version = B_CUR_DRIVER_API_VERSION; + +//3 interfaces (2 midi + 1 audio) can be defined for each card +static char *names[NUM_CARDS*3+1]; +static int32 num_names = 0; #define HMULTI_AUDIO_DEV_PATH "audio/hmulti/ice1712" +//Haiku Driver API +//---------------- -status_t +int32 api_version = B_CUR_DRIVER_API_VERSION; + +extern "C" status_t init_hardware(void) { int ix = 0; pci_info info; memset(cards, 0, sizeof(ice1712) * NUM_CARDS); - TRACE("@@init_hardware()\n"); + ITRACE("@@ init_hardware()\n"); if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci)) return ENOSYS; while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) { - if ((info.vendor_id == ICE1712_VENDOR_ID) && - (info.device_id == ICE1712_DEVICE_ID)) { - TRACE("Found at least 1 card\n"); + if ((info.vendor_id == ICE1712_VENDOR_ID) + && (info.device_id == ICE1712_DEVICE_ID)) { + ITRACE("Found at least 1 card\n"); put_module(B_PCI_MODULE_NAME); return B_OK; } @@ -73,10 +78,133 @@ init_hardware(void) } -int32 -ice_1712_int(void *arg) +extern "C" status_t +init_driver(void) { - ice1712 *ice = arg; + int i = 0; + status_t err; + num_cards = 0; + + ITRACE("@@ init_driver()\n"); + + if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci)) + return ENOSYS; + + if (get_module(B_MPU_401_MODULE_NAME, (module_info **) &mpu401)) { + put_module(B_PCI_MODULE_NAME); + return ENOSYS; + } + + while ((*pci->get_nth_pci_info)(i, &cards[num_cards].info) == B_OK) { + //TODO check other Vendor_ID and DEVICE_ID + if ((cards[num_cards].info.vendor_id == ICE1712_VENDOR_ID) + && (cards[num_cards].info.device_id == ICE1712_DEVICE_ID)) { + if (num_cards == NUM_CARDS) { + ITRACE("Too many ice1712 cards installed!\n"); + break; + } + + if ((err = (*pci->reserve_device)(cards[num_cards].info.bus, + cards[num_cards].info.device, + cards[num_cards].info.function, + DRIVER_NAME, &cards[num_cards])) < B_OK) { + ITRACE_VV("%s: failed to reserve_device(%d, %d, %d,): %s\n", + DRIVER_NAME, cards[num_cards].info.bus, + cards[num_cards].info.device, + cards[num_cards].info.function, strerror(err)); + continue; + } + + ice1712Settings_load(&cards[num_cards]); + + if (ice1712HW_setup(&cards[num_cards]) != B_OK) { + //Vendor_ID and Device_ID has been modified + ITRACE("Setup of ice1712 %" B_PRIu32 " failed\n", num_cards + 1); + (*pci->unreserve_device)(cards[num_cards].info.bus, + cards[num_cards].info.device, + cards[num_cards].info.function, + DRIVER_NAME, &cards[num_cards]); + } else { + num_cards++; + } + } + i++; + } + + ITRACE("Succesfully initialised card : %" B_PRIu32 "\n", num_cards); + + if (num_cards == 0) { + put_module(B_PCI_MODULE_NAME); + put_module(B_MPU_401_MODULE_NAME); + return ENODEV; + } + return B_OK; +} + + +extern "C" void +uninit_driver(void) +{ + int ix, cnt = num_cards; + + ITRACE("@@ uninit_driver()\n"); + + num_cards = 0; + + for (ix = 0; ix < cnt; ix++) { + ice1712HW_shutdown(&cards[ix]); + (*pci->unreserve_device)(cards[ix].info.bus, + cards[ix].info.device, cards[ix].info.function, + DRIVER_NAME, &cards[ix]); + } + memset(&cards, 0, sizeof(cards)); + put_module(B_MPU_401_MODULE_NAME); + put_module(B_PCI_MODULE_NAME); +} + + +extern "C" const char ** +publish_devices(void) +{ + int ix = 0; + ITRACE("@@ publish_devices()\n"); + + for (ix = 0; names[ix]; ix++) { + ITRACE("publish %s\n", names[ix]); + } + return (const char **)names; +} + + +extern "C" device_hooks * +find_device(const char * name) +{ + int ix, midi; + + ITRACE("@@ find_device()\n"); + + for (ix = 0; ix < num_cards; ix++) { + for (midi = 0; midi < MAX_MIDI_INTERFACE; midi++) { + if (!strcmp(cards[ix].midiItf[midi].name, name)) { + return &ice1712Midi_hooks; + } + } + + if (!strcmp(cards[ix].name, name)) { + return &ice1712Audio_hooks; + } + } + ITRACE("!!! failed !!!\n"); + return NULL; +} + +//ICE1712 driver - Hardware +//------------------------- + +int32 +ice1712HW_interrupt(void *arg) +{ + ice1712 *ice = (ice1712*)arg; uint8 reg8 = 0; uint16 reg16 = 0; uint32 status = B_UNHANDLED_INTERRUPT; @@ -98,7 +226,7 @@ ice_1712_int(void *arg) if (reg8 != 0) { bool ret; if (reg8 & CCS_INTERRUPT_MIDI_1) { - ret = (*mpu401->interrupt_hook)(ice->midi_interf[0].mpu401device); + ret = (*mpu401->interrupt_hook)(ice->midiItf[0].mpu401device); if (ret) { //Do not ack, cause more datas are available reg8 &= ~CCS_INTERRUPT_MIDI_1; @@ -106,7 +234,7 @@ ice_1712_int(void *arg) } if (reg8 & CCS_INTERRUPT_MIDI_2) { - ret = (*mpu401->interrupt_hook)(ice->midi_interf[1].mpu401device); + ret = (*mpu401->interrupt_hook)(ice->midiItf[1].mpu401device); if (ret) { //Do not ack, cause more datas are available reg8 &= ~CCS_INTERRUPT_MIDI_2; @@ -131,18 +259,18 @@ ice_1712_int(void *arg) } -static status_t -ice1712_setup(ice1712 *ice) +status_t +ice1712HW_setup(ice1712 *ice) { int i; uint8 reg8 = 0; uint16 mute; - ice->irq = ice->info.u.h0.interrupt_line; - ice->Controller = ice->info.u.h0.base_registers[0]; - ice->DDMA = ice->info.u.h0.base_registers[1]; - ice->DMA_Path = ice->info.u.h0.base_registers[2]; - ice->Multi_Track = ice->info.u.h0.base_registers[3]; + ice->irq = ice->info.u.h0.interrupt_line; + ice->Controller = ice->info.u.h0.base_registers[0]; + ice->DDMA = ice->info.u.h0.base_registers[1]; + ice->DMA_Path = ice->info.u.h0.base_registers[2]; + ice->Multi_Track = ice->info.u.h0.base_registers[3]; // Soft Reset write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x81); @@ -152,11 +280,6 @@ ice1712_setup(ice1712 *ice) read_eeprom(ice, ice->eeprom_data); -/* TRACE("EEprom -> "); - for (i = 0; i < 32; i++) - TRACE("%x, ", eeprom_data[i]); - TRACE("<- EEprom\n");*/ - write_ccs_uint8(ice, CCS_SERR_SHADOW, 0x01); //Write all configurations register from EEProm @@ -164,8 +287,9 @@ ice1712_setup(ice1712 *ice) | ice->eeprom_data[E2PROM_MAP_SUBVENDOR_LOW]; ice->info.vendor_id = ice->eeprom_data[E2PROM_MAP_SUBDEVICE_HIGH] << 8 | ice->eeprom_data[E2PROM_MAP_SUBDEVICE_LOW]; - ice->product = ice->info.vendor_id << 16 | ice->info.device_id; - TRACE("Product ID : 0x%x\n", ice->product); + ice->config.product = (ice1712Product)(ice->info.vendor_id << 16 + | ice->info.device_id); + ITRACE("Product ID : 0x%x\n", ice->config.product); write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ice->eeprom_data[E2PROM_MAP_GPIOMASK]); @@ -174,14 +298,13 @@ ice1712_setup(ice1712 *ice) write_cci_uint8(ice, CCI_GPIO_DIRECTION_CONTROL, ice->eeprom_data[E2PROM_MAP_GPIODIR]); - TRACE("CCI_GPIO_WRITE_MASK : 0x%x\n", + ITRACE("CCI_GPIO_WRITE_MASK : 0x%x\n", ice->eeprom_data[E2PROM_MAP_GPIOMASK]); - TRACE("CCI_GPIO_DATA : 0x%x\n", + ITRACE("CCI_GPIO_DATA : 0x%x\n", ice->eeprom_data[E2PROM_MAP_GPIOSTATE]); - TRACE("CCI_GPIO_DIRECTION_CONTROL : 0x%x\n", + ITRACE("CCI_GPIO_DIRECTION_CONTROL : 0x%x\n", ice->eeprom_data[E2PROM_MAP_GPIODIR]); - //Write Configuration in the PCI configuration Register (pci->write_pci_config)(ice->info.bus, ice->info.device, ice->info.function, 0x60, 1, ice->eeprom_data[E2PROM_MAP_CONFIG]); @@ -192,7 +315,7 @@ ice1712_setup(ice1712 *ice) (pci->write_pci_config)(ice->info.bus, ice->info.device, ice->info.function, 0x63, 1, ice->eeprom_data[E2PROM_MAP_SPDIF]); - TRACE("E2PROM_MAP_CONFIG : 0x%x\n", ice->eeprom_data[E2PROM_MAP_CONFIG]); + ITRACE("E2PROM_MAP_CONFIG : 0x%x\n", ice->eeprom_data[E2PROM_MAP_CONFIG]); reg8 = ice->eeprom_data[E2PROM_MAP_CONFIG]; //Bits signification for E2PROM_MAP_CONFIG Byte // @@ -210,52 +333,50 @@ ice1712_setup(ice1712 *ice) reg8 >>= 2; if ((reg8 & 0x01) != 0) {//Consumer AC'97 Exist - TRACE("Consumer AC'97 does exist\n"); + ITRACE("Consumer AC'97 does exist\n"); //For now do nothing /* write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x40); snooze(10000); write_ccs_uint8(ice, CCS_CONS_AC97_COMMAND_STATUS, 0x00); snooze(20000); */ } else { - TRACE("Consumer AC'97 does NOT exist\n"); + ITRACE("Consumer AC'97 does NOT exist\n"); } reg8 >>= 1; ice->config.nb_MPU401 = (reg8 & 0x1) + 1; if (ice->config.nb_MPU401 > 0) { - sprintf(ice->midi_interf[0].name, "midi/ice1712/%ld/1", - ice - cards + 1); + sprintf(ice->midiItf[0].name, "midi/ice1712/%ld/1", ice - cards + 1); (*mpu401->create_device)(ice->Controller + CCS_MIDI_1_DATA, - &ice->midi_interf[0].mpu401device, + &ice->midiItf[0].mpu401device, 0x14121712, - ice_1712_midi_interrupt_op, - &ice->midi_interf[0]); + ice1712Midi_interrupt, + &ice->midiItf[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; + names[num_names++] = ice->midiItf[0].name; + ice->midiItf[0].card = ice; + ice->midiItf[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); + sprintf(ice->midiItf[1].name, "midi/ice1712/%ld/2", ice - cards + 1); (*mpu401->create_device)(ice->Controller + CCS_MIDI_2_DATA, - &ice->midi_interf[1].mpu401device, + &ice->midiItf[1].mpu401device, 0x14121712, - ice_1712_midi_interrupt_op, - &ice->midi_interf[1]); + ice1712Midi_interrupt, + &ice->midiItf[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; + names[num_names++] = ice->midiItf[1].name; + ice->midiItf[1].card = ice; + ice->midiItf[1].int_mask = CCS_INTERRUPT_MIDI_2; } - TRACE("E2PROM_MAP_SPDIF : 0x%x\n", ice->eeprom_data[E2PROM_MAP_SPDIF]); + ITRACE("E2PROM_MAP_SPDIF : 0x%x\n", ice->eeprom_data[E2PROM_MAP_SPDIF]); ice->config.spdif = ice->eeprom_data[E2PROM_MAP_SPDIF]; - switch (ice->product) { + switch (ice->config.product) { case ICE1712_SUBDEVICE_DELTA66 : case ICE1712_SUBDEVICE_DELTA44 : ice->CommLines.clock = DELTA66_CLK; @@ -299,32 +420,26 @@ ice1712_setup(ice1712 *ice) return ice->buffer_ready_sem; } -// TRACE("installing interrupt : %0x\n", ice->irq); - install_io_interrupt_handler(ice->irq, ice_1712_int, ice, 0); + install_io_interrupt_handler(ice->irq, ice1712HW_interrupt, ice, 0); - ice->mem_id_pb = alloc_mem(&ice->phys_addr_pb, &ice->log_addr_pb, - PLAYBACK_BUFFER_TOTAL_SIZE, - "playback buffer"); + ice->mem_id_pb = alloc_mem(&ice->phys_pb, &ice->log_addr_pb, + PLAYBACK_BUFFER_TOTAL_SIZE, "playback buffer"); if (ice->mem_id_pb < B_OK) { - remove_io_interrupt_handler(ice->irq, ice_1712_int, ice); + remove_io_interrupt_handler(ice->irq, ice1712HW_interrupt, ice); delete_sem(ice->buffer_ready_sem); return ice->mem_id_pb; } - ice->mem_id_rec = alloc_mem(&ice->phys_addr_rec, &ice->log_addr_rec, - RECORD_BUFFER_TOTAL_SIZE, - "record buffer"); + ice->mem_id_rec = alloc_mem(&ice->phys_rec, &ice->log_addr_rec, + RECORD_BUFFER_TOTAL_SIZE, "record buffer"); if (ice->mem_id_rec < B_OK) { - remove_io_interrupt_handler(ice->irq, ice_1712_int, ice); + remove_io_interrupt_handler(ice->irq, ice1712HW_interrupt, ice); delete_sem(ice->buffer_ready_sem); delete_area(ice->mem_id_pb); return(ice->mem_id_rec); } - memset(ice->log_addr_pb, 0, PLAYBACK_BUFFER_TOTAL_SIZE); - memset(ice->log_addr_rec, 0, RECORD_BUFFER_TOTAL_SIZE); - - ice->sampling_rate = 0x08; + ice->config.samplingRate = 0x08; ice->buffer = 0; ice->frames_count = 0; ice->buffer_size = ice->settings.bufferSize; @@ -346,17 +461,9 @@ ice1712_setup(ice1712 *ice) write_mt_uint16(ice, MT_VOLUME_CONTROL_RATE, 0x01); //All Analog outputs from DMA - write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0x0000); + write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0x0000); //All Digital output from DMA - write_mt_uint16(ice, MT_ROUTING_CONTROL_SPDOUT, 0x0000); - - //Just to route all input to all output -// write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0xAAAA); -// write_mt_uint32(ice, MT_CAPTURED_DATA, 0x76543210); - - //Just to route SPDIF Input to DAC 0 -// write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0xAAAF); -// write_mt_uint32(ice, MT_CAPTURED_DATA, 0x76543280); + write_mt_uint16(ice, MT_ROUTING_CONTROL_SPDOUT, 0x0000); //Mute all input mute = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8); @@ -369,90 +476,27 @@ ice1712_setup(ice1712 *ice) write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x41); reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_MASK); - TRACE("-----CCS----- = %x\n", reg8); + ITRACE("-----CCS----- = %x\n", reg8); write_ccs_uint8(ice, CCS_INTERRUPT_MASK, 0xEF); /* reg16 = read_ds_uint16(ice, DS_DMA_INT_MASK); - TRACE("-----DS_DMA----- = %x\n", reg16); + ITRACE("-----DS_DMA----- = %x\n", reg16); write_ds_uint16(ice, DS_DMA_INT_MASK, 0x0000); */ reg8 = read_mt_uint8(ice, MT_DMA_INT_MASK_STATUS); - TRACE("-----MT_DMA----- = %x\n", reg8); + ITRACE("-----MT_DMA----- = %x\n", reg8); write_mt_uint8(ice, MT_DMA_INT_MASK_STATUS, 0x00); return B_OK; }; -status_t -init_driver(void) -{ - int i = 0; - status_t err; - num_cards = 0; - - TRACE("@@init_driver()\n"); - - if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci)) - return ENOSYS; - - if (get_module(B_MPU_401_MODULE_NAME, (module_info **) &mpu401)) { - put_module(B_PCI_MODULE_NAME); - return ENOSYS; - } - - while ((*pci->get_nth_pci_info)(i, &cards[num_cards].info) == B_OK) { - //TODO check other Vendor_ID and DEVICE_ID - if ((cards[num_cards].info.vendor_id == ICE1712_VENDOR_ID) - && (cards[num_cards].info.device_id == ICE1712_DEVICE_ID)) { - if (num_cards == NUM_CARDS) { - TRACE("Too many ice1712 cards installed!\n"); - break; - } - - if ((err = (*pci->reserve_device)(cards[num_cards].info.bus, - cards[num_cards].info.device, cards[num_cards].info.function, - DRIVER_NAME, &cards[num_cards])) < B_OK) { - dprintf("%s: failed to reserve_device(%d, %d, %d,): %s\n", - DRIVER_NAME, cards[num_cards].info.bus, - cards[num_cards].info.device, - cards[num_cards].info.function, strerror(err)); - continue; - } - - load_settings(&cards[num_cards]); - - if (ice1712_setup(&cards[num_cards]) != B_OK) { - //Vendor_ID and Device_ID has been modified - TRACE("Setup of ice1712 %d failed\n", (int)(num_cards + 1)); - (*pci->unreserve_device)(cards[num_cards].info.bus, - cards[num_cards].info.device, - cards[num_cards].info.function, - DRIVER_NAME, &cards[num_cards]); - } else { - num_cards++; - } - } - i++; - } - - TRACE("Number of succesfully initialised card : %d\n", (int)num_cards); - - if (num_cards == 0) { - put_module(B_PCI_MODULE_NAME); - put_module(B_MPU_401_MODULE_NAME); - return ENODEV; - } - return B_OK; -} - - -static void -ice_1712_shutdown(ice1712 *ice) +void +ice1712HW_shutdown(ice1712 *ice) { delete_sem(ice->buffer_ready_sem); - remove_io_interrupt_handler(ice->irq, ice_1712_int, ice); + remove_io_interrupt_handler(ice->irq, ice1712HW_interrupt, ice); if (ice->mem_id_pb != B_ERROR) delete_area(ice->mem_id_pb); @@ -463,58 +507,26 @@ ice_1712_shutdown(ice1712 *ice) codec_write(ice, AK45xx_RESET_REGISTER, 0x00); } - -void -uninit_driver(void) -{ - int ix, cnt = num_cards; - - TRACE("@@uninit_driver()\n"); - - num_cards = 0; - - for (ix = 0; ix < cnt; ix++) { - ice_1712_shutdown(&cards[ix]); - (*pci->unreserve_device)(cards[ix].info.bus, - cards[ix].info.device, cards[ix].info.function, - DRIVER_NAME, &cards[ix]); - } - memset(&cards, 0, sizeof(cards)); - put_module(B_MPU_401_MODULE_NAME); - put_module(B_PCI_MODULE_NAME); -} - - -const char ** -publish_devices(void) -{ - int ix = 0; - TRACE("@@publish_devices()\n"); - - for (ix=0; names[ix]; ix++) { - TRACE("publish %s\n", names[ix]); - } - return (const char **)names; -} - +//ICE1712 driver - Hook +//--------------------- static status_t -ice_1712_open(const char *name, uint32 flags, void **cookie) +ice1712Audio_open(const char *name, uint32 flags, void **cookie) { int ix; ice1712 *card = NULL; - TRACE("**open()\n"); + ITRACE("** open(): %s\n", name); - for (ix=0; ix= MIN_BUFFER_FRAMES) @@ -745,7 +724,7 @@ load_settings(ice1712 *card) status_t -apply_settings(ice1712 *card) +ice1712Settings_apply(ice1712 *card) { int i; uint16 val, mt30 = 0; @@ -758,7 +737,7 @@ apply_settings(ice1712 *card) if (card->settings.playback[i].mute == true) { val = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8); } else { - unsigned char volume = card->settings.playback[i].volume / -1.5; + uint8 volume = card->settings.playback[i].volume / -1.5; if (i & 1) {//a right channel val = ICE1712_MUTE_VALUE << 0; //Mute left volume val |= volume << 8; @@ -769,7 +748,7 @@ apply_settings(ice1712 *card) } write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val); - TRACE_VV("Apply Settings %d : 0x%x\n", i, val); + ITRACE_VV("Apply Settings %d : 0x%x\n", i, val); } for (i = 0; i < ICE1712_HARDWARE_VOLUME; i++) { @@ -791,30 +770,30 @@ apply_settings(ice1712 *card) } write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val); - TRACE_VV("Apply Settings %d : 0x%x\n", i, val); + ITRACE_VV("Apply Settings %d : 0x%x\n", i, val); } //Analog output selection for (i = 0; i < 4; i++) { uint8 out = card->settings.output[i]; if (out == 0) { - TRACE_VV("Output %d is haiku output\n", i); + ITRACE_VV("Output %d is haiku output\n", i); //Nothing to do } else if (out <= (card->config.nb_ADC / 2)) { uint8 mt34_c; out--; - TRACE_VV("Output %d is input %d\n", i, out); + ITRACE_VV("Output %d is input %d\n", i, out); mt34_c = (out * 2); mt34_c |= (out * 2 + 1) << 4; - mt30 |= 0x0202 << (2*i); - mt30 |= mt34_c << (8*i); + mt30 |= 0x0202 << (2 * i); + mt30 |= mt34_c << (8 * i); } else if (out == ((card->config.nb_ADC / 2) + 1) && (card->config.spdif & SPDIF_IN_PRESENT) != 0) { - TRACE_VV("Output %d is digital input\n", i); - mt30 |= 0x0303 << (2*i); - mt34 |= 0x80 << (8*i); + ITRACE_VV("Output %d is digital input\n", i); + mt30 |= 0x0303 << (2 * i); + mt34 |= 0x80 << (8 * i); } else { - TRACE_VV("Output %d is digital Mixer\n", i); + ITRACE_VV("Output %d is digital Mixer\n", i); mt30 |= 0x0101; } } @@ -826,26 +805,25 @@ apply_settings(ice1712 *card) uint16 mt32 = 0; uint8 out = card->settings.output[4]; if (out == 0) { - TRACE_VV("Digital output is haiku output\n"); + ITRACE_VV("Digital output is haiku output\n"); //Nothing to do } else if (out <= (card->config.nb_ADC / 2)) { out--; - TRACE_VV("Digital output is input %d\n", out); + ITRACE_VV("Digital output is input %d\n", out); mt32 |= 0x0202; mt32 |= (out * 2) << 8; mt32 |= (out * 2 + 1) << 12; } else if (out == ((card->config.nb_ADC / 2) + 1) && (card->config.spdif & SPDIF_IN_PRESENT) != 0) { - TRACE_VV("Digital output is digital input\n"); + ITRACE_VV("Digital output is digital input\n"); mt32 |= 0x800F; } else { - TRACE_VV("Digital output is digital Mixer\n"); + ITRACE_VV("Digital output is digital Mixer\n"); mt32 |= 0x0005; } write_mt_uint16(card, MT_ROUTING_CONTROL_SPDOUT, mt32); } - return B_OK; } diff --git a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h index ece826ad03..574b67028c 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h @@ -1,30 +1,30 @@ /* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com */ + + #ifndef _ICE1712_H_ #define _ICE1712_H_ - #include "debug.h" #include "hmulti_audio.h" #include - +#include #define DRIVER_NAME "ice1712" -#define VERSION "0.5" +#define VERSION "0.6" -#define ICE1712_VENDOR_ID 0x1412 -#define ICE1712_DEVICE_ID 0x1712 +#define ICE1712_VENDOR_ID 0x1412 +#define ICE1712_DEVICE_ID 0x1712 -typedef enum product_t { +typedef enum ice1712Product { ICE1712_SUBDEVICE_DELTA1010 = 0x121430d6, ICE1712_SUBDEVICE_DELTADIO2496 = 0x121431d6, ICE1712_SUBDEVICE_DELTA66 = 0x121432d6, @@ -33,10 +33,11 @@ typedef enum product_t { ICE1712_SUBDEVICE_DELTA410 = 0x121438d6, ICE1712_SUBDEVICE_DELTA1010LT = 0x12143bd6, ICE1712_SUBDEVICE_VX442 = 0x12143cd6, -} product_t; +} ice1712Product; #define NUM_CARDS 4 -#define MAX_ADC 12 // + the output of the Digital mixer +#define MAX_ADC 12 +// 5 stereo output + the Digital mixer #define MAX_DAC 10 #define MAX_MIDI_INTERFACE 2 #define SWAPPING_BUFFERS 2 @@ -45,7 +46,7 @@ typedef enum product_t { #define MAX_BUFFER_FRAMES 2048 #define ICE1712_HARDWARE_VOLUME 10 -#define ICE1712_MUTE_VALUE 0x7F +#define ICE1712_MUTE_VALUE 0x7F #define PLAYBACK_BUFFER_SIZE (MAX_BUFFER_FRAMES * MAX_DAC * SAMPLE_SIZE) #define RECORD_BUFFER_SIZE (MAX_BUFFER_FRAMES * MAX_ADC * SAMPLE_SIZE) @@ -68,68 +69,62 @@ typedef enum product_t { struct ice1712; -typedef struct _midi_dev { - 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 ice1712Midi { + struct ice1712 *card; + void *mpu401device; + uint8 int_mask; + char name[64]; +} ice1712Midi; typedef struct _codecCommLines { - uint8 clock; - uint8 data_in; - uint8 data_out; - uint8 cs_mask; //a Mask for removing all Chip select - uint8 reserved[4]; + uint8 clock; + uint8 data_in; + uint8 data_out; + uint8 cs_mask; + //a Mask for removing all Chip select } codecCommLines; -typedef struct channel_volume +typedef struct ice1712Volume { float volume; bool mute; -} channel_volume; +} ice1712Volume; -typedef struct ice1712_settings +typedef struct ice1712Settings { - channel_volume playback[ICE1712_HARDWARE_VOLUME]; - channel_volume record[ICE1712_HARDWARE_VOLUME]; + ice1712Volume playback[ICE1712_HARDWARE_VOLUME]; + ice1712Volume record[ICE1712_HARDWARE_VOLUME]; uint32 bufferSize; //General Settings - uint8 clock; //an index + uint8 clock; //an index //S/PDif Settings - uint8 outFormat; //an index - uint8 emphasis; //an index - uint8 copyMode; //an index + uint8 outFormat; //an index + uint8 emphasis; //an index + uint8 copyMode; //an index //Output settings - uint8 output[5]; //an index + uint8 output[5]; //an index uint8 reserved[32]; -} ice1712_settings; +} ice1712Settings; -typedef struct ice1712_hconfig +typedef struct ice1712HW { - int8 nb_ADC; //Mono Channel - int8 nb_DAC; //Mono Channel + int8 nb_ADC; //Mono Channel + int8 nb_DAC; //Mono Channel int8 nb_MPU401; int8 spdif; -} ice1712_hconfig; + + //in the format of the register + uint8 samplingRate; + uint32 lockSource; + + ice1712Product product; +} ice1712HW; typedef struct ice1712 { @@ -137,7 +132,7 @@ typedef struct ice1712 pci_info info; char name[128]; - midi_dev midi_interf[MAX_MIDI_INTERFACE]; + ice1712Midi midiItf[MAX_MIDI_INTERFACE]; uint32 Controller; //PCI_10 uint32 DDMA; //PCI_14 @@ -146,8 +141,6 @@ typedef struct ice1712 uint8 eeprom_data[32]; - product_t product; - //We hope all manufacturers will use same //communication lines for speaking with codec codecCommLines CommLines; @@ -159,29 +152,22 @@ typedef struct ice1712 //Output area_id mem_id_pb; - void *phys_addr_pb, *log_addr_pb; + physical_entry phys_pb; + addr_t log_addr_pb; uint8 total_output_channels; //Input area_id mem_id_rec; - void *phys_addr_rec, *log_addr_rec; + physical_entry phys_rec; + addr_t log_addr_rec; uint8 total_input_channels; sem_id buffer_ready_sem; - uint8 sampling_rate; //in the format of the register - uint32 lock_source; - - ice1712_hconfig config; - ice1712_settings settings; + ice1712HW config; + ice1712Settings settings; } ice1712; -status_t apply_settings(ice1712 *card); - -//For midi.c -extern int32 num_cards; -extern ice1712 cards[NUM_CARDS]; - //CSS_INTERRUPT_MASK #define CCS_INTERRUPT_MIDI_1 0x80 #define CCS_INTERRUPT_MIDI_2 0x20 @@ -227,7 +213,7 @@ extern ice1712 cards[NUM_CARDS]; #define VX442_CS_MASK 0x70 // Chip Select Mask #define GPIO_I2C_DELAY 5 //Clock Delay for writing - //I2C data throw GPIO + //I2C data throw GPIO //Register definition for the AK45xx codec (xx = 24 or 28) #define AK45xx_CHIP_ADDRESS 0x02 //Chip address of the codec @@ -271,25 +257,27 @@ extern ice1712 cards[NUM_CARDS]; */ //This map comes from ALSA sound drivers -#define E2PROM_MAP_SUBVENDOR_LOW 0x00 -#define E2PROM_MAP_SUBVENDOR_HIGH 0x01 -#define E2PROM_MAP_SUBDEVICE_LOW 0x02 -#define E2PROM_MAP_SUBDEVICE_HIGH 0x03 -#define E2PROM_MAP_SIZE 0x04 -#define E2PROM_MAP_VERSION 0x05 -#define E2PROM_MAP_CONFIG 0x06 -#define E2PROM_MAP_ACL 0x07 -#define E2PROM_MAP_I2S 0x08 -#define E2PROM_MAP_SPDIF 0x09 -#define E2PROM_MAP_GPIOMASK 0x0A -#define E2PROM_MAP_GPIOSTATE 0x0B -#define E2PROM_MAP_GPIODIR 0x0C -#define E2PROM_MAP_AC97MAIN 0x0D -#define E2PROM_MAP_AC97PCM 0x0F -#define E2PROM_MAP_AC97REC 0x11 -#define E2PROM_MAP_AC97REC_SOURCE 0x13 -#define E2PROM_MAP_DAC_ID 0x14 -#define E2PROM_MAP_ADC_ID 0x18 -#define E2PROM_MAP_EXTRA 0x1C +typedef enum ice1712EEprom { + E2PROM_MAP_SUBVENDOR_LOW = 0x00, + E2PROM_MAP_SUBVENDOR_HIGH, + E2PROM_MAP_SUBDEVICE_LOW, + E2PROM_MAP_SUBDEVICE_HIGH, + E2PROM_MAP_SIZE, + E2PROM_MAP_VERSION, + E2PROM_MAP_CONFIG, + E2PROM_MAP_ACL, + E2PROM_MAP_I2S, + E2PROM_MAP_SPDIF, + E2PROM_MAP_GPIOMASK, + E2PROM_MAP_GPIOSTATE, + E2PROM_MAP_GPIODIR, + E2PROM_MAP_AC97MAIN, + E2PROM_MAP_AC97PCM = 0x0F, + E2PROM_MAP_AC97REC = 0x11, + E2PROM_MAP_AC97REC_SOURCE = 0x13, + E2PROM_MAP_DAC_ID = 0x14, + E2PROM_MAP_ADC_ID = 0x18, + E2PROM_MAP_EXTRA = 0x1C +} ice1712EEprom; #endif diff --git a/src/add-ons/kernel/drivers/audio/ice1712/ice1712_reg.h b/src/add-ons/kernel/drivers/audio/ice1712/ice1712_reg.h index d8c87af2e6..e8453bda29 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/ice1712_reg.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/ice1712_reg.h @@ -1,167 +1,130 @@ /* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. * - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com */ + #ifndef _ICE1712_REG_H_ #define _ICE1712_REG_H_ -//------------------------------------------------------ -//------------------------------------------------------ //PCI Interface and Configuration Registers (Page 3.1) //Table 3.1 -/* -#define PCI_VENDOR_ID 0x00 //2 bytes -#define PCI_DEVICE_ID 0x02 //2 bytes -#define PCI_COMMAND 0x04 //2 bytes -#define PCI_DEVICE_STATUS 0x06 //2 bytes -#define PCI_REVISION_ID 0x08 //1 byte -#define PCI_CLASS_CODE 0x0A //2 bytes -#define PCI_LATENCY_TIMER 0x0D //1 byte -#define PCI_HEADER_TYPE 0x0E //1 byte -#define PCI_BIST 0x0F //1 byte -#define PCI_CONTROLLER_BASE_AD 0x10 //4 bytes -#define PCI_DDMA_BASE_AD 0x14 //4 bytes -#define PCI_DMA_BASE_AD 0x18 //4 bytes -#define PCI_MULTI_BASE_AD 0x1C //4 bytes -#define PCI_SUB_VENDOR_ID 0x2C //2 bytes -#define PCI_SUB_SYSTEM_ID 0x2E //2 bytes -#define PCI_CAPABILITY_POINTER 0x34 //4 bytes -#define PCI_INT_PIN_LINE 0x3C //2 bytes -#define PCI_LATENCY_GRANT 0x3E //2 bytes -#define PCI_LEGACY_AUDIO_CONTROL 0x40 //2 bytes -#define PCI_LEGACY_CONF_CONTROL 0x42 //2 bytes -#define PCI_HARD_CONF_CONTROL 0x60 //4 bytes -#define PCI_CAPABILITY_ID 0x80 //1 byte -#define PCI_NEXT_ITEM_POINTER 0x81 //1 byte -#define PCI_POWER_CAPABILITY 0x82 //2 bytes -#define PCI_POWER_CONTROL_STATUS 0x84 //2 bytes -#define PCI_PMCSR_EXT_DATA 0x86 //2 bytes -*/ -//------------------------------------------------------ -//------------------------------------------------------ +#define PCI_VENDOR_ID 0x00 //2 bytes +#define PCI_DEVICE_ID 0x02 //2 bytes +#define PCI_COMMAND 0x04 //2 bytes +#define PCI_DEVICE_STATUS 0x06 //2 bytes +#define PCI_REVISION_ID 0x08 //1 byte +#define PCI_CLASS_CODE 0x0A //2 bytes +#define PCI_LATENCY_TIMER 0x0D //1 byte +#define PCI_HEADER_TYPE 0x0E //1 byte +#define PCI_BIST 0x0F //1 byte +#define PCI_CONTROLLER_BASE_AD 0x10 //4 bytes +#define PCI_DDMA_BASE_AD 0x14 //4 bytes +#define PCI_DMA_BASE_AD 0x18 //4 bytes +#define PCI_MULTI_BASE_AD 0x1C //4 bytes +#define PCI_SUB_VENDOR_ID 0x2C //2 bytes +#define PCI_SUB_SYSTEM_ID 0x2E //2 bytes +#define PCI_CAPABILITY_POINTER 0x34 //4 bytes +#define PCI_INT_PIN_LINE 0x3C //2 bytes +#define PCI_LATENCY_GRANT 0x3E //2 bytes +#define PCI_LEGACY_AUDIO_CONTROL 0x40 //2 bytes +#define PCI_LEGACY_CONF_CONTROL 0x42 //2 bytes +#define PCI_HARD_CONF_CONTROL 0x60 //4 bytes +#define PCI_CAPABILITY_ID 0x80 //1 byte +#define PCI_NEXT_ITEM_POINTER 0x81 //1 byte +#define PCI_POWER_CAPABILITY 0x82 //2 bytes +#define PCI_POWER_CONTROL_STATUS 0x84 //2 bytes +#define PCI_PMCSR_EXT_DATA 0x86 //2 bytes + //CCSxx Controller Register Map (Page 4.3) //Table 4.2 -#define CCS_CONTROL_STATUS 0x00 //1 byte -#define CCS_INTERRUPT_MASK 0x01 //1 byte -#define CCS_INTERRUPT_STATUS 0x02 //1 byte -#define CCS_CCI_INDEX 0x03 //1 byte -#define CCS_CCI_DATA 0x04 //1 byte -#define CCS_NMI_STATUS_1 0x05 //1 byte -#define CCS_NMI_DATA 0x06 //1 byte -#define CCS_NMI_INDEX 0x07 //1 byte -#define CCS_CONS_AC97_INDEX 0x08 //1 byte -#define CCS_CONS_AC97_COMMAND_STATUS 0x09 //1 byte -#define CCS_CONS_AC97_DATA 0x0A //2 bytes -#define CCS_MIDI_1_DATA 0x0C //1 byte -#define CCS_MIDI_1_COMMAND_STATUS 0x0D //1 byte -#define CCS_NMI_STATUS_2 0x0E //1 byte -#define CCS_GAME_PORT 0x0F //1 byte -#define CCS_I2C_DEV_ADDRESS 0x10 //1 byte -#define CCS_I2C_BYTE_ADDRESS 0x11 //1 byte -#define CCS_I2C_DATA 0x12 //1 byte -#define CCS_I2C_CONTROL_STATUS 0x13 //1 byte -#define CCS_CONS_DMA_BASE_ADDRESS 0x14 //4 bytes -#define CCS_CONS_DMA_COUNT_ADDRESS 0x18 //2 bytes -#define CCS_SERR_SHADOW 0x1B //1 byte -#define CCS_MIDI_2_DATA 0x1C //1 byte -#define CCS_MIDI_2_COMMAND_STATUS 0x1D //1 byte -#define CCS_TIMER 0x1E //2 bytes -//------------------------------------------------------ -//------------------------------------------------------ +#define CCS_CONTROL_STATUS 0x00 //1 byte +#define CCS_INTERRUPT_MASK 0x01 //1 byte +#define CCS_INTERRUPT_STATUS 0x02 //1 byte +#define CCS_CCI_INDEX 0x03 //1 byte +#define CCS_CCI_DATA 0x04 //1 byte +#define CCS_NMI_STATUS_1 0x05 //1 byte +#define CCS_NMI_DATA 0x06 //1 byte +#define CCS_NMI_INDEX 0x07 //1 byte +#define CCS_CONS_AC97_INDEX 0x08 //1 byte +#define CCS_CONS_AC97_COMMAND_STATUS 0x09 //1 byte +#define CCS_CONS_AC97_DATA 0x0A //2 bytes +#define CCS_MIDI_1_DATA 0x0C //1 byte +#define CCS_MIDI_1_COMMAND_STATUS 0x0D //1 byte +#define CCS_NMI_STATUS_2 0x0E //1 byte +#define CCS_GAME_PORT 0x0F //1 byte +#define CCS_I2C_DEV_ADDRESS 0x10 //1 byte +#define CCS_I2C_BYTE_ADDRESS 0x11 //1 byte +#define CCS_I2C_DATA 0x12 //1 byte +#define CCS_I2C_CONTROL_STATUS 0x13 //1 byte +#define CCS_CONS_DMA_BASE_ADDRESS 0x14 //4 bytes +#define CCS_CONS_DMA_COUNT_ADDRESS 0x18 //2 bytes +#define CCS_SERR_SHADOW 0x1B //1 byte +#define CCS_MIDI_2_DATA 0x1C //1 byte +#define CCS_MIDI_2_COMMAND_STATUS 0x1D //1 byte +#define CCS_TIMER 0x1E //2 bytes + //Controller Indexed Register (Page 4.12) -#define CCI_PB_TERM_COUNT_HI 0x00 //1 byte -#define CCI_PB_TERM_COUNT_LO 0x01 //1 byte -#define CCI_PB_CONTROL 0x02 //1 byte -#define CCI_PB_LEFT_VOLUME 0x03 //1 byte -#define CCI_PB_RIGHT_VOLUME 0x04 //1 byte -#define CCI_SOFT_VOLUME 0x05 //1 byte -#define CCI_PB_SAMPLING_RATE_LO 0x06 //1 byte -#define CCI_PB_SAMPLING_RATE_MI 0x07 //1 byte -#define CCI_PB_SAMPLING_RATE_HI 0x08 //1 byte -#define CCI_REC_TERM_COUNT_HI 0x10 //1 byte -#define CCI_REC_TERM_COUNT_LO 0x11 //1 byte -#define CCI_REC_CONTROL 0x12 //1 byte -#define CCI_GPIO_DATA 0x20 //1 byte -#define CCI_GPIO_WRITE_MASK 0x21 //1 byte -#define CCI_GPIO_DIRECTION_CONTROL 0x22 //1 byte -#define CCI_CONS_POWER_DOWN 0x30 //1 byte -#define CCI_MULTI_POWER_DOWN 0x31 //1 byte -//------------------------------------------------------ -//------------------------------------------------------ +#define CCI_PB_TERM_COUNT_HI 0x00 //1 byte +#define CCI_PB_TERM_COUNT_LO 0x01 //1 byte +#define CCI_PB_CONTROL 0x02 //1 byte +#define CCI_PB_LEFT_VOLUME 0x03 //1 byte +#define CCI_PB_RIGHT_VOLUME 0x04 //1 byte +#define CCI_SOFT_VOLUME 0x05 //1 byte +#define CCI_PB_SAMPLING_RATE_LO 0x06 //1 byte +#define CCI_PB_SAMPLING_RATE_MI 0x07 //1 byte +#define CCI_PB_SAMPLING_RATE_HI 0x08 //1 byte +#define CCI_REC_TERM_COUNT_HI 0x10 //1 byte +#define CCI_REC_TERM_COUNT_LO 0x11 //1 byte +#define CCI_REC_CONTROL 0x12 //1 byte +#define CCI_GPIO_DATA 0x20 //1 byte +#define CCI_GPIO_WRITE_MASK 0x21 //1 byte +#define CCI_GPIO_DIRECTION_CONTROL 0x22 //1 byte +#define CCI_CONS_POWER_DOWN 0x30 //1 byte +#define CCI_MULTI_POWER_DOWN 0x31 //1 byte + //Consumer Section DMA Channel Registers (Page 4.20) //Table 4.4 -#define DS_DMA_INT_MASK 0x00 //2 bytes -#define DS_DMA_INT_STATUS 0x02 //2 bytes -#define DS_CHANNEL_DATA 0x04 //4 bytes -#define DS_CHANNEL_INDEX 0x08 //1 byte -//------------------------------------------------------ -//------------------------------------------------------ +#define DS_DMA_INT_MASK 0x00 //2 bytes +#define DS_DMA_INT_STATUS 0x02 //2 bytes +#define DS_CHANNEL_DATA 0x04 //4 bytes +#define DS_CHANNEL_INDEX 0x08 //1 byte + //Professional Multi-Track Control Registers (Page 4.24) //Table 4.7 -#define MT_DMA_INT_MASK_STATUS 0x00 //1 byte -#define MT_SAMPLING_RATE_SELECT 0x01 //1 byte -#define MT_I2S_DATA_FORMAT 0x02 //1 byte -#define MT_PROF_AC97_INDEX 0x04 //1 byte -#define MT_PROF_AC97_COMMAND_STATUS 0x05 //1 byte -#define MT_PROF_AC97_DATA 0x06 //2 bytes -#define MT_PROF_PB_DMA_BASE_ADDRESS 0x10 //4 bytes -#define MT_PROF_PB_DMA_COUNT_ADDRESS 0x14 //2 bytes -#define MT_PROF_PB_DMA_TERM_COUNT 0x16 //2 bytes -#define MT_PROF_PB_CONTROL 0x18 //1 byte -#define MT_PROF_REC_DMA_BASE_ADDRESS 0x20 //4 bytes -#define MT_PROF_REC_DMA_COUNT_ADDRESS 0x24 //2 bytes -#define MT_PROF_REC_DMA_TERM_COUNT 0x26 //2 bytes -#define MT_PROF_REC_CONTROL 0x28 //1 byte -#define MT_ROUTING_CONTROL_PSDOUT 0x30 //2 bytes -#define MT_ROUTING_CONTROL_SPDOUT 0x32 //2 bytes -#define MT_CAPTURED_DATA 0x34 //4 bytes -#define MT_LR_VOLUME_CONTROL 0x38 //2 bytes -#define MT_VOLUME_CONTROL_CHANNEL_INDEX 0x3A //1 byte -#define MT_VOLUME_CONTROL_RATE 0x3B //1 byte -#define MT_MIXER_MONITOR_RETURN 0x3C //1 byte -#define MT_PEAK_METER_INDEX 0x3E //1 byte -#define MT_PEAK_METER_DATA 0x3F //1 byte -//------------------------------------------------------ -//------------------------------------------------------ -#define I2C_EEPROM_ADDRESS_READ 0xA0 //1010 0000 -#define I2C_EEPROM_ADDRESS_WRITE 0xA1 //1010 0001 -//------------------------------------------------------ -//------------------------------------------------------ -#define SPDIF_STEREO_IN 0x02 //0000 0010 -#define SPDIF_STEREO_OUT 0x01 //0000 0001 -//------------------------------------------------------ -//------------------------------------------------------ +#define MT_DMA_INT_MASK_STATUS 0x00 //1 byte +#define MT_SAMPLING_RATE_SELECT 0x01 //1 byte +#define MT_I2S_DATA_FORMAT 0x02 //1 byte +#define MT_PROF_AC97_INDEX 0x04 //1 byte +#define MT_PROF_AC97_COMMAND_STATUS 0x05 //1 byte +#define MT_PROF_AC97_DATA 0x06 //2 bytes +#define MT_PROF_PB_DMA_BASE_ADDRESS 0x10 //4 bytes +#define MT_PROF_PB_DMA_COUNT_ADDRESS 0x14 //2 bytes +#define MT_PROF_PB_DMA_TERM_COUNT 0x16 //2 bytes +#define MT_PROF_PB_CONTROL 0x18 //1 byte +#define MT_PROF_REC_DMA_BASE_ADDRESS 0x20 //4 bytes +#define MT_PROF_REC_DMA_COUNT_ADDRESS 0x24 //2 bytes +#define MT_PROF_REC_DMA_TERM_COUNT 0x26 //2 bytes +#define MT_PROF_REC_CONTROL 0x28 //1 byte +#define MT_ROUTING_CONTROL_PSDOUT 0x30 //2 bytes +#define MT_ROUTING_CONTROL_SPDOUT 0x32 //2 bytes +#define MT_CAPTURED_DATA 0x34 //4 bytes +#define MT_LR_VOLUME_CONTROL 0x38 //2 bytes +#define MT_VOLUME_CONTROL_CHANNEL_INDEX 0x3A //1 byte +#define MT_VOLUME_CONTROL_RATE 0x3B //1 byte +#define MT_MIXER_MONITOR_RETURN 0x3C //1 byte +#define MT_PEAK_METER_INDEX 0x3E //1 byte +#define MT_PEAK_METER_DATA 0x3F //1 byte -//------------------------------------------------------ -//------------------------------------------------------ +#define I2C_EEPROM_ADDRESS_READ 0xA0 //1010 0000 +#define I2C_EEPROM_ADDRESS_WRITE 0xA1 //1010 0001 -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ - -//------------------------------------------------------ -//------------------------------------------------------ +#define SPDIF_STEREO_IN 0x02 //0000 0010 +#define SPDIF_STEREO_OUT 0x01 //0000 0001 #endif diff --git a/src/add-ons/kernel/drivers/audio/ice1712/io.c b/src/add-ons/kernel/drivers/audio/ice1712/io.cpp similarity index 81% rename from src/add-ons/kernel/drivers/audio/ice1712/io.c rename to src/add-ons/kernel/drivers/audio/ice1712/io.cpp index 81990a2a98..371152a69c 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/io.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/io.cpp @@ -1,14 +1,14 @@ /* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com */ + #include "io.h" #include "ice1712_reg.h" #include "debug.h" @@ -16,24 +16,23 @@ extern pci_module_info *pci; static void ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr, - uint8 data, uint8 chip_select, uint8 invert_cs); + uint8 data, uint8 chip_select, uint8 invert_cs); static void cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, - uint8 data, uint8 chip_select, uint8 invert_cs); + uint8 data, uint8 chip_select, uint8 invert_cs); static uint8 ak45xx_read_gpio(ice1712 *ice, uint8 reg_addr, - uint8 chip_select, uint8 invert_cs) - {return 0;} //Unimplemented + uint8 chip_select, uint8 invert_cs) + {return 0;} //Unimplemented static uint8 cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr, - uint8 chip_select, uint8 invert_cs); + uint8 chip_select, uint8 invert_cs); static void write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data); static uint8 read_gpio_byte(ice1712 *ice, uint8 gpio_data); //Address are [PCI_10] + xx - uint8 read_ccs_uint8(ice1712 *ice, int8 regno) { @@ -91,10 +90,8 @@ write_cci_uint8(ice1712 *ice, int8 index, uint8 value) write_ccs_uint8(ice, CCS_CCI_DATA, value); }; -//-------------------------------------------------- -//-------------------------------------------------- -//Address are [PCI_14] + xx +//Address are [PCI_14] + xx uint8 read_ddma_uint8(ice1712 *ice, int8 regno) { @@ -137,8 +134,6 @@ write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value) }; -//-------------------------------------------------- -//-------------------------------------------------- //Address are [PCI_18] + x uint8 read_ds_uint8(ice1712 *ice, int8 regno) @@ -187,7 +182,7 @@ read_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index) { uint8 ds8_channel_index = channel << 4 | index; - write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index); + write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index); return read_ds_uint32(ice, DS_CHANNEL_DATA); } @@ -198,60 +193,60 @@ write_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index, { uint8 ds8_channel_index = channel << 4 | index; - write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index); + write_ds_uint8(ice, DS_CHANNEL_INDEX, ds8_channel_index); write_ds_uint32(ice, DS_CHANNEL_DATA, data); } -//-------------------------------------------------- -//-------------------------------------------------- //Address are [PCI_1C] + xx - uint8 -read_mt_uint8(ice1712 *ice, int8 regno) +read_mt_uint8(ice1712 *ice, int8 regno) { - return pci->read_io_8(ice->Multi_Track + regno); + return pci->read_io_8(ice->Multi_Track + regno); }; uint16 -read_mt_uint16(ice1712 *ice, int8 regno) +read_mt_uint16(ice1712 *ice, int8 regno) { - return pci->read_io_16(ice->Multi_Track + regno); + return pci->read_io_16(ice->Multi_Track + regno); }; uint32 -read_mt_uint32(ice1712 *ice, int8 regno) +read_mt_uint32(ice1712 *ice, int8 regno) { return pci->read_io_32(ice->Multi_Track + regno); }; + void -write_mt_uint8(ice1712 *ice, int8 regno, uint8 value) +write_mt_uint8(ice1712 *ice, int8 regno, uint8 value) { pci->write_io_8(ice->Multi_Track + regno, value); }; void -write_mt_uint16(ice1712 *ice, int8 regno, uint16 value) +write_mt_uint16(ice1712 *ice, int8 regno, uint16 value) { pci->write_io_16(ice->Multi_Track + regno, value); }; void -write_mt_uint32(ice1712 *ice, int8 regno, uint32 value) +write_mt_uint32(ice1712 *ice, int8 regno, uint32 value) { pci->write_io_32(ice->Multi_Track + regno, value); }; +/* + * return -1 if error else return an uint8 + */ int16 read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr) -{//return -1 if error else return an uint8 - +{ if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80) return -1; write_ccs_uint8(ice, CCS_I2C_BYTE_ADDRESS, byte_addr); @@ -261,9 +256,12 @@ read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr) } +/* + * return -1 if error else return 0 + */ int16 write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value) -{//return -1 if error else return 0 +{ if (read_ccs_uint8(ice, CCS_I2C_CONTROL_STATUS) != 0x80) return -1; @@ -302,11 +300,13 @@ int16 read_eeprom(ice1712 *ice, uint8 eeprom[32]) void codec_write(ice1712 *ice, uint8 reg_addr, uint8 data) { - switch (ice->product) { + switch (ice->config.product) { case ICE1712_SUBDEVICE_DELTA66: case ICE1712_SUBDEVICE_DELTA44: - ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_0, 0); - ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_1, 0); + ak45xx_write_gpio(ice, reg_addr, data, + DELTA66_CODEC_CS_0, 0); + ak45xx_write_gpio(ice, reg_addr, data, + DELTA66_CODEC_CS_1, 0); break; case ICE1712_SUBDEVICE_DELTA410: case ICE1712_SUBDEVICE_AUDIOPHILE_2496: @@ -315,14 +315,14 @@ codec_write(ice1712 *ice, uint8 reg_addr, uint8 data) break; case ICE1712_SUBDEVICE_DELTA1010: case ICE1712_SUBDEVICE_DELTA1010LT: - ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_0, - DELTA1010LT_CS_NONE); - ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_1, - DELTA1010LT_CS_NONE); - ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_2, - DELTA1010LT_CS_NONE); - ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_3, - DELTA1010LT_CS_NONE); + ak45xx_write_gpio(ice, reg_addr, data, + DELTA1010LT_CODEC_CS_0, DELTA1010LT_CS_NONE); + ak45xx_write_gpio(ice, reg_addr, data, + DELTA1010LT_CODEC_CS_1, DELTA1010LT_CS_NONE); + ak45xx_write_gpio(ice, reg_addr, data, + DELTA1010LT_CODEC_CS_2, DELTA1010LT_CS_NONE); + ak45xx_write_gpio(ice, reg_addr, data, + DELTA1010LT_CODEC_CS_3, DELTA1010LT_CS_NONE); break; case ICE1712_SUBDEVICE_VX442: ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0, 0); @@ -335,7 +335,7 @@ codec_write(ice1712 *ice, uint8 reg_addr, uint8 data) void spdif_write(ice1712 *ice, uint8 reg_addr, uint8 data) { - switch (ice->product) { + switch (ice->config.product) { case ICE1712_SUBDEVICE_DELTA1010: break; case ICE1712_SUBDEVICE_DELTADIO2496: @@ -351,7 +351,7 @@ spdif_write(ice1712 *ice, uint8 reg_addr, uint8 data) break; case ICE1712_SUBDEVICE_DELTA1010LT: cs84xx_write_gpio(ice, reg_addr, data, DELTA1010LT_SPDIF_CS, - DELTA1010LT_CS_NONE); + DELTA1010LT_CS_NONE); break; case ICE1712_SUBDEVICE_VX442: cs84xx_write_gpio(ice, reg_addr, data, VX442_SPDIF_CS, 0); @@ -364,7 +364,7 @@ uint8 codec_read(ice1712 *ice, uint8 reg_addr) { uint8 val = 0xFF; - switch (ice->product) { + switch (ice->config.product) { case ICE1712_SUBDEVICE_DELTA66: case ICE1712_SUBDEVICE_DELTA44: val = ak45xx_read_gpio(ice, reg_addr, DELTA66_CODEC_CS_0, 0); @@ -377,7 +377,7 @@ codec_read(ice1712 *ice, uint8 reg_addr) case ICE1712_SUBDEVICE_DELTA1010: case ICE1712_SUBDEVICE_DELTA1010LT: val = ak45xx_read_gpio(ice, reg_addr, DELTA1010LT_CODEC_CS_0, - DELTA1010LT_CS_NONE); + DELTA1010LT_CS_NONE); break; case ICE1712_SUBDEVICE_VX442: val = ak45xx_read_gpio(ice, reg_addr, VX442_CODEC_CS_0, 0); @@ -392,7 +392,7 @@ uint8 spdif_read(ice1712 *ice, uint8 reg_addr) { uint8 val = 0xFF; - switch (ice->product) { + switch (ice->config.product) { case ICE1712_SUBDEVICE_DELTA1010: break; case ICE1712_SUBDEVICE_DELTADIO2496: @@ -408,7 +408,7 @@ spdif_read(ice1712 *ice, uint8 reg_addr) break; case ICE1712_SUBDEVICE_DELTA1010LT: val = cs84xx_read_gpio(ice, reg_addr, DELTA1010LT_SPDIF_CS, - DELTA1010LT_CS_NONE); + DELTA1010LT_CS_NONE); break; case ICE1712_SUBDEVICE_VX442: val = cs84xx_read_gpio(ice, reg_addr, VX442_SPDIF_CS, 0); @@ -418,6 +418,7 @@ spdif_read(ice1712 *ice, uint8 reg_addr) return val; } + void write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data) { @@ -441,6 +442,7 @@ write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data) } } + uint8 read_gpio_byte(ice1712 *ice, uint8 gpio_data) { @@ -453,7 +455,7 @@ read_gpio_byte(ice1712 *ice, uint8 gpio_data) write_gpio(ice, gpio_data); snooze(GPIO_I2C_DELAY); - if (read_gpio(ice) & ice->CommLines.data_in) + if (read_gpio(ice) &ice->CommLines.data_in) data |= 1 << i; gpio_data |= ice->CommLines.clock; @@ -465,6 +467,7 @@ read_gpio_byte(ice1712 *ice, uint8 gpio_data) return data; } + void ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, uint8 chip_select, uint8 invert_cs) @@ -497,6 +500,7 @@ ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, snooze(GPIO_I2C_DELAY); } + void cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, uint8 chip_select, uint8 invert_cs) @@ -529,6 +533,7 @@ cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, snooze(GPIO_I2C_DELAY); } + uint8 cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr, uint8 chip_select, uint8 invert_cs) @@ -586,16 +591,21 @@ cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr, uint8 chip_select, } +/* + * return -1 if error else return an uint8 + */ uint8 read_gpio(ice1712 *ice) -{//return -1 if error else return an uint8 +{ return read_cci_uint8(ice, CCI_GPIO_DATA); } +/* + * return -1 if error else return 0 + */ void write_gpio(ice1712 *ice, uint8 value) -{//return -1 if error else return 0 +{ write_cci_uint8(ice, CCI_GPIO_DATA, value); } - diff --git a/src/add-ons/kernel/drivers/audio/ice1712/io.h b/src/add-ons/kernel/drivers/audio/ice1712/io.h index 5d45cb7824..20faecc440 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/io.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/io.h @@ -1,14 +1,14 @@ /* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com */ + #ifndef _IO_H_ #define _IO_H_ @@ -16,40 +16,34 @@ #include -//------------------------------------------------------ -//------------------------------------------------------ //Address are [PCI_10] + xx -uint8 read_ccs_uint8(ice1712 *ice, int8 regno); -uint16 read_ccs_uint16(ice1712 *ice, int8 regno); -uint32 read_ccs_uint32(ice1712 *ice, int8 regno); +uint8 read_ccs_uint8(ice1712 *ice, int8 regno); +uint16 read_ccs_uint16(ice1712 *ice, int8 regno); +uint32 read_ccs_uint32(ice1712 *ice, int8 regno); +void write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value); +void write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value); +void write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value); + +uint8 read_cci_uint8(ice1712 *ice, int8 index); +void write_cci_uint8(ice1712 *ice, int8 index, uint8 value); -void write_ccs_uint8(ice1712 *ice, int8 regno, uint8 value); -void write_ccs_uint16(ice1712 *ice, int8 regno, uint16 value); -void write_ccs_uint32(ice1712 *ice, int8 regno, uint32 value); -//------------------------------------------------------ -//------------------------------------------------------ -uint8 read_cci_uint8(ice1712 *ice, int8 index); -void write_cci_uint8(ice1712 *ice, int8 index, uint8 value); -//------------------------------------------------------ -//------------------------------------------------------ //Address are [PCI_14] + xx -uint8 read_ddma_uint8(ice1712 *ice, int8 regno); -uint16 read_ddma_uint16(ice1712 *ice, int8 regno); -uint32 read_ddma_uint32(ice1712 *ice, int8 regno); +uint8 read_ddma_uint8(ice1712 *ice, int8 regno); +uint16 read_ddma_uint16(ice1712 *ice, int8 regno); +uint32 read_ddma_uint32(ice1712 *ice, int8 regno); + +void write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value); +void write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value); +void write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value); -void write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value); -void write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value); -void write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value); -//------------------------------------------------------ -//------------------------------------------------------ //Address are [PCI_18] + x -uint8 read_ds_uint8(ice1712 *ice, int8 regno); -uint16 read_ds_uint16(ice1712 *ice, int8 regno); -uint32 read_ds_uint32(ice1712 *ice, int8 regno); +uint8 read_ds_uint8(ice1712 *ice, int8 regno); +uint16 read_ds_uint16(ice1712 *ice, int8 regno); +uint32 read_ds_uint32(ice1712 *ice, int8 regno); -void write_ds_uint8(ice1712 *ice, int8 regno, uint8 value); -void write_ds_uint16(ice1712 *ice, int8 regno, uint16 value); -void write_ds_uint32(ice1712 *ice, int8 regno, uint32 value); +void write_ds_uint8(ice1712 *ice, int8 regno, uint8 value); +void write_ds_uint16(ice1712 *ice, int8 regno, uint16 value); +void write_ds_uint32(ice1712 *ice, int8 regno, uint32 value); typedef enum { DS8_REGISTER_BUFFER_0_BASE_ADDRESS = 0, @@ -61,26 +55,23 @@ typedef enum { DS8_REGISTER_LEFT_RIGHT_VOLUME, } ds8_register; -uint32 read_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index); -void write_ds_channel_data(ice1712 *ice, uint8 channel, - ds8_register index, uint32 data); -//------------------------------------------------------ -//------------------------------------------------------ +uint32 read_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index); +void write_ds_channel_data(ice1712 *ice, uint8 channel, ds8_register index, + uint32 data); + //Address are [PCI_1C] + xx -uint8 read_mt_uint8(ice1712 *ice, int8 regno); -uint16 read_mt_uint16(ice1712 *ice, int8 regno); -uint32 read_mt_uint32(ice1712 *ice, int8 regno); +uint8 read_mt_uint8(ice1712 *ice, int8 regno); +uint16 read_mt_uint16(ice1712 *ice, int8 regno); +uint32 read_mt_uint32(ice1712 *ice, int8 regno); -void write_mt_uint8(ice1712 *ice, int8 regno, uint8 value); -void write_mt_uint16(ice1712 *ice, int8 regno, uint16 value); -void write_mt_uint32(ice1712 *ice, int8 regno, uint32 value); -//------------------------------------------------------ -//------------------------------------------------------ +void write_mt_uint8(ice1712 *ice, int8 regno, uint8 value); +void write_mt_uint16(ice1712 *ice, int8 regno, uint16 value); +void write_mt_uint32(ice1712 *ice, int8 regno, uint32 value); -int16 read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr); +int16 read_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr); //return -1 if error else return an uint8 -int16 write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value); +int16 write_i2c(ice1712 *ice, uint8 dev_addr, uint8 byte_addr, uint8 value); //return -1 if error else return 0 //------------------------------------------------------ @@ -101,9 +92,9 @@ uint8 spdif_read_mult(ice1712 *ice, uint8 reg_addr, uint8 datas[], uint8 size); //------------------------------------------------------ -uint8 read_gpio(ice1712 *ice); +uint8 read_gpio(ice1712 *ice); //return -1 if error else return an uint8 -void write_gpio(ice1712 *ice, uint8 value); +void write_gpio(ice1712 *ice, uint8 value); #endif diff --git a/src/add-ons/kernel/drivers/audio/ice1712/midi.c b/src/add-ons/kernel/drivers/audio/ice1712/midi.c deleted file mode 100644 index 4581df48d7..0000000000 --- a/src/add-ons/kernel/drivers/audio/ice1712/midi.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller - * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. - */ - -#include -#include -#include -#include - -#include "ice1712.h" -#include "ice1712_reg.h" -#include "io.h" -#include "util.h" -#include "debug.h" - -extern generic_mpu401_module * mpu401; - - -void -ice_1712_midi_interrupt_op(int32 op, void *data) -{ - 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); -} - - -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 (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; - } - } - } - - return ret; -} - - -status_t -ice_1712_midi_close(void* cookie) -{ - TRACE("**midi_close()\n"); - return (*mpu401->close_hook)(cookie); -} - - -status_t -ice_1712_midi_free(void* cookie) -{ - 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; - } - } - } - - return ret; -} - - -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); -} - - -status_t -ice_1712_midi_read(void * cookie, off_t pos, void * ptr, size_t * nread) -{ - status_t ret = B_ERROR; - - ret = (*mpu401->read_hook)(cookie, pos, ptr, nread); - //TRACE("**midi_read(%ld)\n", ret); - - return ret; -} - - -status_t -ice_1712_midi_write(void * cookie, off_t pos, const void * ptr, - size_t * nwritten) -{ - status_t ret = B_ERROR; - - ret = (*mpu401->write_hook)(cookie, pos, ptr, nwritten); - //TRACE("**midi_write(%ld)\n", ret); - - return ret; -} diff --git a/src/add-ons/kernel/drivers/audio/ice1712/midi.cpp b/src/add-ons/kernel/drivers/audio/ice1712/midi.cpp new file mode 100644 index 0000000000..fdd06c1873 --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/ice1712/midi.cpp @@ -0,0 +1,167 @@ +/* + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com + */ + + +#include +#include +#include +#include + +#include "ice1712.h" +#include "ice1712_reg.h" +#include "io.h" +#include "util.h" +#include "debug.h" + +extern generic_mpu401_module * mpu401; +extern int32 num_cards; +extern ice1712 cards[NUM_CARDS]; + +void ice1712Midi_interrupt(int32 op, void *data); + + +void +ice1712Midi_interrupt(int32 op, void *data) +{ + cpu_status status; + uint8 int_status = 0; + ice1712Midi *midi = (ice1712Midi*)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); + + ITRACE("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); + + ITRACE("B_MPU_401_DISABLE_CARD_INT: %s\n", midi->name); + + unlock(status); + } + + ITRACE("New mask status 0x%x\n", int_status); +} + + +static status_t +ice1712Midi_open(const char *name, uint32 flags, void **cookie) +{ + int midi, card; + status_t ret = ENODEV; + + ITRACE("**midi_open()\n"); + *cookie = NULL; + + for (card = 0; card < num_cards; card++) { + for (midi = 0; midi < cards[card].config.nb_MPU401; midi++) { + if (!strcmp(name, cards[card].midiItf[midi].name)) { + ice1712Midi *dev = &(cards[card].midiItf[midi]); + ret = (*mpu401->open_hook)(dev->mpu401device, flags, cookie); + if (ret >= B_OK) { + *cookie = dev->mpu401device; + } + break; + } + } + } + + return ret; +} + + +static status_t +ice1712Midi_close(void* cookie) +{ + ITRACE("**midi_close()\n"); + return (*mpu401->close_hook)(cookie); +} + + +static status_t +ice1712Midi_free(void* cookie) +{ + int midi, card; + status_t ret; + + ITRACE("**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].midiItf[midi].mpu401device) { + cards[card].midiItf[midi].mpu401device = NULL; + ITRACE("Cleared %p card %d, midi %d\n", cookie, card, midi); + break; + } + } + } + + return ret; +} + + +static status_t +ice1712Midi_control(void* cookie, + uint32 iop, void* data, size_t len) +{ + ITRACE("**midi_control()\n"); + return (*mpu401->control_hook)(cookie, iop, data, len); +} + + +static status_t +ice1712Midi_read(void * cookie, off_t pos, void * ptr, size_t * nread) +{ + status_t ret = B_ERROR; + + ret = (*mpu401->read_hook)(cookie, pos, ptr, nread); + ITRACE_VV("**midi_read: %" B_PRIi32 "\n", ret); + + return ret; +} + + +static status_t +ice1712Midi_write(void * cookie, off_t pos, const void * ptr, + size_t * nwritten) +{ + status_t ret = B_ERROR; + + ret = (*mpu401->write_hook)(cookie, pos, ptr, nwritten); + ITRACE_VV("**midi_write: %" B_PRIi32 "\n", ret); + + return ret; +} + + +device_hooks ice1712Midi_hooks = +{ + ice1712Midi_open, + ice1712Midi_close, + ice1712Midi_free, + ice1712Midi_control, + ice1712Midi_read, + ice1712Midi_write, + NULL, + NULL, + NULL, + NULL +}; diff --git a/src/add-ons/kernel/drivers/audio/ice1712/multi.c b/src/add-ons/kernel/drivers/audio/ice1712/multi.cpp similarity index 61% rename from src/add-ons/kernel/drivers/audio/ice1712/multi.c rename to src/add-ons/kernel/drivers/audio/ice1712/multi.cpp index 745315f89b..b4292f7e9a 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/multi.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/multi.cpp @@ -1,12 +1,11 @@ /* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com */ @@ -18,6 +17,24 @@ #include #include "debug.h" +status_t ice1712Settings_apply(ice1712 *card); + +static void ice1712Buffer_Start(ice1712 *card); +static uint32 ice1712UI_GetCombo(ice1712 *card, uint32 index); +static void ice1712UI_SetCombo(ice1712 *card, uint32 index, uint32 value); +static uint32 ice1712UI_GetOutput(ice1712 *card, uint32 index); +static void ice1712UI_SetOutput(ice1712 *card, uint32 index, uint32 value); +static void ice1712UI_GetVolume(ice1712 *card, multi_mix_value *mmv); +static void ice1712UI_SetVolume(ice1712 *card, multi_mix_value *mmv); +static void ice1712UI_CreateOutput(ice1712 *card, multi_mix_control **p_mmc, + int32 output, int32 parent); +static void ice1712UI_CreateCombo(multi_mix_control **p_mmc, + const char *values[], int32 parent, int32 nb_combo, const char *name); +static void ice1712UI_CreateChannel(multi_mix_control **p_mmc, + int32 channel, int32 parent, const char* name); +static int32 ice1712UI_CreateGroup(multi_mix_control **p_mmc, + int32 index, int32 parent, enum strind_id string, const char* name); +static int32 nb_control_created; #define AUTHORIZED_RATE (B_SR_SAME_AS_INPUT | B_SR_96000 \ | B_SR_88200 | B_SR_48000 | B_SR_44100) @@ -25,34 +42,36 @@ #define MAX_CONTROL 32 +//ICE1712 Multi - Buffer +//---------------------- -static void -start_DMA(ice1712 *card) +void +ice1712Buffer_Start(ice1712 *card) { uint16 size = card->buffer_size * MAX_DAC; write_mt_uint8(card, MT_PROF_PB_CONTROL, 0); write_mt_uint32(card, MT_PROF_PB_DMA_BASE_ADDRESS, - (uint32)card->phys_addr_pb); + (uint32)(card->phys_pb.address)); write_mt_uint16(card, MT_PROF_PB_DMA_COUNT_ADDRESS, - (size * SWAPPING_BUFFERS) - 1); + (size * SWAPPING_BUFFERS) - 1); //We want interrupt only from playback write_mt_uint16(card, MT_PROF_PB_DMA_TERM_COUNT, size - 1); - TRACE("SIZE DMA PLAYBACK %#x\n", size); + ITRACE("SIZE DMA PLAYBACK %#x\n", size); size = card->buffer_size * MAX_ADC; write_mt_uint32(card, MT_PROF_REC_DMA_BASE_ADDRESS, - (uint32)card->phys_addr_rec); + (uint32)(card->phys_rec.address)); write_mt_uint16(card, MT_PROF_REC_DMA_COUNT_ADDRESS, - (size * SWAPPING_BUFFERS) - 1); + (size * SWAPPING_BUFFERS) - 1); //We do not want any interrupt from the record write_mt_uint16(card, MT_PROF_REC_DMA_TERM_COUNT, 0); - TRACE("SIZE DMA RECORD %#x\n", size); + ITRACE("SIZE DMA RECORD %#x\n", size); //Enable output AND Input from Analog CODEC - switch (card->product) { + switch (card->config.product) { //TODO: find correct value for all card case ICE1712_SUBDEVICE_DELTA66: case ICE1712_SUBDEVICE_DELTA44: @@ -71,7 +90,7 @@ start_DMA(ice1712 *card) } //Set Data Format for SPDif codec - switch (card->product) { + switch (card->config.product) { //TODO: find correct value for all card case ICE1712_SUBDEVICE_DELTA1010: break; @@ -90,10 +109,14 @@ start_DMA(ice1712 *card) case ICE1712_SUBDEVICE_DELTA410: break; case ICE1712_SUBDEVICE_DELTA1010LT: -// ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_0); -// ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_1); -// ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_2); -// ak45xx_write_gpio(ice, reg_addr, data, DELTA1010LT_CODEC_CS_3); +// ak45xx_write_gpio(ice, reg_addr, data, +// DELTA1010LT_CODEC_CS_0); +// ak45xx_write_gpio(ice, reg_addr, data, +// DELTA1010LT_CODEC_CS_1); +// ak45xx_write_gpio(ice, reg_addr, data, +// DELTA1010LT_CODEC_CS_2); +// ak45xx_write_gpio(ice, reg_addr, data, +// DELTA1010LT_CODEC_CS_3); break; case ICE1712_SUBDEVICE_VX442: // ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0); @@ -107,14 +130,71 @@ start_DMA(ice1712 *card) status_t -ice1712_get_description(ice1712 *card, multi_description *data) +ice1712Buffer_Exchange(ice1712 *card, multi_buffer_info *data) +{ + multi_buffer_info buffer_info; + +#ifdef __HAIKU__ + if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(&buffer_info, data, sizeof(buffer_info)); +#endif + + buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; + + if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT + | B_CAN_INTERRUPT, 50000) == B_TIMED_OUT) { + ITRACE("buffer_exchange timeout\n"); + }; + + // Playback buffers info + buffer_info.played_real_time = card->played_time; + buffer_info.played_frames_count = card->frames_count; + buffer_info.playback_buffer_cycle = (card->buffer - 1) + % SWAPPING_BUFFERS; //Buffer played + + // Record buffers info + buffer_info.recorded_real_time = card->played_time; + buffer_info.recorded_frames_count = card->frames_count; + buffer_info.record_buffer_cycle = (card->buffer - 1) + % SWAPPING_BUFFERS; //Buffer filled + +#ifdef __HAIKU__ + if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(data, &buffer_info, sizeof(buffer_info)); +#endif + + return B_OK; +} + + +status_t +ice1712Buffer_Stop(ice1712 *card) +{ + write_mt_uint8(card, MT_PROF_PB_CONTROL, 0); + + card->played_time = 0; + card->frames_count = 0; + card->buffer = 0; + + return B_OK; +} + +//ICE1712 Multi - Description +//--------------------------- + +status_t +ice1712Get_Description(ice1712 *card, multi_description *data) { int chan = 0, i, size; data->interface_version = B_CURRENT_INTERFACE_VERSION; data->interface_minimum = B_CURRENT_INTERFACE_VERSION; - switch (card->product) { + switch (card->config.product) { case ICE1712_SUBDEVICE_DELTA1010: strncpy(data->friendly_name, "Delta 1010", 32); break; @@ -153,11 +233,12 @@ ice1712_get_description(ice1712 *card, multi_description *data) data->input_bus_channel_count = 0; data->aux_bus_channel_count = 0; - size = data->output_channel_count + data->input_channel_count + size = data->output_channel_count + data->input_channel_count + data->output_bus_channel_count + data->input_bus_channel_count + data->aux_bus_channel_count; - TRACE_VV("request_channel_count = %ld\n", data->request_channel_count); + ITRACE_VV("request_channel_count = %" B_PRIi32 "\n", + data->request_channel_count); if (size <= data->request_channel_count) { for (i = 0; i < card->config.nb_DAC; i++) { @@ -227,10 +308,14 @@ ice1712_get_description(ice1712 *card, multi_description *data) chan++; } - TRACE("output_channel_count = %ld\n", data->output_channel_count); - TRACE("input_channel_count = %ld\n", data->input_channel_count); - TRACE("output_bus_channel_count = %ld\n", data->output_bus_channel_count); - TRACE("input_bus_channel_count = %ld\n", data->input_bus_channel_count); + ITRACE("output_channel_count = %" B_PRIi32 "\n", + data->output_channel_count); + ITRACE("input_channel_count = %" B_PRIi32 "\n", + data->input_channel_count); + ITRACE("output_bus_channel_count = %" B_PRIi32 "\n", + data->output_bus_channel_count); + ITRACE("input_bus_channel_count = %" B_PRIi32 "\n", + data->input_bus_channel_count); data->output_rates = data->input_rates = AUTHORIZED_RATE; data->min_cvsr_rate = 44100; @@ -250,7 +335,7 @@ ice1712_get_description(ice1712 *card, multi_description *data) status_t -ice1712_get_enabled_channels(ice1712 *card, multi_channel_enable *data) +ice1712Get_Channel(ice1712 *card, multi_channel_enable *data) { int i, total_channel; uint8 reg; @@ -271,32 +356,33 @@ ice1712_get_enabled_channels(ice1712 *card, multi_channel_enable *data) status_t -ice1712_set_enabled_channels(ice1712 *card, multi_channel_enable *data) +ice1712Set_Channel(ice1712 *card, multi_channel_enable *data) { int i; int total_channel; total_channel = card->total_output_channels + card->total_input_channels; for (i = 0; i < total_channel; i++) - TRACE("set_enabled_channels %d : %s\n", i, + ITRACE_VV("set_enabled_channels %d : %s\n", i, B_TEST_CHANNEL(data->enable_bits, i) ? "enabled": "disabled"); - TRACE("lock_source %#08X\n", (int)data->lock_source); - TRACE("lock_data %#08X\n", (int)data->lock_data); + ITRACE_VV("lock_source %" B_PRIx32 "\n", data->lock_source); + ITRACE_VV("lock_data %" B_PRIx32 "\n", data->lock_data); if (data->lock_source == B_MULTI_LOCK_SPDIF) write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, 0x10); else - write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, card->sampling_rate); + write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, + card->config.samplingRate); - card->lock_source = data->lock_source; + card->config.lockSource = data->lock_source; return B_OK; } status_t -ice1712_get_global_format(ice1712 *card, multi_format_info *data) +ice1712Get_Format(ice1712 *card, multi_format_info *data) { uint8 sr = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT); @@ -323,17 +409,19 @@ ice1712_get_global_format(ice1712 *card, multi_format_info *data) data->output_latency = data->input_latency = 0; data->output.format = data->input.format = AUTHORIZED_SAMPLE_SIZE; - TRACE("Sampling Rate = %f\n", data->input.cvsr); + ITRACE("Sampling Rate = %f\n", data->input.cvsr); return B_OK; } status_t -ice1712_set_global_format(ice1712 *card, multi_format_info *data) +ice1712Set_Format(ice1712 *card, multi_format_info *data) { - TRACE("Input Sampling Rate = %d\n", data->input.rate); - TRACE("Output Sampling Rate = %d\n", data->output.rate); + ITRACE("Input Sampling Rate = %" B_PRIu32 "\n", + data->input.rate); + ITRACE("Output Sampling Rate = %" B_PRIu32 "\n", + data->output.rate); //We can't have a different rate for input and output //so just wait to change our sample rate when @@ -342,259 +430,31 @@ ice1712_set_global_format(ice1712 *card, multi_format_info *data) if (data->input.rate != data->output.rate) return B_OK; - if (card->lock_source == B_MULTI_LOCK_INTERNAL) { + if (card->config.lockSource == B_MULTI_LOCK_INTERNAL) { switch (data->output.rate) { case B_SR_96000: - card->sampling_rate = 0x07; + card->config.samplingRate = 0x07; break; case B_SR_88200: - card->sampling_rate = 0x0B; + card->config.samplingRate = 0x0B; break; case B_SR_48000: - card->sampling_rate = 0x00; + card->config.samplingRate = 0x00; break; case B_SR_44100: - card->sampling_rate = 0x08; + card->config.samplingRate = 0x08; break; } - write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, card->sampling_rate); + write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, + card->config.samplingRate); } - TRACE("New rate = %#x\n", read_mt_uint8(card, MT_SAMPLING_RATE_SELECT)); + ITRACE("New rate = %#x\n", read_mt_uint8(card, MT_SAMPLING_RATE_SELECT)); return B_OK; } - -static uint32 -get_combo_cb(ice1712 *card, uint32 index) -{ - uint32 value = 0; - - TRACE_VV(" get_combo_cb: %ld, %ld\n", index, value); - - switch (index) { - case 0: - value = card->settings.clock; - break; - - case 1: - value = card->settings.outFormat; - break; - - case 2: - value = card->settings.emphasis; - break; - - case 3: - value = card->settings.copyMode; - break; - } - - return value; -} - - -static void -set_combo_cb(ice1712 *card, uint32 index, uint32 value) -{ - TRACE_VV(" set_combo_cb: %ld, %ld\n", index, value); - - switch (index) { - case 0: - if (value < 2) - card->settings.clock = value; - break; - - case 1: - if (value < 2) - card->settings.outFormat = value; - break; - - case 2: - if (value < 3) - card->settings.emphasis = value; - break; - - case 3: - if (value < 3) - card->settings.copyMode = value; - break; - } -} - - -static uint32 -get_output_cb(ice1712 *card, uint32 index) -{ - uint32 value = 0; - - if (index < 5) - value = card->settings.output[index]; - - TRACE_VV(" get_output_cb: %ld, %ld\n", index, value); - - return value; -} - - -static void -set_output_cb(ice1712 *card, uint32 index, uint32 value) -{ - if (index < 5) - card->settings.output[index] = value; - - TRACE_VV(" set_output_cb: %ld, %ld\n", index, value); -} - - -static void -get_volume_cb(ice1712 *card, multi_mix_value *mmv) -{ - channel_volume *vol; - uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id); - - TRACE_VV(" get_volume_cb\n"); - - if (chan < ICE1712_HARDWARE_VOLUME) { - vol = card->settings.playback; - } - else { - vol = card->settings.record; - chan -= ICE1712_HARDWARE_VOLUME; - } - - //chan is normaly <= ICE1712_HARDWARE_VOLUME - switch (ICE1712_MULTI_GET_INDEX(mmv->id)) { - case 0: //Mute - mmv->u.enable = vol[chan].mute | vol[chan + 1].mute; - TRACE_VV("\tGet mute %d for channel %d or %d\n", - mmv->u.enable, (int)chan, (int)chan + 1); - break; - - case 2: //Right channel - chan++; - //No break - case 1: //Left channel - mmv->u.gain = vol[chan].volume; - TRACE_VV("\tGet Volume %f for channel %d\n", - mmv->u.gain, (int)chan); - break; - } -} - - -static void -set_volume_cb(ice1712 *card, multi_mix_value *mmv) -{ - channel_volume *vol; - uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id); - - TRACE_VV(" set_volume_cb\n"); - - if (chan < ICE1712_HARDWARE_VOLUME) { - vol = card->settings.playback; - } - else { - vol = card->settings.record; - chan -= ICE1712_HARDWARE_VOLUME; - } - - //chan is normaly <= ICE1712_HARDWARE_VOLUME - switch (ICE1712_MULTI_GET_INDEX(mmv->id)) { - case 0: //Mute - vol[chan].mute = mmv->u.enable; - vol[chan + 1].mute = mmv->u.enable; - TRACE_VV("\tChange mute to %d for channel %d and %d\n", - mmv->u.enable, (int)chan, (int)chan + 1); - break; - - case 2: //Right channel - chan++; - //No break - case 1: //Left channel - vol[chan].volume = mmv->u.gain; - TRACE_VV("\tChange Volume to %f for channel %d\n", - mmv->u.gain, (int)chan); - break; - } -} - - -status_t -ice1712_get_mix(ice1712 *card, multi_mix_value_info *data) -{ - int i; - TRACE_VV(" Asking to get %ld control(s)\n", data->item_count); - - for (i = 0; i < data->item_count; i++) { - multi_mix_value *mmv = &(data->values[i]); - TRACE_VV(" Id %#x\n", (unsigned int)mmv->id); - switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) { - case ICE1712_MULTI_CONTROL_TYPE_COMBO: - mmv->u.mux = get_combo_cb(card, - ICE1712_MULTI_GET_CHANNEL(mmv->id)); - break; - - case ICE1712_MULTI_CONTROL_TYPE_VOLUME: - get_volume_cb(card, mmv); - break; - - case ICE1712_MULTI_CONTROL_TYPE_OUTPUT: - mmv->u.mux = get_output_cb(card, - ICE1712_MULTI_GET_CHANNEL(mmv->id)); - break; - - default: - TRACE_VV(" default 0x%x\n", (unsigned int)mmv->id); - break; - } - } - - return B_OK; -} - - -status_t -ice1712_set_mix(ice1712 *card, multi_mix_value_info *data) -{ - int i; - - TRACE_VV(" Asking to set %ld control(s)\n", data->item_count); - - for (i = 0; i < data->item_count; i++) { - multi_mix_value *mmv = &(data->values[i]); - TRACE_VV(" Id %#x\n", (unsigned int)mmv->id); - switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) { - case ICE1712_MULTI_CONTROL_TYPE_COMBO: - set_combo_cb(card, ICE1712_MULTI_GET_CHANNEL(mmv->id), - mmv->u.mux); - break; - - case ICE1712_MULTI_CONTROL_TYPE_VOLUME: - set_volume_cb(card, mmv); - break; - - case ICE1712_MULTI_CONTROL_TYPE_OUTPUT: - set_output_cb(card, ICE1712_MULTI_GET_CHANNEL(mmv->id), - mmv->u.mux); - break; - - default: - TRACE_VV(" default 0x%x\n", (unsigned int)mmv->id); - break; - } - } - - return apply_settings(card); -} - - -status_t -ice1712_list_mix_channels(ice1712 *card, multi_mix_channel_info *data) -{ - //Not Implemented - return B_OK; -} +//ICE1712 Multi - UI +//------------------ static const char *Clock[] = { "Internal", @@ -669,19 +529,17 @@ static const char *string_list[] = { "Internal mixer", //22 }; -static int32 nb_control_created; - -//This will create a Tab -static int32 -create_group_control(multi_mix_control **p_mmc, int32 index, int32 parent, - enum strind_id string, const char* name) +/* + * This will create a Tab + */ +int32 +ice1712UI_CreateGroup(multi_mix_control **p_mmc, int32 index, + int32 parent, enum strind_id string, const char* name) { multi_mix_control *mmc = *p_mmc; int32 group; - TRACE_VV("Create ID create_group_control\n"); - mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_SET_INDEX(index); mmc->parent = parent; mmc->flags = B_MULTI_MIX_GROUP; @@ -693,7 +551,7 @@ create_group_control(multi_mix_control **p_mmc, int32 index, int32 parent, if (name != NULL) strcpy(mmc->name, name); - TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + ITRACE_VV("Create Group: ID %#" B_PRIx32 "\n", mmc->id); nb_control_created++; mmc++; (*p_mmc) = mmc; @@ -702,10 +560,12 @@ create_group_control(multi_mix_control **p_mmc, int32 index, int32 parent, } -//This will create a Slider with a "Mute" CheckBox -static void -create_channel_control(multi_mix_control **p_mmc, int32 channel, int32 parent, - const char* name) +/* + * This will create a Slider with a "Mute" CheckBox + */ +void +ice1712UI_CreateChannel(multi_mix_control **p_mmc, int32 channel, + int32 parent, const char* name) { int32 id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_CONTROL_TYPE_VOLUME @@ -713,13 +573,11 @@ create_channel_control(multi_mix_control **p_mmc, int32 channel, int32 parent, multi_mix_control *mmc = *p_mmc; multi_mix_control control; - TRACE_VV("Create ID create_channel_control\n"); - control.master = CONTROL_IS_MASTER; control.parent = parent; - control.u.gain.max_gain = 0.0; - control.u.gain.min_gain = -144.0; - control.u.gain.granularity = 1.5; + control.gain.max_gain = 0.0; + control.gain.min_gain = -144.0; + control.gain.granularity = 1.5; //The Mute Checkbox control.id = id++; @@ -728,7 +586,7 @@ create_channel_control(multi_mix_control **p_mmc, int32 channel, int32 parent, *mmc = control; mmc++; - TRACE_VV("Create ID %#x\n", (unsigned int)control.id); + ITRACE_VV("Create Channel (Mute): ID %#" B_PRIx32 "\n", control.id); //The Left Slider control.string = S_null; @@ -739,7 +597,7 @@ create_channel_control(multi_mix_control **p_mmc, int32 channel, int32 parent, *mmc = control; mmc++; - TRACE_VV("Create ID %#x\n", (unsigned int)control.id); + ITRACE_VV("Create Channel (Left): ID %#" B_PRIx32 "\n", control.id); //The Right Slider control.master = control.id; //The Id of the Left Slider @@ -747,15 +605,15 @@ create_channel_control(multi_mix_control **p_mmc, int32 channel, int32 parent, *mmc = control; mmc++; - TRACE_VV("Create ID %#x\n", (unsigned int)control.id); + ITRACE_VV("Create Channel (Right): ID %#" B_PRIx32 "\n", control.id); nb_control_created += 3; (*p_mmc) = mmc; } -static void -create_combo_control(multi_mix_control **p_mmc, const char *values[], +void +ice1712UI_CreateCombo(multi_mix_control **p_mmc, const char *values[], int32 parent, int32 nb_combo, const char *name) { int32 id = ICE1712_MULTI_CONTROL_FIRSTID @@ -764,15 +622,13 @@ create_combo_control(multi_mix_control **p_mmc, const char *values[], multi_mix_control *mmc = *p_mmc; int32 parentControl, i; - TRACE_VV("Create ID create_combo_control\n"); - //The label parentControl = mmc->id = id++; mmc->flags = B_MULTI_MIX_MUX; mmc->parent = parent; strcpy(mmc->name, name); - TRACE_VV("Create ID %#x\n", (unsigned int)parentControl); + ITRACE_VV("Create Combo (label): ID %#" B_PRIx32 "\n", parentControl); nb_control_created++; mmc++; @@ -783,7 +639,7 @@ create_combo_control(multi_mix_control **p_mmc, const char *values[], mmc->parent = parentControl; strcpy(mmc->name, values[i]); - TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + ITRACE_VV("Create Combo (value): ID %#" B_PRIx32 "\n", mmc->id); nb_control_created++; mmc++; } @@ -792,10 +648,12 @@ create_combo_control(multi_mix_control **p_mmc, const char *values[], } -//This will create all possible value for the output -//output 0 -> 3 (physical stereo output) 4 is the Digital -static void -create_output_choice(ice1712 *card, multi_mix_control **p_mmc, +/* + * This will create all possible value for the output + * output 0 -> 3 (physical stereo output) 4 is the Digital + */ +void +ice1712UI_CreateOutput(ice1712 *card, multi_mix_control **p_mmc, int32 output, int32 parent) { int32 id = ICE1712_MULTI_CONTROL_FIRSTID @@ -804,8 +662,6 @@ create_output_choice(ice1712 *card, multi_mix_control **p_mmc, multi_mix_control *mmc = *p_mmc; int32 parentControl, i; - TRACE_VV("Create ID create_output_choice\n"); - //The label parentControl = mmc->id = id++; mmc->flags = B_MULTI_MIX_MUX; @@ -813,7 +669,7 @@ create_output_choice(ice1712 *card, multi_mix_control **p_mmc, strcpy(mmc->name, string_list[11 + output]); nb_control_created++; mmc++; - TRACE_VV("Create ID %#x\n", (unsigned int)parentControl); + ITRACE_VV("Create Output (label): ID %#" B_PRIx32 "\n", parentControl); //Haiku output mmc->id = id++; @@ -821,7 +677,7 @@ create_output_choice(ice1712 *card, multi_mix_control **p_mmc, mmc->parent = parentControl; strcpy(mmc->name, string_list[16]); - TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + ITRACE_VV("Create Output (Haiku): ID %#" B_PRIx32 "\n", mmc->id); nb_control_created++; mmc++; @@ -832,7 +688,7 @@ create_output_choice(ice1712 *card, multi_mix_control **p_mmc, mmc->parent = parentControl; strcpy(mmc->name, string_list[17 + (i / 2)]); - TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + ITRACE_VV("Create Output (Physical In): ID %#" B_PRIx32 "\n", mmc->id); nb_control_created++; mmc++; } @@ -844,7 +700,7 @@ create_output_choice(ice1712 *card, multi_mix_control **p_mmc, mmc->parent = parentControl; strcpy(mmc->name, string_list[21]); - TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + ITRACE_VV("Create Output (Digital In) ID %#" B_PRIx32 "\n", mmc->id); nb_control_created++; mmc++; } @@ -856,7 +712,7 @@ create_output_choice(ice1712 *card, multi_mix_control **p_mmc, mmc->parent = parentControl; strcpy(mmc->name, string_list[22]); - TRACE_VV("Create ID %#x\n", (unsigned int)mmc->id); + ITRACE_VV("Create Output (Mix); ID %#" B_PRIx32 "\n", mmc->id); nb_control_created++; mmc++; } @@ -865,191 +721,437 @@ create_output_choice(ice1712 *card, multi_mix_control **p_mmc, } -status_t -ice1712_list_mix_controls(ice1712 *card, multi_mix_control_info *mmci) +uint32 +ice1712UI_GetCombo(ice1712 *card, uint32 index) { - uint32 i, parentTab, parentTabColumn; + uint32 value = 0; + + switch (index) { + case 0: + value = card->settings.clock; + break; + + case 1: + value = card->settings.outFormat; + break; + + case 2: + value = card->settings.emphasis; + break; + + case 3: + value = card->settings.copyMode; + break; + } + + ITRACE_VV("Get combo: %" B_PRIu32 ", %" B_PRIu32 "\n", + index, value); + + return value; +} + + +void +ice1712UI_SetCombo(ice1712 *card, uint32 index, uint32 value) +{ + ITRACE_VV("Set combo: %" B_PRIu32 ", %" B_PRIu32 "\n", index, value); + + switch (index) { + case 0: + if (value < 2) + card->settings.clock = value; + break; + + case 1: + if (value < 2) + card->settings.outFormat = value; + break; + + case 2: + if (value < 3) + card->settings.emphasis = value; + break; + + case 3: + if (value < 3) + card->settings.copyMode = value; + break; + } +} + + +uint32 +ice1712UI_GetOutput(ice1712 *card, uint32 index) +{ + uint32 value = 0; + + if (index < 5) + value = card->settings.output[index]; + + ITRACE_VV("Get output: %" B_PRIu32 ", %" B_PRIu32 "\n", index, value); + + return value; +} + + +void +ice1712UI_SetOutput(ice1712 *card, uint32 index, uint32 value) +{ + if (index < 5) + card->settings.output[index] = value; + + ITRACE_VV("Set output: %" B_PRIu32 ", %" B_PRIu32 "\n", index, value); +} + + +void +ice1712UI_GetVolume(ice1712 *card, multi_mix_value *mmv) +{ + ice1712Volume *vol; + uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id); + + ITRACE_VV("Get volume\n"); + + if (chan < ICE1712_HARDWARE_VOLUME) { + vol = card->settings.playback; + } else { + vol = card->settings.record; + chan -= ICE1712_HARDWARE_VOLUME; + } + + //chan is normaly <= ICE1712_HARDWARE_VOLUME + switch (ICE1712_MULTI_GET_INDEX(mmv->id)) { + case 0: //Mute + mmv->enable = vol[chan].mute | vol[chan + 1].mute; + ITRACE_VV(" Get mute %d for channel %d or %d\n", + mmv->enable, (int)chan, (int)chan + 1); + break; + + case 2: //Right channel + chan++; + //No break + case 1: //Left channel + mmv->gain = vol[chan].volume; + ITRACE_VV(" Get Volume %f for channel %d\n", + mmv->gain, (int)chan); + break; + } +} + + +void +ice1712UI_SetVolume(ice1712 *card, multi_mix_value *mmv) +{ + ice1712Volume *vol; + uint32 chan = ICE1712_MULTI_GET_CHANNEL(mmv->id); + + ITRACE_VV("Set volume\n"); + + if (chan < ICE1712_HARDWARE_VOLUME) { + vol = card->settings.playback; + } else { + vol = card->settings.record; + chan -= ICE1712_HARDWARE_VOLUME; + } + + //chan is normaly <= ICE1712_HARDWARE_VOLUME + switch (ICE1712_MULTI_GET_INDEX(mmv->id)) { + case 0: //Mute + vol[chan].mute = mmv->enable; + vol[chan + 1].mute = mmv->enable; + ITRACE_VV(" Change mute to %d for channel %d and %d\n", + mmv->enable, (int)chan, (int)chan + 1); + break; + + case 2: //Right channel + chan++; + //No break + case 1: //Left channel + vol[chan].volume = mmv->gain; + ITRACE_VV(" Change Volume to %f for channel %d\n", + mmv->gain, (int)chan); + break; + } +} + +//ICE1712 Multi - MIX +//------------------- + +status_t +ice1712Get_MixValue(ice1712 *card, multi_mix_value_info *data) +{ + int i; + + for (i = 0; i < data->item_count; i++) { + multi_mix_value *mmv = &(data->values[i]); + ITRACE_VV("Get Mix: Id %" B_PRIu32 "\n", mmv->id); + switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) { + case ICE1712_MULTI_CONTROL_TYPE_COMBO: + mmv->mux = ice1712UI_GetCombo(card, + ICE1712_MULTI_GET_CHANNEL(mmv->id)); + break; + + case ICE1712_MULTI_CONTROL_TYPE_VOLUME: + ice1712UI_GetVolume(card, mmv); + break; + + case ICE1712_MULTI_CONTROL_TYPE_OUTPUT: + mmv->mux = ice1712UI_GetOutput(card, + ICE1712_MULTI_GET_CHANNEL(mmv->id)); + break; + + default: + ITRACE_VV("Get Mix: unknow %" B_PRIu32 "\n", mmv->id); + break; + } + } + + return B_OK; +} + + +status_t +ice1712Set_MixValue(ice1712 *card, multi_mix_value_info *data) +{ + int i; + + for (i = 0; i < data->item_count; i++) { + multi_mix_value *mmv = &(data->values[i]); + ITRACE_VV("Set Mix: Id %" B_PRIu32 "\n", mmv->id); + switch (mmv->id & ICE1712_MULTI_CONTROL_TYPE_MASK) { + case ICE1712_MULTI_CONTROL_TYPE_COMBO: + ice1712UI_SetCombo(card, + ICE1712_MULTI_GET_CHANNEL(mmv->id), mmv->mux); + break; + + case ICE1712_MULTI_CONTROL_TYPE_VOLUME: + ice1712UI_SetVolume(card, mmv); + break; + + case ICE1712_MULTI_CONTROL_TYPE_OUTPUT: + ice1712UI_SetOutput(card, + ICE1712_MULTI_GET_CHANNEL(mmv->id), mmv->mux); + break; + + default: + ITRACE_VV("Set Mix: unknow %" B_PRIu32 "\n", mmv->id); + break; + } + } + + return ice1712Settings_apply(card); +} + + +/* + * Not implemented + */ +status_t +ice1712Get_MixValueChannel(ice1712 *card, multi_mix_channel_info *data) +{ + return B_OK; +} + + +status_t +ice1712Get_MixValueControls(ice1712 *card, multi_mix_control_info *mmci) +{ + int32 i; + uint32 parentTab, parentTabColumn; multi_mix_control *mmc = mmci->controls; uint32 group = 0, combo = 0, channel = 0; nb_control_created = 0; - TRACE_VV("count = %ld\n", mmci->control_count); + ITRACE_VV("Get MixValue Channels: Max %" B_PRIi32 "\n", mmci->control_count); //Cleaning memset(mmc, 0, mmci->control_count * sizeof(multi_mix_control)); //Setup tab - parentTab = create_group_control(&mmc, group++, + parentTab = ice1712UI_CreateGroup(&mmc, group++, CONTROL_IS_MASTER, S_SETUP, NULL); //General Settings - parentTabColumn = create_group_control(&mmc, group++, parentTab, + parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, parentTab, S_null, string_list[1]); for (i = 0; SettingsGeneral[i] != NULL; i++) { - create_combo_control(&mmc, SettingsGeneral[i], parentTabColumn, + ice1712UI_CreateCombo(&mmc, SettingsGeneral[i], parentTabColumn, combo++, string_list[5 + i]); } //Digital Settings - parentTabColumn = create_group_control(&mmc, group++, parentTab, + parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, parentTab, S_null, string_list[2]); for (i = 0; SettingsDigital[i] != NULL; i++) { - create_combo_control(&mmc, SettingsDigital[i], parentTabColumn, + ice1712UI_CreateCombo(&mmc, SettingsDigital[i], parentTabColumn, combo++, string_list[8 + i]); } //Output Selection Settings - parentTabColumn = create_group_control(&mmc, group++, parentTab, + parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, parentTab, S_null, string_list[3]); for (i = 0; i < card->config.nb_DAC; i += 2) { - create_output_choice(card, &mmc, i / 2, parentTabColumn); + ice1712UI_CreateOutput(card, &mmc, i / 2, parentTabColumn); } if (card->config.spdif & SPDIF_OUT_PRESENT) { - create_output_choice(card, &mmc, 4, parentTabColumn); + ice1712UI_CreateOutput(card, &mmc, 4, parentTabColumn); } //Internal Mixer Tab //Output - parentTab = create_group_control(&mmc, group++, CONTROL_IS_MASTER, + parentTab = ice1712UI_CreateGroup(&mmc, group++, CONTROL_IS_MASTER, S_null, string_list[4]); for (i = 0; i < card->config.nb_DAC; i += 2) { - parentTabColumn = create_group_control(&mmc, group++, parentTab, - S_null, string_list[(i / 2) + 11]); - create_channel_control(&mmc, channel++, parentTabColumn, NULL); + parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, + parentTab, S_null, string_list[(i / 2) + 11]); + ice1712UI_CreateChannel(&mmc, channel++, parentTabColumn, NULL); } if (card->config.spdif & SPDIF_OUT_PRESENT) { - parentTabColumn = create_group_control(&mmc, group++, parentTab, - S_null, string_list[15]); - create_channel_control(&mmc, ICE1712_HARDWARE_VOLUME - 2, + parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, + parentTab, S_null, string_list[15]); + ice1712UI_CreateChannel(&mmc, ICE1712_HARDWARE_VOLUME - 2, parentTabColumn, NULL); } //Input channel = ICE1712_HARDWARE_VOLUME; for (i = 0; i < card->config.nb_ADC; i += 2) { - parentTabColumn = create_group_control(&mmc, group++, parentTab, - S_null, string_list[(i / 2) + 17]); - create_channel_control(&mmc, channel++, parentTabColumn, NULL); + parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, + parentTab, S_null, string_list[(i / 2) + 17]); + ice1712UI_CreateChannel(&mmc, channel++, parentTabColumn, NULL); } if (card->config.spdif & SPDIF_IN_PRESENT) { - parentTabColumn = create_group_control(&mmc, group++, parentTab, - S_null, string_list[21]); - create_channel_control(&mmc, 2 * ICE1712_HARDWARE_VOLUME - 2, + parentTabColumn = ice1712UI_CreateGroup(&mmc, group++, + parentTab, S_null, string_list[21]); + ice1712UI_CreateChannel(&mmc, 2 * ICE1712_HARDWARE_VOLUME - 2, parentTabColumn, NULL); } - TRACE_VV("Return %ld control(s)\n", nb_control_created); mmci->control_count = nb_control_created; + ITRACE_VV("Get MixValue Channels: Returned %" B_PRIi32 "\n", + mmci->control_count); return B_OK; } +/* + * Not implemented + */ status_t -ice1712_list_mix_connections(ice1712 *card, multi_mix_connection_info *data) -{//Not Implemented +ice1712Get_MixValueConnections(ice1712 *card, + multi_mix_connection_info *data) +{ data->actual_count = 0; return B_OK; } status_t -ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) +ice1712Buffer_Get(ice1712 *card, multi_buffer_list *data) { + const size_t stride_o = MAX_DAC * SAMPLE_SIZE; + const size_t stride_i = MAX_ADC * SAMPLE_SIZE; + const uint32 buf_o = stride_o * card->buffer_size; + const uint32 buf_i = stride_i * card->buffer_size; int buff, chan_i = 0, chan_o = 0; - TRACE_VV("flags = %#lx\n", data->flags); - TRACE_VV("request_playback_buffers = %ld\n", - data->request_playback_buffers); - TRACE_VV("request_playback_channels = %ld\n", - data->request_playback_channels); - TRACE_VV("request_playback_buffer_size = %lx\n", - data->request_playback_buffer_size); - TRACE_VV("request_record_buffers = %ld\n", - data->request_record_buffers); - TRACE_VV("request_record_channels = %ld\n", - data->request_record_channels); - TRACE_VV("request_record_buffer_size = %lx\n", - data->request_record_buffer_size); + ITRACE_VV("flags = %#" B_PRIx32 "\n", data->flags); + ITRACE_VV("request_playback_buffers = %" B_PRIu32 "\n", + data->request_playback_buffers); + ITRACE_VV("request_playback_channels = %" B_PRIu32 "\n", + data->request_playback_channels); + ITRACE_VV("request_playback_buffer_size = %" B_PRIx32 "\n", + data->request_playback_buffer_size); + ITRACE_VV("request_record_buffers = %" B_PRIu32 "\n", + data->request_record_buffers); + ITRACE_VV("request_record_channels = %" B_PRIu32 "\n", + data->request_record_channels); + ITRACE_VV("request_record_buffer_size = %" B_PRIx32 "\n", + data->request_record_buffer_size); for (buff = 0; buff < SWAPPING_BUFFERS; buff++) { - uint32 stride_o = MAX_DAC * SAMPLE_SIZE; - uint32 stride_i = MAX_ADC * SAMPLE_SIZE; - uint32 buf_o = stride_o * card->buffer_size; - uint32 buf_i = stride_i * card->buffer_size; - if (data->request_playback_channels == card->total_output_channels) { for (chan_o = 0; chan_o < card->config.nb_DAC; chan_o++) { //Analog STEREO output - data->playback_buffers[buff][chan_o].base = card->log_addr_pb - + buf_o * buff + SAMPLE_SIZE * chan_o; + data->playback_buffers[buff][chan_o].base = + (char*)(card->log_addr_pb + buf_o * buff + + SAMPLE_SIZE * chan_o); data->playback_buffers[buff][chan_o].stride = stride_o; - TRACE_VV("pb_buffer[%ld][%ld] = %p\n", buff, chan_o, + ITRACE_VV("pb_buffer[%d][%d] = %p\n", buff, chan_o, data->playback_buffers[buff][chan_o].base); } if (card->config.spdif & SPDIF_OUT_PRESENT) { //SPDIF STEREO output - data->playback_buffers[buff][chan_o].base = card->log_addr_pb - + buf_o * buff + SAMPLE_SIZE * SPDIF_LEFT; + data->playback_buffers[buff][chan_o].base = + (char*)(card->log_addr_pb + buf_o * buff + + SAMPLE_SIZE * SPDIF_LEFT); data->playback_buffers[buff][chan_o].stride = stride_o; - TRACE_VV("pb_buffer[%ld][%ld] = %p\n", buff, chan_o, + ITRACE_VV("pb_buffer[%d][%d] = %p\n", buff, chan_o, data->playback_buffers[buff][chan_o].base); chan_o++; - data->playback_buffers[buff][chan_o].base = card->log_addr_pb - + buf_o * buff + SAMPLE_SIZE * SPDIF_RIGHT; + data->playback_buffers[buff][chan_o].base = + (char*)(card->log_addr_pb + buf_o * buff + + SAMPLE_SIZE * SPDIF_RIGHT); data->playback_buffers[buff][chan_o].stride = stride_o; - TRACE_VV("pb_buffer[%ld][%ld] = %p\n", buff, chan_o, + ITRACE_VV("pb_buffer[%d][%d] = %p\n", buff, chan_o, data->playback_buffers[buff][chan_o].base); chan_o++; } } - if (data->request_record_channels == card->total_input_channels) { + if (data->request_record_channels == + card->total_input_channels) { for (chan_i = 0; chan_i < card->config.nb_ADC; chan_i++) { //Analog STEREO input - data->record_buffers[buff][chan_i].base = card->log_addr_rec - + buf_i * buff + SAMPLE_SIZE * chan_i; + data->record_buffers[buff][chan_i].base = + (char*)(card->log_addr_rec + buf_i * buff + + SAMPLE_SIZE * chan_i); data->record_buffers[buff][chan_i].stride = stride_i; - TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i, + ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i, data->record_buffers[buff][chan_i].base); } if (card->config.spdif & SPDIF_IN_PRESENT) { //SPDIF STEREO input - data->record_buffers[buff][chan_i].base = card->log_addr_rec - + buf_i * buff + SAMPLE_SIZE * SPDIF_LEFT; + data->record_buffers[buff][chan_i].base = + (char*)(card->log_addr_rec + buf_i * buff + + SAMPLE_SIZE * SPDIF_LEFT); data->record_buffers[buff][chan_i].stride = stride_i; - TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i, + ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i, data->record_buffers[buff][chan_i].base); chan_i++; - data->record_buffers[buff][chan_i].base = card->log_addr_rec - + buf_i * buff + SAMPLE_SIZE * SPDIF_RIGHT; + data->record_buffers[buff][chan_i].base = + (char*)(card->log_addr_rec + buf_i * buff + + SAMPLE_SIZE * SPDIF_RIGHT); data->record_buffers[buff][chan_i].stride = stride_i; - TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i, + ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i, data->record_buffers[buff][chan_i].base); chan_i++; } //The digital mixer output - data->record_buffers[buff][chan_i].base = card->log_addr_rec - + buf_i * buff + SAMPLE_SIZE * MIXER_OUT_LEFT; + data->record_buffers[buff][chan_i].base = + (char*)(card->log_addr_rec + buf_i * buff + + SAMPLE_SIZE * MIXER_OUT_LEFT); data->record_buffers[buff][chan_i].stride = stride_i; - TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i, + ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i, data->record_buffers[buff][chan_i].base); chan_i++; - data->record_buffers[buff][chan_i].base = card->log_addr_rec - + buf_i * buff + SAMPLE_SIZE * MIXER_OUT_RIGHT; + data->record_buffers[buff][chan_i].base = + (char*)(card->log_addr_rec + buf_i * buff + + SAMPLE_SIZE * MIXER_OUT_RIGHT); data->record_buffers[buff][chan_i].stride = stride_i; - TRACE_VV("rec_buffer[%ld][%ld] = %p\n", buff, chan_i, + ITRACE_VV("rec_buffer[%d][%d] = %p\n", buff, chan_i, data->record_buffers[buff][chan_i].base); chan_i++; } @@ -1059,9 +1161,11 @@ ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) data->return_playback_channels = card->total_output_channels; data->return_playback_buffer_size = card->buffer_size; - TRACE("return_playback_buffers = %ld\n", data->return_playback_buffers); - TRACE("return_playback_channels = %ld\n", data->return_playback_channels); - TRACE("return_playback_buffer_size = %ld\n", + ITRACE("return_playback_buffers = %" B_PRIi32 "\n", + data->return_playback_buffers); + ITRACE("return_playback_channels = %" B_PRIi32 "\n", + data->return_playback_channels); + ITRACE("return_playback_buffer_size = %" B_PRIu32 "\n", data->return_playback_buffer_size); data->return_record_buffers = SWAPPING_BUFFERS; @@ -1069,88 +1173,14 @@ ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) data->return_record_channels = chan_i; data->return_record_buffer_size = card->buffer_size; - TRACE("return_record_buffers = %ld\n", data->return_record_buffers); - TRACE("return_record_channels = %ld\n", data->return_record_channels); - TRACE("return_record_buffer_size = %ld\n", + ITRACE("return_record_buffers = %" B_PRIi32 "\n", + data->return_record_buffers); + ITRACE("return_record_channels = %" B_PRIi32 "\n", + data->return_record_channels); + ITRACE("return_record_buffer_size = %" B_PRIu32 "\n", data->return_record_buffer_size); - start_DMA(card); + ice1712Buffer_Start(card); return B_OK; } - - -status_t -ice1712_buffer_exchange(ice1712 *card, multi_buffer_info *data) -{ - int cpu_status; - - multi_buffer_info buffer_info; - -#ifdef __HAIKU__ - if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK) - return B_BAD_ADDRESS; -#else - memcpy(&buffer_info, data, sizeof(buffer_info)); -#endif - - buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; - - if (acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT - | B_CAN_INTERRUPT, 50000) == B_TIMED_OUT) { - TRACE("buffer_exchange timeout\n"); - }; - - cpu_status = lock(); - - // Playback buffers info - buffer_info.played_real_time = card->played_time; - buffer_info.played_frames_count = card->frames_count; - buffer_info.playback_buffer_cycle = (card->buffer - 1) - % SWAPPING_BUFFERS; //Buffer played - - // Record buffers info - buffer_info.recorded_real_time = card->played_time; - buffer_info.recorded_frames_count = card->frames_count; - buffer_info.record_buffer_cycle = (card->buffer - 1) - % SWAPPING_BUFFERS; //Buffer filled - - unlock(cpu_status); - -/* if ((card->buffer % 1500) == 0) { - uint8 reg8, reg8_dir; - reg8 = read_gpio(card); - reg8_dir = read_cci_uint8(card, CCI_GPIO_DIRECTION_CONTROL); - TRACE("DEBUG === GPIO = %d (dir %d)\n", reg8, reg8_dir); - - reg8 = spdif_read(card, CS84xx_VERSION_AND_CHIP_ID); - TRACE("DEBUG === S/PDif Version : 0x%x\n", reg8); - }*/ - -#ifdef __HAIKU__ - if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK) - return B_BAD_ADDRESS; -#else - memcpy(data, &buffer_info, sizeof(buffer_info)); -#endif - - return B_OK; -} - -status_t ice1712_buffer_force_stop(ice1712 *card) -{ -// int cpu_status; - - write_mt_uint8(card, MT_PROF_PB_CONTROL, 0); - -// cpu_status = lock(); - - card->played_time = 0; - card->frames_count = 0; - card->buffer = 0; - -// unlock(cpu_status); - - return B_OK; -} - diff --git a/src/add-ons/kernel/drivers/audio/ice1712/multi.h b/src/add-ons/kernel/drivers/audio/ice1712/multi.h index df2036188a..89ba9479dd 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/multi.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/multi.h @@ -1,14 +1,14 @@ /* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com */ + #ifndef _ICE1712_MULTI_H_ #define _ICE1712_MULTI_H_ @@ -30,14 +30,14 @@ #define ICE1712_MULTI_CONTROL_CHANNEL_MASK (0x0FF00000) #define ICE1712_MULTI_CONTROL_INDEX_MASK (0x00000FFF) -#define ICE1712_MULTI_SET_CHANNEL(_c_) ((_c_ << 20) & \ +#define ICE1712_MULTI_SET_CHANNEL(_c_) ((_c_ << 20) & \ ICE1712_MULTI_CONTROL_CHANNEL_MASK) -#define ICE1712_MULTI_GET_CHANNEL(_c_) ((_c_ & \ +#define ICE1712_MULTI_GET_CHANNEL(_c_) ((_c_ & \ ICE1712_MULTI_CONTROL_CHANNEL_MASK) >> 20) -#define ICE1712_MULTI_SET_INDEX(_i_) (_i_ & \ +#define ICE1712_MULTI_SET_INDEX(_i_) (_i_ & \ ICE1712_MULTI_CONTROL_INDEX_MASK) -#define ICE1712_MULTI_GET_INDEX(_i_) (_i_ & \ +#define ICE1712_MULTI_GET_INDEX(_i_) (_i_ & \ ICE1712_MULTI_CONTROL_INDEX_MASK) /* @@ -51,25 +51,22 @@ #define CONTROL_IS_MASTER (0) -status_t ice1712_get_description(ice1712 *card, multi_description *data); -status_t ice1712_get_enabled_channels(ice1712 *card, - multi_channel_enable *data); -status_t ice1712_set_enabled_channels(ice1712 *card, - multi_channel_enable *data); -status_t ice1712_get_global_format(ice1712 *card, multi_format_info *data); -status_t ice1712_set_global_format(ice1712 *card, multi_format_info *data); -status_t ice1712_get_mix(ice1712 *card, multi_mix_value_info *data); -status_t ice1712_set_mix(ice1712 *card, multi_mix_value_info *data); -status_t ice1712_list_mix_channels(ice1712 *card, - multi_mix_channel_info *data); -status_t ice1712_list_mix_controls(ice1712 *card, - multi_mix_control_info *data); -status_t ice1712_list_mix_connections(ice1712 *card, - multi_mix_connection_info *data); -status_t ice1712_get_buffers(ice1712 *card, multi_buffer_list *data); -status_t ice1712_buffer_exchange(ice1712 *card, multi_buffer_info *data); -status_t ice1712_buffer_force_stop(ice1712 *card); - +status_t ice1712Get_Description(ice1712 *card, multi_description *data); +status_t ice1712Get_Channel(ice1712 *card, multi_channel_enable *data); +status_t ice1712Set_Channel(ice1712 *card, multi_channel_enable *data); +status_t ice1712Get_Format(ice1712 *card, multi_format_info *data); +status_t ice1712Set_Format(ice1712 *card, multi_format_info *data); +status_t ice1712Get_MixValue(ice1712 *card, multi_mix_value_info *data); +status_t ice1712Set_MixValue(ice1712 *card, multi_mix_value_info *data); +status_t ice1712Get_MixValueChannel(ice1712 *card, + multi_mix_channel_info *data); +status_t ice1712Get_MixValueControls(ice1712 *card, + multi_mix_control_info *data); +status_t ice1712Get_MixValueConnections(ice1712 *card, + multi_mix_connection_info *data); +status_t ice1712Buffer_Get(ice1712 *card, multi_buffer_list *data); +status_t ice1712Buffer_Exchange(ice1712 *card, multi_buffer_info *data); +status_t ice1712Buffer_Stop(ice1712 *card); #endif //_ICE1712_MULTI_H_ diff --git a/src/add-ons/kernel/drivers/audio/ice1712/util.c b/src/add-ons/kernel/drivers/audio/ice1712/util.c deleted file mode 100644 index 2feea676aa..0000000000 --- a/src/add-ons/kernel/drivers/audio/ice1712/util.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller - * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. - */ - -#include -#include -#include - -#include "debug.h" -#include "util.h" - -spinlock slock = B_SPINLOCK_INITIALIZER; - -uint32 round_to_pagesize(uint32 size); - - -cpu_status -lock(void) -{ - cpu_status status = disable_interrupts(); - acquire_spinlock(&slock); - return status; -} - - -void -unlock(cpu_status status) -{ - release_spinlock(&slock); - restore_interrupts(status); -} - - -uint32 -round_to_pagesize(uint32 size) -{ - return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); -} - - -area_id -alloc_mem(void **phy, void **log, size_t size, const char *name) -{ -// TODO: phy should be phys_addr_t*! - physical_entry pe; - void * logadr; - area_id areaid; - status_t rv; - - TRACE("allocating %#08X bytes for %s\n", (int)size, name); - - size = round_to_pagesize(size); - areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS, size, - B_32_BIT_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); - // TODO: The rest of the code doesn't deal correctly with physical - // addresses > 4 GB, so we have to force 32 bit addresses here. - if (areaid < B_OK) { - TRACE("couldn't allocate area %s\n",name); - return B_ERROR; - } - rv = get_memory_map(logadr,size,&pe,1); - if (rv < B_OK) { - delete_area(areaid); - TRACE("couldn't map %s\n",name); - return B_ERROR; - } - memset(logadr,0,size); - if (log) - *log = logadr; - if (phy) - *phy = (void*)(addr_t)pe.address; - TRACE("area = %d, size = %#08X, log = %#08X, phy = %#08X\n", - (int)areaid, (int)size, (int)logadr, (int)pe.address); - return areaid; -} - diff --git a/src/add-ons/kernel/drivers/audio/ice1712/util.cpp b/src/add-ons/kernel/drivers/audio/ice1712/util.cpp new file mode 100644 index 0000000000..01a172edca --- /dev/null +++ b/src/add-ons/kernel/drivers/audio/ice1712/util.cpp @@ -0,0 +1,79 @@ +/* + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com + */ + +#include +#include +#include + +#include "debug.h" +#include "util.h" + +static spinlock slock = B_SPINLOCK_INITIALIZER; +static uint32 round_to_pagesize(uint32 size); + +cpu_status +lock(void) +{ + cpu_status status = disable_interrupts(); + acquire_spinlock(&slock); + return status; +} + + +void +unlock(cpu_status status) +{ + release_spinlock(&slock); + restore_interrupts(status); +} + + +uint32 +round_to_pagesize(uint32 size) +{ + return (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); +} + + +area_id +alloc_mem(physical_entry *phy, addr_t *log, size_t size, const char *name) +{ + void * logadr; + area_id areaid; + status_t rv; + + ITRACE("Allocating %s: ", name); + + size = round_to_pagesize(size); + areaid = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS, size, + B_32_BIT_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); + // TODO: The rest of the code doesn't deal correctly with physical + // addresses > 4 GB, so we have to force 32 bit addresses here. + if (areaid < B_OK) { + ITRACE("couldn't allocate\n"); + return B_ERROR; + } + rv = get_memory_map(logadr, size, phy, 1); + if (rv < B_OK) { + delete_area(areaid); + ITRACE("couldn't map\n"); + return B_ERROR; + } + + if (log) + *log = (addr_t)logadr; + + ITRACE("area = %" B_PRId32 ", size = %" B_PRIuSIZE ", log = 0x%" \ + B_PRIXADDR ", phy = 0x%" B_PRIXPHYSADDR "\n", areaid, size, + *log, phy->address); + + return areaid; +} + diff --git a/src/add-ons/kernel/drivers/audio/ice1712/util.h b/src/add-ons/kernel/drivers/audio/ice1712/util.h index b25997e9e1..ef69e7f95b 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/util.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/util.h @@ -1,21 +1,19 @@ /* - * ice1712 BeOS/Haiku Driver for VIA - VT1712 Multi Channel Audio Controller + * Copyright 2004-2015 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. * - * Copyright (c) 2002, Jerome Duval (jerome.duval@free.fr) - * Copyright (c) 2003, Marcus Overhagen (marcus@overhagen.de) - * Copyright (c) 2007, Jerome Leveque (leveque.jerome@neuf.fr) - * - * All rights reserved - * Distributed under the terms of the MIT license. + * Authors: + * Jérôme Duval, jerome.duval@free.fr + * Marcus Overhagen, marcus@overhagen.de + * Jérôme Lévêque, leveque.jerome@gmail.com */ + #ifndef _UTIL_H_ #define _UTIL_H_ -#include - -area_id alloc_mem(void **phy, void **log, size_t size, const char *name); - +area_id alloc_mem(physical_entry *phy, addr_t *log, size_t size, + const char *name); cpu_status lock(void); void unlock(cpu_status status);