diff --git a/src/add-ons/kernel/drivers/audio/ice1712/Jamfile b/src/add-ons/kernel/drivers/audio/ice1712/Jamfile index 8162afe617..1e11dc0eba 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/Jamfile +++ b/src/add-ons/kernel/drivers/audio/ice1712/Jamfile @@ -5,7 +5,6 @@ SetSubDirSupportedPlatformsBeOSCompatible ; UsePrivateHeaders media ; KernelAddon ice1712 : - debug.c ice1712.c io.c midi.c diff --git a/src/add-ons/kernel/drivers/audio/ice1712/debug.c b/src/add-ons/kernel/drivers/audio/ice1712/debug.c deleted file mode 100644 index fa769fe4cb..0000000000 --- a/src/add-ons/kernel/drivers/audio/ice1712/debug.c +++ /dev/null @@ -1,79 +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 -#include "debug.h" -#include "ice1712.h" - -#if DEBUG > 0 -static const char * logfile="/boot/home/"DRIVER_NAME".log"; -static sem_id loglock; -#endif - -void debug_printf(const char *text,...); -void log_printf(const char *text,...); -void log_create(void); - -void debug_printf(const char *text,...) -{ - char buf[1024]; - va_list ap; - - va_start(ap,text); - vsprintf(buf,text,ap); - va_end(ap); - - dprintf(DRIVER_NAME ": %s",buf); -} - -void log_create(void) -{ -#if DEBUG > 0 - int fd = open(logfile, O_WRONLY | O_CREAT | O_TRUNC, 0666); - const char *text = "Driver for " DRIVER_NAME ", Version " VERSION "\n=================\n"; - loglock = create_sem(1,"logfile sem"); - write(fd,text,strlen(text)); - close(fd); -#endif -} - -void log_printf(const char *text,...) -{ -#if DEBUG > 0 - int fd; - char buf[1024]; - va_list ap; - - va_start(ap,text); - vsprintf(buf,text,ap); - va_end(ap); - - dprintf(DRIVER_NAME ": %s",buf); - - acquire_sem(loglock); - fd = open(logfile, O_WRONLY | O_APPEND); - if (fd > 0) - { - write(fd, buf, strlen(buf)); - close(fd); - } - release_sem(loglock); - - #if DEBUG > 1 - snooze(150000); - #endif -#endif -} - diff --git a/src/add-ons/kernel/drivers/audio/ice1712/debug.h b/src/add-ons/kernel/drivers/audio/ice1712/debug.h index 41a5efacf2..126496e220 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/debug.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/debug.h @@ -8,47 +8,22 @@ * All rights reserved * Distributed under the terms of the MIT license. */ +#ifndef _DEBUG_ICE1712_H_ +#define _DEBUG_ICE1712_H_ -#ifndef _DEBUG_H_ -#define _DEBUG_H_ +#include -/* - * PRINT() executes dprintf if DEBUG = 0 (disabled), or expands to LOG() when DEBUG > 0 - * TRACE() executes dprintf if DEBUG > 0 - * LOG() executes dprintf and writes to the logfile if DEBUG > 0 - */ - -/* DEBUG == 0, no debugging, PRINT writes to syslog - * DEBUG == 1, TRACE & LOG, PRINT - * DEBUG == 2, TRACE & LOG, PRINT with snooze() - */ -#undef DEBUG - -#ifndef DEBUG -// #define DEBUG 1 +#ifdef TRACE +# undef TRACE #endif -#undef PRINT_ICE -#undef TRACE_ICE -#undef ASSERT_ICE - -#if DEBUG > 0 - #define PRINT_ICE(a) log_printf a -// #define TRACE_ICE(a) debug_printf a - #define TRACE_ICE(a) log_printf a - #define LOG_ICE(a) log_printf a - #define LOG_CREATE_ICE() log_create() - #define ASSERT_ICE(a) if (a) {} else LOG_ICE(("ASSERT failed! file = %s, line = %d\n",__FILE__,__LINE__)) - void log_create(); - void log_printf(const char *text,...); - void debug_printf(const char *text,...); +#define TRACE_MULTI_AUDIO +#ifdef TRACE_MULTI_AUDIO +# define TRACE(a...) dprintf("\33[34mice1712:\33[0m " a) #else - void debug_printf(const char *text,...); - #define PRINT_ICE(a) debug_printf a - #define TRACE_ICE(a) ((void)(0)) - #define ASSERT_ICE(a) ((void)(0)) - #define LOG_ICE(a) ((void)(0)) - #define LOG_CREATE_ICE() +# define TRACE(a...) ; #endif -#endif +#define ICE1712_VERY_VERBOSE 0 + +#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.c index 28bfd023f1..725075f91e 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.c @@ -25,7 +25,6 @@ #include "multi.h" #include "util.h" - //------------------------------------------------------ //------------------------------------------------------ @@ -66,6 +65,10 @@ int32 api_version = B_CUR_DRIVER_API_VERSION; //extern status_t unload_kernel_addon(image_id imid); //------------------------------------------------------ + +static status_t load_settings(ice1712 *ice); +static status_t save_settings(ice1712 *ice); + //------------------------------------------------------ status_t init_hardware(void) @@ -74,8 +77,7 @@ status_t init_hardware(void) pci_info info; memset(cards, 0, sizeof(ice1712) * NUM_CARDS); - LOG_CREATE_ICE(); - TRACE_ICE(("===init_hardware()===\n")); + TRACE("===init_hardware()===\n"); if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci)) return ENOSYS; @@ -83,7 +85,7 @@ status_t init_hardware(void) while ((*pci->get_nth_pci_info)(ix, &info) == B_OK) { if ((info.vendor_id == ICE1712_VENDOR_ID) && (info.device_id == ICE1712_DEVICE_ID)) { - TRACE_ICE(("Found at least 1 card\n")); + TRACE("Found at least 1 card\n"); put_module(B_PCI_MODULE_NAME); return B_OK; } @@ -107,6 +109,7 @@ ice_1712_int(void *arg) if (reg8 != 0) { ice->buffer++; ice->played_time = system_time(); + ice->frames_count += ice->buffer_size; release_sem_etc(ice->buffer_ready_sem, 1, B_DO_NOT_RESCHEDULE); write_mt_uint8(ice, MT_DMA_INT_MASK_STATUS, reg8); @@ -153,10 +156,10 @@ ice1712_setup(ice1712 *ice) result = read_eeprom(ice, ice->eeprom_data); -/* TRACE_ICE(("EEprom -> ")); +/* TRACE("EEprom -> "); for (i = 0; i < 32; i++) - TRACE_ICE(("%x, ", eeprom_data[i])); - TRACE_ICE(("<- EEprom\n"));*/ + TRACE("%x, ", eeprom_data[i]); + TRACE("<- EEprom\n");*/ write_ccs_uint8(ice, CCS_SERR_SHADOW, 0x01); @@ -164,15 +167,15 @@ ice1712_setup(ice1712 *ice) ice->info.device_id = ice->eeprom_data[E2PROM_MAP_SUBVENDOR_HIGH] << 8 | 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_ICE(("Product ID : 0x%x\n", ice->product)); + TRACE("Product ID : 0x%x\n", ice->product); write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ice->eeprom_data[E2PROM_MAP_GPIOMASK]); write_cci_uint8(ice, CCI_GPIO_DATA, ice->eeprom_data[E2PROM_MAP_GPIOSTATE]); write_cci_uint8(ice, CCI_GPIO_DIRECTION_CONTROL, ice->eeprom_data[E2PROM_MAP_GPIODIR]); - TRACE_ICE(("CCI_GPIO_WRITE_MASK : 0x%x\n", ice->eeprom_data[E2PROM_MAP_GPIOMASK])); - TRACE_ICE(("CCI_GPIO_DATA : 0x%x\n", ice->eeprom_data[E2PROM_MAP_GPIOSTATE])); - TRACE_ICE(("CCI_GPIO_DIRECTION_CONTROL : 0x%x\n", ice->eeprom_data[E2PROM_MAP_GPIODIR])); + TRACE("CCI_GPIO_WRITE_MASK : 0x%x\n", ice->eeprom_data[E2PROM_MAP_GPIOMASK]); + TRACE("CCI_GPIO_DATA : 0x%x\n", ice->eeprom_data[E2PROM_MAP_GPIOSTATE]); + TRACE("CCI_GPIO_DIRECTION_CONTROL : 0x%x\n", ice->eeprom_data[E2PROM_MAP_GPIODIR]); //Write Configuration in the PCI configuration Register @@ -181,7 +184,7 @@ ice1712_setup(ice1712 *ice) (pci->write_pci_config)(ice->info.bus, ice->info.device, ice->info.function, 0x62, 1, ice->eeprom_data[E2PROM_MAP_I2S]); (pci->write_pci_config)(ice->info.bus, ice->info.device, ice->info.function, 0x63, 1, ice->eeprom_data[E2PROM_MAP_SPDIF]); - TRACE_ICE(("E2PROM_MAP_CONFIG : 0x%x\n", ice->eeprom_data[E2PROM_MAP_CONFIG])); + TRACE("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 // @@ -199,14 +202,14 @@ ice1712_setup(ice1712 *ice) reg8 >>= 2; if ((reg8 & 0x01) != 0) {//Consumer AC'97 Exist - TRACE_ICE(("Consumer AC'97 does exist\n")); + TRACE("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_ICE(("Consumer AC'97 does NOT exist\n")); + TRACE("Consumer AC'97 does NOT exist\n"); } reg8 >>= 1; ice->nb_MPU401 = (reg8 & 0x1) + 1; @@ -216,30 +219,37 @@ ice1712_setup(ice1712 *ice) names[num_names++] = ice->midi_interf[i].name; } - TRACE_ICE(("E2PROM_MAP_SPDIF : 0x%x\n", ice->eeprom_data[E2PROM_MAP_SPDIF])); + TRACE("E2PROM_MAP_SPDIF : 0x%x\n", ice->eeprom_data[E2PROM_MAP_SPDIF]); ice->spdif_config = ice->eeprom_data[E2PROM_MAP_SPDIF]; - switch (ice->product) - { + switch (ice->product) { case ICE1712_SUBDEVICE_DELTA66 : case ICE1712_SUBDEVICE_DELTA44 : - ice->gpio_cs_mask = DELTA66_CLK | DELTA66_DOUT | DELTA66_CODEC_CS_0 | DELTA66_CODEC_CS_1; - ice->analog_codec = (codec_info){DELTA66_CLK, 0, DELTA66_DOUT}; + ice->commlines.clock = DELTA66_CLK; + ice->commlines.data_in = 0; + ice->commlines.data_out = DELTA66_DOUT; + ice->commlines.cs_mask = DELTA66_CLK | DELTA66_DOUT | DELTA66_CODEC_CS_0 | DELTA66_CODEC_CS_1; break; case ICE1712_SUBDEVICE_DELTA410 : case ICE1712_SUBDEVICE_AUDIOPHILE_2496 : case ICE1712_SUBDEVICE_DELTADIO2496 : - ice->gpio_cs_mask = AP2496_CLK | AP2496_DIN | AP2496_DOUT | AP2496_SPDIF_CS | AP2496_CODEC_CS; - ice->analog_codec = (codec_info){AP2496_CLK, AP2496_DIN, AP2496_DOUT}; + ice->commlines.clock = AP2496_CLK; + ice->commlines.data_in = AP2496_DIN; + ice->commlines.data_out = AP2496_DOUT; + ice->commlines.cs_mask = AP2496_CLK | AP2496_DIN | AP2496_DOUT | AP2496_SPDIF_CS | AP2496_CODEC_CS; break; case ICE1712_SUBDEVICE_DELTA1010 : case ICE1712_SUBDEVICE_DELTA1010LT : - ice->gpio_cs_mask = DELTA1010LT_CLK | DELTA1010LT_DIN | DELTA1010LT_DOUT | DELTA1010LT_CS_NONE; - ice->analog_codec = (codec_info){DELTA1010LT_CLK, DELTA1010LT_DIN, DELTA1010LT_DOUT}; + ice->commlines.clock = DELTA1010LT_CLK; + ice->commlines.data_in = DELTA1010LT_DIN; + ice->commlines.data_out = DELTA1010LT_DOUT; + ice->commlines.cs_mask = DELTA1010LT_CLK | DELTA1010LT_DIN | DELTA1010LT_DOUT | DELTA1010LT_CS_NONE; break; case ICE1712_SUBDEVICE_VX442 : - ice->gpio_cs_mask = VX442_SPDIF_CS | VX442_CODEC_CS_0 | VX442_CODEC_CS_1; - ice->analog_codec = (codec_info){VX442_CLK, VX442_DIN, VX442_DOUT}; + ice->commlines.clock = VX442_CLK; + ice->commlines.data_in = VX442_DIN; + ice->commlines.data_out = VX442_DOUT; + ice->commlines.cs_mask = VX442_SPDIF_CS | VX442_CODEC_CS_0 | VX442_CODEC_CS_1; break; } @@ -252,12 +262,12 @@ ice1712_setup(ice1712 *ice) return ice->buffer_ready_sem; } -// TRACE_ICE(("installing interrupt : %0x\n", ice->irq)); +// TRACE("installing interrupt : %0x\n", ice->irq); status = install_io_interrupt_handler(ice->irq, ice_1712_int, ice, 0); if (status == B_OK) - TRACE_ICE(("Install Interrupt Handler == B_OK\n")); + TRACE("Install Interrupt Handler == B_OK\n"); else - TRACE_ICE(("Install Interrupt Handler != B_OK\n")); + TRACE("Install Interrupt Handler != B_OK\n"); ice->mem_id_pb = alloc_mem(&ice->phys_addr_pb, &ice->log_addr_pb, PLAYBACK_BUFFER_TOTAL_SIZE, @@ -281,10 +291,12 @@ ice1712_setup(ice1712 *ice) memset(ice->log_addr_pb, 0, PLAYBACK_BUFFER_TOTAL_SIZE); memset(ice->log_addr_rec, 0, RECORD_BUFFER_TOTAL_SIZE); + load_settings(ice); + ice->sampling_rate = 0x08; ice->buffer = 0; - ice->output_buffer_size = MAX_BUFFER_FRAMES; - ice->input_buffer_size = MAX_BUFFER_FRAMES; + ice->frames_count = 0; + ice->buffer_size = MAX_BUFFER_FRAMES; ice->total_output_channels = ice->nb_DAC; if (ice->spdif_config & NO_IN_YES_OUT) @@ -295,9 +307,16 @@ ice1712_setup(ice1712 *ice) ice->total_input_channels += 2; //Write bits in the GPIO - write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ~(ice->gpio_cs_mask)); + write_cci_uint8(ice, CCI_GPIO_WRITE_MASK, ~(ice->commlines.cs_mask)); //Deselect CS - write_cci_uint8(ice, CCI_GPIO_DATA, ice->gpio_cs_mask); + write_cci_uint8(ice, CCI_GPIO_DATA, ice->commlines.cs_mask); + + //Set the rampe volume to a faster one + write_mt_uint16(ice, MT_VOLUME_CONTROL_RATE, 0x01); + + //Digital Mixer To DAC 0 and SPDIF Out +// write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0x0101); +// write_mt_uint16(ice, MT_ROUTING_CONTROL_SPDOUT, 0x0005); //Just to route all input to all output // write_mt_uint16(ice, MT_ROUTING_CONTROL_PSDOUT, 0xAAAA); @@ -318,15 +337,15 @@ ice1712_setup(ice1712 *ice) write_ccs_uint8(ice, CCS_CONTROL_STATUS, 0x41); reg8 = read_ccs_uint8(ice, CCS_INTERRUPT_MASK); - TRACE_ICE(("-----CCS----- = %x\n", reg8)); + TRACE("-----CCS----- = %x\n", reg8); write_ccs_uint8(ice, CCS_INTERRUPT_MASK, 0x6F); /* reg16 = read_ds_uint16(ice, DS_DMA_INT_MASK); - TRACE_ICE(("-----DS_DMA----- = %x\n", reg16)); + TRACE("-----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_ICE(("-----MT_DMA----- = %x\n", reg8)); + TRACE("-----MT_DMA----- = %x\n", reg8); write_mt_uint8(ice, MT_DMA_INT_MASK_STATUS, 0x00); return B_OK; @@ -339,7 +358,7 @@ init_driver(void) int i = 0; num_cards = 0; - TRACE_ICE(("===init_driver()===\n")); + TRACE("===init_driver()===\n"); if (get_module(B_PCI_MODULE_NAME, (module_info **)&pci)) return ENOSYS; @@ -354,13 +373,13 @@ init_driver(void) 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_ICE(("Too many ice1712 cards installed!\n")); + TRACE("Too many ice1712 cards installed!\n"); break; } if (ice1712_setup(&cards[num_cards]) != B_OK) { //Vendor_ID and Device_ID has been modified - TRACE_ICE(("Setup of ice1712 %d failed\n", num_cards + 1)); + TRACE("Setup of ice1712 %d failed\n", (int)(num_cards + 1)); } else { num_cards++; } @@ -368,7 +387,7 @@ init_driver(void) i++; } - TRACE_ICE(("Number of succesfully initialised card : %d\n", num_cards)); + TRACE("Number of succesfully initialised card : %d\n", (int)num_cards); if (num_cards == 0) { put_module(B_PCI_MODULE_NAME); @@ -388,9 +407,9 @@ ice_1712_shutdown(ice1712 *ice) result = remove_io_interrupt_handler(ice->irq, ice_1712_int, ice); if (result == B_OK) - TRACE_ICE(("remove Interrupt result == B_OK\n")); + TRACE("remove Interrupt result == B_OK\n"); else - TRACE_ICE(("remove Interrupt result != B_OK\n")); + TRACE("remove Interrupt result != B_OK\n"); if (ice->mem_id_pb != B_ERROR) delete_area(ice->mem_id_pb); @@ -399,6 +418,8 @@ ice_1712_shutdown(ice1712 *ice) delete_area(ice->mem_id_rec); codec_write(ice, AK45xx_RESET_REGISTER, 0x00); + + save_settings(ice); } @@ -407,7 +428,7 @@ uninit_driver(void) { int ix, cnt = num_cards; - TRACE_ICE(("===uninit_driver()===\n")); + TRACE("===uninit_driver()===\n"); num_cards = 0; @@ -425,10 +446,10 @@ const char ** publish_devices(void) { int ix = 0; - TRACE_ICE(("===publish_devices()===\n")); + TRACE("===publish_devices()===\n"); for (ix=0; names[ix]; ix++) { - TRACE_ICE(("publish %s\n", names[ix])); + TRACE("publish %s\n", names[ix]); } return (const char **)names; } @@ -439,7 +460,7 @@ ice_1712_open(const char *name, uint32 flags, void **cookie) { int ix; ice1712 *card = NULL; - TRACE_ICE(("===open()===\n")); + TRACE("===open()===\n"); for (ix=0; ixsettings.playback[i].volume = -10.5; + ice->settings.playback[i].mute = false; + } + + for (i = 0; i < 10; i++) { + ice->settings.record[i].volume = -10.5; + ice->settings.record[i].mute = false; + } + + ice->settings.clock = 0; + ice->settings.sample_rate = 3; + ice->settings.buffer_size = 3; + ice->settings.debug_mode = 0; + + //S/PDIF Settings + ice->settings.out_format = 0; + ice->settings.emphasis = 0; + ice->settings.copy_mode = 0; + + return apply_settings(ice); +} + + +status_t +save_settings(ice1712 *ice) +{ + return B_OK; +} + + +#define ICE1712_MUTE_VALUE (0x7F) + +status_t +apply_settings(ice1712 *card) +{ + int i; + uint16 val; + + for (i = 0; i < 10; i++) { + //Select the channel + write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX, i); + + if (card->settings.playback[i].mute) { + val = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8); + } else { + unsigned char 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; + } else {//a left channel + val = ICE1712_MUTE_VALUE << 8; //Mute right volume + val |= volume << 0; + } + } + + write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val); + if (ICE1712_VERY_VERBOSE) + TRACE("Apply Settings %d : 0x%x\n", i, val); + } + + for (i = 0; i < 10; i++) { + //Select the channel + write_mt_uint8(card, MT_VOLUME_CONTROL_CHANNEL_INDEX, i + 10); + + if (card->settings.record[i].mute == true) { + val = (ICE1712_MUTE_VALUE << 0) | (ICE1712_MUTE_VALUE << 8); + } else { + unsigned char volume = card->settings.record[i].volume / -1.5; + if (i & 1) {//a right channel + val = ICE1712_MUTE_VALUE << 0; //Mute left volume + val |= volume << 8; + } else {//a left channel + val = ICE1712_MUTE_VALUE << 8; //Mute right volume + val |= volume << 0; + } + } + + write_mt_uint16(card, MT_LR_VOLUME_CONTROL, val); + } + + + 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 f1acd61949..2afb222e71 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/ice1712.h @@ -13,15 +13,13 @@ #define _ICE1712_H_ #include -#include "hmulti_audio.h" #define DRIVER_NAME "ice1712" -#define VERSION "0.3" +#define VERSION "0.4" #define ICE1712_VENDOR_ID 0x1412 #define ICE1712_DEVICE_ID 0x1712 - typedef enum product_t { ICE1712_SUBDEVICE_DELTA1010 = 0x121430d6, ICE1712_SUBDEVICE_DELTADIO2496 = 0x121431d6, @@ -38,7 +36,7 @@ typedef enum product_t { #define MAX_DAC 10 #define SWAPPING_BUFFERS 2 #define SAMPLE_SIZE 4 -#define MIN_BUFFER_FRAMES 64 +#define MIN_BUFFER_FRAMES 256 #define MAX_BUFFER_FRAMES 2048 #define PLAYBACK_BUFFER_SIZE (MAX_BUFFER_FRAMES * MAX_DAC * SAMPLE_SIZE) @@ -52,6 +50,7 @@ typedef enum product_t { #define MIXER_OUT_LEFT 10 #define MIXER_OUT_RIGHT 11 + typedef enum { NO_IN_NO_OUT = 0, NO_IN_YES_OUT = 1, @@ -59,6 +58,7 @@ typedef enum { YES_IN_YES_OUT = 3, } _spdif_config_ ; + typedef struct _midi_dev { struct _ice1712_ *card; void *driver; @@ -67,15 +67,45 @@ typedef struct _midi_dev { char name[64]; } midi_dev; -typedef struct codec_info + +typedef struct _codec_commlines { uint8 clock; uint8 data_in; uint8 data_out; - uint8 reserved[5]; -} codec_info; + uint8 cs_mask; //a Mask for removing all Chip select + uint8 reserved[4]; +} codec_comm_lines; -typedef struct _ice1712_ + +typedef struct channel_volume +{ + float volume; + bool mute; +} channel_volume; + + +typedef struct ice1712_settings +{ + channel_volume playback[10]; //Can't change the volume of the digital mixer + channel_volume record[10]; + + //General Settings + uint8 clock; //an index + uint8 sample_rate; //an index + uint8 buffer_size; //an index + uint8 debug_mode; //an index for debugging + + //S/PDif Settings + uint8 out_format; //an index + uint8 emphasis; //an index + uint8 copy_mode; //an index + + uint8 reserved[32]; +} ice1712_settings; + + +typedef struct ice1712 { uint32 irq; pci_info info; @@ -96,34 +126,38 @@ typedef struct _ice1712_ int8 nb_MPU401; product_t product; - uint8 gpio_cs_mask; //a Mask for removing all Chip select - //We hope all manufacturer will not use different codec on the same card - codec_info analog_codec; - codec_info digital_codec; + //We hope all manufacturers will use same communication lines for speaking with codec + codec_comm_lines commlines; uint32 buffer; bigtime_t played_time; + uint32 buffer_size; //in frames + uint32 frames_count; //Output area_id mem_id_pb; void *phys_addr_pb, *log_addr_pb; - uint32 output_buffer_size; //in frames uint8 total_output_channels; //Input area_id mem_id_rec; void *phys_addr_rec, *log_addr_rec; - uint32 input_buffer_size; //in frames uint8 total_input_channels; sem_id buffer_ready_sem; uint8 sampling_rate; //in the format of the register uint32 lock_source; - + + ice1712_settings settings; } ice1712; + +status_t apply_settings(ice1712 *card); + + +//For midi.c extern int32 num_cards; extern ice1712 cards[NUM_CARDS]; @@ -164,27 +198,15 @@ extern ice1712 cards[NUM_CARDS]; #define VX442_CODEC_CS_0 0x20 // ?? #0 #define VX442_CODEC_CS_1 0x40 // ?? #1 -#define AK45xx_BITS_TO_WRITE 16 -//2 - Chip Address (10b) -//1 - R/W (Always 1 for Writing) -//5 - Register Address -//8 - Data +#define GPIO_I2C_DELAY 5 //Clock Delay for writing I2C data throw GPIO //Register definition for the AK45xx codec (xx = 24 or 28) -#define AK45xx_DELAY 100 //Clock Delay #define AK45xx_CHIP_ADDRESS 0x02 //Chip address of the codec #define AK45xx_RESET_REGISTER 0x01 #define AK45xx_CLOCK_FORMAT_REGISTER 0x02 //Other register are not defined cause they are not used, I'm very lazy... -#define CS84xx_BITS_TO_WRITE 24 -//7 - Chip Address (0010000b) -//1 - R/W (1 for Reading) -//8 - Register MAP -//8 - Data - //Register definition for the CS84xx codec (xx = 27) -#define CS84xx_DELAY 100 //Clock Delay #define CS84xx_CHIP_ADDRESS 0x10 //Chip address of the codec #define CS84xx_CONTROL_1_PORT_REG 0x01 #define CS84xx_CONTROL_2_PORT_REG 0x02 @@ -192,6 +214,8 @@ extern ice1712 cards[NUM_CARDS]; #define CS84xx_CLOCK_SOURCE_REG 0x04 #define CS84xx_SERIAL_INPUT_FORMAT_REG 0x05 #define CS84xx_SERIAL_OUTPUT_FORMAT_REG 0x06 + +#define CS84xx_VERSION_AND_CHIP_ID 0x7F //Other register are not defined cause they are not used, I'm very lazy... @@ -217,7 +241,7 @@ extern ice1712 cards[NUM_CARDS]; } */ -//This map come from ALSA sound drivers +//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 diff --git a/src/add-ons/kernel/drivers/audio/ice1712/io.c b/src/add-ons/kernel/drivers/audio/ice1712/io.c index bc482b4dd5..0e696f6154 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/io.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/io.c @@ -15,13 +15,22 @@ extern pci_module_info *pci; - static void ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, uint8 chip_select); static void cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, uint8 chip_select); +static uint8 ak45xx_read_gpio(ice1712 *ice, uint8 reg_addr, + uint8 chip_select) {return 0;} //Unimplemented + +static uint8 cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr, + uint8 chip_select); + +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 @@ -86,42 +95,42 @@ write_cci_uint8(ice1712 *ice, int8 index, uint8 value) //Address are [PCI_14] + xx uint8 -read_ddma_uint8(ice1712 *ice, int8 regno) +read_ddma_uint8(ice1712 *ice, int8 regno) { return pci->read_io_8(ice->DDMA + regno); }; uint16 -read_ddma_uint16(ice1712 *ice, int8 regno) +read_ddma_uint16(ice1712 *ice, int8 regno) { return pci->read_io_16(ice->DDMA + regno); }; uint32 -read_ddma_uint32(ice1712 *ice, int8 regno) +read_ddma_uint32(ice1712 *ice, int8 regno) { return pci->read_io_32(ice->DDMA + regno); }; void -write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value) +write_ddma_uint8(ice1712 *ice, int8 regno, uint8 value) { pci->write_io_8(ice->DDMA + regno, value); }; void -write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value) +write_ddma_uint16(ice1712 *ice, int8 regno, uint16 value) { pci->write_io_16(ice->DDMA + regno, value); }; void -write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value) +write_ddma_uint32(ice1712 *ice, int8 regno, uint32 value) { pci->write_io_32(ice->DDMA + regno, value); }; @@ -216,6 +225,7 @@ 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) { @@ -291,26 +301,25 @@ int16 read_eeprom(ice1712 *ice, uint8 eeprom[32]) void codec_write(ice1712 *ice, uint8 reg_addr, uint8 data) { - switch (ice->product) - { - case ICE1712_SUBDEVICE_DELTA66 : - case ICE1712_SUBDEVICE_DELTA44 : + switch (ice->product) { + case ICE1712_SUBDEVICE_DELTA66: + case ICE1712_SUBDEVICE_DELTA44: ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_0); ak45xx_write_gpio(ice, reg_addr, data, DELTA66_CODEC_CS_1); break; - case ICE1712_SUBDEVICE_DELTA410 : - case ICE1712_SUBDEVICE_AUDIOPHILE_2496 : - case ICE1712_SUBDEVICE_DELTADIO2496 : + case ICE1712_SUBDEVICE_DELTA410: + case ICE1712_SUBDEVICE_AUDIOPHILE_2496: + case ICE1712_SUBDEVICE_DELTADIO2496: ak45xx_write_gpio(ice, reg_addr, data, AP2496_CODEC_CS); break; - case ICE1712_SUBDEVICE_DELTA1010 : - case ICE1712_SUBDEVICE_DELTA1010LT : + case ICE1712_SUBDEVICE_DELTA1010: + 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); break; - case ICE1712_SUBDEVICE_VX442 : + case ICE1712_SUBDEVICE_VX442: ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_0); ak45xx_write_gpio(ice, reg_addr, data, VX442_CODEC_CS_1); break; @@ -321,123 +330,209 @@ codec_write(ice1712 *ice, uint8 reg_addr, uint8 data) void spdif_write(ice1712 *ice, uint8 reg_addr, uint8 data) { - switch (ice->product) - { - case ICE1712_SUBDEVICE_DELTA1010 : + switch (ice->product) { + case ICE1712_SUBDEVICE_DELTA1010: break; - case ICE1712_SUBDEVICE_DELTADIO2496 : + case ICE1712_SUBDEVICE_DELTADIO2496: break; - case ICE1712_SUBDEVICE_DELTA66 : + case ICE1712_SUBDEVICE_DELTA66: break; - case ICE1712_SUBDEVICE_DELTA44 : + case ICE1712_SUBDEVICE_DELTA44: break; - case ICE1712_SUBDEVICE_AUDIOPHILE_2496 : + case ICE1712_SUBDEVICE_AUDIOPHILE_2496: cs84xx_write_gpio(ice, reg_addr, data, AP2496_SPDIF_CS); break; - case ICE1712_SUBDEVICE_DELTA410 : + case ICE1712_SUBDEVICE_DELTA410: break; - case ICE1712_SUBDEVICE_DELTA1010LT : + case ICE1712_SUBDEVICE_DELTA1010LT: cs84xx_write_gpio(ice, reg_addr, data, DELTA1010LT_SPDIF_CS); break; - case ICE1712_SUBDEVICE_VX442 : + case ICE1712_SUBDEVICE_VX442: cs84xx_write_gpio(ice, reg_addr, data, VX442_SPDIF_CS); break; } } +uint8 +codec_read(ice1712 *ice, uint8 reg_addr) +{ + uint8 val = 0xff; + switch (ice->product) { + case ICE1712_SUBDEVICE_DELTA66: + case ICE1712_SUBDEVICE_DELTA44: + val = ak45xx_read_gpio(ice, reg_addr, DELTA66_CODEC_CS_0); + break; + case ICE1712_SUBDEVICE_DELTA410: + case ICE1712_SUBDEVICE_AUDIOPHILE_2496: + case ICE1712_SUBDEVICE_DELTADIO2496: + val = ak45xx_read_gpio(ice, reg_addr, AP2496_CODEC_CS); + break; + case ICE1712_SUBDEVICE_DELTA1010: + case ICE1712_SUBDEVICE_DELTA1010LT: + val = ak45xx_read_gpio(ice, reg_addr, DELTA1010LT_CODEC_CS_0); + break; + case ICE1712_SUBDEVICE_VX442: + val = ak45xx_read_gpio(ice, reg_addr, VX442_CODEC_CS_0); + break; + } + + return val; +} + + +uint8 +spdif_read(ice1712 *ice, uint8 reg_addr) +{ + uint8 val = 0xff; + switch (ice->product) { + case ICE1712_SUBDEVICE_DELTA1010: + break; + case ICE1712_SUBDEVICE_DELTADIO2496: + break; + case ICE1712_SUBDEVICE_DELTA66: + break; + case ICE1712_SUBDEVICE_DELTA44: + break; + case ICE1712_SUBDEVICE_AUDIOPHILE_2496: + val = cs84xx_read_gpio(ice, reg_addr, AP2496_SPDIF_CS); + break; + case ICE1712_SUBDEVICE_DELTA410: + break; + case ICE1712_SUBDEVICE_DELTA1010LT: + val = cs84xx_read_gpio(ice, reg_addr, DELTA1010LT_SPDIF_CS); + break; + case ICE1712_SUBDEVICE_VX442: + val = cs84xx_read_gpio(ice, reg_addr, VX442_SPDIF_CS); + break; + } + + return val; +} + + +void +write_gpio_byte(ice1712 *ice, uint8 data, uint8 gpio_data) +{ + int i; + + for (i = 7; i >= 0; i--) { + // drop clock and data bits + gpio_data &= ~(ice->commlines.clock | ice->commlines.data_out); + + // set data bit if needed + if (data & (1 << i)) + gpio_data |= ice->commlines.data_out; + + write_gpio(ice, gpio_data); + snooze(GPIO_I2C_DELAY); + + // raise clock + gpio_data |= ice->commlines.clock; + write_gpio(ice, gpio_data); + snooze(GPIO_I2C_DELAY); + } +} + + +uint8 +read_gpio_byte(ice1712 *ice, uint8 gpio_data) +{ + int i; + uint8 data = 0; + + for (i = 7; i >= 0; i--) { + // drop clock + gpio_data &= ~(ice->commlines.clock); + write_gpio(ice, gpio_data); + snooze(GPIO_I2C_DELAY); + + if (read_gpio(ice) & ice->commlines.data_in) + data |= 1 << i; + + gpio_data |= ice->commlines.clock; + + write_gpio(ice, gpio_data); + snooze(GPIO_I2C_DELAY); + } + + return data; +} + + void ak45xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, uint8 chip_select) { - int i; uint8 tmp; - uint32 serial_data; tmp = read_gpio(ice); - - serial_data = ((AK45xx_CHIP_ADDRESS & 0x03) << 6) | 0x20 | (reg_addr & 0x1F); - serial_data = (serial_data << 8) | data; - - tmp |= ice->gpio_cs_mask; + tmp |= ice->commlines.cs_mask; tmp &= ~(chip_select); write_gpio(ice, tmp); - snooze(AK45xx_DELAY); - - for (i = 0; i < AK45xx_BITS_TO_WRITE; i++) { - // drop clock and data bits - tmp &= ~(ice->analog_codec.clock | ice->analog_codec.data_out); - - // set data if needed - if (serial_data & (1 << (AK45xx_BITS_TO_WRITE - 1))) - tmp |= ice->analog_codec.data_out; - - // shift data for sending next bit - serial_data <<= 1; - - write_gpio(ice, tmp); - snooze(AK45xx_DELAY); - - // raise clock - tmp |= ice->analog_codec.clock; - write_gpio(ice, tmp); - snooze(AK45xx_DELAY); - } + snooze(GPIO_I2C_DELAY); - // drop clock and Data - tmp &= ~(ice->analog_codec.clock | ice->analog_codec.data_out); - - tmp |= ice->gpio_cs_mask; + write_gpio_byte(ice, ((AK45xx_CHIP_ADDRESS & 0x03) << 6) | 0x20 | (reg_addr & 0x1f), tmp); + write_gpio_byte(ice, data, tmp); + + tmp |= chip_select; write_gpio(ice, tmp); - snooze(AK45xx_DELAY); + snooze(GPIO_I2C_DELAY); } void cs84xx_write_gpio(ice1712 *ice, uint8 reg_addr, uint8 data, uint8 chip_select) { - int i; uint8 tmp; - uint32 serial_data; tmp = read_gpio(ice); - - serial_data = (CS84xx_CHIP_ADDRESS & 0x7F) << 1; //Last bit is for writing - serial_data = (serial_data << 8) | (reg_addr & 0x7F); //Do not Increment - serial_data = (serial_data << 8) | data; - - tmp |= ice->gpio_cs_mask; + tmp |= ice->commlines.cs_mask; tmp &= ~(chip_select); write_gpio(ice, tmp); - snooze(CS84xx_DELAY); - - for (i = 0; i < CS84xx_BITS_TO_WRITE; i++) { - // drop clock and data bits - tmp &= ~(ice->digital_codec.clock | ice->digital_codec.data_out); - - // set data bit if needed - if (serial_data & (1 << (CS84xx_BITS_TO_WRITE - 1))) - tmp |= ice->digital_codec.data_out; - - // shift data for sending next bit - serial_data <<= 1; - - write_gpio(ice, tmp); - snooze(CS84xx_DELAY); - - // raise clock - tmp |= ice->digital_codec.clock; - write_gpio(ice, tmp); - snooze(CS84xx_DELAY); - } + snooze(GPIO_I2C_DELAY); - // drop clock and Data - tmp &= ~(ice->digital_codec.clock | ice->digital_codec.data_out); + write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7f) << 1, tmp); + write_gpio_byte(ice, reg_addr & 0x7f, tmp); //Do not Increment + write_gpio_byte(ice, data, tmp); - tmp |= ice->gpio_cs_mask; + tmp |= chip_select; write_gpio(ice, tmp); - snooze(CS84xx_DELAY); + snooze(GPIO_I2C_DELAY); +} + + +uint8 +cs84xx_read_gpio(ice1712 *ice, uint8 reg_addr, uint8 chip_select) +{ + uint8 tmp, data; + + tmp = read_gpio(ice); + tmp |= ice->commlines.cs_mask; + tmp &= ~(chip_select); + + write_gpio(ice, tmp); + snooze(GPIO_I2C_DELAY); + + write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7f) << 1, tmp); //For writing the MAP + write_gpio_byte(ice, reg_addr & 0x7F, tmp); //Do not Increment + + tmp |= chip_select; //Deselect the chip + write_gpio(ice, tmp); + snooze(GPIO_I2C_DELAY); + + tmp &= ~(chip_select); //Reselect the chip + write_gpio(ice, tmp); + snooze(GPIO_I2C_DELAY); + + write_gpio_byte(ice, (CS84xx_CHIP_ADDRESS & 0x7f) << 1 | 1, tmp); //For writing the MAP + data = read_gpio_byte(ice, tmp); //For reading + + tmp |= chip_select; //Deselect the chip + write_gpio(ice, tmp); + + return data; } diff --git a/src/add-ons/kernel/drivers/audio/ice1712/io.h b/src/add-ons/kernel/drivers/audio/ice1712/io.h index 1b0c4551d2..6985c6fdeb 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/io.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/io.h @@ -89,8 +89,14 @@ int16 read_eeprom(ice1712 *ice, uint8 eeprom[32]); //------------------------------------------------------ void codec_write(ice1712 *ice, uint8 reg_addr, uint8 data); - void spdif_write(ice1712 *ice, uint8 reg_addr, uint8 data); +void codec_write_mult(ice1712 *ice, uint8 reg_addr, uint8 datas[], uint8 size); +void spdif_write_mult(ice1712 *ice, uint8 reg_addr, uint8 datas[], uint8 size); + +uint8 codec_read(ice1712 *ice, uint8 reg_addr); +uint8 spdif_read(ice1712 *ice, uint8 reg_addr); +uint8 codec_read_mult(ice1712 *ice, uint8 reg_addr, uint8 datas[], uint8 size); +uint8 spdif_read_mult(ice1712 *ice, uint8 reg_addr, uint8 datas[], uint8 size); //------------------------------------------------------ diff --git a/src/add-ons/kernel/drivers/audio/ice1712/midi.c b/src/add-ons/kernel/drivers/audio/ice1712/midi.c index 15890fc461..f59a443487 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/midi.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/midi.c @@ -15,10 +15,11 @@ #include "ice1712.h" #include "io.h" -#include "debug.h" #include "midi_driver.h" #include "util.h" +#include "debug.h" + extern generic_mpu401_module * mpu401; void midi_interrupt_op(int32 op, void * data) @@ -89,38 +90,35 @@ device_hooks midi_hooks = { NULL /* writev */ }; + static status_t midi_open(const char * name, uint32 flags, void ** cookie) { int i, ix, used_midi = -1; int ret; - TRACE_ICE(("midi_open()\n")); + TRACE("midi_open()\n"); *cookie = NULL; - for (ix = 0; ix < num_cards; ix++) - { + for (ix = 0; ix < num_cards; ix++) { for (i = 0; i < cards[ix].nb_MPU401; i++) - if (!strcmp(name, cards[ix].midi_interf[i].name)) - { + if (!strcmp(name, cards[ix].midi_interf[i].name)) { used_midi = i; break; } } - if (ix >= num_cards) - { - TRACE_ICE(("bad device\n")); + if (ix >= num_cards) { + TRACE("bad device\n"); return ENODEV; } - TRACE_ICE(("mpu401: %p open(): %p driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi_interf[used_midi].driver)); + TRACE("mpu401: %p open(): %p driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi_interf[used_midi].driver); ret = (*mpu401->open_hook)(cards[ix].midi_interf[used_midi].driver, flags, cookie); - if (ret >= B_OK) - { + if (ret >= B_OK) { cards[ix].midi_interf[used_midi].cookie = *cookie; atomic_add(&cards[ix].midi_interf[used_midi].count, 1); } - TRACE_ICE(("mpu401: open returns %x / %p\n", ret, *cookie)); + TRACE("mpu401: open returns %x / %p\n", ret, *cookie); return ret; } @@ -128,7 +126,7 @@ static status_t midi_open(const char * name, uint32 flags, void ** cookie) static status_t midi_close(void * cookie) { - TRACE_ICE(("midi_close()\n")); + TRACE("midi_close()\n"); return (*mpu401->close_hook)(cookie); } @@ -137,22 +135,19 @@ static status_t midi_free(void * cookie) { int i, ix; status_t f; - TRACE_ICE(("midi_free()\n")); + TRACE("midi_free()\n"); f = (*mpu401->free_hook)(cookie); - for (ix = 0; ix < num_cards; ix++) - { + for (ix = 0; ix < num_cards; ix++) { for (i = 0; i < cards[ix].nb_MPU401; i++) - if (cards[ix].midi_interf[i].cookie == cookie) - { - if (atomic_add(&cards[ix].midi_interf[i].count, -1) == 1) - { + if (cards[ix].midi_interf[i].cookie == cookie) { + if (atomic_add(&cards[ix].midi_interf[i].count, -1) == 1) { cards[ix].midi_interf[i].cookie = NULL; - TRACE_ICE(("cleared %p card %d\n", cookie, ix)); + TRACE("cleared %p card %d\n", cookie, ix); } break; } } - TRACE_ICE(("midi_free() done\n")); + TRACE("midi_free() done\n"); return f; } @@ -177,9 +172,8 @@ static status_t midi_write(void * cookie, off_t pos, const void * ptr, size_t * bool midi_interrupt(ice1712 *card) { - TRACE_ICE(("midi_interrupt\n")); - if (!card->midi_interf[0].driver) - { + TRACE("midi_interrupt\n"); + if (!card->midi_interf[0].driver) { // kprintf("aiigh\n"); return false; } diff --git a/src/add-ons/kernel/drivers/audio/ice1712/multi.c b/src/add-ons/kernel/drivers/audio/ice1712/multi.c index c84a8c701b..b423c5036b 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/multi.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/multi.c @@ -21,10 +21,11 @@ | B_SR_88200 | B_SR_48000 | B_SR_44100) #define AUTHORIZED_SAMPLE_SIZE (B_FMT_32BIT) + static void start_DMA(ice1712 *card) { - uint16 size = card->output_buffer_size * MAX_DAC; + uint16 size = card->buffer_size * MAX_DAC; write_mt_uint8(card, MT_PROF_PB_CONTROL, 0); @@ -32,15 +33,15 @@ start_DMA(ice1712 *card) write_mt_uint16(card, MT_PROF_PB_DMA_COUNT_ADDRESS, (size * SWAPPING_BUFFERS) - 1); //We want interrupt only from playback write_mt_uint16(card, MT_PROF_PB_DMA_TERM_COUNT, size - 1); - TRACE_ICE(("SIZE DMA PLAYBACK %#x\n", size)); + TRACE("SIZE DMA PLAYBACK %#x\n", size); - size = card->input_buffer_size * MAX_ADC; + size = card->buffer_size * MAX_ADC; write_mt_uint32(card, MT_PROF_REC_DMA_BASE_ADDRESS, (uint32)card->phys_addr_rec); write_mt_uint16(card, MT_PROF_REC_DMA_COUNT_ADDRESS, (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_ICE(("SIZE DMA RECORD %#x\n", size)); + TRACE("SIZE DMA RECORD %#x\n", size); //Enable output AND Input from Analog CODEC switch (card->product) { @@ -135,78 +136,79 @@ ice1712_get_description(ice1712 *card, multi_description *data) break; } - strncpy(data->vendor_info, "J. H Leveque", 32); + strncpy(data->vendor_info, "Jerome Leveque", 32); data->output_channel_count = card->total_output_channels; data->input_channel_count = card->total_input_channels; - data->output_bus_channel_count = card->total_output_channels; - data->input_bus_channel_count = card->total_input_channels; + data->output_bus_channel_count = 0; + data->input_bus_channel_count = 0; data->aux_bus_channel_count = 0; + if (ICE1712_VERY_VERBOSE) + TRACE("request_channel_count = %ld\n", data->request_channel_count); - TRACE_ICE(("request_channel_count = %d\n", data->request_channel_count)); if (data->request_channel_count >= (card->total_output_channels + card->total_input_channels)) { for (i = 0; i < card->nb_DAC; i++) { //Analog STEREO output data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL; + data->channels[chan].kind = B_MULTI_OUTPUT_BUS; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | ((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT; - data->channels[chan++].connectors = 0; + data->channels[chan++].connectors = B_CHANNEL_RCA; } if (card->spdif_config & NO_IN_YES_OUT) { //SPDIF STEREO output data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL; + data->channels[chan].kind = B_MULTI_OUTPUT_BUS; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_LEFT; - data->channels[chan].connectors = 0; + data->channels[chan].connectors = B_CHANNEL_COAX_SPDIF; chan++; data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_OUTPUT_CHANNEL; + data->channels[chan].kind = B_MULTI_OUTPUT_BUS; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_RIGHT; - data->channels[chan++].connectors = 0; + data->channels[chan++].connectors = B_CHANNEL_COAX_SPDIF; } for (i = 0; i < card->nb_ADC; i++) { //Analog STEREO input data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].kind = B_MULTI_INPUT_BUS; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | ((i & 1) == 0) ? B_CHANNEL_LEFT : B_CHANNEL_RIGHT; - data->channels[chan++].connectors = 0; + data->channels[chan++].connectors = B_CHANNEL_RCA; } if (card->spdif_config & YES_IN_NO_OUT) { //SPDIF STEREO input data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].kind = B_MULTI_INPUT_BUS; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_LEFT; - data->channels[chan++].connectors = 0; + data->channels[chan++].connectors = B_CHANNEL_COAX_SPDIF; data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].kind = B_MULTI_INPUT_BUS; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_RIGHT; - data->channels[chan++].connectors = 0; + data->channels[chan++].connectors = B_CHANNEL_COAX_SPDIF; } //The digital mixer output data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].kind = B_MULTI_INPUT_BUS; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_LEFT; - data->channels[chan++].connectors = 0; + data->channels[chan++].connectors = B_CHANNEL_SPDIF_HEADER; data->channels[chan].channel_id = chan; - data->channels[chan].kind = B_MULTI_INPUT_CHANNEL; + data->channels[chan].kind = B_MULTI_INPUT_BUS; data->channels[chan].designations = B_CHANNEL_STEREO_BUS | B_CHANNEL_RIGHT; - data->channels[chan++].connectors = 0; + data->channels[chan++].connectors = B_CHANNEL_SPDIF_HEADER; } - TRACE_ICE(("output_channel_count = %d\n", data->output_channel_count)); - TRACE_ICE(("input_channel_count = %d\n", data->input_channel_count)); - TRACE_ICE(("output_bus_channel_count = %d\n", data->output_bus_channel_count)); - TRACE_ICE(("input_bus_channel_count = %d\n", data->input_bus_channel_count)); + 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); data->output_rates = data->input_rates = AUTHORIZED_RATE; data->min_cvsr_rate = 44100; @@ -248,11 +250,11 @@ ice1712_set_enabled_channels(ice1712 *card, multi_channel_enable *data) { int i; for (i = 0; i < (card->total_output_channels + card->total_input_channels); i++) - TRACE_ICE(("set_enabled_channels %d : %s\n", i, - B_TEST_CHANNEL(data->enable_bits, i) ? "enabled": "disabled")); + TRACE("set_enabled_channels %d : %s\n", i, + B_TEST_CHANNEL(data->enable_bits, i) ? "enabled": "disabled"); - TRACE_ICE(("lock_source %d\n", data->lock_source)); - TRACE_ICE(("lock_data %d\n", data->lock_data)); + TRACE("lock_source %#08X\n", (int)data->lock_source); + TRACE("lock_data %#08X\n", (int)data->lock_data); if (data->lock_source == B_MULTI_LOCK_SPDIF) write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, 0x10); @@ -270,19 +272,22 @@ ice1712_get_global_format(ice1712 *card, multi_format_info *data) { uint8 sr = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT); - switch (sr) - { + switch (sr) { case 0x0: data->input.rate = data->output.rate = B_SR_48000; + data->input.cvsr = data->output.cvsr = 48000.0f; break; case 0x7: data->input.rate = data->output.rate = B_SR_96000; + data->input.cvsr = data->output.cvsr = 96000.0f; break; case 0x8: data->input.rate = data->output.rate = B_SR_44100; + data->input.cvsr = data->output.cvsr = 44100.0f; break; - case 0xB: + case 0xb: data->input.rate = data->output.rate = B_SR_88200; + data->input.cvsr = data->output.cvsr = 88200.0f; break; } @@ -290,6 +295,9 @@ 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("Input Sampling Rate = %d\n", (int)data->input.cvsr); + TRACE("Output Sampling Rate = %d\n", (int)data->output.cvsr); + return B_OK; } @@ -299,8 +307,8 @@ ice1712_set_global_format(ice1712 *card, multi_format_info *data) { uint8 i; - TRACE_ICE(("Input Sampling Rate = %#x\n", data->input.rate)); - TRACE_ICE(("Output Sampling Rate = %#x\n", data->output.rate)); + TRACE("Input Sampling Rate = %#x\n", (int)data->input.rate); + TRACE("Output Sampling Rate = %#x\n", (int)data->output.rate); if ((data->input.rate == data->output.rate) && (card->lock_source == B_MULTI_LOCK_INTERNAL)) { @@ -321,98 +329,357 @@ ice1712_set_global_format(ice1712 *card, multi_format_info *data) write_mt_uint8(card, MT_SAMPLING_RATE_SELECT, card->sampling_rate); } i = read_mt_uint8(card, MT_SAMPLING_RATE_SELECT); - TRACE_ICE(("RATE = %#x\n", i)); + TRACE("RATE = %#x\n", i); return B_OK; } status_t ice1712_get_mix(ice1712 *card, multi_mix_value_info *data) -{//Not Implemented - return B_ERROR; +{ + int i; + TRACE(" 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]); + + switch (mmv->id & ICE1712_MULTI_CONTROL_MASK) { + case ICE1712_MULTI_CONTROL_VOLUME_PB: + mmv->u.gain = card->settings.playback[mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK].volume; + break; + + case ICE1712_MULTI_CONTROL_VOLUME_REC: + mmv->u.gain = card->settings.record[mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK].volume; + break; + + case ICE1712_MULTI_CONTROL_MUTE | ICE1712_MULTI_CONTROL_VOLUME_PB: + mmv->u.enable = card->settings.playback[mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK].mute; + break; + + case ICE1712_MULTI_CONTROL_MUTE | ICE1712_MULTI_CONTROL_VOLUME_REC: + mmv->u.enable = card->settings.record[mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK].mute; + break; + + case ICE1712_MULTI_CONTROL_MUX: + mmv->u.mux = 0; + break; + } + } + + return B_OK; } status_t ice1712_set_mix(ice1712 *card, multi_mix_value_info *data) -{//Not Implemented - return B_ERROR; +{ + int i; + TRACE(" 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]); + + switch (mmv->id & ICE1712_MULTI_CONTROL_MASK) { + case ICE1712_MULTI_CONTROL_VOLUME_PB: + card->settings.playback[mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK].volume = mmv->u.gain; + TRACE(" ICE1712_MULTI_CONTROL_VOLUME_PB 0x%x : %f\n", (unsigned int)mmv->id, mmv->u.gain); + break; + + case ICE1712_MULTI_CONTROL_VOLUME_REC: + card->settings.record[mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK].volume = mmv->u.gain; + TRACE(" ICE1712_MULTI_CONTROL_VOLUME_REC 0x%x : %f\n", (unsigned int)mmv->id, mmv->u.gain); + break; + + case ICE1712_MULTI_CONTROL_MUTE | ICE1712_MULTI_CONTROL_VOLUME_PB: + card->settings.playback[mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK].mute = mmv->u.enable; + card->settings.playback[(mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK) + 1].mute = mmv->u.enable; + TRACE(" ICE1712_MULTI_CONTROL_MUTE_PB 0x%x : %d\n", (unsigned int)mmv->id, mmv->u.enable); + break; + + case ICE1712_MULTI_CONTROL_MUTE | ICE1712_MULTI_CONTROL_VOLUME_REC: + card->settings.record[mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK].mute = mmv->u.enable; + card->settings.record[(mmv->id & ICE1712_MULTI_CONTROL_CHANNEL_MASK) + 1].mute = mmv->u.enable; + TRACE(" ICE1712_MULTI_CONTROL_MUTE_REC 0x%x : %d\n", (unsigned int)mmv->id, mmv->u.enable); + break; + + case ICE1712_MULTI_CONTROL_MUX: + TRACE(" ICE1712_MULTI_CONTROL_MUX 0x%x : 0x%x\n", (unsigned int)mmv->id, (unsigned int)mmv->u.mux); + break; + + default: + TRACE(" 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_ERROR; + return B_OK; +} + +static const char *Clock[] = { "Internal", "Digital", NULL }; +static const char *SampleRate[] = { "44,1 KHz", "48 KHz", "88,2 KHz", + "96 KHz", NULL }; +static const char *BufferSize[] = { "64", "128", "256", "512", "1024", + "2048", NULL }; +#if 0 +static const char *Debug[] = { "Mode 0", "Mode 1", "Mode 2", "Mode 3", + "Mode 4", "Mode 5", NULL }; +#endif +static const char *DigitalFormat[] = { "Consumer", "Professional", NULL }; +static const char *DigitalEmphasis[] = { "None", "CCITT", "15/50usec", NULL }; +static const char *DigitalCopyMode[] = { "Original", "1st Generation", + "No SCMS", NULL }; + + +static const char **SettingsGeneral[] = { Clock, SampleRate, BufferSize, +#if 0 + Debug, +#endif + NULL }; + +static const char **SettingsDigital[] = { DigitalFormat, DigitalEmphasis, + DigitalCopyMode, NULL }; +static const char *string_list[] = { "Setup", "General Not implemented yet", + "Digital Not implemented yet", "Output Selection Not implemented yet", + "Internal Mixer", + + //General settings + "Master clock", "Sample rate", "Buffer size", "Debug", + + //Digital settings + "Output format", "Emphasis", "Copy mode", + + //Output Selection + "Output 1", //12 + "Output 2", + "Output 3", + "Output 4", + "Digital Output", //16 + + "Haiku output", //17 + + "Input 1", //18 + "Input 2", + "Input 3", + "Input 4", + "Digital Input", //22 + "Internal mixer", //23 +}; + +static int32 nb_control_created; + + +//This will create a Tab +static int32 +create_group_control(multi_mix_control **p_mmc, int32 offset, int32 parent, + enum strind_id string, const char* name) +{ + multi_mix_control *mmc = *p_mmc; + int32 group; + //Increase the index cause we fill it + + group = mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + offset; + mmc->parent = parent; + mmc->flags = B_MULTI_MIX_GROUP; + mmc->master = CONTROL_IS_MASTER; + mmc->string = string; + + if (name != NULL) + strcpy(mmc->name, name); + + nb_control_created++; mmc++; + (*p_mmc) = mmc; + + return group; } -#define MULTI_AUDIO_BASE_ID 1024 -#define MULTI_AUDIO_MASTER_ID 0 - -#ifndef B_MULTI_MIX_GROUP -#define B_MULTI_MIX_GROUP 10 -#endif - -#ifndef S_null -#define S_null 10 -#endif - -#ifndef S_STEREO_MIX -#define S_STEREO_MIX 10 -#endif - -static int32 -create_group_control(multi_mix_control *multi, int32 idx, int32 parent, - int32 string, const char* name) +//This will create a Slider with a "Mute" CheckBox +static void +create_channel_control(multi_mix_control **p_mmc, int32 offset, int32 parent, + const char* name) { - multi->id = MULTI_AUDIO_BASE_ID + idx; - multi->master = parent; - multi->flags = B_MULTI_MIX_GROUP; - multi->master = MULTI_AUDIO_MASTER_ID; -// multi->string = string; - - if (name != NULL) - strcpy(multi->name, name); + multi_mix_control *mmc = *p_mmc; + multi_mix_control control; - return multi->id; + 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; + + //The Mute Checkbox + control.id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_CONTROL_MUTE + offset; + control.flags = B_MULTI_MIX_ENABLE; + control.string = S_MUTE; + *mmc = control; + mmc++; + + //The Left Slider + control.string = S_null; + control.id = ICE1712_MULTI_CONTROL_FIRSTID + offset; + control.flags = B_MULTI_MIX_GAIN; + if (name != NULL) + strcpy(control.name, name); + *mmc = control; + mmc++; + + //The Right Slider + control.master = control.id; //The Id of the Left Slider + control.id++; + *mmc = control; + mmc++; + + nb_control_created += 3; + (*p_mmc) = mmc; } -static int32 -create_slider_control(multi_mix_control *multi, int32 idx, int32 parent, - int32 string, const char* name) + +static void +create_combo_control(multi_mix_control **p_mmc, const char *values[], + int32 parent, const char *name) { - multi->id = MULTI_AUDIO_BASE_ID + idx; - multi->master = parent; - multi->flags = B_MULTI_MIX_GAIN; - multi->master = MULTI_AUDIO_MASTER_ID + 1; -// multi->string = string; + multi_mix_control *mmc = *p_mmc; + int32 parentControl, i; - multi->u.gain.min_gain = -144.0; - multi->u.gain.max_gain = 0.0; - multi->u.gain.granularity = 1.5; + //The label + parentControl = mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_CONTROL_MUX + nb_control_created; + mmc->flags = B_MULTI_MIX_MUX; + mmc->parent = parent; + strcpy(mmc->name, name); + nb_control_created++; mmc++; - if (name != NULL) - strcpy(multi->name, name); + //The values + for (i = 0; values[i] != NULL; i++) { + mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + nb_control_created; + mmc->flags = B_MULTI_MIX_MUX_VALUE; + mmc->parent = parentControl; + strcpy(mmc->name, values[i]); + nb_control_created++; mmc++; + } + + (*p_mmc) = mmc; +} + + +//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, int32 output, int32 parent) +{ + multi_mix_control *mmc = *p_mmc; + int32 parentControl, i; + + //The label + parentControl = mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + ICE1712_MULTI_CONTROL_MUX + nb_control_created; + mmc->flags = B_MULTI_MIX_MUX; + mmc->parent = parent; + strcpy(mmc->name, string_list[12 + output]); + nb_control_created++; mmc++; + + //Haiku output + mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + nb_control_created; + mmc->flags = B_MULTI_MIX_MUX_VALUE; + mmc->parent = parentControl; + strcpy(mmc->name, string_list[17]); + nb_control_created++; mmc++; + + //Physical Input + for (i = 0; i < card->nb_DAC; i += 2) { + mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + nb_control_created; + mmc->flags = B_MULTI_MIX_MUX_VALUE; + mmc->parent = parentControl; + strcpy(mmc->name, string_list[18 + (i / 2)]); + nb_control_created++; mmc++; + } - return multi->id; + //Physical Digital Input + if (card->spdif_config & YES_IN_NO_OUT) { + mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + nb_control_created; + mmc->flags = B_MULTI_MIX_MUX_VALUE; + mmc->parent = parentControl; + strcpy(mmc->name, string_list[22]); + nb_control_created++; mmc++; + } + + //Internal mixer only for Output 1 andd Digital Output + if ((output == 0) || (output == 4)) { + mmc->id = ICE1712_MULTI_CONTROL_FIRSTID + nb_control_created; + mmc->flags = B_MULTI_MIX_MUX_VALUE; + mmc->parent = parentControl; + strcpy(mmc->name, string_list[23]); + nb_control_created++; mmc++; + } + + (*p_mmc) = mmc; } status_t -ice1712_list_mix_controls(ice1712 *card, multi_mix_control_info *data) +ice1712_list_mix_controls(ice1712 *card, multi_mix_control_info *mmci) { - int32 parent; + int32 i, parentTab, parentTabColumn; + multi_mix_control *mmc = mmci->controls; - TRACE_ICE(("count = %d\n", data->control_count)); - parent = create_group_control(data->controls + 0, 0, 0, S_null, "Playback"); - create_slider_control(data->controls + 1, 1, parent, S_STEREO_MIX, - "Master Output"); + nb_control_created = 0; - parent = create_group_control(data->controls + 2, 2, 0, S_null, "Record"); - create_slider_control(data->controls + 3, 3, parent, S_STEREO_MIX, - "Master Input"); - data->control_count = 4; + TRACE("count = %ld\n", mmci->control_count); + + //Cleaning + memset(mmc, 0, mmci->control_count * sizeof(multi_mix_control)); + + //Setup tab + parentTab = create_group_control(&mmc, nb_control_created, CONTROL_IS_MASTER, S_SETUP, NULL); + + //General Settings + parentTabColumn = create_group_control(&mmc, nb_control_created, parentTab, S_null, string_list[1]); + for (i = 0; SettingsGeneral[i] != NULL; i++) + create_combo_control(&mmc, SettingsGeneral[i], parentTabColumn, string_list[5 + i]); + + //Digital Settings + parentTabColumn = create_group_control(&mmc, nb_control_created, parentTab, S_null, string_list[2]); + for (i = 0; SettingsDigital[i] != NULL; i++) + create_combo_control(&mmc, SettingsDigital[i], parentTabColumn, string_list[9 + i]); + + //Output Selection Settings + parentTabColumn = create_group_control(&mmc, nb_control_created, parentTab, S_null, string_list[3]); + for (i = 0; i < card->nb_DAC; i += 2) + create_output_choice(card, &mmc, i / 2, parentTabColumn); + + if (card->spdif_config & NO_IN_YES_OUT) + create_output_choice(card, &mmc, 4, parentTabColumn); + + //Internal Mixer Tab + parentTab = create_group_control(&mmc, nb_control_created, CONTROL_IS_MASTER, S_null, string_list[4]); + + for (i = 0; i < card->nb_DAC; i += 2) { + parentTabColumn = create_group_control(&mmc, nb_control_created, parentTab, S_null, string_list[(i / 2) + 18]); + create_channel_control(&mmc, ICE1712_MULTI_CONTROL_VOLUME_PB + i, parentTabColumn, NULL); + } + + if (card->spdif_config & YES_IN_NO_OUT) { + parentTabColumn = create_group_control(&mmc, nb_control_created, parentTab, S_null, string_list[22]); + create_channel_control(&mmc, ICE1712_MULTI_CONTROL_VOLUME_REC + SPDIF_LEFT, parentTabColumn, NULL); + } + + for (i = 0; i < card->nb_ADC; i += 2) { + parentTabColumn = create_group_control(&mmc, nb_control_created, parentTab, S_null, string_list[(i / 2) + 12]); + create_channel_control(&mmc, ICE1712_MULTI_CONTROL_VOLUME_REC + i, parentTabColumn, NULL); + } + + if (card->spdif_config & NO_IN_YES_OUT) { + parentTabColumn = create_group_control(&mmc, nb_control_created, parentTab, S_null, string_list[16]); + create_channel_control(&mmc, ICE1712_MULTI_CONTROL_VOLUME_PB + SPDIF_LEFT, parentTabColumn, NULL); + } + + TRACE("Return %ld control(s)\n", nb_control_created); + mmci->control_count = nb_control_created; return B_OK; } @@ -421,7 +688,8 @@ ice1712_list_mix_controls(ice1712 *card, multi_mix_control_info *data) status_t ice1712_list_mix_connections(ice1712 *card, multi_mix_connection_info *data) {//Not Implemented - return B_ERROR; + data->actual_count = 0; + return B_OK; } @@ -430,38 +698,33 @@ ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) { int buff, chan_i = 0, chan_o = 0; - TRACE_ICE(("flags = %#x\n",data->flags)); - TRACE_ICE(("request_playback_buffers = %#x\n", - data->request_playback_buffers)); - TRACE_ICE(("request_playback_channels = %#x\n", - data->request_playback_channels)); - TRACE_ICE(("request_playback_buffer_size = %#x\n", - data->request_playback_buffer_size)); - TRACE_ICE(("request_record_buffers = %#x\n", - data->request_record_buffers)); - TRACE_ICE(("request_record_channels = %#x\n", - data->request_record_channels)); - TRACE_ICE(("request_record_buffer_size = %#x\n", - data->request_record_buffer_size)); + if (ICE1712_VERY_VERBOSE) { + TRACE("flags = %#x\n", (int)data->flags); + TRACE("request_playback_buffers = %#x\n", (int)data->request_playback_buffers); + TRACE("request_playback_channels = %#x\n", (int)data->request_playback_channels); + TRACE("request_playback_buffer_size = %#x\n", (int)data->request_playback_buffer_size); + TRACE("request_record_buffers = %#x\n", (int)data->request_record_buffers); + TRACE("request_record_channels = %#x\n", (int)data->request_record_channels); + TRACE("request_record_buffer_size = %#x\n", (int)data->request_record_buffer_size); + } //if (ICE1712_VERY_VERBOSE) // MIN_BUFFER_FRAMES <= requested value <= MAX_BUFFER_FRAMES - card->output_buffer_size = data->request_playback_buffer_size; - if (card->output_buffer_size > MAX_BUFFER_FRAMES) - card->output_buffer_size = MAX_BUFFER_FRAMES; - if (card->output_buffer_size < MIN_BUFFER_FRAMES) - card->output_buffer_size = MIN_BUFFER_FRAMES; + card->buffer_size = data->request_playback_buffer_size <= MAX_BUFFER_FRAMES ? \ + data->request_playback_buffer_size >= MIN_BUFFER_FRAMES ? \ + data->request_playback_buffer_size : MIN_BUFFER_FRAMES \ + : MAX_BUFFER_FRAMES; - card->input_buffer_size = data->request_record_buffer_size; - if (card->input_buffer_size > MAX_BUFFER_FRAMES) - card->input_buffer_size = MAX_BUFFER_FRAMES; - if (card->input_buffer_size < MIN_BUFFER_FRAMES) - card->input_buffer_size = MIN_BUFFER_FRAMES; + // MIN_BUFFER_FRAMES <= requested value <= MAX_BUFFER_FRAMES + card->buffer_size = data->request_record_buffer_size <= MAX_BUFFER_FRAMES ? \ + data->request_record_buffer_size >= MIN_BUFFER_FRAMES ? \ + data->request_record_buffer_size : MIN_BUFFER_FRAMES \ + : MAX_BUFFER_FRAMES; 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->output_buffer_size; - uint32 buf_i = stride_i * card->input_buffer_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->nb_DAC; chan_o++) { @@ -469,8 +732,8 @@ ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) data->playback_buffers[buff][chan_o].base = card->log_addr_pb + buf_o * buff + SAMPLE_SIZE * chan_o; data->playback_buffers[buff][chan_o].stride = stride_o; - TRACE_ICE(("pb_buffer[%d][%d] = %#x\n", buff, chan_o, - data->playback_buffers[buff][chan_o].base)); + if (ICE1712_VERY_VERBOSE) + TRACE("pb_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_o, (int)data->playback_buffers[buff][chan_o].base); } if (card->spdif_config & NO_IN_YES_OUT) { @@ -478,15 +741,15 @@ ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) data->playback_buffers[buff][chan_o].base = card->log_addr_pb + buf_o * buff + SAMPLE_SIZE * SPDIF_LEFT; data->playback_buffers[buff][chan_o].stride = stride_o; - TRACE_ICE(("pb_buffer[%d][%d] = %#x\n", buff, chan_o, - data->playback_buffers[buff][chan_o].base)); + if (ICE1712_VERY_VERBOSE) + TRACE("pb_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_o, (int)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].stride = stride_o; - TRACE_ICE(("pb_buffer[%d][%d] = %#x\n", buff, chan_o, - data->playback_buffers[buff][chan_o].base)); + if (ICE1712_VERY_VERBOSE) + TRACE("pb_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_o, (int)data->playback_buffers[buff][chan_o].base); chan_o++; } } @@ -497,8 +760,8 @@ ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) data->record_buffers[buff][chan_i].base = card->log_addr_rec + buf_i * buff + SAMPLE_SIZE * chan_i; data->record_buffers[buff][chan_i].stride = stride_i; - TRACE_ICE(("rec_buffer[%d][%d] = %#x\n", buff, chan_i, - data->record_buffers[buff][chan_i].base)); + if (ICE1712_VERY_VERBOSE) + TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)data->record_buffers[buff][chan_i].base); } if (card->spdif_config & YES_IN_NO_OUT) { @@ -506,15 +769,15 @@ ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) data->record_buffers[buff][chan_i].base = card->log_addr_rec + buf_i * buff + SAMPLE_SIZE * SPDIF_LEFT; data->record_buffers[buff][chan_i].stride = stride_i; - TRACE_ICE(("rec_buffer[%d][%d] = %#x\n", buff, chan_i, - data->record_buffers[buff][chan_i].base)); + if (ICE1712_VERY_VERBOSE) + TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)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].stride = stride_i; - TRACE_ICE(("rec_buffer[%d][%d] = %#x\n", buff, chan_i, - data->record_buffers[buff][chan_i].base)); + if (ICE1712_VERY_VERBOSE) + TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)data->record_buffers[buff][chan_i].base); chan_i++; } @@ -522,41 +785,35 @@ ice1712_get_buffers(ice1712 *card, multi_buffer_list *data) 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].stride = stride_i; - TRACE_ICE(("rec_buffer[%d][%d] = %#x\n", buff, chan_i, - data->record_buffers[buff][chan_i].base)); + if (ICE1712_VERY_VERBOSE) + TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)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].stride = stride_i; - TRACE_ICE(("rec_buffer[%d][%d] = %#x\n", buff, chan_i, - data->record_buffers[buff][chan_i].base)); + if (ICE1712_VERY_VERBOSE) + TRACE("rec_buffer[%d][%d] = %#x\n", (int)buff, (int)chan_i, (int)data->record_buffers[buff][chan_i].base); chan_i++; } } data->return_playback_buffers = SWAPPING_BUFFERS; data->return_playback_channels = card->total_output_channels; - data->return_playback_buffer_size = card->output_buffer_size; + data->return_playback_buffer_size = card->buffer_size; - TRACE_ICE(("return_playback_buffers = %#x\n", - data->return_playback_buffers)); - TRACE_ICE(("return_playback_channels = %#x\n", - data->return_playback_channels)); - TRACE_ICE(("return_playback_buffer_size = %#x\n", - data->return_playback_buffer_size)); + TRACE("return_playback_buffers = %#x\n", (int)data->return_playback_buffers); + TRACE("return_playback_channels = %#x\n", (int)data->return_playback_channels); + TRACE("return_playback_buffer_size = %#x\n", (int)data->return_playback_buffer_size); data->return_record_buffers = SWAPPING_BUFFERS; data->return_record_channels = card->total_input_channels; data->return_record_channels = chan_i; - data->return_record_buffer_size = card->input_buffer_size; + data->return_record_buffer_size = card->buffer_size; - TRACE_ICE(("return_record_buffers = %#x\n", - data->return_record_buffers)); - TRACE_ICE(("return_record_channels = %#x\n", - data->return_record_channels)); - TRACE_ICE(("return_record_buffer_size = %#x\n", - data->return_record_buffer_size)); + TRACE("return_record_buffers = %#x\n",(int)data->return_record_buffers); + TRACE("return_record_channels = %#x\n", (int)data->return_record_channels); + TRACE("return_record_buffer_size = %#x\n", (int)data->return_record_buffer_size); start_DMA(card); @@ -571,78 +828,78 @@ ice1712_buffer_exchange(ice1712 *card, multi_buffer_info *data) /* unsigned char peak[MAX_ADC]; int i; */ -// TRACE_ICE(("Avant Exchange p : %d, r : %d\n", data->playback_buffer_cycle, -// data->record_buffer_cycle)); +// TRACE("Avant Exchange p : %d, r : %d\n", data->playback_buffer_cycle, data->record_buffer_cycle); - status = acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT - | B_CAN_INTERRUPT, 50000); + status = acquire_sem_etc(card->buffer_ready_sem, 1, B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, 50000); switch (status) { - case B_OK: -// TRACE_ICE(("B_NO_ERROR\n")); - cpu_status = lock(); + case B_NO_ERROR: +// TRACE("B_NO_ERROR\n"); + cpu_status = disable_interrupts(); - // do playback - data->played_real_time = card->played_time; - data->played_frames_count += card->output_buffer_size; - data->playback_buffer_cycle = (card->buffer/* - 1*/) & 0x1; //Buffer TO fill + // Playback buffers info + data->played_real_time = card->played_time; + data->played_frames_count = card->frames_count; + data->playback_buffer_cycle = (card->buffer - 1) % SWAPPING_BUFFERS; //Buffer played - // do record - data->recorded_real_time = card->played_time; - data->recorded_frames_count += card->input_buffer_size; - data->record_buffer_cycle = (card->buffer/* - 1*/) & 0x1; //Buffer filled + // Record buffers info + data->recorded_real_time = card->played_time; + data->recorded_frames_count = card->frames_count; + data->record_buffer_cycle = (card->buffer - 1) % SWAPPING_BUFFERS; //Buffer filled data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; - unlock(cpu_status); + restore_interrupts(cpu_status); break; case B_BAD_SEM_ID: - TRACE_ICE(("B_BAD_SEM_ID\n")); + TRACE("B_BAD_SEM_ID\n"); break; case B_INTERRUPTED: - TRACE_ICE(("B_INTERRUPTED\n")); + TRACE("B_INTERRUPTED\n"); break; case B_BAD_VALUE: - TRACE_ICE(("B_BAD_VALUE\n")); + TRACE("B_BAD_VALUE\n"); break; case B_WOULD_BLOCK: - TRACE_ICE(("B_WOULD_BLOCK\n")); + TRACE("B_WOULD_BLOCK\n"); break; case B_TIMED_OUT: - TRACE_ICE(("B_TIMED_OUT\n")); + TRACE("B_TIMED_OUT\n"); start_DMA(card); - cpu_status = lock(); + cpu_status = lock(); data->played_real_time = card->played_time; data->playback_buffer_cycle = 0; - data->played_frames_count += card->output_buffer_size; + data->played_frames_count += card->buffer_size; data->recorded_real_time = card->played_time; data->record_buffer_cycle = 0; - data->recorded_frames_count += card->input_buffer_size; + data->recorded_frames_count += card->buffer_size; data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; unlock(cpu_status); break; default: - TRACE_ICE(("Default\n")); + TRACE("Default\n"); break; } -/* if ((card->buffer % 500) == 0) - { + if ((card->buffer % 1500) == 0) { uint8 reg8, reg8_dir; reg8 = read_gpio(card); reg8_dir = read_cci_uint8(card, CCI_GPIO_DIRECTION_CONTROL); - TRACE_ICE(("B_NO_ERROR buffer = %d : GPIO = %d (%d)\n", card->buffer, reg8, reg8_dir)); + 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); } -*/ + 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 e24b1557d6..a49a8ef0e9 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/multi.h +++ b/src/add-ons/kernel/drivers/audio/ice1712/multi.h @@ -9,8 +9,23 @@ * Distributed under the terms of the MIT license. */ +#ifndef _ICE1712_MULTI_H_ +#define _ICE1712_MULTI_H_ + #include "ice1712.h" +#include + +#define ICE1712_MULTI_CONTROL_FIRSTID (0x08000000) +#define ICE1712_MULTI_CONTROL_VOLUME_PB (0x00010000) +#define ICE1712_MULTI_CONTROL_VOLUME_REC (0x00020000) +#define ICE1712_MULTI_CONTROL_MUTE (0x00040000) +#define ICE1712_MULTI_CONTROL_MUX (0x00080000) +#define ICE1712_MULTI_CONTROL_MASK (0x00FF0000) +#define ICE1712_MULTI_CONTROL_CHANNEL_MASK (0x000000FF) + +#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); @@ -24,3 +39,5 @@ status_t ice1712_list_mix_connections(ice1712 *card, multi_mix_connection_info * 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); + +#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 index caad4219df..84210ec7c9 100644 --- a/src/add-ons/kernel/drivers/audio/ice1712/util.c +++ b/src/add-ons/kernel/drivers/audio/ice1712/util.c @@ -13,8 +13,6 @@ #include #include -//#define DEBUG 2 - #include "debug.h" #include "util.h" @@ -55,19 +53,19 @@ alloc_mem(void **phy, void **log, size_t size, const char *name) area_id areaid; status_t rv; - TRACE_ICE(("allocating %#08 bytes for %s\n",size,name)); + 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_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); if (areaid < B_OK) { - TRACE_ICE(("couldn't allocate area %s\n",name)); + 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_ICE(("couldn't map %s\n",name)); + TRACE("couldn't map %s\n",name); return B_ERROR; } memset(logadr,0,size); @@ -75,7 +73,7 @@ alloc_mem(void **phy, void **log, size_t size, const char *name) *log = logadr; if (phy) *phy = pe.address; - TRACE_ICE(("area = %d, size = %#08X, log = %#08X, phy = %#08X\n",areaid,size,logadr,pe.address)); + TRACE("area = %d, size = %#08X, log = %#08X, phy = %#08X\n", (int)areaid, (int)size, (int)logadr, (int)pe.address); return areaid; }